1
/* atr.c - ISO 7816 ATR fucntions
2
* Copyright (C) 2003 Free Software Foundation, Inc.
4
* This file is part of GnuPG.
6
* GnuPG is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* GnuPG is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
33
static int const fi_table[16] = { 0, 372, 558, 744, 1116,1488, 1860, -1,
34
-1, 512, 768, 1024, 1536, 2048, -1, -1 };
35
static int const di_table[16] = { -1, 1, 2, 4, 8, 16, -1, -1,
36
0, -1, -2, -4, -8, -16, -32, -64};
39
/* Dump the ATR of the card at SLOT in a human readable format to
42
atr_dump (int slot, FILE *fp)
44
unsigned char *atrbuffer, *atr;
46
int have_ta, have_tb, have_tc, have_td;
51
atr = atrbuffer = apdu_get_atr (slot, &atrlen);
53
return gpg_error (GPG_ERR_GENERAL);
55
fprintf (fp, "Info on ATR of length %u at slot %d\n",
56
(unsigned int)atrlen, slot);
59
fprintf (fp, "error: empty ATR\n");
65
fputs ("direct convention\n", fp);
66
else if (*atr == 0x3f)
67
fputs ("inverse convention\n", fp);
69
fprintf (fp,"error: invalid TS character 0x%02x\n", *atr);
75
for (idx=1; idx < atrlen-1; idx++)
78
have_ta = !!(*atr & 0x10);
79
have_tb = !!(*atr & 0x20);
80
have_tc = !!(*atr & 0x40);
81
have_td = !!(*atr & 0x80);
82
n_historical = (*atr & 0x0f);
83
fprintf (fp, "%d historical characters indicated\n", n_historical);
85
if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen)
86
fputs ("error: ATR shorter than indicated by format character\n", fp);
93
fputs ("TA1: F=", fp);
94
val = fi_table[(*atr >> 4) & 0x0f];
96
fputs ("internal clock", fp);
100
fprintf (fp, "%d", val);
102
val = di_table[*atr & 0x0f];
104
fputs ("[impossible value]\n", fp);
108
fprintf (fp, "1/%d\n", val);
110
fprintf (fp, "%d\n", val);
119
fprintf (fp, "TB1: II=%d PI1=%d%s\n", (*atr >> 5) & 3, *atr & 0x1f,
120
(*atr & 0x80)? " [high bit not cleared]":"");
129
fputs ("TC1: guard time shortened to 1 etu\n", fp);
131
fprintf (fp, "TC1: (extra guard time) N=%d\n", *atr);
140
have_ta = !!(*atr & 0x10);
141
have_tb = !!(*atr & 0x20);
142
have_tc = !!(*atr & 0x40);
143
have_td = !!(*atr & 0x80);
144
fprintf (fp, "TD1: protocol T%d supported\n", *atr & 0x0f);
146
if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen)
147
fputs ("error: ATR shorter than indicated by format character\n", fp);
154
have_ta = have_tb = have_tc = have_td = 0;
158
fprintf (fp, "TA2: (PTS) %stoggle, %splicit, T=%02X\n",
159
(*atr & 0x80)? "no-":"",
160
(*atr & 0x10)? "im": "ex",
163
fprintf (fp, "note: reserved bits are set (TA2=0x%02X)\n", *atr);
171
fprintf (fp, "TB2: PI2=%d\n", *atr);
179
fprintf (fp, "TC2: PWI=%d\n", *atr);
187
have_ta = !!(*atr & 0x10);
188
have_tb = !!(*atr & 0x20);
189
have_tc = !!(*atr & 0x40);
190
have_td = !!(*atr & 0x80);
191
fprintf (fp, "TD2: protocol T%d supported\n", *atr & 0x0f);
193
if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen)
194
fputs ("error: ATR shorter than indicated by format character\n", fp);
201
have_ta = have_tb = have_tc = have_td = 0;
203
for (idx = 3; have_ta || have_tb || have_tc || have_td; idx++)
207
fprintf (fp, "TA%d: IFSC=%d\n", idx, *atr);
215
fprintf (fp, "TB%d: BWI=%d CWI=%d\n",
216
idx, (*atr >> 4) & 0x0f, *atr & 0x0f);
224
fprintf (fp, "TC%d: 0x%02X\n", idx, *atr);
232
have_ta = !!(*atr & 0x10);
233
have_tb = !!(*atr & 0x20);
234
have_tc = !!(*atr & 0x40);
235
have_td = !!(*atr & 0x80);
236
fprintf (fp, "TD%d: protocol T%d supported\n", idx, *atr & 0x0f);
238
if (have_ta + have_tb + have_tc + have_td + n_historical > atrlen)
239
fputs ("error: ATR shorter than indicated by format character\n",
247
have_ta = have_tb = have_tc = have_td = 0;
250
if (n_historical + 1 > atrlen)
251
fputs ("error: ATR shorter than required for historical bytes "
252
"and checksum\n", fp);
256
fputs ("Historical:", fp);
257
for (; n_historical && atrlen ; n_historical--, atrlen--, atr++)
258
fprintf (fp, " %02X", *atr);
263
fputs ("error: checksum missing\n", fp);
264
else if (*atr == chksum)
265
fprintf (fp, "TCK: %02X (good)\n", *atr);
267
fprintf (fp, "TCK: %02X (bad; calculated %02X)\n", *atr, chksum);
271
fprintf (fp, "error: %u bytes garbage at end of ATR\n",
272
(unsigned int)atrlen );