Coverage Report

Created: 2025-10-13 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/card-entersafe.c
Line
Count
Source
1
/*
2
 * This library is free software; you can redistribute it and/or
3
 * modify it under the terms of the GNU Lesser General Public
4
 * License as published by the Free Software Foundation; either
5
 * version 2.1 of the License, or (at your option) any later version.
6
 *
7
 * This library is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10
 * Lesser General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU Lesser General Public
13
 * License along with this library; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
 */
16
17
/* Initially written by Weitao Sun (weitao@ftsafe.com) 2008 */
18
19
#ifdef HAVE_CONFIG_H
20
#include "config.h"
21
#endif
22
#ifdef ENABLE_OPENSSL /* empty file without openssl */
23
24
#include <stdlib.h>
25
#include <string.h>
26
27
#include <openssl/evp.h>
28
29
#include "internal.h"
30
#include "asn1.h"
31
#include "cardctl.h"
32
33
static const struct sc_atr_table entersafe_atrs[] = {
34
  {
35
    "3b:0f:00:65:46:53:05:19:05:71:df:00:00:00:00:00:00",
36
    "ff:ff:ff:ff:ff:ff:ff:00:ff:ff:ff:00:00:00:00:00:00",
37
    "ePass3000", SC_CARD_TYPE_ENTERSAFE_3K, 0, NULL },
38
  {
39
    "3b:9f:95:81:31:fe:9f:00:65:46:53:05:30:06:71:df:00:00:00:80:6a:82:5e",
40
    "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00:FF:FF:FF:FF:FF:FF:00:00:00:00",
41
    "FTCOS/PK-01C", SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C, 0, NULL },
42
  {
43
    "3b:fc:18:00:00:81:31:80:45:90:67:46:4a:00:64:18:14:00:00:00:00:02",
44
    "ff:00:00:00:00:00:00:00:00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:00",
45
    "EJAVA/PK-01C", SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C, 0, NULL },
46
  {
47
    "3b:7c:18:00:00:90:67:46:4a:20:28:8c:58:00:00:00:00",
48
    "ff:00:00:00:00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff",
49
    "EJAVA/PK-01C-T0",SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C_T0,0,NULL},
50
  {
51
    "3B:FC:18:00:00:81:31:80:45:90:67:46:4A:21:28:8C:58:00:00:00:00:B7",
52
    "ff:00:00:00:00:00:00:00:00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:00",
53
    "EJAVA/H10CR/PK-01C-T1",SC_CARD_TYPE_ENTERSAFE_EJAVA_H10CR_PK_01C_T1,0,NULL},
54
  {
55
    "3B:FC:18:00:00:81:31:80:45:90:67:46:4A:20:25:c3:30:00:00:00:00",
56
    "ff:00:00:00:00:00:00:00:00:ff:ff:ff:ff:00:00:00:00:00:00:00:00",
57
    "EJAVA/D11CR/PK-01C-T1",SC_CARD_TYPE_ENTERSAFE_EJAVA_D11CR_PK_01C_T1,0,NULL},
58
  {
59
    "3B:FC:18:00:00:81:31:80:45:90:67:46:4A:00:6A:04:24:00:00:00:00:20",
60
    "ff:00:00:00:00:00:00:00:00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:00",
61
    "EJAVA/C21C/PK-01C-T1",SC_CARD_TYPE_ENTERSAFE_EJAVA_C21C_PK_01C_T1,0,NULL},
62
  {
63
    "3B:FC:18:00:00:81:31:80:45:90:67:46:4A:00:68:08:04:00:00:00:00:0E",
64
    "ff:00:00:00:00:00:00:00:00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:00",
65
    "EJAVA/A22CR/PK-01C-T1",SC_CARD_TYPE_ENTERSAFE_EJAVA_A22CR_PK_01C_T1,0,NULL},
66
  {
67
    "3B:FC:18:00:00:81:31:80:45:90:67:46:4A:10:27:61:30:00:00:00:00:0C",
68
    "ff:00:00:00:00:00:00:00:00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:00",
69
    "EJAVA/A40CR/PK-01C-T1",SC_CARD_TYPE_ENTERSAFE_EJAVA_A40CR_PK_01C_T1,0,NULL},
70
  {
71
    "3b:fc:18:00:00:81:31:80:45:90:67:46:4a:00:68:08:06:00:00:00:00:0c",
72
    "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00:FF:FF:FF:FF:FF:FF:00:00:00",
73
    "FTCOS/PK-01C", SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C, 0, NULL },
74
  { NULL, NULL, NULL, 0, 0, NULL }
75
};
76
77
static struct sc_card_operations entersafe_ops;
78
static struct sc_card_operations *iso_ops = NULL;
79
80
static struct sc_card_driver entersafe_drv = {
81
  "entersafe",
82
  "entersafe",
83
  &entersafe_ops,
84
  NULL, 0, NULL
85
};
86
87
static u8 trans_code_3k[] =
88
{
89
  0x01, 0x02, 0x03, 0x04,
90
  0x05, 0x06, 0x07, 0x08,
91
};
92
93
static u8 trans_code_ftcos_pk_01c[] =
94
{
95
  0x92, 0x34, 0x2E, 0xEF,
96
  0x23, 0x40, 0x4F, 0xD1,
97
};
98
99
static u8 init_key[] =
100
{
101
  1,  2,  3,  4,
102
  5,  6,  7,  8,
103
  9,  10, 11, 12,
104
  13, 14, 15, 16,
105
};
106
107
static u8 key_maintain[] =
108
{
109
  0x12, 0x34, 0x56, 0x78,
110
  0x21, 0x43, 0x65, 0x87,
111
  0x11, 0x22, 0xaa, 0xbb,
112
  0x33, 0x44, 0xcd, 0xef
113
};
114
115
static void entersafe_reverse_buffer(u8* buff, size_t size)
116
0
{
117
0
  u8 t;
118
0
  u8 *end = buff + size - 1;
119
120
0
  while (buff < end) {
121
0
    t = *buff;
122
0
    *buff = *end;
123
0
    *end = t;
124
0
    ++buff;
125
0
    --end;
126
0
  }
127
0
}
128
129
static int entersafe_select_file(sc_card_t *card,
130
                 const sc_path_t *in_path,
131
                 sc_file_t **file_out);
132
133
/* the entersafe part */
134
static int entersafe_match_card(sc_card_t *card)
135
9.77k
{
136
9.77k
  int i;
137
9.77k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
138
139
9.77k
  i = _sc_match_atr(card, entersafe_atrs, &card->type);
140
9.77k
  if (i < 0)
141
9.61k
    return 0;
142
143
159
  return 1;
144
9.77k
}
145
146
static int entersafe_init(sc_card_t *card)
147
159
{
148
159
  unsigned int flags;
149
150
159
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
151
152
159
  card->name = "entersafe";
153
159
  card->cla  = 0x00;
154
159
  card->drv_data = NULL;
155
156
159
  flags = SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE;
157
158
159
  _sc_card_add_rsa_alg(card, 512, flags, 0);
159
159
  _sc_card_add_rsa_alg(card, 768, flags, 0);
160
159
  _sc_card_add_rsa_alg(card, 1024, flags, 0);
161
159
  _sc_card_add_rsa_alg(card, 2048, flags, 0);
162
163
159
  card->caps = SC_CARD_CAP_RNG;
164
165
  /* we need read_binary&friends with max 224 bytes per read */
166
159
  card->max_send_size = 224;
167
159
  card->max_recv_size = 224;
168
159
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
169
159
}
170
171
static int entersafe_gen_random(sc_card_t *card, u8 *buff, size_t size)
172
0
{
173
0
  int r = SC_SUCCESS;
174
0
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
175
0
  sc_apdu_t apdu;
176
177
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
178
179
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x84, 0x00, 0x00);
180
0
  apdu.resp = rbuf;
181
0
  apdu.le = size;
182
0
  apdu.resplen = sizeof(rbuf);
183
184
0
  r = sc_transmit_apdu(card, &apdu);
