Coverage Report

Created: 2025-11-09 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/card-epass2003.c
Line
Count
Source
1
/*
2
 * Support for ePass2003 smart cards
3
 *
4
 * Copyright (C) 2008, Weitao Sun <weitao@ftsafe.com>
5
 * Copyright (C) 2011, Xiaoshuo Wu <xiaoshuo@ftsafe.com>
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25
#ifdef ENABLE_SM    /* empty file without SM enabled */
26
#ifdef ENABLE_OPENSSL   /* empty file without openssl */
27
28
#include <ctype.h>
29
#include <stdlib.h>
30
#include <string.h>
31
32
#include <openssl/evp.h>
33
#include <openssl/sha.h>
34
35
#include "internal.h"
36
#include "asn1.h"
37
38
#include <ctype.h>
39
#include <stdlib.h>
40
#include <string.h>
41
42
#include <openssl/cmac.h>
43
#include <openssl/rand.h>
44
#include <openssl/sha.h>
45
46
#include "internal.h"
47
#include "asn1.h"
48
#include "cardctl.h"
49
50
/*
51
 * See https://github.com/OpenSC/OpenSC/issues/2572
52
 * 2012 ATR: note version 01:00:11
53
 *        3b:9f:95:81:31:fe:9f:00:66:46:53:05:01:00:11:71:df:00:00:03:90:00:80
54
 * 2022 ATRs: note version 23:00:25
55
 *   OpenSC-initialized ATR:
56
 *        3b 9f:95:81:31:fe:9f:00:66:46:53:05:23:00:25:71:df:00:00:03:90:00:96
57
 *   Feitian-initalized ATR:
58
 *        3b:9f:95:81:31:fe:9f:00:66:46:53:05:23:00:25:71:df:00:00:00:00:00:05
59
 */
60
61
static const struct sc_atr_table epass2003_atrs[] = {
62
  /* This is a FIPS certified card using SCP01 security messaging. */
63
  /* will match all the above */
64
  {"3B:9F:95:81:31:FE:9F:00:66:46:53:05:00:00:00:71:df:00:00:00:00:00:00",
65
   "FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00:00:00:FF:FF:FF:FF:00:00:00:00",
66
   "FTCOS/ePass2003", SC_CARD_TYPE_ENTERSAFE_FTCOS_EPASS2003, 0, NULL },
67
  {NULL, NULL, NULL, 0, 0, NULL}
68
};
69
70
static struct sc_card_operations *iso_ops = NULL;
71
static struct sc_card_operations epass2003_ops;
72
73
static struct sc_card_driver epass2003_drv = {
74
  "epass2003",
75
  "epass2003",
76
  &epass2003_ops,
77
  NULL, 0, NULL
78
};
79
80
26.3k
#define KEY_TYPE_AES  0x01  /* FIPS mode */
81
7.94k
#define KEY_TYPE_DES  0x02  /* Non-FIPS mode */
82
83
#define KEY_LEN_AES 16
84
#define KEY_LEN_DES 8
85
#define KEY_LEN_DES3  24
86
20
#define HASH_LEN  24
87
88
static unsigned char PIN_ID[2] = { ENTERSAFE_USER_PIN_ID, ENTERSAFE_SO_PIN_ID };
89
90
/*0x00:plain; 0x01:scp01 sm*/
91
9.13k
#define SM_PLAIN        0x00
92
4.36k
#define SM_SCP01        0x01
93
94
static unsigned char g_init_key_enc[16] = {
95
  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
96
  0x0D, 0x0E, 0x0F, 0x10
97
};
98
99
static unsigned char g_init_key_mac[16] = {
100
  0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
101
  0x0D, 0x0E, 0x0F, 0x10
102
};
103
104
static unsigned char g_random[8];
105
106
typedef struct epass2003_exdata_st {
107
  unsigned char sm;   /* SM_PLAIN or SM_SCP01 */
108
  unsigned char smtype;   /* KEY_TYPE_AES or KEY_TYPE_DES */
109
  unsigned char sk_enc[16]; /* encrypt session key */
110
  unsigned char sk_mac[16]; /* mac session key */
111
  unsigned char icv_mac[16];  /* instruction counter vector(for sm) */
112
  unsigned char bFipsCertification; /* fips mode Alg */
113
  unsigned char currAlg;    /* current Alg */
114
  unsigned int  ecAlgFlags;   /* Ec Alg mechanism type*/
115
} epass2003_exdata;
116
117
20
#define REVERSE_ORDER4(x) (       \
118
20
    ((unsigned long)x & 0xFF000000)>> 24  | \
119
20
    ((unsigned long)x & 0x00FF0000)>>  8  | \
120
20
    ((unsigned long)x & 0x0000FF00)<<  8  | \
121
20
    ((unsigned long)x & 0x000000FF)<< 24)
122
123
124
static const struct sc_card_error epass2003_errors[] = {
125
  { 0x6200, SC_ERROR_CARD_CMD_FAILED, "Warning: no information given, non-volatile memory is unchanged" },
126
  { 0x6281, SC_ERROR_CORRUPTED_DATA,  "Part of returned data may be corrupted" },
127
  { 0x6282, SC_ERROR_FILE_END_REACHED,  "End of file/record reached before reading Le bytes" },
128
  { 0x6283, SC_ERROR_CARD_CMD_FAILED, "Selected file invalidated" },
129
  { 0x6284, SC_ERROR_CARD_CMD_FAILED, "FCI not formatted according to ISO 7816-4" },
130
131
  { 0x6300, SC_ERROR_PIN_CODE_INCORRECT,  "Authentication failed"},
132
  { 0x63C1, SC_ERROR_PIN_CODE_INCORRECT,  "Authentication failed. One tries left"},
133
  { 0x63C2, SC_ERROR_PIN_CODE_INCORRECT,  "Authentication failed. Two tries left"},
134
  { 0x63C3, SC_ERROR_PIN_CODE_INCORRECT,  "Authentication failed"},
135
  { 0x63C4, SC_ERROR_PIN_CODE_INCORRECT,  "Authentication failed"},
136
  { 0x63C5, SC_ERROR_PIN_CODE_INCORRECT,  "Authentication failed"},
137
  { 0x63C6, SC_ERROR_PIN_CODE_INCORRECT,  "Authentication failed"},
138
  { 0x63C7, SC_ERROR_PIN_CODE_INCORRECT,  "Authentication failed"},
139
  { 0x63C8, SC_ERROR_PIN_CODE_INCORRECT,  "Authentication failed"},
140
  { 0x63C9, SC_ERROR_PIN_CODE_INCORRECT,  "Authentication failed"},
141
  { 0x63CA, SC_ERROR_PIN_CODE_INCORRECT,  "Authentication failed"},
142
143
  { 0x6381, SC_ERROR_CARD_CMD_FAILED, "Warning: file filled up by last write" },
144
145
  { 0x6581, SC_ERROR_MEMORY_FAILURE,  "Memory failure" },
146
147
  { 0x6700, SC_ERROR_WRONG_LENGTH,  "Wrong length" },
148
149
  { 0x6800, SC_ERROR_NO_CARD_SUPPORT, "Functions in CLA not supported" },
150
  { 0x6881, SC_ERROR_NO_CARD_SUPPORT, "Logical channel not supported" },
151
  { 0x6882, SC_ERROR_NO_CARD_SUPPORT, "Secure messaging not supported" },
152
153
  { 0x6900, SC_ERROR_NOT_ALLOWED,   "Command not allowed" },
154
  { 0x6981, SC_ERROR_CARD_CMD_FAILED, "Command incompatible with file structure" },
155
  { 0x6982, SC_ERROR_SECURITY_STATUS_NOT_SATISFIED, "Security status not satisfied" },
156
  { 0x6983, SC_ERROR_AUTH_METHOD_BLOCKED, "Authentication method blocked" },
157
  { 0x6984, SC_ERROR_REF_DATA_NOT_USABLE, "Referenced data not usable" },
158
  { 0x6985, SC_ERROR_NOT_ALLOWED,   "Conditions of use not satisfied" },
159
  { 0x6986, SC_ERROR_NOT_ALLOWED,   "Command not allowed (no current EF)" },
160
  { 0x6987, SC_ERROR_INCORRECT_PARAMETERS,"Expected SM data objects missing" },
161
  { 0x6988, SC_ERROR_INCORRECT_PARAMETERS,"SM data objects incorrect" },
162
163
  { 0x6A00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" },
164
  { 0x6A80, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters in the data field" },
165
  { 0x6A81, SC_ERROR_NO_CARD_SUPPORT, "Function not supported" },
166
  { 0x6A82, SC_ERROR_FILE_NOT_FOUND,  "File not found" },
167
  { 0x6A83, SC_ERROR_RECORD_NOT_FOUND,  "Record not found" },
168
  { 0x6A84, SC_ERROR_NOT_ENOUGH_MEMORY, "Not enough memory space in the file" },
169
  { 0x6A85, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with TLV structure" },
170
  { 0x6A86, SC_ERROR_INCORRECT_PARAMETERS,"Incorrect parameters P1-P2" },
171
  { 0x6A87, SC_ERROR_INCORRECT_PARAMETERS,"Lc inconsistent with P1-P2" },
172
  { 0x6A88, SC_ERROR_DATA_OBJECT_NOT_FOUND,"Referenced data not found" },
173
  { 0x6A89, SC_ERROR_FILE_ALREADY_EXISTS,  "File already exists"},
174
  { 0x6A8A, SC_ERROR_FILE_ALREADY_EXISTS,  "DF name already exists"},
175
176
  { 0x6B00, SC_ERROR_INCORRECT_PARAMETERS,"Wrong parameter(s) P1-P2" },
177
  { 0x6D00, SC_ERROR_INS_NOT_SUPPORTED, "Instruction code not supported or invalid" },
178
  { 0x6E00, SC_ERROR_CLASS_NOT_SUPPORTED, "Class not supported" },
179
  { 0x6F00, SC_ERROR_CARD_CMD_FAILED, "No precise diagnosis" },
180
181
  { 0x9000,SC_SUCCESS,                       NULL }
182
};
183
184
typedef struct sec_attr_to_acl_entries {
185
  unsigned int file_type;   /* file->type */
186
  unsigned int file_ef_structure; /* file->ef_structure */
187
  int index;      /* index in  epass2003 iversion of sec_attr */
188
  /* use the follow for sc_file_add_entry */
189
  int op;       /* SC_AC_OP_* */
190
} sec_attr_to_acl_entries_t;
191
192
// clang-format off
193
/* Known combinations of file type and methods. More can be added as needed */
194
static const sec_attr_to_acl_entries_t sec_attr_to_acl_entry[] = {
195
  {SC_FILE_TYPE_DF, 0, 0,       SC_AC_OP_LIST_FILES},
196
  {SC_FILE_TYPE_DF, 0, 1,       SC_AC_OP_CREATE},
197
  {SC_FILE_TYPE_DF, 0, 3,       SC_AC_OP_DELETE},
198
199
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 0,  SC_AC_OP_READ},
200
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 1,  SC_AC_OP_UPDATE},
201
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 3,  SC_AC_OP_DELETE},
202
203
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 0,  SC_AC_OP_READ},
204
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 1,  SC_AC_OP_UPDATE},
205
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_TRANSPARENT, 3,  SC_AC_OP_DELETE},
206
207
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_FIXED, 0,  SC_AC_OP_READ},
208
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_FIXED, 1,  SC_AC_OP_UPDATE},
209
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_FIXED, 2,  SC_AC_OP_WRITE},
210
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_FIXED, 3,  SC_AC_OP_DELETE},
211
212
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_VARIABLE, 0,  SC_AC_OP_READ},
213
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_VARIABLE, 1,  SC_AC_OP_UPDATE},
214
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_VARIABLE, 2,  SC_AC_OP_WRITE},
215
  {SC_FILE_TYPE_WORKING_EF, SC_FILE_EF_LINEAR_VARIABLE, 3,  SC_AC_OP_DELETE},
216
217
  {SC_FILE_TYPE_BSO, 0, 0,        SC_AC_OP_UPDATE},
218
  {SC_FILE_TYPE_BSO, 0, 3,        SC_AC_OP_DELETE},
219
220
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_CRT, 1,  SC_AC_OP_UPDATE},
221
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_CRT,  1,  SC_AC_OP_UPDATE},
222
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_CRT, 2,  SC_AC_OP_CRYPTO},
223
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_CRT,  2,  SC_AC_OP_CRYPTO},
224
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_CRT, 3,  SC_AC_OP_DELETE},
225
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_CRT,  3,  SC_AC_OP_DELETE},
226
227
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC, 0, SC_AC_OP_READ},
228
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC,  0, SC_AC_OP_READ},
229
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC, 1, SC_AC_OP_UPDATE},
230
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC,  1, SC_AC_OP_UPDATE},
231
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC, 2, SC_AC_OP_CRYPTO},
232
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC,  2, SC_AC_OP_CRYPTO},
233
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC, 3, SC_AC_OP_DELETE},
234
  {SC_FILE_TYPE_INTERNAL_EF, SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC,  3, SC_AC_OP_DELETE},
235
};
236
// clang-format on
237
238
static int epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu);
239
static int epass2003_select_file(struct sc_card *card, const sc_path_t * in_path, sc_file_t ** file_out);
240
int epass2003_refresh(struct sc_card *card);
241
static int hash_data(struct sc_card *card, const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType);
242
243
static int
244
epass2003_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2)
245
46.3k
{
246
46.3k
  const int err_count = sizeof(epass2003_errors)/sizeof(epass2003_errors[0]);
247
46.3k
  int i;
248
249
  /* Handle special cases here */
250
46.3k
  if (sw1 == 0x6C) {
251
496
    sc_log(card->ctx, "Wrong length; correct length is %d", sw2);
252
496
    return SC_ERROR_WRONG_LENGTH;
253
496
  }
254
255
2.14M
  for (i = 0; i < err_count; i++) {
256
2.14M
    if (epass2003_errors[i].SWs == ((sw1 << 8) | sw2)) {
257
42.8k
      sc_log(card->ctx, "%s", epass2003_errors[i].errorstr);
258
42.8k
      return epass2003_errors[i].errorno;
259
42.8k
    }
260
2.14M
  }
261
262
2.99k
  sc_log(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X", sw1, sw2);
263
2.99k
  return SC_ERROR_CARD_CMD_FAILED;
264
45.8k
}
265
266
static int
267
sc_transmit_apdu_t(sc_card_t *card, sc_apdu_t *apdu)
268
21.9k
{
269
21.9k
  size_t resplen = apdu->resplen;
270
21.9k
  int r = sc_transmit_apdu(card, apdu);
271
21.9k
  if ((0x69 == apdu->sw1 && 0x85 == apdu->sw2) || (0x69 == apdu->sw1 && 0x88 == apdu->sw2)) {
272
711
    epass2003_refresh(card);
273
    /* renew old resplen */
274
711
    apdu->resplen = resplen;
275
711
    r = sc_transmit_apdu(card, apdu);
276
711
  }
277
21.9k
  return r;
278
21.9k
}
279
280
static int
281
openssl_enc(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned char *iv,
282
    const unsigned char *input, size_t length, unsigned char *output)
283
12.1k
{
284
12.1k
  int r = SC_ERROR_INTERNAL;
285
12.1k
  EVP_CIPHER_CTX * ctx = NULL;
286
12.1k
  int outl = 0;
287
12.1k
  int outl_tmp = 0;
288
12.1k
  unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = {0};
289
290
12.1k
  memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH);
291
12.1k
  ctx = EVP_CIPHER_CTX_new();
292
12.1k
  if (ctx == NULL)
293
0
    goto out;
294
295
12.1k
  if (!EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv_tmp) || !EVP_CIPHER_CTX_set_padding(ctx, 0))
296
0
    goto out;
297
298
12.1k
  if (!EVP_EncryptUpdate(ctx, output, &outl, input, (int)length))
299
0
    goto out;
300
301
12.1k
  if (!EVP_EncryptFinal_ex(ctx, output + outl, &outl_tmp))
302
0
    goto out;
303
304
12.1k
  r = SC_SUCCESS;
305
12.1k
out:
306
12.1k
  EVP_CIPHER_CTX_free(ctx);
307
12.1k
  return r;
308
12.1k
}
309
310
static int
311
openssl_dec(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned char *iv,
312
    const unsigned char *input, size_t length, unsigned char *output)
313
3.71k
{
314
3.71k
  int r = SC_ERROR_INTERNAL;
315
3.71k
  EVP_CIPHER_CTX * ctx = NULL;
316
3.71k
  int outl = 0;
317
3.71k
  int outl_tmp = 0;
318
3.71k
  unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = {0};
319
320
3.71k
  memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH);
321
3.71k
  ctx = EVP_CIPHER_CTX_new();
322
3.71k
  if (ctx == NULL)
323
0
    goto out;
324
325
3.71k
  if (!EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv_tmp) ||
326
3.71k
      !EVP_CIPHER_CTX_set_padding(ctx, 0))
327
0
    goto out;
328
329
3.71k
  if (!EVP_DecryptUpdate(ctx, output, &outl, input, (int)length))
330
0
    goto out;
331
332
3.71k
  if (!EVP_DecryptFinal_ex(ctx, output + outl, &outl_tmp))
333
89
    goto out;
334
335
3.62k
  r = SC_SUCCESS;
336
3.71k
out:
337
3.71k
  EVP_CIPHER_CTX_free(ctx);
338
3.71k
  return r;
339
3.62k
}
340
341
static int
342
aes128_encrypt_cmac_ft(struct sc_card *card, const unsigned char *key, int keysize,
343
  const unsigned char *input, size_t length, unsigned char *output,unsigned char *iv)
