Initial commit
[platform/upstream/ccid.git] / src / towitoko / atr.c
1 /*
2     atr.c
3     ISO 7816 ICC's answer to reset abstract data type implementation
4
5     This file is part of the Unix driver for Towitoko smartcard readers
6     Copyright (C) 2000 Carlos Prados <cprados@yahoo.com>
7
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.
12
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.
17
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.
21 */
22
23 #include <config.h>
24
25 #include "atr.h"
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #endif
29 #include "debug.h"
30
31 /*
32  * Not exported variables definition
33  */
34
35 static unsigned
36 atr_num_ib_table[16] =
37 {
38   0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4
39 };
40
41 /*
42  * Exported variables definition
43  */
44
45 static unsigned
46 atr_f_table[16] =
47 {
48   372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768, 1024, 1536, 2048, 0, 0
49 };
50
51 static unsigned
52 atr_d_table[16] =
53 {
54   0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0, 0, 0, 0, 0, 0
55 };
56
57 static unsigned
58 atr_i_table[4] =
59 {
60   25, 50, 100, 0
61 };
62
63 /*
64  * Exported functions definition
65  */
66
67 int
68 ATR_InitFromArray (ATR_t * atr, const BYTE atr_buffer[ATR_MAX_SIZE], unsigned length)
69 {
70   BYTE TDi;
71   unsigned pointer = 0, pn = 0;
72
73   /* Check size of buffer */
74   if (length < 2)
75     return (ATR_MALFORMED);
76
77   /* Store T0 and TS */
78   atr->TS = atr_buffer[0];
79
80   atr->T0 = TDi = atr_buffer[1];
81   pointer = 1;
82
83   /* Store number of historical bytes */
84   atr->hbn = TDi & 0x0F;
85
86   /* TCK is not present by default */
87   (atr->TCK).present = FALSE;
88
89   /* Extract interface bytes */
90   while (pointer < length)
91     {
92       /* Check buffer is long enought */
93       if (pointer + atr_num_ib_table[(0xF0 & TDi) >> 4] >= length)
94         {
95           return (ATR_MALFORMED);
96         }
97       /* Check TAi is present */
98       if ((TDi | 0xEF) == 0xFF)
99         {
100           pointer++;
101           atr->ib[pn][ATR_INTERFACE_BYTE_TA].value = atr_buffer[pointer];
102           atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = TRUE;
103         }
104       else
105         atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = FALSE;
106       /* Check TBi is present */
107       if ((TDi | 0xDF) == 0xFF)
108         {
109           pointer++;
110           atr->ib[pn][ATR_INTERFACE_BYTE_TB].value = atr_buffer[pointer];
111           atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = TRUE;
112         }
113       else
114         atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = FALSE;
115
116       /* Check TCi is present */
117       if ((TDi | 0xBF) == 0xFF)
118         {
119           pointer++;
120           atr->ib[pn][ATR_INTERFACE_BYTE_TC].value = atr_buffer[pointer];
121           atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = TRUE;
122         }
123       else
124         atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = FALSE;
125
126       /* Read TDi if present */
127       if ((TDi | 0x7F) == 0xFF)
128         {
129           pointer++;
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);
133           pn++;
134           if (pn >= ATR_MAX_PROTOCOLS)
135             return (ATR_MALFORMED);
136         }
137       else
138         {
139           atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = FALSE;
140           break;
141         }
142     }
143
144   /* Store number of protocols */
145   atr->pn = pn + 1;
146
147   /* Store historical bytes */
148   if (pointer + atr->hbn >= length)
149     return (ATR_MALFORMED);
150
151   memcpy (atr->hb, atr_buffer + pointer + 1, atr->hbn);
152   pointer += (atr->hbn);
153
154   /* Store TCK  */
155   if ((atr->TCK).present)
156     {
157
158       if (pointer + 1 >= length)
159         return (ATR_MALFORMED);
160
161       pointer++;
162
163       (atr->TCK).value = atr_buffer[pointer];
164     }
165
166   atr->length = pointer + 1;
167   return (ATR_OK);
168 }
169
170 int
171 ATR_GetConvention (ATR_t * atr, int *convention)
172 {
173   if (atr->TS == 0x3B)
174     (*convention) = ATR_CONVENTION_DIRECT;
175   else if (atr->TS == 0x3F)
176     (*convention) = ATR_CONVENTION_INVERSE;
177   else
178     return (ATR_MALFORMED);
179   return (ATR_OK);
180 }
181
182 int
183 ATR_GetIntegerValue (ATR_t * atr, int name, BYTE * value)
184 {
185   int ret;
186
187   if (name == ATR_INTEGER_VALUE_FI)
188     {
189       if (atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
190         {
191           (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TA].value & 0xF0) >> 4;
192           ret = ATR_OK;
193         }
194       else
195         ret = ATR_NOT_FOUND;
196     }
197
198   else if (name == ATR_INTEGER_VALUE_DI)
199     {
200       if (atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
201         {
202           (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TA].value & 0x0F);
203           ret = ATR_OK;
204         }
205       else
206         ret = ATR_NOT_FOUND;
207     }
208
209   else if (name == ATR_INTEGER_VALUE_II)
210     {
211       if (atr->ib[0][ATR_INTERFACE_BYTE_TB].present)
212         {
213           (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TB].value & 0x60) >> 5;
214           ret = ATR_OK;
215         }
216       else
217         ret = ATR_NOT_FOUND;
218     }
219
220   else if (name == ATR_INTEGER_VALUE_PI1)
221     {
222       if (atr->ib[0][ATR_INTERFACE_BYTE_TB].present)
223         {
224           (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TB].value & 0x1F);
225           ret = ATR_OK;
226         }
227       else
228         ret = ATR_NOT_FOUND;
229     }
230
231   else if (name == ATR_INTEGER_VALUE_PI2)
232     {
233       if (atr->ib[1][ATR_INTERFACE_BYTE_TB].present)
234         {
235           (*value) = atr->ib[1][ATR_INTERFACE_BYTE_TB].value;
236           ret = ATR_OK;
237         }
238       else
239         ret = ATR_NOT_FOUND;
240     }
241
242   else if (name == ATR_INTEGER_VALUE_N)
243     {
244       if (atr->ib[0][ATR_INTERFACE_BYTE_TC].present)
245         {
246           (*value) = atr->ib[0][ATR_INTERFACE_BYTE_TC].value;
247           ret = ATR_OK;
248         }
249       else
250         ret = ATR_NOT_FOUND;
251     }
252   else
253     ret = ATR_NOT_FOUND;
254
255   return ret;
256 }
257
258 int
259 ATR_GetParameter (ATR_t * atr, int name, double *parameter)
260 {
261   BYTE FI, DI, II, PI1, PI2, N;
262
263   if (name == ATR_PARAMETER_F)
264     {
265       if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_FI, &FI) == ATR_OK)
266         (*parameter) = (double) (atr_f_table[FI]);
267       else
268         (*parameter) = (double) ATR_DEFAULT_F;
269       return (ATR_OK);
270     }
271
272   else if (name == ATR_PARAMETER_D)
273     {
274       if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_DI, &DI) == ATR_OK)
275         (*parameter) = (double) (atr_d_table[DI]);
276       else
277         (*parameter) = (double) ATR_DEFAULT_D;
278       return (ATR_OK);
279     }
280
281   else if (name == ATR_PARAMETER_I)
282     {
283       if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_II, &II) == ATR_OK)
284         (*parameter) = (double) (atr_i_table[II]);
285       else
286         (*parameter) = ATR_DEFAULT_I;
287       return (ATR_OK);
288     }
289
290   else if (name == ATR_PARAMETER_P)
291     {
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;
296       else
297         (*parameter) = (double) ATR_DEFAULT_P;
298       return (ATR_OK);
299     }
300
301   else if (name == ATR_PARAMETER_N)
302     {
303       if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_N, &N) == ATR_OK)
304         (*parameter) = (double) N;
305       else
306         (*parameter) = (double) ATR_DEFAULT_N;
307       return (ATR_OK);
308     }
309
310   return (ATR_NOT_FOUND);
311 }
312
313 /*
314  * This function was greatly inspired by ATRDecodeAtr() and
315  * PHGetDefaultProtocol() from pcsc-lite
316  *
317  * It was rewritten by Ludovic Rousseau, 2004
318  */
319 #define PROTOCOL_UNSET -1
320 int ATR_GetDefaultProtocol(ATR_t * atr, int *protocol, int *availableProtocols)
321 {
322         int i;
323
324         /* default value */
325         *protocol = PROTOCOL_UNSET;
326         if (availableProtocols)
327                 *availableProtocols = 0;
328
329         for (i=0; i<ATR_MAX_PROTOCOLS; i++)
330                 if (atr->ib[i][ATR_INTERFACE_BYTE_TD].present)
331                 {
332                         int T = atr->ib[i][ATR_INTERFACE_BYTE_TD].value & 0x0F;
333
334                         DEBUG_COMM2("T=%d Protocol Found", T);
335                         if (availableProtocols)
336                                 *availableProtocols |= 1 << T;
337
338                         if (PROTOCOL_UNSET == *protocol)
339                         {
340                                 /* set to the first protocol byte found */
341                                 *protocol = T;
342                                 DEBUG_COMM2("default protocol: T=%d", *protocol);
343                         }
344                 }
345
346         /* specific mode if TA2 present */
347         if (atr->ib[1][ATR_INTERFACE_BYTE_TA].present)
348         {
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);
353         }
354
355         if (PROTOCOL_UNSET == *protocol)
356         {
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;
361         }
362
363         return ATR_OK;
364 }
365