185
0
  LOG_TEST_RET(card->ctx, r, "entersafe gen random failed");
186
187
0
  if (apdu.resplen != size)
188
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
189
0
  memcpy(buff, rbuf, size);
190
191
0
  LOG_FUNC_RETURN(card->ctx, r);
192
0
}
193
194
static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu,
195
                 u8 *key, size_t keylen,
196
                 u8 *buff, size_t buffsize)
197
0
{
198
0
  EVP_CIPHER_CTX *ctx = NULL;
199
0
  EVP_CIPHER *alg = NULL;
200
201
0
  u8 iv[8] = {0};
202
0
  int len;
203
204
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
205
206
0
  assert(card);
207
0
  assert(apdu);
208
0
  assert(key);
209
0
  assert(buff);
210
211
  /* padding as 0x80 0x00 0x00...... */
212
0
  memset(buff, 0, buffsize);
213
0
  buff[0] = apdu->lc;
214
0
  memcpy(buff + 1, apdu->data, apdu->lc);
215
0
  buff[apdu->lc + 1] = 0x80;
216
217
0
  ctx = EVP_CIPHER_CTX_new();
218
0
  if (ctx == NULL) {
219
0
    sc_log_openssl(card->ctx);
220
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
221
0
  }
222
0
  EVP_CIPHER_CTX_set_padding(ctx, 0);
223
224
0
  if (keylen == 8) {
225
0
    alg = sc_evp_cipher(card->ctx, "DES-ECB");
226
0
  } else if (keylen == 16) {
227
0
    alg = sc_evp_cipher(card->ctx, "DES-EDE");
228
0
  } else {
229
0
    EVP_CIPHER_CTX_free(ctx);
230
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
231
0
  }
232
233
0
  if (EVP_EncryptInit_ex(ctx, alg, NULL, key, iv) != 1) {
234
0
    sc_log_openssl(card->ctx);
235
0
    sc_evp_cipher_free(alg);
236
0
    EVP_CIPHER_CTX_free(ctx);
237
0
    sc_log(card->ctx, "entersafe encryption error.");
238
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
239
0
  }
240
241
0
  len = (int)apdu->lc;
242
0
  if (!EVP_EncryptUpdate(ctx, buff, &len, buff, (int)buffsize)) {
243
0
    sc_log_openssl(card->ctx);
244
0
    sc_evp_cipher_free(alg);
245
0
    EVP_CIPHER_CTX_free(ctx);
246
0
    sc_log(card->ctx, "entersafe encryption error.");
247
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
248
0
  }
249
0
  apdu->lc = len;
250
251
0
  sc_evp_cipher_free(alg);
252
0
  EVP_CIPHER_CTX_free(ctx);
253
254
0
  if (apdu->lc != buffsize) {
255
0
    sc_log(card->ctx, "entersafe build cipher apdu failed.");
256
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INTERNAL);
257
0
  }
258
259
0
  apdu->data = buff;
260
0
  apdu->datalen = apdu->lc;
261
262
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
263
0
}
264
265
static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu,
266
                u8 * key,size_t keylen,
267
                u8 * buff,size_t buffsize)
268
0
{
269
0
  int r;
270
0
  u8 iv[8];
271
0
  u8 *tmp = NULL, *tmp_rounded = NULL;
272
0
  size_t tmpsize = 0, tmpsize_rounded = 0;
273
0
  int outl = 0;
274
0
  EVP_CIPHER_CTX *ctx = NULL;
275
0
  EVP_CIPHER *alg = NULL;
276
277
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
278
279
0
  assert(card);
280
0
  assert(apdu);
281
0
  assert(key);
282
0
  assert(buff);
283
284
0
  if (apdu->cse != SC_APDU_CASE_3_SHORT)
285
0
    return SC_ERROR_INTERNAL;
286
0
  if (keylen != 8 && keylen != 16)
287
0
    return SC_ERROR_INTERNAL;
288
289
0
  r = entersafe_gen_random(card, iv, sizeof(iv));
290
0
  LOG_TEST_RET(card->ctx, r, "entersafe gen random failed");
291
292
  /* encode the APDU in the buffer */
293
0
  if ((r = sc_apdu_get_octets(card->ctx, apdu, &tmp, &tmpsize, SC_PROTO_RAW)) != SC_SUCCESS)
294
0
    goto out;
295
296
  /* round to 8 */
297
0
  tmpsize_rounded = (tmpsize / 8 + 1) * 8;
298
299
0
  tmp_rounded = malloc(tmpsize_rounded);
300
0
  if (tmp_rounded == NULL) {
301
0
    r = SC_ERROR_OUT_OF_MEMORY;
302
0
    goto out;
303
0
  }
304
305
  /* build content and padded buffer by 0x80 0x00 0x00..... */
306
0
  memset(tmp_rounded, 0, tmpsize_rounded);
307
0
  memcpy(tmp_rounded, tmp, tmpsize);
308
0
  tmp_rounded[4] += 4;
309
0
  tmp_rounded[tmpsize] = 0x80;
310
311
  /* block_size-1 blocks*/
312
0
  ctx = EVP_CIPHER_CTX_new();
313
0
  if (ctx == NULL) {
314
0
    r = SC_ERROR_OUT_OF_MEMORY;
315
0
    sc_log_openssl(card->ctx);
316
0
    goto out;
317
0
  }
318
0
  EVP_CIPHER_CTX_set_padding(ctx, 0);
319
0
  alg = sc_evp_cipher(card->ctx, "DES-CBC");
320
0
  if (!alg ||
321
0
      EVP_EncryptInit_ex(ctx, alg, NULL, key, iv) != 1) {
322
0
    r = SC_ERROR_INTERNAL;
323
0
    sc_log_openssl(card->ctx);
324
0
    goto out;
325
0
  }
326
327
0
  if (tmpsize_rounded > 8) {
328
0
    if (!EVP_EncryptUpdate(ctx, tmp_rounded, &outl, tmp_rounded, (int)tmpsize_rounded - 8)) {
329
0
      r = SC_ERROR_INTERNAL;
330
0
      sc_log_openssl(card->ctx);
331
0
      goto out;
332
0
    }
333
0
  }
334
  /* last block */
335
0
  if (keylen == 8) {
336
0
    if (!EVP_EncryptUpdate(ctx, tmp_rounded + outl, &outl, tmp_rounded + outl, 8)) {
337
0
      r = SC_ERROR_INTERNAL;
338
0
      sc_log_openssl(card->ctx);
339
0
      goto out;
340
0
    }
341
0
  } else {
342
0
    if (EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, key, tmp_rounded + outl - 8) != 1 ||
343
0
        !EVP_EncryptUpdate(ctx, tmp_rounded + outl, &outl, tmp_rounded + outl, 8)) {
344
0
      r = SC_ERROR_INTERNAL;
345
0
      sc_log_openssl(card->ctx);
346
0
      goto out;
347
0
    }
348
0
  }
349
350
0
  memcpy(buff, apdu->data, apdu->lc);
351
  /* use first 4 bytes of last block as mac value*/
352
0
  memcpy(buff + apdu->lc, tmp_rounded + tmpsize_rounded - 8, 4);
353
0
  apdu->data = buff;
354
0
  apdu->lc += 4;
355
0
  apdu->datalen = apdu->lc;
356
357
0
out:
358
0
  free(tmp);
359
0
  free(tmp_rounded);
360
0
  sc_evp_cipher_free(alg);
361
0
  EVP_CIPHER_CTX_free(ctx);
362
363
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
364
0
}
365
366
static int entersafe_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu,
367
                   u8 * key, size_t keylen,
368
                   int cipher, int mac)