344
0
{
345
0
  unsigned char data1[32] = {0};
346
0
  unsigned char data2[32] = {0};
347
0
  unsigned char k1Bin[32] = {0};
348
0
  unsigned char k2Bin[32] = {0};
349
350
0
  unsigned char check = 0;
351
0
  BIGNUM *enc1,*lenc1;
352
0
  BIGNUM *enc2,*lenc2;
353
354
  // k1
355
0
  int offset = 0;
356
0
  int r = SC_ERROR_INTERNAL;
357
0
  unsigned char out[32] = {0};
358
0
  unsigned char iv0[EVP_MAX_IV_LENGTH] = {0};
359
0
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-ECB");
360
0
  r = openssl_enc(alg, key, iv0, data1, 16, out);
361
0
  if (r != SC_SUCCESS) {
362
0
    sc_log_openssl(card->ctx);
363
0
    sc_evp_cipher_free(alg);
364
0
    return r;
365
0
  }
366
367
0
  check = out[0];
368
0
  enc1 = BN_new();
369
0
  lenc1 = BN_new();
370
0
  BN_bin2bn(out,16,enc1);
371
0
  BN_lshift1(lenc1,enc1);
372
0
  BN_bn2bin(lenc1,k1Bin);
373
0
  if (check & 0x80) {
374
0
    offset = 1;
375
0
    k1Bin[15+offset] ^= 0x87;
376
0
  }
377
0
  BN_free(enc1);
378
0
  BN_free(lenc1);
379
380
  // k2
381
0
  enc2 = BN_new();
382
0
  lenc2 = BN_new();
383
0
  check = k1Bin[offset];
384
0
  BN_bin2bn(&k1Bin[offset],16,enc2);
385
386
0
  offset = 0;
387
0
  BN_lshift1(lenc2,enc2);
388
0
  BN_bn2bin(lenc2,k2Bin);
389
0
  if (check & 0x80) {
390
0
    offset = 1;
391
0
    k2Bin[15+offset] ^= 0x87;
392
0
  }
393
0
  BN_free(enc2);
394
0
  BN_free(lenc2);
395
  // padding
396
0
  if (length < 16) {
397
0
    memcpy(&data2[0],input,length);
398
0
    data2[length] = 0x80;
399
0
  }
400
401
  // k2 xor padded data
402
0
  for (int i = 0; i < 16; i++) {
403
0
    data2[i] = data2[i] ^ k2Bin[offset + i];
404
0
  }
405
0
  r = openssl_enc(alg, key, iv, data2, 16, output);
406
0
  sc_evp_cipher_free(alg);
407
0
  if (r != SC_SUCCESS)
408
0
    sc_log_openssl(card->ctx);
409
0
  return r;
410
0
}
411
412
static int
413
aes128_encrypt_cmac(struct sc_card *card, const unsigned char *key, int keysize,
414
  const unsigned char *input, size_t length, unsigned char *output)
415
763
{
416
763
  size_t mactlen = 0;
417
763
  int r = SC_ERROR_INTERNAL;
418
763
#if OPENSSL_VERSION_NUMBER < 0x30000000L
419
763
  CMAC_CTX *ctx = CMAC_CTX_new();
420
763
  if (ctx == NULL) {
421
0
    return SC_ERROR_INTERNAL;
422
0
  }
423
424
763
  if (!CMAC_Init(ctx, key, keysize / 8, EVP_aes_128_cbc(), NULL)) {
425
0
    goto err;
426
0
  }
427
763
  if (!CMAC_Update(ctx, input, length)) {
428
0
    goto err;
429
0
  }
430
763
  if (!CMAC_Final(ctx, output, &mactlen)) {
431
0
    goto err;
432
0
  }
433
763
  r = SC_SUCCESS;
434
763
err:
435
763
  CMAC_CTX_free(ctx);
436
#else
437
  EVP_MAC *mac = EVP_MAC_fetch(card->ctx->ossl3ctx->libctx, "cmac", NULL);
438
  if (mac == NULL) {
439
    return r;
440
  }
441
442
  OSSL_PARAM params[2] = {0};
443
  params[0] = OSSL_PARAM_construct_utf8_string("cipher","aes-128-cbc", 0);
444
  params[1] = OSSL_PARAM_construct_end();
445
446
  EVP_MAC_CTX *ctx = EVP_MAC_CTX_new(mac);
447
  if (ctx == NULL) {
448
    EVP_MAC_CTX_free(ctx);
449
    sc_log_openssl(card->ctx);
450
    return r;
451
  }
452
  if (!EVP_MAC_init(ctx, (const unsigned char *)key, keysize / 8, params)) {
453
    sc_log_openssl(card->ctx);
454
    goto err;
455
  }
456
  if (!EVP_MAC_update(ctx, input, length)) {
457
    sc_log_openssl(card->ctx);
458
    goto err;
459
  }
460
  if (!EVP_MAC_final(ctx, output, &mactlen, 16)) {
461
    sc_log_openssl(card->ctx);
462
    goto err;
463
  }
464
  r = SC_SUCCESS;
465
err:
466
  EVP_MAC_CTX_free(ctx);
467
  EVP_MAC_free(mac);
468
#endif
469
763
  return r;
470
763
}
471
472
static int
473
aes128_encrypt_ecb(struct sc_card *card, const unsigned char *key, int keysize,
474
    const unsigned char *input, size_t length, unsigned char *output)
475
140
{
476
140
  unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
477
140
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-ECB");
478
140
  int r;
479
140
  r = openssl_enc(alg, key, iv, input, length, output);
480
140
  sc_evp_cipher_free(alg);
481
140
  if (r != SC_SUCCESS)
482
0
    sc_log_openssl(card->ctx);
483
140
  return r;
484
140
}
485
486
487
static int
488
aes128_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[16],
489
    const unsigned char *input, size_t length, unsigned char *output)
490
822
{
491
822
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-CBC");
492
822
  int r;
493
822
  r = openssl_enc(alg, key, iv, input, length, output);
494
822
  sc_evp_cipher_free(alg);
495
822
  if (r != SC_SUCCESS)
496
0
    sc_log_openssl(card->ctx);
497
822
  return r;
498
822
}
499
500
501
static int
502
aes128_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[16],
503
    const unsigned char *input, size_t length, unsigned char *output)
504
141
{
505
141
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-CBC");
506
141
  int r;
507
141
  r = openssl_dec(alg, key, iv, input, length, output);
508
141
  sc_evp_cipher_free(alg);
509
141
  if (r != SC_SUCCESS)
510
89
    sc_log_openssl(card->ctx);
511
141
  return r;
512
141
}
513
514
515
static int
516
des3_encrypt_ecb(struct sc_card *card, const unsigned char *key, int keysize,
517
    const unsigned char *input, int length, unsigned char *output)
518
522
{
519
522
  unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
520
522
  unsigned char bKey[24] = {0};
521
522
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3");
522
522
  int r;
523
524
522
  if (keysize == 16) {
525
522
    memcpy(&bKey[0], key, 16);
526
522
    memcpy(&bKey[16], key, 8);
527
522
  } else {
528
0
    memcpy(&bKey[0], key, 24);
529
0
  }
530
531
522
  r = openssl_enc(alg, bKey, iv, input, length, output);
532
522
  sc_evp_cipher_free(alg);
533
522
  if (r != SC_SUCCESS)
534
0
    sc_log_openssl(card->ctx);
535
522
  return r;
536
522
}
537
538
539
static int
540
des3_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH],
541
    const unsigned char *input, size_t length, unsigned char *output)
542
3.53k
{
543
3.53k
  unsigned char bKey[24] = {0};
544
3.53k
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3-CBC");
545
3.53k
  int r;
546
547
3.53k
  if (keysize == 16) {
548
3.53k
    memcpy(&bKey[0], key, 16);
549
3.53k
    memcpy(&bKey[16], key, 8);
550
3.53k
  } else {
551
0
    memcpy(&bKey[0], key, 24);
552
0
  }
553
554
3.53k
  r = openssl_enc(EVP_des_ede3_cbc(), bKey, iv, input, length, output);
555
3.53k
  sc_evp_cipher_free(alg);
556
3.53k
  if (r != SC_SUCCESS)
557
0
    sc_log_openssl(card->ctx);
558
3.53k
  return r;
559
3.53k
}
560
561
562
static int
563
des3_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH],
564
    const unsigned char *input, size_t length, unsigned char *output)
565
0
{
566
0
  unsigned char bKey[24] = {0};
567
0
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3-CBC");
568
0
  int r;
569
570
0
  if (keysize == 16) {
571
0
    memcpy(&bKey[0], key, 16);
572
0
    memcpy(&bKey[16], key, 8);
573
0
  } else {
574
0
    memcpy(&bKey[0], key, 24);
575
0
  }
576
577
0
  r = openssl_dec(alg, bKey, iv, input, length, output);
578
0
  sc_evp_cipher_free(alg);
579
0
  if (r != SC_SUCCESS)
580
0
    sc_log_openssl(card->ctx);
581
0
  return r;
582
0
}
583
584
585
static int
586
des_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH],
587
    const unsigned char *input, size_t length, unsigned char *output)
588
7.15k
{
589
7.15k
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-CBC");
590
7.15k
  int r;
591
592
7.15k
  r = openssl_enc(alg, key, iv, input, length, output);
593
7.15k
  sc_evp_cipher_free(alg);
594
7.15k
  if (r != SC_SUCCESS)
595
0
    sc_log_openssl(card->ctx);
596
7.15k
  return r;
597
7.15k
}
598
599
600
static int
601
des_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH],
602
    const unsigned char *input, size_t length, unsigned char *output)
603
3.57k
{
604
3.57k
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-CBC");
605
3.57k
  int r;
606
607
3.57k
  r = openssl_dec(alg, key, iv, input, length, output);
608
3.57k
  sc_evp_cipher_free(alg);
609
3.57k
  if (r != SC_SUCCESS)
610
0
    sc_log_openssl(card->ctx);
611
3.57k
  return r;
612
3.57k
}
613
614
615
static int
616
openssl_dig(const EVP_MD * digest, const unsigned char *input, size_t length,
617
    unsigned char *output)
618
20
{
619
20
  int r = 0;
620
20
  EVP_MD_CTX *ctx = NULL;
621
20
  unsigned outl = 0;
622
623
20
  ctx = EVP_MD_CTX_create();
624
20
  if (ctx == NULL) {
625
0
    r = SC_ERROR_OUT_OF_MEMORY;
626
0
    goto err;
627
0
  }
628
629
20
  EVP_MD_CTX_init(ctx);
630
20
  if (!EVP_DigestInit_ex(ctx, digest, NULL) ||
631
20
      !EVP_DigestUpdate(ctx, input, length)) {
632
0
    r = SC_ERROR_INTERNAL;
633
0
    goto err;
634
0
  }
635
636
20
  if (!EVP_DigestFinal_ex(ctx, output, &outl)) {
637
0
    r = SC_ERROR_INTERNAL;
638
0
    goto err;
639
0
  }
640
20
  r = SC_SUCCESS;
641
20
err:
642
20
  if (ctx)
643
20
    EVP_MD_CTX_destroy(ctx);
644
645
20
  return r;
646
20
}
647
648
649
static int
650
sha1_digest(struct sc_card *card, const unsigned char *input, size_t length, unsigned char *output)
651
20
{
652
20
  EVP_MD *md = sc_evp_md(card->ctx, "SHA1");
653
20
  int r;
654
655
20
  r = openssl_dig(md, input, length, output);
656
20
  sc_evp_md_free(md);
657
20
  if (r != SC_SUCCESS)
658
0
    sc_log_openssl(card->ctx);
659
20
  return r;
660
20
}
661
662
static int
663
sha256_digest(struct sc_card *card, const unsigned char *input, size_t length, unsigned char *output)
664
0
{
665
0
  EVP_MD *md = sc_evp_md(card->ctx, "SHA256");
666
0
  int r;
667
668
0
  r = openssl_dig(md, input, length, output);
669
0
  sc_evp_md_free(md);
670
0
  if (r != SC_SUCCESS)
671
0
    sc_log_openssl(card->ctx);
672
0
  return r;
673
0
}
674
675
676
static int
677
gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_mac,
678
    unsigned char *result, unsigned char key_type)
679
4.04k
{
680
4.04k
  int r;
681
4.04k
  struct sc_apdu apdu;
682
4.04k
  unsigned char data[256] = {0};
683
4.04k
  unsigned char tmp_sm;
684
4.04k
  unsigned char isFips;
685
4.04k
  unsigned long blocksize = 0;
686
4.04k
  unsigned char cryptogram[256] = {0}; /* host cryptogram */
687
4.04k
  unsigned char iv[16] = {0};
688
4.04k
  epass2003_exdata *exdata = NULL;
689
690
4.04k
  if (!card->drv_data)
691
0
    return SC_ERROR_INVALID_ARGUMENTS;
692
693
4.04k
  exdata = (epass2003_exdata *)card->drv_data;
694
4.04k
  isFips = exdata->bFipsCertification;
695
696
4.04k
  LOG_FUNC_CALLED(card->ctx);
697
698
4.04k
  if (1 != RAND_bytes(g_random, sizeof(g_random)))
699
0
    return SC_ERROR_INTERNAL;
700
701
4.04k
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x50, 0x00, 0x00);
702
4.04k
  apdu.cla = 0x80;
703
4.04k
  apdu.lc = apdu.datalen = sizeof(g_random);
704
4.04k
  apdu.data = g_random; /* host random */
705
4.04k
  if (isFips)
706
380
    apdu.le = apdu.resplen = 29;
707
3.66k
  else
708
3.66k
    apdu.le = apdu.resplen = 28;
709
710
4.04k
  apdu.resp = result; /* card random is result[12~19] */
711
712
4.04k
  tmp_sm = exdata->sm;
713
4.04k
  exdata->sm = SM_PLAIN;
714
4.04k
  r = epass2003_transmit_apdu(card, &apdu);
715
4.04k
  exdata->sm = tmp_sm;
716
4.04k
  LOG_TEST_RET(card->ctx, r, "APDU gen_init_key failed");
717
718
3.95k
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
719
3.95k
  LOG_TEST_RET(card->ctx, r, "gen_init_key failed");
720
721
  /* Step 1 - Generate Derivation data */
722
416
  if (isFips) {
723
85
    memset(data, 0x00, 15);
724
85
    data[11] = 0x04;
725
85
    data[14] = 0x80;
726
85
    data[15] = 0x01;
727
85
    memcpy(&data[16], g_random, 8);
728
85
    memcpy(&data[24], &result[12 + 1], 8);
729
331
  } else {
730
331
    memcpy(data, &result[16], 4);
731
331
    memcpy(&data[4], g_random, 4);
732
331
    memcpy(&data[8], &result[12], 4);
733
331
    memcpy(&data[12], &g_random[4], 4);
734
331
  }
735
736
  /* Step 2,3 - Create S-ENC/S-MAC Session Key */
737
416
  if (KEY_TYPE_AES == key_type) {
738
155
    if (isFips) {
739
85
      r = aes128_encrypt_cmac(card, key_enc, 128, data, 32, exdata->sk_enc);
740
85
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac enc failed");
741
85
      memset(&data[11], 0x06, 1);
742
85
      r = aes128_encrypt_cmac(card, key_mac, 128, data, 32, exdata->sk_mac);
743
85
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac mac  failed");
744
85
    } else {
745
70
      r = aes128_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc);
746
70
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb enc  failed");
747
70
      r = aes128_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac);
748
70
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb mac  failed");
749
70
    }
750
261
  } else {
751
261
    r = des3_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc);
752
261
    LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed");
753
261
    r = des3_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac);
754
261
    LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed");
755
261
  }
756
757
416
  if (isFips) {
758
85
    data[11] = 0x00;
759
85
    data[14] = 0x40;
760
331
  } else {
761
331
    memcpy(data, g_random, 8);
762
331
    memcpy(&data[8], &result[12], 8);
763
331
    data[16] = 0x80;
764
331
    blocksize = (key_type == KEY_TYPE_AES ? 16 : 8);
765
331
    memset(&data[17], 0x00, blocksize - 1);
766
331
  }
767
768
  /* calculate host cryptogram */
769
416
  if (KEY_TYPE_AES == key_type) {
770
155
    if (isFips) {
771
85
      r = aes128_encrypt_cmac(card, exdata->sk_enc, 128, data, 32, cryptogram);
772
85
    } else {
773
70
      r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram);
774
70
    }
775
261
  } else {
776
261
    r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram);
777
261
  }
778
779
416
  LOG_TEST_RET(card->ctx, r, "calculate host cryptogram failed");
780
781
  /* verify card cryptogram */
782
416
  if (isFips) {
783
85
    if (0 != memcmp(&cryptogram[0], &result[20+1], 8))
784
85
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED);
785
331
  } else {
786
331
    if (0 != memcmp(&cryptogram[16], &result[20], 8))
787
331
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED);
788
331
  }
789
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
790
0
}
791
792
793
static int
794
verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_type)
795
0
{
796
0
  int r;
797
0
  struct sc_apdu apdu;
798
0
  unsigned long blocksize = (key_type == KEY_TYPE_AES ? 16 : 8);
799
0
  unsigned char data[256] = {0};
800
0
  unsigned char cryptogram[256] = {0}; /* host cryptogram */
801
0
  unsigned char iv[16] = {0};
802
0
  unsigned char mac[256] = {0};
803
0
  unsigned long i;
804
0
  unsigned char tmp_sm;
805
0
  unsigned char isFips;
806
0
  epass2003_exdata *exdata = NULL;
807
808
0
  if (!card->drv_data)
809
0
    return SC_ERROR_INVALID_ARGUMENTS;
810
0
  exdata = (epass2003_exdata *)card->drv_data;
811
0
  isFips = exdata->bFipsCertification;
812
813
0
  LOG_FUNC_CALLED(card->ctx);
814
815
0
  if (isFips) {
816
0
    memset(data,0x00,15);
817
0
    data[11] = 0x01;
818
0
    data[14] = 0x40;
819
0
    data[15] = 0x01;
820
0
    memcpy(&data[16], g_random, 8);
821
0
    memcpy(&data[24], ran_key, 8);
822
0
  } else {
823
0
    memcpy(data, ran_key, 8);
824
0
    memcpy(&data[8], g_random, 8);
825
0
    data[16] = 0x80;
826
0
    memset(&data[17], 0x00, blocksize - 1);
827
0
    memset(iv, 0, 16);
828
0
  }
829
830
  /* calculate host cryptogram */
831
0
  if (KEY_TYPE_AES == key_type) {
832
0
    if (isFips) {
833
0
      r = aes128_encrypt_cmac(card, exdata->sk_enc, 128, data, 32, cryptogram);
834
0
    } else {
835
0
      r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram);
836
0
    }
837
0
  } else {
838
0
    r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram);
839
0
  }
840
841
0
  LOG_TEST_RET(card->ctx, r, "calculate host cryptogram  failed");
