xref: /illumos-gate/usr/src/common/ccid/atr.c (revision a61ed2ce)
1*a61ed2ceSHans Rosenfeld /*
2*a61ed2ceSHans Rosenfeld  * This file and its contents are supplied under the terms of the
3*a61ed2ceSHans Rosenfeld  * Common Development and Distribution License ("CDDL"), version 1.0.
4*a61ed2ceSHans Rosenfeld  * You may only use this file in accordance with the terms of version
5*a61ed2ceSHans Rosenfeld  * 1.0 of the CDDL.
6*a61ed2ceSHans Rosenfeld  *
7*a61ed2ceSHans Rosenfeld  * A full copy of the text of the CDDL should have accompanied this
8*a61ed2ceSHans Rosenfeld  * source.  A copy of the CDDL is also available via the Internet at
9*a61ed2ceSHans Rosenfeld  * http://www.illumos.org/license/CDDL.
10*a61ed2ceSHans Rosenfeld  */
11*a61ed2ceSHans Rosenfeld 
12*a61ed2ceSHans Rosenfeld /*
13*a61ed2ceSHans Rosenfeld  * Copyright 2019, Joyent, Inc.
14*a61ed2ceSHans Rosenfeld  */
15*a61ed2ceSHans Rosenfeld 
16*a61ed2ceSHans Rosenfeld /*
17*a61ed2ceSHans Rosenfeld  * ATR parsing routines shared between userland (ccidadm) and the kernel (CCID
18*a61ed2ceSHans Rosenfeld  * driver)
19*a61ed2ceSHans Rosenfeld  */
20*a61ed2ceSHans Rosenfeld 
21*a61ed2ceSHans Rosenfeld #include "atr.h"
22*a61ed2ceSHans Rosenfeld #include <sys/debug.h>
23*a61ed2ceSHans Rosenfeld #include <sys/sysmacros.h>
24*a61ed2ceSHans Rosenfeld 
25*a61ed2ceSHans Rosenfeld #ifdef	_KERNEL
26*a61ed2ceSHans Rosenfeld #include <sys/inttypes.h>
27*a61ed2ceSHans Rosenfeld #include <sys/sunddi.h>
28*a61ed2ceSHans Rosenfeld #include <sys/kmem.h>
29*a61ed2ceSHans Rosenfeld #else
30*a61ed2ceSHans Rosenfeld #include <inttypes.h>
31*a61ed2ceSHans Rosenfeld #include <strings.h>
32*a61ed2ceSHans Rosenfeld #include <stdlib.h>
33*a61ed2ceSHans Rosenfeld #include <stdio.h>
34*a61ed2ceSHans Rosenfeld #include <ctype.h>
35*a61ed2ceSHans Rosenfeld #endif
36*a61ed2ceSHans Rosenfeld 
37*a61ed2ceSHans Rosenfeld /*
38*a61ed2ceSHans Rosenfeld  * The ATR must have at least 2 bytes and then may have up to 33 bytes. The
39*a61ed2ceSHans Rosenfeld  * first byte is always TS and the second required byte is T0.
40*a61ed2ceSHans Rosenfeld  */
41*a61ed2ceSHans Rosenfeld #define	ATR_TS_IDX	0
42*a61ed2ceSHans Rosenfeld #define	ATR_T0_IDX	1
43*a61ed2ceSHans Rosenfeld 
44*a61ed2ceSHans Rosenfeld /*
45*a61ed2ceSHans Rosenfeld  * There are two valid values for TS. It must either be 0x3F or 0x3B. This is
46*a61ed2ceSHans Rosenfeld  * required per ISO/IEC 7816-3:2006 section 8.1.
47*a61ed2ceSHans Rosenfeld  */
48*a61ed2ceSHans Rosenfeld #define	ATR_TS_INVERSE	0x3F
49*a61ed2ceSHans Rosenfeld #define	ATR_TS_DIRECT	0x3B
50*a61ed2ceSHans Rosenfeld 
51*a61ed2ceSHans Rosenfeld /*
52*a61ed2ceSHans Rosenfeld  * After TS, each word is used to indicate a combination of protocol and the
53*a61ed2ceSHans Rosenfeld  * number of bits defined for that protocol. The lower nibble is treated as the
54*a61ed2ceSHans Rosenfeld  * protocol. The upper nibble is treated to indicate which of four defined words
55*a61ed2ceSHans Rosenfeld  * are present. These are usually referred to as TA, TB, TC, and TD. TD is
56*a61ed2ceSHans Rosenfeld  * always used to indicate the next protocol and the number of bytes present for
57*a61ed2ceSHans Rosenfeld  * that. T0 works in a similar way, except that it defines the number of
58*a61ed2ceSHans Rosenfeld  * historical bytes present in its protocol section and then it refers to a set
59*a61ed2ceSHans Rosenfeld  * of pre-defined global bytes that may be present.
60*a61ed2ceSHans Rosenfeld  */
61*a61ed2ceSHans Rosenfeld #define	ATR_TD_PROT(x)	((x) & 0x0f)
62*a61ed2ceSHans Rosenfeld #define	ATR_TD_NBITS(x)	(((x) & 0xf0) >> 4)
63*a61ed2ceSHans Rosenfeld #define	ATR_TA_MASK	0x1
64*a61ed2ceSHans Rosenfeld #define	ATR_TB_MASK	0x2
65*a61ed2ceSHans Rosenfeld #define	ATR_TC_MASK	0x4
66*a61ed2ceSHans Rosenfeld #define	ATR_TD_MASK	0x8
67*a61ed2ceSHans Rosenfeld 
68*a61ed2ceSHans Rosenfeld #define	ATR_TA1_FTABLE(x)	(((x) & 0xf0) >> 4)
69*a61ed2ceSHans Rosenfeld #define	ATR_TA1_DITABLE(x)	((x) & 0x0f)
70*a61ed2ceSHans Rosenfeld 
71*a61ed2ceSHans Rosenfeld #define	ATR_TA2_CANCHANGE(x)	(((x) & 0x80) == 0)
72*a61ed2ceSHans Rosenfeld #define	ATR_TA2_HONORTA1(x)	(((x) & 0x10) == 0)
73*a61ed2ceSHans Rosenfeld #define	ATR_TA2_PROTOCOL(x)	((x) & 0x0f)
74*a61ed2ceSHans Rosenfeld 
75*a61ed2ceSHans Rosenfeld /*
76*a61ed2ceSHans Rosenfeld  * When the checksum is required in the ATR, each byte must XOR to zero.
77*a61ed2ceSHans Rosenfeld  */
78*a61ed2ceSHans Rosenfeld #define	ATR_CKSUM_TARGET	0
79*a61ed2ceSHans Rosenfeld 
80*a61ed2ceSHans Rosenfeld /*
81*a61ed2ceSHans Rosenfeld  * Maximum number of historic ATR bytes. This is limited by the fact that it's a
82*a61ed2ceSHans Rosenfeld  * 4-bit nibble.
83*a61ed2ceSHans Rosenfeld  */
84*a61ed2ceSHans Rosenfeld #define	ATR_HISTORICAL_MAX	15
85*a61ed2ceSHans Rosenfeld 
86*a61ed2ceSHans Rosenfeld /*
87*a61ed2ceSHans Rosenfeld  * The maximum number of TA, TB, TC, and TD levels that can be encountered in a
88*a61ed2ceSHans Rosenfeld  * given structure. In the best case, there are 30 bytes available (TS, T0, and
89*a61ed2ceSHans Rosenfeld  * TCK use the others). Given that each one of these needs 4 bytes to be
90*a61ed2ceSHans Rosenfeld  * represented, the maximum number of layers that can fit is seven.
91*a61ed2ceSHans Rosenfeld  */
92*a61ed2ceSHans Rosenfeld #define	ATR_TI_MAX	7
93*a61ed2ceSHans Rosenfeld 
94*a61ed2ceSHans Rosenfeld /*
95*a61ed2ceSHans Rosenfeld  * Defined protocol values. See ISO/IEC 7816-3:2006 8.2.3 for this list.
96*a61ed2ceSHans Rosenfeld  * Reserved values are noted but not defined.
97*a61ed2ceSHans Rosenfeld  */
98*a61ed2ceSHans Rosenfeld #define	ATR_PROTOCOL_T0		0
99*a61ed2ceSHans Rosenfeld #define	ATR_PROTOCOL_T1		1
100*a61ed2ceSHans Rosenfeld 
101*a61ed2ceSHans Rosenfeld #define	ATR_T1_TB0_CWI(x)	((x) & 0x0f)
102*a61ed2ceSHans Rosenfeld #define	ATR_T1_TB0_BWI(x)	(((x) & 0xf0) >> 4)
103*a61ed2ceSHans Rosenfeld #define	ATR_T1_TC0_CRC(x)	(((x) & 0x01) != 0)
104*a61ed2ceSHans Rosenfeld 
105*a61ed2ceSHans Rosenfeld /*
106*a61ed2ceSHans Rosenfeld  * T=2 and T=3 are reserved for future full-duplex operation.
107*a61ed2ceSHans Rosenfeld  * T=4 is reserved for enhanced half-duplex character transmission.
108*a61ed2ceSHans Rosenfeld  * T=5-13 are reserved for future use by ISO/IEC JTC 1/SC 17.
109*a61ed2ceSHans Rosenfeld  * T=14 is for protocols not standardized by ISO/IEC JTC 1/SC 17.
110*a61ed2ceSHans Rosenfeld  */
111*a61ed2ceSHans Rosenfeld #define	ATR_PROTOCOL_T15	15
112*a61ed2ceSHans Rosenfeld 
113*a61ed2ceSHans Rosenfeld #define	ATR_T15_TA0_CLOCK(x)	(((x) & 0xc0) >> 6)
114*a61ed2ceSHans Rosenfeld #define	ATR_T15_TA0_VOLTAGE(x)	((x) & 0x3f)
115*a61ed2ceSHans Rosenfeld 
116*a61ed2ceSHans Rosenfeld #define	ATR_T15_TB0_SPU_STANDARD(x)	(((x & 0x80)) != 0)
117*a61ed2ceSHans Rosenfeld 
118*a61ed2ceSHans Rosenfeld /*
119*a61ed2ceSHans Rosenfeld  * Various definitions for the configuration of historical data. This comes from
120*a61ed2ceSHans Rosenfeld  * ISO/IEC 7816-4:2013 Section 12.1.1.
121*a61ed2ceSHans Rosenfeld  */
122*a61ed2ceSHans Rosenfeld 
123*a61ed2ceSHans Rosenfeld /*
124*a61ed2ceSHans Rosenfeld  * The first historical byte is used to indicate the encoding of the data. Only
125*a61ed2ceSHans Rosenfeld  * values 0x00, 0x80-0x8f are defined. All others are proprietary. 0x81-0x8f are
126*a61ed2ceSHans Rosenfeld  * reserved for future use.
127*a61ed2ceSHans Rosenfeld  */
128*a61ed2ceSHans Rosenfeld #define	ATR_HIST_CAT_MAND_STATUS	0x00
129*a61ed2ceSHans Rosenfeld #define	ATR_HIST_CAT_TLV_STATUS		0x80
130*a61ed2ceSHans Rosenfeld #define	ATR_HIST_CAT_RFU_MIN		0x81
131*a61ed2ceSHans Rosenfeld #define	ATR_HIST_CAT_RFU_MAX		0x8f
132*a61ed2ceSHans Rosenfeld 
133*a61ed2ceSHans Rosenfeld /*
134*a61ed2ceSHans Rosenfeld  * From ISO/IEC 7816-3:2006 Section 8.3.
135*a61ed2ceSHans Rosenfeld  *
136*a61ed2ceSHans Rosenfeld  * The default value for Fi is 372 which is table entry 1. The default value for
137*a61ed2ceSHans Rosenfeld  * Di is 1, which is table entry 1.
138*a61ed2ceSHans Rosenfeld  */
139*a61ed2ceSHans Rosenfeld #define	ATR_FI_DEFAULT_INDEX	1
140*a61ed2ceSHans Rosenfeld #define	ATR_DI_DEFAULT_INDEX	1
141*a61ed2ceSHans Rosenfeld #define	ATR_EXTRA_GUARDTIME_DEFAULT	0
142*a61ed2ceSHans Rosenfeld 
143*a61ed2ceSHans Rosenfeld /*
144*a61ed2ceSHans Rosenfeld  * From ISO/IEC 7816-3:2006 Section 10.2.
145*a61ed2ceSHans Rosenfeld  */
146*a61ed2ceSHans Rosenfeld #define	ATR_T0_WI_DEFAULT	10
147*a61ed2ceSHans Rosenfeld 
148*a61ed2ceSHans Rosenfeld /*
149*a61ed2ceSHans Rosenfeld  * From ISO/IEC 7816-3:2006 Section 11.4.3.
150*a61ed2ceSHans Rosenfeld  */
151*a61ed2ceSHans Rosenfeld #define	ATR_T1_CWI_DEFAULT	13
152*a61ed2ceSHans Rosenfeld 
153*a61ed2ceSHans Rosenfeld /*
154*a61ed2ceSHans Rosenfeld  * From ISO/IEC 7816-3:2006 Section 11.4.3.
155*a61ed2ceSHans Rosenfeld  */
156*a61ed2ceSHans Rosenfeld #define	ATR_T1_BWI_DEFAULT	4
157*a61ed2ceSHans Rosenfeld 
158*a61ed2ceSHans Rosenfeld /*
159*a61ed2ceSHans Rosenfeld  * From ISO/IEC 7816-3:2006 Section 11.4.2.
160*a61ed2ceSHans Rosenfeld  */
161*a61ed2ceSHans Rosenfeld #define	ATR_T1_IFSC_DEFAULT	32
162*a61ed2ceSHans Rosenfeld 
163*a61ed2ceSHans Rosenfeld /*
164*a61ed2ceSHans Rosenfeld  * From ISO/IEC 7816-3:2006 Section 11.4.4
165*a61ed2ceSHans Rosenfeld  */
166*a61ed2ceSHans Rosenfeld #define	ATR_T1_CHECKSUM_DEFAULT	ATR_T1_CHECKSUM_LRC
167*a61ed2ceSHans Rosenfeld 
168*a61ed2ceSHans Rosenfeld /*
169*a61ed2ceSHans Rosenfeld  * Definitions for PPS construction. These are derived from ISO/IEC 7816-3:2006
170*a61ed2ceSHans Rosenfeld  * section 9, Protocol and parameters selection.
171*a61ed2ceSHans Rosenfeld  */
172*a61ed2ceSHans Rosenfeld #define	PPS_LEN_MIN	3	/* PPSS, PPS0, PCK */
173*a61ed2ceSHans Rosenfeld #define	PPS_LEN_MAX	PPS_BUFFER_MAX
174*a61ed2ceSHans Rosenfeld #define	PPS_PPSS_INDEX	0
175*a61ed2ceSHans Rosenfeld #define	PPS_PPSS_VAL	0xff
176*a61ed2ceSHans Rosenfeld #define	PPS_PPS0_INDEX	0x01
177*a61ed2ceSHans Rosenfeld #define	PPS_PPS0_PROT(x)	((x) & 0x0f)
178*a61ed2ceSHans Rosenfeld #define	PPS_PPS0_PPS1		(1 << 4)
179*a61ed2ceSHans Rosenfeld #define	PPS_PPS0_PPS2		(1 << 5)
180*a61ed2ceSHans Rosenfeld #define	PPS_PPS0_PPS3		(1 << 6)
181*a61ed2ceSHans Rosenfeld #define	PPS_PPS1_SETVAL(f, d)	((((f) & 0x0f) << 4) | ((d) & 0x0f))
182*a61ed2ceSHans Rosenfeld 
183*a61ed2ceSHans Rosenfeld /*
184*a61ed2ceSHans Rosenfeld  * This enum and subsequent structure is used to represent a single level of
185*a61ed2ceSHans Rosenfeld  * 'T'. This includes the possibility for all three values to be set and records
186*a61ed2ceSHans Rosenfeld  * the protocol.
187*a61ed2ceSHans Rosenfeld  */
188*a61ed2ceSHans Rosenfeld typedef enum atr_ti_flags {
189*a61ed2ceSHans Rosenfeld 	ATR_TI_HAVE_TA	= 1 << 0,
190*a61ed2ceSHans Rosenfeld 	ATR_TI_HAVE_TB	= 1 << 1,
191*a61ed2ceSHans Rosenfeld 	ATR_TI_HAVE_TC	= 1 << 2,
192*a61ed2ceSHans Rosenfeld 	ATR_TI_HAVE_TD	= 1 << 3
193*a61ed2ceSHans Rosenfeld } atr_ti_flags_t;
194*a61ed2ceSHans Rosenfeld 
195*a61ed2ceSHans Rosenfeld typedef struct atr_ti {
196*a61ed2ceSHans Rosenfeld 	uint8_t		atrti_protocol;
197*a61ed2ceSHans Rosenfeld 	uint8_t		atrti_ti_val;
198*a61ed2ceSHans Rosenfeld 	uint8_t		atrti_td_idx;
199*a61ed2ceSHans Rosenfeld 	atr_ti_flags_t	atrti_flags;
200*a61ed2ceSHans Rosenfeld 	uint8_t		atrti_ta;
201*a61ed2ceSHans Rosenfeld 	uint8_t		atrti_tb;
202*a61ed2ceSHans Rosenfeld 	uint8_t		atrti_tc;
203*a61ed2ceSHans Rosenfeld 	uint8_t		atrti_td;
204*a61ed2ceSHans Rosenfeld } atr_ti_t;
205*a61ed2ceSHans Rosenfeld 
206*a61ed2ceSHans Rosenfeld typedef enum atr_flags {
207*a61ed2ceSHans Rosenfeld 	ATR_F_USES_DIRECT	= 1 << 0,
208*a61ed2ceSHans Rosenfeld 	ATR_F_USES_INVERSE	= 1 << 1,
209*a61ed2ceSHans Rosenfeld 	ATR_F_HAS_CHECKSUM	= 1 << 2,
210*a61ed2ceSHans Rosenfeld 	ATR_F_VALID		= 1 << 3
211*a61ed2ceSHans Rosenfeld } atr_flags_t;
212*a61ed2ceSHans Rosenfeld 
213*a61ed2ceSHans Rosenfeld 
214*a61ed2ceSHans Rosenfeld struct atr_data {
215*a61ed2ceSHans Rosenfeld 	atr_flags_t	atr_flags;
216*a61ed2ceSHans Rosenfeld 	uint8_t		atr_nti;
217*a61ed2ceSHans Rosenfeld 	atr_ti_t	atr_ti[ATR_TI_MAX];
218*a61ed2ceSHans Rosenfeld 	uint8_t		atr_nhistoric;
219*a61ed2ceSHans Rosenfeld 	uint8_t		atr_historic[ATR_HISTORICAL_MAX];
220*a61ed2ceSHans Rosenfeld 	uint8_t		atr_cksum;
221*a61ed2ceSHans Rosenfeld 	uint8_t		atr_raw[ATR_LEN_MAX];
222*a61ed2ceSHans Rosenfeld 	uint8_t		atr_nraw;
223*a61ed2ceSHans Rosenfeld };
224*a61ed2ceSHans Rosenfeld 
225*a61ed2ceSHans Rosenfeld /*
226*a61ed2ceSHans Rosenfeld  * These tables maps the bit values for Fi from 7816-3:2006 section 8.3 Table 7.
227*a61ed2ceSHans Rosenfeld  */
228*a61ed2ceSHans Rosenfeld static uint_t atr_fi_valtable[16] = {
229*a61ed2ceSHans Rosenfeld 	372,		/* 0000 */
230*a61ed2ceSHans Rosenfeld 	372,		/* 0001 */
231*a61ed2ceSHans Rosenfeld 	558,		/* 0010 */
232*a61ed2ceSHans Rosenfeld 	744,		/* 0011 */
233*a61ed2ceSHans Rosenfeld 	1116,		/* 0100 */
234*a61ed2ceSHans Rosenfeld 	1488,		/* 0101 */
235*a61ed2ceSHans Rosenfeld 	1860,		/* 0110 */
236*a61ed2ceSHans Rosenfeld 	0,		/* 0111 */
237*a61ed2ceSHans Rosenfeld 	0,		/* 1000 */
238*a61ed2ceSHans Rosenfeld 	512,		/* 1001 */
239*a61ed2ceSHans Rosenfeld 	768,		/* 1010 */
240*a61ed2ceSHans Rosenfeld 	1024,		/* 1011 */
241*a61ed2ceSHans Rosenfeld 	1536,		/* 1100 */
242*a61ed2ceSHans Rosenfeld 	2048,		/* 1101 */
243*a61ed2ceSHans Rosenfeld 	0,		/* 1110 */
244*a61ed2ceSHans Rosenfeld 	0		/* 1111 */
245*a61ed2ceSHans Rosenfeld };
246*a61ed2ceSHans Rosenfeld 
247*a61ed2ceSHans Rosenfeld static const char *atr_fi_table[16] = {
248*a61ed2ceSHans Rosenfeld 	"372",		/* 0000 */
249*a61ed2ceSHans Rosenfeld 	"372",		/* 0001 */
250*a61ed2ceSHans Rosenfeld 	"558",		/* 0010 */
251*a61ed2ceSHans Rosenfeld 	"744",		/* 0011 */
252*a61ed2ceSHans Rosenfeld 	"1116",		/* 0100 */
253*a61ed2ceSHans Rosenfeld 	"1488",		/* 0101 */
254*a61ed2ceSHans Rosenfeld 	"1860",		/* 0110 */
255*a61ed2ceSHans Rosenfeld 	"RFU",		/* 0111 */
256*a61ed2ceSHans Rosenfeld 	"RFU",		/* 1000 */
257*a61ed2ceSHans Rosenfeld 	"512",		/* 1001 */
258*a61ed2ceSHans Rosenfeld 	"768",		/* 1010 */
259*a61ed2ceSHans Rosenfeld 	"1024",		/* 1011 */
260*a61ed2ceSHans Rosenfeld 	"1536",		/* 1100 */
261*a61ed2ceSHans Rosenfeld 	"2048",		/* 1101 */
262*a61ed2ceSHans Rosenfeld 	"RFU",		/* 1110 */
263*a61ed2ceSHans Rosenfeld 	"RFU",		/* 1111 */
264*a61ed2ceSHans Rosenfeld };
265*a61ed2ceSHans Rosenfeld 
266*a61ed2ceSHans Rosenfeld /*
267*a61ed2ceSHans Rosenfeld  * This table maps the bit values for f(max) from 7816-3:2006 section 8.3
268*a61ed2ceSHans Rosenfeld  * Table 7.
269*a61ed2ceSHans Rosenfeld  */
270*a61ed2ceSHans Rosenfeld static const char *atr_fmax_table[16] = {
271*a61ed2ceSHans Rosenfeld 	"4",		/* 0000 */
272*a61ed2ceSHans Rosenfeld 	"5",		/* 0001 */
273*a61ed2ceSHans Rosenfeld 	"6",		/* 0010 */
274*a61ed2ceSHans Rosenfeld 	"8",		/* 0011 */
275*a61ed2ceSHans Rosenfeld 	"12",		/* 0100 */
276*a61ed2ceSHans Rosenfeld 	"16",		/* 0101 */
277*a61ed2ceSHans Rosenfeld 	"20",		/* 0110 */
278*a61ed2ceSHans Rosenfeld 	"-",		/* 0111 */
279*a61ed2ceSHans Rosenfeld 	"-",		/* 1000 */
280*a61ed2ceSHans Rosenfeld 	"5",		/* 1001 */
281*a61ed2ceSHans Rosenfeld 	"7.5",		/* 1010 */
282*a61ed2ceSHans Rosenfeld 	"10",		/* 1011 */
283*a61ed2ceSHans Rosenfeld 	"15",		/* 1100 */
284*a61ed2ceSHans Rosenfeld 	"20",		/* 1101 */
285*a61ed2ceSHans Rosenfeld 	"-",		/* 1110 */
286*a61ed2ceSHans Rosenfeld 	"-",		/* 1111 */
287*a61ed2ceSHans Rosenfeld };
288*a61ed2ceSHans Rosenfeld 
289*a61ed2ceSHans Rosenfeld /*
290*a61ed2ceSHans Rosenfeld  * This table maps the bit values for Di from 7816-3:2006 section 8.3 Table 8.
291*a61ed2ceSHans Rosenfeld  */
292*a61ed2ceSHans Rosenfeld static uint_t atr_di_valtable[16] = {
293*a61ed2ceSHans Rosenfeld 	0,		/* 0000 */
294*a61ed2ceSHans Rosenfeld 	1,		/* 0001 */
295*a61ed2ceSHans Rosenfeld 	2,		/* 0010 */
296*a61ed2ceSHans Rosenfeld 	4,		/* 0011 */
297*a61ed2ceSHans Rosenfeld 	8,		/* 0100 */
298*a61ed2ceSHans Rosenfeld 	16,		/* 0101 */
299*a61ed2ceSHans Rosenfeld 	32,		/* 0110 */
300*a61ed2ceSHans Rosenfeld 	64,		/* 0111 */
301*a61ed2ceSHans Rosenfeld 	12,		/* 1000 */
302*a61ed2ceSHans Rosenfeld 	20,		/* 1001 */
303*a61ed2ceSHans Rosenfeld 	0,		/* 1010 */
304*a61ed2ceSHans Rosenfeld 	0,		/* 1011 */
305*a61ed2ceSHans Rosenfeld 	0,		/* 1100 */
306*a61ed2ceSHans Rosenfeld 	0,		/* 1101 */
307*a61ed2ceSHans Rosenfeld 	0,		/* 1110 */
308*a61ed2ceSHans Rosenfeld 	0		/* 1111 */
309*a61ed2ceSHans Rosenfeld };
310*a61ed2ceSHans Rosenfeld 
311*a61ed2ceSHans Rosenfeld static const char *atr_di_table[16] = {
312*a61ed2ceSHans Rosenfeld 	"RFU",		/* 0000 */
313*a61ed2ceSHans Rosenfeld 	"1",		/* 0001 */
314*a61ed2ceSHans Rosenfeld 	"2",		/* 0010 */
315*a61ed2ceSHans Rosenfeld 	"4",		/* 0011 */
316*a61ed2ceSHans Rosenfeld 	"8",		/* 0100 */
317*a61ed2ceSHans Rosenfeld 	"16",		/* 0101 */
318*a61ed2ceSHans Rosenfeld 	"32",		/* 0110 */
319*a61ed2ceSHans Rosenfeld 	"64",		/* 0111 */
320*a61ed2ceSHans Rosenfeld 	"12",		/* 1000 */
321*a61ed2ceSHans Rosenfeld 	"20",		/* 1001 */
322*a61ed2ceSHans Rosenfeld 	"RFU",		/* 1010 */
323*a61ed2ceSHans Rosenfeld 	"RFU",		/* 1011 */
324*a61ed2ceSHans Rosenfeld 	"RFU",		/* 1100 */
325*a61ed2ceSHans Rosenfeld 	"RFU",		/* 1101 */
326*a61ed2ceSHans Rosenfeld 	"RFU",		/* 1110 */
327*a61ed2ceSHans Rosenfeld 	"RFU",		/* 1111 */
328*a61ed2ceSHans Rosenfeld };
329*a61ed2ceSHans Rosenfeld 
330*a61ed2ceSHans Rosenfeld /*
331*a61ed2ceSHans Rosenfeld  * This table maps the bit values for the clock stop indicator from 7816-3:2006
332*a61ed2ceSHans Rosenfeld  * section 8.3 Table 9.
333*a61ed2ceSHans Rosenfeld  */
334*a61ed2ceSHans Rosenfeld static const char *atr_clock_table[4] = {
335*a61ed2ceSHans Rosenfeld 	"disallowed",		/* 00 */
336*a61ed2ceSHans Rosenfeld 	"signal low",		/* 01 */
337*a61ed2ceSHans Rosenfeld 	"signal high",		/* 10 */
338*a61ed2ceSHans Rosenfeld 	"signal low or high"	/* 11 */
339*a61ed2ceSHans Rosenfeld };
340*a61ed2ceSHans Rosenfeld 
341*a61ed2ceSHans Rosenfeld uint_t
atr_fi_index_to_value(uint8_t val)342*a61ed2ceSHans Rosenfeld atr_fi_index_to_value(uint8_t val)
343*a61ed2ceSHans Rosenfeld {
344*a61ed2ceSHans Rosenfeld 	if (val >= ARRAY_SIZE(atr_fi_valtable)) {
345*a61ed2ceSHans Rosenfeld 		return (0);
346*a61ed2ceSHans Rosenfeld 	}
347*a61ed2ceSHans Rosenfeld 
348*a61ed2ceSHans Rosenfeld 	return (atr_fi_valtable[val]);
349*a61ed2ceSHans Rosenfeld }
350*a61ed2ceSHans Rosenfeld 
351*a61ed2ceSHans Rosenfeld const char *
atr_fi_index_to_string(uint8_t val)352*a61ed2ceSHans Rosenfeld atr_fi_index_to_string(uint8_t val)
353*a61ed2ceSHans Rosenfeld {
354*a61ed2ceSHans Rosenfeld 	if (val >= ARRAY_SIZE(atr_fi_table)) {
355*a61ed2ceSHans Rosenfeld 		return ("<invalid>");
356*a61ed2ceSHans Rosenfeld 	}
357*a61ed2ceSHans Rosenfeld 
358*a61ed2ceSHans Rosenfeld 	return (atr_fi_table[val]);
359*a61ed2ceSHans Rosenfeld }
360*a61ed2ceSHans Rosenfeld 
361*a61ed2ceSHans Rosenfeld const char *
atr_fmax_index_to_string(uint8_t val)362*a61ed2ceSHans Rosenfeld atr_fmax_index_to_string(uint8_t val)
363*a61ed2ceSHans Rosenfeld {
364*a61ed2ceSHans Rosenfeld 	if (val >= ARRAY_SIZE(atr_fmax_table)) {
365*a61ed2ceSHans Rosenfeld 		return ("<invalid>");
366*a61ed2ceSHans Rosenfeld 	}
367*a61ed2ceSHans Rosenfeld 
368*a61ed2ceSHans Rosenfeld 	return (atr_fmax_table[val]);
369*a61ed2ceSHans Rosenfeld }
370*a61ed2ceSHans Rosenfeld 
371*a61ed2ceSHans Rosenfeld uint_t
atr_di_index_to_value(uint8_t val)372*a61ed2ceSHans Rosenfeld atr_di_index_to_value(uint8_t val)
373*a61ed2ceSHans Rosenfeld {
374*a61ed2ceSHans Rosenfeld 	if (val >= ARRAY_SIZE(atr_di_valtable)) {
375*a61ed2ceSHans Rosenfeld 		return (0);
376*a61ed2ceSHans Rosenfeld 	}
377*a61ed2ceSHans Rosenfeld 
378*a61ed2ceSHans Rosenfeld 	return (atr_di_valtable[val]);
379*a61ed2ceSHans Rosenfeld }
380*a61ed2ceSHans Rosenfeld const char *
atr_di_index_to_string(uint8_t val)381*a61ed2ceSHans Rosenfeld atr_di_index_to_string(uint8_t val)
382*a61ed2ceSHans Rosenfeld {
383*a61ed2ceSHans Rosenfeld 	if (val >= ARRAY_SIZE(atr_di_table)) {
384*a61ed2ceSHans Rosenfeld 		return ("<invalid>");
385*a61ed2ceSHans Rosenfeld 	}
386*a61ed2ceSHans Rosenfeld 
387*a61ed2ceSHans Rosenfeld 	return (atr_di_table[val]);
388*a61ed2ceSHans Rosenfeld }
389*a61ed2ceSHans Rosenfeld 
390*a61ed2ceSHans Rosenfeld const char *
atr_clock_stop_to_string(atr_clock_stop_t val)391*a61ed2ceSHans Rosenfeld atr_clock_stop_to_string(atr_clock_stop_t val)
392*a61ed2ceSHans Rosenfeld {
393*a61ed2ceSHans Rosenfeld 	if (val >= ARRAY_SIZE(atr_clock_table)) {
394*a61ed2ceSHans Rosenfeld 		return ("<invalid>");
395*a61ed2ceSHans Rosenfeld 	}
396*a61ed2ceSHans Rosenfeld 
397*a61ed2ceSHans Rosenfeld 	return (atr_clock_table[val]);
398*a61ed2ceSHans Rosenfeld }
399*a61ed2ceSHans Rosenfeld 
400*a61ed2ceSHans Rosenfeld const char *
atr_protocol_to_string(atr_protocol_t prot)401*a61ed2ceSHans Rosenfeld atr_protocol_to_string(atr_protocol_t prot)
402*a61ed2ceSHans Rosenfeld {
403*a61ed2ceSHans Rosenfeld 	if (prot == ATR_P_NONE) {
404*a61ed2ceSHans Rosenfeld 		return ("none");
405*a61ed2ceSHans Rosenfeld 	}
406*a61ed2ceSHans Rosenfeld 
407*a61ed2ceSHans Rosenfeld 	if ((prot & ATR_P_T0) == ATR_P_T0) {
408*a61ed2ceSHans Rosenfeld 		return ("T=0");
409*a61ed2ceSHans Rosenfeld 	} else if ((prot & ATR_P_T1) == ATR_P_T1) {
410*a61ed2ceSHans Rosenfeld 		return ("T=1");
411*a61ed2ceSHans Rosenfeld 	} else {
412*a61ed2ceSHans Rosenfeld 		return ("T=0, T=1");
413*a61ed2ceSHans Rosenfeld 	}
414*a61ed2ceSHans Rosenfeld }
415*a61ed2ceSHans Rosenfeld 
416*a61ed2ceSHans Rosenfeld const char *
atr_convention_to_string(atr_convention_t conv)417*a61ed2ceSHans Rosenfeld atr_convention_to_string(atr_convention_t conv)
418*a61ed2ceSHans Rosenfeld {
419*a61ed2ceSHans Rosenfeld 	if (conv == ATR_CONVENTION_DIRECT) {
420*a61ed2ceSHans Rosenfeld 		return ("direct");
421*a61ed2ceSHans Rosenfeld 	} else if (conv == ATR_CONVENTION_INVERSE) {
422*a61ed2ceSHans Rosenfeld 		return ("inverse");
423*a61ed2ceSHans Rosenfeld 	} else {
424*a61ed2ceSHans Rosenfeld 		return ("<invalid convention>");
425*a61ed2ceSHans Rosenfeld 	}
426*a61ed2ceSHans Rosenfeld }
427*a61ed2ceSHans Rosenfeld 
428*a61ed2ceSHans Rosenfeld const char *
atr_strerror(atr_parsecode_t code)429*a61ed2ceSHans Rosenfeld atr_strerror(atr_parsecode_t code)
430*a61ed2ceSHans Rosenfeld {
431*a61ed2ceSHans Rosenfeld 	switch (code) {
432*a61ed2ceSHans Rosenfeld 	case ATR_CODE_OK:
433*a61ed2ceSHans Rosenfeld 		return ("ATR parsed successfully");
434*a61ed2ceSHans Rosenfeld 	case ATR_CODE_TOO_SHORT:
435*a61ed2ceSHans Rosenfeld 		return ("Specified buffer too short");
436*a61ed2ceSHans Rosenfeld 	case ATR_CODE_TOO_LONG:
437*a61ed2ceSHans Rosenfeld 		return ("Specified buffer too long");
438*a61ed2ceSHans Rosenfeld 	case ATR_CODE_INVALID_TS:
439*a61ed2ceSHans Rosenfeld 		return ("ATR has invalid TS byte value");
440*a61ed2ceSHans Rosenfeld 	case ATR_CODE_OVERRUN:
441*a61ed2ceSHans Rosenfeld 		return ("ATR data requires more bytes than provided");
442*a61ed2ceSHans Rosenfeld 	case ATR_CODE_UNDERRUN:
443*a61ed2ceSHans Rosenfeld 		return ("ATR data did not use all provided bytes");
444*a61ed2ceSHans Rosenfeld 	case ATR_CODE_CHECKSUM_ERROR:
445*a61ed2ceSHans Rosenfeld 		return ("ATR data did not checksum correctly");
446*a61ed2ceSHans Rosenfeld 	case ATR_CODE_INVALID_TD1:
447*a61ed2ceSHans Rosenfeld 		return ("ATR data has invalid protocol in TD1");
448*a61ed2ceSHans Rosenfeld 	default:
449*a61ed2ceSHans Rosenfeld 		return ("Unknown Parse Code");
450*a61ed2ceSHans Rosenfeld 	}
451*a61ed2ceSHans Rosenfeld }
452*a61ed2ceSHans Rosenfeld 
453*a61ed2ceSHans Rosenfeld static uint_t
atr_count_cbits(uint8_t x)454*a61ed2ceSHans Rosenfeld atr_count_cbits(uint8_t x)
455*a61ed2ceSHans Rosenfeld {
456*a61ed2ceSHans Rosenfeld 	uint_t ret = 0;
457*a61ed2ceSHans Rosenfeld 
458*a61ed2ceSHans Rosenfeld 	if (x & ATR_TA_MASK)
459*a61ed2ceSHans Rosenfeld 		ret++;
460*a61ed2ceSHans Rosenfeld 	if (x & ATR_TB_MASK)
461*a61ed2ceSHans Rosenfeld 		ret++;
462*a61ed2ceSHans Rosenfeld 	if (x & ATR_TC_MASK)
463*a61ed2ceSHans Rosenfeld 		ret++;
464*a61ed2ceSHans Rosenfeld 	if (x & ATR_TD_MASK)
465*a61ed2ceSHans Rosenfeld 		ret++;
466*a61ed2ceSHans Rosenfeld 	return (ret);
467*a61ed2ceSHans Rosenfeld }
468*a61ed2ceSHans Rosenfeld 
469*a61ed2ceSHans Rosenfeld /*
470*a61ed2ceSHans Rosenfeld  * Parse out ATR values. Focus on only parsing it and not interpreting it.
471*a61ed2ceSHans Rosenfeld  * Interpretation should be done in other functions that can walk over the data
472*a61ed2ceSHans Rosenfeld  * and be more protocol-aware.
473*a61ed2ceSHans Rosenfeld  */
474*a61ed2ceSHans Rosenfeld atr_parsecode_t
atr_parse(const uint8_t * buf,size_t len,atr_data_t * data)475*a61ed2ceSHans Rosenfeld atr_parse(const uint8_t *buf, size_t len, atr_data_t *data)
476*a61ed2ceSHans Rosenfeld {
477*a61ed2ceSHans Rosenfeld 	uint_t nhist, cbits, ncbits, idx, Ti, prot;
478*a61ed2ceSHans Rosenfeld 	uint_t ncksum = 0;
479*a61ed2ceSHans Rosenfeld 	atr_ti_t *atp;
480*a61ed2ceSHans Rosenfeld 
481*a61ed2ceSHans Rosenfeld 	/*
482*a61ed2ceSHans Rosenfeld 	 * Zero out data in case someone's come back around for another loop on
483*a61ed2ceSHans Rosenfeld 	 * the same data.
484*a61ed2ceSHans Rosenfeld 	 */
485*a61ed2ceSHans Rosenfeld 	bzero(data, sizeof (atr_data_t));
486*a61ed2ceSHans Rosenfeld 
487*a61ed2ceSHans Rosenfeld 	if (len < ATR_LEN_MIN) {
488*a61ed2ceSHans Rosenfeld 		return (ATR_CODE_TOO_SHORT);
489*a61ed2ceSHans Rosenfeld 	}
490*a61ed2ceSHans Rosenfeld 
491*a61ed2ceSHans Rosenfeld 	if (len > ATR_LEN_MAX) {
492*a61ed2ceSHans Rosenfeld 		return (ATR_CODE_TOO_LONG);
493*a61ed2ceSHans Rosenfeld 	}
494*a61ed2ceSHans Rosenfeld 
495*a61ed2ceSHans Rosenfeld 	if (buf[ATR_TS_IDX] != ATR_TS_INVERSE &&
496*a61ed2ceSHans Rosenfeld 	    buf[ATR_TS_IDX] != ATR_TS_DIRECT) {
497*a61ed2ceSHans Rosenfeld 		return (ATR_CODE_INVALID_TS);
498*a61ed2ceSHans Rosenfeld 	}
499*a61ed2ceSHans Rosenfeld 
500*a61ed2ceSHans Rosenfeld 	bcopy(buf, data->atr_raw, len);
501*a61ed2ceSHans Rosenfeld 	data->atr_nraw = len;
502*a61ed2ceSHans Rosenfeld 
503*a61ed2ceSHans Rosenfeld 	if (buf[ATR_TS_IDX] == ATR_TS_DIRECT) {
504*a61ed2ceSHans Rosenfeld 		data->atr_flags |= ATR_F_USES_DIRECT;
505*a61ed2ceSHans Rosenfeld 	} else {
506*a61ed2ceSHans Rosenfeld 		data->atr_flags |= ATR_F_USES_INVERSE;
507*a61ed2ceSHans Rosenfeld 	}
508*a61ed2ceSHans Rosenfeld 
509*a61ed2ceSHans Rosenfeld 	/*
510*a61ed2ceSHans Rosenfeld 	 * The protocol of T0 is the number of historical bits present.
511*a61ed2ceSHans Rosenfeld 	 */
512*a61ed2ceSHans Rosenfeld 	nhist = ATR_TD_PROT(buf[ATR_T0_IDX]);
513*a61ed2ceSHans Rosenfeld 	cbits = ATR_TD_NBITS(buf[ATR_T0_IDX]);
514*a61ed2ceSHans Rosenfeld 	idx = ATR_T0_IDX + 1;
515*a61ed2ceSHans Rosenfeld 	ncbits = atr_count_cbits(cbits);
516*a61ed2ceSHans Rosenfeld 
517*a61ed2ceSHans Rosenfeld 	/*
518*a61ed2ceSHans Rosenfeld 	 * Ti is used to track the current iteration of T[A,B,C,D] that we are
519*a61ed2ceSHans Rosenfeld 	 * on, as the ISO/IEC standard suggests. The way that values are
520*a61ed2ceSHans Rosenfeld 	 * interpreted depends on the value of Ti.
521*a61ed2ceSHans Rosenfeld 	 *
522*a61ed2ceSHans Rosenfeld 	 * When Ti is one, TA, TB, and TC represent global properties. TD's
523*a61ed2ceSHans Rosenfeld 	 * protocol represents the preferred protocol.
524*a61ed2ceSHans Rosenfeld 	 *
525*a61ed2ceSHans Rosenfeld 	 * When Ti is two, TA, TB, and TC also represent global properties.
526*a61ed2ceSHans Rosenfeld 	 * However, TC only has meaning if the protocol is T=0.
527*a61ed2ceSHans Rosenfeld 	 *
528*a61ed2ceSHans Rosenfeld 	 * When Ti is 15, it indicates more global properties.
529*a61ed2ceSHans Rosenfeld 	 *
530*a61ed2ceSHans Rosenfeld 	 * For all other values of Ti, the meaning depends on the protocol in
531*a61ed2ceSHans Rosenfeld 	 * question and they are all properties specific to that protocol.
532*a61ed2ceSHans Rosenfeld 	 */
533*a61ed2ceSHans Rosenfeld 	Ti = 1;
534*a61ed2ceSHans Rosenfeld 	/*
535*a61ed2ceSHans Rosenfeld 	 * Initialize prot to an invalid protocol to help us deal with the
536*a61ed2ceSHans Rosenfeld 	 * normal workflow and make sure that we don't mistakenly do anything.
537*a61ed2ceSHans Rosenfeld 	 */
538*a61ed2ceSHans Rosenfeld 	prot = UINT32_MAX;
539*a61ed2ceSHans Rosenfeld 	for (;;) {
540*a61ed2ceSHans Rosenfeld 		atp = &data->atr_ti[data->atr_nti];
541*a61ed2ceSHans Rosenfeld 		data->atr_nti++;
542*a61ed2ceSHans Rosenfeld 		ASSERT3U(data->atr_nti, <=, ATR_TI_MAX);
543*a61ed2ceSHans Rosenfeld 
544*a61ed2ceSHans Rosenfeld 		/*
545*a61ed2ceSHans Rosenfeld 		 * Make sure that we have enough space to read all the cbits.
546*a61ed2ceSHans Rosenfeld 		 * idx points to the first cbit, which could also potentially be
547*a61ed2ceSHans Rosenfeld 		 * over the length of the buffer. This is why we subtract one
548*a61ed2ceSHans Rosenfeld 		 * from idx when doing the calculation.
549*a61ed2ceSHans Rosenfeld 		 */
550*a61ed2ceSHans Rosenfeld 		if (idx - 1 + ncbits >= len) {
551*a61ed2ceSHans Rosenfeld 			return (ATR_CODE_OVERRUN);
552*a61ed2ceSHans Rosenfeld 		}
553*a61ed2ceSHans Rosenfeld 
554*a61ed2ceSHans Rosenfeld 		ASSERT3U(Ti, !=, 0);
555*a61ed2ceSHans Rosenfeld 
556*a61ed2ceSHans Rosenfeld 		/*
557*a61ed2ceSHans Rosenfeld 		 * At the moment we opt to ignore reserved protocols.
558*a61ed2ceSHans Rosenfeld 		 */
559*a61ed2ceSHans Rosenfeld 		atp->atrti_protocol = prot;
560*a61ed2ceSHans Rosenfeld 		atp->atrti_ti_val = Ti;
561*a61ed2ceSHans Rosenfeld 		atp->atrti_td_idx = idx - 1;
562*a61ed2ceSHans Rosenfeld 
563*a61ed2ceSHans Rosenfeld 		if (cbits & ATR_TA_MASK) {
564*a61ed2ceSHans Rosenfeld 			atp->atrti_flags |= ATR_TI_HAVE_TA;
565*a61ed2ceSHans Rosenfeld 			atp->atrti_ta = buf[idx];
566*a61ed2ceSHans Rosenfeld 			idx++;
567*a61ed2ceSHans Rosenfeld 		}
568*a61ed2ceSHans Rosenfeld 
569*a61ed2ceSHans Rosenfeld 		if (cbits & ATR_TB_MASK) {
570*a61ed2ceSHans Rosenfeld 			atp->atrti_flags |= ATR_TI_HAVE_TB;
571*a61ed2ceSHans Rosenfeld 			atp->atrti_tb = buf[idx];
572*a61ed2ceSHans Rosenfeld 			idx++;
573*a61ed2ceSHans Rosenfeld 		}
574*a61ed2ceSHans Rosenfeld 
575*a61ed2ceSHans Rosenfeld 		if (cbits & ATR_TC_MASK) {
576*a61ed2ceSHans Rosenfeld 			atp->atrti_flags |= ATR_TI_HAVE_TC;
577*a61ed2ceSHans Rosenfeld 			atp->atrti_tc = buf[idx];
578*a61ed2ceSHans Rosenfeld 			idx++;
579*a61ed2ceSHans Rosenfeld 		}
580*a61ed2ceSHans Rosenfeld 
581*a61ed2ceSHans Rosenfeld 		if (cbits & ATR_TD_MASK) {
582*a61ed2ceSHans Rosenfeld 			atp->atrti_flags |= ATR_TI_HAVE_TD;
583*a61ed2ceSHans Rosenfeld 			atp->atrti_td = buf[idx];
584*a61ed2ceSHans Rosenfeld 			cbits = ATR_TD_NBITS(buf[idx]);
585*a61ed2ceSHans Rosenfeld 			prot = ATR_TD_PROT(buf[idx]);
586*a61ed2ceSHans Rosenfeld 			ncbits = atr_count_cbits(cbits);
587*a61ed2ceSHans Rosenfeld 			if (prot != 0)
588*a61ed2ceSHans Rosenfeld 				ncksum = 1;
589*a61ed2ceSHans Rosenfeld 
590*a61ed2ceSHans Rosenfeld 			/*
591*a61ed2ceSHans Rosenfeld 			 * T=15 is not allowed in TD1 per 8.2.3.
592*a61ed2ceSHans Rosenfeld 			 */
593*a61ed2ceSHans Rosenfeld 			if (Ti == 1 && prot == 0xf)
594*a61ed2ceSHans Rosenfeld 				return (ATR_CODE_INVALID_TD1);
595*a61ed2ceSHans Rosenfeld 
596*a61ed2ceSHans Rosenfeld 			idx++;
597*a61ed2ceSHans Rosenfeld 			/*
598*a61ed2ceSHans Rosenfeld 			 * Encountering TD means that once we take the next loop
599*a61ed2ceSHans Rosenfeld 			 * and we need to increment Ti.
600*a61ed2ceSHans Rosenfeld 			 */
601*a61ed2ceSHans Rosenfeld 			Ti++;
602*a61ed2ceSHans Rosenfeld 		} else {
603*a61ed2ceSHans Rosenfeld 			break;
604*a61ed2ceSHans Rosenfeld 		}
605*a61ed2ceSHans Rosenfeld 	}
606*a61ed2ceSHans Rosenfeld 
607*a61ed2ceSHans Rosenfeld 	/*
608*a61ed2ceSHans Rosenfeld 	 * We've parsed all of the cbits. At this point, we should take into
609*a61ed2ceSHans Rosenfeld 	 * account all of the historical bits and potentially the checksum.
610*a61ed2ceSHans Rosenfeld 	 */
611*a61ed2ceSHans Rosenfeld 	if (idx - 1 + nhist + ncksum >= len) {
612*a61ed2ceSHans Rosenfeld 		return (ATR_CODE_OVERRUN);
613*a61ed2ceSHans Rosenfeld 	}
614*a61ed2ceSHans Rosenfeld 
615*a61ed2ceSHans Rosenfeld 	if (idx + nhist + ncksum != len) {
616*a61ed2ceSHans Rosenfeld 		return (ATR_CODE_UNDERRUN);
617*a61ed2ceSHans Rosenfeld 	}
618*a61ed2ceSHans Rosenfeld 
619*a61ed2ceSHans Rosenfeld 	if (nhist > 0) {
620*a61ed2ceSHans Rosenfeld 		data->atr_nhistoric = nhist;
621*a61ed2ceSHans Rosenfeld 		bcopy(&buf[idx], data->atr_historic, nhist);
622*a61ed2ceSHans Rosenfeld 	}
623*a61ed2ceSHans Rosenfeld 
624*a61ed2ceSHans Rosenfeld 	if (ncksum > 0) {
625*a61ed2ceSHans Rosenfeld 		size_t i;
626*a61ed2ceSHans Rosenfeld 		uint8_t val;
627*a61ed2ceSHans Rosenfeld 
628*a61ed2ceSHans Rosenfeld 		/*
629*a61ed2ceSHans Rosenfeld 		 * Per ISO/IEC 7816-3:2006 Section 8.2.5 the checksum is all
630*a61ed2ceSHans Rosenfeld 		 * bytes excluding TS. Therefore, we must start at byte 1.
631*a61ed2ceSHans Rosenfeld 		 */
632*a61ed2ceSHans Rosenfeld 		for (val = 0, i = 1; i < len; i++) {
633*a61ed2ceSHans Rosenfeld 			val ^= buf[i];
634*a61ed2ceSHans Rosenfeld 		}
635*a61ed2ceSHans Rosenfeld 
636*a61ed2ceSHans Rosenfeld 		if (val != ATR_CKSUM_TARGET) {
637*a61ed2ceSHans Rosenfeld 			return (ATR_CODE_CHECKSUM_ERROR);
638*a61ed2ceSHans Rosenfeld 		}
639*a61ed2ceSHans Rosenfeld 		data->atr_flags |= ATR_F_HAS_CHECKSUM;
640*a61ed2ceSHans Rosenfeld 		data->atr_cksum = buf[len - 1];
641*a61ed2ceSHans Rosenfeld 	}
642*a61ed2ceSHans Rosenfeld 
643*a61ed2ceSHans Rosenfeld 	data->atr_flags |= ATR_F_VALID;
644*a61ed2ceSHans Rosenfeld 	return (ATR_CODE_OK);
645*a61ed2ceSHans Rosenfeld }
646*a61ed2ceSHans Rosenfeld 
647*a61ed2ceSHans Rosenfeld uint8_t
atr_fi_default_index(void)648*a61ed2ceSHans Rosenfeld atr_fi_default_index(void)
649*a61ed2ceSHans Rosenfeld {
650*a61ed2ceSHans Rosenfeld 	return (ATR_FI_DEFAULT_INDEX);
651*a61ed2ceSHans Rosenfeld }
652*a61ed2ceSHans Rosenfeld 
653*a61ed2ceSHans Rosenfeld uint8_t
atr_di_default_index(void)654*a61ed2ceSHans Rosenfeld atr_di_default_index(void)
655*a61ed2ceSHans Rosenfeld {
656*a61ed2ceSHans Rosenfeld 	return (ATR_DI_DEFAULT_INDEX);
657*a61ed2ceSHans Rosenfeld }
658*a61ed2ceSHans Rosenfeld 
659*a61ed2ceSHans Rosenfeld /*
660*a61ed2ceSHans Rosenfeld  * Parse the data to determine which protocols are supported in this atr data.
661*a61ed2ceSHans Rosenfeld  * Based on this, users can come and ask us to fill in protocol information.
662*a61ed2ceSHans Rosenfeld  */
663*a61ed2ceSHans Rosenfeld atr_protocol_t
atr_supported_protocols(atr_data_t * data)664*a61ed2ceSHans Rosenfeld atr_supported_protocols(atr_data_t *data)
665*a61ed2ceSHans Rosenfeld {
666*a61ed2ceSHans Rosenfeld 	uint_t i;
667*a61ed2ceSHans Rosenfeld 	atr_protocol_t prot;
668*a61ed2ceSHans Rosenfeld 
669*a61ed2ceSHans Rosenfeld 	if ((data->atr_flags & ATR_F_VALID) == 0)
670*a61ed2ceSHans Rosenfeld 		return (ATR_P_NONE);
671*a61ed2ceSHans Rosenfeld 
672*a61ed2ceSHans Rosenfeld 	/*
673*a61ed2ceSHans Rosenfeld 	 * Based on 8.2.3 of ISO/IEC 7816-3:2006, if TD1 is present, then that
674*a61ed2ceSHans Rosenfeld 	 * indicates the first protocol. However, if it is not present, then
675*a61ed2ceSHans Rosenfeld 	 * that implies that T=0 is the only supported protocol. Otherwise, all
676*a61ed2ceSHans Rosenfeld 	 * protocols are referenced in ascending order. The first entry in
677*a61ed2ceSHans Rosenfeld 	 * atr_ti refers to data from T0, so the protocol in the second entry
678*a61ed2ceSHans Rosenfeld 	 * would have the TD1 data.
679*a61ed2ceSHans Rosenfeld 	 */
680*a61ed2ceSHans Rosenfeld 	if (data->atr_nti < 2) {
681*a61ed2ceSHans Rosenfeld 		return (ATR_P_T0);
682*a61ed2ceSHans Rosenfeld 	}
683*a61ed2ceSHans Rosenfeld 
684*a61ed2ceSHans Rosenfeld 	prot = ATR_P_NONE;
685*a61ed2ceSHans Rosenfeld 	for (i = 0; i < data->atr_nti; i++) {
686*a61ed2ceSHans Rosenfeld 		switch (data->atr_ti[i].atrti_protocol) {
687*a61ed2ceSHans Rosenfeld 		case ATR_PROTOCOL_T0:
688*a61ed2ceSHans Rosenfeld 			prot |= ATR_P_T0;
689*a61ed2ceSHans Rosenfeld 			break;
690*a61ed2ceSHans Rosenfeld 		case ATR_PROTOCOL_T1:
691*a61ed2ceSHans Rosenfeld 			prot |= ATR_P_T1;
692*a61ed2ceSHans Rosenfeld 			break;
693*a61ed2ceSHans Rosenfeld 		default:
694*a61ed2ceSHans Rosenfeld 			/*
695*a61ed2ceSHans Rosenfeld 			 * T=15 is not a protocol, and all other protocol values
696*a61ed2ceSHans Rosenfeld 			 * are currently reserved for future use.
697*a61ed2ceSHans Rosenfeld 			 */
698*a61ed2ceSHans Rosenfeld 			continue;
699*a61ed2ceSHans Rosenfeld 		}
700*a61ed2ceSHans Rosenfeld 	}
701*a61ed2ceSHans Rosenfeld 
702*a61ed2ceSHans Rosenfeld 	/*
703*a61ed2ceSHans Rosenfeld 	 * It's possible we've found nothing specific in the above loop (for
704*a61ed2ceSHans Rosenfeld 	 * example, only T=15 global bits were found). In that case, the card
705*a61ed2ceSHans Rosenfeld 	 * defaults to T=0.
706*a61ed2ceSHans Rosenfeld 	 */
707*a61ed2ceSHans Rosenfeld 	if (prot == ATR_P_NONE)
708*a61ed2ceSHans Rosenfeld 		prot = ATR_P_T0;
709*a61ed2ceSHans Rosenfeld 
710*a61ed2ceSHans Rosenfeld 	return (prot);
711*a61ed2ceSHans Rosenfeld }
712*a61ed2ceSHans Rosenfeld 
713*a61ed2ceSHans Rosenfeld boolean_t
atr_params_negotiable(atr_data_t * data)714*a61ed2ceSHans Rosenfeld atr_params_negotiable(atr_data_t *data)
715*a61ed2ceSHans Rosenfeld {
716*a61ed2ceSHans Rosenfeld 	/* If for some reason we're called with invalid data, assume it's not */
717*a61ed2ceSHans Rosenfeld 	if ((data->atr_flags & ATR_F_VALID) == 0)
718*a61ed2ceSHans Rosenfeld 		return (B_FALSE);
719*a61ed2ceSHans Rosenfeld 
720*a61ed2ceSHans Rosenfeld 
721*a61ed2ceSHans Rosenfeld 	/*
722*a61ed2ceSHans Rosenfeld 	 * Whether or not we're negotiable is in the second global page, so atr
723*a61ed2ceSHans Rosenfeld 	 * index 1. If TA2 is missing, then the card always is negotiable.
724*a61ed2ceSHans Rosenfeld 	 */
725*a61ed2ceSHans Rosenfeld 	if (data->atr_nti < 2 ||
726*a61ed2ceSHans Rosenfeld 	    (data->atr_ti[1].atrti_flags & ATR_TI_HAVE_TA) == 0) {
727*a61ed2ceSHans Rosenfeld 		return (B_TRUE);
728*a61ed2ceSHans Rosenfeld 	}
729*a61ed2ceSHans Rosenfeld 
730*a61ed2ceSHans Rosenfeld 	if (ATR_TA2_CANCHANGE(data->atr_ti[1].atrti_ta)) {
731*a61ed2ceSHans Rosenfeld 		return (B_TRUE);
732*a61ed2ceSHans Rosenfeld 	}
733*a61ed2ceSHans Rosenfeld 
734*a61ed2ceSHans Rosenfeld 	return (B_FALSE);
735*a61ed2ceSHans Rosenfeld }
736*a61ed2ceSHans Rosenfeld 
737*a61ed2ceSHans Rosenfeld atr_protocol_t
atr_default_protocol(atr_data_t * data)738*a61ed2ceSHans Rosenfeld atr_default_protocol(atr_data_t *data)
739*a61ed2ceSHans Rosenfeld {
740*a61ed2ceSHans Rosenfeld 	uint8_t prot;
741*a61ed2ceSHans Rosenfeld 
742*a61ed2ceSHans Rosenfeld 	if ((data->atr_flags & ATR_F_VALID) == 0)
743*a61ed2ceSHans Rosenfeld 		return (ATR_P_NONE);
744*a61ed2ceSHans Rosenfeld 	/*
745*a61ed2ceSHans Rosenfeld 	 * If we don't have an TA2 byte, then the system defaults to T=0.
746*a61ed2ceSHans Rosenfeld 	 */
747*a61ed2ceSHans Rosenfeld 	if (data->atr_nti < 2) {
748*a61ed2ceSHans Rosenfeld 		return (ATR_P_T0);
749*a61ed2ceSHans Rosenfeld 	}
750*a61ed2ceSHans Rosenfeld 
751*a61ed2ceSHans Rosenfeld 	/*
752*a61ed2ceSHans Rosenfeld 	 * If TA2 is present, then it encodes the default protocol. Otherwise,
753*a61ed2ceSHans Rosenfeld 	 * we have to grab the protocol value from TD1, which is called the
754*a61ed2ceSHans Rosenfeld 	 * 'first offered protocol'.
755*a61ed2ceSHans Rosenfeld 	 */
756*a61ed2ceSHans Rosenfeld 	if ((data->atr_ti[1].atrti_flags & ATR_TI_HAVE_TA) != 0) {
757*a61ed2ceSHans Rosenfeld 		prot = ATR_TA2_PROTOCOL(data->atr_ti[1].atrti_ta);
758*a61ed2ceSHans Rosenfeld 	} else {
759*a61ed2ceSHans Rosenfeld 		prot = data->atr_ti[1].atrti_protocol;
760*a61ed2ceSHans Rosenfeld 	}
761*a61ed2ceSHans Rosenfeld 
762*a61ed2ceSHans Rosenfeld 	switch (prot) {
763*a61ed2ceSHans Rosenfeld 	case ATR_PROTOCOL_T0:
764*a61ed2ceSHans Rosenfeld 		return (ATR_P_T0);
765*a61ed2ceSHans Rosenfeld 	case ATR_PROTOCOL_T1:
766*a61ed2ceSHans Rosenfeld 		return (ATR_P_T1);
767*a61ed2ceSHans Rosenfeld 	default:
768*a61ed2ceSHans Rosenfeld 		return (ATR_P_NONE);
769*a61ed2ceSHans Rosenfeld 	}
770*a61ed2ceSHans Rosenfeld }
771*a61ed2ceSHans Rosenfeld 
772*a61ed2ceSHans Rosenfeld uint8_t
atr_fi_index(atr_data_t * data)773*a61ed2ceSHans Rosenfeld atr_fi_index(atr_data_t *data)
774*a61ed2ceSHans Rosenfeld {
775*a61ed2ceSHans Rosenfeld 	if (data->atr_nti < 1) {
776*a61ed2ceSHans Rosenfeld 		return (ATR_FI_DEFAULT_INDEX);
777*a61ed2ceSHans Rosenfeld 	}
778*a61ed2ceSHans Rosenfeld 
779*a61ed2ceSHans Rosenfeld 	/*
780*a61ed2ceSHans Rosenfeld 	 * If TA is specified, it is present in TA1. TA2 may override its
781*a61ed2ceSHans Rosenfeld 	 * presence, so if it is here, check that first to determine whether or
782*a61ed2ceSHans Rosenfeld 	 * not we should check TA1.
783*a61ed2ceSHans Rosenfeld 	 */
784*a61ed2ceSHans Rosenfeld 	if (data->atr_nti >= 2 &&
785*a61ed2ceSHans Rosenfeld 	    (data->atr_ti[1].atrti_flags & ATR_TI_HAVE_TA) != 0) {
786*a61ed2ceSHans Rosenfeld 		if (!ATR_TA2_HONORTA1(data->atr_ti[1].atrti_ta)) {
787*a61ed2ceSHans Rosenfeld 			return (ATR_FI_DEFAULT_INDEX);
788*a61ed2ceSHans Rosenfeld 		}
789*a61ed2ceSHans Rosenfeld 	}
790*a61ed2ceSHans Rosenfeld 
791*a61ed2ceSHans Rosenfeld 	if ((data->atr_ti[0].atrti_flags & ATR_TI_HAVE_TA) != 0) {
792*a61ed2ceSHans Rosenfeld 		return (ATR_TA1_FTABLE(data->atr_ti[0].atrti_ta));
793*a61ed2ceSHans Rosenfeld 	}
794*a61ed2ceSHans Rosenfeld 
795*a61ed2ceSHans Rosenfeld 	return (ATR_FI_DEFAULT_INDEX);
796*a61ed2ceSHans Rosenfeld }
797*a61ed2ceSHans Rosenfeld 
798*a61ed2ceSHans Rosenfeld uint8_t
atr_di_index(atr_data_t * data)799*a61ed2ceSHans Rosenfeld atr_di_index(atr_data_t *data)
800*a61ed2ceSHans Rosenfeld {
801*a61ed2ceSHans Rosenfeld 	if (data->atr_nti < 1) {
802*a61ed2ceSHans Rosenfeld 		return (ATR_DI_DEFAULT_INDEX);
803*a61ed2ceSHans Rosenfeld 	}
804*a61ed2ceSHans Rosenfeld 
805*a61ed2ceSHans Rosenfeld 	/*
806*a61ed2ceSHans Rosenfeld 	 * If TA is specified, it is present in TA1. TA2 may override its
807*a61ed2ceSHans Rosenfeld 	 * presence, so if it is here, check that first to determine whether or
808*a61ed2ceSHans Rosenfeld 	 * not we should check TA1.
809*a61ed2ceSHans Rosenfeld 	 */
810*a61ed2ceSHans Rosenfeld 	if (data->atr_nti >= 2 &&
811*a61ed2ceSHans Rosenfeld 	    (data->atr_ti[1].atrti_flags & ATR_TI_HAVE_TA) != 0) {
812*a61ed2ceSHans Rosenfeld 		if (!ATR_TA2_HONORTA1(data->atr_ti[1].atrti_ta)) {
813*a61ed2ceSHans Rosenfeld 			return (ATR_DI_DEFAULT_INDEX);
814*a61ed2ceSHans Rosenfeld 		}
815*a61ed2ceSHans Rosenfeld 	}
816*a61ed2ceSHans Rosenfeld 
817*a61ed2ceSHans Rosenfeld 	if ((data->atr_ti[0].atrti_flags & ATR_TI_HAVE_TA) != 0) {
818*a61ed2ceSHans Rosenfeld 		return (ATR_TA1_DITABLE(data->atr_ti[0].atrti_ta));
819*a61ed2ceSHans Rosenfeld 	}
820*a61ed2ceSHans Rosenfeld 
821*a61ed2ceSHans Rosenfeld 	return (ATR_DI_DEFAULT_INDEX);
822*a61ed2ceSHans Rosenfeld }
823*a61ed2ceSHans Rosenfeld 
824*a61ed2ceSHans Rosenfeld atr_convention_t
atr_convention(atr_data_t * data)825*a61ed2ceSHans Rosenfeld atr_convention(atr_data_t *data)
826*a61ed2ceSHans Rosenfeld {
827*a61ed2ceSHans Rosenfeld 	if ((data->atr_flags & ATR_F_USES_DIRECT) != 0) {
828*a61ed2ceSHans Rosenfeld 		return (ATR_CONVENTION_DIRECT);
829*a61ed2ceSHans Rosenfeld 	}
830*a61ed2ceSHans Rosenfeld 	return (ATR_CONVENTION_INVERSE);
831*a61ed2ceSHans Rosenfeld }
832*a61ed2ceSHans Rosenfeld 
833*a61ed2ceSHans Rosenfeld uint8_t
atr_extra_guardtime(atr_data_t * data)834*a61ed2ceSHans Rosenfeld atr_extra_guardtime(atr_data_t *data)
835*a61ed2ceSHans Rosenfeld {
836*a61ed2ceSHans Rosenfeld 	if ((data->atr_flags & ATR_F_VALID) == 0)
837*a61ed2ceSHans Rosenfeld 		return (ATR_EXTRA_GUARDTIME_DEFAULT);
838*a61ed2ceSHans Rosenfeld 
839*a61ed2ceSHans Rosenfeld 	if (data->atr_nti >= 1 &&
840*a61ed2ceSHans Rosenfeld 	    (data->atr_ti[0].atrti_flags & ATR_TI_HAVE_TC) != 0) {
841*a61ed2ceSHans Rosenfeld 		return (data->atr_ti[0].atrti_tc);
842*a61ed2ceSHans Rosenfeld 	}
843*a61ed2ceSHans Rosenfeld 
844*a61ed2ceSHans Rosenfeld 	return (ATR_EXTRA_GUARDTIME_DEFAULT);
845*a61ed2ceSHans Rosenfeld }
846*a61ed2ceSHans Rosenfeld 
847*a61ed2ceSHans Rosenfeld uint8_t
atr_t0_wi(atr_data_t * data)848*a61ed2ceSHans Rosenfeld atr_t0_wi(atr_data_t *data)
849*a61ed2ceSHans Rosenfeld {
850*a61ed2ceSHans Rosenfeld 	if ((data->atr_flags & ATR_F_VALID) == 0)
851*a61ed2ceSHans Rosenfeld 		return (ATR_T0_WI_DEFAULT);
852*a61ed2ceSHans Rosenfeld 
853*a61ed2ceSHans Rosenfeld 	/*
854*a61ed2ceSHans Rosenfeld 	 * This is stored in the optional global byte in TC2; however, it only
855*a61ed2ceSHans Rosenfeld 	 * applies to T=0.
856*a61ed2ceSHans Rosenfeld 	 */
857*a61ed2ceSHans Rosenfeld 	if (data->atr_nti >= 2 &&
858*a61ed2ceSHans Rosenfeld 	    data->atr_ti[1].atrti_protocol == ATR_PROTOCOL_T0 &&
859*a61ed2ceSHans Rosenfeld 	    (data->atr_ti[1].atrti_flags & ATR_TI_HAVE_TC) != 0) {
860*a61ed2ceSHans Rosenfeld 		return (data->atr_ti[1].atrti_tc);
861*a61ed2ceSHans Rosenfeld 	}
862*a61ed2ceSHans Rosenfeld 
863*a61ed2ceSHans Rosenfeld 	return (ATR_T0_WI_DEFAULT);
864*a61ed2ceSHans Rosenfeld }
865*a61ed2ceSHans Rosenfeld 
866*a61ed2ceSHans Rosenfeld uint8_t
atr_t1_cwi(atr_data_t * data)867*a61ed2ceSHans Rosenfeld atr_t1_cwi(atr_data_t *data)
868*a61ed2ceSHans Rosenfeld {
869*a61ed2ceSHans Rosenfeld 	uint8_t i;
870*a61ed2ceSHans Rosenfeld 
871*a61ed2ceSHans Rosenfeld 	if (data->atr_nti <= 2) {
872*a61ed2ceSHans Rosenfeld 		return (ATR_T1_CWI_DEFAULT);
873*a61ed2ceSHans Rosenfeld 	}
874*a61ed2ceSHans Rosenfeld 
875*a61ed2ceSHans Rosenfeld 	for (i = 2; i < data->atr_nti; i++) {
876*a61ed2ceSHans Rosenfeld 		if (data->atr_ti[i].atrti_protocol == ATR_PROTOCOL_T1) {
877*a61ed2ceSHans Rosenfeld 			if ((data->atr_ti[i].atrti_flags & ATR_TI_HAVE_TB) !=
878*a61ed2ceSHans Rosenfeld 			    0) {
879*a61ed2ceSHans Rosenfeld 				uint8_t tb = data->atr_ti[i].atrti_tb;
880*a61ed2ceSHans Rosenfeld 				return (ATR_T1_TB0_CWI(tb));
881*a61ed2ceSHans Rosenfeld 			}
882*a61ed2ceSHans Rosenfeld 
883*a61ed2ceSHans Rosenfeld 			return (ATR_T1_CWI_DEFAULT);
884*a61ed2ceSHans Rosenfeld 		}
885*a61ed2ceSHans Rosenfeld 	}
886*a61ed2ceSHans Rosenfeld 
887*a61ed2ceSHans Rosenfeld 	return (ATR_T1_CWI_DEFAULT);
888*a61ed2ceSHans Rosenfeld }
889*a61ed2ceSHans Rosenfeld 
890*a61ed2ceSHans Rosenfeld atr_clock_stop_t
atr_clock_stop(atr_data_t * data)891*a61ed2ceSHans Rosenfeld atr_clock_stop(atr_data_t *data)
892*a61ed2ceSHans Rosenfeld {
893*a61ed2ceSHans Rosenfeld 	uint8_t i;
894*a61ed2ceSHans Rosenfeld 
895*a61ed2ceSHans Rosenfeld 	for (i = 0; i < data->atr_nti; i++) {
896*a61ed2ceSHans Rosenfeld 		if (data->atr_ti[i].atrti_protocol == ATR_PROTOCOL_T15) {
897*a61ed2ceSHans Rosenfeld 			if ((data->atr_ti[i].atrti_flags & ATR_TI_HAVE_TA) !=
898*a61ed2ceSHans Rosenfeld 			    0) {
899*a61ed2ceSHans Rosenfeld 				uint8_t ta = data->atr_ti[i].atrti_ta;
900*a61ed2ceSHans Rosenfeld 				return (ATR_T15_TA0_CLOCK(ta));
901*a61ed2ceSHans Rosenfeld 			}
902*a61ed2ceSHans Rosenfeld 
903*a61ed2ceSHans Rosenfeld 			return (ATR_CLOCK_STOP_NONE);
904*a61ed2ceSHans Rosenfeld 		}
905*a61ed2ceSHans Rosenfeld 	}
906*a61ed2ceSHans Rosenfeld 
907*a61ed2ceSHans Rosenfeld 	return (ATR_CLOCK_STOP_NONE);
908*a61ed2ceSHans Rosenfeld }
909*a61ed2ceSHans Rosenfeld 
910*a61ed2ceSHans Rosenfeld atr_t1_checksum_t
atr_t1_checksum(atr_data_t * data)911*a61ed2ceSHans Rosenfeld atr_t1_checksum(atr_data_t *data)
912*a61ed2ceSHans Rosenfeld {
913*a61ed2ceSHans Rosenfeld 	uint8_t i;
914*a61ed2ceSHans Rosenfeld 
915*a61ed2ceSHans Rosenfeld 	if (data->atr_nti <= 2) {
916*a61ed2ceSHans Rosenfeld 		return (ATR_T1_CHECKSUM_DEFAULT);
917*a61ed2ceSHans Rosenfeld 	}
918*a61ed2ceSHans Rosenfeld 
919*a61ed2ceSHans Rosenfeld 	for (i = 2; i < data->atr_nti; i++) {
920*a61ed2ceSHans Rosenfeld 		if (data->atr_ti[i].atrti_protocol == ATR_PROTOCOL_T1) {
921*a61ed2ceSHans Rosenfeld 			if ((data->atr_ti[i].atrti_flags & ATR_TI_HAVE_TC) !=
922*a61ed2ceSHans Rosenfeld 			    0) {
923*a61ed2ceSHans Rosenfeld 				if (ATR_T1_TC0_CRC(data->atr_ti[i].atrti_tc)) {
924*a61ed2ceSHans Rosenfeld 					return (ATR_T1_CHECKSUM_CRC);
925*a61ed2ceSHans Rosenfeld 				} else {
926*a61ed2ceSHans Rosenfeld 					return (ATR_T1_CHECKSUM_LRC);
927*a61ed2ceSHans Rosenfeld 				}
928*a61ed2ceSHans Rosenfeld 			}
929*a61ed2ceSHans Rosenfeld 
930*a61ed2ceSHans Rosenfeld 			return (ATR_T1_CHECKSUM_DEFAULT);
931*a61ed2ceSHans Rosenfeld 		}
932*a61ed2ceSHans Rosenfeld 	}
933*a61ed2ceSHans Rosenfeld 
934*a61ed2ceSHans Rosenfeld 	return (ATR_T1_CHECKSUM_DEFAULT);
935*a61ed2ceSHans Rosenfeld 
936*a61ed2ceSHans Rosenfeld }
937*a61ed2ceSHans Rosenfeld 
938*a61ed2ceSHans Rosenfeld uint8_t
atr_t1_bwi(atr_data_t * data)939*a61ed2ceSHans Rosenfeld atr_t1_bwi(atr_data_t *data)
940*a61ed2ceSHans Rosenfeld {
941*a61ed2ceSHans Rosenfeld 	uint8_t i;
942*a61ed2ceSHans Rosenfeld 
943*a61ed2ceSHans Rosenfeld 	if (data->atr_nti <= 2) {
944*a61ed2ceSHans Rosenfeld 		return (ATR_T1_BWI_DEFAULT);
945*a61ed2ceSHans Rosenfeld 	}
946*a61ed2ceSHans Rosenfeld 
947*a61ed2ceSHans Rosenfeld 	for (i = 2; i < data->atr_nti; i++) {
948*a61ed2ceSHans Rosenfeld 		if (data->atr_ti[i].atrti_protocol == ATR_PROTOCOL_T1) {
949*a61ed2ceSHans Rosenfeld 			if ((data->atr_ti[i].atrti_flags & ATR_TI_HAVE_TB) !=
950*a61ed2ceSHans Rosenfeld 			    0) {
951*a61ed2ceSHans Rosenfeld 				uint8_t tb = data->atr_ti[i].atrti_tb;
952*a61ed2ceSHans Rosenfeld 				return (ATR_T1_TB0_BWI(tb));
953*a61ed2ceSHans Rosenfeld 			}
954*a61ed2ceSHans Rosenfeld 
955*a61ed2ceSHans Rosenfeld 			return (ATR_T1_BWI_DEFAULT);
956*a61ed2ceSHans Rosenfeld 		}
957*a61ed2ceSHans Rosenfeld 	}
958*a61ed2ceSHans Rosenfeld 
959*a61ed2ceSHans Rosenfeld 	return (ATR_T1_BWI_DEFAULT);
960*a61ed2ceSHans Rosenfeld }
961*a61ed2ceSHans Rosenfeld 
962*a61ed2ceSHans Rosenfeld uint8_t
atr_t1_ifsc(atr_data_t * data)963*a61ed2ceSHans Rosenfeld atr_t1_ifsc(atr_data_t *data)
964*a61ed2ceSHans Rosenfeld {
965*a61ed2ceSHans Rosenfeld 	uint8_t i;
966*a61ed2ceSHans Rosenfeld 
967*a61ed2ceSHans Rosenfeld 	if (data->atr_nti <= 2) {
968*a61ed2ceSHans Rosenfeld 		return (ATR_T1_IFSC_DEFAULT);
969*a61ed2ceSHans Rosenfeld 	}
970*a61ed2ceSHans Rosenfeld 
971*a61ed2ceSHans Rosenfeld 	for (i = 2; i < data->atr_nti; i++) {
972*a61ed2ceSHans Rosenfeld 		if (data->atr_ti[i].atrti_protocol == ATR_PROTOCOL_T1) {
973*a61ed2ceSHans Rosenfeld 			if ((data->atr_ti[i].atrti_flags & ATR_TI_HAVE_TA) !=
974*a61ed2ceSHans Rosenfeld 			    0) {
975*a61ed2ceSHans Rosenfeld 				return (data->atr_ti[i].atrti_ta);
976*a61ed2ceSHans Rosenfeld 			}
977*a61ed2ceSHans Rosenfeld 
978*a61ed2ceSHans Rosenfeld 			return (ATR_T1_IFSC_DEFAULT);
979*a61ed2ceSHans Rosenfeld 		}
980*a61ed2ceSHans Rosenfeld 	}
981*a61ed2ceSHans Rosenfeld 
982*a61ed2ceSHans Rosenfeld 	return (ATR_T1_IFSC_DEFAULT);
983*a61ed2ceSHans Rosenfeld }
984*a61ed2ceSHans Rosenfeld 
985*a61ed2ceSHans Rosenfeld /*
986*a61ed2ceSHans Rosenfeld  * Attempt to determine which set of data rates we should be able to use for a
987*a61ed2ceSHans Rosenfeld  * given class of protocol. Here we want to do the calculation based on the CCID
988*a61ed2ceSHans Rosenfeld  * specification, section 9.4.x. To use these higher rates we need:
989*a61ed2ceSHans Rosenfeld  *
990*a61ed2ceSHans Rosenfeld  * + Reader's data rate > frequency * Di / Fi.
991*a61ed2ceSHans Rosenfeld  *
992*a61ed2ceSHans Rosenfeld  * To determine which rate and frequency we use, we look at the reader's
993*a61ed2ceSHans Rosenfeld  * features. If the reader supports both the Automatic baud rate and automatic
994*a61ed2ceSHans Rosenfeld  * ICC clock frequency change, then we use the _maximum_ rate. Otherwise we will
995*a61ed2ceSHans Rosenfeld  * indicate that we can use the ATR's properties, but will require changing the
996*a61ed2ceSHans Rosenfeld  * default data rate.
997*a61ed2ceSHans Rosenfeld  *
998*a61ed2ceSHans Rosenfeld  * Now, some ICC devices are not negotiable. In those cases, we'll see if we can
999*a61ed2ceSHans Rosenfeld  * fit it in with either the default or maximum data rates. If not, then we'll
1000*a61ed2ceSHans Rosenfeld  * not be able to support this card.
1001*a61ed2ceSHans Rosenfeld  *
1002*a61ed2ceSHans Rosenfeld  * There are two wrinkles that exist in this. The first is supported frequencies
1003*a61ed2ceSHans Rosenfeld  * and data rates. If there are no additional data rates supported, then all of
1004*a61ed2ceSHans Rosenfeld  * the data rates between the default and max are supported. If not, then only
1005*a61ed2ceSHans Rosenfeld  * those specified in the data rates array are supported.
1006*a61ed2ceSHans Rosenfeld  *
1007*a61ed2ceSHans Rosenfeld  * The second hurdle is that we need to do this division and try and avoid the
1008*a61ed2ceSHans Rosenfeld  * pitfalls of floating point arithmetic, as floating point is not allowed in
1009*a61ed2ceSHans Rosenfeld  * the kernel (and this is shared). Importantly that means only integers are
1010*a61ed2ceSHans Rosenfeld  * allowed here.
1011*a61ed2ceSHans Rosenfeld  */
1012*a61ed2ceSHans Rosenfeld atr_data_rate_choice_t
atr_data_rate(atr_data_t * data,ccid_class_descr_t * class,uint32_t * rates,uint_t nrates,uint32_t * dataratep)1013*a61ed2ceSHans Rosenfeld atr_data_rate(atr_data_t *data, ccid_class_descr_t *class, uint32_t *rates,
1014*a61ed2ceSHans Rosenfeld     uint_t nrates, uint32_t *dataratep)
1015*a61ed2ceSHans Rosenfeld {
1016*a61ed2ceSHans Rosenfeld 	uint_t nfeats = CCID_CLASS_F_AUTO_ICC_CLOCK | CCID_CLASS_F_AUTO_BAUD;
1017*a61ed2ceSHans Rosenfeld 	uint8_t di, fi;
1018*a61ed2ceSHans Rosenfeld 	uint_t dival, fival;
1019*a61ed2ceSHans Rosenfeld 	boolean_t autospeed, negotiable, exprates;
1020*a61ed2ceSHans Rosenfeld 	uint64_t maxval, defval;
1021*a61ed2ceSHans Rosenfeld 
1022*a61ed2ceSHans Rosenfeld 	if ((data->atr_flags & ATR_F_VALID) == 0)
1023*a61ed2ceSHans Rosenfeld 		return (ATR_RATE_UNSUPPORTED);
1024*a61ed2ceSHans Rosenfeld 
1025*a61ed2ceSHans Rosenfeld 	di = atr_di_index(data);
1026*a61ed2ceSHans Rosenfeld 	fi = atr_fi_index(data);
1027*a61ed2ceSHans Rosenfeld 	dival = atr_di_index_to_value(di);
1028*a61ed2ceSHans Rosenfeld 	fival = atr_fi_index_to_value(fi);
1029*a61ed2ceSHans Rosenfeld 	autospeed = (class->ccd_dwFeatures & nfeats) == nfeats;
1030*a61ed2ceSHans Rosenfeld 	exprates = class->ccd_bNumDataRatesSupported != 0;
1031*a61ed2ceSHans Rosenfeld 	negotiable = atr_params_negotiable(data);
1032*a61ed2ceSHans Rosenfeld 
1033*a61ed2ceSHans Rosenfeld 	/*
1034*a61ed2ceSHans Rosenfeld 	 * We don't support cards with fixed rates at this time as it's not
1035*a61ed2ceSHans Rosenfeld 	 * clear what that rate should be. If it's negotiable, we'll let them
1036*a61ed2ceSHans Rosenfeld 	 * run at the default. Otherwise, we have to fail the request until
1037*a61ed2ceSHans Rosenfeld 	 * we implement the logic to search their data rates.
1038*a61ed2ceSHans Rosenfeld 	 */
1039*a61ed2ceSHans Rosenfeld 	if (exprates) {
1040*a61ed2ceSHans Rosenfeld 		if (negotiable) {
1041*a61ed2ceSHans Rosenfeld 			return (ATR_RATE_USEDEFAULT);
1042*a61ed2ceSHans Rosenfeld 		}
1043*a61ed2ceSHans Rosenfeld 		return (ATR_RATE_UNSUPPORTED);
1044*a61ed2ceSHans Rosenfeld 	}
1045*a61ed2ceSHans Rosenfeld 
1046*a61ed2ceSHans Rosenfeld 	/*
1047*a61ed2ceSHans Rosenfeld 	 * This indicates that the card gave us values that were reserved for
1048*a61ed2ceSHans Rosenfeld 	 * future use. If we could negotiate it, then just stick with the
1049*a61ed2ceSHans Rosenfeld 	 * default paramters. Otherwise, return that we can't support this ICC.
1050*a61ed2ceSHans Rosenfeld 	 */
1051*a61ed2ceSHans Rosenfeld 	if (dival == 0 || fival == 0) {
1052*a61ed2ceSHans Rosenfeld 		if (negotiable)
1053*a61ed2ceSHans Rosenfeld 			return (ATR_RATE_USEDEFAULT);
1054*a61ed2ceSHans Rosenfeld 		return (ATR_RATE_UNSUPPORTED);
1055*a61ed2ceSHans Rosenfeld 	}
1056*a61ed2ceSHans Rosenfeld 
1057*a61ed2ceSHans Rosenfeld 	/*
1058*a61ed2ceSHans Rosenfeld 	 * Calculate the maximum and default values.
1059*a61ed2ceSHans Rosenfeld 	 */
1060*a61ed2ceSHans Rosenfeld 	maxval = class->ccd_dwMaximumClock * 1000;
1061*a61ed2ceSHans Rosenfeld 	maxval *= dival;
1062*a61ed2ceSHans Rosenfeld 	maxval /= fival;
1063*a61ed2ceSHans Rosenfeld 
1064*a61ed2ceSHans Rosenfeld 	defval = class->ccd_dwDefaultClock * 1000;
1065*a61ed2ceSHans Rosenfeld 	defval *= dival;
1066*a61ed2ceSHans Rosenfeld 	defval /= fival;
1067*a61ed2ceSHans Rosenfeld 
1068*a61ed2ceSHans Rosenfeld 	/*
1069*a61ed2ceSHans Rosenfeld 	 * We're allowed any set of data rates between the default and the
1070*a61ed2ceSHans Rosenfeld 	 * maximum. Check if the maximum data rate will work for either the
1071*a61ed2ceSHans Rosenfeld 	 * default or maximum clock. If so, then we can use the cards rates.
1072*a61ed2ceSHans Rosenfeld 	 *
1073*a61ed2ceSHans Rosenfeld 	 * To account for the fact that we may have had a fractional value,
1074*a61ed2ceSHans Rosenfeld 	 * we require a strict greater than comparison.
1075*a61ed2ceSHans Rosenfeld 	 */
1076*a61ed2ceSHans Rosenfeld 	if ((uint64_t)class->ccd_dwMaxDataRate > maxval ||
1077*a61ed2ceSHans Rosenfeld 	    (uint64_t)class->ccd_dwMaxDataRate > defval) {
1078*a61ed2ceSHans Rosenfeld 		if (autospeed) {
1079*a61ed2ceSHans Rosenfeld 			return (ATR_RATE_USEATR);
1080*a61ed2ceSHans Rosenfeld 		}
1081*a61ed2ceSHans Rosenfeld 	}
1082*a61ed2ceSHans Rosenfeld 
1083*a61ed2ceSHans Rosenfeld 	/*
1084*a61ed2ceSHans Rosenfeld 	 * If the CCID reader can't handle the ICC's proposed rates, then fall
1085*a61ed2ceSHans Rosenfeld 	 * back to the defaults if we're allowed to negotiate. Otherwise, we're
1086*a61ed2ceSHans Rosenfeld 	 * not able to use this ICC.
1087*a61ed2ceSHans Rosenfeld 	 */
1088*a61ed2ceSHans Rosenfeld 	if (negotiable) {
1089*a61ed2ceSHans Rosenfeld 		return (ATR_RATE_USEDEFAULT);
1090*a61ed2ceSHans Rosenfeld 	}
1091*a61ed2ceSHans Rosenfeld 
1092*a61ed2ceSHans Rosenfeld 	return (ATR_RATE_UNSUPPORTED);
1093*a61ed2ceSHans Rosenfeld }
1094*a61ed2ceSHans Rosenfeld 
1095*a61ed2ceSHans Rosenfeld void
atr_data_reset(atr_data_t * data)1096*a61ed2ceSHans Rosenfeld atr_data_reset(atr_data_t *data)
1097*a61ed2ceSHans Rosenfeld {
1098*a61ed2ceSHans Rosenfeld 	bzero(data, sizeof (*data));
1099*a61ed2ceSHans Rosenfeld }
1100*a61ed2ceSHans Rosenfeld 
1101*a61ed2ceSHans Rosenfeld #ifdef	_KERNEL
1102*a61ed2ceSHans Rosenfeld atr_data_t *
atr_data_alloc(void)1103*a61ed2ceSHans Rosenfeld atr_data_alloc(void)
1104*a61ed2ceSHans Rosenfeld {
1105*a61ed2ceSHans Rosenfeld 	return (kmem_zalloc(sizeof (atr_data_t), KM_SLEEP));
1106*a61ed2ceSHans Rosenfeld }
1107*a61ed2ceSHans Rosenfeld 
1108*a61ed2ceSHans Rosenfeld void
atr_data_free(atr_data_t * data)1109*a61ed2ceSHans Rosenfeld atr_data_free(atr_data_t *data)
1110*a61ed2ceSHans Rosenfeld {
1111*a61ed2ceSHans Rosenfeld 	kmem_free(data, sizeof (atr_data_t));
1112*a61ed2ceSHans Rosenfeld }
1113*a61ed2ceSHans Rosenfeld 
1114*a61ed2ceSHans Rosenfeld /*
1115*a61ed2ceSHans Rosenfeld  * Make sure that the response we got from the ICC is valid. It must pass
1116*a61ed2ceSHans Rosenfeld  * checksum and have the PPSS value set correctly. The protocol must match
1117*a61ed2ceSHans Rosenfeld  * what we requested; however, the PPS1-3 bits are a bit different. They may
1118*a61ed2ceSHans Rosenfeld  * only be set in the response if we set them in the request. However, they
1119*a61ed2ceSHans Rosenfeld  * do not have to be set in the response.
1120*a61ed2ceSHans Rosenfeld  */
1121*a61ed2ceSHans Rosenfeld boolean_t
atr_pps_valid(void * reqbuf,size_t reqlen,void * respbuf,size_t resplen)1122*a61ed2ceSHans Rosenfeld atr_pps_valid(void *reqbuf, size_t reqlen, void *respbuf, size_t resplen)
1123*a61ed2ceSHans Rosenfeld {
1124*a61ed2ceSHans Rosenfeld 	uint8_t val, i, reqidx, respidx;
1125*a61ed2ceSHans Rosenfeld 	uint8_t *req = reqbuf, *resp = respbuf;
1126*a61ed2ceSHans Rosenfeld 
1127*a61ed2ceSHans Rosenfeld 	if (resplen > PPS_LEN_MAX || resplen < PPS_LEN_MIN)
1128*a61ed2ceSHans Rosenfeld 		return (B_FALSE);
1129*a61ed2ceSHans Rosenfeld 
1130*a61ed2ceSHans Rosenfeld 	/*
1131*a61ed2ceSHans Rosenfeld 	 * Before we validate the data, make sure the checksum is valid.
1132*a61ed2ceSHans Rosenfeld 	 */
1133*a61ed2ceSHans Rosenfeld 	for (i = 0, val = 0; i < resplen; i++) {
1134*a61ed2ceSHans Rosenfeld 		val ^= resp[i];
1135*a61ed2ceSHans Rosenfeld 	}
1136*a61ed2ceSHans Rosenfeld 
1137*a61ed2ceSHans Rosenfeld 	/* Checksum failure */
1138*a61ed2ceSHans Rosenfeld 	if (val != 0) {
1139*a61ed2ceSHans Rosenfeld 		return (B_FALSE);
1140*a61ed2ceSHans Rosenfeld 	}
1141*a61ed2ceSHans Rosenfeld 
1142*a61ed2ceSHans Rosenfeld 	/*
1143*a61ed2ceSHans Rosenfeld 	 * We should always have PPSS echoed back as we set it.
1144*a61ed2ceSHans Rosenfeld 	 */
1145*a61ed2ceSHans Rosenfeld 	if (resp[PPS_PPSS_INDEX] != PPS_PPSS_VAL) {
1146*a61ed2ceSHans Rosenfeld 		return (B_FALSE);
1147*a61ed2ceSHans Rosenfeld 	}
1148*a61ed2ceSHans Rosenfeld 
1149*a61ed2ceSHans Rosenfeld 	/*
1150*a61ed2ceSHans Rosenfeld 	 * Go through and make sure the number of bytes present makes sense for
1151*a61ed2ceSHans Rosenfeld 	 * the number of bits set in PPS1.
1152*a61ed2ceSHans Rosenfeld 	 */
1153*a61ed2ceSHans Rosenfeld 	val = PPS_LEN_MIN;
1154*a61ed2ceSHans Rosenfeld 	if (resp[PPS_PPS0_INDEX] & PPS_PPS0_PPS1)
1155*a61ed2ceSHans Rosenfeld 		val++;
1156*a61ed2ceSHans Rosenfeld 	if (resp[PPS_PPS0_INDEX] & PPS_PPS0_PPS2)
1157*a61ed2ceSHans Rosenfeld 		val++;
1158*a61ed2ceSHans Rosenfeld 	if (resp[PPS_PPS0_INDEX] & PPS_PPS0_PPS3)
1159*a61ed2ceSHans Rosenfeld 		val++;
1160*a61ed2ceSHans Rosenfeld 	if (val != resplen)
1161*a61ed2ceSHans Rosenfeld 		return (B_FALSE);
1162*a61ed2ceSHans Rosenfeld 
1163*a61ed2ceSHans Rosenfeld 	/*
1164*a61ed2ceSHans Rosenfeld 	 * Now we've finally verified that the response is syntactically valid.
1165*a61ed2ceSHans Rosenfeld 	 * We must go through and make sure that it is semantically valid.
1166*a61ed2ceSHans Rosenfeld 	 */
1167*a61ed2ceSHans Rosenfeld 	if (PPS_PPS0_PROT(req[PPS_PPS0_INDEX]) !=
1168*a61ed2ceSHans Rosenfeld 	    PPS_PPS0_PROT(resp[PPS_PPS0_INDEX])) {
1169*a61ed2ceSHans Rosenfeld 		return (B_FALSE);
1170*a61ed2ceSHans Rosenfeld 	}
1171*a61ed2ceSHans Rosenfeld 
1172*a61ed2ceSHans Rosenfeld 	/*
1173*a61ed2ceSHans Rosenfeld 	 * When checking the PPS bit and extensions, we first check in the
1174*a61ed2ceSHans Rosenfeld 	 * response as a bit in the request is allowed to not be in the
1175*a61ed2ceSHans Rosenfeld 	 * response. But not the opposite way around. We also have to keep track
1176*a61ed2ceSHans Rosenfeld 	 * of the fact that the index for values will vary.
1177*a61ed2ceSHans Rosenfeld 	 */
1178*a61ed2ceSHans Rosenfeld 	reqidx = respidx = PPS_PPS0_INDEX + 1;
1179*a61ed2ceSHans Rosenfeld 	if ((resp[PPS_PPS0_INDEX] & PPS_PPS0_PPS1) != 0) {
1180*a61ed2ceSHans Rosenfeld 		if ((req[PPS_PPS0_INDEX] & PPS_PPS0_PPS1) == 0) {
1181*a61ed2ceSHans Rosenfeld 			return (B_FALSE);
1182*a61ed2ceSHans Rosenfeld 		}
1183*a61ed2ceSHans Rosenfeld 
1184*a61ed2ceSHans Rosenfeld 		if (req[reqidx] != resp[respidx]) {
1185*a61ed2ceSHans Rosenfeld 			return (B_FALSE);
1186*a61ed2ceSHans Rosenfeld 		}
1187*a61ed2ceSHans Rosenfeld 
1188*a61ed2ceSHans Rosenfeld 		reqidx++;
1189*a61ed2ceSHans Rosenfeld 		respidx++;
1190*a61ed2ceSHans Rosenfeld 	} else if ((req[PPS_PPS0_INDEX] & PPS_PPS0_PPS1) != 0) {
1191*a61ed2ceSHans Rosenfeld 		reqidx++;
1192*a61ed2ceSHans Rosenfeld 	}
1193*a61ed2ceSHans Rosenfeld 
1194*a61ed2ceSHans Rosenfeld 	if ((resp[PPS_PPS0_INDEX] & PPS_PPS0_PPS2) != 0) {
1195*a61ed2ceSHans Rosenfeld 		if ((req[PPS_PPS0_INDEX] & PPS_PPS0_PPS2) == 0) {
1196*a61ed2ceSHans Rosenfeld 			return (B_FALSE);
1197*a61ed2ceSHans Rosenfeld 		}
1198*a61ed2ceSHans Rosenfeld 
1199*a61ed2ceSHans Rosenfeld 		if (req[reqidx] != resp[respidx]) {
1200*a61ed2ceSHans Rosenfeld 			return (B_FALSE);
1201*a61ed2ceSHans Rosenfeld 		}
1202*a61ed2ceSHans Rosenfeld 
1203*a61ed2ceSHans Rosenfeld 		reqidx++;
1204*a61ed2ceSHans Rosenfeld 		respidx++;
1205*a61ed2ceSHans Rosenfeld 	} else if ((req[PPS_PPS0_INDEX] & PPS_PPS0_PPS2) != 0) {
1206*a61ed2ceSHans Rosenfeld 		reqidx++;
1207*a61ed2ceSHans Rosenfeld 	}
1208*a61ed2ceSHans Rosenfeld 
1209*a61ed2ceSHans Rosenfeld 	if ((resp[PPS_PPS0_INDEX] & PPS_PPS0_PPS3) != 0) {
1210*a61ed2ceSHans Rosenfeld 		/*
1211*a61ed2ceSHans Rosenfeld 		 * At this time, we never specify PPS3 in a request. Therefore
1212*a61ed2ceSHans Rosenfeld 		 * if it is present in the response, treat this as an invalid
1213*a61ed2ceSHans Rosenfeld 		 * request.
1214*a61ed2ceSHans Rosenfeld 		 */
1215*a61ed2ceSHans Rosenfeld 		return (B_FALSE);
1216*a61ed2ceSHans Rosenfeld 	}
1217*a61ed2ceSHans Rosenfeld 
1218*a61ed2ceSHans Rosenfeld 	return (B_TRUE);
1219*a61ed2ceSHans Rosenfeld }
1220*a61ed2ceSHans Rosenfeld 
1221*a61ed2ceSHans Rosenfeld uint_t
atr_pps_generate(uint8_t * buf,size_t buflen,atr_protocol_t prot,boolean_t pps1,uint8_t fi,uint8_t di,boolean_t pps2,uint8_t spu)1222*a61ed2ceSHans Rosenfeld atr_pps_generate(uint8_t *buf, size_t buflen, atr_protocol_t prot,
1223*a61ed2ceSHans Rosenfeld     boolean_t pps1, uint8_t fi, uint8_t di, boolean_t pps2, uint8_t spu)
1224*a61ed2ceSHans Rosenfeld {
1225*a61ed2ceSHans Rosenfeld 	uint8_t protval, cksum, i;
1226*a61ed2ceSHans Rosenfeld 	uint_t len = 0;
1227*a61ed2ceSHans Rosenfeld 
1228*a61ed2ceSHans Rosenfeld 	if (buflen < PPS_BUFFER_MAX)
1229*a61ed2ceSHans Rosenfeld 		return (0);
1230*a61ed2ceSHans Rosenfeld 
1231*a61ed2ceSHans Rosenfeld 	buf[PPS_PPSS_INDEX] = PPS_PPSS_VAL;
1232*a61ed2ceSHans Rosenfeld 	switch (prot) {
1233*a61ed2ceSHans Rosenfeld 	case ATR_P_T0:
1234*a61ed2ceSHans Rosenfeld 		protval = 0;
1235*a61ed2ceSHans Rosenfeld 		break;
1236*a61ed2ceSHans Rosenfeld 	case ATR_P_T1:
1237*a61ed2ceSHans Rosenfeld 		protval = 1;
1238*a61ed2ceSHans Rosenfeld 		break;
1239*a61ed2ceSHans Rosenfeld 	default:
1240*a61ed2ceSHans Rosenfeld 		return (0);
1241*a61ed2ceSHans Rosenfeld 	}
1242*a61ed2ceSHans Rosenfeld 
1243*a61ed2ceSHans Rosenfeld 	buf[PPS_PPS0_INDEX] = PPS_PPS0_PROT(protval);
1244*a61ed2ceSHans Rosenfeld 	len = 2;
1245*a61ed2ceSHans Rosenfeld 	if (pps1) {
1246*a61ed2ceSHans Rosenfeld 		buf[PPS_PPS0_INDEX] |= PPS_PPS0_PPS1;
1247*a61ed2ceSHans Rosenfeld 		buf[len++] = PPS_PPS1_SETVAL(fi, di);
1248*a61ed2ceSHans Rosenfeld 	}
1249*a61ed2ceSHans Rosenfeld 
1250*a61ed2ceSHans Rosenfeld 	if (pps2) {
1251*a61ed2ceSHans Rosenfeld 		buf[PPS_PPS0_INDEX] |= PPS_PPS0_PPS2;
1252*a61ed2ceSHans Rosenfeld 		buf[len++] = spu;
1253*a61ed2ceSHans Rosenfeld 	}
1254*a61ed2ceSHans Rosenfeld 
1255*a61ed2ceSHans Rosenfeld 	/*
1256*a61ed2ceSHans Rosenfeld 	 * The checksum must xor to zero.
1257*a61ed2ceSHans Rosenfeld 	 */
1258*a61ed2ceSHans Rosenfeld 	for (i = 0, cksum = 0; i < len; i++) {
1259*a61ed2ceSHans Rosenfeld 		cksum ^= buf[i];
1260*a61ed2ceSHans Rosenfeld 	}
1261*a61ed2ceSHans Rosenfeld 	buf[len++] = cksum;
1262*a61ed2ceSHans Rosenfeld 	return (len);
1263*a61ed2ceSHans Rosenfeld }
1264*a61ed2ceSHans Rosenfeld 
1265*a61ed2ceSHans Rosenfeld /*
1266*a61ed2ceSHans Rosenfeld  * The caller of this wants to know if the Fi/Di values that they proposed were
1267*a61ed2ceSHans Rosenfeld  * accepted. The caller must have already called atr_pps_valid(). At this point,
1268*a61ed2ceSHans Rosenfeld  * we can say that the value was accepted if the PPS1 bit is set.
1269*a61ed2ceSHans Rosenfeld  */
1270*a61ed2ceSHans Rosenfeld boolean_t
atr_pps_fidi_accepted(void * respbuf,size_t len)1271*a61ed2ceSHans Rosenfeld atr_pps_fidi_accepted(void *respbuf, size_t len)
1272*a61ed2ceSHans Rosenfeld {
1273*a61ed2ceSHans Rosenfeld 	uint8_t *resp = respbuf;
1274*a61ed2ceSHans Rosenfeld 	return ((resp[PPS_PPS0_INDEX] & PPS_PPS0_PPS1) != 0);
1275*a61ed2ceSHans Rosenfeld }
1276*a61ed2ceSHans Rosenfeld 
1277*a61ed2ceSHans Rosenfeld #else	/* !_KERNEL */
1278*a61ed2ceSHans Rosenfeld atr_data_t *
atr_data_alloc(void)1279*a61ed2ceSHans Rosenfeld atr_data_alloc(void)
1280*a61ed2ceSHans Rosenfeld {
1281*a61ed2ceSHans Rosenfeld 	return (calloc(1, sizeof (atr_data_t)));
1282*a61ed2ceSHans Rosenfeld }
1283*a61ed2ceSHans Rosenfeld 
1284*a61ed2ceSHans Rosenfeld void
atr_data_free(atr_data_t * data)1285*a61ed2ceSHans Rosenfeld atr_data_free(atr_data_t *data)
1286*a61ed2ceSHans Rosenfeld {
1287*a61ed2ceSHans Rosenfeld 	if (data == NULL)
1288*a61ed2ceSHans Rosenfeld 		return;
1289*a61ed2ceSHans Rosenfeld 	free(data);
1290*a61ed2ceSHans Rosenfeld }
1291*a61ed2ceSHans Rosenfeld 
1292*a61ed2ceSHans Rosenfeld /*
1293*a61ed2ceSHans Rosenfeld  * This table maps the bit values for Fi from 7816-3:2006 section 8.3 Table 9.
1294*a61ed2ceSHans Rosenfeld  * The table is up to 6 bits wide. Entries not present are RFU. We use NULL as a
1295*a61ed2ceSHans Rosenfeld  * sentinel to indicate that.
1296*a61ed2ceSHans Rosenfeld  */
1297*a61ed2ceSHans Rosenfeld static const char *atr_voltage_table[64] = {
1298*a61ed2ceSHans Rosenfeld 	NULL,			/* 00 0000 */
1299*a61ed2ceSHans Rosenfeld 	"5V",			/* 00 0001 */
1300*a61ed2ceSHans Rosenfeld 	"3V",			/* 00 0010 */
1301*a61ed2ceSHans Rosenfeld 	"5V, 3V",		/* 00 0011 */
1302*a61ed2ceSHans Rosenfeld 	"1.5V",			/* 00 0100 */
1303*a61ed2ceSHans Rosenfeld 	NULL,			/* 00 0101 */
1304*a61ed2ceSHans Rosenfeld 	"3V, 1.5V",		/* 00 0110 */
1305*a61ed2ceSHans Rosenfeld 	"5V, 3V, 1.5V"		/* 00 0111 */
1306*a61ed2ceSHans Rosenfeld };
1307*a61ed2ceSHans Rosenfeld 
1308*a61ed2ceSHans Rosenfeld static void
atr_data_dump_ta(atr_ti_t * atp,FILE * out,uint_t level)1309*a61ed2ceSHans Rosenfeld atr_data_dump_ta(atr_ti_t *atp, FILE *out, uint_t level)
1310*a61ed2ceSHans Rosenfeld {
1311*a61ed2ceSHans Rosenfeld 	uint8_t ta;
1312*a61ed2ceSHans Rosenfeld 
1313*a61ed2ceSHans Rosenfeld 	if (!(atp->atrti_flags & ATR_TI_HAVE_TA)) {
1314*a61ed2ceSHans Rosenfeld 		return;
1315*a61ed2ceSHans Rosenfeld 	}
1316*a61ed2ceSHans Rosenfeld 
1317*a61ed2ceSHans Rosenfeld 	ta = atp->atrti_ta;
1318*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "   %c%c%c+-> TA%u 0x%02x",
1319*a61ed2ceSHans Rosenfeld 	    atp->atrti_flags & ATR_TI_HAVE_TD ? '|' : ' ',
1320*a61ed2ceSHans Rosenfeld 	    atp->atrti_flags & ATR_TI_HAVE_TC ? '|' : ' ',
1321*a61ed2ceSHans Rosenfeld 	    atp->atrti_flags & ATR_TI_HAVE_TB ? '|' : ' ',
1322*a61ed2ceSHans Rosenfeld 	    atp->atrti_ti_val, ta);
1323*a61ed2ceSHans Rosenfeld 	switch (atp->atrti_ti_val) {
1324*a61ed2ceSHans Rosenfeld 	case 1:
1325*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "; Fi: %s, F(max): %s MHz, Di: %s",
1326*a61ed2ceSHans Rosenfeld 		    atr_fi_table[ATR_TA1_FTABLE(ta)],
1327*a61ed2ceSHans Rosenfeld 		    atr_fmax_table[ATR_TA1_FTABLE(ta)],
1328*a61ed2ceSHans Rosenfeld 		    atr_di_table[ATR_TA1_DITABLE(ta)]);
1329*a61ed2ceSHans Rosenfeld 		break;
1330*a61ed2ceSHans Rosenfeld 	case 2:
1331*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "; ICC in %s mode; %shonoring TA1; default "
1332*a61ed2ceSHans Rosenfeld 		    "T=%u",
1333*a61ed2ceSHans Rosenfeld 		    ATR_TA2_CANCHANGE(ta) ? "negotiable" : "specific",
1334*a61ed2ceSHans Rosenfeld 		    ATR_TA2_HONORTA1(ta) ? "" : "not ",
1335*a61ed2ceSHans Rosenfeld 		    ATR_TA2_PROTOCOL(ta));
1336*a61ed2ceSHans Rosenfeld 		break;
1337*a61ed2ceSHans Rosenfeld 	default:
1338*a61ed2ceSHans Rosenfeld 		switch (atp->atrti_protocol) {
1339*a61ed2ceSHans Rosenfeld 		case ATR_PROTOCOL_T1:
1340*a61ed2ceSHans Rosenfeld 			if (level != 0)
1341*a61ed2ceSHans Rosenfeld 				break;
1342*a61ed2ceSHans Rosenfeld 			if (ta == 0 || ta == 0xff) {
1343*a61ed2ceSHans Rosenfeld 				(void) fprintf(out, "; IFSC: RFU");
1344*a61ed2ceSHans Rosenfeld 			} else {
1345*a61ed2ceSHans Rosenfeld 				(void) fprintf(out, "; IFSC: %u", ta);
1346*a61ed2ceSHans Rosenfeld 			}
1347*a61ed2ceSHans Rosenfeld 			break;
1348*a61ed2ceSHans Rosenfeld 		case ATR_PROTOCOL_T15:
1349*a61ed2ceSHans Rosenfeld 			if (level != 0)
1350*a61ed2ceSHans Rosenfeld 				break;
1351*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "; Clock stop: %s, Supported "
1352*a61ed2ceSHans Rosenfeld 			    "Voltage: %s",
1353*a61ed2ceSHans Rosenfeld 			    atr_clock_table[ATR_T15_TA0_CLOCK(ta)],
1354*a61ed2ceSHans Rosenfeld 			    atr_voltage_table[ATR_T15_TA0_VOLTAGE(ta)] != NULL ?
1355*a61ed2ceSHans Rosenfeld 			    atr_voltage_table[ATR_T15_TA0_VOLTAGE(ta)] : "RFU");
1356*a61ed2ceSHans Rosenfeld 			break;
1357*a61ed2ceSHans Rosenfeld 		default:
1358*a61ed2ceSHans Rosenfeld 			break;
1359*a61ed2ceSHans Rosenfeld 		}
1360*a61ed2ceSHans Rosenfeld 	}
1361*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "\n");
1362*a61ed2ceSHans Rosenfeld }
1363*a61ed2ceSHans Rosenfeld 
1364*a61ed2ceSHans Rosenfeld static void
atr_data_dump_tb(atr_ti_t * atp,FILE * out,uint_t level)1365*a61ed2ceSHans Rosenfeld atr_data_dump_tb(atr_ti_t *atp, FILE *out, uint_t level)
1366*a61ed2ceSHans Rosenfeld {
1367*a61ed2ceSHans Rosenfeld 	uint8_t tb;
1368*a61ed2ceSHans Rosenfeld 
1369*a61ed2ceSHans Rosenfeld 	if (!(atp->atrti_flags & ATR_TI_HAVE_TB)) {
1370*a61ed2ceSHans Rosenfeld 		return;
1371*a61ed2ceSHans Rosenfeld 	}
1372*a61ed2ceSHans Rosenfeld 
1373*a61ed2ceSHans Rosenfeld 	tb = atp->atrti_tb;
1374*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "   %c%c+--> TB%u 0x%02x",
1375*a61ed2ceSHans Rosenfeld 	    atp->atrti_flags & ATR_TI_HAVE_TD ? '|' : ' ',
1376*a61ed2ceSHans Rosenfeld 	    atp->atrti_flags & ATR_TI_HAVE_TC ? '|' : ' ',
1377*a61ed2ceSHans Rosenfeld 	    atp->atrti_ti_val, tb);
1378*a61ed2ceSHans Rosenfeld 	switch (atp->atrti_ti_val) {
1379*a61ed2ceSHans Rosenfeld 	case 1:
1380*a61ed2ceSHans Rosenfeld 	case 2:
1381*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "; deprecated");
1382*a61ed2ceSHans Rosenfeld 		break;
1383*a61ed2ceSHans Rosenfeld 	default:
1384*a61ed2ceSHans Rosenfeld 		switch (atp->atrti_protocol) {
1385*a61ed2ceSHans Rosenfeld 		case ATR_PROTOCOL_T1:
1386*a61ed2ceSHans Rosenfeld 			if (level != 0)
1387*a61ed2ceSHans Rosenfeld 				break;
1388*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "; CWI: %u, BWI: %u\n",
1389*a61ed2ceSHans Rosenfeld 			    ATR_T1_TB0_CWI(tb),
1390*a61ed2ceSHans Rosenfeld 			    ATR_T1_TB0_BWI(tb));
1391*a61ed2ceSHans Rosenfeld 			break;
1392*a61ed2ceSHans Rosenfeld 		case ATR_PROTOCOL_T15:
1393*a61ed2ceSHans Rosenfeld 			if (level != 0)
1394*a61ed2ceSHans Rosenfeld 				break;
1395*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "; SPU: %s", tb == 0 ? "not used" :
1396*a61ed2ceSHans Rosenfeld 			    ATR_T15_TB0_SPU_STANDARD(tb) ? "standard" :
1397*a61ed2ceSHans Rosenfeld 			    "proprietary");
1398*a61ed2ceSHans Rosenfeld 			break;
1399*a61ed2ceSHans Rosenfeld 		default:
1400*a61ed2ceSHans Rosenfeld 			break;
1401*a61ed2ceSHans Rosenfeld 		}
1402*a61ed2ceSHans Rosenfeld 	}
1403*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "\n");
1404*a61ed2ceSHans Rosenfeld }
1405*a61ed2ceSHans Rosenfeld 
1406*a61ed2ceSHans Rosenfeld static void
atr_data_dump_tc(atr_ti_t * atp,FILE * out,uint_t level)1407*a61ed2ceSHans Rosenfeld atr_data_dump_tc(atr_ti_t *atp, FILE *out, uint_t level)
1408*a61ed2ceSHans Rosenfeld {
1409*a61ed2ceSHans Rosenfeld 	uint8_t tc;
1410*a61ed2ceSHans Rosenfeld 
1411*a61ed2ceSHans Rosenfeld 	if (!(atp->atrti_flags & ATR_TI_HAVE_TC)) {
1412*a61ed2ceSHans Rosenfeld 		return;
1413*a61ed2ceSHans Rosenfeld 	}
1414*a61ed2ceSHans Rosenfeld 
1415*a61ed2ceSHans Rosenfeld 	tc = atp->atrti_tc;
1416*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "   %c+---> TC%u 0x%02x",
1417*a61ed2ceSHans Rosenfeld 	    atp->atrti_flags & ATR_TI_HAVE_TD ? '|' : ' ',
1418*a61ed2ceSHans Rosenfeld 	    atp->atrti_ti_val, tc);
1419*a61ed2ceSHans Rosenfeld 
1420*a61ed2ceSHans Rosenfeld 	switch (atp->atrti_ti_val) {
1421*a61ed2ceSHans Rosenfeld 	case 1:
1422*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "; Extra Guard Time Integer: %u", tc);
1423*a61ed2ceSHans Rosenfeld 		break;
1424*a61ed2ceSHans Rosenfeld 	case 2:
1425*a61ed2ceSHans Rosenfeld 		if (atp->atrti_protocol != ATR_PROTOCOL_T0) {
1426*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "; illegal value -- only valid for "
1427*a61ed2ceSHans Rosenfeld 			    "T=0");
1428*a61ed2ceSHans Rosenfeld 		} else {
1429*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "; Waiting Time Integer: %u", tc);
1430*a61ed2ceSHans Rosenfeld 		}
1431*a61ed2ceSHans Rosenfeld 		break;
1432*a61ed2ceSHans Rosenfeld 	default:
1433*a61ed2ceSHans Rosenfeld 		switch (atp->atrti_protocol) {
1434*a61ed2ceSHans Rosenfeld 		case ATR_PROTOCOL_T1:
1435*a61ed2ceSHans Rosenfeld 			if (level != 0)
1436*a61ed2ceSHans Rosenfeld 				break;
1437*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "; Error Detection Code: %s",
1438*a61ed2ceSHans Rosenfeld 			    ATR_T1_TC0_CRC(tc) ? "CRC" : "LRC");
1439*a61ed2ceSHans Rosenfeld 			break;
1440*a61ed2ceSHans Rosenfeld 		default:
1441*a61ed2ceSHans Rosenfeld 			break;
1442*a61ed2ceSHans Rosenfeld 		}
1443*a61ed2ceSHans Rosenfeld 	}
1444*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "\n");
1445*a61ed2ceSHans Rosenfeld }
1446*a61ed2ceSHans Rosenfeld 
1447*a61ed2ceSHans Rosenfeld void
atr_data_hexdump(const uint8_t * buf,size_t nbytes,FILE * out)1448*a61ed2ceSHans Rosenfeld atr_data_hexdump(const uint8_t *buf, size_t nbytes, FILE *out)
1449*a61ed2ceSHans Rosenfeld {
1450*a61ed2ceSHans Rosenfeld 	size_t i, j;
1451*a61ed2ceSHans Rosenfeld 
1452*a61ed2ceSHans Rosenfeld 	/* Print out the header */
1453*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "%*s    0", 4, "");
1454*a61ed2ceSHans Rosenfeld 	for (i = 1; i < 16; i++) {
1455*a61ed2ceSHans Rosenfeld 		if (i % 4 == 0 && i % 16 != 0) {
1456*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, " ");
1457*a61ed2ceSHans Rosenfeld 		}
1458*a61ed2ceSHans Rosenfeld 
1459*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "%2x", i);
1460*a61ed2ceSHans Rosenfeld 	}
1461*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "  0123456789abcdef\n");
1462*a61ed2ceSHans Rosenfeld 
1463*a61ed2ceSHans Rosenfeld 	/* Print out data */
1464*a61ed2ceSHans Rosenfeld 	for (i = 0; i < nbytes; i++) {
1465*a61ed2ceSHans Rosenfeld 
1466*a61ed2ceSHans Rosenfeld 		if (i % 16 == 0) {
1467*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "%04x:  ", i);
1468*a61ed2ceSHans Rosenfeld 		}
1469*a61ed2ceSHans Rosenfeld 
1470*a61ed2ceSHans Rosenfeld 		if (i % 4 == 0 && i % 16 != 0) {
1471*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, " ");
1472*a61ed2ceSHans Rosenfeld 		}
1473*a61ed2ceSHans Rosenfeld 
1474*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "%02x", buf[i]);
1475*a61ed2ceSHans Rosenfeld 
1476*a61ed2ceSHans Rosenfeld 		if (i % 16 == 15 || i + 1 == nbytes) {
1477*a61ed2ceSHans Rosenfeld 			for (j = (i % 16) + 1; j < 16; j++) {
1478*a61ed2ceSHans Rosenfeld 				if (j % 4 == 0 && j % 16 != 0) {
1479*a61ed2ceSHans Rosenfeld 					(void) fprintf(out, " ");
1480*a61ed2ceSHans Rosenfeld 				}
1481*a61ed2ceSHans Rosenfeld 
1482*a61ed2ceSHans Rosenfeld 				(void) fprintf(out, "  ");
1483*a61ed2ceSHans Rosenfeld 			}
1484*a61ed2ceSHans Rosenfeld 
1485*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "  ");
1486*a61ed2ceSHans Rosenfeld 			for (j = i - (i % 16); j <= i; j++) {
1487*a61ed2ceSHans Rosenfeld 				(void) fprintf(out, "%c",
1488*a61ed2ceSHans Rosenfeld 				    isprint(buf[j]) ? buf[j] : '.');
1489*a61ed2ceSHans Rosenfeld 			}
1490*a61ed2ceSHans Rosenfeld 			(void) printf("\n");
1491*a61ed2ceSHans Rosenfeld 		}
1492*a61ed2ceSHans Rosenfeld 	}
1493*a61ed2ceSHans Rosenfeld }
1494*a61ed2ceSHans Rosenfeld 
1495*a61ed2ceSHans Rosenfeld static void
atr_data_hexdump_historical(atr_data_t * data,FILE * out)1496*a61ed2ceSHans Rosenfeld atr_data_hexdump_historical(atr_data_t *data, FILE *out)
1497*a61ed2ceSHans Rosenfeld {
1498*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "Dumping raw historical bytes\n");
1499*a61ed2ceSHans Rosenfeld 
1500*a61ed2ceSHans Rosenfeld 	atr_data_hexdump(data->atr_historic, data->atr_nhistoric, out);
1501*a61ed2ceSHans Rosenfeld }
1502*a61ed2ceSHans Rosenfeld 
1503*a61ed2ceSHans Rosenfeld static void
atr_data_dump_historical(atr_data_t * data,FILE * out)1504*a61ed2ceSHans Rosenfeld atr_data_dump_historical(atr_data_t *data, FILE *out)
1505*a61ed2ceSHans Rosenfeld {
1506*a61ed2ceSHans Rosenfeld 	uint8_t cat;
1507*a61ed2ceSHans Rosenfeld 
1508*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "Historic Data: %u bytes", data->atr_nhistoric);
1509*a61ed2ceSHans Rosenfeld 	if (data->atr_nhistoric == 0) {
1510*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "\n");
1511*a61ed2ceSHans Rosenfeld 		return;
1512*a61ed2ceSHans Rosenfeld 	}
1513*a61ed2ceSHans Rosenfeld 
1514*a61ed2ceSHans Rosenfeld 	cat = data->atr_historic[0];
1515*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "; format (0x%02x) ", cat);
1516*a61ed2ceSHans Rosenfeld 	if (cat == ATR_HIST_CAT_MAND_STATUS) {
1517*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "card status, not shown");
1518*a61ed2ceSHans Rosenfeld 	} else if (cat == ATR_HIST_CAT_TLV_STATUS) {
1519*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "COMPACT-TLV, not shown");
1520*a61ed2ceSHans Rosenfeld 	} else if (cat >= ATR_HIST_CAT_RFU_MIN && cat <= ATR_HIST_CAT_RFU_MAX) {
1521*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "reserved\n");
1522*a61ed2ceSHans Rosenfeld 		atr_data_hexdump_historical(data, out);
1523*a61ed2ceSHans Rosenfeld 		return;
1524*a61ed2ceSHans Rosenfeld 	} else {
1525*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "proprietary\n");
1526*a61ed2ceSHans Rosenfeld 		atr_data_hexdump_historical(data, out);
1527*a61ed2ceSHans Rosenfeld 		return;
1528*a61ed2ceSHans Rosenfeld 	}
1529*a61ed2ceSHans Rosenfeld }
1530*a61ed2ceSHans Rosenfeld 
1531*a61ed2ceSHans Rosenfeld void
atr_data_dump(atr_data_t * data,FILE * out)1532*a61ed2ceSHans Rosenfeld atr_data_dump(atr_data_t *data, FILE *out)
1533*a61ed2ceSHans Rosenfeld {
1534*a61ed2ceSHans Rosenfeld 	uint8_t i, level;
1535*a61ed2ceSHans Rosenfeld 	if ((data->atr_flags & ATR_F_VALID) == 0)
1536*a61ed2ceSHans Rosenfeld 		return;
1537*a61ed2ceSHans Rosenfeld 
1538*a61ed2ceSHans Rosenfeld 	(void) fprintf(out, "TS  0x%02u - ", data->atr_raw[0]);
1539*a61ed2ceSHans Rosenfeld 	if (data->atr_flags & ATR_F_USES_DIRECT) {
1540*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "direct convention\n");
1541*a61ed2ceSHans Rosenfeld 	} else {
1542*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "inverse convention\n");
1543*a61ed2ceSHans Rosenfeld 	}
1544*a61ed2ceSHans Rosenfeld 
1545*a61ed2ceSHans Rosenfeld 	level = 0;
1546*a61ed2ceSHans Rosenfeld 	for (i = 0; i < data->atr_nti; i++) {
1547*a61ed2ceSHans Rosenfeld 		atr_ti_t *atp = &data->atr_ti[i];
1548*a61ed2ceSHans Rosenfeld 
1549*a61ed2ceSHans Rosenfeld 		/*
1550*a61ed2ceSHans Rosenfeld 		 * Various protocols may appear multiple times, indicating
1551*a61ed2ceSHans Rosenfeld 		 * different sets of bits each time. When dealing with T0 and
1552*a61ed2ceSHans Rosenfeld 		 * TD1, the protocol doesn't matter. Otherwise if we have the
1553*a61ed2ceSHans Rosenfeld 		 * same value, we should increment this.
1554*a61ed2ceSHans Rosenfeld 		 */
1555*a61ed2ceSHans Rosenfeld 		if (i <= 2) {
1556*a61ed2ceSHans Rosenfeld 			level = 0;
1557*a61ed2ceSHans Rosenfeld 		} else if (atp->atrti_protocol ==
1558*a61ed2ceSHans Rosenfeld 		    data->atr_ti[i - 1].atrti_protocol) {
1559*a61ed2ceSHans Rosenfeld 			level++;
1560*a61ed2ceSHans Rosenfeld 		} else {
1561*a61ed2ceSHans Rosenfeld 			level = 0;
1562*a61ed2ceSHans Rosenfeld 		}
1563*a61ed2ceSHans Rosenfeld 
1564*a61ed2ceSHans Rosenfeld 		if (i == 0) {
1565*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "T0  ");
1566*a61ed2ceSHans Rosenfeld 		} else {
1567*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "TD%u ", i);
1568*a61ed2ceSHans Rosenfeld 		}
1569*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "0x%02x\n",
1570*a61ed2ceSHans Rosenfeld 		    data->atr_raw[atp->atrti_td_idx]);
1571*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "      |+-> ");
1572*a61ed2ceSHans Rosenfeld 		if (i == 0) {
1573*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "%u historical bytes\n",
1574*a61ed2ceSHans Rosenfeld 			    data->atr_nhistoric);
1575*a61ed2ceSHans Rosenfeld 		} else {
1576*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "protocol T=%u\n",
1577*a61ed2ceSHans Rosenfeld 			    atp->atrti_protocol);
1578*a61ed2ceSHans Rosenfeld 		}
1579*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "      v\n");
1580*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, " 0r%u%u%u%u\n",
1581*a61ed2ceSHans Rosenfeld 		    atp->atrti_flags & ATR_TI_HAVE_TD ? 1 : 0,
1582*a61ed2ceSHans Rosenfeld 		    atp->atrti_flags & ATR_TI_HAVE_TC ? 1 : 0,
1583*a61ed2ceSHans Rosenfeld 		    atp->atrti_flags & ATR_TI_HAVE_TB ? 1 : 0,
1584*a61ed2ceSHans Rosenfeld 		    atp->atrti_flags & ATR_TI_HAVE_TA ? 1 : 0);
1585*a61ed2ceSHans Rosenfeld 
1586*a61ed2ceSHans Rosenfeld 		atr_data_dump_ta(atp, out, level);
1587*a61ed2ceSHans Rosenfeld 		atr_data_dump_tb(atp, out, level);
1588*a61ed2ceSHans Rosenfeld 		atr_data_dump_tc(atp, out, level);
1589*a61ed2ceSHans Rosenfeld 		if (atp->atrti_flags & ATR_TI_HAVE_TD) {
1590*a61ed2ceSHans Rosenfeld 			(void) fprintf(out, "   v\n");
1591*a61ed2ceSHans Rosenfeld 		}
1592*a61ed2ceSHans Rosenfeld 	}
1593*a61ed2ceSHans Rosenfeld 
1594*a61ed2ceSHans Rosenfeld 	atr_data_dump_historical(data, out);
1595*a61ed2ceSHans Rosenfeld 
1596*a61ed2ceSHans Rosenfeld 	if (data->atr_flags & ATR_F_HAS_CHECKSUM) {
1597*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "TCK  0x%02x\n", data->atr_cksum);
1598*a61ed2ceSHans Rosenfeld 	} else {
1599*a61ed2ceSHans Rosenfeld 		(void) fprintf(out, "TCK  ----; Checksum not present\n");
1600*a61ed2ceSHans Rosenfeld 	}
1601*a61ed2ceSHans Rosenfeld 
1602*a61ed2ceSHans Rosenfeld }
1603*a61ed2ceSHans Rosenfeld #endif	/* _KERNEL */
1604