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