1 /* iso7816.c - ISO 7816 commands
2 * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * GnuPG is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
28 #if defined(GNUPG_SCD_MAIN_HEADER)
29 #include GNUPG_SCD_MAIN_HEADER
30 #elif GNUPG_MAJOR_VERSION == 1
31 /* This is used with GnuPG version < 1.9. The code has been source
32 copied from the current GnuPG >= 1.9 and is maintained over
39 #else /* GNUPG_MAJOR_VERSION != 1 */
41 #endif /* GNUPG_MAJOR_VERSION != 1 */
47 #define CMD_SELECT_FILE 0xA4
48 #define CMD_VERIFY ISO7816_VERIFY
49 #define CMD_CHANGE_REFERENCE_DATA ISO7816_CHANGE_REFERENCE_DATA
50 #define CMD_RESET_RETRY_COUNTER ISO7816_RESET_RETRY_COUNTER
51 #define CMD_GET_DATA 0xCA
52 #define CMD_PUT_DATA 0xDA
55 #define CMD_INTERNAL_AUTHENTICATE 0x88
56 #define CMD_GENERATE_KEYPAIR 0x47
57 #define CMD_GET_CHALLENGE 0x84
58 #define CMD_READ_BINARY 0xB0
59 #define CMD_READ_RECORD 0xB2
68 case SW_EEPROM_FAILURE
: ec
= GPG_ERR_HARDWARE
; break;
69 case SW_WRONG_LENGTH
: ec
= GPG_ERR_INV_VALUE
; break;
70 case SW_CHV_WRONG
: ec
= GPG_ERR_BAD_PIN
; break;
71 case SW_CHV_BLOCKED
: ec
= GPG_ERR_PIN_BLOCKED
; break;
72 case SW_USE_CONDITIONS
: ec
= GPG_ERR_USE_CONDITIONS
; break;
73 case SW_NOT_SUPPORTED
: ec
= GPG_ERR_NOT_SUPPORTED
; break;
74 case SW_BAD_PARAMETER
: ec
= GPG_ERR_INV_VALUE
; break;
75 case SW_FILE_NOT_FOUND
: ec
= GPG_ERR_ENOENT
; break;
76 case SW_RECORD_NOT_FOUND
:ec
= GPG_ERR_NOT_FOUND
; break;
77 case SW_REF_NOT_FOUND
: ec
= GPG_ERR_NO_OBJ
; break;
78 case SW_BAD_P0_P1
: ec
= GPG_ERR_INV_VALUE
; break;
79 case SW_EXACT_LENGTH
: ec
= GPG_ERR_INV_VALUE
; break;
80 case SW_INS_NOT_SUP
: ec
= GPG_ERR_CARD
; break;
81 case SW_CLA_NOT_SUP
: ec
= GPG_ERR_CARD
; break;
82 case SW_SUCCESS
: ec
= 0; break;
84 case SW_HOST_OUT_OF_CORE
: ec
= GPG_ERR_ENOMEM
; break;
85 case SW_HOST_INV_VALUE
: ec
= GPG_ERR_INV_VALUE
; break;
86 case SW_HOST_INCOMPLETE_CARD_RESPONSE
: ec
= GPG_ERR_CARD
; break;
87 case SW_HOST_NOT_SUPPORTED
: ec
= GPG_ERR_NOT_SUPPORTED
; break;
88 case SW_HOST_LOCKING_FAILED
: ec
= GPG_ERR_BUG
; break;
89 case SW_HOST_BUSY
: ec
= GPG_ERR_EBUSY
; break;
90 case SW_HOST_NO_CARD
: ec
= GPG_ERR_CARD_NOT_PRESENT
; break;
91 case SW_HOST_CARD_INACTIVE
: ec
= GPG_ERR_CARD_RESET
; break;
92 case SW_HOST_CARD_IO_ERROR
: ec
= GPG_ERR_EIO
; break;
93 case SW_HOST_GENERAL_ERROR
: ec
= GPG_ERR_GENERAL
; break;
94 case SW_HOST_NO_READER
: ec
= GPG_ERR_ENODEV
; break;
95 case SW_HOST_ABORTED
: ec
= GPG_ERR_CANCELED
; break;
96 case SW_HOST_NO_KEYPAD
: ec
= GPG_ERR_NOT_SUPPORTED
; break;
100 ec
= GPG_ERR_GENERAL
; /* Should not happen. */
101 else if ((sw
& 0xff00) == SW_MORE_DATA
)
102 ec
= 0; /* This should actually never been seen here. */
106 return gpg_error (ec
);
109 /* Map a status word from the APDU layer to a gpg-error code. */
111 iso7816_map_sw (int sw
)
113 /* All APDU functions should return 0x9000 on success but for
114 historical reasons of the implementation some return 0 to
115 indicate success. We allow for that here. */
116 return sw
? map_sw (sw
) : 0;
120 /* This function is specialized version of the SELECT FILE command.
121 SLOT is the card and reader as created for example by
122 apdu_open_reader (), AID is a buffer of size AIDLEN holding the
123 requested application ID. The function can't be used to enumerate
124 AIDs and won't return the AID on success. The return value is 0
125 for okay or a GPG error code. Note that ISO error codes are
126 internally mapped. Bit 0 of FLAGS should be set if the card does
127 not understand P2=0xC0. */
129 iso7816_select_application (int slot
, const char *aid
, size_t aidlen
,
133 sw
= apdu_send_simple (slot
, 0x00, CMD_SELECT_FILE
, 4,
134 (flags
&1)? 0 :0x0c, aidlen
, aid
);
140 iso7816_select_file (int slot
, int tag
, int is_dir
,
141 unsigned char **result
, size_t *resultlen
)
144 unsigned char tagbuf
[2];
146 tagbuf
[0] = (tag
>> 8) & 0xff;
147 tagbuf
[1] = tag
& 0xff;
149 if (result
|| resultlen
)
153 return gpg_error (GPG_ERR_NOT_IMPLEMENTED
);
157 p0
= (tag
== 0x3F00)? 0: is_dir
? 1:2;
158 p1
= 0x0c; /* No FC return. */
159 sw
= apdu_send_simple (slot
, 0x00, CMD_SELECT_FILE
,
160 p0
, p1
, 2, (char*)tagbuf
);
168 /* Do a select file command with a direct path. */
170 iso7816_select_path (int slot
, const unsigned short *path
, size_t pathlen
,
171 unsigned char **result
, size_t *resultlen
)
174 unsigned char buffer
[100];
177 if (result
|| resultlen
)
181 return gpg_error (GPG_ERR_NOT_IMPLEMENTED
);
184 if (pathlen
/2 >= sizeof buffer
)
185 return gpg_error (GPG_ERR_TOO_LARGE
);
187 for (buflen
= 0; pathlen
; pathlen
--, path
++)
189 buffer
[buflen
++] = (*path
>> 8);
190 buffer
[buflen
++] = *path
;
194 p1
= 0x0c; /* No FC return. */
195 sw
= apdu_send_simple (slot
, 0x00, CMD_SELECT_FILE
,
196 p0
, p1
, buflen
, (char*)buffer
);
201 /* This is a private command currently only working for TCOS cards. */
203 iso7816_list_directory (int slot
, int list_dirs
,
204 unsigned char **result
, size_t *resultlen
)
208 if (!result
|| !resultlen
)
209 return gpg_error (GPG_ERR_INV_VALUE
);
213 sw
= apdu_send (slot
, 0x80, 0xAA, list_dirs
? 1:2, 0, -1, NULL
,
215 if (sw
!= SW_SUCCESS
)
217 /* Make sure that pending buffers are released. */
226 /* Check whether the reader supports the ISO command code COMMAND on
227 the keypad. Returns 0 on success. */
229 iso7816_check_keypad (int slot
, int command
, iso7816_pininfo_t
*pininfo
)
233 sw
= apdu_check_keypad (slot
, command
,
234 pininfo
->mode
, pininfo
->minlen
, pininfo
->maxlen
,
236 return iso7816_map_sw (sw
);
240 /* Perform a VERIFY command on SLOT using the card holder verification
241 vector CHVNO with a CHV of lenght CHVLEN. With PININFO non-NULL
242 the keypad of the reader will be used. Returns 0 on success. */
244 iso7816_verify_kp (int slot
, int chvno
, const char *chv
, size_t chvlen
,
245 iso7816_pininfo_t
*pininfo
)
249 if (pininfo
&& pininfo
->mode
)
250 sw
= apdu_send_simple_kp (slot
, 0x00, CMD_VERIFY
, 0, chvno
, chvlen
, chv
,
256 sw
= apdu_send_simple (slot
, 0x00, CMD_VERIFY
, 0, chvno
, chvlen
, chv
);
260 /* Perform a VERIFY command on SLOT using the card holder verification
261 vector CHVNO with a CHV of lenght CHVLEN. Returns 0 on success. */
263 iso7816_verify (int slot
, int chvno
, const char *chv
, size_t chvlen
)
265 return iso7816_verify_kp (slot
, chvno
, chv
, chvlen
, NULL
);
268 /* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder
269 verification vector CHVNO. If the OLDCHV is NULL (and OLDCHVLEN
270 0), a "change reference data" is done, otherwise an "exchange
271 reference data". The new reference data is expected in NEWCHV of
272 length NEWCHVLEN. With PININFO non-NULL the keypad of the reader
275 iso7816_change_reference_data_kp (int slot
, int chvno
,
276 const char *oldchv
, size_t oldchvlen
,
277 const char *newchv
, size_t newchvlen
,
278 iso7816_pininfo_t
*pininfo
)
283 if ((!oldchv
&& oldchvlen
)
284 || (oldchv
&& !oldchvlen
)
285 || !newchv
|| !newchvlen
)
286 return gpg_error (GPG_ERR_INV_VALUE
);
288 buf
= xtrymalloc (oldchvlen
+ newchvlen
);
290 return gpg_error (gpg_err_code_from_errno (errno
));
292 memcpy (buf
, oldchv
, oldchvlen
);
293 memcpy (buf
+oldchvlen
, newchv
, newchvlen
);
295 if (pininfo
&& pininfo
->mode
)
296 sw
= apdu_send_simple_kp (slot
, 0x00, CMD_CHANGE_REFERENCE_DATA
,
297 oldchvlen
? 0 : 1, chvno
, oldchvlen
+newchvlen
, buf
,
303 sw
= apdu_send_simple (slot
, 0x00, CMD_CHANGE_REFERENCE_DATA
,
304 oldchvlen
? 0 : 1, chvno
, oldchvlen
+newchvlen
, buf
);
310 /* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder
311 verification vector CHVNO. If the OLDCHV is NULL (and OLDCHVLEN
312 0), a "change reference data" is done, otherwise an "exchange
313 reference data". The new reference data is expected in NEWCHV of
316 iso7816_change_reference_data (int slot
, int chvno
,
317 const char *oldchv
, size_t oldchvlen
,
318 const char *newchv
, size_t newchvlen
)
320 return iso7816_change_reference_data_kp (slot
, chvno
, oldchv
, oldchvlen
,
321 newchv
, newchvlen
, NULL
);
326 iso7816_reset_retry_counter_kp (int slot
, int chvno
,
327 const char *newchv
, size_t newchvlen
,
328 iso7816_pininfo_t
*pininfo
)
332 if (!newchv
|| !newchvlen
)
333 return gpg_error (GPG_ERR_INV_VALUE
);
335 if (pininfo
&& pininfo
->mode
)
336 sw
= apdu_send_simple_kp (slot
, 0x00, CMD_RESET_RETRY_COUNTER
,
337 2, chvno
, newchvlen
, newchv
,
343 sw
= apdu_send_simple (slot
, 0x00, CMD_RESET_RETRY_COUNTER
,
344 2, chvno
, newchvlen
, newchv
);
350 iso7816_reset_retry_counter (int slot
, int chvno
,
351 const char *newchv
, size_t newchvlen
)
353 return iso7816_reset_retry_counter_kp (slot
, chvno
, newchv
, newchvlen
, NULL
);
358 /* Perform a GET DATA command requesting TAG and storing the result in
359 a newly allocated buffer at the address passed by RESULT. Return
360 the length of this data at the address of RESULTLEN. */
362 iso7816_get_data (int slot
, int tag
,
363 unsigned char **result
, size_t *resultlen
)
367 if (!result
|| !resultlen
)
368 return gpg_error (GPG_ERR_INV_VALUE
);
372 sw
= apdu_send (slot
, 0x00, CMD_GET_DATA
,
373 ((tag
>> 8) & 0xff), (tag
& 0xff), -1, NULL
,
375 if (sw
!= SW_SUCCESS
)
377 /* Make sure that pending buffers are released. */
388 /* Perform a PUT DATA command on card in SLOT. Write DATA of length
391 iso7816_put_data (int slot
, int tag
,
392 const unsigned char *data
, size_t datalen
)
396 sw
= apdu_send_simple (slot
, 0x00, CMD_PUT_DATA
,
397 ((tag
>> 8) & 0xff), (tag
& 0xff),
398 datalen
, (const char*)data
);
402 /* Manage Security Environment. This is a weird operation and there
403 is no easy abstraction for it. Furthermore, some card seem to have
404 a different interpreation of 7816-8 and thus we resort to let the
405 caller decide what to do. */
407 iso7816_manage_security_env (int slot
, int p1
, int p2
,
408 const unsigned char *data
, size_t datalen
)
412 if (p1
< 0 || p1
> 255 || p2
< 0 || p2
> 255 )
413 return gpg_error (GPG_ERR_INV_VALUE
);
415 sw
= apdu_send_simple (slot
, 0x00, CMD_MSE
, p1
, p2
,
416 data
? datalen
: -1, (const char*)data
);
421 /* Perform the security operation COMPUTE DIGITAL SIGANTURE. On
422 success 0 is returned and the data is availavle in a newly
423 allocated buffer stored at RESULT with its length stored at
426 iso7816_compute_ds (int slot
, const unsigned char *data
, size_t datalen
,
427 unsigned char **result
, size_t *resultlen
)
431 if (!data
|| !datalen
|| !result
|| !resultlen
)
432 return gpg_error (GPG_ERR_INV_VALUE
);
436 sw
= apdu_send (slot
, 0x00, CMD_PSO
, 0x9E, 0x9A, datalen
, (const char*)data
,
438 if (sw
!= SW_SUCCESS
)
440 /* Make sure that pending buffers are released. */
451 /* Perform the security operation DECIPHER. PADIND is the padding
452 indicator to be used. It should be 0 if no padding is required, a
453 value of -1 suppresses the padding byte. On success 0 is returned
454 and the plaintext is available in a newly allocated buffer stored
455 at RESULT with its length stored at RESULTLEN. */
457 iso7816_decipher (int slot
, const unsigned char *data
, size_t datalen
,
458 int padind
, unsigned char **result
, size_t *resultlen
)
463 if (!data
|| !datalen
|| !result
|| !resultlen
)
464 return gpg_error (GPG_ERR_INV_VALUE
);
470 /* We need to prepend the padding indicator. */
471 buf
= xtrymalloc (datalen
+ 1);
473 return gpg_error (gpg_err_code_from_errno (errno
));
475 *buf
= padind
; /* Padding indicator. */
476 memcpy (buf
+1, data
, datalen
);
477 sw
= apdu_send (slot
, 0x00, CMD_PSO
, 0x80, 0x86,
478 datalen
+1, (char*)buf
,
484 sw
= apdu_send (slot
, 0x00, CMD_PSO
, 0x80, 0x86,
485 datalen
, (const char *)data
,
488 if (sw
!= SW_SUCCESS
)
490 /* Make sure that pending buffers are released. */
502 iso7816_internal_authenticate (int slot
,
503 const unsigned char *data
, size_t datalen
,
504 unsigned char **result
, size_t *resultlen
)
508 if (!data
|| !datalen
|| !result
|| !resultlen
)
509 return gpg_error (GPG_ERR_INV_VALUE
);
513 sw
= apdu_send (slot
, 0x00, CMD_INTERNAL_AUTHENTICATE
, 0, 0,
514 datalen
, (const char*)data
, result
, resultlen
);
515 if (sw
!= SW_SUCCESS
)
517 /* Make sure that pending buffers are released. */
529 do_generate_keypair (int slot
, int readonly
,
530 const unsigned char *data
, size_t datalen
,
531 unsigned char **result
, size_t *resultlen
)
535 if (!data
|| !datalen
|| !result
|| !resultlen
)
536 return gpg_error (GPG_ERR_INV_VALUE
);
540 sw
= apdu_send (slot
, 0x00, CMD_GENERATE_KEYPAIR
, readonly
? 0x81:0x80, 0,
541 datalen
, (const char*)data
, result
, resultlen
);
542 if (sw
!= SW_SUCCESS
)
544 /* Make sure that pending buffers are released. */
556 iso7816_generate_keypair (int slot
,
557 const unsigned char *data
, size_t datalen
,
558 unsigned char **result
, size_t *resultlen
)
560 return do_generate_keypair (slot
, 0, data
, datalen
, result
, resultlen
);
565 iso7816_read_public_key (int slot
,
566 const unsigned char *data
, size_t datalen
,
567 unsigned char **result
, size_t *resultlen
)
569 return do_generate_keypair (slot
, 1, data
, datalen
, result
, resultlen
);
575 iso7816_get_challenge (int slot
, int length
, unsigned char *buffer
)
578 unsigned char *result
;
581 if (!buffer
|| length
< 1)
582 return gpg_error (GPG_ERR_INV_VALUE
);
587 n
= length
> 254? 254 : length
;
588 sw
= apdu_send_le (slot
, 0x00, CMD_GET_CHALLENGE
, 0, 0, -1, NULL
,
590 &result
, &resultlen
);
591 if (sw
!= SW_SUCCESS
)
593 /* Make sure that pending buffers are released. */
599 memcpy (buffer
, result
, resultlen
);
609 /* Perform a READ BINARY command requesting a maximum of NMAX bytes
610 from OFFSET. With NMAX = 0 the entire file is read. The result is
611 stored in a newly allocated buffer at the address passed by RESULT.
612 Returns the length of this data at the address of RESULTLEN. */
614 iso7816_read_binary (int slot
, size_t offset
, size_t nmax
,
615 unsigned char **result
, size_t *resultlen
)
618 unsigned char *buffer
;
620 int read_all
= !nmax
;
623 if (!result
|| !resultlen
)
624 return gpg_error (GPG_ERR_INV_VALUE
);
628 /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus
629 we check for this limit. */
631 return gpg_error (GPG_ERR_INV_VALUE
);
637 /* Note, that we to set N to 254 due to problems either with the
638 ccid driver or some TCOS cards. It actually should be 0
639 which is the official ISO value to read a variable length
641 if (read_all
|| nmax
> 254)
645 sw
= apdu_send_le (slot
, 0x00, CMD_READ_BINARY
,
646 ((offset
>>8) & 0xff), (offset
& 0xff) , -1, NULL
,
647 n
, &buffer
, &bufferlen
);
648 if ( SW_EXACT_LENGTH_P(sw
) )
651 sw
= apdu_send_le (slot
, 0x00, CMD_READ_BINARY
,
652 ((offset
>>8) & 0xff), (offset
& 0xff) , -1, NULL
,
653 n
, &buffer
, &bufferlen
);
656 if (*result
&& sw
== SW_BAD_P0_P1
)
658 /* Bad Parameter means that the offset is outside of the
659 EF. When reading all data we take this as an indication
664 if (sw
!= SW_SUCCESS
&& sw
!= SW_EOF_REACHED
)
666 /* Make sure that pending buffers are released. */
673 if (*result
) /* Need to extend the buffer. */
675 unsigned char *p
= xtryrealloc (*result
, *resultlen
+ bufferlen
);
678 gpg_error_t err
= gpg_error_from_syserror ();
686 memcpy (*result
+ *resultlen
, buffer
, bufferlen
);
687 *resultlen
+= bufferlen
;
691 else /* Transfer the buffer into our result. */
694 *resultlen
= bufferlen
;
698 break; /* We simply truncate the result for too large
700 if (nmax
> bufferlen
)
705 while ((read_all
&& sw
!= SW_EOF_REACHED
) || (!read_all
&& nmax
));
710 /* Perform a READ RECORD command. RECNO gives the record number to
711 read with 0 indicating the current record. RECCOUNT must be 1 (not
712 all cards support reading of more than one record). SHORT_EF
713 should be 0 to read the current EF or contain a short EF. The
714 result is stored in a newly allocated buffer at the address passed
715 by RESULT. Returns the length of this data at the address of
718 iso7816_read_record (int slot
, int recno
, int reccount
, int short_ef
,
719 unsigned char **result
, size_t *resultlen
)
722 unsigned char *buffer
;
725 if (!result
|| !resultlen
)
726 return gpg_error (GPG_ERR_INV_VALUE
);
730 /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus
731 we check for this limit. */
732 if (recno
< 0 || recno
> 255 || reccount
!= 1
733 || short_ef
< 0 || short_ef
> 254 )
734 return gpg_error (GPG_ERR_INV_VALUE
);
738 /* Fixme: Either the ccid driver or the TCOS cards have problems
740 sw
= apdu_send_le (slot
, 0x00, CMD_READ_RECORD
,
742 short_ef
? short_ef
: 0x04,
744 254, &buffer
, &bufferlen
);
746 if (sw
!= SW_SUCCESS
&& sw
!= SW_EOF_REACHED
)
748 /* Make sure that pending buffers are released. */
756 *resultlen
= bufferlen
;