iso7816 linux driver,ISO7816智能卡读写源代码----ISO7816

本文档详细介绍了ISO7816智能卡读写源代码中的错误处理函数`iso7816_check_sw()`以及读取和写入数据的函数。通过对错误代码映射和APDU命令的处理,展示了智能卡与读卡器之间的交互过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

26#include 27

28#include "internal.h"

29#include "asn1.h"

30#include "iso7816.h"

31

32static const struct sc_card_error iso7816_errors[] = {

33        { 0x6200, SC_ERROR_MEMORY_FAILURE,      "State of non-volatile memory unchanged" },

34        { 0x6281, SC_ERROR_MEMORY_FAILURE,      "Part of returned data may be corrupted" },

35        { 0x6282, SC_ERROR_CARD_CMD_FAILED,     "End of file/record reached before reading Le bytes" },

36        { 0x6283, SC_ERROR_CARD_CMD_FAILED,     "Selected file invalidated" },

37        { 0x6284, SC_ERROR_CARD_CMD_FAILED,     "FCI not formatted according to ISO 7816-4" },

38

39        { 0x6300, SC_ERROR_MEMORY_FAILURE,      "State of non-volatile memory changed" },

40        { 0x6381, SC_ERROR_CARD_CMD_FAILED,     "File filled up by last write" },

41

42        { 0x6581, SC_ERROR_MEMORY_FAILURE,      "Memory failure" },

43

44        { 0x6700, SC_ERROR_WRONG_LENGTH,        "Wrong length" },

45

46        { 0x6800, SC_ERROR_NO_CARD_SUPPORT,     "Functions in CLA not supported" },

47        { 0x6881, SC_ERROR_NO_CARD_SUPPORT,     "Logical channel not supported" },

48        { 0x6882, SC_ERROR_NO_CARD_SUPPORT,     "Secure messaging not supported" },

49

50        { 0x6900, SC_ERROR_NOT_ALLOWED,         "Command not allowed" },

51        { 0x6981, SC_ERROR_CARD_CMD_FAILED,     "Command incompatible with file structure" },

52        { 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Security status not satisfied" },

53        { 0x6983, SC_ERROR_AUTH_METHOD_BLOCKED, "Authentication method blocked" },

54        { 0x6984, SC_ERROR_CARD_CMD_FAILED,     "Referenced data invalidated" },

55        { 0x6985, SC_ERROR_NOT_ALLOWED,         "Conditions of use not satisfied" },

56        { 0x6986, SC_ERROR_NOT_ALLOWED,         "Command not allowed (no current EF)" },

57        { 0x6987, SC_ERROR_INCORRECT_PARAMETERS,"Expected SM data objects missing" },

58        { 0x6988, SC_ERROR_INCORRECT_PARAMETERS,"SM data objects incorrect" },

59

60        { 0x6A00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" },

61        { 0x6A80, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters in the data field" },

62        { 0x6A81, SC_ERROR_NO_CARD_SUPPORT,     "Function not supported" },

63        { 0x6A82, SC_ERROR_FILE_NOT_FOUND,      "File not found" },

64        { 0x6A83, SC_ERROR_RECORD_NOT_FOUND,    "Record not found" },

65        { 0x6A84, SC_ERROR_NOT_ENOUGH_MEMORY,   "Not enough memory space in the file" },

66        { 0x6A85, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with TLV structure" },

67        { 0x6A86, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters P1-P2" },

68        { 0x6A87, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with P1-P2" },

69        { 0x6A88, SC_ERROR_DATA_OBJECT_NOT_FOUND,"Referenced data not found" },

70

71        { 0x6B00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" },

72        { 0x6D00, SC_ERROR_INS_NOT_SUPPORTED,   "Instruction code not supported or invalid" },

73        { 0x6E00, SC_ERROR_CLASS_NOT_SUPPORTED, "Class not supported" },

74        { 0x6F00, SC_ERROR_CARD_CMD_FAILED,     "No precise diagnosis" },

75

76        /* Possibly TCOS / Micardo specific errors */

77        { 0x6600, SC_ERROR_INCORRECT_PARAMETERS, "Error setting the security env"},

78        { 0x66F0, SC_ERROR_INCORRECT_PARAMETERS, "No space left for padding"},

79        { 0x69F0, SC_ERROR_NOT_ALLOWED,          "Command not allowed"},

80        { 0x6A89, SC_ERROR_FILE_ALREADY_EXISTS,  "Files exists"},

81        { 0x6A8A, SC_ERROR_FILE_ALREADY_EXISTS,  "Application exists"},

82};

83

84static int iso7816_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2)

85{

86        const int err_count = sizeof(iso7816_errors)/sizeof(iso7816_errors[0]);

87        int i;

88

89        /* Handle special cases here */

90        if (sw1 == 0x6C) {

91                sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Wrong length; correct length is %d", sw2);

92                return SC_ERROR_WRONG_LENGTH;

93        }

94        if (sw1 == 0x90)

95                return SC_SUCCESS;

96        if (sw1 == 0x63U && (sw2 & ~0x0fU) == 0xc0U ) {

97             sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Verification failed (remaining tries: %d)",

98                   (sw2 & 0x0f));

99             return SC_ERROR_PIN_CODE_INCORRECT;

100        }

101        for (i = 0; i < err_count; i++)

102                if (iso7816_errors[i].SWs == ((sw1 << 8) | sw2)) {

103                        sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s", iso7816_errors[i].errorstr);

104                        return iso7816_errors[i].errorno;

105                }

106        sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Unknown SWs; SW1=%02X, SW2=%02X", sw1, sw2);

107        return SC_ERROR_CARD_CMD_FAILED;

108}

109

110static int iso7816_read_binary(sc_card_t *card,

111                               unsigned int idx, u8 *buf, size_t count,

112                               unsigned long flags)

113{

114        sc_apdu_t apdu;

115        u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE];

116        int r;

117

118        if (idx > 0x7fff) {

119                sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "invalid EF offset: 0x%X > 0x7FFF", idx);

120                return SC_ERROR_OFFSET_TOO_LARGE;

121        }

122

123        assert(count <= (card->max_recv_size > 0 ? card->max_recv_size : 256));

124        sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0,

125                       (idx >> 8) & 0x7F, idx & 0xFF);

126        apdu.le = count;

127        apdu.resplen = count;

128        apdu.resp = recvbuf;

129

130        r = sc_transmit_apdu(card, &apdu);

131        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");

132        if (apdu.resplen == 0)

133                SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));

134        memcpy(buf, recvbuf, apdu.resplen);

135

136        SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen);