842
843
0
  memset(data, 0, sizeof(data));
844
0
  memcpy(data, "\x84\x82\x03\x00\x10", 5);
845
0
  if (isFips) {
846
0
    memcpy(&data[5], &cryptogram[0], 8);
847
0
  } else {
848
0
    memcpy(&data[5], &cryptogram[16], 8);
849
0
    memcpy(&data[13], "\x80\x00\x00", 3);
850
0
  }
851
852
  /* calculate mac icv */
853
0
  memset(iv, 0x00, 16);
854
0
  if (KEY_TYPE_AES == key_type) {
855
0
    if (isFips) {
856
0
      r = aes128_encrypt_cmac(card, exdata->sk_mac, 128, data, 13, mac);
857
0
    } else {
858
0
      r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, iv, data, 16, mac);
859
0
    }
860
0
    i = 0;
861
0
  } else {
862
0
    r = des3_encrypt_cbc(card, exdata->sk_mac, 16, iv, data, 16, mac);
863
0
    i = 8;
864
0
  }
865
866
0
  LOG_TEST_RET(card->ctx, r, "calculate mac icv failed");
867
  /* save mac icv */
868
0
  memset(exdata->icv_mac, 0x00, 16);
869
0
  memcpy(exdata->icv_mac, &mac[i], 8);
870
871
  /* verify host cryptogram */
872
0
  if (isFips) {
873
0
    memcpy(data, &cryptogram[0], 8);
874
0
  } else {
875
0
    memcpy(data, &cryptogram[16], 8);
876
0
  }
877
0
  memcpy(&data[8], &mac[i], 8);
878
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x03, 0x00);
879
0
  apdu.cla = 0x84;
880
0
  apdu.lc = apdu.datalen = 16;
881
0
  apdu.data = data;
882
0
  tmp_sm = exdata->sm;
883
0
  exdata->sm = SM_PLAIN;
884
0
  r = epass2003_transmit_apdu(card, &apdu);
885
0
  exdata->sm = tmp_sm;
886
0
  LOG_TEST_RET(card->ctx, r, "APDU verify_init_key failed");
887
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
888
0
  LOG_TEST_RET(card->ctx, r, "verify_init_key failed");
889
0
  return r;
890
0
}
891
892
893
static int
894
mutual_auth(struct sc_card *card, unsigned char *key_enc,
895
      unsigned char *key_mac)
896
4.04k
{
897
4.04k
  struct sc_context *ctx = card->ctx;
898
4.04k
  int r;
899
4.04k
  unsigned char result[256] = {0};
900
4.04k
  unsigned char ran_key[8] = {0};
901
4.04k
  epass2003_exdata *exdata = NULL;
902
903
4.04k
  if (!card->drv_data)
904
0
    return SC_ERROR_INVALID_ARGUMENTS;
905
4.04k
  exdata = (epass2003_exdata *)card->drv_data;
906
907
4.04k
  LOG_FUNC_CALLED(ctx);
908
909
4.04k
  r = gen_init_key(card, key_enc, key_mac, result, exdata->smtype);
910
4.04k
  LOG_TEST_RET(ctx, r, "gen_init_key failed");
911
0
  if (exdata->bFipsCertification) {
912
0
    memcpy(ran_key, &result[12+1], 8);
913
0
  } else {
914
0
    memcpy(ran_key, &result[12], 8);
915
0
  }
916
917
0
  r = verify_init_key(card, ran_key, exdata->smtype);
918
0
  LOG_TEST_RET(ctx, r, "verify_init_key failed");
919
920
0
  LOG_FUNC_RETURN(ctx, r);
921
0
}
922
923
924
int
925
epass2003_refresh(struct sc_card *card)
926
4.93k
{
927
4.93k
  int r = SC_SUCCESS;
928
4.93k
  epass2003_exdata *exdata = NULL;
929
930
4.93k
  if (!card->drv_data)
931
0
    return SC_ERROR_INVALID_ARGUMENTS;
932
933
4.93k
  exdata = (epass2003_exdata *)card->drv_data;
934
935
4.93k
  if (exdata->sm) {
936
4.04k
    card->sm_ctx.sm_mode = 0;
937
4.04k
    r = mutual_auth(card, g_init_key_enc, g_init_key_mac);
938
4.04k
    card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
939
4.04k
    LOG_TEST_RET(card->ctx, r, "mutual_auth failed");
940
4.04k
  }
941
942
881
  return r;
943
4.93k
}
944
945
946
/* Data(TLV)=0x87|L|0x01+Cipher */
947
static int
948
construct_data_tlv(struct sc_card *card, struct sc_apdu *apdu, unsigned char *apdu_buf,
949
    unsigned char *data_tlv, size_t * data_tlv_len, const unsigned char key_type)
950
3.82k
{
951
3.82k
  size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
952
3.82k
  unsigned char pad[4096] = {0};
953
3.82k
  size_t pad_len;
954
3.82k
  size_t tlv_more;  /* increased tlv length */
955
3.82k
  unsigned char iv[16] = {0};
956
3.82k
  epass2003_exdata *exdata = NULL;
957
3.82k
  int r = 0;
958
959
3.82k
  if (!card->drv_data)
960
0
    return SC_ERROR_INVALID_ARGUMENTS;
961
962
3.82k
  exdata = (epass2003_exdata *)card->drv_data;
963
964
  /* padding */
965
3.82k
  apdu_buf[block_size] = 0x87;
966
3.82k
  memcpy(pad, apdu->data, apdu->lc);
967
3.82k
  pad[apdu->lc] = 0x80;
968
3.82k
  if ((apdu->lc + 1) % block_size)
969
3.80k
    pad_len = ((apdu->lc + 1) / block_size + 1) * block_size;
970
19
  else
971
19
    pad_len = apdu->lc + 1;
972
973
  /* encode Lc' */
974
3.82k
  if (pad_len > 0x7E) {
975
    /* Lc' > 0x7E, use extended APDU */
976
12
    apdu_buf[block_size + 1] = 0x82;
977
12
    apdu_buf[block_size + 2] = (unsigned char)((pad_len + 1) / 0x100);
978
12
    apdu_buf[block_size + 3] = (unsigned char)((pad_len + 1) % 0x100);
979
12
    apdu_buf[block_size + 4] = 0x01;
980
12
    tlv_more = 5;
981
3.81k
  } else {
982
3.81k
    apdu_buf[block_size + 1] = (unsigned char)pad_len + 1;
983
3.81k
    apdu_buf[block_size + 2] = 0x01;
984
3.81k
    tlv_more = 3;
985
3.81k
  }
986
3.82k
  memcpy(data_tlv, &apdu_buf[block_size], tlv_more);
987
988
  /* encrypt Data */
989
3.82k
  if (KEY_TYPE_AES == key_type) {
990
556
    r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);
991
556
    LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed");
992
3.27k
  } else {
993
3.27k
    r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);
994
3.27k
    LOG_TEST_RET(card->ctx, r, "des3_encrypt_cbc failed");
995
3.27k
  }
996
997
3.82k
  memcpy(data_tlv + tlv_more, apdu_buf + block_size + tlv_more, pad_len);
998
3.82k
  *data_tlv_len = tlv_more + pad_len;
999
3.82k
  return 0;
1000
3.82k
}
1001
1002
1003
/* Le(TLV)=0x97|L|Le */
1004
static int
1005
construct_le_tlv(struct sc_apdu *apdu, unsigned char *apdu_buf, size_t data_tlv_len,
1006
    unsigned char *le_tlv, size_t * le_tlv_len, const unsigned char key_type)
1007
4.15k
{
1008
4.15k
  size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
1009
1010
4.15k
  *(apdu_buf + block_size + data_tlv_len) = 0x97;
1011
4.15k
  if (apdu->le > 0x7F) {
1012
    /* Le' > 0x7E, use extended APDU */
1013
58
    *(apdu_buf + block_size + data_tlv_len + 1) = 2;
1014
58
    *(apdu_buf + block_size + data_tlv_len + 2) = (unsigned char)(apdu->le / 0x100);
1015
58
    *(apdu_buf + block_size + data_tlv_len + 3) = (unsigned char)(apdu->le % 0x100);
1016
58
    memcpy(le_tlv, apdu_buf + block_size + data_tlv_len, 4);
1017
58
    *le_tlv_len = 4;
1018
4.09k
  } else {
1019
4.09k
    *(apdu_buf + block_size + data_tlv_len + 1) = 1;
1020
4.09k
    *(apdu_buf + block_size + data_tlv_len + 2) = (unsigned char)apdu->le;
1021
4.09k
    memcpy(le_tlv, apdu_buf + block_size + data_tlv_len, 3);
1022
4.09k
    *le_tlv_len = 3;
1023
4.09k
  }
1024
4.15k
  return 0;
1025
4.15k
}
1026
1027
1028
/* MAC(TLV)=0x8e|0x08|MAC */
1029
static int
1030
construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_len,
1031
    unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type)
1032
4.19k
{
1033
4.19k
  size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
1034
4.19k
  unsigned char mac[4096] = {0};
1035
4.19k
  size_t mac_len;
1036
4.19k
  unsigned char icv[16] = {0};
1037
4.19k
  int r ;
1038
4.19k
  int i = (KEY_TYPE_AES == key_type ? 15 : 7);
1039
4.19k
  epass2003_exdata *exdata = NULL;
1040
1041
4.19k
  if (!card->drv_data)
1042
0
    return SC_ERROR_INVALID_ARGUMENTS;
1043
1044
4.19k
  exdata = (epass2003_exdata *)card->drv_data;
1045
1046
4.19k
  if (0 == data_tlv_len && 0 == le_tlv_len) {
1047
0
    mac_len = block_size;
1048
4.19k
  } else {
1049
    /* padding */
1050
4.19k
    *(apdu_buf + block_size + data_tlv_len + le_tlv_len) = 0x80;
1051
4.19k
    if ((data_tlv_len + le_tlv_len + 1) % block_size) {
1052
4.14k
      mac_len = (((data_tlv_len + le_tlv_len + 1) / block_size) +
1053
4.14k
          1) * block_size + block_size;
1054
4.14k
    } else {
1055
49
      mac_len = data_tlv_len + le_tlv_len + 1 + block_size;
1056
49
    }
1057
4.19k
    memset((apdu_buf + block_size + data_tlv_len + le_tlv_len + 1),
1058
4.19k
           0, (mac_len - (data_tlv_len + le_tlv_len + 1)));
1059
4.19k
  }
1060
1061
  /* increase icv */
1062
4.19k
  for (; i >= 0; i--) {
1063
4.19k
    if (exdata->icv_mac[i] == 0xff) {
1064
0
      exdata->icv_mac[i] = 0;
1065
4.19k
    } else {
1066
4.19k
      exdata->icv_mac[i]++;
1067
4.19k
      break;
1068
4.19k
    }
1069
4.19k
  }
1070
1071
  /* calculate MAC */
1072
4.19k
  memset(icv, 0, sizeof(icv));
1073
4.19k
  memcpy(icv, exdata->icv_mac, 16);
1074
4.19k
  if (KEY_TYPE_AES == key_type) {
1075
698
    if (exdata->bFipsCertification) {
1076
8.63k
      for (int i = 0; i < 16; i++) {
1077
8.12k
        apdu_buf[i] = apdu_buf[i] ^ icv[i];
1078
8.12k
      }
1079
508
      r = aes128_encrypt_cmac(card, exdata->sk_mac, 128, apdu_buf, data_tlv_len + le_tlv_len + block_size, mac);
1080
508
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac failed");
1081
508
      memcpy(mac_tlv + 2, &mac[0 /*ulmacLen-16*/], 8);
1082
2.54k
      for (int j = 0; j < 4; j++) {
1083
2.03k
        apdu_buf[j] = apdu_buf[j] ^ icv[j];
1084
2.03k
      }
1085
508
    } else {
1086
190
      r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac);
1087
190
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed");
1088
190
      memcpy(mac_tlv + 2, &mac[mac_len - 16], 8);
1089
190
    }
1090
3.49k
  } else {
1091
3.49k
    unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
1092
3.49k
    unsigned char tmp[8] = {0};
1093
3.49k
    r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac);
1094
3.49k
    LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 1 failed");
1095
3.49k
    r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp);
1096
3.49k
    LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed");
1097
3.49k
    memset(iv, 0x00, sizeof iv);
1098
3.49k
    r = des_encrypt_cbc(card, exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2);
1099
3.49k
    LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 2 failed");
1100
3.49k
  }
1101
1102
4.19k
  *mac_tlv_len = 2 + 8;
1103
4.19k
  return 0;
1104
4.19k
}
1105
1106
/* MAC(TLV case 1) */
1107
static int
1108
construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_len,
1109
  unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type)
1110
0
{
1111
0
  int r;
1112
0
  size_t block_size = 4;
1113
0
  unsigned char mac[4096] = {0};
1114
0
  size_t mac_len;
1115
0
  int i = (KEY_TYPE_AES == key_type ? 15 : 7);
1116
0
  unsigned char icv[16] = {0};
1117
1118
0
  epass2003_exdata *exdata = NULL;
1119
1120
0
  if (!card->drv_data)
1121
0
    return SC_ERROR_INVALID_ARGUMENTS;
1122
1123
0
  exdata = (epass2003_exdata *)card->drv_data;
1124
1125
0
  if (0 == data_tlv_len && 0 == le_tlv_len) {
1126
0
    mac_len = block_size;
1127
0
  } else {
1128
    /* padding */
1129
0
    *(apdu_buf + block_size + data_tlv_len + le_tlv_len) = 0x80;
1130
0
    if ((data_tlv_len + le_tlv_len + 1) % block_size) {
1131
0
      mac_len = (((data_tlv_len + le_tlv_len + 1) / block_size) + 1) * block_size + block_size;
1132
0
    } else {
1133
0
      mac_len = data_tlv_len + le_tlv_len + 1 + block_size;
1134
0
    }
1135
0
  }
1136
  /* increase icv */
1137
0
  for (; i >= 0; i--) {
1138
0
    if (exdata->icv_mac[i] == 0xff) {
1139
0
      exdata->icv_mac[i] = 0;
1140
0
    } else {
1141
0
      exdata->icv_mac[i]++;
1142
0
      break;
1143
0
    }
1144
0
  }
1145
1146
  /* calculate MAC */
1147
0
  memset(icv, 0, sizeof(icv));
1148
0
  memcpy(icv, exdata->icv_mac, 16);
1149
0
  if (KEY_TYPE_AES == key_type) {
1150
0
    if (exdata->bFipsCertification) {
1151
0
      r = aes128_encrypt_cmac_ft(card, exdata->sk_mac, 128, apdu_buf, data_tlv_len + le_tlv_len + block_size, mac, &icv[0]);
1152
0
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac_ft failed");
1153
0
      memcpy(mac_tlv + 2, &mac[0 /*ulmacLen-16*/], 8);
1154
0
    } else {
1155
0
      if (mac_len < 16)
1156
0
        LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "incorrect mac length");
1157
0
      r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac);
1158
0
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed");
1159
0
      memcpy(mac_tlv + 2, &mac[mac_len - 16], 8);
1160
0
    }
1161
0
  } else {
1162
0
    unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
1163
0
    unsigned char tmp[8] = {0};
1164
0
    if (mac_len < 8)
1165
0
      LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "incorrect mac length");
1166
0
    r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac);
1167
0
    LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc  failed");
1168
0
    r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp);
1169
0
    LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed");
1170
0
    memset(iv, 0x00, sizeof iv);
1171
0
    r = des_encrypt_cbc(card, exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2);
1172
0
    LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed");
1173
0
  }
1174
1175
0
  *mac_tlv_len = 2 + 8;
1176
0
  return 0;
1177
0
}
1178
1179
/* According to GlobalPlatform Card Specification's SCP01
1180
 * encode APDU from
1181
 * CLA INS P1 P2 [Lc] Data [Le]
1182
 * to
1183
 * CLA INS P1 P2 Lc' Data' [Le]
1184
 * where
1185
 * Data'=Data(TLV)+Le(TLV)+MAC(TLV) */
1186
static int
1187
encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm,
1188
    unsigned char *apdu_buf, size_t * apdu_buf_len)
1189
4.19k
{
1190
4.19k
  size_t block_size = 0;
1191
4.19k
  unsigned char dataTLV[4096] = {0};
1192
4.19k
  size_t data_tlv_len = 0;
1193
4.19k
  unsigned char le_tlv[256] = {0};
1194
4.19k
  size_t le_tlv_len = 0;
1195
4.19k
  size_t mac_tlv_len = 10;
1196
4.19k
  size_t tmp_lc = 0;
1197
4.19k
  size_t tmp_le = 0;
1198
4.19k
  unsigned char mac_tlv[256] = {0};
1199
4.19k
  epass2003_exdata *exdata = NULL;
1200
1201
4.19k
  mac_tlv[0] = 0x8E;
1202
4.19k
  mac_tlv[1] = 8;
1203
  /* size_t plain_le = 0; */
1204
4.19k
  if (!card->drv_data)
1205
0
    return SC_ERROR_INVALID_ARGUMENTS;
1206
4.19k
  exdata = (epass2003_exdata*)card->drv_data;
1207
4.19k
  block_size = (KEY_TYPE_DES == exdata->smtype ? 16 : 8);
1208
1209
4.19k
  sm->cse = SC_APDU_CASE_4_SHORT;
1210
4.19k
  apdu_buf[0] = (unsigned char)plain->cla;
1211
4.19k
  apdu_buf[1] = (unsigned char)plain->ins;
1212
4.19k
  apdu_buf[2] = (unsigned char)plain->p1;
1213
4.19k
  apdu_buf[3] = (unsigned char)plain->p2;
1214
  /* plain_le = plain->le; */
1215
  /* padding */
1216
4.19k
  if (exdata->bFipsCertification && plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01) {
1217
0
    apdu_buf[4] = 0x00;
1218
4.19k
  } else {
1219
4.19k
    apdu_buf[4] = 0x80;
1220
4.19k
  }
1221
4.19k
  memset(&apdu_buf[5], 0x00, block_size - 5);
1222
1223
  /* Data -> Data' */
1224
4.19k
  if (plain->lc != 0)
1225
3.82k
    if (0 != construct_data_tlv(card, plain, apdu_buf, dataTLV, &data_tlv_len, exdata->smtype))
1226
0
      return -1;
1227
1228
4.19k
  if (plain->le != 0 || (plain->le == 0 && plain->resplen != 0))
1229
4.15k
    if (0 != construct_le_tlv(plain, apdu_buf, data_tlv_len, le_tlv,
1230
4.15k
             &le_tlv_len, exdata->smtype))
1231
0
      return -1;
1232
1233
4.19k
  if (exdata->bFipsCertification && plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01) {
1234
0
    if (0 != construct_mac_tlv_case1(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype))
1235
0
      return -1;
1236
4.19k
  } else {
1237
4.19k
    if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype))