369
2.76k
{
370
2.76k
  u8 *cipher_data = NULL, *mac_data = NULL;
371
2.76k
  size_t cipher_data_size, mac_data_size, blocks;
372
2.76k
  int r = SC_SUCCESS;
373
2.76k
  u8 *sbuf = NULL;
374
2.76k
  size_t ssize = 0;
375
376
2.76k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
377
378
2.76k
  assert(card);
379
2.76k
  assert(apdu);
380
381
2.76k
  if ((cipher || mac) && (!key || (keylen != 8 && keylen != 16)))
382
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
383
384
2.76k
  r = sc_apdu_get_octets(card->ctx, apdu, &sbuf, &ssize, SC_PROTO_RAW);
385
2.76k
  if (r == SC_SUCCESS)
386
2.76k
    sc_apdu_log(card->ctx, sbuf, ssize, 1);
387
2.76k
  if (sbuf)
388
2.76k
    free(sbuf);
389
390
2.76k
  if (cipher) {
391
0
    blocks = (apdu->lc + 2) / 8 + 1;
392
0
    cipher_data_size = blocks * 8;
393
0
    cipher_data = malloc(cipher_data_size);
394
0
    if (!cipher_data) {
395
0
      r = SC_ERROR_OUT_OF_MEMORY;
396
0
      goto out;
397
0
    }
398
399
0
    if ((r = entersafe_cipher_apdu(card, apdu, key, keylen, cipher_data, cipher_data_size)) < 0)
400
0
      goto out;
401
0
  }
402
2.76k
  if (mac) {
403
0
    mac_data_size = apdu->lc + 4;
404
0
    mac_data = malloc(mac_data_size);
405
0
    if (!mac_data) {
406
0
      r = SC_ERROR_OUT_OF_MEMORY;
407
0
      goto out;
408
0
    }
409
0
    r = entersafe_mac_apdu(card, apdu, key, keylen, mac_data, mac_data_size);
410
0
    if (r < 0)
411
0
      goto out;
412
0
  }
413
414
2.76k
  r = sc_transmit_apdu(card, apdu);
415
416
2.76k
out:
417
2.76k
  free(cipher_data);
418
2.76k
  free(mac_data);
419
420
2.76k
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
421
2.76k
}
422
423
static int entersafe_read_binary(sc_card_t *card,
424
                 unsigned int idx, u8 *buf, size_t count,
425
                 unsigned long *flags)
426
2.62k
{
427
2.62k
  sc_apdu_t apdu;
428
2.62k
  u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE];
429
2.62k
  int r;
430
431
2.62k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
432
433
2.62k
  assert(count <= card->max_recv_size);
434
2.62k
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, (idx >> 8) & 0xFF, idx & 0xFF);
435
436
2.62k
  apdu.cla = idx > 0x7fff ? 0x80 : 0x00;
437
2.62k
  apdu.le = count;
438
2.62k
  apdu.resplen = count;
439
2.62k
  apdu.resp = recvbuf;
440
441
2.62k
  r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
442
2.62k
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
443
2.56k
  if (apdu.resplen == 0)
444
122
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
445
2.44k
  memcpy(buf, recvbuf, apdu.resplen);
446
447
2.44k
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, (int)apdu.resplen);
448
2.44k
}
449
450
static int entersafe_update_binary(sc_card_t *card,
451
                   unsigned int idx, const u8 *buf,
452
                   size_t count, unsigned long flags)
453
0
{
454
0
  sc_apdu_t apdu;
455
0
  int r;
456
457
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
458
459
0
  assert(count <= card->max_send_size);
460
461
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD6, (idx >> 8) & 0xFF, idx & 0xFF);
462
0
  apdu.cla = idx > 0x7fff ? 0x80 : 0x00;
463
0
  apdu.lc = count;
464
0
  apdu.datalen = count;
465
0
  apdu.data = buf;
466
467
0
  r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
468
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
469
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2),
470
0
        "Card returned error");
471
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, (int)count);
472
0
}
473
474
static int entersafe_process_fci(struct sc_card *card, struct sc_file *file,
475
                 const u8 *buf, size_t buflen)
476
395
{
477
395
  int r;
478
479
395
  assert(file);
480
395
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
481
482
395
  r = iso_ops->process_fci(card, file, buf, buflen);
483
395
  LOG_TEST_RET(card->ctx, r, "Process fci failed");
484
485
395
  if (file->namelen) {
486
72
    file->type = SC_FILE_TYPE_DF;
487
72
    file->ef_structure = SC_FILE_EF_UNKNOWN;
488
323
  } else {
489
323
    file->type = SC_FILE_TYPE_WORKING_EF;
490
323
    file->ef_structure = SC_FILE_EF_TRANSPARENT;
491
323
  }
492
493
395
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
494
395
}
495
496
static int entersafe_select_fid(sc_card_t *card,
497
                unsigned int id_hi, unsigned int id_lo,
498
                sc_file_t **file_out)
499
894
{
500
894
  int r;
501
894
  sc_file_t *file = NULL;
502
894
  sc_path_t path;
503
504
894
  memset(&path, 0, sizeof(sc_path_t));
505
506
894
  path.type = SC_PATH_TYPE_FILE_ID;
507
894
  path.value[0] = id_hi;
508
894
  path.value[1] = id_lo;
509
894
  path.len = 2;
510
511
894
  r = iso_ops->select_file(card, &path, &file);
512
894
  if (r < 0)
513
438
    sc_file_free(file);
514
894
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
515
516
456
  if (file_out)
517
204
    *file_out = file;
518
252
  else
519
252
    sc_file_free(file);
520
521
456
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
522
456
}
523
524
static int entersafe_select_aid(sc_card_t *card,
525
                const sc_path_t *in_path,
526
                sc_file_t **file_out)
527
258
{
528
258
  int r;
529
530
258
  r = iso_ops->select_file(card, in_path, file_out);
531
258
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
532
533
21
  if (file_out) {
534
0
    sc_file_t *file = *file_out;
535
0
    assert(file);
536
537
0
    file->type = SC_FILE_TYPE_DF;
538
0
    file->ef_structure = SC_FILE_EF_UNKNOWN;
539
0
    file->path.len = 0;
540
0
    file->size = 0;
541
    /* AID */
542
0
    memcpy(file->name, in_path->value, in_path->len);
543
0
    file->namelen = in_path->len;
544
0
    file->id = 0x0000;
545
0
  }
546
21
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
547
21
}
548
549
static int entersafe_select_path(sc_card_t *card,
550
                const u8 pathbuf[16], const size_t len,
551
                sc_file_t **file_out)
552
682
{
553
682
  u8 n_pathbuf[SC_MAX_PATH_SIZE];
554
682
  const u8 *path = pathbuf;
555
682
  size_t pathlen = len;
556
682
  unsigned int i;
557
682
  int r;
558
559
682
  if (pathlen % 2 != 0 || pathlen > 6 || pathlen <= 0)
560
29
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
561
562
  /* if pathlen == 6 then the first FID must be MF (== 3F00) */
563
653
  if (pathlen == 6 && (path[0] != 0x3f || path[1] != 0x00))
564
2
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
565
566
  /* unify path (the first FID should be MF) */
567
651
  if (path[0] != 0x3f || path[1] != 0x00) {
568
15
    n_pathbuf[0] = 0x3f;
569
15
    n_pathbuf[1] = 0x00;
570
15
    memcpy(n_pathbuf + 2, path, pathlen);
571
15
    path = n_pathbuf;
572
15
    pathlen += 2;
573
15
  }
574
575
893
  for (i = 0; i < pathlen - 2; i += 2) {
576
655
    r = entersafe_select_fid(card, path[i], path[i + 1], NULL);
577
655
    LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed");
578
655
  }
579
238
  return entersafe_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out);
580
651
}
581
582
static int entersafe_select_file(sc_card_t *card,
583
                const sc_path_t *in_path,
584
                sc_file_t **file_out)
