diff options
Diffstat (limited to 'usr/src/uts/common/sys')
-rw-r--r-- | usr/src/uts/common/sys/Makefile | 7 | ||||
-rw-r--r-- | usr/src/uts/common/sys/Makefile.syshdrs | 6 | ||||
-rw-r--r-- | usr/src/uts/common/sys/sunddi.h | 2 | ||||
-rw-r--r-- | usr/src/uts/common/sys/usb/clients/ccid/ccid.h | 311 | ||||
-rw-r--r-- | usr/src/uts/common/sys/usb/clients/ccid/uccid.h | 133 |
5 files changed, 459 insertions, 0 deletions
diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile index cee6dfb94d..7ae4558f97 100644 --- a/usr/src/uts/common/sys/Makefile +++ b/usr/src/uts/common/sys/Makefile @@ -1040,6 +1040,10 @@ USBWCMHDRS= \ UGENHDRS= \ usb_ugen.h +USBCCIDHDRS = \ + ccid.h \ + uccid.h + HOTPLUGHDRS= \ hpcsvc.h \ hpctrl.h @@ -1186,6 +1190,7 @@ CHECKHDRS= \ $(SYSEVENTHDRS:%.h=sysevent/%.check) \ $(CONTRACTHDRS:%.h=contract/%.check) \ $(USBAUDHDRS:%.h=usb/clients/audio/%.check) \ + $(USBCCIDHDRS:%.h=usb/clients/ccid/%.check) \ $(USBHUBDHDRS:%.h=usb/hubd/%.check) \ $(USBHIDHDRS:%.h=usb/clients/hid/%.check) \ $(USBMSHDRS:%.h=usb/clients/mass_storage/%.check) \ @@ -1260,6 +1265,7 @@ CHECKHDRS= \ $(ROOTUSBCDCHDRS) \ $(ROOTUSBVIDHDRS) \ $(ROOTUSBWCMHDRS) \ + $(ROOTUSBCCIDHDRS) \ $(ROOTUGENHDRS) \ $(ROOT1394HDRS) \ $(ROOTHOTPLUGHDRS) \ @@ -1318,6 +1324,7 @@ install_h: \ $(ROOTUWBHDRS) \ $(ROOTUWBAHDRS) \ $(ROOTUSBHDRS) \ + $(ROOTUSBCCIDHDRS) \ $(ROOTUSBAUDHDRS) \ $(ROOTUSBHUBDHDRS) \ $(ROOTUSBHIDHDRS) \ diff --git a/usr/src/uts/common/sys/Makefile.syshdrs b/usr/src/uts/common/sys/Makefile.syshdrs index dee5eef53a..54a89a5e9a 100644 --- a/usr/src/uts/common/sys/Makefile.syshdrs +++ b/usr/src/uts/common/sys/Makefile.syshdrs @@ -23,6 +23,7 @@ # Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. # Copyright 2014 Garrett D'Amore <garrett@damore.org> # Copyright 2016 Nexenta Systems, Inc. +# Copyright 2019 Joyent, Inc. # # Common definitions for open and closed headers. @@ -149,6 +150,9 @@ usb/clients/mass_storage/%.check: usb/clients/mass_storage/%.h usb/clients/printer/%.check: usb/clients/printer/%.h $(DOT_H_CHECK) +usb/clients/ccid/%.check: usb/clients/ccid/%.h + $(DOT_H_CHECK) + usb/clients/usbcdc/%.check: usb/clients/usbcdc/%.h $(DOT_H_CHECK) @@ -231,6 +235,7 @@ ROOTDIRS= \ $(ROOTDIR)/usb/clients/usbcdc \ $(ROOTDIR)/usb/clients/video/usbvc \ $(ROOTDIR)/usb/clients/usbinput/usbwcm \ + $(ROOTDIR)/usb/clients/ccid \ $(ROOTDIR)/usb/clients/ugen \ $(ROOTDIR)/1394 \ $(ROOTDIR)/rsm \ @@ -311,6 +316,7 @@ ROOTUSBPRNHDRS= $(USBPRNHDRS:%=$(ROOTDIR)/usb/clients/printer/%) ROOTUSBCDCHDRS= $(USBCDCHDRS:%=$(ROOTDIR)/usb/clients/usbcdc/%) ROOTUSBVIDHDRS= $(USBVIDHDRS:%=$(ROOTDIR)/usb/clients/video/usbvc/%) ROOTUSBWCMHDRS= $(USBWCMHDRS:%=$(ROOTDIR)/usb/clients/usbinput/usbwcm/%) +ROOTUSBCCIDHDRS= $(USBCCIDHDRS:%=$(ROOTDIR)/usb/clients/ccid/%) ROOTUGENHDRS= $(UGENHDRS:%=$(ROOTDIR)/usb/clients/ugen/%) ROOT1394HDRS= $(I1394HDRS:%=$(ROOTDIR)/1394/%) diff --git a/usr/src/uts/common/sys/sunddi.h b/usr/src/uts/common/sys/sunddi.h index 8ce8508114..4d943b8e89 100644 --- a/usr/src/uts/common/sys/sunddi.h +++ b/usr/src/uts/common/sys/sunddi.h @@ -247,6 +247,8 @@ extern "C" { /* Fabric Devices */ #define DDI_NT_IB_ATTACHMENT_POINT "ddi_ctl:attachment_point:ib" /* IB devices */ +#define DDI_NT_CCID_ATTACHMENT_POINT "ddi_ctl:attachment_point:ccid" + /* CCID devices */ #define DDI_NT_AV_ASYNC "ddi_av:async" /* asynchronous AV device */ #define DDI_NT_AV_ISOCH "ddi_av:isoch" /* isochronous AV device */ diff --git a/usr/src/uts/common/sys/usb/clients/ccid/ccid.h b/usr/src/uts/common/sys/usb/clients/ccid/ccid.h new file mode 100644 index 0000000000..0437a957ba --- /dev/null +++ b/usr/src/uts/common/sys/usb/clients/ccid/ccid.h @@ -0,0 +1,311 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019, Joyent, Inc. + */ + +#ifndef _SYS_USB_CCID_H +#define _SYS_USB_CCID_H + +/* + * CCID class driver definitions. + */ + +#include <sys/stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Values for various Hardware, Mechanical, and Pin features. These come from + * the device's class descriptor. + */ +typedef enum ccid_class_voltage { + CCID_CLASS_VOLT_AUTO = 0x00, + CCID_CLASS_VOLT_5_0 = 0x01, + CCID_CLASS_VOLT_3_0 = 0x02, + CCID_CLASS_VOLT_1_8 = 0x04 +} ccid_class_voltage_t; + +typedef enum ccid_class_mechanical { + CCID_CLASS_MECH_CARD_ACCEPT = 0x01, + CCID_CLASS_MECH_CARD_EJECT = 0x02, + CCID_CLASS_MECH_CARD_CAPTURE = 0x04, + CCID_CLASS_MECH_CARD_LOCK = 0x08 +} ccid_class_mechanical_t; + +typedef enum ccid_class_features { + CCID_CLASS_F_AUTO_PARAM_ATR = 0x00000002, + CCID_CLASS_F_AUTO_ICC_ACTIVATE = 0x00000004, + CCID_CLASS_F_AUTO_ICC_VOLTAGE = 0x00000008, + CCID_CLASS_F_AUTO_ICC_CLOCK = 0x00000010, + CCID_CLASS_F_AUTO_BAUD = 0x00000020, + CCID_CLASS_F_AUTO_PARAM_NEG = 0x00000040, + CCID_CLASS_F_AUTO_PPS = 0x00000080, + CCID_CLASS_F_ICC_CLOCK_STOP = 0x00000100, + CCID_CLASS_F_ALTNAD_SUP = 0x00000200, + CCID_CLASS_F_AUTO_IFSD = 0x00000400, + CCID_CLASS_F_TPDU_XCHG = 0x00010000, + CCID_CLASS_F_SHORT_APDU_XCHG = 0x00020000, + CCID_CLASS_F_EXT_APDU_XCHG = 0x00040000, + CCID_CLASS_F_WAKE_UP = 0x00100000 +} ccid_class_features_t; + +typedef enum ccid_class_pin { + CCID_CLASS_PIN_VERIFICATION = 0x01, + CCID_CLASS_PIN_MODIFICATION = 0x02 +} ccid_class_pin_t; + +/* + * CCID Class Descriptor + * + * This structure represents the CCID class descriptor. Note, it should not be a + * packed structure. This is designed to be a native representation. The raw + * structure will be parsed into this instead. + */ +typedef struct ccid_class_descr { + uint8_t ccd_bLength; + uint8_t ccd_bDescriptorType; + uint16_t ccd_bcdCCID; + uint8_t ccd_bMaxSlotIndex; + uint8_t ccd_bVoltageSupport; + uint32_t ccd_dwProtocols; + uint32_t ccd_dwDefaultClock; + uint32_t ccd_dwMaximumClock; + uint8_t ccd_bNumClockSupported; + uint32_t ccd_dwDataRate; + uint32_t ccd_dwMaxDataRate; + uint8_t ccd_bNumDataRatesSupported; + uint32_t ccd_dwMaxIFSD; + uint32_t ccd_dwSyncProtocols; + uint32_t ccd_dwMechanical; + uint32_t ccd_dwFeatures; + uint32_t ccd_dwMaxCCIDMessageLength; + uint8_t ccd_bClassGetResponse; + uint8_t ccd_bClassEnvelope; + uint16_t ccd_wLcdLayout; + uint8_t ccd_bPinSupport; + uint8_t ccd_bMaxCCIDBusySlots; +} ccid_class_descr_t; + +/* + * Definitions for the supported versions of the CCID specification. The version + * is encoded in binary encoded decimal. The major version is in the upper 8 + * bits and the minor version is in the lower 8 bits. We currently check for the + * major version to match. + */ +#define CCID_VERSION_MAJOR(ver) (((ver) & 0xff00) >> 8) +#define CCID_VERSION_MINOR(ver) ((ver) & 0x00ff) +#define CCID_VERSION_ONE 0x01 + +/* + * This structure is used as the data for the CCID_REQUEST_SET_PARAMS request + * and the CCID_RESPONSE_PARAMETERS response. There are different structures for + * T=0 and T=1. These come from CCID r1.1 / Section 6.1.7. + */ +typedef struct ccid_params_t0 { + uint8_t cp0_bmFindexDindex; + uint8_t cp0_bmTCCKST0; + uint8_t cp0_bGuardTimeT0; + uint8_t cp0_bWaitingIntegerT0; + uint8_t cp0_bClockStop; +} __packed ccid_params_t0_t; + +#define CCID_P_TCCKST0_DIRECT 0x00 +#define CCID_P_TCCKST0_INVERSE 0x02 + +typedef struct ccid_params_t1 { + uint8_t cp1_bmFindexDindex; + uint8_t cp1_bmTCCKST1; + uint8_t cp1_bGuardTimeT1; + uint8_t cp1_bmWaitingIntegersT1; + uint8_t cp1_bClockStop; + uint8_t cp1_bIFSC; + uint8_t cp1_bNadValue; +} __packed ccid_params_t1_t; + +typedef union ccid_params { + ccid_params_t0_t ccp_t0; + ccid_params_t1_t ccp_t1; +} ccid_params_t; + +#define CCID_P_FI_DI(fi, di) ((((fi) & 0x0f) << 4) | ((di) & 0x0f)) + +/* + * Everything below this point is reserved for the kernel. + */ +#ifdef _KERNEL + +/* + * These values come from CCID r1.1.0 Table 5.1-1 'Smart Card Device + * Descriptors' + */ +#define CCID_DESCR_TYPE 0x21 +#define CCID_DESCR_LENGTH 0x36 + + +/* + * Minimum and maximum value for a sequence number in the CCID specification. + * The sequence is a 1 byte unsigned value. The values are inclusive. We reserve + * the value of 0x00 so that we can use it as a sentinel in the ccid_command_t + * structure to know when we should or shouldn't free a command structure's + * sequence number back to the id space. + */ +#define CCID_SEQ_MIN 0x01 +#define CCID_SEQ_MAX UINT8_MAX + + +/* + * All structures from the specification must be packed. + */ + +/* + * Interrupt-IN messages codes. + */ +typedef enum ccid_intr_code { + CCID_INTR_CODE_SLOT_CHANGE = 0x50, + CCID_INTR_CODE_HW_ERROR = 0x51 +} __packed ccid_intr_code_t; + +typedef enum ccid_intr_hwerr_code { + CCID_INTR_HWERR_OVERCURRENT = 0x01 +} __packed ccid_intr_hwerr_code_t; + +typedef struct ccid_intr_slot { + uint8_t cis_type; + uint8_t cis_state[]; +} __packed ccid_intr_slot_t; + +typedef struct ccid_intr_hwerr { + uint8_t cih_type; + uint8_t cih_slot; + uint8_t cih_seq; + uint8_t cih_code; +} __packed ccid_intr_hwerr_t; + +/* + * Message request codes. These codes are based on CCID r1.1.0 Table 6.1-1 + * 'Summary of Bulk-Out Messages'. The name from the standard is to the right of + * the enum. + */ +typedef enum ccid_request_code { + CCID_REQUEST_POWER_ON = 0x62, /* PC_to_RDR_IccPowerOn */ + CCID_REQUEST_POWER_OFF = 0x63, /* PC_to_RDR_IccPowerOff */ + CCID_REQUEST_SLOT_STATUS = 0x65, /* PC_to_RDR_GetSlotStatus */ + CCID_REQUEST_TRANSFER_BLOCK = 0x6f, /* PC_to_RDR_XfrBlock */ + CCID_REQUEST_GET_PARAMS = 0x6c, /* PC_to_RDR_GetParameters */ + CCID_REQUEST_RESET_PARAMS = 0x6d, /* PC_to_RDR_ResetParameters */ + CCID_REQUEST_SET_PARAMS = 0x61, /* PC_to_RDR_SetParameters */ + CCID_REQUEST_ESCAPE = 0x6b, /* PC_to_RDR_Escape */ + CCID_REQUEST_ICC_CLOCK = 0x6e, /* PC_to_RDR_IccClock */ + CCID_REQUEST_T0APDU = 0x6a, /* PC_to_RDR_T0APDU */ + CCID_REQUEST_SECURE = 0x69, /* PC_to_RDR_Secure */ + CCID_REQUEST_MECHANICAL = 0x71, /* PC_to_RDR_Mechanica */ + CCID_REQEUST_ABORT = 0x72, /* PC_to_RDR_Abort */ + CCID_REQUEST_DATA_CLOCK = 0x73 /* PC_to_RDR_SetDataRateAnd */ + /* ClockFrequency */ +} __packed ccid_request_code_t; + +/* + * Message request codes. These codes are based on CCID r1.1.0 Table 6.2-1 + * 'Summary of Bulk-In Messages'. The name from the standard is to the right of + * the enum. + */ +typedef enum ccid_response_code { + CCID_RESPONSE_DATA_BLOCK = 0x80, /* RDR_to_PC_DataBlock */ + CCID_RESPONSE_SLOT_STATUS = 0x81, /* RDR_to_PC_SlotStatus */ + CCID_RESPONSE_PARAMETERS = 0x82, /* RDR_to_PC_Parameters */ + CCID_RESPONSE_ESCAPE = 0x83, /* RDR_to_PC_Escape */ + CCID_RESPONSE_DATA_CLOCK = 0x84 /* RDR_to_PC_DataRateAnd */ + /* ClockFrequency */ +} __packed ccid_response_code_t; + +/* + * This represents the CCID command header that is used for every request and + * response. + */ +typedef struct ccid_header { + uint8_t ch_mtype; + uint32_t ch_length; /* Length of ch_data in bytes */ + uint8_t ch_slot; /* CCID slot to target */ + uint8_t ch_seq; /* Request/Response sequence num */ + uint8_t ch_param0; /* Request/Response specific */ + uint8_t ch_param1; /* Request/Response specific */ + uint8_t ch_param2; /* Request/Response specific */ + uint8_t ch_data[]; /* Optional Request/Response Data */ +} __packed ccid_header_t; + +/* + * This structure is used as the data for the CCID_REQUEST_DATA_CLOCK and + * CCID_RESPONSE_DATA_CLOCK commands. + */ +typedef struct ccid_data_clock { + uint32_t cdc_clock; + uint32_t cdc_data; +} __packed ccid_data_clock_t; + +/* + * Macros and constants to take apart the slot status (in ch_param1) when a CCID + * reply comes in. + */ +#define CCID_REPLY_ICC(x) (x & 0x3) +#define CCID_REPLY_STATUS(x) ((x & 0xc0) >> 6) + +typedef enum { + CCID_REPLY_ICC_ACTIVE = 0, + CCID_REPLY_ICC_INACTIVE, + CCID_REPLY_ICC_MISSING +} __packed ccid_reply_icc_status_t; + +typedef enum { + CCID_REPLY_STATUS_COMPLETE = 0, + CCID_REPLY_STATUS_FAILED, + CCID_REPLY_STATUS_MORE_TIME +} __packed ccid_reply_command_status_t; + +/* + * Errors that are defined based when commands fail. These are based on CCID + * r.1.1.0 Table 6.2-2 'Slot error register when bmCommandStatus = 1'. + */ +typedef enum ccid_command_err { + CCID_ERR_CMD_ABORTED = 0xff, + CCID_ERR_ICC_MUTE = 0xfe, + CCID_ERR_XFR_PARITY_ERROR = 0xfd, + CCID_ERR_XFR_OVERRUN = 0xfc, + CCID_ERR_HW_ERROR = 0xfb, + CCID_ERR_BAD_ATR_TS = 0xf8, + CCID_ERR_BAD_ATR_TCK = 0xf7, + CCID_ERR_ICC_PROTOCOL_NOT_SUPPORTED = 0xf6, + CCID_ERR_ICC_CLASS_NOT_SUPPORTED = 0xf5, + CCID_ERR_PROCEDURE_BYTE_CONFLICT = 0xf4, + CCID_ERR_DEACTIVATED_PROTOCOL = 0xf3, + CCID_ERR_BUSY_WITH_AUTO_SEQUENCE = 0xf2, + CCID_ERR_PIN_TIMEOUT = 0xf0, + CCID_ERR_PIN_CANCELLED = 0xef, + CCID_ERR_CMD_SLOT_BUSY = 0xe0, + CCID_ERR_CMD_NOT_SUPPORTED = 0x00 +} __packed ccid_command_err_t; + +/* + * Maximum size of an APDU (application data unit) payload. There are both short + * and extended ADPUs. At this time, we only support the short ADPUs. + */ +#define CCID_APDU_LEN_MAX 261 + +#endif /* _KERNEL */ + +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_USB_CCID_H */ diff --git a/usr/src/uts/common/sys/usb/clients/ccid/uccid.h b/usr/src/uts/common/sys/usb/clients/ccid/uccid.h new file mode 100644 index 0000000000..9aee0559b6 --- /dev/null +++ b/usr/src/uts/common/sys/usb/clients/ccid/uccid.h @@ -0,0 +1,133 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2019, Joyent, Inc. + */ + +#ifndef _SYS_USB_UCCID_H +#define _SYS_USB_UCCID_H + +/* + * Definitions for the userland CCID interface. + */ + +#include <sys/types.h> +#include <sys/usb/clients/ccid/ccid.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The maximum size of a normal APDU. This is the upper bound of what a user can + * read or write to a given card. + */ +#define UCCID_APDU_SIZE_MAX 261 + +/* + * This is the maximum length of an ATR as per ISO/IEC 7816-3:2006. + */ +#define UCCID_ATR_MAX 33 + + +#define UCCID_IOCTL (('u' << 24) | ('c' << 16) | ('d') << 8) + +#define UCCID_VERSION_ONE 1 +#define UCCID_CURRENT_VERSION UCCID_VERSION_ONE + +/* + * Attempt to obtain exclusive access. If the UCN_TXN_DONT_BLOCK flag is + * specified, the ioctl will return immediately if exclusive access cannot be + * gained. Otherwise, it will block in an interruptible fashion. The argument is + * a uccid_cmd_txn_begin_t. + */ +#define UCCID_CMD_TXN_BEGIN (UCCID_IOCTL | 0x01) +#define UCCID_TXN_DONT_BLOCK 0x01 + +typedef struct uccid_cmd_txn_begin { + uint32_t uct_version; + uint32_t uct_flags; +} __packed uccid_cmd_txn_begin_t; + +/* + * Relinquish exclusive access. Takes a uccid_cmd_txn_end_t. The callers should + * specify one of UCCID_TXN_END_RESET or UCCID_TXN_END_RELEASE. These indicate + * what behavior should be taken when we release the transaction. It is + * considered an error if neither is specified. If the caller exits without + * calling this function, then the ICC will be reset. + */ +#define UCCID_CMD_TXN_END (UCCID_IOCTL | 0x02) +#define UCCID_TXN_END_RESET 0x01 +#define UCCID_TXN_END_RELEASE 0x02 + +typedef struct uccid_cmd_txn_end { + uint32_t uct_version; + uint32_t uct_flags; +} __packed uccid_cmd_txn_end_t; + +/* + * Obtain the status of the slot. Returns a filled-in uccid_cmd_status_t. + */ +#define UCCID_CMD_STATUS (UCCID_IOCTL | 0x3) + +/* + * Protocol definitions. This should match common/ccid/atr.h. + */ +typedef enum { + UCCID_PROT_T0 = 1 << 0, + UCCID_PROT_T1 = 1 << 1 +} uccid_prot_t; + +/* + * Bits for UCS Status + */ +#define UCCID_STATUS_F_CARD_PRESENT 0x01 +#define UCCID_STATUS_F_CARD_ACTIVE 0x02 +#define UCCID_STATUS_F_PRODUCT_VALID 0x04 +#define UCCID_STATUS_F_SERIAL_VALID 0x08 +#define UCCID_STATUS_F_PARAMS_VALID 0x10 + +typedef struct uccid_cmd_status { + uint32_t ucs_version; + uint32_t ucs_status; + int32_t ucs_instance; + uint32_t ucs_slot; + uint8_t ucs_atr[UCCID_ATR_MAX]; + uint8_t ucs_atrlen; + uint8_t ucs_pad[6]; + int8_t ucs_product[256]; + int8_t ucs_serial[256]; + ccid_class_descr_t ucs_class; + uccid_prot_t ucs_prot; + ccid_params_t ucs_params; +} __packed uccid_cmd_status_t; + +/* + * Modify the state of the ICC, if present. + */ +#define UCCID_CMD_ICC_MODIFY (UCCID_IOCTL | 0x04) + +#define UCCID_ICC_POWER_ON 0x01 +#define UCCID_ICC_POWER_OFF 0x02 +#define UCCID_ICC_WARM_RESET 0x03 + +typedef struct uccid_cmd_icc_modify { + uint32_t uci_version; + uint32_t uci_action; +} __packed uccid_cmd_icc_modify_t; + +#ifdef __cplusplus +} +#endif + + +#endif /* _SYS_USB_UCCID_H */ |