Coverage Report

Created: 2026-05-30 06:29

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