summaryrefslogtreecommitdiff
path: root/usr/src/man/man4d/ccid.4d
blob: 622d37109e9491474ee59745ec476a14059fcad2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
.\"
.\" 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.
.\"
.Dd December 20, 2019
.Dt CCID 4D
.Os
.Sh NAME
.Nm ccid
.Nd chip card interface device USB client class driver
.Sh SYNOPSIS
.In sys/usb/clients/ccid/uccid.h
.Sh INTERFACE LEVEL
.Sy Volatile
.Pp
The interfaces provided by this driver are private at this time and
subject to change.
It should not be relied upon.
.Sh DESCRIPTION
The
.Nm
driver is a USB CCID (chip card interface device) class device driver.
.Pp
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
.Xr cfgadm 8 .
.Ss 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.
.Pp
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.
.Pp
In addition, at this time the driver does not support devices which
require manually setting the clock and data rates to support an ICC.
.Ss 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
.Pa /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.
.Pp
Slots are enumerated using this pattern:
.Pa /dev/ccid/ccid%instance/slot%slot .
.Pp
For example, all the slots that belong to CCID instance 5 will be
enumerated under the directory
.Pa /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:
.Pa /dev/ccid/ccid0/slot1 .
.Pp
To enumerate all of the ccid devices present on the system, one could
read all of the directories under
.Pa /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:
.Pa /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).
.Pp
All of the CCID devices in the system can also be listed by using the
.Xr ccidadm 8
command.
.Ss 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.
.Pp
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
.Xr read 2
and
.Xr write 2
family of system calls.
To submit a command, the program would issue a
.Xr 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
.Xr 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
.Xr read 2
system call to obtain results.
Only a single thread may be blocked waiting to submit a command or
read a response.
.Pp
To facilitate non-blocking operation, the underlying file descriptor may
be opened with
.Dv O_NONBLOCK .
.Pp
While a transaction is active,
.Xr poll 2
may be used to receive status information about the slot.
The following events are used by
.Nm :
.Bl -tag -width POLLRDNORM
.It Dv POLLOUT
The device is ready to receive a command using
.Xr write 2 .
.It Dv POLLIN, POLLRDNORM
The device has completed a command the results may be retrieved with
.Xr read 2 .
.It Dv POLLHUP
The card has been removed from the slot.
.It Dv POLLERR
An hardware error has occurred, or the CCID reader has been disconnected.
.El
.Pp
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.
.Pp
While a transaction is open, various events can occur that cause a fatal
error on the transaction.
These include:
.Bl -bullet -offset indent
.It
USB CCID reader removed
.It
ICC removed
.It
A fatal error while communicating to the device
.It
An administrator issued an ioctl to power off or reset the ICC
.El
.Pp
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.
.Ss 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
.Sy PRIV_SYS_DEVICES .
The device node can be opened through the
.Xr open 2
or
.Xr openat 2
system calls.
For programs that just want to query the slot status using the
.Dv 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
.Po Dv O_RDWR Pc .
.Pp
Once the device has been opened, the program may issue ioctls to get
status information.
.Pp
To perform general I/O to the card, a program must be in the context of
a transaction as discussed in the
.Sx I/O Model
section.
To open a transaction, a program must issue the
.Dv UCCID_CMD_TXN_BEGIN
command through the
.Xr ioctl 2
system call.
.Pp
When a program is done, it must issue the
.Dv 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.
.Pp
Please see the ioctl listing in the
.Sx IOCTLS
section for more information on the command structure.
.Pp
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
.Dv EINPROGRESS .
If another transaction is already active,
.Dv 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
.Xr fork 2 ,
even across calls to
.Xr exec 2 .
.Ss 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.
.Pp
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.
.Pp
To obtain information about the reader, slot, and the ATR, one should
issue the
.Dv UCCID_CMD_STATUS
command.
Please see the ioctl listing in the
.Sx IOCTLS
section for more information.
.Sh IOCTLS
This section lists the different commands that may be issued to a CCID
device through the
.Xr ioctl 2
system call.
.Ss Ic 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.
.Pp
The
.Ic UCCID_CMD_STATUS
command uses the structure
.Vt uccid_cmd_status_t ,
the fields of which have the following meanings:
.Bl -tag -width Fa
.It Fa uint32_t ucs_version
Indicates the current version of the structure.
This should be set to
.Dv UCCID_CURRENT_VERSION .
.It Fa 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
.Vt uccid_cmd_status_t .
The following flags are defined:
.Bl -tag -width Dv
.It Dv UCCID_STATUS_F_CARD_PRESENT
A card has been inserted into the slot of the CCID class device.
.It Dv UCCID_STATUS_F_CARD_ACTIVE
The inserted card has been successfully activated.
This will only be set if the
.Dv UCCID_STATUS_F_CARD_PRESENT
flag is also set.
.It Dv UCCID_STATUS_F_PRODUCT_VALID
The contents of
.Fa ucs_product
are valid.
.It Dv UCCID_STATUS_F_SERIAL_VALID
The contents of
.Fa ucs_serial
are valid.
.It Dv UCCID_STATUS_F_PARAMS_VALID
The parameters returned in
.Fa ucs_params
are valid.
.El
.It Fa int32_t ucs_instance
The instance number of the CCID device.
.It Fa uint32_t ucs_slot
The slot number currently in use.
.It Fa uint8_t ucs_atr[UCCID_ATR_MAX]
The ATR (answer to reset) of the card.
.It Fa uint8_t ucs_atrlen
The actual length of the ATR data.
A length of 0 indicates that there is no ATR data.
.It Fa int8_t ucs_product[256]
The product string of the CCID device.
.It Fa int8_t ucs_serial[256]
The serial number of the CCID device.
.It Fa ccid_class_descr_t ucs_class
The CCID class descriptor of the CCID device.
.It Fa uccid_prot_t ucs_prot
The protocol in use by the ICC.
This can be either
.Dv UCCID_PROT_T0
for the TPDU T=0 protocol or
.Dv UCCID_PROT_T1
for the TPDU T=1 protocol.
.It Fa ccid_params_t ucs_params
The CCID parameters available on the card.
.El
.Ss Ic 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
.Dv UCCID_TXN_DONT_BLOCK
flag.
.Pp
The command uses the structure
.Vt uccid_cmd_txn_begin_t
with the following members:
.Bl -tag -width Fa
.It Fa uint32_t ucs_version
Indicates the current version of the structure.
This should be set to
.Dv UCCID_CURRENT_VERSION .
.It Fa uint32_t uct_flags
Flags that impact the behavior of the command.
The following flags are defined:
.Bl -tag -width Dv
.It Dv UCCID_TXN_DONT_BLOCK
The command should not block for exclusive access.
If exclusive access is not available, then the command will fail
immediately.
.El
.Pp
If an unknown flag is specified, an error will be returned.
.El
.Ss Ic UCCID_CMD_TXN_END
The
.Dv UCCID_CMD_TXN_END
command is used to end a transaction and relinquish exclusive access
to the ICC.
.Pp
The command uses the structure
.Vt uccid_cmd_txn_end_t
with the following members:
.Bl -tag -width Fa
.It Fa uint32_t uct_version
Indicates the current version of the structure.
This should be set to
.Dv UCCID_CURRENT_VERSION .
.It Fa uint32_t uct_flags
.Bl -tag -width Dv
.It Dv UCCID_TXN_END_RESET
The ICC should be reset at the end of the transaction.
.It Dv UCCID_TXN_END_RELEASE
The ICC should be released without being reset at the end of the
transaction.
.El
.Pp
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.
.El
.Ss Ic UCCID_CMD_ICC_MODIFY
This command can be used to change the state of an ICC, if present.
.Pp
The command uses the structure
.Vt uccid_cmd_icc_modify_t
with the following members:
.Bl -tag -width Fa
.It Fa uint32_t uci_version
Indicates the current version of the structure.
This should be set to
.Dv UCCID_CURRENT_VERSION .
.It Fa uint32_t uci_action
The action to be taken on the ICC.
The following actions are defined:
.Bl -tag -width Dv
.It Dv UCCID_ICC_POWER_ON
Power on the ICC.
.It Dv UCCID_ICC_POWER_OFF
Power off the ICC.
.It Dv UCCID_ICC_WARM_RESET
Perform a warm reset of the ICC.
.El
.El
.Ss Ic FIONREAD
This command returns the size in bytes of a command response available
for reading with
.Xr read 2 .
The size is returned in an
.Vt int
pointed to by the argument.
.Sh SYSTEM CALLS
This section lists the different system calls that may be issued to a
CCID device.
.Ss Xr open 2
.Nm
slot device nodes can be opened using
.Xr open 2 .
Non-blocking operation can be selected by using the
.Dv 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.
.Ss Xr close 2
When no longer needed by a program, a device node can be closed with
.Xr 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.
.Ss Xr ioctl 2
The
.Xr ioctl 2
system call can be used to start or end a transaction, query the reply size for
.Xr read 2 ,
query the ICC and CCID reader status, or change the state of an ICC in a reader.
See section
.Sx IOCTLS
for details.
.Ss Xr write 2
Within an active transaction the
.Xr 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
.Xr read 2
call before
.Xr write 2
can be called again within the same transaction.
.Pp
The following errors for
.Xr write 2
have specific meaning in
.Nm :
.Bl -tag -width Dv
.It Dv E2BIG
The number of bytes to write is larger than the maximum APDU length supported by
.Nm ,
currently defined as 261 bytes.
.It Dv EACCES
The device is opened read-only, or no transaction is active.
.It Dv EBUSY
There is unread data from a previous call to
.Xr write 2 .
.It Dv ENOTSUP
The reader and/or ICC is unsupported for I/O.
.It Dv ENXIO
The ICC is inactive and can't be used for I/O.
.It Dv ENODEV
The CCID reader has been disconnected.
.El
.Ss Xr read 2
Within an active transaction the
.Xr read 2
system call is used to read the reply from an ICC following sending an APDU with
.Xr write 2 .
The whole reply needs to be read with a single call to
.Xr read 2 .
The size of the reply can be queried before reading by issuing the
.Dv FIONREAD
ioctl.
See section
.Sx IOCTLS
for details.
.Pp
The following errors for
.Xr read 2
have specific meaning in
.Nm :
.Bl -tag -width Dv
.It Dv EACCES
No transaction is active.
.It Dv EBUSY
Another thread is already blocked in
.Xr read 2
waiting for data.
.It Dv EOVERFLOW
The buffer size is too small to fit the reply.
.It Dv ENODATA
No
.Xr write 2
was issued before and consequently there is no reply to be read.
.It Dv ENODEV
The CCID reader has been disconnected.
.El
.Ss Xr poll 2
Within an active transaction the
.Xr poll 2
system call is used to wait for status changes on a device node.
See section
.Sx I/O model
for details.
.Pp
The following errors for
.Xr poll 2
have specific meaning in
.Nm :
.Bl -tag -width Dv
.It Dv EACCES
No transaction is active.
.It Dv ENODEV
The CCID reader has been disconnected.
.El
.Sh SEE ALSO
.Xr close 2 ,
.Xr ioctl 2 ,
.Xr open 2 ,
.Xr poll 2 ,
.Xr read 2 ,
.Xr write 2 ,
.Xr ccidadm 8 ,
.Xr cfgadm 8
.Rs
.%T Universal Serial Bus Device Class: Smart Card CCID
.%O Revision 1.1
.%D April 22, 2005
.Re
.Rs
.%Q ISO/IEC
.%B Identification Cards - Integrated Circuits
.%N Part 3: Cards with contacts — Electrical interface and transmission protocols
.%O ISO/IEC 7616-3:2006
.%D 2006
.Re