source: trunk/csctapi/atr.c@ 1137

Last change on this file since 1137 was 1137, checked in by C.H.A.D.o, 12 years ago

Fix compiler warnings
Add Wextra flag

File size: 13.2 KB
Line 
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 version is modified by doz21 to work in a special manner ;)
9
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.
14
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.
19
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
23*/
24
25#include "defines.h"
26#include "atr.h"
27#include <stdlib.h>
28#include <string.h>
29
30/*
31 * Not exported variables definition
32 */
33
34unsigned long atr_fs_table[16] = {4000000L, 5000000L, 6000000L, 8000000L, 12000000L, 16000000L, 20000000L, 0, 0, 5000000L, 7500000L, 10000000L, 15000000L, 20000000L, 0, 0};
35
36static unsigned atr_num_ib_table[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
37
38/*
39 * Exported variables definition
40 */
41
42unsigned atr_f_table[16] = {372, 372, 558, 744, 1116, 1488, 1860, 0, 0, 512, 768, 1024, 1536, 2048, 0, 0};
43
44double atr_d_table[16] = {0, 1, 2, 4, 8, 16, 32, 64, 12, 20, 0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625};
45//old table has 0 for RFU:
46//double atr_d_table[16] = {0, 1, 2, 4, 8, 16, 0, 0, 0, 0, 0.5, 0.25, 125, 0.0625, 0.03125, 0.015625};
47
48unsigned atr_i_table[4] = {25, 50, 100, 0};
49
50/*
51 * Not exported functions declaration
52 */
53
54static bool ATR_GetNextByte (IO_Serial * io, unsigned timeout, BYTE * b, bool invert);
55
56/*
57 * Exported funcions definition
58 */
59
60ATR * ATR_New (void)
61{
62 ATR *atr;
63
64 /* Allocate memory */
65 atr = (ATR *) malloc (sizeof (ATR));
66
67 return atr;
68}
69
70int ATR_InitFromArray (ATR * atr, BYTE atr_buffer[ATR_MAX_SIZE], unsigned length)
71{
72 BYTE TDi;
73 BYTE buffer[ATR_MAX_SIZE];
74 unsigned pointer = 0, pn = 0;
75
76 /* Check size of buffer */
77 if (length < 2)
78 return (ATR_MALFORMED);
79
80 /* Check if ATR is from a inverse convention card */
81 if (atr_buffer[0] == 0x03)
82 {
83 for (pointer = 0; pointer < length; pointer++)
84 buffer[pointer] = ~(INVERT_BYTE (atr_buffer[pointer]));
85 }
86 else
87 {
88 memcpy (buffer, atr_buffer, length);
89 }
90
91 /* Store T0 and TS */
92 atr->TS = buffer[0];
93
94 atr->T0 = TDi = buffer[1];
95 pointer = 1;
96
97 /* Store number of historical bytes */
98 atr->hbn = TDi & 0x0F;
99
100 /* TCK is not present by default */
101 (atr->TCK).present = FALSE;
102
103 /* Extract interface bytes */
104 while (pointer < length)
105 {
106 /* Check buffer is long enought */
107 if (pointer + atr_num_ib_table[(0xF0 & TDi) >> 4] >= length)
108 {
109 return (ATR_MALFORMED);
110 }
111
112 /* Check TAi is present */
113 if ((TDi | 0xEF) == 0xFF)
114 {
115 pointer++;
116 atr->ib[pn][ATR_INTERFACE_BYTE_TA].value = buffer[pointer];
117 atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = TRUE;
118 }
119 else
120 {
121 atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = FALSE;
122 }
123
124 /* Check TBi is present */
125 if ((TDi | 0xDF) == 0xFF)
126 {
127 pointer++;
128 atr->ib[pn][ATR_INTERFACE_BYTE_TB].value = buffer[pointer];
129 atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = TRUE;
130 }
131 else
132 {
133 atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = FALSE;
134 }
135
136 /* Check TCi is present */
137 if ((TDi | 0xBF) == 0xFF)
138 {
139 pointer++;
140 atr->ib[pn][ATR_INTERFACE_BYTE_TC].value = buffer[pointer];
141 atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = TRUE;
142 }
143 else
144 {
145 atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = FALSE;
146 }
147
148 /* Read TDi if present */
149 if ((TDi | 0x7F) == 0xFF)
150 {
151 pointer++;
152 TDi = atr->ib[pn][ATR_INTERFACE_BYTE_TD].value = buffer[pointer];
153 atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = TRUE;
154 (atr->TCK).present = ((TDi & 0x0F) != ATR_PROTOCOL_TYPE_T0);
155 if ((TDi & 0xF0) == 0) //last TDi byte
156 break;
157 if (pn >= ATR_MAX_PROTOCOLS)
158 return (ATR_MALFORMED);
159 pn++;
160 }
161 else
162 {
163 atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = FALSE;
164 break;
165 }
166 }
167
168 /* Store number of protocols */
169 atr->pn = pn + 1;
170
171 /* Store historical bytes */
172 if (pointer + atr->hbn >= length) {
173 cs_log("ATR is malformed, it reports %i historical bytes but there are only %i",atr->hbn, length-pointer-2);
174 if (length-pointer >= 2)
175 atr->hbn = length-pointer-2;
176 else {
177 atr->hbn = 0;
178 atr->length = pointer + 1;
179 return (ATR_MALFORMED);
180 }
181
182 }
183
184 memcpy (atr->hb, buffer + pointer + 1, atr->hbn);
185 pointer += (atr->hbn);
186
187 /* Store TCK */
188 if ((atr->TCK).present)
189 {
190 if (pointer + 1 >= length)
191 return (ATR_MALFORMED);
192
193 pointer++;
194
195 (atr->TCK).value = buffer[pointer];
196 }
197
198 atr->length = pointer + 1;
199 return (ATR_OK);
200}
201
202int ATR_InitFromStream (ATR * atr, IO_Serial * io, unsigned timeout)
203{
204 BYTE TDi;
205 unsigned pointer = 0, pn = 0, i;
206 bool invert;
207
208 invert = FALSE;
209
210 /* Store T0 and TS */
211 if (!ATR_GetNextByte (io, timeout, &(atr->TS), invert))
212 return ATR_IO_ERROR;
213
214 if (atr->TS == 0x03)
215 {
216 atr->TS = 0x3F;
217 invert = TRUE;
218 }
219
220 if ((atr->TS != 0x3B) && (atr->TS != 0x3F))
221 return ATR_MALFORMED;
222
223 if (!ATR_GetNextByte (io, timeout, &(atr->T0), invert))
224 return ATR_MALFORMED;
225
226 TDi = atr->T0;
227 pointer = 1;
228
229 /* Store number of historical bytes */
230 atr->hbn = TDi & 0x0F;
231
232 /* TCK is not present by default */
233 (atr->TCK).present = FALSE;
234
235 /* Extract interface bytes */
236 while (TRUE)
237 {
238 /* Check TAi is present */
239 if ((TDi | 0xEF) == 0xFF)
240 {
241 pointer++;
242 if (!ATR_GetNextByte(io, timeout, &(atr->ib[pn][ATR_INTERFACE_BYTE_TA].value),invert))
243 return ATR_MALFORMED;
244 atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = TRUE;
245 }
246 else
247 {
248 atr->ib[pn][ATR_INTERFACE_BYTE_TA].present = FALSE;
249 }
250
251 /* Check TBi is present */
252 if ((TDi | 0xDF) == 0xFF)
253 {
254 pointer++;
255 if (!ATR_GetNextByte(io, timeout, &(atr->ib[pn][ATR_INTERFACE_BYTE_TB].value),invert))
256 return ATR_MALFORMED;
257 atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = TRUE;
258 }
259 else
260 {
261 atr->ib[pn][ATR_INTERFACE_BYTE_TB].present = FALSE;
262 }
263
264 /* Check TCi is present */
265 if ((TDi | 0xBF) == 0xFF)
266 {
267 pointer++;
268 if (!ATR_GetNextByte(io, timeout, &(atr->ib[pn][ATR_INTERFACE_BYTE_TC].value), invert))
269 return ATR_MALFORMED;
270 atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = TRUE;
271 }
272 else
273 {
274 atr->ib[pn][ATR_INTERFACE_BYTE_TC].present = FALSE;
275 }
276
277 /* Read TDi if present */
278 if ((TDi | 0x7F) == 0xFF)
279 {
280 pointer++;
281 if (!ATR_GetNextByte(io, timeout, &(atr->ib[pn][ATR_INTERFACE_BYTE_TD].value), invert))
282 return ATR_MALFORMED;
283 TDi = atr->ib[pn][ATR_INTERFACE_BYTE_TD].value;
284 atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = TRUE;
285 (atr->TCK).present = ((TDi & 0x0F) != ATR_PROTOCOL_TYPE_T0);
286 if ((TDi & 0xF0) == 0) //last TDi byte
287 break;
288 if (pn >= ATR_MAX_PROTOCOLS)
289 return (ATR_MALFORMED);
290 pn++;
291 }
292 else
293 {
294 atr->ib[pn][ATR_INTERFACE_BYTE_TD].present = FALSE;
295 break;
296 }
297 }
298
299 /* Store number of protocols */
300 atr->pn = pn + 1;
301
302 /* Store historical bytes */
303 for (i = 0; i < (atr->hbn); i++)
304 {
305 if (!ATR_GetNextByte (io, timeout, &(atr->hb[i]), invert))
306 return ATR_MALFORMED;
307 }
308
309 pointer += (atr->hbn);
310
311 /* Store TCK */
312 if ((atr->TCK).present)
313 {
314 pointer++;
315
316 if (!ATR_GetNextByte (io, timeout, (&((atr->TCK).value)), invert))
317 return ATR_MALFORMED;
318 }
319
320 atr->length = pointer + 1;
321 return (ATR_OK);
322
323}
324
325void ATR_Delete (ATR * atr)
326{
327 free (atr);
328}
329
330int ATR_GetConvention (ATR * atr, int *convention)
331{
332 if (atr->TS == 0x3B)
333 (*convention) = ATR_CONVENTION_DIRECT;
334 else if (atr->TS == 0x3F)
335 (*convention) = ATR_CONVENTION_INVERSE;
336 else
337 return (ATR_MALFORMED);
338
339 return (ATR_OK);
340}
341
342int ATR_GetSize (ATR * atr, unsigned *size)
343{
344 (*size) = atr->length;
345 return (ATR_OK);
346}
347
348int ATR_GetNumberOfProtocols (ATR * atr, unsigned *number_protocols)
349{
350 (*number_protocols) = atr->pn;
351 return (ATR_OK);
352}
353
354int ATR_GetProtocolType (ATR * atr, unsigned number_protocol, BYTE *protocol_type)
355{
356 if ((number_protocol > atr->pn) || number_protocol < 1)
357 return ATR_NOT_FOUND;
358
359 if (atr->ib[number_protocol - 1][ATR_INTERFACE_BYTE_TD].present)
360 (*protocol_type) = (atr->ib[number_protocol - 1][ATR_INTERFACE_BYTE_TD].value & 0x0F);
361 else
362 (*protocol_type) = ATR_PROTOCOL_TYPE_T0;
363
364 return (ATR_OK);
365}
366
367int ATR_GetInterfaceByte (ATR * atr, unsigned number, int character, BYTE * value)
368{
369 if (number > atr->pn || number < 1)
370 return (ATR_NOT_FOUND);
371
372 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))
373 (*value) = atr->ib[number - 1][character].value;
374 else
375 return (ATR_NOT_FOUND);
376
377 return (ATR_OK);
378}
379
380int ATR_GetIntegerValue (ATR * atr, int name, BYTE * value)
381{
382 int ret;
383
384 if (name == ATR_INTEGER_VALUE_FI)
385 {
386 if (atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
387 {
388 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TA].value & 0xF0) >> 4;
389 ret = ATR_OK;
390 }
391 else
392 {
393 ret = ATR_NOT_FOUND;
394 }
395 }
396 else if (name == ATR_INTEGER_VALUE_DI)
397 {
398 if (atr->ib[0][ATR_INTERFACE_BYTE_TA].present)
399 {
400 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TA].value & 0x0F);
401 ret = ATR_OK;
402 }
403 else
404 {
405 ret = ATR_NOT_FOUND;
406 }
407 }
408 else if (name == ATR_INTEGER_VALUE_II)
409 {
410 if (atr->ib[0][ATR_INTERFACE_BYTE_TB].present)
411 {
412 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TB].value & 0x60) >> 5;
413 ret = ATR_OK;
414 }
415 else
416 {
417 ret = ATR_NOT_FOUND;
418 }
419 }
420 else if (name == ATR_INTEGER_VALUE_PI1)
421 {
422 if (atr->ib[0][ATR_INTERFACE_BYTE_TB].present)
423 {
424 (*value) = (atr->ib[0][ATR_INTERFACE_BYTE_TB].value & 0x1F);
425 ret = ATR_OK;
426 }
427 else
428 {
429 ret = ATR_NOT_FOUND;
430 }
431 }
432 else if (name == ATR_INTEGER_VALUE_PI2)
433 {
434 if (atr->ib[1][ATR_INTERFACE_BYTE_TB].present)
435 {
436 (*value) = atr->ib[1][ATR_INTERFACE_BYTE_TB].value;
437 ret = ATR_OK;
438 }
439 else
440 {
441 ret = ATR_NOT_FOUND;
442 }
443 }
444 else if (name == ATR_INTEGER_VALUE_N)
445 {
446 if (atr->ib[0][ATR_INTERFACE_BYTE_TC].present)
447 {
448 (*value) = atr->ib[0][ATR_INTERFACE_BYTE_TC].value;
449 ret = ATR_OK;
450 }
451 else
452 {
453 ret = ATR_NOT_FOUND;
454 }
455 }
456 else
457 {
458 ret = ATR_NOT_FOUND;
459 }
460
461 return ret;
462}
463
464int ATR_GetParameter (ATR * atr, int name, double *parameter)
465{
466 BYTE FI, DI, II, PI1, PI2, N;
467
468 if (name == ATR_PARAMETER_F)
469 {
470 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_FI, &FI) != ATR_OK)
471 FI = ATR_DEFAULT_FI;
472 (*parameter) = (double) (atr_f_table[FI]);
473 return (ATR_OK);
474 }
475 else if (name == ATR_PARAMETER_D)
476 {
477 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_DI, &DI) == ATR_OK)
478 (*parameter) = (double) (atr_d_table[DI]);
479 else
480 (*parameter) = (double) ATR_DEFAULT_D;
481 return (ATR_OK);
482 }
483 else if (name == ATR_PARAMETER_I)
484 {
485 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_II, &II) == ATR_OK)
486 (*parameter) = (double) (atr_i_table[II]);
487 else
488 (*parameter) = ATR_DEFAULT_I;
489 return (ATR_OK);
490 }
491 else if (name == ATR_PARAMETER_P)
492 {
493 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_PI2, &PI2) == ATR_OK)
494 (*parameter) = (double) PI2;
495 else if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_PI1, &PI1) == ATR_OK)
496 (*parameter) = (double) PI1;
497 else
498 (*parameter) = (double) ATR_DEFAULT_P;
499 return (ATR_OK);
500 }
501 else if (name == ATR_PARAMETER_N)
502 {
503 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_N, &N) == ATR_OK)
504 (*parameter) = (double) N;
505 else
506 (*parameter) = (double) ATR_DEFAULT_N;
507 return (ATR_OK);
508 }
509
510 return (ATR_NOT_FOUND);
511}
512
513int ATR_GetHistoricalBytes (ATR * atr, BYTE hist[ATR_MAX_HISTORICAL], unsigned *length)
514{
515 if (atr->hbn == 0)
516 return (ATR_NOT_FOUND);
517
518 (*length) = atr->hbn;
519 memcpy (hist, atr->hb, atr->hbn);
520 return (ATR_OK);
521}
522
523int ATR_GetRaw (ATR * atr, BYTE buffer[ATR_MAX_SIZE], unsigned *length)
524{
525 unsigned i, j;
526
527 buffer[0] = atr->TS;
528 buffer[1] = atr->T0;
529
530 j = 2;
531
532 for (i = 0; i < atr->pn; i++)
533 {
534 if (atr->ib[i][ATR_INTERFACE_BYTE_TA].present)
535 buffer[j++] = atr->ib[i][ATR_INTERFACE_BYTE_TA].value;
536
537 if (atr->ib[i][ATR_INTERFACE_BYTE_TB].present)
538 buffer[j++] = atr->ib[i][ATR_INTERFACE_BYTE_TB].value;
539
540 if (atr->ib[i][ATR_INTERFACE_BYTE_TC].present)
541 buffer[j++] = atr->ib[i][ATR_INTERFACE_BYTE_TC].value;
542
543 if (atr->ib[i][ATR_INTERFACE_BYTE_TD].present)
544 buffer[j++] = atr->ib[i][ATR_INTERFACE_BYTE_TD].value;
545 }
546
547 if (atr->hbn > 0)
548 {
549 memcpy (&(buffer[j]), atr->hb, atr->hbn);
550 j += atr->hbn;
551 }
552
553 if ((atr->TCK).present)
554 buffer[j++] = (atr->TCK).value;
555
556 (*length) = j;
557
558 return ATR_OK;
559}
560
561int ATR_GetCheckByte (ATR * atr, BYTE * check_byte)
562{
563 if (!((atr->TCK).present))
564 return (ATR_NOT_FOUND);
565
566 (*check_byte) = (atr->TCK).value;
567 return (ATR_OK);
568}
569
570int ATR_GetFsMax (ATR * atr, unsigned long *fsmax)
571{
572 BYTE FI;
573
574 if (ATR_GetIntegerValue (atr, ATR_INTEGER_VALUE_FI, &FI) == ATR_OK)
575 (*fsmax) = atr_fs_table[FI];
576 else
577 (*fsmax) = atr_fs_table[1];
578
579 return (ATR_OK);
580}
581
582/*
583 * Not exported functions definition
584 */
585
586static bool ATR_GetNextByte (IO_Serial * io, unsigned timeout, BYTE * byte, bool invert)
587{
588 bool ret;
589 ret = IO_Serial_Read (io, timeout, 1, byte);
590 /* Para tarjetas inversas quiza */
591 if (invert)
592 (*byte) = ~(INVERT_BYTE (*byte));
593
594 return ret;
595}
Note: See TracBrowser for help on using the repository browser.