3 ISO 7816 ICC's answer to reset abstract data type implementation
5 This file is part of the Unix driver for Towitoko smartcard readers
6 Copyright (C) 2000 Carlos Prados <cprados@yahoo.com>
8 This version is modified by doz21 to work in a special manner ;)
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "../globals.h"
28 const uint32_t atr_fs_table
[16] = {5000000L, 5000000L, 6000000L, 8000000L, 12000000L, 16000000L, 20000000L, 0, 0, 5000000L, 7500000L, 10000000L, 15000000L, 20000000L, 0, 0};
29 const uint32_t atr_f_table
[16] = {372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768, 1024, 1536, 2048, 0, 0};
30 const double atr_d_table
[16] = {0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0, 0, 0, 0, 0, 0};
32 #ifdef WITH_CARDREADER
33 int32_t ATR_InitFromArray(ATR
*atr
, const unsigned char atr_buffer
[ATR_MAX_SIZE
], uint32_t length
)
36 unsigned char buffer
[ATR_MAX_SIZE
] = "\x00";
37 uint32_t pointer
= 0, pn
= 0;
38 static const uint32_t atr_num_ib_table
[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
40 /* Check size of buffer */
43 cs_log_dbg(D_ATR
, "ERROR: this ATR length is %d and minimum length is 2", length
);
47 /* Check if ATR is from a inverse convention card */
48 if(atr_buffer
[0] == 0x03) // Readers of type R_MOUSE need this in case of inverse convention cards!
50 for(pointer
= 0; pointer
< length
; pointer
++)
51 { buffer
[pointer
] = ~(INVERT_BYTE(atr_buffer
[pointer
])); }
55 memcpy(buffer
, atr_buffer
, length
);
61 atr
->T0
= TDi
= buffer
[1];
64 /* Store number of historical bytes */
65 atr
->hbn
= TDi
& 0x0F;
67 /* TCK is not present by default */
68 (atr
->TCK
).present
= 0;
70 /* Extract interface bytes */
71 while(pointer
< length
)
73 /* Check buffer is long enought */
74 if(pointer
+ atr_num_ib_table
[(0xF0 & TDi
) >> 4] >= length
)
76 cs_log_dbg(D_ATR
, "ERROR: this ATR the %d interface bytes for protocol %d are missing", pointer
+ atr_num_ib_table
[(0xF0 & TDi
) >> 4], pn
+ 1);
80 /* Check TAi is present */
81 if((TDi
| 0xEF) == 0xFF)
84 atr
->ib
[pn
][ATR_INTERFACE_BYTE_TA
].value
= buffer
[pointer
];
85 atr
->ib
[pn
][ATR_INTERFACE_BYTE_TA
].present
= 1;
89 atr
->ib
[pn
][ATR_INTERFACE_BYTE_TA
].present
= 0;
92 /* Check TBi is present */
93 if((TDi
| 0xDF) == 0xFF)
96 atr
->ib
[pn
][ATR_INTERFACE_BYTE_TB
].value
= buffer
[pointer
];
97 atr
->ib
[pn
][ATR_INTERFACE_BYTE_TB
].present
= 1;
101 atr
->ib
[pn
][ATR_INTERFACE_BYTE_TB
].present
= 0;
104 /* Check TCi is present */
105 if((TDi
| 0xBF) == 0xFF)
108 atr
->ib
[pn
][ATR_INTERFACE_BYTE_TC
].value
= buffer
[pointer
];
109 atr
->ib
[pn
][ATR_INTERFACE_BYTE_TC
].present
= 1;
113 atr
->ib
[pn
][ATR_INTERFACE_BYTE_TC
].present
= 0;
116 /* Read TDi if present */
117 if((TDi
| 0x7F) == 0xFF)
120 TDi
= atr
->ib
[pn
][ATR_INTERFACE_BYTE_TD
].value
= buffer
[pointer
];
121 atr
->ib
[pn
][ATR_INTERFACE_BYTE_TD
].present
= 1;
122 (atr
->TCK
).present
= ((TDi
& 0x0F) != ATR_PROTOCOL_TYPE_T0
);
123 if(pn
>= ATR_MAX_PROTOCOLS
)
125 cs_log_dbg(D_ATR
, "ERROR: this ATR reports %d protocols but the maximum value is %d", pn
+ 1, ATR_MAX_PROTOCOLS
+ 1);
132 atr
->ib
[pn
][ATR_INTERFACE_BYTE_TD
].present
= 0;
137 /* Store number of protocols */
140 /* Store historical bytes */
141 if(pointer
+ atr
->hbn
>= length
)
143 cs_log_dbg(D_ATR
, "ERROR: this ATR reports %i historical bytes but there are only %i", atr
->hbn
, length
- pointer
- 2);
144 if(length
- pointer
>= 2)
145 { atr
->hbn
= length
- pointer
- 2; }
149 atr
->length
= pointer
+ 1;
155 memcpy(atr
->hb
, buffer
+ pointer
+ 1, atr
->hbn
);
156 pointer
+= (atr
->hbn
);
159 if((atr
->TCK
).present
)
161 if(pointer
+ 1 >= length
)
163 cs_log_dbg(D_ATR
, "ATR is malformed, this ATR should have a TCK byte but it was not received!");
164 return (ATR_MALFORMED
);
168 (atr
->TCK
).value
= buffer
[pointer
];
171 atr
->length
= pointer
+ 1;
173 // check that TA1, if pn==1 , has a valid value for FI
174 if(atr
->pn
== 1 && atr
->ib
[pn
][ATR_INTERFACE_BYTE_TA
].present
== 1)
177 cs_log_dbg(D_ATR
, "TA1 = %02x", atr
->ib
[pn
][ATR_INTERFACE_BYTE_TA
].value
);
178 FI
= (atr
->ib
[pn
][ATR_INTERFACE_BYTE_TA
].value
& 0xF0) >> 4;
179 cs_log_dbg(D_ATR
, "FI = %02x", FI
);
180 if(atr_fs_table
[FI
] == 0)
182 cs_log_dbg(D_ATR
, "ERROR: this ATR FI for protocol %d is not returning a valid cardfrequency value", pn
+ 1);
187 // check that TB1 < 0x80
188 if(atr
->pn
== 1 && atr
->ib
[pn
][ATR_INTERFACE_BYTE_TB
].present
== 1)
190 if(atr
->ib
[pn
][ATR_INTERFACE_BYTE_TB
].value
> 0x80)
192 cs_log_dbg(D_ATR
, "ERROR: this ATR TB1 for protocol %d has an invalid value", pn
+ 1);
199 int32_t ATR_GetConvention(ATR
*atr
, int32_t *convention
)
201 if(atr
->TS
== 0x3B || atr
->TS
== 0xDB)
202 { (*convention
) = ATR_CONVENTION_DIRECT
; }
203 else if(atr
->TS
== 0x3F)
204 { (*convention
) = ATR_CONVENTION_INVERSE
; }
207 cs_log_dbg(D_ATR
, "ERROR: this ATR TS byte is %02X and that should be 3B for direct or 3F for inverse convention!", atr
->TS
);
214 int32_t ATR_GetSize(ATR
*atr
, uint32_t *size
)
216 (*size
) = atr
->length
;
220 int32_t ATR_GetNumberOfProtocols(ATR
*atr
, uint32_t *number_protocols
)
222 (*number_protocols
) = atr
->pn
;
226 int32_t ATR_GetProtocolType(ATR
*atr
, uint32_t number_protocol
, unsigned char *protocol_type
)
228 if((number_protocol
> atr
->pn
) || number_protocol
< 1)
229 { return ATR_NOT_FOUND
; }
231 if(atr
->ib
[number_protocol
- 1][ATR_INTERFACE_BYTE_TD
].present
)
232 { (*protocol_type
) = (atr
->ib
[number_protocol
- 1][ATR_INTERFACE_BYTE_TD
].value
& 0x0F); }
234 { (*protocol_type
) = ATR_PROTOCOL_TYPE_T0
; }
239 int32_t ATR_GetInterfaceByte(ATR
*atr
, uint32_t number
, int32_t character
, unsigned char *value
)
241 if(number
> atr
->pn
|| number
< 1)
242 { return (ATR_NOT_FOUND
); }
244 if(atr
->ib
[number
- 1][character
].present
&& (character
== ATR_INTERFACE_BYTE_TA
|| character
== ATR_INTERFACE_BYTE_TB
|| character
== ATR_INTERFACE_BYTE_TC
|| character
== ATR_INTERFACE_BYTE_TD
))
245 { (*value
) = atr
->ib
[number
- 1][character
].value
; }
247 { return (ATR_NOT_FOUND
); }
252 int32_t ATR_GetIntegerValue(ATR
*atr
, int32_t name
, unsigned char *value
)
256 if(name
== ATR_INTEGER_VALUE_FI
)
258 if(atr
->ib
[0][ATR_INTERFACE_BYTE_TA
].present
)
260 (*value
) = (atr
->ib
[0][ATR_INTERFACE_BYTE_TA
].value
& 0xF0) >> 4;
268 else if(name
== ATR_INTEGER_VALUE_DI
)
270 if(atr
->ib
[0][ATR_INTERFACE_BYTE_TA
].present
)
272 (*value
) = (atr
->ib
[0][ATR_INTERFACE_BYTE_TA
].value
& 0x0F);
280 else if(name
== ATR_INTEGER_VALUE_II
)
282 if(atr
->ib
[0][ATR_INTERFACE_BYTE_TB
].present
)
284 (*value
) = (atr
->ib
[0][ATR_INTERFACE_BYTE_TB
].value
& 0x60) >> 5;
292 else if(name
== ATR_INTEGER_VALUE_PI1
)
294 if(atr
->ib
[0][ATR_INTERFACE_BYTE_TB
].present
)
296 (*value
) = (atr
->ib
[0][ATR_INTERFACE_BYTE_TB
].value
& 0x1F);
304 else if(name
== ATR_INTEGER_VALUE_PI2
)
306 if(atr
->ib
[1][ATR_INTERFACE_BYTE_TB
].present
)
308 (*value
) = atr
->ib
[1][ATR_INTERFACE_BYTE_TB
].value
;
316 else if(name
== ATR_INTEGER_VALUE_N
)
318 if(atr
->ib
[0][ATR_INTERFACE_BYTE_TC
].present
)
320 (*value
) = atr
->ib
[0][ATR_INTERFACE_BYTE_TC
].value
;
336 int32_t ATR_GetParameter(ATR
*atr
, int32_t name
, uint32_t *parameter
)
338 unsigned char FI
, DI
, II
, PI1
, PI2
, N
;
339 static const uint32_t atr_i_table
[4] = {25, 50, 100, 0};
340 if(name
== ATR_PARAMETER_F
)
342 if(ATR_GetIntegerValue(atr
, ATR_INTEGER_VALUE_FI
, &FI
) != ATR_OK
)
343 { FI
= ATR_DEFAULT_FI
; }
344 (*parameter
) = (double)(atr_f_table
[FI
]);
347 else if(name
== ATR_PARAMETER_D
)
349 if(ATR_GetIntegerValue(atr
, ATR_INTEGER_VALUE_DI
, &DI
) == ATR_OK
)
350 { (*parameter
) = (double)(atr_d_table
[DI
]); }
352 { (*parameter
) = (double) ATR_DEFAULT_D
; }
355 else if(name
== ATR_PARAMETER_I
)
357 if(ATR_GetIntegerValue(atr
, ATR_INTEGER_VALUE_II
, &II
) == ATR_OK
)
358 { (*parameter
) = (double)(atr_i_table
[II
]); }
360 { (*parameter
) = ATR_DEFAULT_I
; }
363 else if(name
== ATR_PARAMETER_P
)
365 if(ATR_GetIntegerValue(atr
, ATR_INTEGER_VALUE_PI2
, &PI2
) == ATR_OK
)
366 { (*parameter
) = (double) PI2
; }
367 else if(ATR_GetIntegerValue(atr
, ATR_INTEGER_VALUE_PI1
, &PI1
) == ATR_OK
)
368 { (*parameter
) = (double) PI1
; }
370 { (*parameter
) = (double) ATR_DEFAULT_P
; }
373 else if(name
== ATR_PARAMETER_N
)
375 if(ATR_GetIntegerValue(atr
, ATR_INTEGER_VALUE_N
, &N
) == ATR_OK
)
376 { (*parameter
) = (double) N
; }
378 { (*parameter
) = (double) ATR_DEFAULT_N
; }
382 return (ATR_NOT_FOUND
);
385 int32_t ATR_GetHistoricalBytes(ATR
*atr
, unsigned char *hist
, uint32_t *length
)
388 { return (ATR_NOT_FOUND
); }
390 (*length
) = atr
->hbn
;
391 memcpy(hist
, atr
->hb
, atr
->hbn
);
395 int32_t ATR_GetRaw(ATR
*atr
, unsigned char *buffer
, uint32_t *length
)
404 for(i
= 0; i
< atr
->pn
; i
++)
406 if(atr
->ib
[i
][ATR_INTERFACE_BYTE_TA
].present
)
407 { buffer
[j
++] = atr
->ib
[i
][ATR_INTERFACE_BYTE_TA
].value
; }
409 if(atr
->ib
[i
][ATR_INTERFACE_BYTE_TB
].present
)
410 { buffer
[j
++] = atr
->ib
[i
][ATR_INTERFACE_BYTE_TB
].value
; }
412 if(atr
->ib
[i
][ATR_INTERFACE_BYTE_TC
].present
)
413 { buffer
[j
++] = atr
->ib
[i
][ATR_INTERFACE_BYTE_TC
].value
; }
415 if(atr
->ib
[i
][ATR_INTERFACE_BYTE_TD
].present
)
416 { buffer
[j
++] = atr
->ib
[i
][ATR_INTERFACE_BYTE_TD
].value
; }
421 memcpy(&(buffer
[j
]), atr
->hb
, atr
->hbn
);
425 if((atr
->TCK
).present
)
426 { buffer
[j
++] = (atr
->TCK
).value
; }
433 int32_t ATR_GetCheckByte(ATR
*atr
, unsigned char *check_byte
)
435 if(!((atr
->TCK
).present
))
436 { return (ATR_NOT_FOUND
); }
438 (*check_byte
) = (atr
->TCK
).value
;
442 int32_t ATR_GetFsMax(ATR
*atr
, uint32_t *fsmax
)
446 if(ATR_GetIntegerValue(atr
, ATR_INTEGER_VALUE_FI
, &FI
) == ATR_OK
)
447 { (*fsmax
) = atr_fs_table
[FI
]; }
449 { (*fsmax
) = atr_fs_table
[1]; }