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 _SYS_USB_CCID_H 17 #define _SYS_USB_CCID_H 18 19 /* 20 * CCID class driver definitions. 21 */ 22 23 #include <sys/stdint.h> 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 /* 30 * Values for various Hardware, Mechanical, and Pin features. These come from 31 * the device's class descriptor. 32 */ 33 typedef enum ccid_class_voltage { 34 CCID_CLASS_VOLT_AUTO = 0x00, 35 CCID_CLASS_VOLT_5_0 = 0x01, 36 CCID_CLASS_VOLT_3_0 = 0x02, 37 CCID_CLASS_VOLT_1_8 = 0x04 38 } ccid_class_voltage_t; 39 40 typedef enum ccid_class_mechanical { 41 CCID_CLASS_MECH_CARD_ACCEPT = 0x01, 42 CCID_CLASS_MECH_CARD_EJECT = 0x02, 43 CCID_CLASS_MECH_CARD_CAPTURE = 0x04, 44 CCID_CLASS_MECH_CARD_LOCK = 0x08 45 } ccid_class_mechanical_t; 46 47 typedef enum ccid_class_features { 48 CCID_CLASS_F_AUTO_PARAM_ATR = 0x00000002, 49 CCID_CLASS_F_AUTO_ICC_ACTIVATE = 0x00000004, 50 CCID_CLASS_F_AUTO_ICC_VOLTAGE = 0x00000008, 51 CCID_CLASS_F_AUTO_ICC_CLOCK = 0x00000010, 52 CCID_CLASS_F_AUTO_BAUD = 0x00000020, 53 CCID_CLASS_F_AUTO_PARAM_NEG = 0x00000040, 54 CCID_CLASS_F_AUTO_PPS = 0x00000080, 55 CCID_CLASS_F_ICC_CLOCK_STOP = 0x00000100, 56 CCID_CLASS_F_ALTNAD_SUP = 0x00000200, 57 CCID_CLASS_F_AUTO_IFSD = 0x00000400, 58 CCID_CLASS_F_TPDU_XCHG = 0x00010000, 59 CCID_CLASS_F_SHORT_APDU_XCHG = 0x00020000, 60 CCID_CLASS_F_EXT_APDU_XCHG = 0x00040000, 61 CCID_CLASS_F_WAKE_UP = 0x00100000 62 } ccid_class_features_t; 63 64 typedef enum ccid_class_pin { 65 CCID_CLASS_PIN_VERIFICATION = 0x01, 66 CCID_CLASS_PIN_MODIFICATION = 0x02 67 } ccid_class_pin_t; 68 69 /* 70 * CCID Class Descriptor 71 * 72 * This structure represents the CCID class descriptor. Note, it should not be a 73 * packed structure. This is designed to be a native representation. The raw 74 * structure will be parsed into this instead. 75 */ 76 typedef struct ccid_class_descr { 77 uint8_t ccd_bLength; 78 uint8_t ccd_bDescriptorType; 79 uint16_t ccd_bcdCCID; 80 uint8_t ccd_bMaxSlotIndex; 81 uint8_t ccd_bVoltageSupport; 82 uint32_t ccd_dwProtocols; 83 uint32_t ccd_dwDefaultClock; 84 uint32_t ccd_dwMaximumClock; 85 uint8_t ccd_bNumClockSupported; 86 uint32_t ccd_dwDataRate; 87 uint32_t ccd_dwMaxDataRate; 88 uint8_t ccd_bNumDataRatesSupported; 89 uint32_t ccd_dwMaxIFSD; 90 uint32_t ccd_dwSyncProtocols; 91 uint32_t ccd_dwMechanical; 92 uint32_t ccd_dwFeatures; 93 uint32_t ccd_dwMaxCCIDMessageLength; 94 uint8_t ccd_bClassGetResponse; 95 uint8_t ccd_bClassEnvelope; 96 uint16_t ccd_wLcdLayout; 97 uint8_t ccd_bPinSupport; 98 uint8_t ccd_bMaxCCIDBusySlots; 99 } ccid_class_descr_t; 100 101 /* 102 * Definitions for the supported versions of the CCID specification. The version 103 * is encoded in binary encoded decimal. The major version is in the upper 8 104 * bits and the minor version is in the lower 8 bits. We currently check for the 105 * major version to match. 106 */ 107 #define CCID_VERSION_MAJOR(ver) (((ver) & 0xff00) >> 8) 108 #define CCID_VERSION_MINOR(ver) ((ver) & 0x00ff) 109 #define CCID_VERSION_ONE 0x01 110 111 /* 112 * This structure is used as the data for the CCID_REQUEST_SET_PARAMS request 113 * and the CCID_RESPONSE_PARAMETERS response. There are different structures for 114 * T=0 and T=1. These come from CCID r1.1 / Section 6.1.7. 115 */ 116 typedef struct ccid_params_t0 { 117 uint8_t cp0_bmFindexDindex; 118 uint8_t cp0_bmTCCKST0; 119 uint8_t cp0_bGuardTimeT0; 120 uint8_t cp0_bWaitingIntegerT0; 121 uint8_t cp0_bClockStop; 122 } __packed ccid_params_t0_t; 123 124 #define CCID_P_TCCKST0_DIRECT 0x00 125 #define CCID_P_TCCKST0_INVERSE 0x02 126 127 typedef struct ccid_params_t1 { 128 uint8_t cp1_bmFindexDindex; 129 uint8_t cp1_bmTCCKST1; 130 uint8_t cp1_bGuardTimeT1; 131 uint8_t cp1_bmWaitingIntegersT1; 132 uint8_t cp1_bClockStop; 133 uint8_t cp1_bIFSC; 134 uint8_t cp1_bNadValue; 135 } __packed ccid_params_t1_t; 136 137 typedef union ccid_params { 138 ccid_params_t0_t ccp_t0; 139 ccid_params_t1_t ccp_t1; 140 } ccid_params_t; 141 142 #define CCID_P_FI_DI(fi, di) ((((fi) & 0x0f) << 4) | ((di) & 0x0f)) 143 144 /* 145 * Everything below this point is reserved for the kernel. 146 */ 147 #ifdef _KERNEL 148 149 /* 150 * These values come from CCID r1.1.0 Table 5.1-1 'Smart Card Device 151 * Descriptors' 152 */ 153 #define CCID_DESCR_TYPE 0x21 154 #define CCID_DESCR_LENGTH 0x36 155 156 157 /* 158 * Minimum and maximum value for a sequence number in the CCID specification. 159 * The sequence is a 1 byte unsigned value. The values are inclusive. We reserve 160 * the value of 0x00 so that we can use it as a sentinel in the ccid_command_t 161 * structure to know when we should or shouldn't free a command structure's 162 * sequence number back to the id space. 163 */ 164 #define CCID_SEQ_MIN 0x01 165 #define CCID_SEQ_MAX UINT8_MAX 166 167 168 /* 169 * All structures from the specification must be packed. 170 */ 171 172 /* 173 * Interrupt-IN messages codes. 174 */ 175 typedef enum ccid_intr_code { 176 CCID_INTR_CODE_SLOT_CHANGE = 0x50, 177 CCID_INTR_CODE_HW_ERROR = 0x51 178 } ccid_intr_code_t; 179 180 typedef enum ccid_intr_hwerr_code { 181 CCID_INTR_HWERR_OVERCURRENT = 0x01 182 } ccid_intr_hwerr_code_t; 183 184 typedef struct ccid_intr_slot { 185 uint8_t cis_type; 186 uint8_t cis_state[]; 187 } ccid_intr_slot_t; 188 189 typedef struct ccid_intr_hwerr { 190 uint8_t cih_type; 191 uint8_t cih_slot; 192 uint8_t cih_seq; 193 uint8_t cih_code; 194 } ccid_intr_hwerr_t; 195 196 /* 197 * Message request codes. These codes are based on CCID r1.1.0 Table 6.1-1 198 * 'Summary of Bulk-Out Messages'. The name from the standard is to the right of 199 * the enum. 200 */ 201 typedef enum ccid_request_code { 202 CCID_REQUEST_POWER_ON = 0x62, /* PC_to_RDR_IccPowerOn */ 203 CCID_REQUEST_POWER_OFF = 0x63, /* PC_to_RDR_IccPowerOff */ 204 CCID_REQUEST_SLOT_STATUS = 0x65, /* PC_to_RDR_GetSlotStatus */ 205 CCID_REQUEST_TRANSFER_BLOCK = 0x6f, /* PC_to_RDR_XfrBlock */ 206 CCID_REQUEST_GET_PARAMS = 0x6c, /* PC_to_RDR_GetParameters */ 207 CCID_REQUEST_RESET_PARAMS = 0x6d, /* PC_to_RDR_ResetParameters */ 208 CCID_REQUEST_SET_PARAMS = 0x61, /* PC_to_RDR_SetParameters */ 209 CCID_REQUEST_ESCAPE = 0x6b, /* PC_to_RDR_Escape */ 210 CCID_REQUEST_ICC_CLOCK = 0x6e, /* PC_to_RDR_IccClock */ 211 CCID_REQUEST_T0APDU = 0x6a, /* PC_to_RDR_T0APDU */ 212 CCID_REQUEST_SECURE = 0x69, /* PC_to_RDR_Secure */ 213 CCID_REQUEST_MECHANICAL = 0x71, /* PC_to_RDR_Mechanica */ 214 CCID_REQEUST_ABORT = 0x72, /* PC_to_RDR_Abort */ 215 CCID_REQUEST_DATA_CLOCK = 0x73 /* PC_to_RDR_SetDataRateAnd */ 216 /* ClockFrequency */ 217 } ccid_request_code_t; 218 219 /* 220 * Message request codes. These codes are based on CCID r1.1.0 Table 6.2-1 221 * 'Summary of Bulk-In Messages'. The name from the standard is to the right of 222 * the enum. 223 */ 224 typedef enum ccid_response_code { 225 CCID_RESPONSE_DATA_BLOCK = 0x80, /* RDR_to_PC_DataBlock */ 226 CCID_RESPONSE_SLOT_STATUS = 0x81, /* RDR_to_PC_SlotStatus */ 227 CCID_RESPONSE_PARAMETERS = 0x82, /* RDR_to_PC_Parameters */ 228 CCID_RESPONSE_ESCAPE = 0x83, /* RDR_to_PC_Escape */ 229 CCID_RESPONSE_DATA_CLOCK = 0x84 /* RDR_to_PC_DataRateAnd */ 230 /* ClockFrequency */ 231 } ccid_response_code_t; 232 233 /* 234 * This represents the CCID command header that is used for every request and 235 * response. 236 */ 237 typedef struct ccid_header { 238 uint8_t ch_mtype; 239 uint32_t ch_length; /* Length of ch_data in bytes */ 240 uint8_t ch_slot; /* CCID slot to target */ 241 uint8_t ch_seq; /* Request/Response sequence num */ 242 uint8_t ch_param0; /* Request/Response specific */ 243 uint8_t ch_param1; /* Request/Response specific */ 244 uint8_t ch_param2; /* Request/Response specific */ 245 uint8_t ch_data[]; /* Optional Request/Response Data */ 246 } __packed ccid_header_t; 247 248 /* 249 * This structure is used as the data for the CCID_REQUEST_DATA_CLOCK and 250 * CCID_RESPONSE_DATA_CLOCK commands. 251 */ 252 typedef struct ccid_data_clock { 253 uint32_t cdc_clock; 254 uint32_t cdc_data; 255 } __packed ccid_data_clock_t; 256 257 /* 258 * Macros and constants to take apart the slot status (in ch_param1) when a CCID 259 * reply comes in. 260 */ 261 #define CCID_REPLY_ICC(x) (x & 0x3) 262 #define CCID_REPLY_STATUS(x) ((x & 0xc0) >> 6) 263 264 typedef enum { 265 CCID_REPLY_ICC_ACTIVE = 0, 266 CCID_REPLY_ICC_INACTIVE, 267 CCID_REPLY_ICC_MISSING 268 } ccid_reply_icc_status_t; 269 270 typedef enum { 271 CCID_REPLY_STATUS_COMPLETE = 0, 272 CCID_REPLY_STATUS_FAILED, 273 CCID_REPLY_STATUS_MORE_TIME 274 } ccid_reply_command_status_t; 275 276 /* 277 * Errors that are defined based when commands fail. These are based on CCID 278 * r.1.1.0 Table 6.2-2 'Slot error register when bmCommandStatus = 1'. 279 */ 280 typedef enum ccid_command_err { 281 CCID_ERR_CMD_ABORTED = 0xff, 282 CCID_ERR_ICC_MUTE = 0xfe, 283 CCID_ERR_XFR_PARITY_ERROR = 0xfd, 284 CCID_ERR_XFR_OVERRUN = 0xfc, 285 CCID_ERR_HW_ERROR = 0xfb, 286 CCID_ERR_BAD_ATR_TS = 0xf8, 287 CCID_ERR_BAD_ATR_TCK = 0xf7, 288 CCID_ERR_ICC_PROTOCOL_NOT_SUPPORTED = 0xf6, 289 CCID_ERR_ICC_CLASS_NOT_SUPPORTED = 0xf5, 290 CCID_ERR_PROCEDURE_BYTE_CONFLICT = 0xf4, 291 CCID_ERR_DEACTIVATED_PROTOCOL = 0xf3, 292 CCID_ERR_BUSY_WITH_AUTO_SEQUENCE = 0xf2, 293 CCID_ERR_PIN_TIMEOUT = 0xf0, 294 CCID_ERR_PIN_CANCELLED = 0xef, 295 CCID_ERR_CMD_SLOT_BUSY = 0xe0, 296 CCID_ERR_CMD_NOT_SUPPORTED = 0x00 297 } ccid_command_err_t; 298 299 /* 300 * Maximum size of an APDU (application data unit) payload. There are both short 301 * and extended ADPUs. At this time, we only support the short ADPUs. 302 */ 303 #define CCID_APDU_LEN_MAX 261 304 305 #endif /* _KERNEL */ 306 307 #ifdef __cplusplus 308 } 309 #endif 310 311 #endif /* _SYS_USB_CCID_H */ 312