1 /*
2 * card-sc-hsm.c
3 *
4 * Driver for the SmartCard-HSM, a light-weight hardware security module
5 *
6 * Copyright (C) 2012 Andreas Schwier, CardContact, Minden, Germany, and others
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #if HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <string.h>
28 #include <stdlib.h>
29 #include <ctype.h>
30
31 #include "internal.h"
32 #include "asn1.h"
33 #include "cardctl.h"
34 #include "types.h"
35
36 #include "card-sc-hsm.h"
37
38
39 /* Static reference to ISO driver */
40 static const struct sc_card_operations *iso_ops = NULL;
41
42 /* Our operations */
43 static struct sc_card_operations sc_hsm_ops;
44
45 /* Our driver description */
46 static struct sc_card_driver sc_hsm_drv = {
47 "SmartCard-HSM",
48 "sc-hsm",
49 &sc_hsm_ops,
50 NULL,
51 0,
52 NULL
53 };
54
55
56
57 /* Our AID */
58 struct sc_aid sc_hsm_aid = { { 0xE8,0x2B,0x06,0x01,0x04,0x01,0x81,0xC3,0x1F,0x02,0x01 }, 11 };
59
60
61
62 /* Known ATRs for SmartCard-HSMs */
63 const struct sc_atr_table sc_hsm_atrs[] = {
64 /* standard version */
65 {"3B:FE:18:00:00:81:31:FE:45:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:FA", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL},
66 {"3B:8E:80:01:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:18", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL},
67 {"3B:DE:18:FF:81:91:FE:1F:C3:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:1C", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL},
68 {"3B:DE:96:FF:81:91:FE:1F:C3:80:31:81:54:48:53:4D:31:73:80:21:40:81:07:92", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL},
69
70 {"3B:80:80:01:01", NULL, NULL, SC_CARD_TYPE_SC_HSM_SOC, 0, NULL}, // SoC Sample Card
71 {
72 "3B:84:80:01:47:6f:49:44:00",
73 "FF:FF:FF:FF:FF:FF:FF:FF:00",
74 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
75 },
76 {
77 "3B:85:80:01:47:6f:49:44:00:00",
78 "FF:FF:FF:FF:FF:FF:FF:FF:00:00",
79 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
80 },
81 {
82 "3B:86:80:01:47:6f:49:44:00:00:00",
83 "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00",
84 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
85 },
86 {
87 "3B:87:80:01:47:6f:49:44:00:00:00:00",
88 "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00",
89 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
90 },
91 {
92 "3B:88:80:01:47:6f:49:44:00:00:00:00:00",
93 "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00",
94 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
95 },
96 {
97 "3B:89:80:01:47:6f:49:44:00:00:00:00:00:00",
98 "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00",
99 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
100 },
101 {
102 "3B:8a:80:01:47:6f:49:44:00:00:00:00:00:00:00",
103 "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00",
104 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
105 },
106 {
107 "3B:8b:80:01:47:6f:49:44:00:00:00:00:00:00:00:00",
108 "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00",
109 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
110 },
111 {
112 "3B:8c:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00",
113 "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00",
114 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
115 },
116 {
117 "3B:8d:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00",
118 "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00",
119 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
120 },
121 {
122 "3B:8e:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00",
123 "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00",
124 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
125 },
126 {
127 "3B:8f:80:01:47:6f:49:44:00:00:00:00:00:00:00:00:00:00:00:00",
128 "FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:00:00:00:00:00:00:00:00:00",
129 "GoID", SC_CARD_TYPE_SC_HSM_GOID, 0, NULL
130 },
131 {NULL, NULL, NULL, 0, 0, NULL}
132 };
133
134
135
sc_hsm_select_file_ex(sc_card_t * card,const sc_path_t * in_path,int forceselect,sc_file_t ** file_out)136 static int sc_hsm_select_file_ex(sc_card_t *card,
137 const sc_path_t *in_path, int forceselect,
138 sc_file_t **file_out)
139 {
140 int rv;
141 sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
142 sc_file_t *file = NULL;
143 sc_path_t cpath;
144
145 if (file_out == NULL) { // Versions before 0.16 of the SmartCard-HSM do not support P2='0C'
146 rv = sc_hsm_select_file_ex(card, in_path, forceselect, &file);
147 if (file != NULL) {
148 sc_file_free(file);
149 }
150 return rv;
151 }
152
153 if ((in_path->type == SC_PATH_TYPE_FILE_ID) && in_path->aid.len) {
154 // Split applet selection and file selection into two separate calls
155 cpath = *in_path;
156 cpath.len = 0;
157 cpath.type = SC_PATH_TYPE_DF_NAME;
158 rv = sc_hsm_select_file_ex(card, &cpath, forceselect, NULL);
159 LOG_TEST_RET(card->ctx, rv, "Could not select SmartCard-HSM application");
160
161 if (in_path->len) {
162 cpath = *in_path;
163 cpath.aid.len = 0;
164 rv = sc_hsm_select_file_ex(card, &cpath, forceselect, file_out);
165 }
166 return rv;
167 }
168
169 // Prevent selection of applet unless this is the first time, selection is forced or the device is not authenticated
170 if (in_path->type == SC_PATH_TYPE_DF_NAME
171 || (in_path->type == SC_PATH_TYPE_PATH
172 && in_path->len == sc_hsm_aid.len
173 && !memcmp(in_path->value, sc_hsm_aid.value, sc_hsm_aid.len))
174 || (in_path->type == SC_PATH_TYPE_PATH
175 && in_path->len == 0
176 && in_path->aid.len == sc_hsm_aid.len
177 && !memcmp(in_path->aid.value, sc_hsm_aid.value, sc_hsm_aid.len))) {
178 if (!priv || (priv->dffcp == NULL) || forceselect) {
179 rv = (*iso_ops->select_file)(card, in_path, file_out);
180 LOG_TEST_RET(card->ctx, rv, "Could not select SmartCard-HSM application");
181
182 if (priv) {
183 if (priv->dffcp != NULL) {
184 sc_file_free(priv->dffcp);
185 }
186 // Cache the FCP returned when selecting the applet
187 sc_file_dup(&priv->dffcp, *file_out);
188 }
189 } else {
190 sc_file_dup(file_out, priv->dffcp);
191 rv = SC_SUCCESS;
192 }
193 return rv;
194 }
195
196 if ((in_path->len >= 2) && (in_path->value[0] == 0x3F) && (in_path->value[1] == 0x00)) {
197 // The SmartCard-HSM is an applet that is not default selected. Simulate selection of the MF
198 if (in_path->len == 2) {
199 file = sc_file_new();
200 if (file == NULL)
201 LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
202 file->path = *in_path;
203 file->id = 0x3F00;
204 file->type = SC_FILE_TYPE_DF;
205 file->magic = SC_FILE_MAGIC;
206
207 *file_out = file;
208 return SC_SUCCESS;
209 } else {
210 sc_path_t truncated;
211 memcpy(&truncated, in_path, sizeof truncated);
212 truncated.len = in_path->len - 2;
213 memcpy(truncated.value, in_path->value+2, truncated.len);
214 return (*iso_ops->select_file)(card, &truncated, file_out);
215 }
216 }
217 return (*iso_ops->select_file)(card, in_path, file_out);
218 }
219
220
221
sc_hsm_select_file(sc_card_t * card,const sc_path_t * in_path,sc_file_t ** file_out)222 static int sc_hsm_select_file(sc_card_t *card,
223 const sc_path_t *in_path,
224 sc_file_t **file_out)
225 {
226 return sc_hsm_select_file_ex(card, in_path, 0, file_out);
227 }
228
229
230
sc_hsm_get_challenge(struct sc_card * card,unsigned char * rnd,size_t len)231 static int sc_hsm_get_challenge(struct sc_card *card, unsigned char *rnd, size_t len)
232 {
233 LOG_FUNC_CALLED(card->ctx);
234
235 if (len > 1024) {
236 len = 1024;
237 }
238
239 LOG_FUNC_RETURN(card->ctx, iso_ops->get_challenge(card, rnd, len));
240 }
241
242
243
sc_hsm_match_card(struct sc_card * card)244 static int sc_hsm_match_card(struct sc_card *card)
245 {
246 sc_path_t path;
247 int i, r, type = 0;
248 sc_file_t *file = NULL;
249
250 i = _sc_match_atr(card, sc_hsm_atrs, &type);
251 if (i >= 0 && type != SC_CARD_TYPE_SC_HSM_SOC) {
252 card->type = type;
253 return 1;
254 }
255
256 sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
257 r = sc_hsm_select_file(card, &path, &file);
258 LOG_TEST_RET(card->ctx, r, "Could not select SmartCard-HSM application");
259
260 // Validate that card returns a FCP with a proprietary tag 85 with value longer than 2 byte (Fixes #1377)
261 if (file != NULL) {
262 i = file->prop_attr_len;
263 sc_file_free(file);
264 if (i < 2) {
265 return 0;
266 }
267 }
268
269 if (type == SC_CARD_TYPE_SC_HSM_SOC) {
270 card->type = SC_CARD_TYPE_SC_HSM_SOC;
271 } else {
272 card->type = SC_CARD_TYPE_SC_HSM;
273 }
274
275 return 1;
276 }
277
278
279
280 /*
281 * Encode 16 hexadecimals of SO-PIN into binary form
282 * Caller must check length of sopin and provide an 8 byte buffer
283 */
sc_hsm_encode_sopin(const u8 * sopin,u8 * sopinbin)284 static int sc_hsm_encode_sopin(const u8 *sopin, u8 *sopinbin)
285 {
286 int i;
287 unsigned char digit;
288
289 memset(sopinbin, 0, 8);
290 for (i = 0; i < 16; i++) {
291 *sopinbin <<= 4;
292 digit = *sopin++;
293
294 if (!isxdigit(digit))
295 return SC_ERROR_PIN_CODE_INCORRECT;
296 digit = toupper(digit);
297
298 if (digit >= 'A')
299 digit = digit - 'A' + 10;
300 else
301 digit = digit & 0xF;
302
303 *sopinbin |= digit & 0xf;
304 if (i & 1)
305 sopinbin++;
306 }
307 return SC_SUCCESS;
308 }
309
310
sc_hsm_soc_select_minbioclient(sc_card_t * card)311 static int sc_hsm_soc_select_minbioclient(sc_card_t *card)
312 {
313 sc_apdu_t apdu;
314 struct sc_aid minBioClient_aid = {
315 { 0xFF,'m','i','n','B','i','o','C','l','i','e','n','t',0x01 }, 14
316 };
317
318 /* Select MinBioClient */
319 #ifdef ENABLE_SM
320 sc_sm_stop(card);
321 #endif
322 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x0C);
323 apdu.data = minBioClient_aid.value;
324 apdu.datalen = minBioClient_aid.len;
325 apdu.lc = minBioClient_aid.len;
326 LOG_TEST_RET(card->ctx,
327 sc_transmit_apdu(card, &apdu),
328 "APDU transmit failed");
329
330 return sc_check_sw(card, apdu.sw1, apdu.sw2);
331 }
332
sc_hsm_soc_change(sc_card_t * card,struct sc_pin_cmd_data * data,int * tries_left)333 static int sc_hsm_soc_change(sc_card_t *card, struct sc_pin_cmd_data *data,
334 int *tries_left)
335 {
336 sc_apdu_t apdu;
337 sc_path_t path;
338 int r;
339
340 if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
341 /* Select MinBioClient */
342 r = sc_hsm_soc_select_minbioclient(card);
343 LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application");
344
345 /* verify PIN */
346 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x80);
347 r = sc_transmit_apdu(card, &apdu);
348 LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
349 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
350 LOG_TEST_GOTO_ERR(card->ctx, r, "Could not verify PIN");
351
352 /* change PIN */
353 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x80);
354 r = sc_transmit_apdu(card, &apdu);
355 LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
356 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
357 LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN");
358 } else {
359 #ifdef ENABLE_SM
360 unsigned sm_mode = card->sm_ctx.sm_mode;
361 #endif
362
363 /* verify PIN */
364 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x85);
365 apdu.cla = 0x80;
366 r = sc_transmit_apdu(card, &apdu);
367 LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
368
369 #ifdef ENABLE_SM
370 /* temporary disable SM, change reference data does not reach the applet */
371 card->sm_ctx.sm_mode = SM_MODE_NONE;
372 #endif
373
374 /* change PIN */
375 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x85);
376 apdu.cla = 0x80;
377 r = sc_transmit_apdu(card, &apdu);
378 #ifdef ENABLE_SM
379 /* restore SM if possible */
380 card->sm_ctx.sm_mode = sm_mode;
381 #endif
382 LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
383 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
384 LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN");
385 }
386
387 err:
388 if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
389 /* Select SC-HSM */
390 sc_path_set(&path, SC_PATH_TYPE_DF_NAME,
391 sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
392 LOG_TEST_RET(card->ctx,
393 sc_hsm_select_file_ex(card, &path, 1, NULL),
394 "Could not select SmartCard-HSM application");
395 }
396
397 return r;
398 }
399
sc_hsm_soc_unblock(sc_card_t * card,struct sc_pin_cmd_data * data,int * tries_left)400 static int sc_hsm_soc_unblock(sc_card_t *card, struct sc_pin_cmd_data *data,
401 int *tries_left)
402 {
403 sc_apdu_t apdu;
404 sc_path_t path;
405 int r;
406
407 if (card->type == SC_CARD_TYPE_SC_HSM_GOID) {
408 return SC_ERROR_NOT_SUPPORTED;
409 }
410
411 /* Select MinBioClient */
412 r = sc_hsm_soc_select_minbioclient(card);
413 LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application");
414
415 /* verify PUK */
416 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x81);
417 r = sc_transmit_apdu(card, &apdu);
418 LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
419 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
420 LOG_TEST_GOTO_ERR(card->ctx, r, "Could not verify PUK");
421
422 /* reset retry counter */
423 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2c, 0x03, 0x00);
424 r = sc_transmit_apdu(card, &apdu);
425 LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
426 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
427 LOG_TEST_GOTO_ERR(card->ctx, r, "Could not unblock PIN");
428
429 err:
430 /* Select SC-HSM */
431 sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
432 LOG_TEST_RET(card->ctx,
433 sc_hsm_select_file_ex(card, &path, 1, NULL),
434 "Could not select SmartCard-HSM application");
435
436 return r;
437 }
438
sc_hsm_soc_biomatch(sc_card_t * card,struct sc_pin_cmd_data * data,int * tries_left)439 static int sc_hsm_soc_biomatch(sc_card_t *card, struct sc_pin_cmd_data *data,
440 int *tries_left)
441 {
442 sc_apdu_t apdu;
443 u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
444 int r;
445
446 if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
447 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x85);
448 apdu.cla = 0x80;
449 apdu.data = (unsigned char*)"\x7F\x24\x00";
450 apdu.datalen = 3;
451 apdu.lc = 3;
452 apdu.resplen = 0;
453
454 r = sc_transmit_apdu(card, &apdu);
455 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
456 /* ignore the actual status bytes */
457 }
458
459 /* JCOP's SM accelerator is incapable of using case 1 APDU in SM */
460 sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x20, 0x00, 0x81);
461 if (card->type == SC_CARD_TYPE_SC_HSM_GOID) {
462 apdu.cla = 0x80;
463 }
464 apdu.resp = rbuf;
465 apdu.resplen = sizeof rbuf;
466 r = sc_transmit_apdu(card, &apdu);
467 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
468
469 /* now check the status bytes */
470 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
471 if (r == SC_SUCCESS) {
472 LOG_FUNC_RETURN(card->ctx, r);
473 }
474
475 LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
476 }
477
478
479
480 #ifdef ENABLE_SM
481 #ifdef ENABLE_OPENPACE
482 #include "sm/sm-eac.h"
483 #include <eac/cv_cert.h>
484 #include <eac/eac.h>
485 #include <eac/ta.h>
486 #include <openssl/bio.h>
487 #include <openssl/crypto.h>
488
sc_hsm_perform_chip_authentication(sc_card_t * card)489 static int sc_hsm_perform_chip_authentication(sc_card_t *card)
490 {
491 int r, protocol;
492 sc_path_t path;
493 u8 all_certs[1024];
494 EAC_CTX *ctx = NULL;
495 size_t all_certs_len = sizeof all_certs, left, device_cert_len, issuer_cert_len;
496 const unsigned char *cert = all_certs, *device_cert, *issuer_cert;
497 BUF_MEM *comp_pub_key = NULL;
498 sc_cvc_t cvc_device, cvc_issuer;
499 /* this is only needed to call sc_pkcs15emu_sc_hsm_decode_cvc */
500 sc_pkcs15_card_t p15card;
501 sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
502 /* we know that sc_pkcs15emu_sc_hsm_decode_cvc does not require anything
503 * else to be initialized than p15card->card */
504 p15card.card = card;
505
506 memset(&cvc_device, 0, sizeof(cvc_device));
507 memset(&cvc_issuer, 0, sizeof(cvc_issuer));
508
509
510 if (priv->EF_C_DevAut && priv->EF_C_DevAut_len) {
511 all_certs_len = priv->EF_C_DevAut_len;
512 cert = priv->EF_C_DevAut;
513 } else {
514 /* get issuer and device certificate from the card */
515 r = sc_path_set(&path, SC_PATH_TYPE_FILE_ID, (u8 *) "\x2F\x02", 2, 0, 0);
516 if (r < 0)
517 goto err;
518 r = sc_select_file(card, &path, NULL);
519 if (r < 0)
520 goto err;
521 r = sc_read_binary(card, 0, all_certs, all_certs_len, 0);
522 if (r < 0)
523 goto err;
524 if (r == 0) {
525 r = SC_ERROR_FILE_NOT_FOUND;
526 goto err;
527 }
528
529 all_certs_len = r;
530
531 /* save EF_C_DevAut for further use */
532 cert = realloc(priv->EF_C_DevAut, all_certs_len);
533 if (cert) {
534 memcpy((unsigned char *) cert, all_certs, all_certs_len);
535 priv->EF_C_DevAut = (unsigned char *) cert;
536 priv->EF_C_DevAut_len = all_certs_len;
537 }
538
539 cert = all_certs;
540 }
541 left = all_certs_len;
542
543 device_cert = cert;
544 r = sc_pkcs15emu_sc_hsm_decode_cvc(&p15card, &cert, &left, &cvc_device);
545 if (r < 0)
546 goto err;
547 device_cert_len = all_certs_len - left;
548
549 issuer_cert = cert;
550 r = sc_pkcs15emu_sc_hsm_decode_cvc(&p15card, &cert, &left, &cvc_issuer);
551 if (r < 0)
552 goto err;
553 issuer_cert_len = all_certs_len - device_cert_len - left;
554
555 ctx = EAC_CTX_new();
556 if (!ctx) {
557 r = SC_ERROR_INTERNAL;
558 goto err;
559 }
560
561
562 /* check all CVCs given of the document's pki */
563 if (!TA_STEP2_import_certificate(ctx, issuer_cert, issuer_cert_len)
564 || !TA_STEP2_import_certificate(ctx, device_cert, device_cert_len)) {
565 r = SC_ERROR_INTERNAL;
566 goto err;
567 }
568
569 /* XXX on older JCOPs only NID_id_CA_ECDH_3DES_CBC_CBC may be
570 * supported. The card does not export its capabilities. We hardcode
571 * NID_id_CA_ECDH_AES_CBC_CMAC_128 here, because we don't have the older
572 * cards in production. */
573 protocol = NID_id_CA_ECDH_AES_CBC_CMAC_128;
574
575 /* initialize CA domain parameter with the document's public key */
576 if (!EAC_CTX_init_ca(ctx, protocol, 8)) {
577 r = SC_ERROR_INTERNAL;
578 goto err;
579 }
580 EVP_PKEY_free(ctx->ca_ctx->ka_ctx->key);
581 EVP_PKEY_up_ref(ctx->ta_ctx->pub_key);
582 ctx->ca_ctx->ka_ctx->key = ctx->ta_ctx->pub_key;
583
584 /* generate keys for CA */
585 comp_pub_key = TA_STEP3_generate_ephemeral_key(ctx);
586 r = perform_chip_authentication_ex(card, ctx,
587 cvc_device.publicPoint, cvc_device.publicPointlen);
588
589 err:
590 if (r < 0)
591 EAC_CTX_clear_free(ctx);
592 if (comp_pub_key)
593 BUF_MEM_free(comp_pub_key);
594 sc_pkcs15emu_sc_hsm_free_cvc(&cvc_device);
595 sc_pkcs15emu_sc_hsm_free_cvc(&cvc_issuer);
596
597 return r;
598 }
599
600 #else
601
sc_hsm_perform_chip_authentication(sc_card_t * card)602 static int sc_hsm_perform_chip_authentication(sc_card_t *card)
603 {
604 return SC_ERROR_NOT_SUPPORTED;
605 }
606 #endif
607 #endif
608
609
610
sc_hsm_pin_cmd(sc_card_t * card,struct sc_pin_cmd_data * data,int * tries_left)611 static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
612 int *tries_left)
613 {
614 sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
615 sc_apdu_t apdu;
616 u8 cmdbuff[16];
617 #ifdef ENABLE_SM
618 u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
619 #endif
620 int r;
621 int cmd = data->cmd;
622 size_t pin2_len = data->pin2.len;
623
624 if (cmd == SC_PIN_CMD_GET_SESSION_PIN) {
625 /* First, perform a standard VERIFY */
626 data->cmd = SC_PIN_CMD_VERIFY;
627 /* we assign pin2.len to 0 early on so that in case of an error we are
628 * not exiting with an undefined session PIN */
629 data->pin2.len = 0;
630 }
631
632 if ((card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)
633 && (data->cmd == SC_PIN_CMD_CHANGE)
634 && (data->pin_reference == 0x81)
635 && (!data->pin1.data || data->pin1.len <= 0)) {
636 return sc_hsm_soc_change(card, data, tries_left);
637 } else if ((card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)
638 && (data->cmd == SC_PIN_CMD_UNBLOCK)
639 && (data->pin_reference == 0x81)
640 && (!data->pin1.data || data->pin1.len <= 0)) {
641 return sc_hsm_soc_unblock(card, data, tries_left);
642 }
643
644 #ifdef ENABLE_SM
645 /* For contactless cards always establish a secure channel before PIN
646 * verification. Also, Session PIN generation requires SM. */
647 if ((card->type == SC_CARD_TYPE_SC_HSM_SOC
648 || card->type == SC_CARD_TYPE_SC_HSM_GOID
649 || card->reader->uid.len || cmd == SC_PIN_CMD_GET_SESSION_PIN)
650 && (data->cmd != SC_PIN_CMD_GET_INFO)) {
651 struct sc_pin_cmd_data check_sm_pin_data;
652 memset(&check_sm_pin_data, 0, sizeof(check_sm_pin_data));
653 check_sm_pin_data.cmd = SC_PIN_CMD_GET_INFO;
654 check_sm_pin_data.pin_type = data->pin_type;
655 check_sm_pin_data.pin_reference = data->pin_reference;
656
657 r = SC_ERROR_NOT_ALLOWED;
658 if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT) {
659 /* check if the existing SM channel is still valid */
660 r = sc_pin_cmd(card, &check_sm_pin_data, NULL);
661 }
662 if (r == SC_ERROR_ASN1_OBJECT_NOT_FOUND || r == SC_ERROR_NOT_ALLOWED) {
663 /* need to establish a new SM channel */
664 LOG_TEST_RET(card->ctx,
665 sc_hsm_perform_chip_authentication(card),
666 "Could not perform chip authentication");
667 }
668 }
669 #endif
670
671 if ((card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)
672 && (data->cmd == SC_PIN_CMD_VERIFY)
673 && (data->pin_reference == 0x81)
674 && (!data->pin1.data || data->pin1.len <= 0)) {
675 r = sc_hsm_soc_biomatch(card, data, tries_left);
676 } else {
677 if ((data->cmd == SC_PIN_CMD_VERIFY) && (data->pin_reference == 0x88)) {
678 if (data->pin1.len != 16)
679 return SC_ERROR_INVALID_PIN_LENGTH;
680
681 // Save SO PIN for later use in sc_hsm_init_pin()
682 r = sc_hsm_encode_sopin(data->pin1.data, priv->sopin);
683 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
684
685 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
686 }
687
688 if ((data->cmd == SC_PIN_CMD_CHANGE) && (data->pin_reference == 0x88)) {
689 if ((data->pin1.len != 16) || (data->pin2.len != 16))
690 return SC_ERROR_INVALID_PIN_LENGTH;
691
692 r = sc_hsm_encode_sopin(data->pin1.data, cmdbuff);
693 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
694
695 r = sc_hsm_encode_sopin(data->pin2.data, cmdbuff + 8);
696 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
697
698 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x00, data->pin_reference);
699 apdu.data = cmdbuff;
700 apdu.datalen = sizeof(cmdbuff);
701 apdu.lc = 16;
702 apdu.resplen = 0;
703 data->apdu = &apdu;
704 }
705
706 #ifdef ENABLE_SM
707 if ((data->cmd == SC_PIN_CMD_GET_INFO)
708 && (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT)) {
709 /* JCOP's SM accelerator is incapable of using case 1 APDU in SM */
710 sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x20, 0x00, data->pin_reference);
711 apdu.resp = rbuf;
712 apdu.resplen = sizeof rbuf;
713 data->apdu = &apdu;
714 }
715 #endif
716
717 data->pin1.offset = 5;
718 data->pin2.offset = 5;
719
720 r = (*iso_ops->pin_cmd)(card, data, tries_left);
721 data->apdu = NULL;
722 }
723 LOG_TEST_RET(card->ctx, r, "Verification failed");
724
725 if (cmd == SC_PIN_CMD_GET_SESSION_PIN) {
726 /* reset data->cmd to its original value */
727 data->cmd = SC_PIN_CMD_GET_SESSION_PIN;
728 if (data->pin_reference == 0x81) {
729 u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE];
730 #ifdef ENABLE_SM
731 if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) {
732 sc_log(card->ctx,
733 "Session PIN generation only supported in SM");
734 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
735 }
736 #else
737 sc_log(card->ctx,
738 "Session PIN generation only supported in SM");
739 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
740 #endif
741 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x5A, 0x01, data->pin_reference);
742 apdu.cla = 0x80;
743 apdu.resp = recvbuf;
744 apdu.resplen = sizeof recvbuf;
745 apdu.le = 0;
746 if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS
747 || sc_check_sw(card, apdu.sw1, apdu.sw2) != SC_SUCCESS) {
748 sc_log(card->ctx,
749 "Generating session PIN failed");
750 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
751 }
752 if (data->pin2.data && pin2_len > 0) {
753 if (pin2_len >= apdu.resplen) {
754 memcpy((unsigned char *) data->pin2.data, apdu.resp,
755 apdu.resplen);
756 data->pin2.len = apdu.resplen;
757 } else {
758 sc_log(card->ctx,
759 "Buffer too small for session PIN");
760 }
761 }
762 } else {
763 sc_log(card->ctx,
764 "Session PIN not supported for this PIN (0x%02X)",
765 data->pin_reference);
766 }
767 }
768 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
769 }
770
771
772
sc_hsm_logout(sc_card_t * card)773 static int sc_hsm_logout(sc_card_t * card)
774 {
775 sc_path_t path;
776 sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
777 memset(priv->sopin, 0, sizeof(priv->sopin));
778 #ifdef ENABLE_SM
779 sc_sm_stop(card);
780 #endif
781
782 sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
783
784 return sc_hsm_select_file_ex(card, &path, 1, NULL);
785 }
786
787
788
sc_hsm_read_binary(sc_card_t * card,unsigned int idx,u8 * buf,size_t count,unsigned long flags)789 static int sc_hsm_read_binary(sc_card_t *card,
790 unsigned int idx, u8 *buf, size_t count,
791 unsigned long flags)
792 {
793 sc_context_t *ctx = card->ctx;
794 sc_apdu_t apdu;
795 u8 cmdbuff[4];
796 int r;
797
798 if (idx > 0xffff) {
799 sc_log(ctx, "invalid EF offset: 0x%X > 0xFFFF", idx);
800 return SC_ERROR_OFFSET_TOO_LARGE;
801 }
802
803 cmdbuff[0] = 0x54;
804 cmdbuff[1] = 0x02;
805 cmdbuff[2] = (idx >> 8) & 0xFF;
806 cmdbuff[3] = idx & 0xFF;
807
808 assert(count <= sc_get_max_recv_size(card));
809 sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0xB1, 0x00, 0x00);
810 apdu.data = cmdbuff;
811 apdu.datalen = 4;
812 apdu.lc = 4;
813 apdu.le = count;
814 apdu.resplen = count;
815 apdu.resp = buf;
816
817 r = sc_transmit_apdu(card, &apdu);
818 LOG_TEST_RET(ctx, r, "APDU transmit failed");
819
820 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
821 if (r != SC_ERROR_FILE_END_REACHED) {
822 LOG_TEST_RET(ctx, r, "Check SW error");
823 }
824
825 LOG_FUNC_RETURN(ctx, apdu.resplen);
826 }
827
828
829
sc_hsm_write_ef(sc_card_t * card,int fid,unsigned int idx,const u8 * buf,size_t count)830 static int sc_hsm_write_ef(sc_card_t *card,
831 int fid,
832 unsigned int idx, const u8 *buf, size_t count)
833 {
834 sc_context_t *ctx = card->ctx;
835 sc_apdu_t apdu;
836 u8 *cmdbuff, *p;
837 size_t len;
838 int r;
839
840 if (idx > 0xffff) {
841 sc_log(ctx, "invalid EF offset: 0x%X > 0xFFFF", idx);
842 return SC_ERROR_OFFSET_TOO_LARGE;
843 }
844
845 cmdbuff = malloc(8 + count);
846 if (!cmdbuff) {
847 LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
848 }
849
850 p = cmdbuff;
851 *p++ = 0x54;
852 *p++ = 0x02;
853 *p++ = (idx >> 8) & 0xFF;
854 *p++ = idx & 0xFF;
855 *p++ = 0x53;
856 if (count < 128) {
857 *p++ = (u8) count;
858 len = 6;
859 } else if (count < 256) {
860 *p++ = 0x81;
861 *p++ = (u8) count;
862 len = 7;
863 } else {
864 *p++ = 0x82;
865 *p++ = (count >> 8) & 0xFF;
866 *p++ = count & 0xFF;
867 len = 8;
868 }
869
870 if (buf != NULL)
871 memcpy(p, buf, count);
872 len += count;
873
874 sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xD7, fid >> 8, fid & 0xFF);
875 apdu.data = cmdbuff;
876 apdu.datalen = len;
877 apdu.lc = len;
878
879 r = sc_transmit_apdu(card, &apdu);
880 free(cmdbuff);
881 LOG_TEST_RET(ctx, r, "APDU transmit failed");
882
883 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
884 LOG_TEST_RET(ctx, r, "Check SW error");
885
886 LOG_FUNC_RETURN(ctx, count);
887 }
888
889
890
sc_hsm_update_binary(sc_card_t * card,unsigned int idx,const u8 * buf,size_t count,unsigned long flags)891 static int sc_hsm_update_binary(sc_card_t *card,
892 unsigned int idx, const u8 *buf, size_t count,
893 unsigned long flags)
894 {
895 return sc_hsm_write_ef(card, 0, idx, buf, count);
896 }
897
898
899
sc_hsm_list_files(sc_card_t * card,u8 * buf,size_t buflen)900 static int sc_hsm_list_files(sc_card_t *card, u8 * buf, size_t buflen)
901 {
902 sc_apdu_t apdu;
903 u8 recvbuf[MAX_EXT_APDU_LENGTH];
904 sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
905 int r;
906
907 if (priv->noExtLength) {
908 sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x58, 0, 0);
909 } else {
910 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_EXT, 0x58, 0, 0);
911 }
912 apdu.cla = 0x80;
913 apdu.resp = recvbuf;
914 apdu.resplen = sizeof(recvbuf);
915 apdu.le = 0;
916 r = sc_transmit_apdu(card, &apdu);
917
918 if ((r == SC_ERROR_TRANSMIT_FAILED) && (!priv->noExtLength)) {
919 sc_log(card->ctx, "No extended length support ? Trying fall-back to short APDUs, probably breaking support for RSA 2048 operations");
920 priv->noExtLength = 1;
921 card->max_send_size = 248; // 255 - 7 because of TLV in odd ins UPDATE BINARY
922 return sc_hsm_list_files(card, buf, buflen);
923 }
924 LOG_TEST_RET(card->ctx, r, "ENUMERATE OBJECTS APDU transmit failed");
925
926 memcpy(buf, recvbuf, buflen);
927
928 LOG_FUNC_RETURN(card->ctx, apdu.resplen);
929 }
930
931
932
sc_hsm_create_file(sc_card_t * card,sc_file_t * file)933 static int sc_hsm_create_file(sc_card_t *card, sc_file_t *file)
934 {
935 int r;
936
937 r = sc_hsm_write_ef(card, file->id, 0, NULL, 0);
938 LOG_TEST_RET(card->ctx, r, "Create file failed");
939
940 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
941 }
942
943
944
sc_hsm_delete_file(sc_card_t * card,const sc_path_t * path)945 static int sc_hsm_delete_file(sc_card_t *card, const sc_path_t *path)
946 {
947 sc_context_t *ctx = card->ctx;
948 sc_apdu_t apdu;
949 u8 sbuf[2];
950 int r;
951
952 if ((path->type != SC_PATH_TYPE_FILE_ID) || (path->len != 2)) {
953 sc_log(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID");
954 LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
955 }
956
957 sbuf[0] = path->value[0];
958 sbuf[1] = path->value[1];
959
960 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x02, 0x00);
961 apdu.data = sbuf;
962 apdu.datalen = sizeof(sbuf);
963 apdu.lc = sizeof(sbuf);
964
965 r = sc_transmit_apdu(card, &apdu);
966 LOG_TEST_RET(ctx, r, "APDU transmit failed");
967
968 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
969 LOG_TEST_RET(ctx, r, "Check SW error");
970
971 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
972 }
973
974
sc_hsm_set_security_env(sc_card_t * card,const sc_security_env_t * env,int se_num)975 static int sc_hsm_set_security_env(sc_card_t *card,
976 const sc_security_env_t *env,
977 int se_num)
978 {
979 sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
980
981 priv->env = env;
982
983 switch(env->algorithm) {
984 case SC_ALGORITHM_RSA:
985 if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
986 if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) {
987 priv->algorithm = ALGO_RSA_PKCS1_SHA1;
988 } else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) {
989 priv->algorithm = ALGO_RSA_PKCS1_SHA256;
990 } else {
991 priv->algorithm = ALGO_RSA_PKCS1;
992 }
993 } else if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PSS) {
994 priv->algorithm = ALGO_RSA_PSS;
995 } else {
996 if (env->operation == SC_SEC_OPERATION_DECIPHER) {
997 priv->algorithm = ALGO_RSA_DECRYPT;
998 } else {
999 priv->algorithm = ALGO_RSA_RAW;
1000 }
1001 }
1002 break;
1003 case SC_ALGORITHM_EC:
1004 if (env->operation == SC_SEC_OPERATION_DERIVE) {
1005 priv->algorithm = ALGO_EC_DH;
1006 } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_NONE) {
1007 priv->algorithm = ALGO_EC_RAW;
1008 } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1) {
1009 priv->algorithm = ALGO_EC_SHA1;
1010 } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA224) {
1011 priv->algorithm = ALGO_EC_SHA224;
1012 } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256) {
1013 priv->algorithm = ALGO_EC_SHA256;
1014 } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_RAW) {
1015 priv->algorithm = ALGO_EC_RAW;
1016 } else {
1017 LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1018 }
1019 break;
1020 default:
1021 LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1022 break;
1023 }
1024 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1025 }
1026
1027
1028
sc_hsm_decode_ecdsa_signature(sc_card_t * card,const u8 * data,size_t datalen,u8 * out,size_t outlen)1029 static int sc_hsm_decode_ecdsa_signature(sc_card_t *card,
1030 const u8 * data, size_t datalen,
1031 u8 * out, size_t outlen) {
1032
1033 int i, r;
1034 size_t fieldsizebytes;
1035 const u8 *body, *tag;
1036 size_t bodylen, taglen;
1037
1038 // Determine field size from length of signature
1039 if (datalen <= 58) { // 192 bit curve = 24 * 2 + 10 byte maximum DER signature
1040 fieldsizebytes = 24;
1041 } else if (datalen <= 66) { // 224 bit curve = 28 * 2 + 10 byte maximum DER signature
1042 fieldsizebytes = 28;
1043 } else if (datalen <= 74) { // 256 bit curve = 32 * 2 + 10 byte maximum DER signature
1044 fieldsizebytes = 32;
1045 } else if (datalen <= 90) { // 320 bit curve = 40 * 2 + 10 byte maximum DER signature
1046 fieldsizebytes = 40;
1047 } else if (datalen <= 106) { // 384 bit curve = 48 * 2 + 10 byte maximum DER signature
1048 fieldsizebytes = 48;
1049 } else if (datalen <= 138) { // 512 bit curve = 64 * 2 + 10 byte maximum DER signature
1050 fieldsizebytes = 64;
1051 } else {
1052 fieldsizebytes = 66;
1053 }
1054
1055 sc_log(card->ctx,
1056 "Field size %"SC_FORMAT_LEN_SIZE_T"u, signature buffer size %"SC_FORMAT_LEN_SIZE_T"u",
1057 fieldsizebytes, outlen);
1058
1059 if (outlen < (fieldsizebytes * 2)) {
1060 LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_DATA, "output too small for EC signature");
1061 }
1062 memset(out, 0, outlen);
1063
1064 // Copied from card-piv.c. Thanks
1065 body = sc_asn1_find_tag(card->ctx, data, datalen, 0x30, &bodylen);
1066
1067 for (i = 0; i<2; i++) {
1068 if (body) {
1069 tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x02, &taglen);
1070 if (tag) {
1071 bodylen -= taglen - (tag - body);
1072 body = tag + taglen;
1073
1074 if (taglen > fieldsizebytes) { /* drop leading 00 if present */
1075 if (*tag != 0x00) {
1076 r = SC_ERROR_INVALID_DATA;
1077 goto err;
1078 }
1079 tag++;
1080 taglen--;
1081 }
1082 memcpy(out + fieldsizebytes*i + fieldsizebytes - taglen , tag, taglen);
1083 } else {
1084 r = SC_ERROR_INVALID_DATA;
1085 goto err;
1086 }
1087 } else {
1088 r = SC_ERROR_INVALID_DATA;
1089 goto err;
1090 }
1091 }
1092 r = 2 * fieldsizebytes;
1093 err:
1094 LOG_FUNC_RETURN(card->ctx, r);
1095 }
1096
1097
1098
sc_hsm_compute_signature(sc_card_t * card,const u8 * data,size_t datalen,u8 * out,size_t outlen)1099 static int sc_hsm_compute_signature(sc_card_t *card,
1100 const u8 * data, size_t datalen,
1101 u8 * out, size_t outlen)
1102 {
1103 int r;
1104 sc_apdu_t apdu;
1105 u8 rbuf[514];
1106 sc_hsm_private_data_t *priv;
1107
1108 if (card == NULL || data == NULL || out == NULL) {
1109 return SC_ERROR_INVALID_ARGUMENTS;
1110 }
1111 priv = (sc_hsm_private_data_t *) card->drv_data;
1112
1113 if (priv->env == NULL) {
1114 LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND);
1115 }
1116
1117 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x68, priv->env->key_ref[0], priv->algorithm);
1118 apdu.cla = 0x80;
1119 apdu.resp = rbuf;
1120 apdu.resplen = sizeof(rbuf);
1121 apdu.le = 512;
1122
1123 apdu.data = data;
1124 apdu.lc = datalen;
1125 apdu.datalen = datalen;
1126 r = sc_transmit_apdu(card, &apdu);
1127
1128 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1129 if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
1130 int len;
1131
1132 if ((priv->algorithm & 0xF0) == ALGO_EC_RAW) {
1133 len = sc_hsm_decode_ecdsa_signature(card, apdu.resp, apdu.resplen, out, outlen);
1134 if (len < 0) {
1135 LOG_FUNC_RETURN(card->ctx, len);
1136 }
1137 } else {
1138 len = apdu.resplen > outlen ? outlen : apdu.resplen;
1139 memcpy(out, apdu.resp, len);
1140 }
1141 LOG_FUNC_RETURN(card->ctx, len);
1142 }
1143 LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
1144 }
1145
1146
1147
sc_hsm_decipher(sc_card_t * card,const u8 * crgram,size_t crgram_len,u8 * out,size_t outlen)1148 static int sc_hsm_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len, u8 * out, size_t outlen)
1149 {
1150 int r;
1151 size_t len;
1152 sc_apdu_t apdu;
1153 u8 rbuf[514];
1154 sc_hsm_private_data_t *priv;
1155
1156 if (card == NULL || crgram == NULL || out == NULL) {
1157 return SC_ERROR_INVALID_ARGUMENTS;
1158 }
1159 LOG_FUNC_CALLED(card->ctx);
1160 priv = (sc_hsm_private_data_t *) card->drv_data;
1161
1162 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x62, priv->env->key_ref[0], priv->algorithm);
1163 apdu.cla = 0x80;
1164 apdu.resp = rbuf;
1165 apdu.resplen = sizeof(rbuf);
1166 apdu.le = 512;
1167
1168 apdu.data = (u8 *)crgram;
1169 apdu.lc = crgram_len;
1170 apdu.datalen = crgram_len;
1171
1172 r = sc_transmit_apdu(card, &apdu);
1173
1174 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1175 if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
1176 if (priv->algorithm == ALGO_EC_DH) {
1177 //
1178 // The SmartCard-HSM returns the point result of the DH operation
1179 // with a leading '04'
1180 assert(apdu.resplen > 0);
1181 len = apdu.resplen - 1 > outlen ? outlen : apdu.resplen - 1;
1182 memcpy(out, apdu.resp + 1, len);
1183 LOG_FUNC_RETURN(card->ctx, len);
1184 } else {
1185 len = apdu.resplen > outlen ? outlen : apdu.resplen;
1186 memcpy(out, apdu.resp, len);
1187 LOG_FUNC_RETURN(card->ctx, len);
1188 }
1189 }
1190 else
1191 LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
1192 }
1193
1194
1195
sc_hsm_set_serialnr(sc_card_t * card,char * serial)1196 void sc_hsm_set_serialnr(sc_card_t *card, char *serial)
1197 {
1198 sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
1199
1200 if (priv->serialno) {
1201 free(priv->serialno);
1202 }
1203
1204 priv->serialno = strdup(serial);
1205 }
1206
1207
1208
sc_hsm_get_serialnr(sc_card_t * card,sc_serial_number_t * serial)1209 static int sc_hsm_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
1210 {
1211 sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
1212
1213 LOG_FUNC_CALLED(card->ctx);
1214
1215 if (!priv->serialno) {
1216 return SC_ERROR_OBJECT_NOT_FOUND;
1217 }
1218
1219 serial->len = strlen(priv->serialno);
1220 if (serial->len > sizeof(serial->value))
1221 serial->len = sizeof(serial->value);
1222
1223 memcpy(serial->value, priv->serialno, serial->len);
1224
1225 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1226 }
1227
1228
1229
sc_hsm_initialize(sc_card_t * card,sc_cardctl_sc_hsm_init_param_t * params)1230 static int sc_hsm_initialize(sc_card_t *card, sc_cardctl_sc_hsm_init_param_t *params)
1231 {
1232 sc_context_t *ctx = card->ctx;
1233 sc_pkcs15_tokeninfo_t ti;
1234 struct sc_pin_cmd_data pincmd;
1235 int r;
1236 size_t tilen;
1237 sc_apdu_t apdu;
1238 u8 ibuff[64+0xFF], *p;
1239
1240 LOG_FUNC_CALLED(card->ctx);
1241
1242 p = ibuff;
1243 *p++ = 0x80; // Options
1244 *p++ = 0x02;
1245 memcpy(p, params->options, 2);
1246 p += 2;
1247
1248 if (params->user_pin_len > 0xFF) {
1249 return SC_ERROR_INVALID_ARGUMENTS;
1250 }
1251 *p++ = 0x81; // User PIN
1252 *p++ = (u8) params->user_pin_len;
1253 memcpy(p, params->user_pin, params->user_pin_len);
1254 p += params->user_pin_len;
1255
1256 *p++ = 0x82; // Initialization code
1257 *p++ = 0x08;
1258 memcpy(p, params->init_code, 8);
1259 p += 8;
1260
1261 *p++ = 0x91; // User PIN retry counter
1262 *p++ = 0x01;
1263 *p++ = params->user_pin_retry_counter;
1264
1265 if (params->dkek_shares >= 0) {
1266 *p++ = 0x92; // Number of DKEK shares
1267 *p++ = 0x01;
1268 *p++ = (u8)params->dkek_shares;
1269 }
1270
1271 if (params->bio1.len) {
1272 *p++ = 0x95;
1273 *p++ = params->bio1.len;
1274 memcpy(p, params->bio1.value, params->bio1.len);
1275 p += params->bio1.len;
1276 }
1277 if (params->bio2.len) {
1278 *p++ = 0x96;
1279 *p++ = params->bio2.len;
1280 memcpy(p, params->bio2.value, params->bio2.len);
1281 p += params->bio2.len;
1282 }
1283
1284 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x50, 0x00, 0x00);
1285 apdu.cla = 0x80;
1286 apdu.data = ibuff;
1287 apdu.datalen = p - ibuff;
1288 apdu.lc = apdu.datalen;
1289
1290 r = sc_transmit_apdu(card, &apdu);
1291 LOG_TEST_RET(ctx, r, "APDU transmit failed");
1292
1293 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1294
1295 if (r == SC_ERROR_NOT_ALLOWED) {
1296 r = SC_ERROR_PIN_CODE_INCORRECT;
1297 }
1298
1299 LOG_TEST_RET(ctx, r, "Check SW error");
1300
1301 if (params->label) {
1302 memset(&ti, 0, sizeof(ti));
1303
1304 ti.label = params->label;
1305 ti.flags = SC_PKCS15_TOKEN_PRN_GENERATION;
1306
1307 r = sc_pkcs15_encode_tokeninfo(ctx, &ti, &p, &tilen);
1308 LOG_TEST_RET(ctx, r, "Error encoding tokeninfo");
1309
1310 memset(&pincmd, 0, sizeof(pincmd));
1311 pincmd.cmd = SC_PIN_CMD_VERIFY;
1312 pincmd.pin_type = SC_AC_CHV;
1313 pincmd.pin_reference = 0x81;
1314 pincmd.pin1.data = params->user_pin;
1315 pincmd.pin1.len = params->user_pin_len;
1316
1317 r = (*iso_ops->pin_cmd)(card, &pincmd, NULL);
1318 LOG_TEST_RET(ctx, r, "Could not verify PIN");
1319
1320 r = sc_hsm_write_ef(card, 0x2F03, 0, p, tilen);
1321 LOG_TEST_RET(ctx, r, "Could not write EF.TokenInfo");
1322 }
1323
1324 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1325 }
1326
1327
1328
sc_hsm_import_dkek_share(sc_card_t * card,sc_cardctl_sc_hsm_dkek_t * params)1329 static int sc_hsm_import_dkek_share(sc_card_t *card, sc_cardctl_sc_hsm_dkek_t *params)
1330 {
1331 sc_context_t *ctx = card->ctx;
1332 sc_apdu_t apdu;
1333 u8 status[SC_MAX_APDU_BUFFER_SIZE];
1334 int r;
1335
1336 LOG_FUNC_CALLED(card->ctx);
1337
1338 if (params->importShare) {
1339 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x52, 0x00, 0x00);
1340 apdu.cla = 0x80;
1341 apdu.data = params->dkek_share;
1342 apdu.datalen = sizeof(params->dkek_share);
1343 apdu.lc = apdu.datalen;
1344 } else {
1345 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x52, 0x00, 0x00);
1346 }
1347 apdu.cla = 0x80;
1348 apdu.le = 0;
1349 apdu.resp = status;
1350 apdu.resplen = sizeof(status);
1351
1352 r = sc_transmit_apdu(card, &apdu);
1353 LOG_TEST_RET(ctx, r, "APDU transmit failed");
1354
1355 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1356
1357 LOG_TEST_RET(ctx, r, "Check SW error");
1358
1359 assert(apdu.resplen >= (sizeof(params->key_check_value) + 2));
1360
1361 params->dkek_shares = status[0];
1362 params->outstanding_shares = status[1];
1363 memcpy(params->key_check_value, status + 2, sizeof(params->key_check_value));
1364
1365 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1366 }
1367
1368
1369
sc_hsm_wrap_key(sc_card_t * card,sc_cardctl_sc_hsm_wrapped_key_t * params)1370 static int sc_hsm_wrap_key(sc_card_t *card, sc_cardctl_sc_hsm_wrapped_key_t *params)
1371 {
1372 sc_context_t *ctx = card->ctx;
1373 sc_apdu_t apdu;
1374 u8 data[1500];
1375 int r;
1376
1377 LOG_FUNC_CALLED(card->ctx);
1378
1379 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_EXT, 0x72, params->key_id, 0x92);
1380 apdu.cla = 0x80;
1381 apdu.le = 0;
1382 apdu.resp = data;
1383 apdu.resplen = sizeof(data);
1384
1385 r = sc_transmit_apdu(card, &apdu);
1386 LOG_TEST_RET(ctx, r, "APDU transmit failed");
1387
1388 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1389
1390 LOG_TEST_RET(ctx, r, "Check SW error");
1391
1392 if (params->wrapped_key == NULL) {
1393 params->wrapped_key_length = apdu.resplen;
1394 params->wrapped_key = malloc(apdu.resplen);
1395 if (params->wrapped_key == NULL) {
1396 LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1397 }
1398 } else {
1399 if (apdu.resplen > params->wrapped_key_length) {
1400 LOG_FUNC_RETURN(card->ctx, SC_ERROR_BUFFER_TOO_SMALL);
1401 }
1402 params->wrapped_key_length = apdu.resplen;
1403 }
1404 memcpy(params->wrapped_key, data, apdu.resplen);
1405 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1406 }
1407
1408
1409
sc_hsm_unwrap_key(sc_card_t * card,sc_cardctl_sc_hsm_wrapped_key_t * params)1410 static int sc_hsm_unwrap_key(sc_card_t *card, sc_cardctl_sc_hsm_wrapped_key_t *params)
1411 {
1412 sc_context_t *ctx = card->ctx;
1413 sc_apdu_t apdu;
1414 int r;
1415
1416 LOG_FUNC_CALLED(card->ctx);
1417
1418 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT, 0x74, params->key_id, 0x93);
1419 apdu.cla = 0x80;
1420 apdu.lc = params->wrapped_key_length;
1421 apdu.data = params->wrapped_key;
1422 apdu.datalen = params->wrapped_key_length;
1423
1424 r = sc_transmit_apdu(card, &apdu);
1425 LOG_TEST_RET(ctx, r, "APDU transmit failed");
1426
1427 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1428
1429 LOG_TEST_RET(ctx, r, "Check SW error");
1430
1431 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1432 }
1433
1434
1435
sc_hsm_init_token(sc_card_t * card,sc_cardctl_pkcs11_init_token_t * params)1436 static int sc_hsm_init_token(sc_card_t *card, sc_cardctl_pkcs11_init_token_t *params)
1437 {
1438 sc_context_t *ctx = card->ctx;
1439 sc_cardctl_sc_hsm_init_param_t ip;
1440 int r;
1441 char label[33],*cpo;
1442
1443 LOG_FUNC_CALLED(ctx);
1444
1445 if (params->so_pin_len != 16) {
1446 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "SO PIN wrong length (!=16)");
1447 }
1448
1449 memset(&ip, 0, sizeof(ip));
1450 ip.dkek_shares = -1;
1451 ip.options[0] = 0x00;
1452 ip.options[1] = 0x01;
1453
1454 r = sc_hsm_encode_sopin(params->so_pin, ip.init_code);
1455 LOG_TEST_RET(ctx, r, "SO PIN wrong format");
1456
1457 ip.user_pin = ip.init_code; // Use the first 6 bytes of the SO-PIN as initial User-PIN value
1458 ip.user_pin_len = 6;
1459 ip.user_pin_retry_counter = 3;
1460
1461 if (params->label) {
1462 // Strip trailing spaces
1463 memcpy(label, params->label, 32);
1464 label[32] = 0;
1465 cpo = label + 31;
1466 while ((cpo >= label) && (*cpo == ' ')) {
1467 *cpo = 0;
1468 cpo--;
1469 }
1470 ip.label = label;
1471 }
1472
1473 r = sc_hsm_initialize(card, &ip);
1474 LOG_TEST_RET(ctx, r, "Check SW error");
1475
1476 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1477 }
1478
1479
1480
sc_hsm_init_pin(sc_card_t * card,sc_cardctl_pkcs11_init_pin_t * params)1481 static int sc_hsm_init_pin(sc_card_t *card, sc_cardctl_pkcs11_init_pin_t *params)
1482 {
1483 sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
1484 sc_context_t *ctx = card->ctx;
1485 int r;
1486 sc_apdu_t apdu;
1487 u8 ibuff[50], *p;
1488
1489 LOG_FUNC_CALLED(card->ctx);
1490
1491 if (params->pin_len > 16) {
1492 LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_DATA, "User PIN too long");
1493 }
1494
1495 p = ibuff;
1496
1497 memcpy(p, priv->sopin, sizeof(priv->sopin));
1498 p += sizeof(priv->sopin);
1499
1500 memcpy(p, params->pin, params->pin_len);
1501 p += params->pin_len;
1502
1503 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2C, 0x00, 0x81);
1504 apdu.data = ibuff;
1505 apdu.datalen = p - ibuff;
1506 apdu.lc = apdu.datalen;
1507
1508 r = sc_transmit_apdu(card, &apdu);
1509 LOG_TEST_RET(ctx, r, "APDU transmit failed");
1510
1511 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1512
1513 // Cards before version 1.0 do not implement RESET_RETRY_COUNTER
1514 // For those cards the CHANGE REFERENCE DATA command is used instead
1515 if (r == SC_ERROR_INS_NOT_SUPPORTED) {
1516 p = ibuff;
1517 memcpy(p, priv->sopin, 6);
1518 p += 6;
1519
1520 memcpy(p, params->pin, params->pin_len);
1521 p += params->pin_len;
1522
1523 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x00, 0x81);
1524 apdu.data = ibuff;
1525 apdu.datalen = p - ibuff;
1526 apdu.lc = apdu.datalen;
1527
1528 r = sc_transmit_apdu(card, &apdu);
1529 LOG_TEST_RET(ctx, r, "APDU transmit failed");
1530
1531 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1532 }
1533
1534 LOG_TEST_RET(ctx, r, "Check SW error");
1535
1536 memset(priv->sopin, 0, sizeof(priv->sopin));
1537
1538 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1539 }
1540
1541
1542
sc_hsm_generate_keypair(sc_card_t * card,sc_cardctl_sc_hsm_keygen_info_t * keyinfo)1543 static int sc_hsm_generate_keypair(sc_card_t *card, sc_cardctl_sc_hsm_keygen_info_t *keyinfo)
1544 {
1545 u8 rbuf[1200];
1546 int r;
1547 sc_apdu_t apdu;
1548
1549 LOG_FUNC_CALLED(card->ctx);
1550
1551 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x46, keyinfo->key_id, keyinfo->auth_key_id);
1552 apdu.cla = 0x00;
1553 apdu.resp = rbuf;
1554 apdu.resplen = sizeof(rbuf);
1555 apdu.le = 0;
1556
1557 apdu.data = keyinfo->gakprequest;
1558 apdu.lc = keyinfo->gakprequest_len;
1559 apdu.datalen = keyinfo->gakprequest_len;
1560
1561 r = sc_transmit_apdu(card, &apdu);
1562 LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1563
1564 r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1565 LOG_TEST_RET(card->ctx, r, "Check SW error");
1566
1567 keyinfo->gakpresponse_len = apdu.resplen;
1568 keyinfo->gakpresponse = malloc(apdu.resplen);
1569
1570 if (keyinfo->gakpresponse == NULL) {
1571 LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1572 }
1573
1574 memcpy(keyinfo->gakpresponse, apdu.resp, apdu.resplen);
1575
1576 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1577 }
1578
1579
1580
sc_hsm_card_ctl(sc_card_t * card,unsigned long cmd,void * ptr)1581 static int sc_hsm_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
1582 {
1583 switch (cmd) {
1584 case SC_CARDCTL_GET_SERIALNR:
1585 return sc_hsm_get_serialnr(card, (sc_serial_number_t *)ptr);
1586 case SC_CARDCTL_PKCS11_INIT_TOKEN:
1587 return sc_hsm_init_token(card, (sc_cardctl_pkcs11_init_token_t *)ptr);
1588 case SC_CARDCTL_PKCS11_INIT_PIN:
1589 return sc_hsm_init_pin(card, (sc_cardctl_pkcs11_init_pin_t *)ptr);
1590 case SC_CARDCTL_SC_HSM_GENERATE_KEY:
1591 return sc_hsm_generate_keypair(card, (sc_cardctl_sc_hsm_keygen_info_t *)ptr);
1592 case SC_CARDCTL_SC_HSM_INITIALIZE:
1593 return sc_hsm_initialize(card, (sc_cardctl_sc_hsm_init_param_t *)ptr);
1594 case SC_CARDCTL_SC_HSM_IMPORT_DKEK_SHARE:
1595 return sc_hsm_import_dkek_share(card, (sc_cardctl_sc_hsm_dkek_t *)ptr);
1596 case SC_CARDCTL_SC_HSM_WRAP_KEY:
1597 return sc_hsm_wrap_key(card, (sc_cardctl_sc_hsm_wrapped_key_t *)ptr);
1598 case SC_CARDCTL_SC_HSM_UNWRAP_KEY:
1599 return sc_hsm_unwrap_key(card, (sc_cardctl_sc_hsm_wrapped_key_t *)ptr);
1600 }
1601 return SC_ERROR_NOT_SUPPORTED;
1602 }
1603
1604
1605
sc_hsm_init(struct sc_card * card)1606 static int sc_hsm_init(struct sc_card *card)
1607 {
1608 #if defined(ENABLE_OPENPACE) && defined(_WIN32)
1609 char expanded_val[PATH_MAX];
1610 size_t expanded_len = PATH_MAX;
1611 #endif
1612 int flags,ext_flags;
1613 sc_file_t *file = NULL;
1614 sc_path_t path;
1615 sc_hsm_private_data_t *priv = card->drv_data;
1616
1617 LOG_FUNC_CALLED(card->ctx);
1618
1619 if (!priv) {
1620 priv = calloc(1, sizeof(sc_hsm_private_data_t));
1621 if (!priv)
1622 LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1623 card->drv_data = priv;
1624 }
1625
1626 flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_RSA_PAD_PSS|SC_ALGORITHM_ONBOARD_KEY_GEN;
1627
1628 _sc_card_add_rsa_alg(card, 1024, flags, 0);
1629 _sc_card_add_rsa_alg(card, 1536, flags, 0);
1630 _sc_card_add_rsa_alg(card, 2048, flags, 0);
1631 _sc_card_add_rsa_alg(card, 3072, flags, 0);
1632 _sc_card_add_rsa_alg(card, 4096, flags, 0);
1633
1634 flags = SC_ALGORITHM_ECDSA_RAW|
1635 SC_ALGORITHM_ECDH_CDH_RAW|
1636 SC_ALGORITHM_ECDSA_HASH_NONE|
1637 SC_ALGORITHM_ECDSA_HASH_SHA1|
1638 SC_ALGORITHM_ECDSA_HASH_SHA224|
1639 SC_ALGORITHM_ECDSA_HASH_SHA256|
1640 SC_ALGORITHM_ONBOARD_KEY_GEN;
1641
1642 ext_flags = SC_ALGORITHM_EXT_EC_F_P|
1643 SC_ALGORITHM_EXT_EC_ECPARAMETERS|
1644 SC_ALGORITHM_EXT_EC_NAMEDCURVE|
1645 SC_ALGORITHM_EXT_EC_UNCOMPRESES|
1646 SC_ALGORITHM_ONBOARD_KEY_GEN;
1647 _sc_card_add_ec_alg(card, 192, flags, ext_flags, NULL);
1648 _sc_card_add_ec_alg(card, 224, flags, ext_flags, NULL);
1649 _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
1650 _sc_card_add_ec_alg(card, 320, flags, ext_flags, NULL);
1651 _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL);
1652 _sc_card_add_ec_alg(card, 512, flags, ext_flags, NULL);
1653 _sc_card_add_ec_alg(card, 521, flags, ext_flags, NULL);
1654
1655 card->caps |= SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT|SC_CARD_CAP_ISO7816_PIN_INFO;
1656
1657 sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
1658 if (sc_hsm_select_file_ex(card, &path, 0, &file) == SC_SUCCESS
1659 && file && file->prop_attr && file->prop_attr_len >= 2) {
1660 static char card_name[SC_MAX_APDU_BUFFER_SIZE];
1661 u8 type = 0xFF;
1662 u8 major = file->prop_attr[file->prop_attr_len - 2];
1663 u8 minor = file->prop_attr[file->prop_attr_len - 1];
1664 char p00[] = "SmartCard-HSM Applet for JCOP";
1665 char p01[] = "SmartCard-HSM Demo Applet for JCOP";
1666 char *p = "SmartCard-HSM";
1667 if (file->prop_attr_len >= 3) {
1668 type = file->prop_attr[file->prop_attr_len - 3];
1669 }
1670 switch (type) {
1671 case 0x00:
1672 p = p00;
1673 break;
1674 case 0x01:
1675 p = p01;
1676 break;
1677 default:
1678 break;
1679 }
1680 snprintf(card_name, sizeof card_name, "%s version %u.%u", p, major, minor);
1681 card->name = card_name;
1682
1683 if (file->prop_attr[1] & 0x04) {
1684 card->caps |= SC_CARD_CAP_SESSION_PIN;
1685 }
1686 }
1687 sc_file_free(file);
1688
1689 // APDU Buffer limits
1690 // JCOP 2.4.1r3 1462
1691 // JCOP 2.4.2r3 1454
1692 // JCOP 3 1232
1693 // MicroSD with JCOP 3 478 / 506
1694 // Reiner SCT 1014
1695
1696 card->max_send_size = 1232 - 17; // 1232 buffer size - 17 byte header and TLV because of odd ins in UPDATE BINARY
1697
1698 if (!strncmp("Secure Flash Card", card->reader->name, 17)) {
1699 card->max_send_size = 478 - 17;
1700 card->max_recv_size = 506 - 2;
1701 } else if (card->type == SC_CARD_TYPE_SC_HSM_SOC
1702 || card->type == SC_CARD_TYPE_SC_HSM_GOID) {
1703 card->max_recv_size = 0x0630; // SoC Proxy forces this limit
1704 } else {
1705 card->max_recv_size = 0; // Card supports sending with extended length APDU and without limit
1706 }
1707
1708 priv->EF_C_DevAut = NULL;
1709 priv->EF_C_DevAut_len = 0;
1710
1711 #ifdef ENABLE_OPENPACE
1712 EAC_init();
1713 #ifdef _WIN32
1714 expanded_len = ExpandEnvironmentStringsA(CVCDIR, expanded_val, sizeof expanded_val);
1715 if (0 < expanded_len && expanded_len < sizeof expanded_val)
1716 EAC_set_cvc_default_dir(expanded_val);
1717 #else
1718 EAC_set_cvc_default_dir(CVCDIR);
1719 #endif
1720 #endif
1721
1722 return 0;
1723 }
1724
1725
1726
sc_hsm_finish(sc_card_t * card)1727 static int sc_hsm_finish(sc_card_t * card)
1728 {
1729 sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
1730 #ifdef ENABLE_SM
1731 sc_sm_stop(card);
1732 #endif
1733 if (priv->serialno) {
1734 free(priv->serialno);
1735 }
1736 if (priv->dffcp) {
1737 sc_file_free(priv->dffcp);
1738 }
1739 free(priv->EF_C_DevAut);
1740 free(priv);
1741
1742 return SC_SUCCESS;
1743 }
1744
1745
1746
sc_get_driver(void)1747 static struct sc_card_driver * sc_get_driver(void)
1748 {
1749 struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
1750
1751 if (iso_ops == NULL)
1752 iso_ops = iso_drv->ops;
1753
1754 sc_hsm_ops = *iso_drv->ops;
1755 sc_hsm_ops.match_card = sc_hsm_match_card;
1756 sc_hsm_ops.select_file = sc_hsm_select_file;
1757 sc_hsm_ops.get_challenge = sc_hsm_get_challenge;
1758 sc_hsm_ops.read_binary = sc_hsm_read_binary;
1759 sc_hsm_ops.update_binary = sc_hsm_update_binary;
1760 sc_hsm_ops.list_files = sc_hsm_list_files;
1761 sc_hsm_ops.create_file = sc_hsm_create_file;
1762 sc_hsm_ops.delete_file = sc_hsm_delete_file;
1763 sc_hsm_ops.set_security_env = sc_hsm_set_security_env;
1764 sc_hsm_ops.compute_signature = sc_hsm_compute_signature;
1765 sc_hsm_ops.decipher = sc_hsm_decipher;
1766 sc_hsm_ops.init = sc_hsm_init;
1767 sc_hsm_ops.finish = sc_hsm_finish;
1768 sc_hsm_ops.card_ctl = sc_hsm_card_ctl;
1769 sc_hsm_ops.pin_cmd = sc_hsm_pin_cmd;
1770 sc_hsm_ops.logout = sc_hsm_logout;
1771
1772 /* no record oriented file services */
1773 sc_hsm_ops.read_record = NULL;
1774 sc_hsm_ops.write_record = NULL;
1775 sc_hsm_ops.append_record = NULL;
1776 sc_hsm_ops.update_record = NULL;
1777
1778 return &sc_hsm_drv;
1779 }
1780
1781
1782
sc_get_sc_hsm_driver(void)1783 struct sc_card_driver * sc_get_sc_hsm_driver(void)
1784 {
1785 return sc_get_driver();
1786 }
1787
1788