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 library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with this library; if not, write to the Free Software Foundation,
20 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
32 * Not exported variables definition
36 atr_num_ib_table[16] =
38 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
42 * Exported variables definition
48 372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768, 1024, 1536, 2048, 0, 0
54 0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0, 0, 0, 0, 0, 0
64 * Exported functions definition
68 ATR_InitFromArray (ATR_t * atr, const BYTE atr_buffer[ATR_MAX_SIZE], unsigned length)
71 unsigned pointer = 0, pn = 0;
73 /* Check size of buffer */
75 return (ATR_MALFORMED);
78 atr->TS = atr_buffer[0];
80 atr->T0 = TDi = atr_buffer[1];
83 /* Store number of historical bytes */
84 atr->hbn = TDi & 0x0F;
86 /* TCK is not present by default */
87 (atr->TCK).present = FALSE;
89 /* Extract interface bytes */
90 while (pointer < length)
92 /* Check buffer is long enought */
93 if (pointer + atr_num_ib_table[(0xF0 & TDi) >> 4] >= length)
95 return (ATR_MALFORMED);
97 /* Check TAi is present */
98 if ((TDi | 0xEF) == 0xFF)
101 atr->ib[pn][ATR_INTERFACE_BYTE_TA].value = atr_buffer[pointer];
102 atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = TRUE;
105 atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = FALSE;
106 /* Check TBi is present */
107 if ((TDi | 0xDF) == 0xFF)
110 atr->ib[pn][ATR_INTERFACE_BYTE_TB].value = atr_buffer[pointer];
111 atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = TRUE;
114 atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = FALSE;
116 /* Check TCi is present */
117 if ((TDi | 0xBF) == 0xFF)
120 atr->ib[pn][ATR_INTERFACE_BYTE_TC].value = atr_buffer[pointer];
121 atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = TRUE;
124 atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = FALSE;
126 /* Read TDi if present */
127 if ((TDi | 0x7F) == 0xFF)
130 TDi = atr->ib[pn][ATR_INTERFACE_BYTE_TD].value = atr_buffer[pointer];
131 atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = TRUE;
132 (atr->TCK).present = ((TDi & 0x0F) != ATR_PROTOCOL_TYPE_T0);
134 if (pn >= ATR_MAX_PROTOCOLS)
135 return (ATR_MALFORMED);
139 atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = FALSE;
144 /* Store number of protocols */
147 /* Store historical bytes */
148 if (pointer + atr->hbn >= length)
149 return (ATR_MALFORMED);
151 memcpy (atr->hb, atr_buffer + pointer + 1, atr->hbn);
152 pointer += (atr->hbn);
155 if ((atr->TCK).present)
158 if (pointer + 1 >= length)
159 return (ATR_MALFORMED);
163 (atr->TCK).value = atr_buffer[pointer];
166 atr->length = pointer + 1;
171 ATR_GetConvention (ATR_t * atr, int *convention)
174 (*convention) = ATR_CONVENTION_DIRECT;
175 else if (atr->TS == 0x3F)
176 (*convention) = ATR_CONVENTION_INVERSE;
178 return (ATR_MALFORMED);
183 ATR_GetIntegerValue (ATR_t * atr, int name, BYTE * value)
187 if (name == ATR_INTEGER_VALUE_FI)
189 if (atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
191 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TA].value & 0xF0) >> 4;
198 else if (name == ATR_INTEGER_VALUE_DI)
200 if (atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
202 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TA].value & 0x0F);
209 else if (name == ATR_INTEGER_VALUE_II)
211 if (atr->ib[0][ATR_INTERFACE_BYTE_TB].present)
213 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TB].value & 0x60) >> 5;
220 else if (name == ATR_INTEGER_VALUE_PI1)
222 if (atr->ib[0][ATR_INTERFACE_BYTE_TB].present)
224 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TB].value & 0x1F);
231 else if (name == ATR_INTEGER_VALUE_PI2)
233 if (atr->ib[1][ATR_INTERFACE_BYTE_TB].present)
235 (*value) = atr->ib[1][ATR_INTERFACE_BYTE_TB].value;
242 else if (name == ATR_INTEGER_VALUE_N)
244 if (atr->ib[0][ATR_INTERFACE_BYTE_TC].present)
246 (*value) = atr->ib[0][ATR_INTERFACE_BYTE_TC].value;
259 ATR_GetParameter (ATR_t * atr, int name, double *parameter)
261 BYTE FI, DI, II, PI1, PI2, N;
263 if (name == ATR_PARAMETER_F)
265 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_FI, &FI) == ATR_OK)
266 (*parameter) = (double) (atr_f_table[FI]);
268 (*parameter) = (double) ATR_DEFAULT_F;
272 else if (name == ATR_PARAMETER_D)
274 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_DI, &DI) == ATR_OK)
275 (*parameter) = (double) (atr_d_table[DI]);
277 (*parameter) = (double) ATR_DEFAULT_D;
281 else if (name == ATR_PARAMETER_I)
283 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_II, &II) == ATR_OK)
284 (*parameter) = (double) (atr_i_table[II]);
286 (*parameter) = ATR_DEFAULT_I;
290 else if (name == ATR_PARAMETER_P)
292 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_PI2, &PI2) == ATR_OK)
293 (*parameter) = (double) PI2;
294 else if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_PI1, &PI1) == ATR_OK)
295 (*parameter) = (double) PI1;
297 (*parameter) = (double) ATR_DEFAULT_P;
301 else if (name == ATR_PARAMETER_N)
303 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_N, &N) == ATR_OK)
304 (*parameter) = (double) N;
306 (*parameter) = (double) ATR_DEFAULT_N;
310 return (ATR_NOT_FOUND);
314 * This function was greatly inspired by ATRDecodeAtr() and
315 * PHGetDefaultProtocol() from pcsc-lite
317 * It was rewritten by Ludovic Rousseau, 2004
319 #define PROTOCOL_UNSET -1
320 int ATR_GetDefaultProtocol(ATR_t * atr, int *protocol, int *availableProtocols)
325 *protocol = PROTOCOL_UNSET;
326 if (availableProtocols)
327 *availableProtocols = 0;
329 for (i=0; i<ATR_MAX_PROTOCOLS; i++)
330 if (atr->ib[i][ATR_INTERFACE_BYTE_TD].present)
332 int T = atr->ib[i][ATR_INTERFACE_BYTE_TD].value & 0x0F;
334 DEBUG_COMM2("T=%d Protocol Found", T);
335 if (availableProtocols)
336 *availableProtocols |= 1 << T;
338 if (PROTOCOL_UNSET == *protocol)
340 /* set to the first protocol byte found */
342 DEBUG_COMM2("default protocol: T=%d", *protocol);
346 /* specific mode if TA2 present */
347 if (atr->ib[1][ATR_INTERFACE_BYTE_TA].present)
349 *protocol = atr->ib[1][ATR_INTERFACE_BYTE_TA].value & 0x0F;
350 if (availableProtocols)
351 *availableProtocols = 1 << *protocol;
352 DEBUG_COMM2("specific mode found: T=%d", *protocol);
355 if (PROTOCOL_UNSET == *protocol)
357 DEBUG_INFO1("no default protocol found in ATR. Using T=0");
358 *protocol = ATR_PROTOCOL_TYPE_T0;
359 if (availableProtocols)
360 *availableProtocols = 1 << *protocol;