585
941
{
586
941
  assert(card);
587
941
  assert(in_path);
588
941
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
589
590
941
  switch (in_path->type) {
591
1
    case SC_PATH_TYPE_FILE_ID:
592
1
      if (in_path->len != 2)
593
0
        SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
594
1
      return entersafe_select_fid(card,in_path->value[0], in_path->value[1], file_out);
595
258
    case SC_PATH_TYPE_DF_NAME:
596
258
      return entersafe_select_aid(card, in_path, file_out);
597
682
    case SC_PATH_TYPE_PATH:
598
682
      return entersafe_select_path(card, in_path->value, in_path->len, file_out);
599
0
    default:
600
0
      SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
601
941
  }
602
941
}
603
604
static int entersafe_create_mf(sc_card_t *card, sc_entersafe_create_data *data)
605
0
{
606
0
  int r;
607
0
  sc_apdu_t apdu;
608
609
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
610
611
0
  memcpy(data->data.df.init_key, init_key, sizeof(init_key));
612
613
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00);
614
0
  apdu.cla = 0x84;
615
0
  apdu.data = (u8 *)&data->data.df;
616
0
  apdu.datalen = apdu.lc = sizeof(data->data.df);
617
618
0
  switch(card->type) {
619
0
    case SC_CARD_TYPE_ENTERSAFE_3K:
620
0
      r = entersafe_transmit_apdu(card, &apdu, trans_code_3k, sizeof(trans_code_3k), 0, 1);
621
0
      break;
622
0
    case SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C:
623
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C:
624
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C_T0:
625
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_H10CR_PK_01C_T1:
626
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_D11CR_PK_01C_T1:
627
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_C21C_PK_01C_T1:
628
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_A22CR_PK_01C_T1:
629
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_A40CR_PK_01C_T1:
630
0
      r = entersafe_transmit_apdu(card, &apdu, trans_code_ftcos_pk_01c, sizeof(trans_code_ftcos_pk_01c), 0, 1);
631
0
      break;
632
0
    default:
633
0
      r = SC_ERROR_INTERNAL;
634
0
      break;
635
0
  }
636
637
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
638
0
  return sc_check_sw(card, apdu.sw1, apdu.sw2);
639
0
}
640
641
static int entersafe_create_df(sc_card_t *card, sc_entersafe_create_data *data)
642
0
{
643
0
  int r;
644
0
  sc_apdu_t apdu;
645
646
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
647
648
0
  memcpy(data->data.df.init_key, init_key, sizeof(init_key));
649
650
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x01, 0x00);
651
0
  apdu.cla = 0x84;
652
0
  apdu.data = (u8 *)&data->data.df;
653
0
  apdu.lc = apdu.datalen = sizeof(data->data.df);
654
655
0
  r = entersafe_transmit_apdu(card, &apdu,init_key,sizeof(init_key),0,1);
656
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
657
0
  return sc_check_sw(card, apdu.sw1, apdu.sw2);
658
0
}
659
660
static int entersafe_create_ef(sc_card_t *card, sc_entersafe_create_data *data)
661
0
{
662
0
  int r;
663
0
  sc_apdu_t apdu;
664
665
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
666
667
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x02, 0x00);
668
0
  apdu.cla = 0x84;
669
0
  apdu.data = (u8*)&data->data.ef;
670
0
  apdu.lc = apdu.datalen = sizeof(data->data.ef);
671
672
0
  r = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1);
673
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
674
0
  return sc_check_sw(card, apdu.sw1, apdu.sw2);
675
0
}
676
677
static u8 process_acl_entry(sc_file_t *in, unsigned int method, unsigned int in_def)
678
0
{
679
0
  u8 def = (u8)in_def;
680
0
  const sc_acl_entry_t *entry = sc_file_get_acl_entry(in, method);
681
0
  if (!entry) {
682
0
    return def;
683
0
  } else if (entry->method & SC_AC_CHV) {
684
0
    unsigned int key_ref = entry->key_ref;
685
0
    if (key_ref == SC_AC_KEY_REF_NONE)
686
0
      return def;
687
0
    else
688
0
      return ENTERSAFE_AC_ALWAYS&0x04;
689
0
  } else if (entry->method & SC_AC_NEVER) {
690
0
    return ENTERSAFE_AC_NEVER;
691
0
  }
692
0
  return def;
693
0
}
694
695
static int entersafe_create_file(sc_card_t *card, sc_file_t *file)
696
0
{
697
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
698
699
0
  if (file->type == SC_FILE_TYPE_WORKING_EF) {
700
0
    sc_entersafe_create_data data;
701
0
    memset(&data, 0, sizeof(data));
702
703
0
    data.data.ef.file_id[0] = (file->id >> 8) & 0xFF;
704
0
    data.data.ef.file_id[1] = file->id & 0xFF;
705
0
    data.data.ef.size[0] = (file->size >> 8) & 0xFF;
706
0
    data.data.ef.size[1] = file->size & 0xFF;
707
0
    memset(data.data.ef.ac, ENTERSAFE_AC_ALWAYS, sizeof(data.data.ef.ac));
708
0
    data.data.ef.ac[0] = process_acl_entry(file, SC_AC_OP_READ, ENTERSAFE_AC_ALWAYS);
709
0
    data.data.ef.ac[1] = process_acl_entry(file, SC_AC_OP_UPDATE, ENTERSAFE_AC_ALWAYS);
710
711
0
    return entersafe_create_ef(card, &data);
712
0
  } else {
713
0
    return SC_ERROR_INVALID_ARGUMENTS;
714
0
  }
715
0
}
716
717
static int entersafe_internal_set_security_env(sc_card_t *card,
718
                         const sc_security_env_t *env,
719
                         u8 ** data,size_t* size)
720
0
{
721
0
  sc_apdu_t apdu;
722
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
723
0
  u8 *p = sbuf;
724
0
  int r;
725
726
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
727
728
0
  assert(card != NULL && env != NULL);
729
730
0
  switch (env->operation) {
731
0
    case SC_SEC_OPERATION_DECIPHER:
732
0
    case SC_SEC_OPERATION_SIGN:
733
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0);
734
0
      apdu.p1 = 0x41;
735
0
      apdu.p2 = 0xB8;
736
0
      *p++ = 0x80;
737
0
      *p++ = 0x01;
738
0
      *p++ = 0x80;
739
0
      *p++ = 0x83;
740
0
      *p++ = 0x02;
741
0
      *p++ = env->key_ref[0];
742
0
      *p++ = 0x22;
743
0
      if (*size > 1024 / 8) {
744
0
        if (*size == 2048 / 8) {
745
0
          *p++ = 0x89;
746
0
          *p++ = 0x40;
747
0
          memcpy(p, *data, 0x40);
748
0
          p += 0x40;
749
0
          *data += 0x40;
750
0
          *size -= 0x40;
751
0
        } else {
752
0
          SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
753
0
        }
754
0
      }
755
0
      break;
756
0
    default:
757
0
      SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
758
0
  }
759
760
0
  apdu.le = 0;
761
0
  apdu.lc = apdu.datalen = p - sbuf;
762
0
  apdu.data = sbuf;
763
0
  apdu.resplen = 0;
764
765
0
  r = sc_transmit_apdu(card, &apdu);
766
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
767
0
  return sc_check_sw(card, apdu.sw1, apdu.sw2);
768
0
}
769
770
/**
771
 * We don't really set the security environment,but cache it.It will be set when
772
 * security operation is performed later.Because we may transport partial of
773
 * the sign/decipher data within the security environment apdu.
774
 */
775
static int entersafe_set_security_env(sc_card_t *card,
776
                    const sc_security_env_t *env,
777
                    int se_num)
778
0
{
779
0
  assert(card);
780
0
  assert(env);
781
782
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
783
784
0
  if (card->drv_data) {
785
0
    free(card->drv_data);
786
0
    card->drv_data = 0;
787
0
  }
788
789
0
  card->drv_data = calloc(1, sizeof(*env));
790
0
  if (!card->drv_data)
791
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY);
792
793
0
  memcpy(card->drv_data, env, sizeof(*env));
794
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
795
0
}
796
797
static int entersafe_restore_security_env(sc_card_t *card, int se_num)
798
0
{
799
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
800
0
  return SC_SUCCESS;
801
0
}
802
803
804
static int entersafe_compute_with_prkey(sc_card_t *card,
805
                    const u8 *data, size_t datalen,
806
                    u8 *out, size_t outlen)
