]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/emv/apduinfo.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2017 Merlok
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
8 // APDU status bytes information
9 //-----------------------------------------------------------------------------
18 const APDUCode APDUCodeTable
[] = {
19 // ID Type Description
20 { "XXXX" , APDUCODE_TYPE_NONE
, "" }, // blank string
21 { "6---" , APDUCODE_TYPE_ERROR
, "Class not supported." },
22 { "61--" , APDUCODE_TYPE_INFO
, "Response bytes still available" },
23 { "61XX" , APDUCODE_TYPE_INFO
, "Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE." },
24 { "62--" , APDUCODE_TYPE_WARNING
, "State of non-volatile memory unchanged" },
25 { "6200" , APDUCODE_TYPE_WARNING
, "No information given (NV-Ram not changed)" },
26 { "6201" , APDUCODE_TYPE_WARNING
, "NV-Ram not changed 1." },
27 { "6281" , APDUCODE_TYPE_WARNING
, "Part of returned data may be corrupted" },
28 { "6282" , APDUCODE_TYPE_WARNING
, "End of file/record reached before reading Le bytes" },
29 { "6283" , APDUCODE_TYPE_WARNING
, "Selected file invalidated" },
30 { "6284" , APDUCODE_TYPE_WARNING
, "Selected file is not valid. FCI not formated according to ISO" },
31 { "6285" , APDUCODE_TYPE_WARNING
, "No input data available from a sensor on the card. No Purse Engine enslaved for R3bc" },
32 { "62A2" , APDUCODE_TYPE_WARNING
, "Wrong R-MAC" },
33 { "62A4" , APDUCODE_TYPE_WARNING
, "Card locked (during reset( ))" },
34 { "62CX" , APDUCODE_TYPE_WARNING
, "Counter with value x (command dependent)" },
35 { "62F1" , APDUCODE_TYPE_WARNING
, "Wrong C-MAC" },
36 { "62F3" , APDUCODE_TYPE_WARNING
, "Internal reset" },
37 { "62F5" , APDUCODE_TYPE_WARNING
, "Default agent locked" },
38 { "62F7" , APDUCODE_TYPE_WARNING
, "Cardholder locked" },
39 { "62F8" , APDUCODE_TYPE_WARNING
, "Basement is current agent" },
40 { "62F9" , APDUCODE_TYPE_WARNING
, "CALC Key Set not unblocked" },
41 { "62FX" , APDUCODE_TYPE_WARNING
, "-" },
42 { "62XX" , APDUCODE_TYPE_WARNING
, "RFU" },
43 { "63--" , APDUCODE_TYPE_WARNING
, "State of non-volatile memory changed" },
44 { "6300" , APDUCODE_TYPE_WARNING
, "No information given (NV-Ram changed)" },
45 { "6381" , APDUCODE_TYPE_WARNING
, "File filled up by the last write. Loading/updating is not allowed." },
46 { "6382" , APDUCODE_TYPE_WARNING
, "Card key not supported." },
47 { "6383" , APDUCODE_TYPE_WARNING
, "Reader key not supported." },
48 { "6384" , APDUCODE_TYPE_WARNING
, "Plaintext transmission not supported." },
49 { "6385" , APDUCODE_TYPE_WARNING
, "Secured transmission not supported." },
50 { "6386" , APDUCODE_TYPE_WARNING
, "Volatile memory is not available." },
51 { "6387" , APDUCODE_TYPE_WARNING
, "Non-volatile memory is not available." },
52 { "6388" , APDUCODE_TYPE_WARNING
, "Key number not valid." },
53 { "6389" , APDUCODE_TYPE_WARNING
, "Key length is not correct." },
54 { "63C0" , APDUCODE_TYPE_WARNING
, "Verify fail, no try left." },
55 { "63C1" , APDUCODE_TYPE_WARNING
, "Verify fail, 1 try left." },
56 { "63C2" , APDUCODE_TYPE_WARNING
, "Verify fail, 2 tries left." },
57 { "63C3" , APDUCODE_TYPE_WARNING
, "Verify fail, 3 tries left." },
58 { "63CX" , APDUCODE_TYPE_WARNING
, "The counter has reached the value 'x' (0 = x = 15) (command dependent)." },
59 { "63F1" , APDUCODE_TYPE_WARNING
, "More data expected." },
60 { "63F2" , APDUCODE_TYPE_WARNING
, "More data expected and proactive command pending." },
61 { "63FX" , APDUCODE_TYPE_WARNING
, "-" },
62 { "63XX" , APDUCODE_TYPE_WARNING
, "RFU" },
63 { "64--" , APDUCODE_TYPE_ERROR
, "State of non-volatile memory unchanged" },
64 { "6400" , APDUCODE_TYPE_ERROR
, "No information given (NV-Ram not changed)" },
65 { "6401" , APDUCODE_TYPE_ERROR
, "Command timeout. Immediate response required by the card." },
66 { "64XX" , APDUCODE_TYPE_ERROR
, "RFU" },
67 { "65--" , APDUCODE_TYPE_ERROR
, "State of non-volatile memory changed" },
68 { "6500" , APDUCODE_TYPE_ERROR
, "No information given" },
69 { "6501" , APDUCODE_TYPE_ERROR
, "Write error. Memory failure. There have been problems in writing or reading the EEPROM. Other hardware problems may also bring this error." },
70 { "6581" , APDUCODE_TYPE_ERROR
, "Memory failure" },
71 { "65FX" , APDUCODE_TYPE_ERROR
, "-" },
72 { "65XX" , APDUCODE_TYPE_ERROR
, "RFU" },
73 { "66--" , APDUCODE_TYPE_SECURITY
, " " },
74 { "6600" , APDUCODE_TYPE_SECURITY
, "Error while receiving (timeout)" },
75 { "6601" , APDUCODE_TYPE_SECURITY
, "Error while receiving (character parity error)" },
76 { "6602" , APDUCODE_TYPE_SECURITY
, "Wrong checksum" },
77 { "6603" , APDUCODE_TYPE_SECURITY
, "The current DF file without FCI" },
78 { "6604" , APDUCODE_TYPE_SECURITY
, "No SF or KF under the current DF" },
79 { "6669" , APDUCODE_TYPE_SECURITY
, "Incorrect Encryption/Decryption Padding" },
80 { "66XX" , APDUCODE_TYPE_SECURITY
, "-" },
81 { "67--" , APDUCODE_TYPE_ERROR
, " " },
82 { "6700" , APDUCODE_TYPE_ERROR
, "Wrong length" },
83 { "67XX" , APDUCODE_TYPE_ERROR
, "length incorrect (procedure)(ISO 7816-3)" },
84 { "68--" , APDUCODE_TYPE_ERROR
, "Functions in CLA not supported" },
85 { "6800" , APDUCODE_TYPE_ERROR
, "No information given (The request function is not supported by the card)" },
86 { "6881" , APDUCODE_TYPE_ERROR
, "Logical channel not supported" },
87 { "6882" , APDUCODE_TYPE_ERROR
, "Secure messaging not supported" },
88 { "6883" , APDUCODE_TYPE_ERROR
, "Last command of the chain expected" },
89 { "6884" , APDUCODE_TYPE_ERROR
, "Command chaining not supported" },
90 { "68FX" , APDUCODE_TYPE_ERROR
, "-" },
91 { "68XX" , APDUCODE_TYPE_ERROR
, "RFU" },
92 { "69--" , APDUCODE_TYPE_ERROR
, "Command not allowed" },
93 { "6900" , APDUCODE_TYPE_ERROR
, "No information given (Command not allowed)" },
94 { "6901" , APDUCODE_TYPE_ERROR
, "Command not accepted (inactive state)" },
95 { "6981" , APDUCODE_TYPE_ERROR
, "Command incompatible with file structure" },
96 { "6982" , APDUCODE_TYPE_ERROR
, "Security condition not satisfied." },
97 { "6983" , APDUCODE_TYPE_ERROR
, "Authentication method blocked" },
98 { "6984" , APDUCODE_TYPE_ERROR
, "Referenced data reversibly blocked (invalidated)" },
99 { "6985" , APDUCODE_TYPE_ERROR
, "Conditions of use not satisfied." },
100 { "6986" , APDUCODE_TYPE_ERROR
, "Command not allowed (no current EF)" },
101 { "6987" , APDUCODE_TYPE_ERROR
, "Expected secure messaging (SM) object missing" },
102 { "6988" , APDUCODE_TYPE_ERROR
, "Incorrect secure messaging (SM) data object" },
103 { "698D" , APDUCODE_TYPE_NONE
, "Reserved" },
104 { "6996" , APDUCODE_TYPE_ERROR
, "Data must be updated again" },
105 { "69E1" , APDUCODE_TYPE_ERROR
, "POL1 of the currently Enabled Profile prevents this action." },
106 { "69F0" , APDUCODE_TYPE_ERROR
, "Permission Denied" },
107 { "69F1" , APDUCODE_TYPE_ERROR
, "Permission Denied - Missing Privilege" },
108 { "69FX" , APDUCODE_TYPE_ERROR
, "-" },
109 { "69XX" , APDUCODE_TYPE_ERROR
, "RFU" },
110 { "6A--" , APDUCODE_TYPE_ERROR
, "Wrong parameter(s) P1-P2" },
111 { "6A00" , APDUCODE_TYPE_ERROR
, "No information given (Bytes P1 and/or P2 are incorrect)" },
112 { "6A80" , APDUCODE_TYPE_ERROR
, "The parameters in the data field are incorrect." },
113 { "6A81" , APDUCODE_TYPE_ERROR
, "Function not supported" },
114 { "6A82" , APDUCODE_TYPE_ERROR
, "File not found" },
115 { "6A83" , APDUCODE_TYPE_ERROR
, "Record not found" },
116 { "6A84" , APDUCODE_TYPE_ERROR
, "There is insufficient memory space in record or file" },
117 { "6A85" , APDUCODE_TYPE_ERROR
, "Lc inconsistent with TLV structure" },
118 { "6A86" , APDUCODE_TYPE_ERROR
, "Incorrect P1 or P2 parameter." },
119 { "6A87" , APDUCODE_TYPE_ERROR
, "Lc inconsistent with P1-P2" },
120 { "6A88" , APDUCODE_TYPE_ERROR
, "Referenced data not found" },
121 { "6A89" , APDUCODE_TYPE_ERROR
, "File already exists" },
122 { "6A8A" , APDUCODE_TYPE_ERROR
, "DF name already exists." },
123 { "6AF0" , APDUCODE_TYPE_ERROR
, "Wrong parameter value" },
124 { "6AFX" , APDUCODE_TYPE_ERROR
, "-" },
125 { "6AXX" , APDUCODE_TYPE_ERROR
, "RFU" },
126 { "6B--" , APDUCODE_TYPE_ERROR
, " " },
127 { "6B00" , APDUCODE_TYPE_ERROR
, "Wrong parameter(s) P1-P2" },
128 { "6BXX" , APDUCODE_TYPE_ERROR
, "Reference incorrect (procedure byte), (ISO 7816-3)" },
129 { "6C--" , APDUCODE_TYPE_ERROR
, "Wrong length Le" },
130 { "6C00" , APDUCODE_TYPE_ERROR
, "Incorrect P3 length." },
131 { "6CXX" , APDUCODE_TYPE_ERROR
, "Bad length value in Le; 'xx' is the correct exact Le" },
132 { "6D--" , APDUCODE_TYPE_ERROR
, " " },
133 { "6D00" , APDUCODE_TYPE_ERROR
, "Instruction code not supported or invalid" },
134 { "6DXX" , APDUCODE_TYPE_ERROR
, "Instruction code not programmed or invalid (procedure byte), (ISO 7816-3)" },
135 { "6E--" , APDUCODE_TYPE_ERROR
, " " },
136 { "6E00" , APDUCODE_TYPE_ERROR
, "Class not supported" },
137 { "6EXX" , APDUCODE_TYPE_ERROR
, "Instruction class not supported (procedure byte), (ISO 7816-3)" },
138 { "6F--" , APDUCODE_TYPE_ERROR
, "Internal exception" },
139 { "6F00" , APDUCODE_TYPE_ERROR
, "Command aborted - more exact diagnosis not possible (e.g., operating system error)." },
140 { "6FFF" , APDUCODE_TYPE_ERROR
, "Card dead (overuse)" },
141 { "6FXX" , APDUCODE_TYPE_ERROR
, "No precise diagnosis (procedure byte), (ISO 7816-3)" },
142 { "9---" , APDUCODE_TYPE_NONE
, "" },
143 { "9000" , APDUCODE_TYPE_INFO
, "Command successfully executed (OK)." },
144 { "9004" , APDUCODE_TYPE_WARNING
, "PIN not successfully verified, 3 or more PIN tries left" },
145 { "9008" , APDUCODE_TYPE_NONE
, "Key/file not found" },
146 { "9080" , APDUCODE_TYPE_WARNING
, "Unblock Try Counter has reached zero" },
147 { "9100" , APDUCODE_TYPE_NONE
, "OK" },
148 { "9101" , APDUCODE_TYPE_NONE
, "States.activity, States.lock Status or States.lockable has wrong value" },
149 { "9102" , APDUCODE_TYPE_NONE
, "Transaction number reached its limit" },
150 { "910C" , APDUCODE_TYPE_NONE
, "No changes" },
151 { "910E" , APDUCODE_TYPE_NONE
, "Insufficient NV-Memory to complete command" },
152 { "911C" , APDUCODE_TYPE_NONE
, "Command code not supported" },
153 { "911E" , APDUCODE_TYPE_NONE
, "CRC or MAC does not match data" },
154 { "9140" , APDUCODE_TYPE_NONE
, "Invalid key number specified" },
155 { "917E" , APDUCODE_TYPE_NONE
, "Length of command string invalid" },
156 { "919D" , APDUCODE_TYPE_NONE
, "Not allow the requested command" },
157 { "919E" , APDUCODE_TYPE_NONE
, "Value of the parameter invalid" },
158 { "91A0" , APDUCODE_TYPE_NONE
, "Requested AID not present on PICC" },
159 { "91A1" , APDUCODE_TYPE_NONE
, "Unrecoverable error within application" },
160 { "91AE" , APDUCODE_TYPE_NONE
, "Authentication status does not allow the requested command" },
161 { "91AF" , APDUCODE_TYPE_NONE
, "Additional data frame is expected to be sent" },
162 { "91BE" , APDUCODE_TYPE_NONE
, "Out of boundary" },
163 { "91C1" , APDUCODE_TYPE_NONE
, "Unrecoverable error within PICC" },
164 { "91CA" , APDUCODE_TYPE_NONE
, "Previous Command was not fully completed" },
165 { "91CD" , APDUCODE_TYPE_NONE
, "PICC was disabled by an unrecoverable error" },
166 { "91CE" , APDUCODE_TYPE_NONE
, "Number of Applications limited to 28" },
167 { "91DE" , APDUCODE_TYPE_NONE
, "File or application already exists" },
168 { "91EE" , APDUCODE_TYPE_NONE
, "Could not complete NV-write operation due to loss of power" },
169 { "91F0" , APDUCODE_TYPE_NONE
, "Specified file number does not exist" },
170 { "91F1" , APDUCODE_TYPE_NONE
, "Unrecoverable error within file" },
171 { "920x" , APDUCODE_TYPE_INFO
, "Writing to EEPROM successful after 'x' attempts." },
172 { "9210" , APDUCODE_TYPE_ERROR
, "Insufficient memory. No more storage available." },
173 { "9240" , APDUCODE_TYPE_ERROR
, "Writing to EEPROM not successful." },
174 { "9301" , APDUCODE_TYPE_NONE
, "Integrity error" },
175 { "9302" , APDUCODE_TYPE_NONE
, "Candidate S2 invalid" },
176 { "9303" , APDUCODE_TYPE_ERROR
, "Application is permanently locked" },
177 { "9400" , APDUCODE_TYPE_ERROR
, "No EF selected." },
178 { "9401" , APDUCODE_TYPE_NONE
, "Candidate currency code does not match purse currency" },
179 { "9402" , APDUCODE_TYPE_NONE
, "Candidate amount too high" },
180 { "9402" , APDUCODE_TYPE_ERROR
, "Address range exceeded." },
181 { "9403" , APDUCODE_TYPE_NONE
, "Candidate amount too low" },
182 { "9404" , APDUCODE_TYPE_ERROR
, "FID not found, record not found or comparison pattern not found." },
183 { "9405" , APDUCODE_TYPE_NONE
, "Problems in the data field" },
184 { "9406" , APDUCODE_TYPE_ERROR
, "Required MAC unavailable" },
185 { "9407" , APDUCODE_TYPE_NONE
, "Bad currency : purse engine has no slot with R3bc currency" },
186 { "9408" , APDUCODE_TYPE_NONE
, "R3bc currency not supported in purse engine" },
187 { "9408" , APDUCODE_TYPE_ERROR
, "Selected file type does not match command." },
188 { "9580" , APDUCODE_TYPE_NONE
, "Bad sequence" },
189 { "9681" , APDUCODE_TYPE_NONE
, "Slave not found" },
190 { "9700" , APDUCODE_TYPE_NONE
, "PIN blocked and Unblock Try Counter is 1 or 2" },
191 { "9702" , APDUCODE_TYPE_NONE
, "Main keys are blocked" },
192 { "9704" , APDUCODE_TYPE_NONE
, "PIN not successfully verified, 3 or more PIN tries left" },
193 { "9784" , APDUCODE_TYPE_NONE
, "Base key" },
194 { "9785" , APDUCODE_TYPE_NONE
, "Limit exceeded - C-MAC key" },
195 { "9786" , APDUCODE_TYPE_NONE
, "SM error - Limit exceeded - R-MAC key" },
196 { "9787" , APDUCODE_TYPE_NONE
, "Limit exceeded - sequence counter" },
197 { "9788" , APDUCODE_TYPE_NONE
, "Limit exceeded - R-MAC length" },
198 { "9789" , APDUCODE_TYPE_NONE
, "Service not available" },
199 { "9802" , APDUCODE_TYPE_ERROR
, "No PIN defined." },
200 { "9804" , APDUCODE_TYPE_ERROR
, "Access conditions not satisfied, authentication failed." },
201 { "9835" , APDUCODE_TYPE_ERROR
, "ASK RANDOM or GIVE RANDOM not executed." },
202 { "9840" , APDUCODE_TYPE_ERROR
, "PIN verification not successful." },
203 { "9850" , APDUCODE_TYPE_ERROR
, "INCREASE or DECREASE could not be executed because a limit has been reached." },
204 { "9862" , APDUCODE_TYPE_ERROR
, "Authentication Error, application specific (incorrect MAC)" },
205 { "9900" , APDUCODE_TYPE_NONE
, "1 PIN try left" },
206 { "9904" , APDUCODE_TYPE_NONE
, "PIN not successfully verified, 1 PIN try left" },
207 { "9985" , APDUCODE_TYPE_NONE
, "Wrong status - Cardholder lock" },
208 { "9986" , APDUCODE_TYPE_ERROR
, "Missing privilege" },
209 { "9987" , APDUCODE_TYPE_NONE
, "PIN is not installed" },
210 { "9988" , APDUCODE_TYPE_NONE
, "Wrong status - R-MAC state" },
211 { "9A00" , APDUCODE_TYPE_NONE
, "2 PIN try left" },
212 { "9A04" , APDUCODE_TYPE_NONE
, "PIN not successfully verified, 2 PIN try left" },
213 { "9A71" , APDUCODE_TYPE_NONE
, "Wrong parameter value - Double agent AID" },
214 { "9A72" , APDUCODE_TYPE_NONE
, "Wrong parameter value - Double agent Type" },
215 { "9D05" , APDUCODE_TYPE_ERROR
, "Incorrect certificate type" },
216 { "9D07" , APDUCODE_TYPE_ERROR
, "Incorrect session data size" },
217 { "9D08" , APDUCODE_TYPE_ERROR
, "Incorrect DIR file record size" },
218 { "9D09" , APDUCODE_TYPE_ERROR
, "Incorrect FCI record size" },
219 { "9D0A" , APDUCODE_TYPE_ERROR
, "Incorrect code size" },
220 { "9D10" , APDUCODE_TYPE_ERROR
, "Insufficient memory to load application" },
221 { "9D11" , APDUCODE_TYPE_ERROR
, "Invalid AID" },
222 { "9D12" , APDUCODE_TYPE_ERROR
, "Duplicate AID" },
223 { "9D13" , APDUCODE_TYPE_ERROR
, "Application previously loaded" },
224 { "9D14" , APDUCODE_TYPE_ERROR
, "Application history list full" },
225 { "9D15" , APDUCODE_TYPE_ERROR
, "Application not open" },
226 { "9D17" , APDUCODE_TYPE_ERROR
, "Invalid offset" },
227 { "9D18" , APDUCODE_TYPE_ERROR
, "Application already loaded" },
228 { "9D19" , APDUCODE_TYPE_ERROR
, "Invalid certificate" },
229 { "9D1A" , APDUCODE_TYPE_ERROR
, "Invalid signature" },
230 { "9D1B" , APDUCODE_TYPE_ERROR
, "Invalid KTU" },
231 { "9D1D" , APDUCODE_TYPE_ERROR
, "MSM controls not set" },
232 { "9D1E" , APDUCODE_TYPE_ERROR
, "Application signature does not exist" },
233 { "9D1F" , APDUCODE_TYPE_ERROR
, "KTU does not exist" },
234 { "9D20" , APDUCODE_TYPE_ERROR
, "Application not loaded" },
235 { "9D21" , APDUCODE_TYPE_ERROR
, "Invalid Open command data length" },
236 { "9D30" , APDUCODE_TYPE_ERROR
, "Check data parameter is incorrect (invalid start address)" },
237 { "9D31" , APDUCODE_TYPE_ERROR
, "Check data parameter is incorrect (invalid length)" },
238 { "9D32" , APDUCODE_TYPE_ERROR
, "Check data parameter is incorrect (illegal memory check area)" },
239 { "9D40" , APDUCODE_TYPE_ERROR
, "Invalid MSM Controls ciphertext" },
240 { "9D41" , APDUCODE_TYPE_ERROR
, "MSM controls already set" },
241 { "9D42" , APDUCODE_TYPE_ERROR
, "Set MSM Controls data length less than 2 bytes" },
242 { "9D43" , APDUCODE_TYPE_ERROR
, "Invalid MSM Controls data length" },
243 { "9D44" , APDUCODE_TYPE_ERROR
, "Excess MSM Controls ciphertext" },
244 { "9D45" , APDUCODE_TYPE_ERROR
, "Verification of MSM Controls data failed" },
245 { "9D50" , APDUCODE_TYPE_ERROR
, "Invalid MCD Issuer production ID" },
246 { "9D51" , APDUCODE_TYPE_ERROR
, "Invalid MCD Issuer ID" },
247 { "9D52" , APDUCODE_TYPE_ERROR
, "Invalid set MSM controls data date" },
248 { "9D53" , APDUCODE_TYPE_ERROR
, "Invalid MCD number" },
249 { "9D54" , APDUCODE_TYPE_ERROR
, "Reserved field error" },
250 { "9D55" , APDUCODE_TYPE_ERROR
, "Reserved field error" },
251 { "9D56" , APDUCODE_TYPE_ERROR
, "Reserved field error" },
252 { "9D57" , APDUCODE_TYPE_ERROR
, "Reserved field error" },
253 { "9D60" , APDUCODE_TYPE_ERROR
, "MAC verification failed" },
254 { "9D61" , APDUCODE_TYPE_ERROR
, "Maximum number of unblocks reached" },
255 { "9D62" , APDUCODE_TYPE_ERROR
, "Card was not blocked" },
256 { "9D63" , APDUCODE_TYPE_ERROR
, "Crypto functions not available" },
257 { "9D64" , APDUCODE_TYPE_ERROR
, "No application loaded" },
258 { "9E00" , APDUCODE_TYPE_NONE
, "PIN not installed" },
259 { "9E04" , APDUCODE_TYPE_NONE
, "PIN not successfully verified, PIN not installed" },
260 { "9F00" , APDUCODE_TYPE_NONE
, "PIN blocked and Unblock Try Counter is 3" },
261 { "9F04" , APDUCODE_TYPE_NONE
, "PIN not successfully verified, PIN blocked and Unblock Try Counter is 3" },
262 { "9FXX" , APDUCODE_TYPE_NONE
, "Command successfully executed; 'xx' bytes of data are available and can be requested using GET RESPONSE." },
263 { "9XXX" , APDUCODE_TYPE_NONE
, "Application related status, (ISO 7816-3)" }
265 const size_t APDUCodeTableLen
= sizeof ( APDUCodeTable
) / sizeof ( APDUCode
);
267 static int CodeCmp ( const char * code1
, const char * code2
) {
270 for ( int i
= 0 ; i
< 4 ; i
++) {
271 if ( code1
[ i
] == code2
[ i
])
273 if ( code1
[ i
] == 'X' || code2
[ i
] == 'X' )
279 if ( cmp
+ xsymb
== 4 )
285 const APDUCode
* GetAPDUCode ( uint8_t sw1
, uint8_t sw2
) {
287 int mineq
= APDUCodeTableLen
;
290 sprintf ( buf
, "%02X%02X" , sw1
, sw2
);
292 for ( int i
= 0 ; i
< APDUCodeTableLen
; i
++) {
293 int res
= CodeCmp ( APDUCodeTable
[ i
]. ID
, buf
);
297 return & APDUCodeTable
[ i
];
301 if ( res
> 0 && mineq
> res
) {
307 // if we have not equal, but with some 'X'
308 if ( mineqindx
< APDUCodeTableLen
) {
309 return & APDUCodeTable
[ mineqindx
];
315 const char * GetAPDUCodeDescription ( uint8_t sw1
, uint8_t sw2
) {
316 const APDUCode
* cd
= GetAPDUCode ( sw1
, sw2
);
318 return cd
-> Description
;
320 return APDUCodeTable
[ 0 ]. Description
; //empty string
323 int APDUDecode ( uint8_t * data
, int len
, APDUStruct
* apdu
) {
324 ExtAPDUHeader
* hapdu
= ( ExtAPDUHeader
*) data
;
326 apdu
-> cla
= hapdu
-> cla
;
327 apdu
-> ins
= hapdu
-> ins
;
328 apdu
-> p1
= hapdu
-> p1
;
329 apdu
-> p2
= hapdu
-> p2
;
334 apdu
-> extended_apdu
= false ;
335 apdu
-> case_type
= 0x00 ;
337 uint8_t b0
= hapdu
-> lc
[ 0 ];
341 apdu
-> case_type
= 0x01 ;
346 apdu
-> case_type
= 0x02 ;
352 // case 3S (Lc + data)
353 if ( len
== 5U + b0
&& b0
!= 0 ) {
354 apdu
-> case_type
= 0x03 ;
358 // case 4S (Lc + data + Le)
359 if ( len
== 5U + b0
+ 1U && b0
!= 0 ) {
360 apdu
-> case_type
= 0x04 ;
362 apdu
-> le
= data
[ len
- 1 ];
367 // extended length apdu
368 if ( len
>= 7 && b0
== 0 ) {
369 uint16_t extlen
= ( hapdu
-> lc
[ 1 ] << 8 ) + hapdu
-> lc
[ 2 ];
371 // case 2E (Le) - extended
373 apdu
-> case_type
= 0x12 ;
374 apdu
-> extended_apdu
= true ;
380 // case 3E (Lc + data) - extended
381 if ( len
== 7U + extlen
) {
382 apdu
-> case_type
= 0x13 ;
383 apdu
-> extended_apdu
= true ;
387 // case 4E (Lc + data + Le) - extended 2-byte Le
388 if ( len
== 7U + extlen
+ 2U ) {
389 apdu
-> case_type
= 0x14 ;
390 apdu
-> extended_apdu
= true ;
392 apdu
-> le
= ( data
[ len
- 2 ] << 8 ) + data
[ len
- 1 ];
397 // case 4E (Lc + data + Le) - extended 3-byte Le
398 if ( len
== 7U + extlen
+ 3U && data
[ len
- 3 ] == 0 ) {
399 apdu
-> case_type
= 0x24 ;
400 apdu
-> extended_apdu
= true ;
402 apdu
-> le
= ( data
[ len
- 2 ] << 8 ) + data
[ len
- 1 ];
408 if (! apdu
-> case_type
)
412 if ( apdu
-> extended_apdu
) {
413 apdu
-> data
= data
+ 7 ;
415 apdu
-> data
= data
+ 5 ;
423 int APDUEncode ( APDUStruct
* apdu
, uint8_t * data
, int * len
) {
427 if ( apdu
-> le
> 0x10000 || apdu
-> lc
> 0xffff )
431 data
[ dptr
++] = apdu
-> cla
;
432 data
[ dptr
++] = apdu
-> ins
;
433 data
[ dptr
++] = apdu
-> p1
;
434 data
[ dptr
++] = apdu
-> p2
;
437 if ( apdu
-> extended_apdu
|| apdu
-> lc
> 0xff || apdu
-> le
> 0x100 ) {
439 data
[ dptr
++] = ( apdu
-> lc
>> 8 ) & 0xff ;
440 data
[ dptr
++] = ( apdu
-> lc
) & 0xff ;
441 memmove (& data
[ dptr
], apdu
-> data
, apdu
-> lc
);
443 apdu
-> extended_apdu
= true ;
445 data
[ dptr
++] = apdu
-> lc
;
446 memmove (& data
[ dptr
], apdu
-> data
, apdu
-> lc
);
452 if ( apdu
-> extended_apdu
) {
453 if ( apdu
-> le
!= 0x10000 ) {
455 data
[ dptr
++] = ( apdu
-> le
>> 8 ) & 0xff ;
456 data
[ dptr
++] = ( apdu
-> le
) & 0xff ;
463 if ( apdu
-> le
!= 0x100 )
464 data
[ dptr
++] = apdu
-> le
;
475 int APDUEncodeS ( sAPDU
* sapdu
, bool extended
, uint16_t le
, uint8_t * data
, int * len
) {
476 if ( extended
&& le
> 0x100 )
481 apdu
. cla
= sapdu
-> CLA
;
482 apdu
. ins
= sapdu
-> INS
;
488 apdu
. data
= sapdu
-> data
;
493 apdu
. extended_apdu
= extended
;
494 apdu
. case_type
= 0x00 ;
496 return APDUEncode (& apdu
, data
, len
);
499 void APDUPrint ( APDUStruct apdu
) {
500 APDUPrintEx ( apdu
, 0 );
503 void APDUPrintEx ( APDUStruct apdu
, size_t maxdatalen
) {
504 PrintAndLogEx ( INFO
, "APDU: %scase=0x%02x cla=0x%02x ins=0x%02x p1=0x%02x p2=0x%02x Lc=0x%02x(%d) Le=0x%02x(%d)" ,
505 apdu
. extended_apdu
? "[e]" : "" , apdu
. case_type
, apdu
. cla
, apdu
. ins
, apdu
. p1
, apdu
. p2
, apdu
. lc
, apdu
. lc
, apdu
. le
, apdu
. le
);
507 PrintAndLogEx ( INFO
, "data: %s%s" , sprint_hex ( apdu
. data
, MIN ( apdu
. lc
, maxdatalen
)), apdu
. lc
> maxdatalen
? "..." : "" );