CCID(4D)                           Devices                          CCID(4D)
NAME
     ccid - chip card interface device USB client class driver
SYNOPSIS
     #include <sys/usb/clients/ccid/uccid.h>INTERFACE LEVEL
     Volatile     The interfaces provided by this driver are private at this time and
     subject to change.  It should not be relied upon.
DESCRIPTION
     The 
ccid driver is a USB CCID (chip card interface device) class device
     driver.
     The driver exposes interfaces that allow consumers to send and receive
     APDUs (application protocol data unit) to a given smart card that is
     plugged into a reader.  The driver also provides interfaces to obtain
     status information, the ATR (answer to reset), and obtain exclusive
     access to the device.  In addition, the system exposes control of CCID
     devices through 
cfgadm(8).
   Supported Devices
     The CCID specification allows for readers to come in different flavors.
     These different flavors support different communication protocols and
     have different levels of automation for determining the protocol and
     transfers that are required.
     At this time, only the short APDU protocol is supported, which also
     works with readers using the extended APDU protocol.  TPDU and
     character level readers are not supported by the driver.  Readers in
     this category will still attach; however, I/O cannot be performed to
     them.
     In addition, at this time the driver does not support devices which
     require manually setting the clock and data rates to support an ICC.
   Device Model
     Each CCID class device provides a number of slots.  Each slot may have
     an independent ICC (integrated circuit card or Smart Card) inserted
     into it.  Each device, or reader, has its own directory under 
/dev/ccid     based on its device number.  Inside of each directory is a character
     device for each slot.  A slot exists regardless of whether or not an
     ICC is inserted into it.  As long as a CCID device is present in the
     system, its device nodes will be present.
     Slots are enumerated using this pattern:     
/dev/ccid/ccid%instance/slot%slot.
     For example, all the slots that belong to CCID instance 5 will be
     enumerated under the directory 
/dev/ccid/ccid5.  Slots are numbered
     starting at zero for each reader and increment from there.  For
     example, the second physical slot would be numbered as slot one.  If
     this were on CCID instance zero, then we would find a character device
     at: 
/dev/ccid/ccid0/slot1.
     To enumerate all of the ccid devices present on the system, one could
     read all of the directories under 
/dev/ccid.  To enumerate all of the
     slots on a device, one could read all of the device nodes under a
     particular CCID device, such as: 
/dev/ccid/ccid0.  The number of slots
     is also obtainable through various ioctls that will be discussed later
     on.  It's important to note that while slot numbering will always be
     consistent for a given device, the CCID numbering is based on the
     driver instance.  Therefore, it is possible for a device to change
     device numbers.  To deal with this, symlinks based on other properties
     will be provided (for example, the USB serial number).
     All of the CCID devices in the system can also be listed by using the     
ccidadm(8) command.   
I/O Model     To send and receive responses to commands, a program must open up the
     corresponding slot's device node.  In many of the commands that use an
     ICC, there is a logical notion of state associated with the ICC that is
     mutated by performing commands on it.  For example, a command might be
     issued that uses a PIN to unlock a slot or that selects a particular
     PIV applet for use.  Because of this, all I/O to a given device must be
     performed inside the context of a transaction.  When a program begins a
     transaction, it is guaranteed that no one else may send commands to the
     ICC.  When a program is finished, it must explicitly end the
     transaction, which may have the side effect of resetting the ICC.  If a
     program with an open transaction crashes or closes the file descriptor
     without taking other actions, then the transaction will be
     automatically closed and the ICC will be reset.  Without a transaction
     open, it will still be possible to issue ioctls that obtain the status
     of the slot and the reader.
     While in an active transaction, a program may send commands to a card.
     Sending a command and reading a response are done through the
     traditional 
read(2) and 
write(2) family of system calls.  To submit a
     command, the program would issue a 
write(2) family system call that
     contained the payload to send to the ICC.  Once submitted, the call
     would return and the program would be able to issue a 