807
0
{
808
0
  int r;
809
0
  sc_apdu_t apdu;
810
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
811
0
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
812
0
  u8 *p = sbuf;
813
0
  size_t size = datalen;
814
815
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
816
817
0
  if (!data)
818
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
819
820
0
  memcpy(p,data,size);
821
822
0
  if (!card->drv_data)
823
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INTERNAL);
824
825
0
  r = entersafe_internal_set_security_env(card, card->drv_data, &p, &size);
826
0
  LOG_TEST_RET(card->ctx, r, "internal set security env failed");
827
828
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x86, 0x80);
829
0
  apdu.data = p;
830
0
  apdu.lc = size;
831
0
  apdu.datalen = size;
832
0
  apdu.resp = rbuf;
833
0
  apdu.resplen = sizeof(rbuf);
834
0
  apdu.le = 256;
835
836
0
  r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
837
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
838
839
0
  if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
840
0
    size_t len = apdu.resplen > outlen ? outlen : apdu.resplen;
841
0
    memcpy(out, apdu.resp, len);
842
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, (int)len);
843
0
  }
844
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
845
0
}
846
847
static int entersafe_compute_signature(sc_card_t *card,
848
                     const u8 * data, size_t datalen,
849
                     u8 * out, size_t outlen)
850
0
{
851
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
852
0
  return entersafe_compute_with_prkey(card, data, datalen, out, outlen);
853
0
}
854
855
static int entersafe_decipher(sc_card_t *card,
856
                const u8 *crgram, size_t crgram_len,
857
                u8 *out, size_t outlen)
858
0
{
859
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
860
0
  return entersafe_compute_with_prkey(card, crgram, crgram_len, out, outlen);
861
0
}
862
863
static void entersafe_init_pin_info(struct sc_pin_cmd_pin *pin, unsigned int num)
864
8
{
865
8
  pin->encoding   = SC_PIN_ENCODING_ASCII;
866
8
  pin->min_length = 4;
867
8
  pin->max_length = 16;
868
8
  pin->pad_length = 16;
869
8
  pin->offset     = 5 + num * 16;
870
8
  pin->pad_char   = 0x00;
871
8
}
872
873
static int entersafe_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
874
               int *tries_left)
875
4
{
876
4
  int r;
877
4
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
878
4
  entersafe_init_pin_info(&data->pin1, 0);
879
4
  entersafe_init_pin_info(&data->pin2, 1);
880
4
  data->flags |= SC_PIN_CMD_NEED_PADDING;
881
882
4
  if (data->cmd != SC_PIN_CMD_UNBLOCK) {
883
4
    r = iso_ops->pin_cmd(card, data, tries_left);
884
4
    sc_log(card->ctx, "Verify rv:%i", r);
885
4
  } else {
886
0
    { /*verify*/
887
0
      sc_apdu_t apdu;
888
0
      u8 sbuf[0x10] = {0};
889
890
0
      memcpy(sbuf, data->pin1.data, data->pin1.len);
891
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, data->pin_reference + 1);
892
0
      apdu.lc = apdu.datalen = sizeof(sbuf);
893
0
      apdu.data = sbuf;
894
895
0
      r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
896
0
      LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
897
0
    }
898
899
0
    { /*change*/
900
0
      sc_apdu_t apdu;
901
0
      u8 sbuf[0x12] = {0};
902
903
0
      sbuf[0] = 0x33;
904
0
      sbuf[1] = 0x00;
905
0
      memcpy(sbuf + 2, data->pin2.data, data->pin2.len);
906
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF4, 0x0B, data->pin_reference);
907
0
      apdu.cla = 0x84;
908
0
      apdu.lc = apdu.datalen = sizeof(sbuf);
909
0
      apdu.data = sbuf;
910
911
0
      r = entersafe_transmit_apdu(card, &apdu, key_maintain, sizeof(key_maintain), 1, 1);
912
0
      LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
913
0
    }
914
0
  }
915
4
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
916
4
}
917
918
static int entersafe_erase_card(sc_card_t *card)
919
0
{
920
0
  int r;
921
0
  u8  sbuf[2];
922
0
  sc_apdu_t apdu;
923
924
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
925
926
0
  sbuf[0] = 0x3f;
927
0
  sbuf[1] = 0x00;
928
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x00, 0x00);
929
0
  apdu.lc = 2;
930
0
  apdu.datalen = 2;
931
0
  apdu.data = sbuf;
932
933
0
  r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
934
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
935
936
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xEE, 0x00, 0x00);
937
0
  apdu.cla = 0x84;
938
0
  apdu.lc = 2;
939
0
  apdu.datalen = 2;
940
0
  apdu.data = sbuf;
941
942
0
  switch(card->type) {
943
0
    case SC_CARD_TYPE_ENTERSAFE_3K:
944
0
      r = entersafe_transmit_apdu(card, &apdu, trans_code_3k, sizeof(trans_code_3k), 0, 1);
945
0
      break;
946
0
    case SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C:
947
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C:
948
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_PK_01C_T0:
949
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_H10CR_PK_01C_T1:
950
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_D11CR_PK_01C_T1:
951
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_C21C_PK_01C_T1:
952
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_A22CR_PK_01C_T1:
953
0
    case SC_CARD_TYPE_ENTERSAFE_EJAVA_A40CR_PK_01C_T1:
954
0
      r = entersafe_transmit_apdu(card, &apdu, trans_code_ftcos_pk_01c, sizeof(trans_code_ftcos_pk_01c), 0, 1);
955
0
      break;
956
0
    default:
957
0
      r = SC_ERROR_INTERNAL;
958
0
      break;
959
0
  }
960
961
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
962
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
963
0
}
964
965
static void entersafe_encode_bignum(u8 tag, sc_pkcs15_bignum_t bignum, u8 **ptr)
966
0
{
967
0
  u8 *p = *ptr;
968
969
0
  *p++ = tag;
970
0
  if (bignum.len < 128) {
971
0
    *p++ = (u8)bignum.len;
972
0
  } else {
973
0
    u8 bytes = 1;
974
0
    size_t len = bignum.len;
975
0
    while (len) {
976
0
      len = len >> 8;
977
0
      ++bytes;
978
0
    }
979
0
    bytes &= 0x0F;
980
0
    *p++ = 0x80 | bytes;
981
0
    while (bytes) {
982
0
      *p++ = bignum.len >> ((bytes - 1) * 8);
983
0
      --bytes;
984
0
    }
985
0
  }
986
0
  memcpy(p, bignum.data, bignum.len);
987
0
  entersafe_reverse_buffer(p, bignum.len);
988
0
  p += bignum.len;
989
0
  *ptr = p;
990
0
}
991
992
static int entersafe_write_small_rsa_key(sc_card_t *card, u8 key_id, struct sc_pkcs15_prkey_rsa *rsa)
993
0
{
994
0
  sc_apdu_t apdu;
995
0
  u8 sbuff[SC_MAX_APDU_BUFFER_SIZE];
996
0
  int r;
997
0
  u8 *p = sbuff;
998
999
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1000
1001
0
  { /* write prkey */
1002
0
    *p++ = 0x00;      /* EC */
1003
0
    *p++ = 0x00;      /* ver */
1004
0
    entersafe_encode_bignum('E', rsa->exponent, &p);
1005
0
    entersafe_encode_bignum('D', rsa->d, &p);
1006
1007
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF4, 0x22, key_id);
1008
0
    apdu.cla = 0x84;
1009
0
    apdu.data = sbuff;
1010
0
    apdu.lc = apdu.datalen = p - sbuff;
1011
1012
0
    r = entersafe_transmit_apdu(card, &apdu, key_maintain, sizeof(key_maintain), 1, 1);
1013
0
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1014
0
    LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write prkey failed");
1015
0
  }
1016
1017
0
  p = sbuff;