1238
0
      return -1;
1239
4.19k
  }
1240
1241
4.19k
  memset(apdu_buf + 4, 0, *apdu_buf_len - 4);
1242
4.19k
  sm->lc = sm->datalen = data_tlv_len + le_tlv_len + mac_tlv_len;
1243
4.19k
  if (sm->lc > 0xFF) {
1244
0
    sm->cse = SC_APDU_CASE_4_EXT;
1245
0
    apdu_buf[4] = (unsigned char)((sm->lc) / 0x10000);
1246
0
    apdu_buf[5] = (unsigned char)(((sm->lc) / 0x100) % 0x100);
1247
0
    apdu_buf[6] = (unsigned char)((sm->lc) % 0x100);
1248
0
    tmp_lc = 3;
1249
4.19k
  } else {
1250
4.19k
    apdu_buf[4] = (unsigned char)sm->lc;
1251
4.19k
    tmp_lc = 1;
1252
4.19k
  }
1253
1254
4.19k
  memcpy(apdu_buf + 4 + tmp_lc, dataTLV, data_tlv_len);
1255
4.19k
  memcpy(apdu_buf + 4 + tmp_lc + data_tlv_len, le_tlv, le_tlv_len);
1256
4.19k
  memcpy(apdu_buf + 4 + tmp_lc + data_tlv_len + le_tlv_len, mac_tlv, mac_tlv_len);
1257
4.19k
  memcpy((unsigned char *)sm->data, apdu_buf + 4 + tmp_lc, sm->datalen);
1258
4.19k
  *apdu_buf_len = 0;
1259
1260
4.19k
  if (4 == le_tlv_len) {
1261
58
    sm->cse = SC_APDU_CASE_4_EXT;
1262
58
    *(apdu_buf + 4 + tmp_lc + sm->lc) = (unsigned char)(plain->le / 0x100);
1263
58
    *(apdu_buf + 4 + tmp_lc + sm->lc + 1) = (unsigned char)(plain->le % 0x100);
1264
58
    tmp_le = 2;
1265
4.13k
  } else if (3 == le_tlv_len) {
1266
4.09k
    *(apdu_buf + 4 + tmp_lc + sm->lc) = (unsigned char)plain->le;
1267
4.09k
    tmp_le = 1;
1268
4.09k
  }
1269
1270
4.19k
  *apdu_buf_len += 4 + tmp_lc + data_tlv_len + le_tlv_len + mac_tlv_len + tmp_le;
1271
  /* sm->le = calc_le(plain_le); */
1272
4.19k
  return 0;
1273
4.19k
}
1274
1275
1276
static int
1277
epass2003_sm_wrap_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm)
1278
13.3k
{
1279
13.3k
  unsigned char buf[4096] = {0}; /* APDU buffer */
1280
13.3k
  size_t buf_len = sizeof(buf);
1281
13.3k
  epass2003_exdata *exdata = NULL;
1282
1283
13.3k
  if (!card->drv_data)
1284
0
    return SC_ERROR_INVALID_ARGUMENTS;
1285
1286
13.3k
  exdata = (epass2003_exdata *)card->drv_data;
1287
1288
13.3k
  LOG_FUNC_CALLED(card->ctx);
1289
1290
13.3k
  if (exdata->sm)
1291
4.19k
    plain->cla |= 0x0C;
1292
1293
13.3k
  sm->cse = plain->cse;
1294
13.3k
  sm->cla = plain->cla;
1295
13.3k
  sm->ins = plain->ins;
1296
13.3k
  sm->p1 = plain->p1;
1297
13.3k
  sm->p2 = plain->p2;
1298
13.3k
  sm->lc = plain->lc;
1299
13.3k
  sm->le = plain->le;
1300
13.3k
  sm->control = plain->control;
1301
13.3k
  sm->flags = plain->flags;
1302
1303
13.3k
  switch (sm->cla & 0x0C) {
1304
9.18k
  case 0x00:
1305
9.18k
  case 0x04:
1306
9.18k
    sm->datalen = plain->datalen;
1307
9.18k
    memcpy((void *)sm->data, plain->data, plain->datalen);
1308
9.18k
    sm->resplen = plain->resplen;
1309
9.18k
    memcpy(sm->resp, plain->resp, plain->resplen);
1310
9.18k
    break;
1311
4.19k
  case 0x0C:
1312
4.19k
    memset(buf, 0, sizeof(buf));
1313
4.19k
    if (0 != encode_apdu(card, plain, sm, buf, &buf_len))
1314
0
      return SC_ERROR_CARD_CMD_FAILED;
1315
4.19k
    break;
1316
4.19k
  default:
1317
0
    return SC_ERROR_INCORRECT_PARAMETERS;
1318
13.3k
  }
1319
1320
13.3k
  return SC_SUCCESS;
1321
13.3k
}
1322
1323
static int
1324
epass2003_check_response_mac_and_sw(struct sc_card *card, struct sc_apdu *sm)
1325
4.19k
{
1326
4.19k
  unsigned char iv[16];
1327
4.19k
  unsigned char *data = NULL, *mac = NULL;
1328
4.19k
  size_t blocksize, mac_len;
1329
4.19k
  int ret = -1;
1330
4.19k
  size_t taglen;
1331
4.19k
  const u8 *tag;
1332
4.19k
  epass2003_exdata *exdata;
1333
4.19k
  unsigned char *in = sm->resp;
1334
4.19k
  unsigned char *alt_in;
1335
4.19k
  size_t inlen = sm->resplen;
1336
4.19k
  size_t len_correction;
1337
1338
  /* card/ctx/drv_data is already checked by caller */
1339
4.19k
  exdata = (epass2003_exdata *)card->drv_data;
1340
1341
  /* The SM must contain at least TLV encoded SW and MAC fields. */
1342
4.19k
  if (inlen < 14 )
1343
3.10k
    return ret;
1344
1345
  /* compare BER-TLV encoded SW (TAG 0x99) and raw SW */
1346
1.09k
  alt_in = in;
1347
1.09k
  tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x99, &taglen);
1348
1.09k
  if (tag == NULL || taglen != 2) {
1349
    /*
1350
     * It seems that the EPASS2003 firmware has some problem with BER-TLV encoding.
1351
     * Instead of (correct) TLV 87 81 81 [01 .. ..] incorrect TLV 87 81 [01 .. ..]
1352
     * is returned. There seems to be some proprietary fix for the faulty encoding
1353
     * in the decrypt_response() function, similar fix here:
1354
     */
1355
558
    if (0x01 == in[2] && 0x82 != in[1]) {
1356
341
      sc_log(card->ctx, "Workaround, wrong BER-TLV ?");
1357
341
      len_correction = in[1] + 2;
1358
341
      if (inlen < len_correction)
1359
69
        return ret;
1360
272
      inlen -= len_correction;
1361
272
      alt_in += len_correction;
1362
272
      tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x99, &taglen);
1363
272
      if (tag == NULL || taglen != 2)
1364
233
        return ret;
1365
272
    } else {
1366
217
      return ret;
1367
217
    }
1368
558
  }
1369
571
  if (sm->sw1 != tag[0] || sm->sw2 != tag[1])
1370
130
    return ret;
1371
1372
  /* no documentation/real hardware to test, the response is accepted without MAC check */
1373
441
  if (exdata->bFipsCertification) {
1374
314
    sc_log(card->ctx, "Warning, MAC is not checked");
1375
314
    return 0;
1376
314
  }
1377
127
  tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x8e, &taglen);
1378
127
  if (tag == NULL || taglen != 8)
1379
40
    return ret;
1380
1381
87
  if (KEY_TYPE_AES == exdata->smtype)
1382
6
    blocksize = 16;
1383
81
  else
1384
81
    blocksize = 8;
1385
1386
87
  mac_len = tag - in - 2;
1387
87
  if (NULL == (data = calloc(1, mac_len + blocksize)))
1388
0
    goto end;
1389
87
  if (NULL == (mac = malloc(mac_len + blocksize)))
1390
0
    goto end;
1391
1392
  /* copy response to buffer and append padding */
1393
87
  memcpy(data, in, mac_len);
1394
87
  data[mac_len++] = 0x80;
1395
1396
87
  if (mac_len % blocksize)
1397
78
    mac_len += (blocksize - (mac_len % blocksize));
1398
1399
  /* calculate MAC */
1400
87
  memcpy(iv, exdata->icv_mac, blocksize);
1401
1402
87
  if (KEY_TYPE_AES == exdata->smtype) {
1403
6
    if (aes128_encrypt_cbc(card, exdata->sk_mac, 16, iv, data, mac_len, mac))
1404
0
      goto end;
1405
81
  } else {
1406
81
    uint8_t tmp[8];
1407
81
    uint8_t iv0[EVP_MAX_IV_LENGTH];
1408
81
    if (des_encrypt_cbc(card, exdata->sk_mac, 8, iv, data, mac_len, mac))
1409
0
      goto end;
1410
81
    memset(iv0, 0, EVP_MAX_IV_LENGTH);
1411
81
    if (des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv0, &mac[mac_len - 8], 8, tmp))
1412
0
      goto end;
1413
81
    memset(iv0, 0, EVP_MAX_IV_LENGTH);
1414
81
    if (des_encrypt_cbc(card, exdata->sk_mac, 8, iv0, tmp, 8, &mac[mac_len - 8]))
1415
0
      goto end;
1416
81
  }
1417
  /* compare MAC */
1418
87
  if (!memcmp(tag, mac + mac_len - blocksize, 8))
1419
21
    ret = 0;
1420
87
end:
1421
87
  if (data)
1422
87
    free(data);
1423
87
  if (mac)
1424
87
    free(mac);
1425
87
  return ret;
1426
87
}
1427
1428
/* According to GlobalPlatform Card Specification's SCP01
1429
 * decrypt APDU response from
1430
 * ResponseData' SW1 SW2
1431
 * to
1432
 * ResponseData SW1 SW2
1433
 * where
1434
 * ResponseData'=Data(TLV)+SW12(TLV)+MAC(TLV)
1435
 * where
1436
 * Data(TLV)=0x87|L|Cipher
1437
 * SW12(TLV)=0x99|0x02|SW1+SW2
1438
 * MAC(TLV)=0x8e|0x08|MAC */
1439
static int
1440
decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned char *out, size_t * out_len)
1441
295
{
1442
295
  size_t cipher_len;
1443
295
  size_t i;
1444
295
  unsigned char iv[16] = {0};
1445
295
  unsigned char plaintext[4096] = {0};
1446
295
  epass2003_exdata *exdata = NULL;
1447
1448
295
  if (!card->drv_data)
1449
0
    return SC_ERROR_INVALID_ARGUMENTS;
1450
1451
295
  exdata = (epass2003_exdata *)card->drv_data;
1452
1453
  /* no cipher */
1454
295
  if (in[0] == 0x99)
1455
48
    return 0;
1456
1457
  /* parse cipher length */
1458
247
  if (0x01 == in[2] && 0x82 != in[1]) {
1459
130
    cipher_len = in[1];
1460
130
    i = 3;
1461
130
  } else if (0x01 == in[3] && 0x81 == in[1]) {
1462
10
    cipher_len = in[2];
1463
10
    i = 4;
1464
107
  } else if (0x01 == in[4] && 0x82 == in[1]) {
1465
87
    cipher_len = in[2] * 0x100;
1466
87
    cipher_len += in[3];
1467
87
    i = 5;
1468
87
  } else {
1469
20
    return -1;
1470
20
  }
1471
1472
227
  if (cipher_len < 2 || i + cipher_len > inlen || cipher_len > sizeof plaintext)
1473
86
    return -1;
1474
1475
  /* decrypt */
1476
141
  if (KEY_TYPE_AES == exdata->smtype)
1477
141
    aes128_decrypt_cbc(card, exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext);
1478
0
  else
1479
0
    des3_decrypt_cbc(card, exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext);
1480
1481
  /* unpadding */
1482
11.6k
  while (0x80 != plaintext[cipher_len - 2] && (cipher_len > 2))
1483
11.4k
    cipher_len--;
1484
1485
141
  if (2 == cipher_len || *out_len < cipher_len - 2)
1486
76
    return -1;
1487
1488
65
  memcpy(out, plaintext, cipher_len - 2);
1489
65
  *out_len = cipher_len - 2;
1490
65
  return 0;
1491
141
}
1492
1493
1494
static int
1495
epass2003_sm_unwrap_apdu(struct sc_card *card, struct sc_apdu *sm, struct sc_apdu *plain)
1496
13.3k
{
1497
13.3k
  int r;
1498
13.3k
  size_t len = 0;
1499
13.3k
  epass2003_exdata *exdata = NULL;
1500
1501
13.3k
  if (!card->drv_data)
1502
0
    return SC_ERROR_INVALID_ARGUMENTS;
1503
1504
13.3k
  exdata = (epass2003_exdata *)card->drv_data;
1505
1506
13.3k
  LOG_FUNC_CALLED(card->ctx);
1507
1508
  /* verify MAC, and check if SW1,2 match SW1,2 encapsulated in SM */
1509
13.3k
  if (exdata->sm) {
1510
4.19k
    if (epass2003_check_response_mac_and_sw(card, sm)) {
1511
3.85k
      sc_log(card->ctx, "MAC or SW incorrect");
1512
3.85k
      return SC_ERROR_CARD_CMD_FAILED;
1513
3.85k
    }
1514
4.19k
  }
1515
9.51k
  r = sc_check_sw(card, sm->sw1, sm->sw2);
1516
9.51k
  if (r == SC_SUCCESS) {
1517
6.70k
    if (exdata->sm) {
1518
295
      len = plain->resplen;
1519
295
      if (0 != decrypt_response(card, sm->resp, sm->resplen, plain->resp, &len))
1520
182
        return SC_ERROR_CARD_CMD_FAILED;
1521
6.41k
    } else {
1522
6.41k
      memcpy(plain->resp, sm->resp, sm->resplen);
1523
6.41k
      len = sm->resplen;
1524
6.41k
    }
1525
6.70k
  }
1526
1527
9.33k
  plain->resplen = len;
1528
9.33k
  plain->sw1 = sm->sw1;
1529
9.33k
  plain->sw2 = sm->sw2;
1530
1531
9.33k
  sc_log(card->ctx,
1532
9.33k
         "unwrapped APDU: resplen %"SC_FORMAT_LEN_SIZE_T"u, SW %02X%02X",
1533
9.33k
         plain->resplen, plain->sw1, plain->sw2);
1534
9.33k
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1535
9.33k
}
1536
1537
1538
static int
1539
epass2003_sm_free_wrapped_apdu(struct sc_card *card,
1540
    struct sc_apdu *plain, struct sc_apdu **sm_apdu)
1541
13.3k
{
1542
13.3k
  struct sc_context *ctx = card->ctx;
1543
13.3k
  int rv = SC_SUCCESS;
1544
1545
13.3k
  LOG_FUNC_CALLED(ctx);
1546
13.3k
  if (!sm_apdu)
1547
13.3k
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1548
13.3k
  if (!(*sm_apdu))
1549
13.3k
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1550
1551
1552
13.3k
  if (plain)
1553
13.3k
    rv = epass2003_sm_unwrap_apdu(card, *sm_apdu, plain);
1554
1555
13.3k
  if ((*sm_apdu)->data) {
1556
13.3k
    unsigned char * p = (unsigned char *)((*sm_apdu)->data);
1557
13.3k
    free(p);
1558
13.3k
  }
1559
13.3k
  if ((*sm_apdu)->resp) {
1560
13.3k
    free((*sm_apdu)->resp);
1561
13.3k
  }
1562
1563
13.3k
  free(*sm_apdu);
1564
13.3k
  *sm_apdu = NULL;
1565
1566
13.3k
  LOG_FUNC_RETURN(ctx, rv);
1567
13.3k
}
1568
1569
1570
static int
1571
epass2003_sm_get_wrapped_apdu(struct sc_card *card,
1572
    struct sc_apdu *plain, struct sc_apdu **sm_apdu)