read(2) system
     call to obtain the results.  Once a command has been submitted, it is
     illegal to submit another one.  The next command cannot be submitted
     until the response has been fully consumed.  Similarly, if a command
     has not been submitted, one cannot issue a 
read(2) system call to
     obtain results.  Only a single thread may be blocked waiting to submit
     a command or read a response.
     To facilitate non-blocking operation, the underlying file descriptor
     may be opened with O_NONBLOCK.
     While a transaction is active, 
poll(2) may be used to receive status
     information about the slot.  The following events are used by 
ccid:
     POLLOUT     The device is ready to receive a command using 
write(2).
     POLLIN, POLLRDNORM
                 The device has completed a command the results may be
                 retrieved with 
read(2).
     POLLHUP     The card has been removed from the slot.
     POLLERR     An hardware error has occurred, or the CCID reader has been
                 disconnected.
     One important note is that readers with multiple slots often still only
     allow I/O a single command to be outstanding across all of the slots in
     the system.  Because transactions are on a per-slot basis, it is still
     possible for a command submission to block even though one has a
     transaction open.
     While a transaction is open, various events can occur that cause a
     fatal error on the transaction.  These include:           
+o   USB CCID reader removed           
+o   ICC removed           
+o   A fatal error while communicating to the device           
+o   An administrator issued an ioctl to power off or reset the
               ICC
     Once such a fatal error has occurred, all new I/O will fail though it
     will still be possible to read any successfully completed commands.  To
     clear the error state the program will need to end the transaction and
     begin a new one or close the file descriptor if the device has been
     removed.   
Opening Devices, Exclusive Access, and Performing I/O     To perform I/O to a particular card, one must first open the slot of
     interest.  Opening the slot requires that the process be in the global
     zone and that it have the privilege 
PRIV_SYS_DEVICES.  The device node
     can be opened through the 
open(2) or 
openat(2) system calls.  For
     programs that just want to query the slot status using the
     UCCID_CMD_STATUS command, opening the device node read-only is
     sufficient.  All other uses require that the device be opened both for
     reading and writing (O_RDWR).
     Once the device has been opened, the program may issue ioctls to get
     status information.
     To perform general I/O to the card, a program must be in the context of
     a transaction as discussed in the 
I/O Model section.  To open a
     transaction, a program must issue the UCCID_CMD_TXN_BEGIN command
     through the 
ioctl(2) system call.
     When a program is done, it must issue the UCCID_CMD_TXN_END command to
     release the transaction.  As part of issuing the command, the program
     must determine a disposition of what it would like done with the card
     when it has completed.  These options include leaving the ICC alone and
     resetting the ICC.  For many use cases, such as those where a pin is
     entered or the ICC's state is mutated, a reset is the recommended
     option.  If the program crashes or closes the file descriptor without
     issuing a transaction end, then the ICC will be reset.
     Please see the ioctl listing in the 
IOCTLS section for more information
     on the command structure.
     If a multi-threaded application opens a slot once and shares it among
     multiple threads performing I/O to that slot, there can still only be
     one transaction active or waiting on the slot shared by all threads.
     Acquiring another transaction on the same slot minor while another
     thread is already blocked waiting for one will return EINPROGRESS.  If
     another transaction is already active, EINVAL will be returned.
     Consequently, all threads in a multi-threaded application share the
     transaction state and may issue writes, and read the results.  The same
     applies to any other method of sharing an open file descriptor of a
     slot minor, be it by sharing the fd over a socket, a child process
     inheriting it from its parent during 
fork(2), even across calls to     
exec(2).
   Device Status and ATR
     Once a slot has been opened, any caller may issue commands to get the
     status of the slot.  This can also be used to obtain the ATR (answer to
     reset) of an ICC that is present on the slot, if it is known.
     While exclusive access is not required to issue these commands, there
     is no guarantee that they will not have changed between the time that
     the program issued the command and it obtains a transaction.
     To obtain information about the reader, slot, and the ATR, one should
     issue the UCCID_CMD_STATUS command.  Please see the ioctl listing in
     the 