1018
0
  { /* write pukey */
1019
0
    *p++ = 0x00;      /* EC */
1020
0
    *p++ = 0x00;      /* ver */
1021
0
    entersafe_encode_bignum('E', rsa->exponent, &p);
1022
0
    entersafe_encode_bignum('N', rsa->modulus, &p);
1023
1024
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF4, 0x2A, key_id);
1025
0
    apdu.cla = 0x84;
1026
0
    apdu.data = sbuff;
1027
0
    apdu.lc = apdu.datalen = p - sbuff;
1028
1029
0
    r = entersafe_transmit_apdu(card, &apdu, key_maintain, sizeof(key_maintain), 1, 1);
1030
0
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1031
0
    LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write pukey failed");
1032
0
  }
1033
1034
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
1035
0
}
1036
1037
static int entersafe_write_rsa_key_factor(sc_card_t *card,
1038
                      u8 key_id,u8 usage,
1039
                      u8 factor,
1040
                      sc_pkcs15_bignum_t data)
1041
0
{
1042
0
  int r;
1043
0
  sc_apdu_t apdu;
1044
1045
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1046
1047
0
  { /* MSE */
1048
0
    u8 sbuff[4];
1049
0
    sbuff[0] = 0x84;
1050
0
    sbuff[1] = 0x02;
1051
0
    sbuff[2] = key_id;
1052
0
    sbuff[3] = usage;
1053
1054
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x01, 0xB8);
1055
0
    apdu.data = sbuff;
1056
0
    apdu.lc = apdu.datalen = 4;
1057
1058
0
    r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
1059
0
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1060
0
    LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write prkey factor failed(MSE)");
1061
0
  }
1062
1063
0
  { /* Write 'x'; */
1064
0
    u8 sbuff[SC_MAX_APDU_BUFFER_SIZE];
1065
1066
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, factor, 0x00);
1067
1068
0
    memcpy(sbuff, data.data, data.len);
1069
0
    entersafe_reverse_buffer(sbuff, data.len);
1070
/*
1071
 *  PK01C and PK13C smart card only support 1024 or 2048bit key .
1072
 *  Size of exponent1 exponent2 coefficient of RSA private key keep the same as size of prime1
1073
 *  So check factor is padded with zero or not
1074
 */
1075
0
    switch(factor) {
1076
0
      case 0x3:
1077
0
      case 0x4:
1078
0
      case 0x5: {
1079
0
          size_t i;
1080
0
          if (data.len > 32 && data.len < 64) {
1081
0
            for (i = data.len; i < 64; i++)
1082
0
              sbuff[i] = 0;
1083
0
            data.len = 64;
1084
0
          } else if( data.len > 64 && data.len < 128 ) {
1085
0
            for (i = data.len; i < 128; i++)
1086
0
              sbuff[i] = 0;
1087
0
            data.len = 128;
1088
0
          }
1089
0
        }
1090
0
        break;
1091
0
      default:
1092
0
        break;
1093
0
    }
1094
1095
0
    apdu.data = sbuff;
1096
0
    apdu.lc = apdu.datalen = data.len;
1097
1098
0
    r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
1099
0
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1100
0
    LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write prkey factor failed");
1101
0
  }
1102
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
1103
0
}
1104
1105
static int entersafe_write_large_rsa_key(sc_card_t *card,u8 key_id,struct sc_pkcs15_prkey_rsa *rsa)
1106
0
{
1107
0
  int r;
1108
1109
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1110
1111
0
  { /* write prkey */
1112
0
    r = entersafe_write_rsa_key_factor(card, key_id, 0x22, 0x01, rsa->p);
1113
0
    LOG_TEST_RET(card->ctx, r, "write p failed");
1114
0
    r = entersafe_write_rsa_key_factor(card, key_id, 0x22, 0x02, rsa->q);
1115
0
    LOG_TEST_RET(card->ctx, r, "write q failed");
1116
0
    r = entersafe_write_rsa_key_factor(card, key_id, 0x22, 0x03, rsa->dmp1);
1117
0
    LOG_TEST_RET(card->ctx, r, "write dmp1 failed");
1118
0
    r = entersafe_write_rsa_key_factor(card, key_id, 0x22, 0x04, rsa->dmq1);
1119
0
    LOG_TEST_RET(card->ctx, r, "write dmq1 failed");
1120
0
    r = entersafe_write_rsa_key_factor(card, key_id, 0x22, 0x05, rsa->iqmp);
1121
0
    LOG_TEST_RET(card->ctx, r, "write iqmp failed");
1122
0
  }
1123
1124
0
  { /* write pukey */
1125
0
    u8 sbuff[SC_MAX_APDU_BUFFER_SIZE];
1126
0
    sc_apdu_t apdu;
1127
1128
    /* first 64(0x40) bytes of N */
1129
0
    sbuff[0] = 0x83;
1130
0
    sbuff[1] = 0x02;
1131
0
    sbuff[2] = key_id;
1132
0
    sbuff[3] = 0x2A;
1133
0
    sbuff[4] = 0x89;
1134
0
    sbuff[5] = 0x40;
1135
0
    memcpy(sbuff + 6, rsa->modulus.data, 0x40);
1136
1137
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x01, 0xB8);
1138
0
    apdu.data = sbuff;
1139
0
    apdu.lc = apdu.datalen = 0x46;
1140
1141
0
    r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
1142
0
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1143
0
    LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write pukey N(1) failed");
1144
1145
    /* left 192(0xC0) bytes of N */
1146
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x0B, 0x00);
1147
0
    apdu.data = rsa->modulus.data + 0x40;
1148
0
    apdu.lc = apdu.datalen = 0xC0;
1149
1150
0
    r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
1151
0
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1152
0
    LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write pukey N(2) failed");
1153
1154
    /* E */
1155
0
    r = entersafe_write_rsa_key_factor(card, key_id, 0x2A, 0x0D, rsa->exponent);
1156
0
    LOG_TEST_RET(card->ctx, r, "write exponent failed");
1157
0
  }
1158
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
1159
0
}
1160
1161
static int entersafe_write_symmetric_key(sc_card_t *card,
1162
                     u8 key_id, u8 usage,
1163
                     u8 EC, u8 ver,
1164
                     u8 *data, size_t len)
1165
0
{
1166
0
  sc_apdu_t apdu;
1167
0
  u8 sbuff[SC_MAX_APDU_BUFFER_SIZE] = {0};
1168
0
  int r;
1169
1170
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1171
1172
0
  if (len > 240)
1173
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INCORRECT_PARAMETERS);
1174
1175
0
  sbuff[0] = EC;
1176
0
  sbuff[1] = ver;
1177
0
  memcpy(&sbuff[2], data, len);
1178
1179
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF4, usage, key_id);
1180
0
  apdu.cla = 0x84;
1181
0
  apdu.data = sbuff;
1182
0
  apdu.lc = apdu.datalen = len + 2;
1183
1184
0
  r = entersafe_transmit_apdu(card, &apdu, key_maintain, sizeof(key_maintain), 1, 1);
1185
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1186
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "Write prkey failed");
1187
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
1188
0
}
1189
1190
static int entersafe_write_key(sc_card_t *card, sc_entersafe_wkey_data *data)
1191
0
{
1192
0
  struct sc_pkcs15_prkey_rsa *rsa = data->key_data.rsa;
1193
1194
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1195
1196
0
  switch(data->usage) {
1197
0
    case 0x22:
1198
0
      if(rsa->modulus.len < 256)
1199
0
        return entersafe_write_small_rsa_key(card,data->key_id, rsa);
1200
0
      else
1201
0
        return entersafe_write_large_rsa_key(card,data->key_id, rsa);
1202
0
      break;
1203
0
    case 0x2A:
1204
0
      SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NOT_SUPPORTED);
1205
0
      break;
1206
0
    default:
1207
0
      return entersafe_write_symmetric_key(card,data->key_id,data->usage,
1208
0
                        data->key_data.symmetric.EC,
1209
0
                        data->key_data.symmetric.ver,
1210
0
                        data->key_data.symmetric.key_val,
1211
0
                        data->key_data.symmetric.key_len);
1212
0
      break;
1213
0
  }