1573
13.3k
{
1574
13.3k
  struct sc_context *ctx = card->ctx;
1575
13.3k
  struct sc_apdu *apdu = NULL;
1576
13.3k
  int rv;
1577
1578
13.3k
  LOG_FUNC_CALLED(ctx);
1579
13.3k
  if (!plain || !sm_apdu)
1580
13.3k
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1581
1582
13.3k
  *sm_apdu = NULL;
1583
  //construct new SM apdu from original apdu
1584
13.3k
  apdu = calloc(1, sizeof(struct sc_apdu));
1585
13.3k
  if (!apdu) {
1586
0
    rv = SC_ERROR_OUT_OF_MEMORY;
1587
0
    goto err;
1588
0
  }
1589
13.3k
  apdu->data = calloc (1, SC_MAX_EXT_APDU_BUFFER_SIZE);
1590
13.3k
  if (!apdu->data) {
1591
0
    rv = SC_ERROR_OUT_OF_MEMORY;
1592
0
    goto err;
1593
0
  }
1594
13.3k
  apdu->resp = calloc (1, SC_MAX_EXT_APDU_BUFFER_SIZE);
1595
13.3k
  if (!apdu->resp) {
1596
0
    rv = SC_ERROR_OUT_OF_MEMORY;
1597
0
    goto err;
1598
0
  }
1599
13.3k
  apdu->datalen = SC_MAX_EXT_APDU_BUFFER_SIZE;
1600
13.3k
  apdu->resplen = SC_MAX_EXT_APDU_BUFFER_SIZE;
1601
1602
13.3k
  rv = epass2003_sm_wrap_apdu(card, plain, apdu);
1603
13.3k
  if (rv) {
1604
0
    rv = epass2003_sm_free_wrapped_apdu(card, NULL, &apdu);
1605
0
    if (rv < 0)
1606
0
      goto err;
1607
0
  }
1608
1609
13.3k
  *sm_apdu = apdu;
1610
13.3k
  apdu = NULL;
1611
13.3k
err:
1612
13.3k
  if (apdu) {
1613
0
    free((unsigned char *) apdu->data);
1614
0
    free(apdu->resp);
1615
0
    free(apdu);
1616
0
    apdu = NULL;
1617
0
  }
1618
13.3k
  LOG_FUNC_RETURN(ctx, rv);
1619
13.3k
}
1620
1621
1622
static int
1623
epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu)
1624
4.04k
{
1625
4.04k
  int r;
1626
1627
4.04k
  LOG_FUNC_CALLED(card->ctx);
1628
1629
4.04k
  r = sc_transmit_apdu_t(card, apdu);
1630
4.04k
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1631
1632
3.95k
  return r;
1633
4.04k
}
1634
1635
1636
static int
1637
get_data(struct sc_card *card, unsigned char type, unsigned char *data, size_t datalen)
1638
4.67k
{
1639
4.67k
  int r;
1640
4.67k
  struct sc_apdu apdu;
1641
4.67k
  unsigned char resp[SC_MAX_APDU_BUFFER_SIZE] = {0};
1642
4.67k
  size_t resplen = SC_MAX_APDU_BUFFER_SIZE;
1643
4.67k
  epass2003_exdata *exdata = NULL;
1644
1645
4.67k
  if (!card->drv_data)
1646
0
    return SC_ERROR_INVALID_ARGUMENTS;
1647
1648
4.67k
  exdata = (epass2003_exdata *)card->drv_data;
1649
1650
4.67k
  LOG_FUNC_CALLED(card->ctx);
1651
1652
4.67k
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, type);
1653
4.67k
  apdu.resp = resp;
1654
4.67k
  apdu.le = 0;
1655
4.67k
  apdu.resplen = resplen;
1656
4.67k
  if (0x86 == type) {
1657
    /* No SM temporarily */
1658
4.36k
    unsigned char tmp_sm = exdata->sm;
1659
4.36k
    exdata->sm = SM_PLAIN;
1660
4.36k
    r = sc_transmit_apdu(card, &apdu);
1661
4.36k
    exdata->sm = tmp_sm;
1662
4.36k
  } else {
1663
309
    r = sc_transmit_apdu_t(card, &apdu);
1664
309
  }
1665
4.67k
  LOG_TEST_RET(card->ctx, r, "APDU get_data failed");
1666
4.62k
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1667
4.62k
  LOG_TEST_RET(card->ctx, r, "get_data failed");
1668
1669
4.31k
  memcpy(data, resp, datalen);
1670
4.31k
  return r;
1671
4.62k
}
1672
1673
/* card driver functions */
1674
1675
static int epass2003_match_card(struct sc_card *card)
1676
65.4k
{
1677
65.4k
  int r;
1678
1679
65.4k
  LOG_FUNC_CALLED(card->ctx);
1680
65.4k
  r = _sc_match_atr(card, epass2003_atrs, &card->type);
1681
65.4k
  if (r < 0)
1682
61.1k
    return 0;
1683
1684
4.36k
  return 1;
1685
65.4k
}
1686
1687
1688
static int
1689
epass2003_init(struct sc_card *card)
1690
4.36k
{
1691
4.36k
  unsigned int flags;
1692
4.36k
  unsigned int ext_flags;
1693
4.36k
  unsigned char data[SC_MAX_APDU_BUFFER_SIZE] = {0};
1694
4.36k
  size_t datalen = SC_MAX_APDU_BUFFER_SIZE;
1695
4.36k
  epass2003_exdata *exdata = NULL;
1696
4.36k
  void *old_drv_data = card->drv_data;
1697
1698
4.36k
  LOG_FUNC_CALLED(card->ctx);
1699
1700
4.36k
  card->name = "epass2003";
1701
4.36k
  card->cla = 0x00;
1702
4.36k
  exdata = (epass2003_exdata *)calloc(1, sizeof(epass2003_exdata));
1703
4.36k
  if (!exdata)
1704
0
    return SC_ERROR_OUT_OF_MEMORY;
1705
1706
4.36k
  card->drv_data = exdata;
1707
1708
4.36k
  exdata->sm = SM_SCP01;
1709
1710
  /* decide FIPS/Non-FIPS mode */
1711
4.36k
  if (SC_SUCCESS != get_data(card, 0x86, data, datalen)) {
1712
143
    free(exdata);
1713
143
    card->drv_data = old_drv_data;
1714
143
    return SC_ERROR_INVALID_CARD;
1715
143
  }
1716
1717
4.21k
  if (memcmp(&data[32], "\x87\x01\x01", 3) == 0 && memcmp(&data[0], "\x80\x01\x01", 3) == 0) {
1718
321
    exdata->bFipsCertification = 0x01;
1719
3.89k
  } else {
1720
3.89k
    exdata->bFipsCertification = 0x00;
1721
3.89k
  }
1722
1723
4.21k
  if (0x01 == data[2])
1724
470
    exdata->smtype = KEY_TYPE_AES;
1725
3.74k
  else
1726
3.74k
    exdata->smtype = KEY_TYPE_DES;
1727
1728
4.21k
  if (0x84 == data[14]) {
1729
747
    if (0x00 == data[16]) {
1730
727
      exdata->sm = SM_PLAIN;
1731
727
    }
1732
747
  }
1733
1734
  /* mutual authentication */
1735
4.21k
  card->max_recv_size = 0xD8;
1736
4.21k
  card->max_send_size = 0xE8;
1737
1738
4.21k
  card->sm_ctx.ops.open = epass2003_refresh;
1739
4.21k
  card->sm_ctx.ops.get_sm_apdu = epass2003_sm_get_wrapped_apdu;
1740
4.21k
  card->sm_ctx.ops.free_sm_apdu = epass2003_sm_free_wrapped_apdu;
1741
1742
  /* FIXME (VT): rather then set/unset 'g_sm', better to implement filter for APDUs to be wrapped */
1743
4.21k
  epass2003_refresh(card);
1744
1745
4.21k
  card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
1746
1747
4.21k
  flags = SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE;
1748
1749
4.21k
  _sc_card_add_rsa_alg(card, 512, flags, 0);
1750
4.21k
  _sc_card_add_rsa_alg(card, 768, flags, 0);
1751
4.21k
  _sc_card_add_rsa_alg(card, 1024, flags, 0);
1752
4.21k
  _sc_card_add_rsa_alg(card, 2048, flags, 0);
1753
1754
  //set EC Alg Flags
1755
4.21k
  flags = SC_ALGORITHM_ONBOARD_KEY_GEN|SC_ALGORITHM_ECDSA_HASH_SHA1|SC_ALGORITHM_ECDSA_HASH_SHA256|SC_ALGORITHM_ECDSA_HASH_NONE|SC_ALGORITHM_ECDSA_RAW;
1756
4.21k
  ext_flags = 0;
1757
4.21k
  _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
1758
1759
4.21k
  card->caps = SC_CARD_CAP_RNG | SC_CARD_CAP_APDU_EXT;
1760
1761
4.21k
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1762
4.21k
}
1763
1764
static int
1765
epass2003_finish(sc_card_t *card)
1766
4.21k
{
1767
4.21k
  epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
1768
1769
4.21k
  if (exdata)
1770
4.21k
    free(exdata);
1771
4.21k
  return SC_SUCCESS;
1772
4.21k
}
1773
1774
/* COS implement SFI as lower 5 bits of FID, and not allow same SFI at the
1775
 * same DF, so use hook functions to increase/decrease FID by 0x20 */
1776
static int
1777
epass2003_hook_path(struct sc_path *path, int inc)
1778
24.2k
{
1779
24.2k
  u8 fid_h = 0;
1780
24.2k
  u8 fid_l = 0;
1781
1782
24.2k
  if (!path || path->len < 2)
1783
83
    return -1;
1784
24.1k
  fid_h = path->value[path->len - 2];
1785
24.1k
  fid_l = path->value[path->len - 1];
1786
1787
24.1k
  switch (fid_h) {
1788
1.65k
  case 0x29:
1789
1.78k
  case 0x30:
1790
1.93k
  case 0x31:
1791
2.08k
  case 0x32:
1792
2.21k
  case 0x33:
1793
2.36k
  case 0x34:
1794
2.36k
    if (inc)
1795
1.28k
      fid_l = fid_l * FID_STEP;
1796
1.07k
    else
1797
1.07k
      fid_l = fid_l / FID_STEP;
1798
2.36k
    path->value[path->len - 1] = fid_l;
1799
2.36k
    return 1;
1800
21.7k
  default:
1801
21.7k
    break;
1802
24.1k
  }
1803
21.7k
  return 0;
1804
24.1k
}
1805
1806
1807
static int
1808
epass2003_hook_file(struct sc_file *file, int inc)
1809
6.67k
{
1810
6.67k
  int fidl = file->id & 0xff;
1811
6.67k
  int fidh = file->id & 0xff00;
1812
6.67k
  int rv = 0;
1813
1814
6.67k
  rv = epass2003_hook_path(&file->path, inc);
1815
1816
6.67k
  if (rv > 0) {
1817
1.18k
    if (inc)
1818
114
      file->id = fidh + fidl * FID_STEP;
1819
1.07k
    else
1820
1.07k
      file->id = fidh + fidl / FID_STEP;
1821
1.18k
  }
1822
6.67k
  if (rv < 0)
1823
83
    return rv;
1824
6.59k
  return SC_SUCCESS;
1825
6.67k
}
1826
1827
1828
static int
1829
epass2003_select_fid_(struct sc_card *card, sc_path_t * in_path, sc_file_t ** file_out)
1830
17.4k
{
1831
17.4k
  struct sc_apdu apdu;
1832
17.4k
  u8 buf[SC_MAX_APDU_BUFFER_SIZE] = {0};
1833
17.4k
  u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
1834
17.4k
  int r;
1835
17.4k
  size_t pathlen;
1836
17.4k
  sc_file_t *file = NULL;
1837
1838
17.4k
  r = epass2003_hook_path(in_path, 1);
1839
17.4k
  LOG_TEST_RET(card->ctx, r, "Can not hook path");
1840
1841
17.4k
  memcpy(path, in_path->value, in_path->len);
1842
17.4k
  pathlen = in_path->len;
1843
1844
17.4k
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x00);
1845
1846
17.4k
  switch (in_path->type) {
1847
17.4k
  case SC_PATH_TYPE_FILE_ID:
1848
17.4k
    apdu.p1 = 0;
1849
17.4k
    if (pathlen != 2)
1850
0
      return SC_ERROR_INVALID_ARGUMENTS;
1851
17.4k
    break;
1852
17.4k
  default:
1853
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1854
17.4k
  }
1855
17.4k
  apdu.p2 = 0;    /* first record, return FCI */
1856
17.4k
  apdu.lc = pathlen;
1857
17.4k
  apdu.data = path;
1858
17.4k
  apdu.datalen = pathlen;
1859
1860
17.4k
  if (file_out != NULL) {
1861
17.4k
    apdu.resp = buf;
1862
17.4k
    apdu.resplen = sizeof(buf);
1863
17.4k
    apdu.le = 0;
1864
17.4k
  } else {
1865
0
    apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT;
1866
0
  }
1867
1868
17.4k
  if (path[0] == 0x29) { /* TODO:0x29 accords with FID prefix in profile  */
1869
    /* Not allowed to select private key file, so fake fci. */
1870
    /* 62 16 82 02 11 00 83 02 29 00 85 02 08 00 86 08 FF 90 90 90 FF FF FF FF */
1871
741
    apdu.resplen = 0x18;
1872
741
    memcpy(apdu.resp,
1873
741
           "\x6f\x16\x82\x02\x11\x00\x83\x02\x29\x00\x85\x02\x08\x00\x86\x08\xff\x90\x90\x90\xff\xff\xff\xff",
1874
741
           apdu.resplen);
1875
741
    apdu.resp[9] = path[1];
1876
741
    apdu.sw1 = 0x90;
1877
741
    apdu.sw2 = 0x00;
1878
741
  }
1879
16.7k
  else {
1880
16.7k
    r = sc_transmit_apdu_t(card, &apdu);
1881
16.7k
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1882
16.7k
  }
1883
1884
13.7k
  if (file_out == NULL) {
1885
0
    if (apdu.sw1 == 0x61)
1886
0
      LOG_FUNC_RETURN(card->ctx, 0);
1887
0
    LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
1888
0
  }
1889
1890
13.7k
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1891
13.7k
  if (r)
1892
13.7k
    LOG_FUNC_RETURN(card->ctx, r);
1893
6.87k
  if (apdu.resplen < 2)
1894
6.87k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1895
1896
6.33k
  switch (apdu.resp[0]) {
1897
6.05k
  case 0x6F:
1898
6.05k
    file = sc_file_new();
1899
6.05k
    if (file == NULL)
1900
6.05k
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1901
6.05k
    file->path = *in_path;
1902
6.05k
    if (card->ops->process_fci == NULL) {
1903
0
      sc_file_free(file);
1904
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1905
0
    }
1906
1907
6.05k
    if ((size_t) apdu.resp[1] + 2 <= apdu.resplen)
1908
5.06k
      card->ops->process_fci(card, file, apdu.resp + 2, apdu.resp[1]);
1909
6.05k
    epass2003_hook_file(file, 0);
1910
6.05k
    *file_out = file;
1911
6.05k
    break;
1912
96
  case 0x00:    /* proprietary coding */
1913
96
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1914
0
    break;
1915
180
  default:
1916
180
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1917
6.33k
  }
1918
6.05k
  return 0;
1919
6.33k
}
1920
1921
1922
static int
1923
epass2003_select_fid(struct sc_card *card, unsigned int id_hi, unsigned int id_lo,
1924
    sc_file_t ** file_out)
1925
17.4k
{
1926
17.4k
  int r;
1927
17.4k
  sc_file_t *file = NULL;
1928
17.4k
  sc_path_t path;
1929
1930
17.4k
  memset(&path, 0, sizeof(path));
1931
17.4k
  path.type = SC_PATH_TYPE_FILE_ID;
1932
17.4k
  path.value[0] = id_hi;
1933
17.4k
  path.value[1] = id_lo;
1934
17.4k
  path.len = 2;
1935
1936
17.4k
  r = epass2003_select_fid_(card, &path, &file);
1937
17.4k
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1938
1939
6.05k
  if (file_out) {
1940
1.31k
    *file_out = file;
1941
4.74k
  } else {
1942
4.74k
    sc_file_free(file);
1943
4.74k
  }
1944
1945
6.05k
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1946
6.05k
}
1947
1948
1949
static int
1950
epass2003_select_aid(struct sc_card *card, const sc_path_t * in_path, sc_file_t ** file_out)
1951
7.83k
{
1952
7.83k
  int r = 0;
1953
1954
7.83k
  r = iso_ops->select_file(card, in_path, file_out);
1955
7.83k
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1956
1957
1.04k
  if (file_out) {
1958
75
    sc_file_t *file = *file_out;
1959
1960
75
    file->type = SC_FILE_TYPE_DF;
1961
75
    file->ef_structure = SC_FILE_EF_UNKNOWN;
1962
75
    file->path.len = 0;
1963
75
    file->size = 0;
1964
    /* AID */
1965
75
    memcpy(file->name, in_path->value, in_path->len);
1966
75
    file->namelen = in_path->len;
1967
75
    file->id = 0x0000;
1968
75
  }
1969
1970
1.04k
  LOG_FUNC_RETURN(card->ctx, r);
1971
1.04k
}
1972
1973
1974
static int
1975
epass2003_select_path(struct sc_card *card, const u8 pathbuf[16], const size_t len,
1976
    sc_file_t ** file_out)
1977
13.4k
{
1978
13.4k
  u8 n_pathbuf[SC_MAX_PATH_SIZE];
1979
13.4k
  const u8 *path = pathbuf;
1980
13.4k
  size_t pathlen = len;
1981
13.4k
  unsigned int i;
1982
13.4k
  int r;
1983
1984
13.4k
  if (pathlen % 2 != 0 || pathlen > 6 || pathlen <= 0)
1985
13.4k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1986
1987
  /* if pathlen == 6 then the first FID must be MF (== 3F00) */
1988
13.3k
  if (pathlen == 6 && (path[0] != 0x3f || path[1] != 0x00))
1989
13.3k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1990
1991
  /* unify path (the first FID should be MF) */
1992
13.2k
  if (path[0] != 0x3f || path[1] != 0x00) {
1993
1.20k
    n_pathbuf[0] = 0x3f;
1994
1.20k
    n_pathbuf[1] = 0x00;
1995
1.20k
    memcpy(n_pathbuf + 2, path, pathlen);
1996
1.20k
    path = n_pathbuf;
1997
1.20k
    pathlen += 2;
1998
1.20k
  }
1999
2000
17.0k
  for (i = 0; i < pathlen - 2; i += 2) {
2001
13.8k
    r = epass2003_select_fid(card, path[i], path[i + 1], NULL);
2002
13.8k
    LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed");
2003
13.8k
  }
2004
2005
3.21k
  return epass2003_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out);
2006
13.2k
}
2007
2008
2009
static int
2010
epass2003_select_file(struct sc_card *card, const sc_path_t * in_path,
2011
    sc_file_t ** file_out)
2012
21.9k
{
2013
21.9k
  LOG_FUNC_CALLED(card->ctx);
2014
2015
21.9k
  switch (in_path->type) {
2016
718
  case SC_PATH_TYPE_FILE_ID:
2017
718
    if (in_path->len != 2)
2018
718
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2019
404
    return epass2003_select_fid(card, in_path->value[0], in_path->value[1], file_out);
2020
7.83k
  case SC_PATH_TYPE_DF_NAME:
2021
7.83k
    return epass2003_select_aid(card, in_path, file_out);
2022
13.4k
  case SC_PATH_TYPE_PATH:
2023
13.4k
    return epass2003_select_path(card, in_path->value, in_path->len, file_out);
2024
0
  default:
2025
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2026
21.9k
  }
2027
21.9k
}
2028
2029
static int
2030
epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env, int se_num)
2031
0
{
2032
0
  struct sc_apdu apdu;
2033
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
2034
0
  u8 *p;
2035
0
  unsigned short fid = 0;
2036
0
  int r, locked = 0;
2037
0
  epass2003_exdata *exdata = NULL;
2038
2039
0
  if (!card->drv_data)
2040
0
    return SC_ERROR_INVALID_ARGUMENTS;
2041
2042
0
  exdata = (epass2003_exdata *)card->drv_data;
2043
2044
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0);
2045
2046
0
  p = sbuf;