IOCTLS section for more information.
IOCTLS
     This section lists the different commands that may be issued to a CCID
     device through the 
ioctl(2) system call.   
UCCID_CMD_STATUS     This command is used to obtain the status of the slot.  It may be used
     regardless of whether or not the caller has exclusive access.
     The 
UCCID_CMD_STATUS command uses the structure 
uccid_cmd_status_t, the
     fields of which have the following meanings:     
uint32_t ucs_version                   Indicates the current version of the structure.  This
                   should be set to UCCID_CURRENT_VERSION.     
uint32_t ucs_status                   This value is ignored when issuing the command.  On
                   return, it will be filled in with various flags that
                   describe the current status of the slot and the contents
                   returned in the 
uccid_cmd_status_t.  The following flags
                   are defined:
                   UCCID_STATUS_F_CARD_PRESENT
                                 A card has been inserted into the slot of
                                 the CCID class device.
                   UCCID_STATUS_F_CARD_ACTIVE
                                 The inserted card has been successfully
                                 activated.  This will only be set if the
                                 UCCID_STATUS_F_CARD_PRESENT flag is also
                                 set.
                   UCCID_STATUS_F_PRODUCT_VALID
                                 The contents of 
ucs_product are valid.
                   UCCID_STATUS_F_SERIAL_VALID
                                 The contents of 
ucs_serial are valid.
                   UCCID_STATUS_F_PARAMS_VALID
                                 The parameters returned in 
ucs_params are
                                 valid.     
int32_t ucs_instance                   The instance number of the CCID device.     
uint32_t ucs_slot                   The slot number currently in use.     
uint8_t ucs_atr[UCCID_ATR_MAX]                   The ATR (answer to reset) of the card.     
uint8_t ucs_atrlen                   The actual length of the ATR data.  A length of 0
                   indicates that there is no ATR data.     
int8_t ucs_product[256]                   The product string of the CCID device.     
int8_t ucs_serial[256]                   The serial number of the CCID device.     
ccid_class_descr_t ucs_class                   The CCID class descriptor of the CCID device.     
uccid_prot_t ucs_prot                   The protocol in use by the ICC.  This can be either
                   UCCID_PROT_T0 for the TPDU T=0 protocol or UCCID_PROT_T1
                   for the TPDU T=1 protocol.     
ccid_params_t ucs_params                   The CCID parameters available on the card.   
UCCID_CMD_TXN_BEGIN     This command is used to begin a transaction.  The command will block
     until exclusive access is available to the caller.  If the caller does
     not wish to block, it should set the UCCID_TXN_DONT_BLOCK flag.
     The command uses the structure 
uccid_cmd_txn_begin_t with the following
     members:     
uint32_t ucs_version                   Indicates the current version of the structure.  This
                   should be set to UCCID_CURRENT_VERSION.     
uint32_t uct_flags                   Flags that impact the behavior of the command.  The
                   following flags are defined:
                   UCCID_TXN_DONT_BLOCK
                                 The command should not block for exclusive
                                 access.  If exclusive access is not
                                 available, then the command will fail
                                 immediately.
                   If an unknown flag is specified, an error will be
                   returned.   
UCCID_CMD_TXN_END     The UCCID_CMD_TXN_END command is used to end a transaction and
     relinquish exclusive access to the ICC.
     The command uses the structure 
uccid_cmd_txn_end_t with the following
     members:     
uint32_t uct_version                   Indicates the current version of the structure.  This
                   should be set to UCCID_CURRENT_VERSION.     
uint32_t uct_flags                   UCCID_TXN_END_RESET
                                 The ICC should be reset at the end of the
                                 transaction.
                   UCCID_TXN_END_RELEASE
                                 The ICC should be released without being
                                 reset at the end of the transaction.
                   Exactly one of these two flags must be specified.  It is
                   an error if neither flag or both flags are specified at
                   the same time.  If the device is closed without ending a
                   transaction first, then the ICC will be reset.   