1214
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
1215
0
}
1216
1217
static int entersafe_gen_key(sc_card_t *card, sc_entersafe_gen_key_data *data)
1218
0
{
1219
0
  int r;
1220
0
  size_t len = data->key_length >> 3;
1221
0
  sc_apdu_t apdu;
1222
0
  u8 rbuf[300] = {0};
1223
0
  u8 sbuf[4], *p;
1224
0
  size_t plen = 0;
1225
1226
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1227
1228
  /* MSE */
1229
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x01, 0xB8);
1230
0
  apdu.lc = 0x04;
1231
0
  sbuf[0] = 0x83;
1232
0
  sbuf[1] = 0x02;
1233
0
  sbuf[2] = data->key_id;
1234
0
  sbuf[3] = 0x2A;
1235
0
  apdu.data = sbuf;
1236
0
  apdu.datalen = 4;
1237
0
  apdu.lc = 4;
1238
0
  apdu.le = 0;
1239
1240
0
  r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
1241
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1242
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "EnterSafe set MSE failed");
1243
1244
  /* generate key */
1245
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, 0x00);
1246
0
  apdu.le = 0;
1247
0
  sbuf[0] = (u8)(data->key_length >> 8);
1248
0
  sbuf[1] = (u8)(data->key_length);
1249
0
  apdu.data = sbuf;
1250
0
  apdu.lc = 2;
1251
0
  apdu.datalen = 2;
1252
1253
0
  r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
1254
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1255
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "EnterSafe generate key pair failed");
1256
1257
  /* read public key via READ PUBLIC KEY */
1258
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xE6, 0x2A, data->key_id);
1259
0
  apdu.cla     = 0x80;
1260
0
  apdu.resp    = rbuf;
1261
0
  apdu.resplen = sizeof(rbuf);
1262
0
  apdu.le      = 256;
1263
0
  r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
1264
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1265
0
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "EnterSafe get pukey failed");
1266
1267
0
  p = rbuf;
1268
0
  plen = apdu.resplen;
1269
0
  if (*p != 'E') {
1270
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
1271
0
  }
1272
0
  if ((size_t)(p - rbuf) + 2 + p[1] >= plen) {
1273
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
1274
0
  }
1275
0
  p += 2 + p[1];
1276
  /* N */
1277
0
  if (*p != 'N') {
1278
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
1279
0
  }
1280
0
  if ((size_t)(p - rbuf) + 2 >= plen) {
1281
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
1282
0
  }
1283
0
  ++p;
1284
0
  if (*p++ > 0x80) {
1285
0
    u8 len_bytes = (*(p - 1)) & 0x0f;
1286
0
    size_t module_len = 0;
1287
0
    if ((size_t)(p - rbuf) + len_bytes >= plen) {
1288
0
      SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
1289
0
    }
1290
0
    while (len_bytes != 0) {
1291
0
      module_len = module_len << 8;
1292
0
      module_len += *p++;
1293
0
      --len_bytes;
1294
0
    }
1295
0
  }
1296
1297
0
  if ((p - rbuf) + len >= plen) {
1298
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_DATA);
1299
0
  }
1300
1301
0
  data->modulus = malloc(len);
1302
0
  if (!data->modulus)
1303
0
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_OUT_OF_MEMORY);
1304
0
  entersafe_reverse_buffer(p, len);
1305
0
  memcpy(data->modulus, p, len);
1306
1307
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
1308
0
}
1309
1310
static int entersafe_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
1311
136
{
1312
136
  int r;
1313
136
  sc_apdu_t apdu;
1314
136
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
1315
1316
136
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1317
136
  assert(serial);
1318
1319
136
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xEA, 0x00, 0x00);
1320
136
  apdu.cla = 0x80;
1321
136
  apdu.resp = rbuf;
1322
136
  apdu.resplen = sizeof(rbuf);
1323
136
  apdu.le = 0x08;
1324
1325
136
  r = entersafe_transmit_apdu(card, &apdu, 0, 0, 0, 0);
1326
136
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1327
128
  LOG_TEST_RET(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2), "EnterSafe get SN failed");
1328
9
  if (apdu.resplen != 8)
1329
9
    LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Invalid length of SN");
1330
1331
2
  card->serialnr.len = serial->len = 8;
1332
2
  memcpy(card->serialnr.value, rbuf, 8);
1333
2
  memcpy(serial->value, rbuf, 8);
1334
1335
2
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
1336
2
}
1337
1338
static int entersafe_preinstall_rsa_2048(sc_card_t *card, u8 key_id)
1339
0
{
1340
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
1341
0
  sc_apdu_t apdu;
1342
0
  int ret = 0;
1343
0
  static u8 const rsa_key_e[] =
1344
0
  {
1345
0
    'E', 0x04, 0x01, 0x00, 0x01, 0x00
1346
0
  };
1347
1348
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1349
1350
  /* create rsa item in IKF */
1351
0
  sbuf[0] = 0x04; /* key len extern */
1352
0
  sbuf[1] = 0x0a; /* key len */
1353
0
  sbuf[2] = 0x22; /* USAGE */
1354
0
  sbuf[3] = 0x34; /* user ac */
1355
0
  sbuf[4] = 0x04; /* change ac */
1356
0
  sbuf[5] = 0x34; /* UPDATE AC */
1357
0
  sbuf[6] = 0x40; /* ALGO */
1358
0
  sbuf[7] = 0x00; /* EC */
1359
0
  sbuf[8] = 0x00; /* VER */
1360
0
  memcpy(&sbuf[9], rsa_key_e, sizeof(rsa_key_e));
1361
0
  sbuf[9 + sizeof(rsa_key_e) + 0] = 'C'+'R'+'T';
1362
0
  sbuf[9 + sizeof(rsa_key_e) + 1] = 0x82;
1363
0
  sbuf[9 + sizeof(rsa_key_e) + 2] = 0x04;
1364
0
  sbuf[9 + sizeof(rsa_key_e) + 3] = 0x00;
1365
1366
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF0, 0x00, key_id);
1367
0
  apdu.cla = 0x84;
1368
0
  apdu.data = sbuf;
1369
0
  apdu.lc = apdu.datalen = 9 + sizeof(rsa_key_e) + 4;
1370
1371
0
  ret = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1);
1372
0
  LOG_TEST_RET(card->ctx, ret, "Preinstall rsa failed");
1373
1374
  /* create rsa item in PKF */
1375
0
  sbuf[0] = 0x01; /* key len extern */
1376
0
  sbuf[1] = 0x0A; /* key len */
1377
0
  sbuf[2] = 0x2A; /* USAGE */
1378
0
  sbuf[3] = ENTERSAFE_AC_ALWAYS; /* user ac */
1379
0
  sbuf[4] = 0x04; /* change ac */
1380
0
  sbuf[5] = ENTERSAFE_AC_ALWAYS; /* UPDATE AC */
1381
0
  sbuf[6] = 0x40; /* ALGO */
1382
0
  sbuf[7] = 0x00; /* EC */
1383
0
  sbuf[8] = 0x00; /* VER */
1384
0
  memcpy(&sbuf[9], rsa_key_e, sizeof(rsa_key_e));
1385
0
  sbuf[9 + sizeof(rsa_key_e) + 0] = 'N';
1386
0
  sbuf[9 + sizeof(rsa_key_e) + 1] = 0x82;
1387
0
  sbuf[9 + sizeof(rsa_key_e) + 2] = 0x01;
1388
0
  sbuf[9 + sizeof(rsa_key_e) + 3] = 0x00;
1389
1390
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF0, 0x00, key_id);
1391
0
  apdu.cla = 0x84;
1392
0
  apdu.data = sbuf;
1393
0
  apdu.lc = apdu.datalen = 9 + sizeof(rsa_key_e) + 4;
1394
1395
0
  ret = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1);
1396
0
  LOG_TEST_RET(card->ctx, ret, "Preinstall rsa failed");