2047
0
  *p++ = 0x80;    /* algorithm reference */
2048
0
  *p++ = 0x01;
2049
0
  *p++ = 0x84;
2050
2051
0
  *p++ = 0x81;
2052
0
  *p++ = 0x02;
2053
2054
0
  fid = 0x2900;
2055
0
  fid += (unsigned short)(0x20 * (env->key_ref[0] & 0xff));
2056
0
  *p++ = fid >> 8;
2057
0
  *p++ = fid & 0xff;
2058
0
  r = (int)(p - sbuf);
2059
0
  apdu.lc = r;
2060
0
  apdu.datalen = r;
2061
0
  apdu.data = sbuf;
2062
2063
0
  if (env->algorithm == SC_ALGORITHM_EC) {
2064
0
    apdu.p2 = 0xB6;
2065
0
    exdata->currAlg = SC_ALGORITHM_EC;
2066
0
    if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1) {
2067
0
      sbuf[2] = 0x91;
2068
0
      exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA1;
2069
0
    } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256) {
2070
0
      sbuf[2] = 0x92;
2071
0
      exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA256;
2072
0
    } else {
2073
0
      sbuf[2] = 0x92;
2074
0
      exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_NONE;
2075
0
    }
2076
0
  } else if (env->algorithm == SC_ALGORITHM_RSA) {
2077
0
    exdata->currAlg = SC_ALGORITHM_RSA;
2078
0
    apdu.p2 = 0xB8;
2079
0
    sc_log(card->ctx, "setenv RSA Algorithm alg_flags = %0lx\n", env->algorithm_flags);
2080
0
  } else {
2081
0
    sc_log(card->ctx, "%0lx Alg Not Supported!", env->algorithm);
2082
0
  }
2083
2084
0
  if (se_num > 0) {
2085
0
    r = sc_lock(card);
2086
0
    LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
2087
0
    locked = 1;
2088
0
  }
2089
0
  if (apdu.datalen != 0) {
2090
0
    r = sc_transmit_apdu_t(card, &apdu);
2091
0
    if (r) {
2092
0
      sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r));
2093
0
      goto err;
2094
0
    }
2095
2096
0
    r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2097
0
    if (r) {
2098
0
      sc_log(card->ctx, "%s: Card returned error", sc_strerror(r));
2099
0
      goto err;
2100
0
    }
2101
0
  }
2102
0
  if (se_num <= 0)
2103
0
    return 0;
2104
2105
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF2, se_num);
2106
0
  r = sc_transmit_apdu_t(card, &apdu);
2107
0
  sc_unlock(card);
2108
2109
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2110
0
  return sc_check_sw(card, apdu.sw1, apdu.sw2);
2111
2112
0
err:
2113
0
  if (locked)
2114
0
    sc_unlock(card);
2115
0
  return r;
2116
0
}
2117
2118
2119
static int
2120
epass2003_restore_security_env(struct sc_card *card, int se_num)
2121
0
{
2122
0
  LOG_FUNC_CALLED(card->ctx);
2123
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2124
0
}
2125
2126
2127
static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t datalen,
2128
    u8 * out, size_t outlen)
2129
0
{
2130
0
  int r;
2131
0
  struct sc_apdu apdu;
2132
0
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
2133
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
2134
0
  epass2003_exdata *exdata = NULL;
2135
2136
0
  LOG_FUNC_CALLED(card->ctx);
2137
2138
0
  if (!card->drv_data)
2139
0
    return SC_ERROR_INVALID_ARGUMENTS;
2140
2141
0
  exdata = (epass2003_exdata *)card->drv_data;
2142
2143
0
  if (exdata->currAlg == SC_ALGORITHM_EC) {
2144
0
    if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA1) {
2145
0
      r = hash_data(card, data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA1);
2146
0
      LOG_TEST_RET(card->ctx, r, "hash_data failed");
2147
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0x2A, 0x9E, 0x9A);
2148
0
      apdu.data = sbuf;
2149
0
      apdu.lc = 0x14;
2150
0
      apdu.datalen = 0x14;
2151
0
    } else if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA256) {
2152
0
      r = hash_data(card, data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA256);
2153
0
      LOG_TEST_RET(card->ctx, r, "hash_data failed");
2154
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0x2A, 0x9E, 0x9A);
2155
0
      apdu.data = sbuf;
2156
0
      apdu.lc = 0x20;
2157
0
      apdu.datalen = 0x20;
2158
0
    } else if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_NONE) {
2159
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A);
2160
0
      apdu.data = data;
2161
0
      apdu.lc = datalen;
2162
0
      apdu.datalen = datalen;
2163
0
    } else {
2164
0
      return SC_ERROR_NOT_SUPPORTED;
2165
0
    }
2166
0
    apdu.resp = rbuf;
2167
0
    apdu.resplen = sizeof(rbuf);
2168
0
    apdu.le = 0;
2169
2170
0
    r = sc_transmit_apdu_t(card, &apdu);
2171
0
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2172
0
    if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
2173
0
      size_t len = apdu.resplen > outlen ? outlen : apdu.resplen;
2174
0
      memcpy(out, apdu.resp, len);
2175
0
      LOG_FUNC_RETURN(card->ctx, (int)len);
2176
0
    }
2177
0
    LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
2178
0
  } else if (exdata->currAlg == SC_ALGORITHM_RSA) {
2179
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86);
2180
0
    apdu.resp = rbuf;
2181
0
    apdu.resplen = sizeof(rbuf);
2182
0
    apdu.le = 0;
2183
2184
0
    memcpy(sbuf, data, datalen);
2185
0
    apdu.data = sbuf;
2186
0
    apdu.lc = datalen;
2187
0
    apdu.datalen = datalen;
2188
0
  } else {
2189
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86);
2190
0
    apdu.resp = rbuf;
2191
0
    apdu.resplen = sizeof(rbuf);
2192
0
    apdu.le = 256;
2193
2194
0
    memcpy(sbuf, data, datalen);
2195
0
    apdu.data = sbuf;
2196
0
    apdu.lc = datalen;
2197
0
    apdu.datalen = datalen;
2198
0
  }
2199
2200
0
  r = sc_transmit_apdu_t(card, &apdu);
2201
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2202
2203
0
  if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
2204
0
    size_t len = apdu.resplen > outlen ? outlen : apdu.resplen;
2205
0
    memcpy(out, apdu.resp, len);
2206
0
    LOG_FUNC_RETURN(card->ctx, (int)len);
2207
0
  }
2208
2209
0
  LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
2210
0
}
2211
2212
2213
static int
2214
acl_to_ac_byte(struct sc_card *card, const struct sc_acl_entry *e)
2215
1.08k
{
2216
1.08k
  if (e == NULL)
2217
0
    return SC_ERROR_OBJECT_NOT_FOUND;
2218
2219
1.08k
  switch (e->method) {
2220
974
  case SC_AC_NONE:
2221
974
    LOG_FUNC_RETURN(card->ctx, EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE);
2222
14
  case SC_AC_NEVER:
2223
14
    LOG_FUNC_RETURN(card->ctx, EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_NOONE);
2224
97
  default:
2225
97
    LOG_FUNC_RETURN(card->ctx, EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER);
2226
1.08k
  }
2227
2228
0
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
2229
0
}
2230
2231
/* Use epass2003 sec_attr to add acl entries */
2232
int
2233
sec_attr_to_entry(struct sc_card *card, sc_file_t *file, int index)
2234
13.7k
{
2235
13.7k
  int i;
2236
13.7k
  int found = 0;
2237
2238
13.7k
  unsigned int method;
2239
13.7k
  unsigned long  keyref;
2240
2241
13.7k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2242
2243
13.7k
  switch (file->sec_attr[index]) {
2244
3.94k
  case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE):
2245
3.94k
    method = SC_AC_NONE;
2246
3.94k
    keyref = SC_AC_KEY_REF_NONE;
2247
3.94k
    break;
2248
1.69k
  case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER):
2249
1.69k
    method = SC_AC_CHV;
2250
1.69k
    keyref = 1;
2251
1.69k
    break;
2252
8.11k
  default:
2253
8.11k
    sc_log(card->ctx, "Unknown value 0x%2.2x in file->sec_attr[%d]", file->sec_attr[index], index);
2254
8.11k
    method = SC_AC_NEVER;
2255
8.11k
    keyref = SC_AC_KEY_REF_NONE;
2256
8.11k
    break;
2257
13.7k
  }
2258
2259
467k
  for (i = 0; i < (int)(sizeof(sec_attr_to_acl_entry) / sizeof(sec_attr_to_acl_entries_t)); i++) {
2260
453k
    const sec_attr_to_acl_entries_t *e = &sec_attr_to_acl_entry[i];
2261
2262
453k
    if (index == e->index && file->type == e->file_type
2263
12.1k
        && file->ef_structure == e->file_ef_structure) {
2264
        /* may add multiple entries */
2265
842
      sc_file_add_acl_entry(file, e->op, method, keyref);
2266
842
      found++;
2267
842
    }
2268
453k
  }
2269
13.7k
  if (found != 1) {
2270
13.3k
    sc_log(card->ctx,"found %d entries ", found);
2271
13.3k
  }
2272
2273
13.7k
  return 0;
2274
13.7k
}
2275
2276
static int
2277
epass2003_process_fci(struct sc_card *card, sc_file_t * file, const u8 * buf, size_t buflen)
2278
5.06k
{
2279
5.06k
  sc_context_t *ctx = card->ctx;
2280
5.06k
  size_t taglen, len = buflen;
2281
5.06k
  const u8 *tag = NULL, *p = buf;
2282
2283
5.06k
  sc_log(ctx, "processing FCI bytes");
2284
5.06k
  tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen);
2285
5.06k
  if (tag != NULL && taglen == 2) {
2286
991
    file->id = (tag[0] << 8) | tag[1];
2287
991
    sc_log(ctx, "  file identifier: 0x%02X%02X", tag[0], tag[1]);
2288
991
  }
2289
2290
5.06k
  tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen);
2291
5.06k
  if (tag != NULL && taglen > 0 && taglen < 3) {
2292
438
    file->size = tag[0];
2293
438
    if (taglen == 2)
2294
355
      file->size = (file->size << 8) + tag[1];
2295
438
    sc_log(ctx, "  bytes in file: %"SC_FORMAT_LEN_SIZE_T"u",
2296
438
         file->size);
2297
438
  }
2298
2299
5.06k
  if (tag == NULL) {
2300
4.43k
    tag = sc_asn1_find_tag(ctx, p, len, 0x81, &taglen);
2301
4.43k
    if (tag != NULL && taglen >= 2) {
2302
172
      int bytes = (tag[0] << 8) + tag[1];
2303
2304
172
      sc_log(ctx, "  bytes in file: %d", bytes);
2305
172
      file->size = bytes;
2306
172
    }
2307
4.43k
  }
2308
2309
5.06k
  tag = sc_asn1_find_tag(ctx, p, len, 0x82, &taglen);
2310
5.06k
  if (tag != NULL) {
2311
2.28k
    if (taglen > 0) {
2312
2.20k
      unsigned char byte = tag[0];
2313
2.20k
      const char *type;
2314
2315
2.20k
      if (byte == 0x38) {
2316
109
        type = "DF";
2317
109
        file->type = SC_FILE_TYPE_DF;
2318
2.09k
      } else if (0x01 <= byte && byte <= 0x07) {
2319
759
        type = "working EF";
2320
759
        file->type = SC_FILE_TYPE_WORKING_EF;
2321
759
        switch (byte) {
2322
158
        case 0x01:
2323
158
          file->ef_structure = SC_FILE_EF_TRANSPARENT;
2324
158
          break;
2325
182
        case 0x02:
2326
182
          file->ef_structure = SC_FILE_EF_LINEAR_FIXED;
2327
182
          break;
2328
227
        case 0x04:
2329
227
          file->ef_structure = SC_FILE_EF_LINEAR_FIXED;
2330
227
          break;
2331
192
        default:
2332
192
          break;
2333
759
        }
2334
2335
1.33k
      } else if (0x10 == byte) {
2336
59
        type = "BSO";
2337
59
        file->type = SC_FILE_TYPE_BSO;
2338
1.27k
      } else if (0x11 <= byte) {
2339
1.14k
        type = "internal EF";
2340
1.14k
        file->type = SC_FILE_TYPE_INTERNAL_EF;
2341
1.14k
        switch (byte) {
2342
798
        case 0x11:
2343
798
          break;
2344
66
        case 0x12:
2345
66
          break;
2346
285
        default:
2347
285
          break;
2348
1.14k
        }
2349
1.14k
      } else {
2350
125
        type = "unknown";
2351
125
        file->type = SC_FILE_TYPE_INTERNAL_EF;
2352
125
      }
2353
2.20k
      sc_log(ctx, "type %s, EF structure %d", type, byte);
2354
2.20k
    }
2355
2.28k
  }
2356
2357
5.06k
  tag = sc_asn1_find_tag(ctx, p, len, 0x84, &taglen);
2358
5.06k
  if (tag != NULL && taglen > 0 && taglen <= 16) {
2359
219
    memcpy(file->name, tag, taglen);
2360
219
    file->namelen = taglen;
2361
2362
219
    sc_log_hex(ctx, "File name", file->name, file->namelen);
2363
219
    if (!file->type)
2364
130
      file->type = SC_FILE_TYPE_DF;
2365
219
  }
2366
2367
5.06k
  tag = sc_asn1_find_tag(ctx, p, len, 0x85, &taglen);
2368
5.06k
  if (tag != NULL && taglen)
2369
922
    sc_file_set_prop_attr(file, tag, taglen);
2370
4.14k
  else
2371
4.14k
    file->prop_attr_len = 0;
2372
2373
5.06k
  tag = sc_asn1_find_tag(ctx, p, len, 0xA5, &taglen);
2374
5.06k
  if (tag != NULL && taglen)
2375
82
    sc_file_set_prop_attr(file, tag, taglen);
2376
2377
5.06k
  tag = sc_asn1_find_tag(ctx, p, len, 0x86, &taglen);
2378
5.06k
  if (tag != NULL && taglen) {
2379
1.45k
    unsigned int i;
2380
1.45k
    sc_file_set_sec_attr(file, tag, taglen);
2381
21.3k
    for (i = 0; i< taglen; i++)
2382
19.9k
      if (tag[i] != 0xff) /* skip unused entries */
2383
13.7k
        sec_attr_to_entry(card, file, i);
2384
1.45k
  }
2385
2386
5.06k
  tag = sc_asn1_find_tag(ctx, p, len, 0x8A, &taglen);
2387
5.06k
  if (tag != NULL && taglen == 1) {
2388
453
    if (tag[0] == 0x01)
2389
103
      file->status = SC_FILE_STATUS_CREATION;
2390
350
    else if (tag[0] == 0x07 || tag[0] == 0x05)
2391
121
      file->status = SC_FILE_STATUS_ACTIVATED;
2392
229
    else if (tag[0] == 0x06 || tag[0] == 0x04)
2393
125
      file->status = SC_FILE_STATUS_INVALIDATED;
2394
453
  }
2395
5.06k
  file->magic = SC_FILE_MAGIC;
2396
2397
5.06k
  return 0;
2398
5.06k
}
2399
2400
2401
static int
2402
epass2003_construct_fci(struct sc_card *card, const sc_file_t * file,
2403
    u8 * out, size_t * outlen)
2404
402
{
2405
402
  u8 *p = out;
2406
402
  u8 buf[64];
2407
402
  unsigned char ops[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2408
402
  int rv;
2409
402
  unsigned ii;
2410
2411
402
  if (*outlen < 2)
2412
0
    return SC_ERROR_BUFFER_TOO_SMALL;
2413
2414
402
  *p++ = 0x62;
2415
402
  p++;
2416
402
  if (file->type == SC_FILE_TYPE_WORKING_EF) {
2417
38
    if (file->ef_structure == SC_FILE_EF_TRANSPARENT) {
2418
35
      buf[0] = (file->size >> 8) & 0xFF;
2419
35
      buf[1] = file->size & 0xFF;
2420
35
      sc_asn1_put_tag(0x80, buf, 2, p, *outlen - (p - out), &p);
2421
35
    }
2422
38
  }
2423
402
  if (file->type == SC_FILE_TYPE_DF) {
2424
23
    buf[0] = 0x38;
2425
23
    buf[1] = 0x00;
2426
23
    sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2427
23
  }
2428
379
  else if (file->type == SC_FILE_TYPE_WORKING_EF) {
2429
38
    buf[0] = file->ef_structure & 7;
2430
38
    if (file->ef_structure == SC_FILE_EF_TRANSPARENT) {
2431
35
      buf[1] = 0x00;
2432
35
      sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2433
35
    } else if (file->ef_structure == SC_FILE_EF_LINEAR_FIXED ||
2434
3
        file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) {
2435
0
      buf[1] = 0x00;
2436
0
      buf[2] = 0x00;
2437
0
      buf[3] = 0x40;  /* record length */
2438
0
      buf[4] = 0x00;  /* record count */
2439
0
      sc_asn1_put_tag(0x82, buf, 5, p, *outlen - (p - out), &p);
2440
3
    } else {
2441
3
      return SC_ERROR_NOT_SUPPORTED;
2442
3
    }
2443
2444
38
  }
2445
341
  else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
2446
295
    if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
2447
223
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) {
2448
223
      buf[0] = 0x11;
2449
223
      buf[1] = 0x00;
2450
223
    } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2451
69
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2452
69
      buf[0] = 0x12;
2453
69
      buf[1] = 0x00;
2454
69
    } else {
2455
3
      return SC_ERROR_NOT_SUPPORTED;
2456
3
    }
2457
292
    sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2458
292
  } else if (file->type == SC_FILE_TYPE_BSO) {
2459
1
    buf[0] = 0x10;
2460
1
    buf[1] = 0x00;
2461
1
    sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2462
1
  }