UCCID_CMD_ICC_MODIFY     This command can be used to change the state of an ICC, if present.
     The command uses the structure 
uccid_cmd_icc_modify_t with the
     following members:     
uint32_t uci_version                   Indicates the current version of the structure.  This
                   should be set to UCCID_CURRENT_VERSION.     
uint32_t uci_action                   The action to be taken on the ICC.  The following actions
                   are defined:
                   UCCID_ICC_POWER_ON
                                 Power on the ICC.
                   UCCID_ICC_POWER_OFF
                                 Power off the ICC.
                   UCCID_ICC_WARM_RESET
                                 Perform a warm reset of the ICC.
   FIONREAD
     This command returns the size in bytes of a command response available
     for reading with 
read(2).  The size is returned in an 
int pointed to by
     the argument.
SYSTEM CALLS
     This section lists the different system calls that may be issued to a
     CCID device.   
open(2)     ccid slot device nodes can be opened using 
open(2).  Non-blocking
     operation can be selected by using the O_NONBLOCK flag when opening the
     device node.  A device node opened for read-only operations will not
     allow creating transactions or doing I/O, but it will allow the
     ICC/reader status to be queried.   
close(2)     When no longer needed by a program, a device node can be closed with     
close(2).  If a transaction is still active when a device node is
     closed, the transaction will be ended automatically and the ICC will be
     reset.  Any unread data is discarded.   
ioctl(2)     The 
ioctl(2) system call can be used to start or end a transaction,
     query the reply size for 
read(2), query the ICC and CCID reader status,
     or change the state of an ICC in a reader.  See section 
IOCTLS for
     details.   
write(2)     Within an active transaction the 
write(2) system call can be used to
     transfer an APDU (application protocol data unit) to an ICC, one single
     complete APDU at a time.  Partial writes or writing more than one APDU
     at a time are not supported.  The data returned by the ICC must be
     consumed by a subsequent 
read(2) call before 
write(2) can be called
     again within the same transaction.
     The following errors for 
write(2) have specific meaning in 
ccid:
     E2BIG         The number of bytes to write is larger than the maximum
                   APDU length supported by 
ccid, currently defined as 261
                   bytes.
     EACCES        The device is opened read-only, or no transaction is
                   active.
     EBUSY         There is unread data from a previous call to 
write(2).
     ENOTSUP       The reader and/or ICC is unsupported for I/O.
     ENXIO         The ICC is inactive and can't be used for I/O.
     ENODEV        The CCID reader has been disconnected.   
read(2)     Within an active transaction the 
read(2) system call is used to read
     the reply from an ICC following sending an APDU with 
write(2).  The
     whole reply needs to be read with a single call to 
read(2).  The size
     of the reply can be queried before reading by issuing the FIONREAD
     ioctl.  See section 
IOCTLS for details.
     The following errors for 
read(2) have specific meaning in 
ccid:
     EACCES        No transaction is active.
     EBUSY         Another thread is already blocked in 
read(2) waiting for
                   data.
     EOVERFLOW     The buffer size is too small to fit the reply.
     ENODATA       No 
write(2) was issued before and consequently there is
                   no reply to be read.
     ENODEV        The CCID reader has been disconnected.   
poll(2)     Within an active transaction the 
poll(2) system call is used to wait
     for status changes on a device node.  See section 
I/O model for
     details.
     The following errors for 
poll(2) have specific meaning in 
ccid:
     EACCES        No transaction is active.
     ENODEV        The CCID reader has been disconnected.
SEE ALSO
     close(2), 
ioctl(2), 
open(2), 
poll(2), 
read(2), 
write(2), 
ccidadm(8),     
cfgadm(8)     Universal Serial Bus Device Class: Smart Card CCID, April 22, 2005,
     Revision 1.1.     
Identification Cards - Integrated Circuits, Part 3: Cards with contacts
     -- Electrical interface and transmission protocols, ISO/IEC, 2006,
     ISO/IEC 7616-3:2006.
illumos                       December 20, 2019                      illumos