1397
1398
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
1399
0
}
1400
1401
static int entersafe_preinstall_keys(sc_card_t *card, int (*install_rsa)(sc_card_t *, u8))
1402
0
{
1403
0
  int r;
1404
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
1405
0
  sc_apdu_t apdu;
1406
1407
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1408
1409
0
  { /* RSA */
1410
0
    u8 rsa_index;
1411
0
    for (rsa_index = ENTERSAFE_MIN_KEY_ID; rsa_index <= ENTERSAFE_MAX_KEY_ID; ++rsa_index) {
1412
0
      r = install_rsa(card, rsa_index);
1413
0
      LOG_TEST_RET(card->ctx, r, "Preinstall rsa key failed");
1414
0
    }
1415
0
  }
1416
1417
0
  { /* key maintain */
1418
    /* create key maintain*/
1419
0
    sbuf[0] = 0;  /* key len extern */
1420
0
    sbuf[1] = sizeof(key_maintain); /* key len */
1421
0
    sbuf[2] = 0x03; /* USAGE */
1422
0
    sbuf[3] = ENTERSAFE_AC_ALWAYS; /* use AC */
1423
0
    sbuf[4] = ENTERSAFE_AC_ALWAYS; /* CHANGE AC */
1424
0
    sbuf[5] = ENTERSAFE_AC_NEVER; /* UPDATE AC */
1425
0
    sbuf[6] = 0x01; /* ALGO */
1426
0
    sbuf[7] = 0x00; /* EC */
1427
0
    sbuf[8] = 0x00; /* VER */
1428
0
    memcpy(&sbuf[9], key_maintain, sizeof(key_maintain));
1429
1430
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF0, 0x00, 0x00);
1431
0
    apdu.cla = 0x84;
1432
0
    apdu.data = sbuf;
1433
0
    apdu.lc = apdu.datalen = 0x19;
1434
1435
0
    r = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1);
1436
0
    LOG_TEST_RET(card->ctx, r, "Preinstall key maintain failed");
1437
0
  }
1438
1439
0
  { /* user PIN */
1440
0
    memset(sbuf, 0, sizeof(sbuf));
1441
0
    sbuf[0] = 0;  /* key len extern */
1442
0
    sbuf[1] = 16; /* key len */
1443
0
    sbuf[2] = 0x0B; /* USAGE */
1444
0
    sbuf[3] = ENTERSAFE_AC_ALWAYS; /* use AC */
1445
0
    sbuf[4] = 0X04; /* CHANGE AC */
1446
0
    sbuf[5] = 0x38; /* UPDATE AC */
1447
0
    sbuf[6] = 0x01; /* ALGO */
1448
0
    sbuf[7] = 0xFF; /* EC */
1449
0
    sbuf[8] = 0x00; /* VER */
1450
1451
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF0, 0x00, ENTERSAFE_USER_PIN_ID);
1452
0
    apdu.cla = 0x84;
1453
0
    apdu.data = sbuf;
1454
0
    apdu.lc = apdu.datalen = 0x19;
1455
1456
0
    r = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1);
1457
0
    LOG_TEST_RET(card->ctx, r, "Preinstall user PIN failed");
1458
0
  }
1459
1460
0
  { /* user PUK */
1461
0
    memset(sbuf, 0, sizeof(sbuf));
1462
0
    sbuf[0] = 0;  /* key len extern */
1463
0
    sbuf[1] = 16; /* key len */
1464
0
    sbuf[2] = 0x0B; /* USAGE */
1465
0
    sbuf[3] = ENTERSAFE_AC_ALWAYS; /* use AC */
1466
0
    sbuf[4] = 0X08; /* CHANGE AC */
1467
0
    sbuf[5] = 0xC0; /* UPDATE AC */
1468
0
    sbuf[6] = 0x01; /* ALGO */
1469
0
    sbuf[7] = 0xFF; /* EC */
1470
0
    sbuf[8] = 0x00; /* VER */
1471
1472
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xF0, 0x00, ENTERSAFE_USER_PIN_ID + 1);
1473
0
    apdu.cla = 0x84;
1474
0
    apdu.data = sbuf;
1475
0
    apdu.lc = apdu.datalen = 0x19;
1476
1477
0
    r = entersafe_transmit_apdu(card, &apdu, init_key, sizeof(init_key), 0, 1);
1478
0
    LOG_TEST_RET(card->ctx, r, "Preinstall user PUK failed");
1479
0
  }
1480
1481
0
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS);
1482
0
}
1483
1484
static int entersafe_card_ctl_2048(sc_card_t *card, unsigned long cmd, void *ptr)
1485
136
{
1486
136
  sc_entersafe_create_data *tmp = (sc_entersafe_create_data *)ptr;
1487
1488
136
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1489
1490
136
  switch (cmd) {
1491
0
    case SC_CARDCTL_ENTERSAFE_CREATE_FILE:
1492
0
      if (tmp->type == SC_ENTERSAFE_MF_DATA)
1493
0
        return entersafe_create_mf(card, tmp);
1494
0
      else if (tmp->type == SC_ENTERSAFE_DF_DATA)
1495
0
        return entersafe_create_df(card, tmp);
1496
0
      else if (tmp->type == SC_ENTERSAFE_EF_DATA)
1497
0
        return entersafe_create_ef(card, tmp);
1498
0
      else
1499
0
        return SC_ERROR_INTERNAL;
1500
0
    case SC_CARDCTL_ENTERSAFE_WRITE_KEY:
1501
0
      return entersafe_write_key(card, (sc_entersafe_wkey_data *)ptr);
1502
0
    case SC_CARDCTL_ENTERSAFE_GENERATE_KEY:
1503
0
      return entersafe_gen_key(card, (sc_entersafe_gen_key_data *)ptr);
1504
0
    case SC_CARDCTL_ERASE_CARD:
1505
0
      return entersafe_erase_card(card);
1506
136
    case SC_CARDCTL_GET_SERIALNR:
1507
136
      return entersafe_get_serialnr(card, (sc_serial_number_t *)ptr);
1508
0
    case SC_CARDCTL_ENTERSAFE_PREINSTALL_KEYS:
1509
0
      return entersafe_preinstall_keys(card, entersafe_preinstall_rsa_2048);
1510
0
    default:
1511
0
      return SC_ERROR_NOT_SUPPORTED;
1512
136
  }
1513
136
}
1514
1515
static struct sc_card_driver * sc_get_driver(void)
1516
15.1k
{
1517
15.1k
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
1518
1519
15.1k
  if (iso_ops == NULL)
1520
1
    iso_ops = iso_drv->ops;
1521
1522
15.1k
  entersafe_ops = *iso_drv->ops;
1523
15.1k
  entersafe_ops.match_card = entersafe_match_card;
1524
15.1k
  entersafe_ops.init = entersafe_init;
1525
15.1k
  entersafe_ops.read_binary = entersafe_read_binary;
1526
15.1k
  entersafe_ops.write_binary = NULL;
1527
15.1k
  entersafe_ops.update_binary = entersafe_update_binary;
1528
15.1k
  entersafe_ops.select_file = entersafe_select_file;
1529
15.1k
  entersafe_ops.restore_security_env = entersafe_restore_security_env;
1530
15.1k
  entersafe_ops.set_security_env = entersafe_set_security_env;
1531
15.1k
  entersafe_ops.decipher = entersafe_decipher;
1532
15.1k
  entersafe_ops.compute_signature = entersafe_compute_signature;
1533
15.1k
  entersafe_ops.create_file = entersafe_create_file;
1534
15.1k
  entersafe_ops.delete_file = NULL;
1535
15.1k
  entersafe_ops.pin_cmd = entersafe_pin_cmd;
1536
15.1k
  entersafe_ops.card_ctl = entersafe_card_ctl_2048;
1537
15.1k
  entersafe_ops.process_fci = entersafe_process_fci;
1538
15.1k
  return &entersafe_drv;
1539
15.1k
}
1540
1541
struct sc_card_driver * sc_get_entersafe_driver(void)
1542
15.1k
{
1543
15.1k
  return sc_get_driver();
1544
15.1k
}
1545
#endif