2463
2464
396
  buf[0] = (file->id >> 8) & 0xFF;
2465
396
  buf[1] = file->id & 0xFF;
2466
396
  sc_asn1_put_tag(0x83, buf, 2, p, *outlen - (p - out), &p);
2467
396
  if (file->type == SC_FILE_TYPE_DF) {
2468
23
    if (file->namelen != 0) {
2469
11
      sc_asn1_put_tag(0x84, file->name, file->namelen, p, *outlen - (p - out), &p);
2470
12
    } else {
2471
12
      return SC_ERROR_INVALID_ARGUMENTS;
2472
12
    }
2473
23
  }
2474
384
  if (file->type == SC_FILE_TYPE_DF) {
2475
11
    unsigned char data[2] = {0x00, 0x7F};
2476
    /* 127 files at most */
2477
11
    sc_asn1_put_tag(0x85, data, sizeof(data), p, *outlen - (p - out), &p);
2478
373
  } else if (file->type == SC_FILE_TYPE_BSO) {
2479
1
    buf[0] = file->size & 0xff;
2480
1
    sc_asn1_put_tag(0x85, buf, 1, p, *outlen - (p - out), &p);
2481
372
  } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
2482
292
    if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
2483
170
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2484
138
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT ||
2485
292
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2486
292
      buf[0] = (file->size >> 8) & 0xFF;
2487
292
      buf[1] = file->size & 0xFF;
2488
292
      sc_asn1_put_tag(0x85, buf, 2, p, *outlen - (p - out), &p);
2489
292
    }
2490
292
  }
2491
384
  if (file->sec_attr_len) {
2492
0
    memcpy(buf, file->sec_attr, file->sec_attr_len);
2493
0
    sc_asn1_put_tag(0x86, buf, file->sec_attr_len, p, *outlen - (p - out), &p);
2494
2495
384
  } else {
2496
384
    sc_log(card->ctx, "SC_FILE_ACL");
2497
384
    if (file->type == SC_FILE_TYPE_DF) {
2498
11
      ops[0] = SC_AC_OP_LIST_FILES;
2499
11
      ops[1] = SC_AC_OP_CREATE;
2500
11
      ops[3] = SC_AC_OP_DELETE;
2501
373
    } else if (file->type == SC_FILE_TYPE_WORKING_EF) {
2502
35
      if (file->ef_structure == SC_FILE_EF_TRANSPARENT) {
2503
35
        ops[0] = SC_AC_OP_READ;
2504
35
        ops[1] = SC_AC_OP_UPDATE;
2505
35
        ops[3] = SC_AC_OP_DELETE;
2506
35
      } else if (file->ef_structure == SC_FILE_EF_LINEAR_FIXED ||
2507
0
          file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) {
2508
0
        ops[0] = SC_AC_OP_READ;
2509
0
        ops[1] = SC_AC_OP_UPDATE;
2510
0
        ops[2] = SC_AC_OP_WRITE;
2511
0
        ops[3] = SC_AC_OP_DELETE;
2512
0
      } else {
2513
0
        return SC_ERROR_NOT_SUPPORTED;
2514
0
      }
2515
338
    } else if (file->type == SC_FILE_TYPE_BSO) {
2516
1
      ops[0] = SC_AC_OP_UPDATE;
2517
1
      ops[3] = SC_AC_OP_DELETE;
2518
337
    } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
2519
292
      if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
2520
223
          file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) {
2521
223
        ops[1] = SC_AC_OP_UPDATE;
2522
223
        ops[2] = SC_AC_OP_CRYPTO;
2523
223
        ops[3] = SC_AC_OP_DELETE;
2524
223
      } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2525
69
          file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2526
69
        ops[0] = SC_AC_OP_READ;
2527
69
        ops[1] = SC_AC_OP_UPDATE;
2528
69
        ops[2] = SC_AC_OP_CRYPTO;
2529
69
        ops[3] = SC_AC_OP_DELETE;
2530
69
      }
2531
292
    } else {
2532
45
      return SC_ERROR_NOT_SUPPORTED;
2533
45
    }
2534
2535
3.05k
    for (ii = 0; ii < sizeof(ops); ii++) {
2536
2.71k
      const struct sc_acl_entry *entry;
2537
2538
2.71k
      buf[ii] = 0xFF;
2539
2.71k
      if (ops[ii] == 0xFF)
2540
1.62k
        continue;
2541
1.08k
      entry = sc_file_get_acl_entry(file, ops[ii]);
2542
2543
1.08k
      rv = acl_to_ac_byte(card, entry);
2544
1.08k
      LOG_TEST_RET(card->ctx, rv, "Invalid ACL");
2545
2546
1.08k
      buf[ii] = rv;
2547
1.08k
    }
2548
339
    sc_asn1_put_tag(0x86, buf, sizeof(ops), p, *outlen - (p - out), &p);
2549
339
    if (file->size == 256) {
2550
139
      out[4]= 0x13;
2551
139
    }
2552
339
  }
2553
2554
  /* VT ??? */
2555
339
  if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2556
307
      file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2557
69
    unsigned char data[2] = {0x00, 0x66};
2558
69
    sc_asn1_put_tag(0x87, data, sizeof(data), p, *outlen - (p - out), &p);
2559
69
    if (file->size == 256) {
2560
37
      out[4] = 0x14;
2561
37
    }
2562
69
  }
2563
2564
339
  out[1] = p - out - 2;
2565
2566
339
  *outlen = p - out;
2567
339
  return 0;
2568
384
}
2569
2570
2571
static int
2572
epass2003_create_file(struct sc_card *card, sc_file_t * file)
2573
402
{
2574
402
  int r;
2575
402
  size_t len;
2576
402
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
2577
402
  struct sc_apdu apdu;
2578
2579
402
  len = SC_MAX_APDU_BUFFER_SIZE;
2580
2581
402
  epass2003_hook_file(file, 1);
2582
2583
402
  if (card->ops->construct_fci == NULL)
2584
402
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2585
2586
402
  r = epass2003_construct_fci(card, file, sbuf, &len);
2587
402
  LOG_TEST_RET(card->ctx, r, "construct_fci() failed");
2588
2589
339
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00);
2590
339
  apdu.lc = len;
2591
339
  apdu.datalen = len;
2592
339
  apdu.data = sbuf;
2593
2594
339
  r = sc_transmit_apdu_t(card, &apdu);
2595
339
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2596
336
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2597
336
  LOG_TEST_RET(card->ctx, r, "APDU sw1/2 wrong");
2598
2599
218
  epass2003_hook_file(file, 0);
2600
218
  return r;
2601
336
}
2602
2603
2604
static int
2605
epass2003_delete_file(struct sc_card *card, const sc_path_t * path)
2606
428
{
2607
428
  int r;
2608
428
  u8 sbuf[2];
2609
428
  struct sc_apdu apdu;
2610
2611
428
  LOG_FUNC_CALLED(card->ctx);
2612
2613
428
  r = sc_select_file(card, path, NULL);
2614
428
  LOG_TEST_RET(card->ctx, r, "Can not select file");
2615
89
  r = epass2003_hook_path((struct sc_path *)path, 1);
2616
89
  LOG_TEST_RET(card->ctx, r, "Can not hook path");
2617
2618
89
  sbuf[0] = path->value[path->len - 2];
2619
89
  sbuf[1] = path->value[path->len - 1];
2620
89
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00);
2621
89
  apdu.lc = 2;
2622
89
  apdu.datalen = 2;
2623
89
  apdu.data = sbuf;
2624
2625
89
  r = sc_transmit_apdu_t(card, &apdu);
2626
89
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2627
86
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2628
86
  LOG_TEST_RET(card->ctx, r, "Delete file failed");
2629
2630
50
  LOG_FUNC_RETURN(card->ctx, r);
2631
50
}
2632
2633
static int
2634
epass2003_list_files(struct sc_card *card, unsigned char *buf, size_t buflen)
2635
361
{
2636
361
  struct sc_apdu apdu;
2637
361
  unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
2638
361
  int r;
2639
2640
361
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2641
361
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x34, 0x00, 0x00);
2642
361
  apdu.cla = 0x80;
2643
361
  apdu.le = 0;
2644
361
  apdu.resplen = sizeof(rbuf);
2645
361
  apdu.resp = rbuf;
2646
2647
361
  r = sc_transmit_apdu_t(card, &apdu);
2648
361
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2649
2650
77
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2651
77
  LOG_TEST_RET(card->ctx, r, "Card returned error");
2652
2653
47
  if (apdu.resplen == 0x100 && rbuf[0] == 0 && rbuf[1] == 0)
2654
47
    LOG_FUNC_RETURN(card->ctx, 0);
2655
2656
46
  buflen = buflen < apdu.resplen ? buflen : apdu.resplen;
2657
46
  memcpy(buf, rbuf, buflen);
2658
2659
46
  LOG_FUNC_RETURN(card->ctx, (int)buflen);
2660
46
}
2661
2662
2663
static int
2664
internal_write_rsa_key_factor(struct sc_card *card, unsigned short fid, u8 factor,
2665
    sc_pkcs15_bignum_t data)
2666
0
{
2667
0
  int r;
2668
0
  struct sc_apdu apdu;
2669
0
  u8 sbuff[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0};
2670
2671
0
  LOG_FUNC_CALLED(card->ctx);
2672
2673
0
  sbuff[0] = ((fid & 0xff00) >> 8);
2674
0
  sbuff[1] = (fid & 0x00ff);
2675
0
  memcpy(&sbuff[2], data.data, data.len);
2676
//  sc_mem_reverse(&sbuff[2], data.len);
2677
2678
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xe7, factor, 0x00);
2679
0
  apdu.cla = 0x80;
2680
0
  apdu.lc = apdu.datalen = 2 + data.len;
2681
0
  apdu.data = sbuff;
2682
2683
0
  r = sc_transmit_apdu_t(card, &apdu);
2684
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2685
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2686
0
  LOG_TEST_RET(card->ctx, r, "Write rsa key factor failed");
2687
2688
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2689
0
}
2690
2691
2692
static int
2693
internal_write_rsa_key(struct sc_card *card, unsigned short fid, struct sc_pkcs15_prkey_rsa *rsa)
2694
0
{
2695
0
  int r;
2696
2697
0
  LOG_FUNC_CALLED(card->ctx);
2698
2699
0
  r = internal_write_rsa_key_factor(card, fid, 0x02, rsa->modulus);
2700
0
  LOG_TEST_RET(card->ctx, r, "write n failed");
2701
0
  r = internal_write_rsa_key_factor(card, fid, 0x03, rsa->d);
2702
0
  LOG_TEST_RET(card->ctx, r, "write d failed");
2703
2704
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2705
0
}
2706
2707
2708
static int
2709
hash_data(struct sc_card *card, const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType)
2710
20
{
2711
2712
20
  if ((NULL == data) || (NULL == hash))
2713
0
    return SC_ERROR_INVALID_ARGUMENTS;
2714
2715
20
  if (mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA1) {
2716
20
    unsigned char data_hash[24] = {0};
2717
20
    size_t len = 0;
2718
2719
20
    sha1_digest(card, data, datalen, data_hash);
2720
20
    len = REVERSE_ORDER4(datalen);
2721
20
    memcpy(&data_hash[20], &len, 4);
2722
20
    memcpy(hash, data_hash, 24);
2723
20
  } else if (mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA256) {
2724
0
    unsigned char data_hash[36] = {0};
2725
0
    size_t len = 0;
2726
2727
0
    sha256_digest(card, data, datalen, data_hash);
2728
0
    len = REVERSE_ORDER4(datalen);
2729
0
    memcpy(&data_hash[32], &len, 4);
2730
0
    memcpy(hash, data_hash, 36);
2731
0
  } else {
2732
0
    return SC_ERROR_NOT_SUPPORTED;
2733
0
  }
2734
2735
20
  return SC_SUCCESS;
2736
20
}
2737
2738
2739
static int
2740
install_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid,
2741
    unsigned char useac, unsigned char modifyac, unsigned char EC,
2742
    unsigned char *data, unsigned long dataLen)
2743
20
{
2744
20
  int r;
2745
20
  struct sc_apdu apdu;
2746
20
  unsigned char isapp = 0x00; /* appendable */
2747
20
  unsigned char tmp_data[256] = {0};
2748
2749
20
  tmp_data[0] = ktype;
2750
20
  tmp_data[1] = kid;
2751
20
  tmp_data[2] = useac;
2752
20
  tmp_data[3] = modifyac;
2753
20
  tmp_data[8] = 0xFF;
2754
2755
20
  if (0x04 == ktype || 0x06 == ktype) {
2756
20
    tmp_data[4] = EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_SO;
2757
20
    tmp_data[5] = EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_SO;
2758
20
    tmp_data[7] = (kid == PIN_ID[0] ? EPASS2003_AC_USER : EPASS2003_AC_SO);
2759
20
    tmp_data[9] = (EC << 4) | EC;
2760
20
  }
2761
2762
20
  memcpy(&tmp_data[10], data, dataLen);
2763
20
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xe3, isapp, 0x00);
2764
20
  apdu.cla = 0x80;
2765
20
  apdu.lc = apdu.datalen = 10 + dataLen;
2766
20
  apdu.data = tmp_data;
2767
2768
20
  r = sc_transmit_apdu_t(card, &apdu);
2769
20
  LOG_TEST_RET(card->ctx, r, "APDU install_secret_key failed");
2770
19
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2771
19
  LOG_TEST_RET(card->ctx, r, "install_secret_key failed");
2772
2773
5
  return r;
2774
19
}
2775
2776
2777
static int
2778
internal_install_pre(struct sc_card *card)
2779
0
{
2780
0
  int r;
2781
  /* init key for enc */
2782
0
  r = install_secret_key(card, 0x01, 0x00,
2783
0
             EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE,
2784
0
             EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE,
2785
0
             0, g_init_key_enc, 16);
2786
0
  LOG_TEST_RET(card->ctx, r, "Install init key failed");
2787
2788
  /* init key for mac */
2789
0
  r = install_secret_key(card, 0x02, 0x00,
2790
0
             EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE,
2791
0
             EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE,
2792
0
             0, g_init_key_mac, 16);
2793
0
  LOG_TEST_RET(card->ctx, r, "Install init key failed");
2794
2795
0
  return r;
2796
0
}
2797
2798
2799
/* use external auth secret as pin */
2800
static int
2801
internal_install_pin(struct sc_card *card, sc_epass2003_wkey_data * pin)
2802
20
{
2803
20
  int r;
2804
20
  unsigned char hash[HASH_LEN] = {0};
2805
2806
20
  r = hash_data(card, pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
2807
20
  LOG_TEST_RET(card->ctx, r, "hash data failed");
2808
2809
20
  r = install_secret_key(card, 0x04, pin->key_data.es_secret.kid,
2810
20
             pin->key_data.es_secret.ac[0],
2811
20
             pin->key_data.es_secret.ac[1],
2812
20
             pin->key_data.es_secret.EC, hash, HASH_LEN);
2813
20
  LOG_TEST_RET(card->ctx, r, "Install failed");
2814
2815
5
  return r;
2816
20
}
2817
2818
2819
static int
2820
epass2003_write_key(struct sc_card *card, sc_epass2003_wkey_data * data)
2821
20
{
2822
20
  LOG_FUNC_CALLED(card->ctx);
2823
2824
20
  if (data->type & SC_EPASS2003_KEY) {
2825
0
    if (data->type == SC_EPASS2003_KEY_RSA)
2826
0
      return internal_write_rsa_key(card, data->key_data.es_key.fid,
2827
0
                  data->key_data.es_key.rsa);
2828
0
    else
2829
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2830
20
  } else if (data->type & SC_EPASS2003_SECRET) {
2831
20
    if (data->type == SC_EPASS2003_SECRET_PRE)
2832
0
      return internal_install_pre(card);
2833
20
    else if (data->type == SC_EPASS2003_SECRET_PIN)
2834
20
      return internal_install_pin(card, data);
2835
0
    else
2836
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2837
20
  } else {
2838
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2839
0
  }
2840
2841
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2842
0
}
2843
2844
2845
static int
2846
epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data)
2847
52
{
2848
52
  int r;
2849
52
  size_t len = data->key_length;
2850
52
  struct sc_apdu apdu;
2851
52
  u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0};
2852
52
  u8 sbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0};
2853
2854
52
  LOG_FUNC_CALLED(card->ctx);
2855
2856
52
  if (len == 256) {
2857
30
    sbuf[0] = 0x02;
2858
30
  } else {
2859
22
    sbuf[0] = 0x01;
2860
22
  }
2861
52
  sbuf[1] = (u8) ((len >> 8) & 0xff);
2862
52
  sbuf[2] = (u8) (len & 0xff);
2863
52
  sbuf[3] = (u8) ((data->prkey_id >> 8) & 0xFF);
2864
52
  sbuf[4] = (u8) ((data->prkey_id) & 0xFF);
2865
52
  sbuf[5] = (u8) ((data->pukey_id >> 8) & 0xFF);
2866
52
  sbuf[6] = (u8) ((data->pukey_id) & 0xFF);
2867
2868
  /* generate key */
2869
52
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, 0x00);
2870
52
  apdu.lc = apdu.datalen = 7;
2871
52
  apdu.data = sbuf;
2872
2873
52
  r = sc_transmit_apdu_t(card, &apdu);
2874
52
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2875
50
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2876
50
  LOG_TEST_RET(card->ctx, r, "generate key pair failed");
2877
2878
  /* read public key */
2879
37
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xb4, 0x02, 0x00);
2880
37
  if (len == 256) {
2881
21
    apdu.p1 = 0x00;
2882
21
  }
2883
2884
37
  apdu.cla = 0x80;
2885
37
  apdu.lc = apdu.datalen = 2;
2886
37
  apdu.data = &sbuf[5];
2887
37
  apdu.resp = rbuf;
2888
37
  apdu.resplen = sizeof(rbuf);
2889
37
  apdu.le = 0x00;
2890
2891
37
  r = sc_transmit_apdu_t(card, &apdu);
2892
37
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2893
36
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2894
36
  LOG_TEST_RET(card->ctx, r, "get pukey failed");
2895
2896
30
  if (len < apdu.resplen)