137}

138

139static int iso7816_read_record(sc_card_t *card,

140                               unsigned int rec_nr, u8 *buf, size_t count,

141                               unsigned long flags)

142{

143        sc_apdu_t apdu;

144        u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE];

145        int r;

146

147        sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB2, rec_nr, 0);

148        apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;

149        if (flags & SC_RECORD_BY_REC_NR)

150                apdu.p2 |= 0x04;

151

152        apdu.le = count;

153        apdu.resplen = count;

154        apdu.resp = recvbuf;

155

156        r = sc_transmit_apdu(card, &apdu);

157        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");

158        if (apdu.resplen == 0)

159                SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));

160        memcpy(buf, recvbuf, apdu.resplen);

161

162        SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, apdu.resplen);

163}

164

165static int iso7816_write_record(sc_card_t *card, unsigned int rec_nr,

166                                const u8 *buf, size_t count,

167                                unsigned long flags)

168{

169        sc_apdu_t apdu;

170        int r;

171

172        if (count > 256) {

173                sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Trying to send too many bytes");

174                return SC_ERROR_INVALID_ARGUMENTS;

175        }

176        sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD2, rec_nr, 0);

177        apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;

178        if (flags & SC_RECORD_BY_REC_NR)

179                apdu.p2 |= 0x04;

180

181        apdu.lc = count;

182        apdu.datalen = count;

183        apdu.data = buf;

184

185        r = sc_transmit_apdu(card, &apdu);

186        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed");

187        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, sc_check_sw(card, apdu.sw1, apdu.sw2),

188                    "Card returned error");

189        SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, count);

190}

191

192static int iso7816_append_record(sc_card_t *card,

193                                 const u8 *buf, size_t count,

194                                 unsigned long flags)

195{

196        sc_apdu_t apdu;

197        int r;

198

199        if (count > 256) {

200                sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "Trying to send too many bytes");

201                return SC_ERROR_INVALID_ARGUMENTS;

202        }

203        sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE2, 0, 0);

204        apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3;

205

206        apdu.lc = count;

207        apdu.datalen = count;

208        apdu.data = buf;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值