1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2019, Joyent, Inc. 14 */ 15 16 #ifndef _ATR_H 17 #define _ATR_H 18 19 /* 20 * Parse Answer-To-Reset values. This header file is private to illumos and 21 * should not be shipped or used by applications. 22 * 23 * This is based on ISO/IEC 7816-3:2006. It has been designed such that if newer 24 * revisions come out that define reserved values, they will be ignored until 25 * this code is updated. 26 */ 27 28 #include <sys/types.h> 29 #include <sys/usb/clients/ccid/ccid.h> 30 #ifndef _KERNEL 31 #include <stdio.h> 32 #endif 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 /* 39 * The ATR must have at least 2 bytes and then may have up to 33 bytes. 40 */ 41 #define ATR_LEN_MIN 2 42 #define ATR_LEN_MAX 33 43 44 typedef enum atr_parsecode { 45 ATR_CODE_OK = 0, 46 ATR_CODE_TOO_SHORT, 47 ATR_CODE_TOO_LONG, 48 ATR_CODE_INVALID_TS, 49 ATR_CODE_OVERRUN, 50 ATR_CODE_UNDERRUN, 51 ATR_CODE_CHECKSUM_ERROR, 52 ATR_CODE_INVALID_TD1 53 } atr_parsecode_t; 54 55 typedef enum atr_protocol { 56 ATR_P_NONE = 0, 57 ATR_P_T0 = 1 << 0, 58 ATR_P_T1 = 1 << 1 59 } atr_protocol_t; 60 61 typedef enum atr_convention { 62 ATR_CONVENTION_DIRECT = 0x00, 63 ATR_CONVENTION_INVERSE = 0x01 64 } atr_convention_t; 65 66 typedef enum atr_clock_stop { 67 ATR_CLOCK_STOP_NONE = 0x00, 68 ATR_CLOCK_STOP_LOW = 0x01, 69 ATR_CLOCK_STOP_HI = 0x02, 70 ATR_CLOCK_STOP_BOTH = 0x03 71 } atr_clock_stop_t; 72 73 typedef enum atr_data_rate_choice { 74 /* 75 * Indicates that the reader cannot support the data rate needed for the 76 * ICC. 77 */ 78 ATR_RATE_UNSUPPORTED = 0x00, 79 /* 80 * Indicates that the reader supports the ICC present, but must run at 81 * the protocol's default rate (Di index = Fi index = 1) 82 */ 83 ATR_RATE_USEDEFAULT = 0x01, 84 /* 85 * The reader supports the Di/Fi values that the ICC proposed in its ATR 86 * and no action beyond setting the parameters of the reader is required 87 * (this may be automatic depending on the reader's dwFeatures). 88 */ 89 ATR_RATE_USEATR = 0x02, 90 /* 91 * The reader can use the features of the ATR specified. However, it 92 * must change the data rate or frequency that the card is running at to 93 * proceed. 94 */ 95 ATR_RATE_USEATR_SETRATE = 0x03 96 } atr_data_rate_choice_t; 97 98 typedef enum atr_t1_checksum { 99 ATR_T1_CHECKSUM_LRC = 0x00, 100 ATR_T1_CHECKSUM_CRC = 0x01 101 } atr_t1_checksum_t; 102 103 typedef struct atr_data atr_data_t; 104 105 /* 106 * Allocate and free ATR data. 107 */ 108 extern atr_data_t *atr_data_alloc(void); 109 extern void atr_data_free(atr_data_t *); 110 111 /* 112 * Reset an allocated ATR data to be ready to parse something else. 113 */ 114 extern void atr_data_reset(atr_data_t *); 115 116 /* 117 * Parse the ATR data into an opaque structure that organizes the data and 118 * allows for various queries to be made on it later. 119 */ 120 extern atr_parsecode_t atr_parse(const uint8_t *, size_t, atr_data_t *data); 121 extern const char *atr_strerror(atr_parsecode_t); 122 123 /* 124 * Get an eumeration of supported protocols in this ATR data. Note that if a 125 * reserved protocol is encountered, we may not report it as we don't know of it 126 * at this time. 127 */ 128 extern atr_protocol_t atr_supported_protocols(atr_data_t *); 129 130 /* 131 * Based on the ATR determine what the default protocol is and whether or not it 132 * supports negotiation. When a ICC is not negotiable, it will always start up 133 * with a specific protocol and parameters based on the ATR and be ready to use. 134 * Otherwise, the card will be in a negotiable mode and be set to a default set 135 * of parameters. 136 */ 137 extern boolean_t atr_params_negotiable(atr_data_t *); 138 extern atr_protocol_t atr_default_protocol(atr_data_t *); 139 140 /* 141 * Protocol default values. 142 */ 143 extern uint8_t atr_fi_default_index(void); 144 extern uint8_t atr_di_default_index(void); 145 146 /* 147 * Obtain the table indexes that should be used by the device. 148 */ 149 extern uint8_t atr_fi_index(atr_data_t *); 150 extern uint8_t atr_di_index(atr_data_t *); 151 extern atr_convention_t atr_convention(atr_data_t *); 152 extern uint8_t atr_extra_guardtime(atr_data_t *); 153 extern uint8_t atr_t0_wi(atr_data_t *); 154 extern atr_t1_checksum_t atr_t1_checksum(atr_data_t *); 155 extern uint8_t atr_t1_bwi(atr_data_t *); 156 extern uint8_t atr_t1_cwi(atr_data_t *); 157 extern atr_clock_stop_t atr_clock_stop(atr_data_t *); 158 extern uint8_t atr_t1_ifsc(atr_data_t *); 159 160 /* 161 * Use this function to determine what set of Di and Fi values should be used by 162 * a reader, based on the parameters from the ATR and the reader's cclass. 163 */ 164 extern atr_data_rate_choice_t atr_data_rate(atr_data_t *, ccid_class_descr_t *, 165 uint32_t *, uint_t, uint32_t *); 166 167 #ifndef _KERNEL 168 extern void atr_data_hexdump(const uint8_t *, size_t, FILE *); 169 extern void atr_data_dump(atr_data_t *, FILE *); 170 #endif 171 172 /* 173 * String and table index values. 174 */ 175 extern const char *atr_protocol_to_string(atr_protocol_t); 176 extern uint_t atr_fi_index_to_value(uint8_t); 177 extern const char *atr_fi_index_to_string(uint8_t); 178 extern const char *atr_fmax_index_to_string(uint8_t); 179 extern uint_t atr_di_index_to_value(uint8_t); 180 extern const char *atr_di_index_to_string(uint8_t); 181 extern const char *atr_clock_stop_to_string(atr_clock_stop_t); 182 extern const char *atr_convention_to_string(atr_convention_t); 183 184 /* 185 * Functions for generating and testing PPS values. Before calling 186 * atr_pps_fidi_accepted(), one must call atr_pps_valid(). 187 */ 188 #define PPS_BUFFER_MAX 6 189 extern uint_t atr_pps_generate(uint8_t *, size_t, atr_protocol_t, boolean_t, 190 uint8_t, uint8_t, boolean_t, uint8_t); 191 extern boolean_t atr_pps_valid(void *, size_t, void *, size_t); 192 extern boolean_t atr_pps_fidi_accepted(void *, size_t); 193 194 #ifdef __cplusplus 195 } 196 #endif 197 198 #endif /* _ATR_H */ 199