2897
30
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2898
2899
25
  if (256 == len) { /* ECC 256 bit */
2900
17
    size_t xCoordinateLen = rbuf[1];
2901
17
    size_t yCoordinateLen;
2902
17
    unsigned char *tmp;
2903
2904
17
    if (2 + xCoordinateLen + 1 > apdu.resplen) {
2905
3
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
2906
3
    }
2907
14
    yCoordinateLen = rbuf[2 + xCoordinateLen + 1];
2908
14
    if (2 + xCoordinateLen + 2 + yCoordinateLen > apdu.resplen) {
2909
6
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
2910
6
    }
2911
8
    data->modulus_len = xCoordinateLen + yCoordinateLen;
2912
8
    tmp = (u8 *)malloc(data->modulus_len);
2913
8
    if (!tmp) {
2914
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
2915
0
    }
2916
2917
8
    if (0x58 == rbuf[0]) {
2918
3
      memcpy(tmp, &rbuf[2], xCoordinateLen);
2919
5
    } else {
2920
5
      free(tmp);
2921
5
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
2922
5
    }
2923
3
    if (0x59 == rbuf[2 + xCoordinateLen]) {
2924
2
      memcpy(tmp + xCoordinateLen, &rbuf[2+xCoordinateLen+2], yCoordinateLen);
2925
2
    } else {
2926
1
      free(tmp);
2927
1
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
2928
1
    }
2929
2930
2
    data->modulus = tmp;
2931
8
  } else {
2932
8
    data->modulus = (u8 *) malloc(len);
2933
8
    if (!data->modulus) {
2934
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
2935
8
    } else {
2936
8
      memcpy(data->modulus, rbuf, len);
2937
8
    }
2938
8
  }
2939
10
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2940
10
}
2941
2942
2943
static int
2944
epass2003_erase_card(struct sc_card *card)
2945
17
{
2946
17
  static const unsigned char install_magic_pin[26] = {
2947
    /* compare install_secret_key */
2948
17
      0x06, 0x01, 0x10, 0x16, 0x16, 0x16, 0x00, 0x0f, 0xff, 0x66,
2949
17
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2950
17
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2951
17
  };
2952
17
  static const unsigned char magic_pin[16] = {
2953
17
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2954
17
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2955
17
  };
2956
17
  static const unsigned char mf_path[2] = { 0x3f, 0x00 };
2957
17
  sc_apdu_t apdu;
2958
17
  int r;
2959
2960
17
  LOG_FUNC_CALLED(card->ctx);
2961
2962
  /* install magic pin */
2963
17
  sc_format_apdu(card, &apdu, 0x03, 0xe3, 0x00, 0x00);
2964
17
  apdu.cla = 0x80;
2965
17
  apdu.data = install_magic_pin;
2966
17
  apdu.datalen = apdu.lc = sizeof(install_magic_pin);
2967
17
  r = sc_transmit_apdu(card, &apdu);
2968
17
  LOG_TEST_RET(card->ctx, r, "APDU install magic pin failed");
2969
16
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2970
16
  LOG_TEST_RET(card->ctx, r, "install magic pin failed");
2971
2972
  /* verify magic pin */
2973
6
  sc_format_apdu(card, &apdu, 0x03, 0x20, 0x00, 0x01);
2974
6
  apdu.cla = 0;
2975
6
  apdu.data = magic_pin;
2976
6
  apdu.datalen = apdu.lc = sizeof(magic_pin);
2977
6
  r = sc_transmit_apdu(card, &apdu);
2978
6
  LOG_TEST_RET(card->ctx, r, "APDU verify magic pin failed");
2979
5
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2980
5
  LOG_TEST_RET(card->ctx, r, "verify magic pin failed");
2981
2982
  /* delete MF */
2983
4
  sc_format_apdu(card, &apdu, 0x03, 0xe4, 0x00, 0x00);
2984
4
  apdu.cla = 0;
2985
4
  apdu.data = mf_path;
2986
4
  apdu.datalen = apdu.lc = sizeof(mf_path);
2987
4
  r = sc_transmit_apdu(card, &apdu);
2988
4
  LOG_TEST_RET(card->ctx, r, "APDU delete MF failed");
2989
3
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2990
3
  LOG_TEST_RET(card->ctx, r, "delete MF failed");
2991
2992
1
  LOG_FUNC_RETURN(card->ctx, r);
2993
1
}
2994
2995
2996
static int
2997
epass2003_get_serialnr(struct sc_card *card, sc_serial_number_t * serial)
2998
309
{
2999
309
  u8 rbuf[8];
3000
309
  size_t rbuf_len = sizeof(rbuf);
3001
3002
309
  LOG_FUNC_CALLED(card->ctx);
3003
3004
309
  if (SC_SUCCESS != get_data(card, 0x80, rbuf, rbuf_len))
3005
217
    return SC_ERROR_CARD_CMD_FAILED;
3006
3007
92
  card->serialnr.len = serial->len = 8;
3008
92
  memcpy(card->serialnr.value, rbuf, 8);
3009
92
  memcpy(serial->value, rbuf, 8);
3010
3011
92
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
3012
92
}
3013
3014
3015
static int
3016
epass2003_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
3017
1.66k
{
3018
1.66k
  LOG_FUNC_CALLED(card->ctx);
3019
3020
1.66k
  sc_log(card->ctx, "cmd is %0lx", cmd);
3021
1.66k
  switch (cmd) {
3022
20
  case SC_CARDCTL_ENTERSAFE_WRITE_KEY:
3023
20
    return epass2003_write_key(card, (sc_epass2003_wkey_data *) ptr);
3024
52
  case SC_CARDCTL_ENTERSAFE_GENERATE_KEY:
3025
52
    return epass2003_gen_key(card, (sc_epass2003_gen_key_data *) ptr);
3026
17
  case SC_CARDCTL_ERASE_CARD:
3027
17
    return epass2003_erase_card(card);
3028
309
  case SC_CARDCTL_GET_SERIALNR:
3029
309
    return epass2003_get_serialnr(card, (sc_serial_number_t *) ptr);
3030
1.26k
  default:
3031
1.26k
    return SC_ERROR_NOT_SUPPORTED;
3032
1.66k
  }
3033
1.66k
}
3034
3035
3036
static void
3037
internal_sanitize_pin_info(struct sc_pin_cmd_pin *pin, unsigned int num)
3038
618
{
3039
618
  pin->encoding = SC_PIN_ENCODING_ASCII;
3040
618
  pin->min_length = 4;
3041
618
  pin->max_length = 16;
3042
618
  pin->pad_length = 16;
3043
618
  pin->offset = 5 + num * 16;
3044
618
  pin->pad_char = 0x00;
3045
618
}
3046
3047
3048
static int
3049
get_external_key_maxtries(struct sc_card *card, unsigned char *maxtries)
3050
0
{
3051
0
  unsigned char maxcounter[2] = {0};
3052
0
  static const sc_path_t file_path = {
3053
0
    {0x3f, 0x00, 0x50, 0x15, 0x9f, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6,
3054
0
    0,
3055
0
    0,
3056
0
    SC_PATH_TYPE_PATH,
3057
0
    {{0}, 0}
3058
0
  };
3059
0
  int ret;
3060
3061
0
  ret = sc_select_file(card, &file_path, NULL);
3062
0
  LOG_TEST_RET(card->ctx, ret, "select max counter file failed");
3063
3064
0
  ret = sc_read_binary(card, 0, maxcounter, 2, 0);
3065
0
  LOG_TEST_RET(card->ctx, ret, "read max counter file failed");
3066
3067
0
  *maxtries = maxcounter[0];
3068
0
  return SC_SUCCESS;
3069
0
}
3070
3071
3072
static int
3073
get_external_key_retries(struct sc_card *card, unsigned char kid, unsigned char *retries)
3074
0
{
3075
0
  int r;
3076
0
  struct sc_apdu apdu;
3077
0
  unsigned char random[16] = {0};
3078
3079
0
  r = sc_get_challenge(card, random, 8);
3080
0
  LOG_TEST_RET(card->ctx, r, "get challenge get_external_key_retries failed");
3081
3082
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x82, 0x01, 0x80 | kid);
3083
0
  apdu.resp = NULL;
3084
0
  apdu.resplen = 0;
3085
3086
0
  r = sc_transmit_apdu_t(card, &apdu);
3087
0
  LOG_TEST_RET(card->ctx, r, "APDU get_external_key_retries failed");
3088
3089
0
  if (retries && ((0x63 == (apdu.sw1 & 0xff)) && (0xC0 == (apdu.sw2 & 0xf0)))) {
3090
0
    *retries = (apdu.sw2 & 0x0f);
3091
0
    r = SC_SUCCESS;
3092
0
  } else {
3093
0
    LOG_TEST_RET(card->ctx, r, "get_external_key_retries failed");
3094
0
    r = SC_ERROR_CARD_CMD_FAILED;
3095
0
  }
3096
3097
0
  return r;
3098
0
}
3099
3100
static int
3101
epass2003_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
3102
1.57k
{
3103
1.57k
  u8 rbuf[16];
3104
1.57k
  size_t out_len;
3105
1.57k
  int r;
3106
3107
1.57k
  LOG_FUNC_CALLED(card->ctx);
3108
3109
1.57k
  r = iso_ops->get_challenge(card, rbuf, sizeof rbuf);
3110
1.57k
  LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed");
3111
3112
1.24k
  if (len < (size_t) r) {
3113
2
    out_len = len;
3114
1.24k
  } else {
3115
1.24k
    out_len = (size_t) r;
3116
1.24k
  }
3117
1.24k
  memcpy(rnd, rbuf, out_len);
3118
3119
1.24k
  LOG_FUNC_RETURN(card->ctx, (int) out_len);
3120
1.24k
}
3121
3122
3123
static int
3124
external_key_auth(struct sc_card *card, unsigned char kid,
3125
    unsigned char *data, size_t datalen)
3126
0
{
3127
0
  int r;
3128
0
  struct sc_apdu apdu;
3129
0
  unsigned char random[16] = {0};
3130
0
  unsigned char tmp_data[16] = {0};
3131
0
  unsigned char hash[HASH_LEN] = {0};
3132
0
  unsigned char iv[16] = {0};
3133
3134
0
  r = sc_get_challenge(card, random, 8);
3135
0
  LOG_TEST_RET(card->ctx, r, "get challenge external_key_auth failed");
3136
3137
0
  r = hash_data(card, data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
3138
0
  LOG_TEST_RET(card->ctx, r, "hash data failed");
3139
3140
0
  r = des3_encrypt_cbc(card, hash, HASH_LEN, iv, random, 8, tmp_data);
3141
0
  LOG_TEST_RET(card->ctx, r, "encryption failed");
3142
3143
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x01, 0x80 | kid);
3144
0
  apdu.lc = apdu.datalen = 8;
3145
0
  apdu.data = tmp_data;
3146
3147
0
  r = sc_transmit_apdu_t(card, &apdu);
3148
0
  LOG_TEST_RET(card->ctx, r, "APDU external_key_auth failed");
3149
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
3150
0
  LOG_TEST_RET(card->ctx, r, "external_key_auth failed");
3151
3152
0
  return r;
3153
0
}
3154
3155
3156
static int
3157
update_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid,
3158
    const unsigned char *data, unsigned long datalen)
3159
0
{
3160
0
  int r;
3161
0
  struct sc_apdu apdu;
3162
0
  unsigned char hash[HASH_LEN] = {0};
3163
0
  unsigned char tmp_data[256] = {0};
3164
0
  unsigned char maxtries = 0;
3165
3166
0
  r = hash_data(card, data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
3167
0
  LOG_TEST_RET(card->ctx, r, "hash data failed");
3168
3169
0
  r = get_external_key_maxtries(card, &maxtries);
3170
0
  LOG_TEST_RET(card->ctx, r, "get max counter failed");
3171
3172
0
  tmp_data[0] = (maxtries << 4) | maxtries;
3173
0
  memcpy(&tmp_data[1], hash, HASH_LEN);
3174
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xe5, ktype, kid);
3175
0
  apdu.cla = 0x80;
3176
0
  apdu.lc = apdu.datalen = 1 + HASH_LEN;
3177
0
  apdu.data = tmp_data;
3178
3179
0
  r = sc_transmit_apdu_t(card, &apdu);
3180
0
  LOG_TEST_RET(card->ctx, r, "APDU update_secret_key failed");
3181
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
3182
0
  LOG_TEST_RET(card->ctx, r, "update_secret_key failed");
3183
3184
0
  return r;
3185
0
}
3186
3187
/* use external auth secret as pin */
3188
static int
3189
epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
3190
309
{
3191
309
  int r;
3192
309
  u8 kid;
3193
309
  u8 retries = 0;
3194
309
  u8 pin_low = 3;
3195
309
  unsigned char maxtries = 0;
3196
3197
309
  LOG_FUNC_CALLED(card->ctx);
3198
3199
309
  internal_sanitize_pin_info(&data->pin1, 0);
3200
309
  internal_sanitize_pin_info(&data->pin2, 1);
3201
309
  data->flags |= SC_PIN_CMD_NEED_PADDING;
3202
309
  kid = data->pin_reference;
3203
3204
309
  if (NULL == (unsigned char *)data->pin1.data || 0 == data->pin1.len)
3205
309
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
3206
3207
  /* get pin retries */
3208
0
  if (data->cmd == SC_PIN_CMD_GET_INFO) {
3209
3210
0
    r = get_external_key_retries(card, 0x80 | kid, &retries);
3211
0
    if (r == SC_SUCCESS) {
3212
0
      data->pin1.tries_left = retries;
3213
0
      if (tries_left)
3214
0
        *tries_left = retries;
3215
3216
0
      r = get_external_key_maxtries(card, &maxtries);
3217
0
      LOG_TEST_RET(card->ctx, r, "get max counter failed");
3218
3219
0
      data->pin1.max_tries = maxtries;
3220
0
    }
3221
0
    LOG_TEST_RET(card->ctx, r, "verify pin failed");
3222
0
  } else if (data->cmd == SC_PIN_CMD_UNBLOCK) { /* verify */
3223
0
    r = external_key_auth(card, (kid + 1), (unsigned char *)data->pin1.data,
3224
0
        data->pin1.len);
3225
0
    LOG_TEST_RET(card->ctx, r, "verify pin failed");
3226
0
  } else if (data->cmd == SC_PIN_CMD_CHANGE || data->cmd == SC_PIN_CMD_UNBLOCK) { /* change */
3227
0
    r = external_key_auth(card, kid, (unsigned char *)data->pin1.data,
3228
0
        data->pin1.len);
3229
0
    LOG_TEST_RET(card->ctx, r, "verify pin failed");
3230
3231
0
    r = update_secret_key(card, 0x04, kid, data->pin2.data,
3232
0
        (unsigned long)data->pin2.len);
3233
0
    LOG_TEST_RET(card->ctx, r, "change pin failed");
3234
0
  } else {
3235
0
    r = external_key_auth(card, kid, (unsigned char *)data->pin1.data,
3236
0
        data->pin1.len);
3237
0
    LOG_TEST_RET(card->ctx, r, "verify pin failed");
3238
3239
0
    r = get_external_key_retries(card, 0x80 | kid, &retries);
3240
0
    if (retries < pin_low)
3241
0
      sc_log(card->ctx, "Verification failed (remaining tries: %d)", retries);
3242
3243
0
    LOG_TEST_RET(card->ctx, r, "verify pin failed");
3244
0
  }
3245
3246
0
  if (r == SC_SUCCESS) {
3247
0
    data->pin1.logged_in = SC_PIN_STATE_LOGGED_IN;
3248
0
  }
3249
0
  return r;
3250
0
}
3251
3252
static int
3253
epass2003_logout(struct sc_card *card)
3254
0
{
3255
0
  epass2003_exdata *exdata = NULL;
3256
3257
0
  if (!card->drv_data)
3258
0
    return SC_ERROR_INVALID_ARGUMENTS;
3259
3260
0
  exdata = (epass2003_exdata *)card->drv_data;
3261
0
  if (exdata->sm) {
3262
0
    sc_sm_stop(card);
3263
0
    return epass2003_refresh(card);
3264
0
  }
3265
3266
0
  return SC_ERROR_NOT_SUPPORTED;
3267
0
}
3268
3269
static struct sc_card_driver *sc_get_driver(void)
3270
101k
{
3271
101k
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
3272
3273
101k
  if (iso_ops == NULL)
3274
10
    iso_ops = iso_drv->ops;
3275
3276
101k
  epass2003_ops = *iso_ops;
3277
3278
101k
  epass2003_ops.match_card = epass2003_match_card;
3279
101k
  epass2003_ops.init = epass2003_init;
3280
101k
  epass2003_ops.finish = epass2003_finish;
3281
101k
  epass2003_ops.write_binary = NULL;
3282
101k
  epass2003_ops.write_record = NULL;
3283
101k
  epass2003_ops.select_file = epass2003_select_file;
3284
101k
  epass2003_ops.get_response = NULL;
3285
101k
  epass2003_ops.restore_security_env = epass2003_restore_security_env;
3286
101k
  epass2003_ops.set_security_env = epass2003_set_security_env;
3287
101k
  epass2003_ops.decipher = epass2003_decipher;
3288
101k
  epass2003_ops.compute_signature = epass2003_decipher;
3289
101k
  epass2003_ops.create_file = epass2003_create_file;
3290
101k
  epass2003_ops.delete_file = epass2003_delete_file;
3291
101k
  epass2003_ops.list_files = epass2003_list_files;
3292
101k
  epass2003_ops.card_ctl = epass2003_card_ctl;
3293
101k
  epass2003_ops.process_fci = epass2003_process_fci;
3294
101k
  epass2003_ops.construct_fci = epass2003_construct_fci;
3295
101k
  epass2003_ops.pin_cmd = epass2003_pin_cmd;
3296
101k
  epass2003_ops.check_sw = epass2003_check_sw;
3297
101k
  epass2003_ops.get_challenge = epass2003_get_challenge;
3298
101k
  epass2003_ops.logout = epass2003_logout;
3299
101k
  return &epass2003_drv;
3300
101k
}
3301
3302
struct sc_card_driver *sc_get_epass2003_driver(void)
3303
101k
{
3304
101k
  return sc_get_driver();
3305
101k
}
3306
#endif  /* #ifdef ENABLE_OPENSSL */
3307
#endif  /* #ifdef ENABLE_SM */