Coverage Report

Created: 2026-08-13 06:09

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
5.68k
#define KEY_TYPE_AES  0x01  /* FIPS mode */
81
1.71k
#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
22
#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
1.95k
#define SM_PLAIN        0x00
92
908
#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
22
#define REVERSE_ORDER4(x) (       \
118
22
    ((unsigned long)x & 0xFF000000)>> 24  | \
119
22
    ((unsigned long)x & 0x00FF0000)>>  8  | \
120
22
    ((unsigned long)x & 0x0000FF00)<<  8  | \
121
22
    ((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
10.6k
{
246
10.6k
  const int err_count = sizeof(epass2003_errors)/sizeof(epass2003_errors[0]);
247
10.6k
  int i;
248
249
  /* Handle special cases here */
250
10.6k
  if (sw1 == 0x6C) {
251
53
    sc_log(card->ctx, "Wrong length; correct length is %d", sw2);
252
53
    return SC_ERROR_WRONG_LENGTH;
253
53
  }
254
255
494k
  for (i = 0; i < err_count; i++) {
256
493k
    if (epass2003_errors[i].SWs == ((sw1 << 8) | sw2)) {
257
9.86k
      sc_log(card->ctx, "%s", epass2003_errors[i].errorstr);
258
9.86k
      return epass2003_errors[i].errorno;
259
9.86k
    }
260
493k
  }
261
262
736
  sc_log(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X", sw1, sw2);
263
736
  return SC_ERROR_CARD_CMD_FAILED;
264
10.5k
}
265
266
static int
267
sc_transmit_apdu_t(sc_card_t *card, sc_apdu_t *apdu)
268
7.02k
{
269
7.02k
  size_t resplen = apdu->resplen;
270
7.02k
  int r = sc_transmit_apdu(card, apdu);
271
7.02k
  if ((0x69 == apdu->sw1 && 0x85 == apdu->sw2) || (0x69 == apdu->sw1 && 0x88 == apdu->sw2)) {
272
203
    epass2003_refresh(card);
273
    /* renew old resplen */
274
203
    apdu->resplen = resplen;
275
203
    r = sc_transmit_apdu(card, apdu);
276
203
  }
277
7.02k
  return r;
278
7.02k
}
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
3.05k
{
284
3.05k
  int r = SC_ERROR_INTERNAL;
285
3.05k
  EVP_CIPHER_CTX * ctx = NULL;
286
3.05k
  int outl = 0;
287
3.05k
  int outl_tmp = 0;
288
3.05k
  unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = {0};
289
290
3.05k
  memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH);
291
3.05k
  ctx = EVP_CIPHER_CTX_new();
292
3.05k
  if (ctx == NULL)
293
0
    goto out;
294
295
3.05k
  if (!EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv_tmp) || !EVP_CIPHER_CTX_set_padding(ctx, 0))
296
0
    goto out;
297
298
3.05k
  if (!EVP_EncryptUpdate(ctx, output, &outl, input, (int)length))
299
0
    goto out;
300
301
3.05k
  if (!EVP_EncryptFinal_ex(ctx, output + outl, &outl_tmp))
302
0
    goto out;
303
304
3.05k
  r = SC_SUCCESS;
305
3.05k
out:
306
3.05k
  EVP_CIPHER_CTX_free(ctx);
307
3.05k
  return r;
308
3.05k
}
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
815
{
314
815
  int r = SC_ERROR_INTERNAL;
315
815
  EVP_CIPHER_CTX * ctx = NULL;
316
815
  int outl = 0;
317
815
  int outl_tmp = 0;
318
815
  unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = {0};
319
320
815
  memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH);
321
815
  ctx = EVP_CIPHER_CTX_new();
322
815
  if (ctx == NULL)
323
0
    goto out;
324
325
815
  if (!EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv_tmp) ||
326
815
      !EVP_CIPHER_CTX_set_padding(ctx, 0))
327
0
    goto out;
328
329
815
  if (!EVP_DecryptUpdate(ctx, output, &outl, input, (int)length))
330
0
    goto out;
331
332
815
  if (!EVP_DecryptFinal_ex(ctx, output + outl, &outl_tmp))
333
0
    goto out;
334
335
815
  r = SC_SUCCESS;
336
815
out:
337
815
  EVP_CIPHER_CTX_free(ctx);
338
815
  return r;
339
815
}
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
17
{
416
17
  size_t mactlen = 0;
417
17
  int r = SC_ERROR_INTERNAL;
418
17
#if OPENSSL_VERSION_NUMBER < 0x30000000L
419
17
  CMAC_CTX *ctx = CMAC_CTX_new();
420
17
  if (ctx == NULL) {
421
0
    return SC_ERROR_INTERNAL;
422
0
  }
423
424
17
  if (!CMAC_Init(ctx, key, keysize / 8, EVP_aes_128_cbc(), NULL)) {
425
0
    goto err;
426
0
  }
427
17
  if (!CMAC_Update(ctx, input, length)) {
428
0
    goto err;
429
0
  }
430
17
  if (!CMAC_Final(ctx, output, &mactlen)) {
431
0
    goto err;
432
0
  }
433
17
  r = SC_SUCCESS;
434
17
err:
435
17
  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
17
  return r;
470
17
}
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
22
{
476
22
  unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
477
22
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-ECB");
478
22
  int r;
479
22
  r = openssl_enc(alg, key, iv, input, length, output);
480
22
  sc_evp_cipher_free(alg);
481
22
  if (r != SC_SUCCESS)
482
0
    sc_log_openssl(card->ctx);
483
22
  return r;
484
22
}
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
99
{
491
99
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-CBC");
492
99
  int r;
493
99
  r = openssl_enc(alg, key, iv, input, length, output);
494
99
  sc_evp_cipher_free(alg);
495
99
  if (r != SC_SUCCESS)
496
0
    sc_log_openssl(card->ctx);
497
99
  return r;
498
99
}
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
0
{
505
0
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-CBC");
506
0
  int r;
507
0
  r = openssl_dec(alg, key, iv, input, length, output);
508
0
  sc_evp_cipher_free(alg);
509
0
  if (r != SC_SUCCESS)
510
0
    sc_log_openssl(card->ctx);
511
0
  return r;
512
0
}
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
336
{
519
336
  unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
520
336
  unsigned char bKey[24] = {0};
521
336
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3");
522
336
  int r;
523
524
336
  if (keysize == 16) {
525
336
    memcpy(&bKey[0], key, 16);
526
336
    memcpy(&bKey[16], key, 8);
527
336
  } else {
528
0
    memcpy(&bKey[0], key, 24);
529
0
  }
530
531
336
  r = openssl_enc(alg, bKey, iv, input, length, output);
532
336
  sc_evp_cipher_free(alg);
533
336
  if (r != SC_SUCCESS)
534
0
    sc_log_openssl(card->ctx);
535
336
  return r;
536
336
}
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
963
{
543
963
  unsigned char bKey[24] = {0};
544
963
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3-CBC");
545
963
  int r;
546
547
963
  if (keysize == 16) {
548
963
    memcpy(&bKey[0], key, 16);
549
963
    memcpy(&bKey[16], key, 8);
550
963
  } else {
551
0
    memcpy(&bKey[0], key, 24);
552
0
  }
553
554
963
  r = openssl_enc(EVP_des_ede3_cbc(), bKey, iv, input, length, output);
555
963
  sc_evp_cipher_free(alg);
556
963
  if (r != SC_SUCCESS)
557
0
    sc_log_openssl(card->ctx);
558
963
  return r;
559
963
}
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
1.63k
{
589
1.63k
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-CBC");
590
1.63k
  int r;
591
592
1.63k
  r = openssl_enc(alg, key, iv, input, length, output);
593
1.63k
  sc_evp_cipher_free(alg);
594
1.63k
  if (r != SC_SUCCESS)
595
0
    sc_log_openssl(card->ctx);
596
1.63k
  return r;
597
1.63k
}
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
815
{
604
815
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-CBC");
605
815
  int r;
606
607
815
  r = openssl_dec(alg, key, iv, input, length, output);
608
815
  sc_evp_cipher_free(alg);
609
815
  if (r != SC_SUCCESS)
610
0
    sc_log_openssl(card->ctx);
611
815
  return r;
612
815
}
613
614
615
static int
616
openssl_dig(const EVP_MD * digest, const unsigned char *input, size_t length,
617
    unsigned char *output)
618
22
{
619
22
  int r = 0;
620
22
  EVP_MD_CTX *ctx = NULL;
621
22
  unsigned outl = 0;
622
623
22
  ctx = EVP_MD_CTX_create();
624
22
  if (ctx == NULL) {
625
0
    r = SC_ERROR_OUT_OF_MEMORY;
626
0
    goto err;
627
0
  }
628
629
22
  EVP_MD_CTX_init(ctx);
630
22
  if (!EVP_DigestInit_ex(ctx, digest, NULL) ||
631
22
      !EVP_DigestUpdate(ctx, input, length)) {
632
0
    r = SC_ERROR_INTERNAL;
633
0
    goto err;
634
0
  }
635
636
22
  if (!EVP_DigestFinal_ex(ctx, output, &outl)) {
637
0
    r = SC_ERROR_INTERNAL;
638
0
    goto err;
639
0
  }
640
22
  r = SC_SUCCESS;
641
22
err:
642
22
  if (ctx)
643
22
    EVP_MD_CTX_destroy(ctx);
644
645
22
  return r;
646
22
}
647
648
649
static int
650
sha1_digest(struct sc_card *card, const unsigned char *input, size_t length, unsigned char *output)
651
22
{
652
22
  EVP_MD *md = sc_evp_md(card->ctx, "SHA1");
653
22
  int r;
654
655
22
  r = openssl_dig(md, input, length, output);
656
22
  sc_evp_md_free(md);
657
22
  if (r != SC_SUCCESS)
658
0
    sc_log_openssl(card->ctx);
659
22
  return r;
660
22
}
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
853
{
680
853
  int r;
681
853
  struct sc_apdu apdu;
682
853
  unsigned char data[256] = {0};
683
853
  unsigned char tmp_sm;
684
853
  unsigned char isFips;
685
853
  unsigned long blocksize = 0;
686
853
  unsigned char cryptogram[256] = {0}; /* host cryptogram */
687
853
  unsigned char iv[16] = {0};
688
853
  epass2003_exdata *exdata = NULL;
689
690
853
  if (!card->drv_data)
691
0
    return SC_ERROR_INVALID_ARGUMENTS;
692
693
853
  exdata = (epass2003_exdata *)card->drv_data;
694
853
  isFips = exdata->bFipsCertification;
695
696
853
  LOG_FUNC_CALLED(card->ctx);
697
698
853
  if (1 != RAND_bytes(g_random, sizeof(g_random)))
699
0
    return SC_ERROR_INTERNAL;
700
701
853
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x50, 0x00, 0x00);
702
853
  apdu.cla = 0x80;
703
853
  apdu.lc = apdu.datalen = sizeof(g_random);
704
853
  apdu.data = g_random; /* host random */
705
853
  if (isFips)
706
5
    apdu.le = apdu.resplen = 29;
707
848
  else
708
848
    apdu.le = apdu.resplen = 28;
709
710
853
  apdu.resp = result; /* card random is result[12~19] */
711
712
853
  tmp_sm = exdata->sm;
713
853
  exdata->sm = SM_PLAIN;
714
853
  r = epass2003_transmit_apdu(card, &apdu);
715
853
  exdata->sm = tmp_sm;
716
853
  LOG_TEST_RET(card->ctx, r, "APDU gen_init_key failed");
717
718
809
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
719
809
  LOG_TEST_RET(card->ctx, r, "gen_init_key failed");
720
721
  /* Step 1 - Generate Derivation data */
722
183
  if (isFips) {
723
4
    memset(data, 0x00, 15);
724
4
    data[11] = 0x04;
725
4
    data[14] = 0x80;
726
4
    data[15] = 0x01;
727
4
    memcpy(&data[16], g_random, 8);
728
4
    memcpy(&data[24], &result[12 + 1], 8);
729
179
  } else {
730
179
    memcpy(data, &result[16], 4);
731
179
    memcpy(&data[4], g_random, 4);
732
179
    memcpy(&data[8], &result[12], 4);
733
179
    memcpy(&data[12], &g_random[4], 4);
734
179
  }
735
736
  /* Step 2,3 - Create S-ENC/S-MAC Session Key */
737
183
  if (KEY_TYPE_AES == key_type) {
738
15
    if (isFips) {
739
4
      r = aes128_encrypt_cmac(card, key_enc, 128, data, 32, exdata->sk_enc);
740
4
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac enc failed");
741
4
      memset(&data[11], 0x06, 1);
742
4
      r = aes128_encrypt_cmac(card, key_mac, 128, data, 32, exdata->sk_mac);
743
4
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac mac  failed");
744
11
    } else {
745
11
      r = aes128_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc);
746
11
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb enc  failed");
747
11
      r = aes128_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac);
748
11
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb mac  failed");
749
11
    }
750
168
  } else {
751
168
    r = des3_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc);
752
168
    LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed");
753
168
    r = des3_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac);
754
168
    LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed");
755
168
  }
756
757
183
  if (isFips) {
758
4
    data[11] = 0x00;
759
4
    data[14] = 0x40;
760
179
  } else {
761
179
    memcpy(data, g_random, 8);
762
179
    memcpy(&data[8], &result[12], 8);
763
179
    data[16] = 0x80;
764
179
    blocksize = (key_type == KEY_TYPE_AES ? 16 : 8);
765
179
    memset(&data[17], 0x00, blocksize - 1);
766
179
  }
767
768
  /* calculate host cryptogram */
769
183
  if (KEY_TYPE_AES == key_type) {
770
15
    if (isFips) {
771
4
      r = aes128_encrypt_cmac(card, exdata->sk_enc, 128, data, 32, cryptogram);
772
11
    } else {
773
11
      r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram);
774
11
    }
775
168
  } else {
776
168
    r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram);
777
168
  }
778
779
183
  LOG_TEST_RET(card->ctx, r, "calculate host cryptogram failed");
780
781
  /* verify card cryptogram */
782
183
  if (isFips) {
783
4
    if (0 != memcmp(&cryptogram[0], &result[20+1], 8))
784
4
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED);
785
179
  } else {
786
179
    if (0 != memcmp(&cryptogram[16], &result[20], 8))
787
179
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED);
788
179
  }
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
853
{
897
853
  struct sc_context *ctx = card->ctx;
898
853
  int r;
899
853
  unsigned char result[256] = {0};
900
853
  unsigned char ran_key[8] = {0};
901
853
  epass2003_exdata *exdata = NULL;
902
903
853
  if (!card->drv_data)
904
0
    return SC_ERROR_INVALID_ARGUMENTS;
905
853
  exdata = (epass2003_exdata *)card->drv_data;
906
907
853
  LOG_FUNC_CALLED(ctx);
908
909
853
  r = gen_init_key(card, key_enc, key_mac, result, exdata->smtype);
910
853
  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
1.09k
{
927
1.09k
  int r = SC_SUCCESS;
928
1.09k
  epass2003_exdata *exdata = NULL;
929
930
1.09k
  if (!card->drv_data)
931
0
    return SC_ERROR_INVALID_ARGUMENTS;
932
933
1.09k
  exdata = (epass2003_exdata *)card->drv_data;
934
935
1.09k
  if (exdata->sm) {
936
853
    card->sm_ctx.sm_mode = 0;
937
853
    r = mutual_auth(card, g_init_key_enc, g_init_key_mac);
938
853
    card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
939
853
    LOG_TEST_RET(card->ctx, r, "mutual_auth failed");
940
853
  }
941
942
242
  return r;
943
1.09k
}
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
840
{
951
840
  size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
952
840
  unsigned char pad[4096] = {0};
953
840
  size_t pad_len;
954
840
  size_t tlv_more;  /* increased tlv length */
955
840
  unsigned char iv[16] = {0};
956
840
  epass2003_exdata *exdata = NULL;
957
840
  int r = 0;
958
959
840
  if (!card->drv_data)
960
0
    return SC_ERROR_INVALID_ARGUMENTS;
961
962
840
  exdata = (epass2003_exdata *)card->drv_data;
963
964
  /* we encrypt the pad buffer and then write it to the apdu_buf at offset block_size + tlv_more */
965
840
  if (apdu->lc >= sizeof(pad) - block_size - 5)
966
840
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_DATA,
967
840
        "ePass2003 secure messaging APDU data too large");
968
969
  /* padding */
970
840
  apdu_buf[block_size] = 0x87;
971
840
  memcpy(pad, apdu->data, apdu->lc);
972
840
  pad[apdu->lc] = 0x80;
973
840
  if ((apdu->lc + 1) % block_size)
974
839
    pad_len = ((apdu->lc + 1) / block_size + 1) * block_size;
975
1
  else
976
1
    pad_len = apdu->lc + 1;
977
978
  /* encode Lc' */
979
840
  if (pad_len > 0x7E) {
980
    /* Lc' > 0x7E, use extended APDU */
981
0
    apdu_buf[block_size + 1] = 0x82;
982
0
    apdu_buf[block_size + 2] = (unsigned char)((pad_len + 1) / 0x100);
983
0
    apdu_buf[block_size + 3] = (unsigned char)((pad_len + 1) % 0x100);
984
0
    apdu_buf[block_size + 4] = 0x01;
985
0
    tlv_more = 5;
986
840
  } else {
987
840
    apdu_buf[block_size + 1] = (unsigned char)pad_len + 1;
988
840
    apdu_buf[block_size + 2] = 0x01;
989
840
    tlv_more = 3;
990
840
  }
991
840
  memcpy(data_tlv, &apdu_buf[block_size], tlv_more);
992
993
  /* encrypt Data */
994
840
  if (KEY_TYPE_AES == key_type) {
995
45
    r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);
996
45
    LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed");
997
795
  } else {
998
795
    r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);
999
795
    LOG_TEST_RET(card->ctx, r, "des3_encrypt_cbc failed");
1000
795
  }
1001
1002
840
  memcpy(data_tlv + tlv_more, apdu_buf + block_size + tlv_more, pad_len);
1003
840
  *data_tlv_len = tlv_more + pad_len;
1004
840
  return 0;
1005
840
}
1006
1007
1008
/* Le(TLV)=0x97|L|Le */
1009
static int
1010
construct_le_tlv(struct sc_apdu *apdu, unsigned char *apdu_buf, size_t data_tlv_len,
1011
    unsigned char *le_tlv, size_t * le_tlv_len, const unsigned char key_type)
1012
848
{
1013
848
  size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
1014
1015
848
  *(apdu_buf + block_size + data_tlv_len) = 0x97;
1016
848
  if (apdu->le > 0x7F) {
1017
    /* Le' > 0x7E, use extended APDU */
1018
23
    *(apdu_buf + block_size + data_tlv_len + 1) = 2;
1019
23
    *(apdu_buf + block_size + data_tlv_len + 2) = (unsigned char)(apdu->le / 0x100);
1020
23
    *(apdu_buf + block_size + data_tlv_len + 3) = (unsigned char)(apdu->le % 0x100);
1021
23
    memcpy(le_tlv, apdu_buf + block_size + data_tlv_len, 4);
1022
23
    *le_tlv_len = 4;
1023
825
  } else {
1024
825
    *(apdu_buf + block_size + data_tlv_len + 1) = 1;
1025
825
    *(apdu_buf + block_size + data_tlv_len + 2) = (unsigned char)apdu->le;
1026
825
    memcpy(le_tlv, apdu_buf + block_size + data_tlv_len, 3);
1027
825
    *le_tlv_len = 3;
1028
825
  }
1029
848
  return 0;
1030
848
}
1031
1032
1033
/* MAC(TLV)=0x8e|0x08|MAC */
1034
static int
1035
construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_len,
1036
    unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type)
1037
853
{
1038
853
  size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
1039
853
  unsigned char mac[4096] = {0};
1040
853
  size_t mac_len;
1041
853
  unsigned char icv[16] = {0};
1042
853
  int r ;
1043
853
  int i = (KEY_TYPE_AES == key_type ? 15 : 7);
1044
853
  epass2003_exdata *exdata = NULL;
1045
1046
853
  if (!card->drv_data)
1047
0
    return SC_ERROR_INVALID_ARGUMENTS;
1048
1049
853
  exdata = (epass2003_exdata *)card->drv_data;
1050
1051
853
  if (data_tlv_len + le_tlv_len + block_size + 1 > sizeof(mac)) {
1052
0
    return SC_ERROR_BUFFER_TOO_SMALL;
1053
0
  }
1054
1055
853
  if (0 == data_tlv_len && 0 == le_tlv_len) {
1056
0
    mac_len = block_size;
1057
853
  } else {
1058
    /* padding */
1059
853
    *(apdu_buf + block_size + data_tlv_len + le_tlv_len) = 0x80;
1060
853
    if ((data_tlv_len + le_tlv_len + 1) % block_size) {
1061
839
      mac_len = (((data_tlv_len + le_tlv_len + 1) / block_size) +
1062
839
          1) * block_size + block_size;
1063
839
    } else {
1064
14
      mac_len = data_tlv_len + le_tlv_len + 1 + block_size;
1065
14
    }
1066
853
    memset((apdu_buf + block_size + data_tlv_len + le_tlv_len + 1),
1067
853
           0, (mac_len - (data_tlv_len + le_tlv_len + 1)));
1068
853
  }
1069
1070
  /* increase icv */
1071
853
  for (; i >= 0; i--) {
1072
853
    if (exdata->icv_mac[i] == 0xff) {
1073
0
      exdata->icv_mac[i] = 0;
1074
853
    } else {
1075
853
      exdata->icv_mac[i]++;
1076
853
      break;
1077
853
    }
1078
853
  }
1079
1080
  /* calculate MAC */
1081
853
  memset(icv, 0, sizeof(icv));
1082
853
  memcpy(icv, exdata->icv_mac, 16);
1083
853
  if (KEY_TYPE_AES == key_type) {
1084
48
    if (exdata->bFipsCertification) {
1085
85
      for (int i = 0; i < 16; i++) {
1086
80
        apdu_buf[i] = apdu_buf[i] ^ icv[i];
1087
80
      }
1088
5
      r = aes128_encrypt_cmac(card, exdata->sk_mac, 128, apdu_buf, data_tlv_len + le_tlv_len + block_size, mac);
1089
5
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac failed");
1090
5
      memcpy(mac_tlv + 2, &mac[0 /*ulmacLen-16*/], 8);
1091
25
      for (int j = 0; j < 4; j++) {
1092
20
        apdu_buf[j] = apdu_buf[j] ^ icv[j];
1093
20
      }
1094
43
    } else {
1095
43
      r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac);
1096
43
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed");
1097
43
      memcpy(mac_tlv + 2, &mac[mac_len - 16], 8);
1098
43
    }
1099
805
  } else {
1100
805
    unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
1101
805
    unsigned char tmp[8] = {0};
1102
805
    r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac);
1103
805
    LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 1 failed");
1104
805
    r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp);
1105
805
    LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed");
1106
805
    memset(iv, 0x00, sizeof iv);
1107
805
    r = des_encrypt_cbc(card, exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2);
1108
805
    LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 2 failed");
1109
805
  }
1110
1111
853
  *mac_tlv_len = 2 + 8;
1112
853
  return 0;
1113
853
}
1114
1115
/* MAC(TLV case 1) */
1116
static int
1117
construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_len,
1118
  unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type)
1119
0
{
1120
0
  int r;
1121
0
  size_t block_size = 4;
1122
0
  unsigned char mac[4096] = {0};
1123
0
  size_t mac_len;
1124
0
  int i = (KEY_TYPE_AES == key_type ? 15 : 7);
1125
0
  unsigned char icv[16] = {0};
1126
1127
0
  epass2003_exdata *exdata = NULL;
1128
1129
0
  if (!card->drv_data)
1130
0
    return SC_ERROR_INVALID_ARGUMENTS;
1131
1132
0
  exdata = (epass2003_exdata *)card->drv_data;
1133
1134
0
  if (data_tlv_len + le_tlv_len + block_size + 1 > sizeof(mac)) {
1135
0
    return SC_ERROR_BUFFER_TOO_SMALL;
1136
0
  }
1137
1138
0
  if (0 == data_tlv_len && 0 == le_tlv_len) {
1139
0
    mac_len = block_size;
1140
0
  } else {
1141
    /* padding */
1142
0
    *(apdu_buf + block_size + data_tlv_len + le_tlv_len) = 0x80;
1143
0
    if ((data_tlv_len + le_tlv_len + 1) % block_size) {
1144
0
      mac_len = (((data_tlv_len + le_tlv_len + 1) / block_size) + 1) * block_size + block_size;
1145
0
    } else {
1146
0
      mac_len = data_tlv_len + le_tlv_len + 1 + block_size;
1147
0
    }
1148
0
  }
1149
  /* increase icv */
1150
0
  for (; i >= 0; i--) {
1151
0
    if (exdata->icv_mac[i] == 0xff) {
1152
0
      exdata->icv_mac[i] = 0;
1153
0
    } else {
1154
0
      exdata->icv_mac[i]++;
1155
0
      break;
1156
0
    }
1157
0
  }
1158
1159
  /* calculate MAC */
1160
0
  memset(icv, 0, sizeof(icv));
1161
0
  memcpy(icv, exdata->icv_mac, 16);
1162
0
  if (KEY_TYPE_AES == key_type) {
1163
0
    if (exdata->bFipsCertification) {
1164
0
      r = aes128_encrypt_cmac_ft(card, exdata->sk_mac, 128, apdu_buf, data_tlv_len + le_tlv_len + block_size, mac, &icv[0]);
1165
0
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac_ft failed");
1166
0
      memcpy(mac_tlv + 2, &mac[0 /*ulmacLen-16*/], 8);
1167
0
    } else {
1168
0
      if (mac_len < 16)
1169
0
        LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "incorrect mac length");
1170
0
      r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac);
1171
0
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed");
1172
0
      memcpy(mac_tlv + 2, &mac[mac_len - 16], 8);
1173
0
    }
1174
0
  } else {
1175
0
    unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
1176
0
    unsigned char tmp[8] = {0};
1177
0
    if (mac_len < 8)
1178
0
      LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "incorrect mac length");
1179
0
    r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac);
1180
0
    LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc  failed");
1181
0
    r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp);
1182
0
    LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed");
1183
0
    memset(iv, 0x00, sizeof iv);
1184
0
    r = des_encrypt_cbc(card, exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2);
1185
0
    LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed");
1186
0
  }
1187
1188
0
  *mac_tlv_len = 2 + 8;
1189
0
  return 0;
1190
0
}
1191
1192
/* According to GlobalPlatform Card Specification's SCP01
1193
 * encode APDU from
1194
 * CLA INS P1 P2 [Lc] Data [Le]
1195
 * to
1196
 * CLA INS P1 P2 Lc' Data' [Le]
1197
 * where
1198
 * Data'=Data(TLV)+Le(TLV)+MAC(TLV) */
1199
static int
1200
encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm,
1201
    unsigned char *apdu_buf, size_t * apdu_buf_len)
1202
853
{
1203
853
  size_t block_size = 0;
1204
853
  unsigned char dataTLV[4096] = {0};
1205
853
  size_t data_tlv_len = 0;
1206
853
  unsigned char le_tlv[256] = {0};
1207
853
  size_t le_tlv_len = 0;
1208
853
  size_t mac_tlv_len = 10;
1209
853
  size_t tmp_lc = 0;
1210
853
  size_t tmp_le = 0;
1211
853
  size_t expected_total_len;
1212
853
  unsigned char mac_tlv[256] = {0};
1213
853
  epass2003_exdata *exdata = NULL;
1214
1215
853
  mac_tlv[0] = 0x8E;
1216
853
  mac_tlv[1] = 8;
1217
  /* size_t plain_le = 0; */
1218
853
  if (!card->drv_data)
1219
0
    return SC_ERROR_INVALID_ARGUMENTS;
1220
853
  exdata = (epass2003_exdata*)card->drv_data;
1221
853
  block_size = (KEY_TYPE_DES == exdata->smtype ? 16 : 8);
1222
1223
853
  sm->cse = SC_APDU_CASE_4_SHORT;
1224
853
  apdu_buf[0] = (unsigned char)plain->cla;
1225
853
  apdu_buf[1] = (unsigned char)plain->ins;
1226
853
  apdu_buf[2] = (unsigned char)plain->p1;
1227
853
  apdu_buf[3] = (unsigned char)plain->p2;
1228
  /* plain_le = plain->le; */
1229
  /* padding */
1230
853
  if (exdata->bFipsCertification && plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01) {
1231
0
    apdu_buf[4] = 0x00;
1232
853
  } else {
1233
853
    apdu_buf[4] = 0x80;
1234
853
  }
1235
853
  memset(&apdu_buf[5], 0x00, block_size - 5);
1236
1237
  /* Data -> Data' */
1238
853
  if (plain->lc != 0)
1239
840
    if (0 != construct_data_tlv(card, plain, apdu_buf, dataTLV, &data_tlv_len, exdata->smtype))
1240
0
      return -1;
1241
1242
853
  if (plain->le != 0 || (plain->le == 0 && plain->resplen != 0))
1243
848
    if (0 != construct_le_tlv(plain, apdu_buf, data_tlv_len, le_tlv,
1244
848
             &le_tlv_len, exdata->smtype))
1245
0
      return -1;
1246
1247
853
  if (exdata->bFipsCertification && plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01) {
1248
0
    if (0 != construct_mac_tlv_case1(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype))
1249
0
      return -1;
1250
853
  } else {
1251
853
    if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype))
1252
0
      return -1;
1253
853
  }
1254
1255
853
  memset(apdu_buf + 4, 0, *apdu_buf_len - 4);
1256
853
  sm->lc = sm->datalen = data_tlv_len + le_tlv_len + mac_tlv_len;
1257
853
  if (sm->lc > 0xFF) {
1258
0
    sm->cse = SC_APDU_CASE_4_EXT;
1259
0
    apdu_buf[4] = (unsigned char)((sm->lc) / 0x10000);
1260
0
    apdu_buf[5] = (unsigned char)(((sm->lc) / 0x100) % 0x100);
1261
0
    apdu_buf[6] = (unsigned char)((sm->lc) % 0x100);
1262
0
    tmp_lc = 3;
1263
853
  } else {
1264
853
    apdu_buf[4] = (unsigned char)sm->lc;
1265
853
    tmp_lc = 1;
1266
853
  }
1267
1268
  /* 2 is for Le extension in the worst case */
1269
853
  expected_total_len = 4 + tmp_lc + data_tlv_len + le_tlv_len + mac_tlv_len + 2;
1270
1271
853
  if (expected_total_len > *apdu_buf_len) {
1272
0
      return SC_ERROR_BUFFER_TOO_SMALL;
1273
0
  }
1274
1275
853
  memcpy(apdu_buf + 4 + tmp_lc, dataTLV, data_tlv_len);
1276
853
  memcpy(apdu_buf + 4 + tmp_lc + data_tlv_len, le_tlv, le_tlv_len);
1277
853
  memcpy(apdu_buf + 4 + tmp_lc + data_tlv_len + le_tlv_len, mac_tlv, mac_tlv_len);
1278
853
  memcpy((unsigned char *)sm->data, apdu_buf + 4 + tmp_lc, sm->datalen);
1279
853
  *apdu_buf_len = 0;
1280
1281
853
  if (4 == le_tlv_len) {
1282
23
    sm->cse = SC_APDU_CASE_4_EXT;
1283
23
    *(apdu_buf + 4 + tmp_lc + sm->lc) = (unsigned char)(plain->le / 0x100);
1284
23
    *(apdu_buf + 4 + tmp_lc + sm->lc + 1) = (unsigned char)(plain->le % 0x100);
1285
23
    tmp_le = 2;
1286
830
  } else if (3 == le_tlv_len) {
1287
825
    *(apdu_buf + 4 + tmp_lc + sm->lc) = (unsigned char)plain->le;
1288
825
    tmp_le = 1;
1289
825
  }
1290
1291
853
  *apdu_buf_len += 4 + tmp_lc + data_tlv_len + le_tlv_len + mac_tlv_len + tmp_le;
1292
  /* sm->le = calc_le(plain_le); */
1293
853
  return 0;
1294
853
}
1295
1296
1297
static int
1298
epass2003_sm_wrap_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm)
1299
1.68k
{
1300
1.68k
  unsigned char buf[4096] = {0}; /* APDU buffer */
1301
1.68k
  size_t buf_len = sizeof(buf);
1302
1.68k
  epass2003_exdata *exdata = NULL;
1303
1304
1.68k
  if (!card->drv_data)
1305
0
    return SC_ERROR_INVALID_ARGUMENTS;
1306
1307
1.68k
  exdata = (epass2003_exdata *)card->drv_data;
1308
1309
1.68k
  LOG_FUNC_CALLED(card->ctx);
1310
1311
1.68k
  if (exdata->sm)
1312
853
    plain->cla |= 0x0C;
1313
1314
1.68k
  sm->cse = plain->cse;
1315
1.68k
  sm->cla = plain->cla;
1316
1.68k
  sm->ins = plain->ins;
1317
1.68k
  sm->p1 = plain->p1;
1318
1.68k
  sm->p2 = plain->p2;
1319
1.68k
  sm->lc = plain->lc;
1320
1.68k
  sm->le = plain->le;
1321
1.68k
  sm->control = plain->control;
1322
1.68k
  sm->flags = plain->flags;
1323
1324
1.68k
  switch (sm->cla & 0x0C) {
1325
831
  case 0x00:
1326
831
  case 0x04:
1327
831
    sm->datalen = plain->datalen;
1328
831
    memcpy((void *)sm->data, plain->data, plain->datalen);
1329
831
    sm->resplen = plain->resplen;
1330
831
    memcpy(sm->resp, plain->resp, plain->resplen);
1331
831
    break;
1332
853
  case 0x0C:
1333
853
    memset(buf, 0, sizeof(buf));
1334
853
    if (0 != encode_apdu(card, plain, sm, buf, &buf_len))
1335
0
      return SC_ERROR_CARD_CMD_FAILED;
1336
853
    break;
1337
853
  default:
1338
0
    return SC_ERROR_INCORRECT_PARAMETERS;
1339
1.68k
  }
1340
1341
1.68k
  return SC_SUCCESS;
1342
1.68k
}
1343
1344
static int
1345
epass2003_check_response_mac_and_sw(struct sc_card *card, struct sc_apdu *sm)
1346
853
{
1347
853
  unsigned char iv[16];
1348
853
  unsigned char *data = NULL, *mac = NULL;
1349
853
  size_t blocksize, mac_len;
1350
853
  int ret = -1;
1351
853
  size_t taglen;
1352
853
  const u8 *tag;
1353
853
  epass2003_exdata *exdata;
1354
853
  unsigned char *in = sm->resp;
1355
853
  unsigned char *alt_in;
1356
853
  size_t inlen = sm->resplen;
1357
853
  size_t len_correction;
1358
1359
  /* card/ctx/drv_data is already checked by caller */
1360
853
  exdata = (epass2003_exdata *)card->drv_data;
1361
1362
  /* The SM must contain at least TLV encoded SW and MAC fields. */
1363
853
  if (inlen < 14 )
1364
694
    return ret;
1365
1366
  /* compare BER-TLV encoded SW (TAG 0x99) and raw SW */
1367
159
  alt_in = in;
1368
159
  tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x99, &taglen);
1369
159
  if (tag == NULL || taglen != 2) {
1370
    /*
1371
     * It seems that the EPASS2003 firmware has some problem with BER-TLV encoding.
1372
     * Instead of (correct) TLV 87 81 81 [01 .. ..] incorrect TLV 87 81 [01 .. ..]
1373
     * is returned. There seems to be some proprietary fix for the faulty encoding
1374
     * in the decrypt_response() function, similar fix here:
1375
     */
1376
137
    if (0x01 == in[2] && 0x82 != in[1]) {
1377
43
      sc_log(card->ctx, "Workaround, wrong BER-TLV ?");
1378
43
      len_correction = in[1] + 2;
1379
43
      if (inlen < len_correction)
1380
11
        return ret;
1381
32
      inlen -= len_correction;
1382
32
      alt_in += len_correction;
1383
32
      tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x99, &taglen);
1384
32
      if (tag == NULL || taglen != 2)
1385
28
        return ret;
1386
94
    } else {
1387
94
      return ret;
1388
94
    }
1389
137
  }
1390
26
  if (sm->sw1 != tag[0] || sm->sw2 != tag[1])
1391
14
    return ret;
1392
1393
  /* no documentation/real hardware to test, the response is accepted without MAC check */
1394
12
  if (exdata->bFipsCertification) {
1395
0
    sc_log(card->ctx, "Warning, MAC is not checked");
1396
0
    return 0;
1397
0
  }
1398
12
  tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x8e, &taglen);
1399
12
  if (tag == NULL || taglen != 8)
1400
2
    return ret;
1401
1402
10
  if (KEY_TYPE_AES == exdata->smtype)
1403
0
    blocksize = 16;
1404
10
  else
1405
10
    blocksize = 8;
1406
1407
10
  mac_len = tag - in - 2;
1408
10
  if (NULL == (data = calloc(1, mac_len + blocksize)))
1409
0
    goto end;
1410
10
  if (NULL == (mac = malloc(mac_len + blocksize)))
1411
0
    goto end;
1412
1413
  /* copy response to buffer and append padding */
1414
10
  memcpy(data, in, mac_len);
1415
10
  data[mac_len++] = 0x80;
1416
1417
10
  if (mac_len % blocksize)
1418
9
    mac_len += (blocksize - (mac_len % blocksize));
1419
1420
  /* calculate MAC */
1421
10
  memcpy(iv, exdata->icv_mac, blocksize);
1422
1423
10
  if (KEY_TYPE_AES == exdata->smtype) {
1424
0
    if (aes128_encrypt_cbc(card, exdata->sk_mac, 16, iv, data, mac_len, mac))
1425
0
      goto end;
1426
10
  } else {
1427
10
    uint8_t tmp[8];
1428
10
    uint8_t iv0[EVP_MAX_IV_LENGTH];
1429
10
    if (des_encrypt_cbc(card, exdata->sk_mac, 8, iv, data, mac_len, mac))
1430
0
      goto end;
1431
10
    memset(iv0, 0, EVP_MAX_IV_LENGTH);
1432
10
    if (des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv0, &mac[mac_len - 8], 8, tmp))
1433
0
      goto end;
1434
10
    memset(iv0, 0, EVP_MAX_IV_LENGTH);
1435
10
    if (des_encrypt_cbc(card, exdata->sk_mac, 8, iv0, tmp, 8, &mac[mac_len - 8]))
1436
0
      goto end;
1437
10
  }
1438
  /* compare MAC */
1439
10
  if (!memcmp(tag, mac + mac_len - blocksize, 8))
1440
1
    ret = 0;
1441
10
end:
1442
10
  if (data)
1443
10
    free(data);
1444
10
  if (mac)
1445
10
    free(mac);
1446
10
  return ret;
1447
10
}
1448
1449
/* According to GlobalPlatform Card Specification's SCP01
1450
 * decrypt APDU response from
1451
 * ResponseData' SW1 SW2
1452
 * to
1453
 * ResponseData SW1 SW2
1454
 * where
1455
 * ResponseData'=Data(TLV)+SW12(TLV)+MAC(TLV)
1456
 * where
1457
 * Data(TLV)=0x87|L|Cipher
1458
 * SW12(TLV)=0x99|0x02|SW1+SW2
1459
 * MAC(TLV)=0x8e|0x08|MAC */
1460
static int
1461
decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned char *out, size_t * out_len)
1462
0
{
1463
0
  unsigned int cla = 0, tag = 0;
1464
0
  const unsigned char *p = in;
1465
0
  size_t cipher_len;
1466
0
  unsigned char iv[16] = {0};
1467
0
  unsigned char plaintext[4096] = {0};
1468
0
  epass2003_exdata *exdata = NULL;
1469
1470
0
  if (!card->drv_data)
1471
0
    return SC_ERROR_INVALID_ARGUMENTS;
1472
1473
0
  exdata = (epass2003_exdata *)card->drv_data;
1474
1475
0
  if (SC_SUCCESS != sc_asn1_read_tag(&p, inlen, &cla, &tag, &cipher_len) || p == NULL) {
1476
0
    return -1;
1477
0
  }
1478
0
  if ((cla | tag) == 0x99)
1479
0
    return 0;
1480
0
  if ((cla | tag) != 0x87)
1481
0
    return -1;
1482
1483
0
  if (cipher_len < 2 || cipher_len > sizeof plaintext)
1484
0
    return -1;
1485
1486
  /* Skip the 0x01 separator between tag and ciphertext */
1487
0
  p++;
1488
  /* decrypt */
1489
0
  if (KEY_TYPE_AES == exdata->smtype)
1490
0
    aes128_decrypt_cbc(card, exdata->sk_enc, 16, iv, p, cipher_len - 1, plaintext);
1491
0
  else
1492
0
    des3_decrypt_cbc(card, exdata->sk_enc, 16, iv, p, cipher_len - 1, plaintext);
1493
1494
  /* unpadding */
1495
0
  while (0x80 != plaintext[cipher_len - 2] && (cipher_len > 2))
1496
0
    cipher_len--;
1497
1498
0
  if (2 == cipher_len || *out_len < cipher_len - 2)
1499
0
    return -1;
1500
1501
0
  memcpy(out, plaintext, cipher_len - 2);
1502
0
  *out_len = cipher_len - 2;
1503
0
  return 0;
1504
0
}
1505
1506
1507
static int
1508
epass2003_sm_unwrap_apdu(struct sc_card *card, struct sc_apdu *sm, struct sc_apdu *plain)
1509
1.68k
{
1510
1.68k
  int r;
1511
1.68k
  size_t len = 0;
1512
1.68k
  epass2003_exdata *exdata = NULL;
1513
1514
1.68k
  if (!card->drv_data)
1515
0
    return SC_ERROR_INVALID_ARGUMENTS;
1516
1517
1.68k
  exdata = (epass2003_exdata *)card->drv_data;
1518
1519
1.68k
  LOG_FUNC_CALLED(card->ctx);
1520
1521
  /* verify MAC, and check if SW1,2 match SW1,2 encapsulated in SM */
1522
1.68k
  if (exdata->sm) {
1523
853
    if (epass2003_check_response_mac_and_sw(card, sm)) {
1524
852
      sc_log(card->ctx, "MAC or SW incorrect");
1525
852
      return SC_ERROR_CARD_CMD_FAILED;
1526
852
    }
1527
853
  }
1528
832
  r = sc_check_sw(card, sm->sw1, sm->sw2);
1529
832
  if (r == SC_SUCCESS) {
1530
449
    if (exdata->sm) {
1531
0
      len = plain->resplen;
1532
0
      if (0 != decrypt_response(card, sm->resp, sm->resplen, plain->resp, &len))
1533
0
        return SC_ERROR_CARD_CMD_FAILED;
1534
449
    } else {
1535
449
      memcpy(plain->resp, sm->resp, sm->resplen);
1536
449
      len = sm->resplen;
1537
449
    }
1538
449
  }
1539
1540
832
  plain->resplen = len;
1541
832
  plain->sw1 = sm->sw1;
1542
832
  plain->sw2 = sm->sw2;
1543
1544
832
  sc_log(card->ctx,
1545
832
         "unwrapped APDU: resplen %"SC_FORMAT_LEN_SIZE_T"u, SW %02X%02X",
1546
832
         plain->resplen, plain->sw1, plain->sw2);
1547
832
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1548
832
}
1549
1550
1551
static int
1552
epass2003_sm_free_wrapped_apdu(struct sc_card *card,
1553
    struct sc_apdu *plain, struct sc_apdu **sm_apdu)
1554
1.68k
{
1555
1.68k
  struct sc_context *ctx = card->ctx;
1556
1.68k
  int rv = SC_SUCCESS;
1557
1558
1.68k
  LOG_FUNC_CALLED(ctx);
1559
1.68k
  if (!sm_apdu)
1560
1.68k
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1561
1.68k
  if (!(*sm_apdu))
1562
1.68k
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1563
1564
1565
1.68k
  if (plain)
1566
1.68k
    rv = epass2003_sm_unwrap_apdu(card, *sm_apdu, plain);
1567
1568
1.68k
  if ((*sm_apdu)->data) {
1569
1.68k
    unsigned char * p = (unsigned char *)((*sm_apdu)->data);
1570
1.68k
    free(p);
1571
1.68k
  }
1572
1.68k
  if ((*sm_apdu)->resp) {
1573
1.68k
    free((*sm_apdu)->resp);
1574
1.68k
  }
1575
1576
1.68k
  free(*sm_apdu);
1577
1.68k
  *sm_apdu = NULL;
1578
1579
1.68k
  LOG_FUNC_RETURN(ctx, rv);
1580
1.68k
}
1581
1582
1583
static int
1584
epass2003_sm_get_wrapped_apdu(struct sc_card *card,
1585
    struct sc_apdu *plain, struct sc_apdu **sm_apdu)
1586
1.68k
{
1587
1.68k
  struct sc_context *ctx = card->ctx;
1588
1.68k
  struct sc_apdu *apdu = NULL;
1589
1.68k
  int rv;
1590
1591
1.68k
  LOG_FUNC_CALLED(ctx);
1592
1.68k
  if (!plain || !sm_apdu)
1593
1.68k
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1594
1595
1.68k
  *sm_apdu = NULL;
1596
  //construct new SM apdu from original apdu
1597
1.68k
  apdu = calloc(1, sizeof(struct sc_apdu));
1598
1.68k
  if (!apdu) {
1599
0
    rv = SC_ERROR_OUT_OF_MEMORY;
1600
0
    goto err;
1601
0
  }
1602
1.68k
  apdu->data = calloc (1, SC_MAX_EXT_APDU_BUFFER_SIZE);
1603
1.68k
  if (!apdu->data) {
1604
0
    rv = SC_ERROR_OUT_OF_MEMORY;
1605
0
    goto err;
1606
0
  }
1607
1.68k
  apdu->resp = calloc (1, SC_MAX_EXT_APDU_BUFFER_SIZE);
1608
1.68k
  if (!apdu->resp) {
1609
0
    rv = SC_ERROR_OUT_OF_MEMORY;
1610
0
    goto err;
1611
0
  }
1612
1.68k
  apdu->datalen = SC_MAX_EXT_APDU_BUFFER_SIZE;
1613
1.68k
  apdu->resplen = SC_MAX_EXT_APDU_BUFFER_SIZE;
1614
1615
1.68k
  rv = epass2003_sm_wrap_apdu(card, plain, apdu);
1616
1.68k
  if (rv) {
1617
0
    rv = epass2003_sm_free_wrapped_apdu(card, NULL, &apdu);
1618
0
    if (rv < 0)
1619
0
      goto err;
1620
0
  }
1621
1622
1.68k
  *sm_apdu = apdu;
1623
1.68k
  apdu = NULL;
1624
1.68k
err:
1625
1.68k
  if (apdu) {
1626
0
    free((unsigned char *) apdu->data);
1627
0
    free(apdu->resp);
1628
0
    free(apdu);
1629
0
    apdu = NULL;
1630
0
  }
1631
1.68k
  LOG_FUNC_RETURN(ctx, rv);
1632
1.68k
}
1633
1634
1635
static int
1636
epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu)
1637
853
{
1638
853
  int r;
1639
1640
853
  LOG_FUNC_CALLED(card->ctx);
1641
1642
853
  r = sc_transmit_apdu_t(card, apdu);
1643
853
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1644
1645
809
  return r;
1646
853
}
1647
1648
1649
static int
1650
get_data(struct sc_card *card, unsigned char type, unsigned char *data, size_t datalen)
1651
1.13k
{
1652
1.13k
  int r;
1653
1.13k
  struct sc_apdu apdu;
1654
1.13k
  unsigned char resp[SC_MAX_APDU_BUFFER_SIZE] = {0};
1655
1.13k
  size_t resplen = SC_MAX_APDU_BUFFER_SIZE;
1656
1.13k
  epass2003_exdata *exdata = NULL;
1657
1658
1.13k
  if (!card->drv_data)
1659
0
    return SC_ERROR_INVALID_ARGUMENTS;
1660
1661
1.13k
  exdata = (epass2003_exdata *)card->drv_data;
1662
1663
1.13k
  LOG_FUNC_CALLED(card->ctx);
1664
1665
1.13k
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, type);
1666
1.13k
  apdu.resp = resp;
1667
1.13k
  apdu.le = 0;
1668
1.13k
  apdu.resplen = resplen;
1669
1.13k
  if (0x86 == type) {
1670
    /* No SM temporarily */
1671
908
    unsigned char tmp_sm = exdata->sm;
1672
908
    exdata->sm = SM_PLAIN;
1673
908
    r = sc_transmit_apdu(card, &apdu);
1674
908
    exdata->sm = tmp_sm;
1675
908
  } else {
1676
226
    r = sc_transmit_apdu_t(card, &apdu);
1677
226
  }
1678
1.13k
  LOG_TEST_RET(card->ctx, r, "APDU get_data failed");
1679
1.12k
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1680
1.12k
  LOG_TEST_RET(card->ctx, r, "get_data failed");
1681
1682
933
  memcpy(data, resp, datalen);
1683
933
  return r;
1684
1.12k
}
1685
1686
/* card driver functions */
1687
1688
static int epass2003_match_card(struct sc_card *card)
1689
13.5k
{
1690
13.5k
  int r;
1691
1692
13.5k
  LOG_FUNC_CALLED(card->ctx);
1693
13.5k
  r = _sc_match_atr(card, epass2003_atrs, &card->type);
1694
13.5k
  if (r < 0)
1695
12.6k
    return 0;
1696
1697
908
  return 1;
1698
13.5k
}
1699
1700
1701
static int
1702
epass2003_init(struct sc_card *card)
1703
908
{
1704
908
  unsigned int flags;
1705
908
  unsigned int ext_flags;
1706
908
  unsigned char data[SC_MAX_APDU_BUFFER_SIZE] = {0};
1707
908
  size_t datalen = SC_MAX_APDU_BUFFER_SIZE;
1708
908
  epass2003_exdata *exdata = NULL;
1709
908
  void *old_drv_data = card->drv_data;
1710
1711
908
  LOG_FUNC_CALLED(card->ctx);
1712
1713
908
  card->name = "epass2003";
1714
908
  card->cla = 0x00;
1715
908
  exdata = (epass2003_exdata *)calloc(1, sizeof(epass2003_exdata));
1716
908
  if (!exdata)
1717
0
    return SC_ERROR_OUT_OF_MEMORY;
1718
1719
908
  card->drv_data = exdata;
1720
1721
908
  exdata->sm = SM_SCP01;
1722
1723
  /* decide FIPS/Non-FIPS mode */
1724
908
  if (SC_SUCCESS != get_data(card, 0x86, data, datalen)) {
1725
16
    free(exdata);
1726
16
    card->drv_data = old_drv_data;
1727
16
    return SC_ERROR_INVALID_CARD;
1728
16
  }
1729
1730
892
  if (memcmp(&data[32], "\x87\x01\x01", 3) == 0 && memcmp(&data[0], "\x80\x01\x01", 3) == 0) {
1731
5
    exdata->bFipsCertification = 0x01;
1732
887
  } else {
1733
887
    exdata->bFipsCertification = 0x00;
1734
887
  }
1735
1736
892
  if (0x01 == data[2])
1737
32
    exdata->smtype = KEY_TYPE_AES;
1738
860
  else
1739
860
    exdata->smtype = KEY_TYPE_DES;
1740
1741
892
  if (0x84 == data[14]) {
1742
198
    if (0x00 == data[16]) {
1743
189
      exdata->sm = SM_PLAIN;
1744
189
    }
1745
198
  }
1746
1747
  /* mutual authentication */
1748
892
  card->max_recv_size = 0xD8;
1749
892
  card->max_send_size = 0xE8;
1750
1751
892
  card->sm_ctx.ops.open = epass2003_refresh;
1752
892
  card->sm_ctx.ops.get_sm_apdu = epass2003_sm_get_wrapped_apdu;
1753
892
  card->sm_ctx.ops.free_sm_apdu = epass2003_sm_free_wrapped_apdu;
1754
1755
  /* FIXME (VT): rather then set/unset 'g_sm', better to implement filter for APDUs to be wrapped */
1756
892
  epass2003_refresh(card);
1757
1758
892
  card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
1759
1760
892
  flags = SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE;
1761
1762
892
  _sc_card_add_rsa_alg(card, 512, flags, 0);
1763
892
  _sc_card_add_rsa_alg(card, 768, flags, 0);
1764
892
  _sc_card_add_rsa_alg(card, 1024, flags, 0);
1765
892
  _sc_card_add_rsa_alg(card, 2048, flags, 0);
1766
1767
  //set EC Alg Flags
1768
892
  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;
1769
892
  ext_flags = 0;
1770
892
  _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
1771
1772
892
  card->caps = SC_CARD_CAP_RNG | SC_CARD_CAP_APDU_EXT;
1773
1774
892
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1775
892
}
1776
1777
static int
1778
epass2003_finish(sc_card_t *card)
1779
892
{
1780
892
  epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
1781
1782
892
  if (exdata)
1783
892
    free(exdata);
1784
892
  return SC_SUCCESS;
1785
892
}
1786
1787
/* COS implement SFI as lower 5 bits of FID, and not allow same SFI at the
1788
 * same DF, so use hook functions to increase/decrease FID by 0x20 */
1789
static int
1790
epass2003_hook_path(struct sc_path *path, int inc)
1791
9.14k
{
1792
9.14k
  u8 fid_h = 0;
1793
9.14k
  u8 fid_l = 0;
1794
1795
9.14k
  if (!path || path->len < 2)
1796
81
    return -1;
1797
9.06k
  fid_h = path->value[path->len - 2];
1798
9.06k
  fid_l = path->value[path->len - 1];
1799
1800
9.06k
  switch (fid_h) {
1801
1.54k
  case 0x29:
1802
1.63k
  case 0x30:
1803
1.83k
  case 0x31:
1804
1.95k
  case 0x32:
1805
2.04k
  case 0x33:
1806
2.13k
  case 0x34:
1807
2.13k
    if (inc)
1808
1.16k
      fid_l = fid_l * FID_STEP;
1809
966
    else
1810
966
      fid_l = fid_l / FID_STEP;
1811
2.13k
    path->value[path->len - 1] = fid_l;
1812
2.13k
    return 1;
1813
6.92k
  default:
1814
6.92k
    break;
1815
9.06k
  }
1816
6.92k
  return 0;
1817
9.06k
}
1818
1819
1820
static int
1821
epass2003_hook_file(struct sc_file *file, int inc)
1822
2.95k
{
1823
2.95k
  int fidl = file->id & 0xff;
1824
2.95k
  int fidh = file->id & 0xff00;
1825
2.95k
  int rv = 0;
1826
1827
2.95k
  rv = epass2003_hook_path(&file->path, inc);
1828
1829
2.95k
  if (rv > 0) {
1830
1.07k
    if (inc)
1831
107
      file->id = fidh + fidl * FID_STEP;
1832
966
    else
1833
966
      file->id = fidh + fidl / FID_STEP;
1834
1.07k
  }
1835
2.95k
  if (rv < 0)
1836
81
    return rv;
1837
2.87k
  return SC_SUCCESS;
1838
2.95k
}
1839
1840
1841
static int
1842
epass2003_select_fid_(struct sc_card *card, sc_path_t * in_path, sc_file_t ** file_out)
1843
6.05k
{
1844
6.05k
  struct sc_apdu apdu;
1845
6.05k
  u8 buf[SC_MAX_APDU_BUFFER_SIZE] = {0};
1846
6.05k
  u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
1847
6.05k
  int r;
1848
6.05k
  size_t pathlen;
1849
6.05k
  sc_file_t *file = NULL;
1850
1851
6.05k
  r = epass2003_hook_path(in_path, 1);
1852
6.05k
  LOG_TEST_RET(card->ctx, r, "Can not hook path");
1853
1854
6.05k
  memcpy(path, in_path->value, in_path->len);
1855
6.05k
  pathlen = in_path->len;
1856
1857
6.05k
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x00);
1858
1859
6.05k
  switch (in_path->type) {
1860
6.05k
  case SC_PATH_TYPE_FILE_ID:
1861
6.05k
    apdu.p1 = 0;
1862
6.05k
    if (pathlen != 2)
1863
0
      return SC_ERROR_INVALID_ARGUMENTS;
1864
6.05k
    break;
1865
6.05k
  default:
1866
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1867
6.05k
  }
1868
6.05k
  apdu.p2 = 0;    /* first record, return FCI */
1869
6.05k
  apdu.lc = pathlen;
1870
6.05k
  apdu.data = path;
1871
6.05k
  apdu.datalen = pathlen;
1872
1873
6.05k
  if (file_out != NULL) {
1874
6.05k
    apdu.resp = buf;
1875
6.05k
    apdu.resplen = sizeof(buf);
1876
6.05k
    apdu.le = 0;
1877
6.05k
  } else {
1878
0
    apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT;
1879
0
  }
1880
1881
6.05k
  if (path[0] == 0x29) { /* TODO:0x29 accords with FID prefix in profile  */
1882
    /* Not allowed to select private key file, so fake fci. */
1883
    /* 62 16 82 02 11 00 83 02 29 00 85 02 08 00 86 08 FF 90 90 90 FF FF FF FF */
1884
673
    apdu.resplen = 0x18;
1885
673
    memcpy(apdu.resp,
1886
673
           "\x6f\x16\x82\x02\x11\x00\x83\x02\x29\x00\x85\x02\x08\x00\x86\x08\xff\x90\x90\x90\xff\xff\xff\xff",
1887
673
           apdu.resplen);
1888
673
    apdu.resp[9] = path[1];
1889
673
    apdu.sw1 = 0x90;
1890
673
    apdu.sw2 = 0x00;
1891
673
  }
1892
5.37k
  else {
1893
5.37k
    r = sc_transmit_apdu_t(card, &apdu);
1894
5.37k
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1895
5.37k
  }
1896
1897
5.20k
  if (file_out == NULL) {
1898
0
    if (apdu.sw1 == 0x61)
1899
0
      LOG_FUNC_RETURN(card->ctx, 0);
1900
0
    LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
1901
0
  }
1902
1903
5.20k
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1904
5.20k
  if (r)
1905
5.20k
    LOG_FUNC_RETURN(card->ctx, r);
1906
2.73k
  if (apdu.resplen < 2)
1907
2.73k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1908
1909
2.41k
  switch (apdu.resp[0]) {
1910
2.34k
  case 0x6F:
1911
2.34k
    file = sc_file_new();
1912
2.34k
    if (file == NULL)
1913
2.34k
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1914
2.34k
    file->path = *in_path;
1915
2.34k
    if (card->ops->process_fci == NULL) {
1916
0
      sc_file_free(file);
1917
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
1918
0
    }
1919
1920
2.34k
    if ((size_t) apdu.resp[1] + 2 <= apdu.resplen)
1921
2.18k
      card->ops->process_fci(card, file, apdu.resp + 2, apdu.resp[1]);
1922
2.34k
    epass2003_hook_file(file, 0);
1923
2.34k
    *file_out = file;
1924
2.34k
    break;
1925
19
  case 0x00:    /* proprietary coding */
1926
19
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1927
0
    break;
1928
46
  default:
1929
46
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1930
2.41k
  }
1931
2.34k
  return 0;
1932
2.41k
}
1933
1934
1935
static int
1936
epass2003_select_fid(struct sc_card *card, unsigned int id_hi, unsigned int id_lo,
1937
    sc_file_t ** file_out)
1938
6.05k
{
1939
6.05k
  int r;
1940
6.05k
  sc_file_t *file = NULL;
1941
6.05k
  sc_path_t path;
1942
1943
6.05k
  memset(&path, 0, sizeof(path));
1944
6.05k
  path.type = SC_PATH_TYPE_FILE_ID;
1945
6.05k
  path.value[0] = id_hi;
1946
6.05k
  path.value[1] = id_lo;
1947
6.05k
  path.len = 2;
1948
1949
6.05k
  r = epass2003_select_fid_(card, &path, &file);
1950
6.05k
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1951
1952
2.34k
  if (file_out) {
1953
812
    *file_out = file;
1954
1.53k
  } else {
1955
1.53k
    sc_file_free(file);
1956
1.53k
  }
1957
1958
2.34k
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1959
2.34k
}
1960
1961
1962
static int
1963
epass2003_select_aid(struct sc_card *card, const sc_path_t * in_path, sc_file_t ** file_out)
1964
2.08k
{
1965
2.08k
  int r = 0;
1966
1967
2.08k
  r = iso_ops->select_file(card, in_path, file_out);
1968
2.08k
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1969
1970
676
  if (file_out) {
1971
147
    sc_file_t *file = *file_out;
1972
1973
147
    file->type = SC_FILE_TYPE_DF;
1974
147
    file->ef_structure = SC_FILE_EF_UNKNOWN;
1975
147
    file->path.len = 0;
1976
147
    file->size = 0;
1977
    /* AID */
1978
147
    memcpy(file->name, in_path->value, in_path->len);
1979
147
    file->namelen = in_path->len;
1980
147
    file->id = 0x0000;
1981
147
  }
1982
1983
676
  LOG_FUNC_RETURN(card->ctx, r);
1984
676
}
1985
1986
1987
static int
1988
epass2003_select_path(struct sc_card *card, const u8 pathbuf[16], const size_t len,
1989
    sc_file_t ** file_out)
1990
4.48k
{
1991
4.48k
  u8 n_pathbuf[SC_MAX_PATH_SIZE];
1992
4.48k
  const u8 *path = pathbuf;
1993
4.48k
  size_t pathlen = len;
1994
4.48k
  unsigned int i;
1995
4.48k
  int r;
1996
1997
4.48k
  if (pathlen % 2 != 0 || pathlen > 6 || pathlen <= 0)
1998
4.48k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1999
2000
  /* if pathlen == 6 then the first FID must be MF (== 3F00) */
2001
4.45k
  if (pathlen == 6 && (path[0] != 0x3f || path[1] != 0x00))
2002
4.45k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2003
2004
  /* unify path (the first FID should be MF) */
2005
4.38k
  if (path[0] != 0x3f || path[1] != 0x00) {
2006
646
    n_pathbuf[0] = 0x3f;
2007
646
    n_pathbuf[1] = 0x00;
2008
646
    memcpy(n_pathbuf + 2, path, pathlen);
2009
646
    path = n_pathbuf;
2010
646
    pathlen += 2;
2011
646
  }
2012
2013
5.68k
  for (i = 0; i < pathlen - 2; i += 2) {
2014
4.46k
    r = epass2003_select_fid(card, path[i], path[i + 1], NULL);
2015
4.46k
    LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed");
2016
4.46k
  }
2017
2018
1.21k
  return epass2003_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out);
2019
4.38k
}
2020
2021
2022
static int
2023
epass2003_select_file(struct sc_card *card, const sc_path_t * in_path,
2024
    sc_file_t ** file_out)
2025
7.22k
{
2026
7.22k
  LOG_FUNC_CALLED(card->ctx);
2027
2028
7.22k
  switch (in_path->type) {
2029
646
  case SC_PATH_TYPE_FILE_ID:
2030
646
    if (in_path->len != 2)
2031
646
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2032
366
    return epass2003_select_fid(card, in_path->value[0], in_path->value[1], file_out);
2033
2.08k
  case SC_PATH_TYPE_DF_NAME:
2034
2.08k
    return epass2003_select_aid(card, in_path, file_out);
2035
4.48k
  case SC_PATH_TYPE_PATH:
2036
4.48k
    return epass2003_select_path(card, in_path->value, in_path->len, file_out);
2037
0
  default:
2038
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2039
7.22k
  }
2040
7.22k
}
2041
2042
static int
2043
epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env, int se_num)
2044
0
{
2045
0
  struct sc_apdu apdu;
2046
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
2047
0
  u8 *p;
2048
0
  unsigned short fid = 0;
2049
0
  int r, locked = 0;
2050
0
  epass2003_exdata *exdata = NULL;
2051
2052
0
  if (!card->drv_data)
2053
0
    return SC_ERROR_INVALID_ARGUMENTS;
2054
2055
0
  exdata = (epass2003_exdata *)card->drv_data;
2056
2057
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0);
2058
2059
0
  p = sbuf;
2060
0
  *p++ = 0x80;    /* algorithm reference */
2061
0
  *p++ = 0x01;
2062
0
  *p++ = 0x84;
2063
2064
0
  *p++ = 0x81;
2065
0
  *p++ = 0x02;
2066
2067
0
  fid = 0x2900;
2068
0
  fid += (unsigned short)(0x20 * (env->key_ref[0] & 0xff));
2069
0
  *p++ = fid >> 8;
2070
0
  *p++ = fid & 0xff;
2071
0
  r = (int)(p - sbuf);
2072
0
  apdu.lc = r;
2073
0
  apdu.datalen = r;
2074
0
  apdu.data = sbuf;
2075
2076
0
  if (env->algorithm == SC_ALGORITHM_EC) {
2077
0
    apdu.p2 = 0xB6;
2078
0
    exdata->currAlg = SC_ALGORITHM_EC;
2079
0
    if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA1) {
2080
0
      sbuf[2] = 0x91;
2081
0
      exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA1;
2082
0
    } else if (env->algorithm_flags & SC_ALGORITHM_ECDSA_HASH_SHA256) {
2083
0
      sbuf[2] = 0x92;
2084
0
      exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_SHA256;
2085
0
    } else {
2086
0
      sbuf[2] = 0x92;
2087
0
      exdata->ecAlgFlags = SC_ALGORITHM_ECDSA_HASH_NONE;
2088
0
    }
2089
0
  } else if (env->algorithm == SC_ALGORITHM_RSA) {
2090
0
    exdata->currAlg = SC_ALGORITHM_RSA;
2091
0
    apdu.p2 = 0xB8;
2092
0
    sc_log(card->ctx, "setenv RSA Algorithm alg_flags = %0lx\n", env->algorithm_flags);
2093
0
  } else {
2094
0
    sc_log(card->ctx, "%0lx Alg Not Supported!", env->algorithm);
2095
0
  }
2096
2097
0
  if (se_num > 0) {
2098
0
    r = sc_lock(card);
2099
0
    LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
2100
0
    locked = 1;
2101
0
  }
2102
0
  if (apdu.datalen != 0) {
2103
0
    r = sc_transmit_apdu_t(card, &apdu);
2104
0
    if (r) {
2105
0
      sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r));
2106
0
      goto err;
2107
0
    }
2108
2109
0
    r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2110
0
    if (r) {
2111
0
      sc_log(card->ctx, "%s: Card returned error", sc_strerror(r));
2112
0
      goto err;
2113
0
    }
2114
0
  }
2115
0
  if (se_num <= 0)
2116
0
    return 0;
2117
2118
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF2, se_num);
2119
0
  r = sc_transmit_apdu_t(card, &apdu);
2120
0
  sc_unlock(card);
2121
2122
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2123
0
  return sc_check_sw(card, apdu.sw1, apdu.sw2);
2124
2125
0
err:
2126
0
  if (locked)
2127
0
    sc_unlock(card);
2128
0
  return r;
2129
0
}
2130
2131
2132
static int
2133
epass2003_restore_security_env(struct sc_card *card, int se_num)
2134
0
{
2135
0
  LOG_FUNC_CALLED(card->ctx);
2136
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2137
0
}
2138
2139
2140
static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t datalen,
2141
    u8 * out, size_t outlen)
2142
0
{
2143
0
  int r;
2144
0
  struct sc_apdu apdu;
2145
0
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
2146
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
2147
0
  epass2003_exdata *exdata = NULL;
2148
2149
0
  LOG_FUNC_CALLED(card->ctx);
2150
2151
0
  if (!card->drv_data)
2152
0
    return SC_ERROR_INVALID_ARGUMENTS;
2153
2154
0
  exdata = (epass2003_exdata *)card->drv_data;
2155
2156
0
  if (exdata->currAlg == SC_ALGORITHM_EC) {
2157
0
    if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA1) {
2158
0
      r = hash_data(card, data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA1);
2159
0
      LOG_TEST_RET(card->ctx, r, "hash_data failed");
2160
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0x2A, 0x9E, 0x9A);
2161
0
      apdu.data = sbuf;
2162
0
      apdu.lc = 0x14;
2163
0
      apdu.datalen = 0x14;
2164
0
    } else if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA256) {
2165
0
      r = hash_data(card, data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA256);
2166
0
      LOG_TEST_RET(card->ctx, r, "hash_data failed");
2167
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0x2A, 0x9E, 0x9A);
2168
0
      apdu.data = sbuf;
2169
0
      apdu.lc = 0x20;
2170
0
      apdu.datalen = 0x20;
2171
0
    } else if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_NONE) {
2172
0
      sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A);
2173
0
      apdu.data = data;
2174
0
      apdu.lc = datalen;
2175
0
      apdu.datalen = datalen;
2176
0
    } else {
2177
0
      return SC_ERROR_NOT_SUPPORTED;
2178
0
    }
2179
0
    apdu.resp = rbuf;
2180
0
    apdu.resplen = sizeof(rbuf);
2181
0
    apdu.le = 0;
2182
2183
0
    r = sc_transmit_apdu_t(card, &apdu);
2184
0
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2185
0
    if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
2186
0
      size_t len = apdu.resplen > outlen ? outlen : apdu.resplen;
2187
0
      memcpy(out, apdu.resp, len);
2188
0
      LOG_FUNC_RETURN(card->ctx, (int)len);
2189
0
    }
2190
0
    LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
2191
0
  } else if (exdata->currAlg == SC_ALGORITHM_RSA) {
2192
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86);
2193
0
    apdu.resp = rbuf;
2194
0
    apdu.resplen = sizeof(rbuf);
2195
0
    apdu.le = 0;
2196
2197
0
    memcpy(sbuf, data, datalen);
2198
0
    apdu.data = sbuf;
2199
0
    apdu.lc = datalen;
2200
0
    apdu.datalen = datalen;
2201
0
  } else {
2202
0
    sc_format_apdu(card, &apdu, SC_APDU_CASE_4_EXT, 0x2A, 0x80, 0x86);
2203
0
    apdu.resp = rbuf;
2204
0
    apdu.resplen = sizeof(rbuf);
2205
0
    apdu.le = 256;
2206
2207
0
    memcpy(sbuf, data, datalen);
2208
0
    apdu.data = sbuf;
2209
0
    apdu.lc = datalen;
2210
0
    apdu.datalen = datalen;
2211
0
  }
2212
2213
0
  r = sc_transmit_apdu_t(card, &apdu);
2214
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2215
2216
0
  if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
2217
0
    size_t len = apdu.resplen > outlen ? outlen : apdu.resplen;
2218
0
    memcpy(out, apdu.resp, len);
2219
0
    LOG_FUNC_RETURN(card->ctx, (int)len);
2220
0
  }
2221
2222
0
  LOG_FUNC_RETURN(card->ctx, sc_check_sw(card, apdu.sw1, apdu.sw2));
2223
0
}
2224
2225
2226
static int
2227
acl_to_ac_byte(struct sc_card *card, const struct sc_acl_entry *e)
2228
1.04k
{
2229
1.04k
  if (e == NULL)
2230
0
    return SC_ERROR_OBJECT_NOT_FOUND;
2231
2232
1.04k
  switch (e->method) {
2233
928
  case SC_AC_NONE:
2234
928
    LOG_FUNC_RETURN(card->ctx, EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE);
2235
6
  case SC_AC_NEVER:
2236
6
    LOG_FUNC_RETURN(card->ctx, EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_NOONE);
2237
109
  default:
2238
109
    LOG_FUNC_RETURN(card->ctx, EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER);
2239
1.04k
  }
2240
2241
0
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_INCORRECT_PARAMETERS);
2242
0
}
2243
2244
/* Use epass2003 sec_attr to add acl entries */
2245
int
2246
sec_attr_to_entry(struct sc_card *card, sc_file_t *file, int index)
2247
3.90k
{
2248
3.90k
  int i;
2249
3.90k
  int found = 0;
2250
2251
3.90k
  unsigned int method;
2252
3.90k
  unsigned long  keyref;
2253
2254
3.90k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2255
2256
3.90k
  switch (file->sec_attr[index]) {
2257
2.26k
  case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE):
2258
2.26k
    method = SC_AC_NONE;
2259
2.26k
    keyref = SC_AC_KEY_REF_NONE;
2260
2.26k
    break;
2261
295
  case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER):
2262
295
    method = SC_AC_CHV;
2263
295
    keyref = 1;
2264
295
    break;
2265
1.34k
  default:
2266
1.34k
    sc_log(card->ctx, "Unknown value 0x%2.2x in file->sec_attr[%d]", file->sec_attr[index], index);
2267
1.34k
    method = SC_AC_NEVER;
2268
1.34k
    keyref = SC_AC_KEY_REF_NONE;
2269
1.34k
    break;
2270
3.90k
  }
2271
2272
132k
  for (i = 0; i < (int)(sizeof(sec_attr_to_acl_entry) / sizeof(sec_attr_to_acl_entries_t)); i++) {
2273
128k
    const sec_attr_to_acl_entries_t *e = &sec_attr_to_acl_entry[i];
2274
2275
128k
    if (index == e->index && file->type == e->file_type
2276
8.78k
        && file->ef_structure == e->file_ef_structure) {
2277
        /* may add multiple entries */
2278
326
      sc_file_add_acl_entry(file, e->op, method, keyref);
2279
326
      found++;
2280
326
    }
2281
128k
  }
2282
3.90k
  if (found != 1) {
2283
3.82k
    sc_log(card->ctx,"found %d entries ", found);
2284
3.82k
  }
2285
2286
3.90k
  return 0;
2287
3.90k
}
2288
2289
static int
2290
epass2003_process_fci(struct sc_card *card, sc_file_t * file, const u8 * buf, size_t buflen)
2291
2.18k
{
2292
2.18k
  sc_context_t *ctx = card->ctx;
2293
2.18k
  size_t taglen, len = buflen;
2294
2.18k
  const u8 *tag = NULL, *p = buf;
2295
2296
2.18k
  sc_log(ctx, "processing FCI bytes");
2297
2.18k
  tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen);
2298
2.18k
  if (tag != NULL && taglen == 2) {
2299
726
    file->id = (tag[0] << 8) | tag[1];
2300
726
    sc_log(ctx, "  file identifier: 0x%02X%02X", tag[0], tag[1]);
2301
726
  }
2302
2303
2.18k
  tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen);
2304
2.18k
  if (tag != NULL && taglen > 0 && taglen < 3) {
2305
68
    file->size = tag[0];
2306
68
    if (taglen == 2)
2307
56
      file->size = (file->size << 8) + tag[1];
2308
68
    sc_log(ctx, "  bytes in file: %"SC_FORMAT_LEN_SIZE_T"u",
2309
68
         file->size);
2310
68
  }
2311
2312
2.18k
  if (tag == NULL) {
2313
2.07k
    tag = sc_asn1_find_tag(ctx, p, len, 0x81, &taglen);
2314
2.07k
    if (tag != NULL && taglen >= 2) {
2315
36
      int bytes = (tag[0] << 8) + tag[1];
2316
2317
36
      sc_log(ctx, "  bytes in file: %d", bytes);
2318
36
      file->size = bytes;
2319
36
    }
2320
2.07k
  }
2321
2322
2.18k
  tag = sc_asn1_find_tag(ctx, p, len, 0x82, &taglen);
2323
2.18k
  if (tag != NULL) {
2324
973
    if (taglen > 0) {
2325
955
      unsigned char byte = tag[0];
2326
955
      const char *type;
2327
2328
955
      if (byte == 0x38) {
2329
37
        type = "DF";
2330
37
        file->type = SC_FILE_TYPE_DF;
2331
918
      } else if (0x01 <= byte && byte <= 0x07) {
2332
121
        type = "working EF";
2333
121
        file->type = SC_FILE_TYPE_WORKING_EF;
2334
121
        switch (byte) {
2335
60
        case 0x01:
2336
60
          file->ef_structure = SC_FILE_EF_TRANSPARENT;
2337
60
          break;
2338
29
        case 0x02:
2339
29
          file->ef_structure = SC_FILE_EF_LINEAR_FIXED;
2340
29
          break;
2341
13
        case 0x04:
2342
13
          file->ef_structure = SC_FILE_EF_LINEAR_FIXED;
2343
13
          break;
2344
19
        default:
2345
19
          break;
2346
121
        }
2347
2348
797
      } else if (0x10 == byte) {
2349
6
        type = "BSO";
2350
6
        file->type = SC_FILE_TYPE_BSO;
2351
791
      } else if (0x11 <= byte) {
2352
758
        type = "internal EF";
2353
758
        file->type = SC_FILE_TYPE_INTERNAL_EF;
2354
758
        switch (byte) {
2355
674
        case 0x11:
2356
674
          break;
2357
20
        case 0x12:
2358
20
          break;
2359
64
        default:
2360
64
          break;
2361
758
        }
2362
758
      } else {
2363
33
        type = "unknown";
2364
33
        file->type = SC_FILE_TYPE_INTERNAL_EF;
2365
33
      }
2366
955
      sc_log(ctx, "type %s, EF structure %d", type, byte);
2367
955
    }
2368
973
  }
2369
2370
2.18k
  tag = sc_asn1_find_tag(ctx, p, len, 0x84, &taglen);
2371
2.18k
  if (tag != NULL && taglen > 0 && taglen <= 16) {
2372
34
    memcpy(file->name, tag, taglen);
2373
34
    file->namelen = taglen;
2374
2375
34
    sc_log_hex(ctx, "File name", file->name, file->namelen);
2376
34
    if (!file->type)
2377
23
      file->type = SC_FILE_TYPE_DF;
2378
34
  }
2379
2380
2.18k
  tag = sc_asn1_find_tag(ctx, p, len, 0x85, &taglen);
2381
2.18k
  if (tag != NULL && taglen)
2382
721
    sc_file_set_prop_attr(file, tag, taglen);
2383
1.46k
  else
2384
1.46k
    file->prop_attr_len = 0;
2385
2386
2.18k
  tag = sc_asn1_find_tag(ctx, p, len, 0xA5, &taglen);
2387
2.18k
  if (tag != NULL && taglen)
2388
11
    sc_file_set_prop_attr(file, tag, taglen);
2389
2390
2.18k
  tag = sc_asn1_find_tag(ctx, p, len, 0x86, &taglen);
2391
2.18k
  if (tag != NULL && taglen) {
2392
838
    unsigned int i;
2393
838
    sc_file_set_sec_attr(file, tag, taglen);
2394
8.56k
    for (i = 0; i< taglen; i++)
2395
7.72k
      if (tag[i] != 0xff) /* skip unused entries */
2396
3.90k
        sec_attr_to_entry(card, file, i);
2397
838
  }
2398
2399
2.18k
  tag = sc_asn1_find_tag(ctx, p, len, 0x8A, &taglen);
2400
2.18k
  if (tag != NULL && taglen == 1) {
2401
97
    if (tag[0] == 0x01)
2402
29
      file->status = SC_FILE_STATUS_CREATION;
2403
68
    else if (tag[0] == 0x07 || tag[0] == 0x05)
2404
29
      file->status = SC_FILE_STATUS_ACTIVATED;
2405
39
    else if (tag[0] == 0x06 || tag[0] == 0x04)
2406
20
      file->status = SC_FILE_STATUS_INVALIDATED;
2407
97
  }
2408
2.18k
  file->magic = SC_FILE_MAGIC;
2409
2410
2.18k
  return 0;
2411
2.18k
}
2412
2413
2414
static int
2415
epass2003_construct_fci(struct sc_card *card, const sc_file_t * file,
2416
    u8 * out, size_t * outlen)
2417
388
{
2418
388
  u8 *p = out;
2419
388
  u8 buf[64];
2420
388
  unsigned char ops[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2421
388
  int rv;
2422
388
  unsigned ii;
2423
2424
388
  if (*outlen < 2)
2425
0
    return SC_ERROR_BUFFER_TOO_SMALL;
2426
2427
388
  *p++ = 0x62;
2428
388
  p++;
2429
388
  if (file->type == SC_FILE_TYPE_WORKING_EF) {
2430
40
    if (file->ef_structure == SC_FILE_EF_TRANSPARENT) {
2431
37
      buf[0] = (file->size >> 8) & 0xFF;
2432
37
      buf[1] = file->size & 0xFF;
2433
37
      sc_asn1_put_tag(0x80, buf, 2, p, *outlen - (p - out), &p);
2434
37
    }
2435
40
  }
2436
388
  if (file->type == SC_FILE_TYPE_DF) {
2437
26
    buf[0] = 0x38;
2438
26
    buf[1] = 0x00;
2439
26
    sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2440
26
  }
2441
362
  else if (file->type == SC_FILE_TYPE_WORKING_EF) {
2442
40
    buf[0] = file->ef_structure & 7;
2443
40
    if (file->ef_structure == SC_FILE_EF_TRANSPARENT) {
2444
37
      buf[1] = 0x00;
2445
37
      sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2446
37
    } else if (file->ef_structure == SC_FILE_EF_LINEAR_FIXED ||
2447
3
        file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) {
2448
0
      buf[1] = 0x00;
2449
0
      buf[2] = 0x00;
2450
0
      buf[3] = 0x40;  /* record length */
2451
0
      buf[4] = 0x00;  /* record count */
2452
0
      sc_asn1_put_tag(0x82, buf, 5, p, *outlen - (p - out), &p);
2453
3
    } else {
2454
3
      return SC_ERROR_NOT_SUPPORTED;
2455
3
    }
2456
2457
40
  }
2458
322
  else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
2459
279
    if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
2460
213
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) {
2461
213
      buf[0] = 0x11;
2462
213
      buf[1] = 0x00;
2463
213
    } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2464
63
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2465
63
      buf[0] = 0x12;
2466
63
      buf[1] = 0x00;
2467
63
    } else {
2468
3
      return SC_ERROR_NOT_SUPPORTED;
2469
3
    }
2470
276
    sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2471
276
  } else if (file->type == SC_FILE_TYPE_BSO) {
2472
1
    buf[0] = 0x10;
2473
1
    buf[1] = 0x00;
2474
1
    sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2475
1
  }
2476
2477
382
  buf[0] = (file->id >> 8) & 0xFF;
2478
382
  buf[1] = file->id & 0xFF;
2479
382
  sc_asn1_put_tag(0x83, buf, 2, p, *outlen - (p - out), &p);
2480
382
  if (file->type == SC_FILE_TYPE_DF) {
2481
26
    if (file->namelen != 0) {
2482
13
      sc_asn1_put_tag(0x84, file->name, file->namelen, p, *outlen - (p - out), &p);
2483
13
    } else {
2484
13
      return SC_ERROR_INVALID_ARGUMENTS;
2485
13
    }
2486
26
  }
2487
369
  if (file->type == SC_FILE_TYPE_DF) {
2488
13
    unsigned char data[2] = {0x00, 0x7F};
2489
    /* 127 files at most */
2490
13
    sc_asn1_put_tag(0x85, data, sizeof(data), p, *outlen - (p - out), &p);
2491
356
  } else if (file->type == SC_FILE_TYPE_BSO) {
2492
1
    buf[0] = file->size & 0xff;
2493
1
    sc_asn1_put_tag(0x85, buf, 1, p, *outlen - (p - out), &p);
2494
355
  } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
2495
276
    if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
2496
160
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2497
133
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT ||
2498
276
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2499
276
      buf[0] = (file->size >> 8) & 0xFF;
2500
276
      buf[1] = file->size & 0xFF;
2501
276
      sc_asn1_put_tag(0x85, buf, 2, p, *outlen - (p - out), &p);
2502
276
    }
2503
276
  }
2504
369
  if (file->sec_attr_len) {
2505
0
    memcpy(buf, file->sec_attr, file->sec_attr_len);
2506
0
    sc_asn1_put_tag(0x86, buf, file->sec_attr_len, p, *outlen - (p - out), &p);
2507
2508
369
  } else {
2509
369
    sc_log(card->ctx, "SC_FILE_ACL");
2510
369
    if (file->type == SC_FILE_TYPE_DF) {
2511
13
      ops[0] = SC_AC_OP_LIST_FILES;
2512
13
      ops[1] = SC_AC_OP_CREATE;
2513
13
      ops[3] = SC_AC_OP_DELETE;
2514
356
    } else if (file->type == SC_FILE_TYPE_WORKING_EF) {
2515
37
      if (file->ef_structure == SC_FILE_EF_TRANSPARENT) {
2516
37
        ops[0] = SC_AC_OP_READ;
2517
37
        ops[1] = SC_AC_OP_UPDATE;
2518
37
        ops[3] = SC_AC_OP_DELETE;
2519
37
      } else if (file->ef_structure == SC_FILE_EF_LINEAR_FIXED ||
2520
0
          file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE) {
2521
0
        ops[0] = SC_AC_OP_READ;
2522
0
        ops[1] = SC_AC_OP_UPDATE;
2523
0
        ops[2] = SC_AC_OP_WRITE;
2524
0
        ops[3] = SC_AC_OP_DELETE;
2525
0
      } else {
2526
0
        return SC_ERROR_NOT_SUPPORTED;
2527
0
      }
2528
319
    } else if (file->type == SC_FILE_TYPE_BSO) {
2529
1
      ops[0] = SC_AC_OP_UPDATE;
2530
1
      ops[3] = SC_AC_OP_DELETE;
2531
318
    } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
2532
276
      if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
2533
213
          file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) {
2534
213
        ops[1] = SC_AC_OP_UPDATE;
2535
213
        ops[2] = SC_AC_OP_CRYPTO;
2536
213
        ops[3] = SC_AC_OP_DELETE;
2537
213
      } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2538
63
          file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2539
63
        ops[0] = SC_AC_OP_READ;
2540
63
        ops[1] = SC_AC_OP_UPDATE;
2541
63
        ops[2] = SC_AC_OP_CRYPTO;
2542
63
        ops[3] = SC_AC_OP_DELETE;
2543
63
      }
2544
276
    } else {
2545
42
      return SC_ERROR_NOT_SUPPORTED;
2546
42
    }
2547
2548
2.94k
    for (ii = 0; ii < sizeof(ops); ii++) {
2549
2.61k
      const struct sc_acl_entry *entry;
2550
2551
2.61k
      buf[ii] = 0xFF;
2552
2.61k
      if (ops[ii] == 0xFF)
2553
1.57k
        continue;
2554
1.04k
      entry = sc_file_get_acl_entry(file, ops[ii]);
2555
2556
1.04k
      rv = acl_to_ac_byte(card, entry);
2557
1.04k
      LOG_TEST_RET(card->ctx, rv, "Invalid ACL");
2558
2559
1.04k
      buf[ii] = rv;
2560
1.04k
    }
2561
327
    sc_asn1_put_tag(0x86, buf, sizeof(ops), p, *outlen - (p - out), &p);
2562
327
    if (file->size == 256) {
2563
135
      out[4]= 0x13;
2564
135
    }
2565
327
  }
2566
2567
  /* VT ??? */
2568
327
  if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2569
300
      file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2570
63
    unsigned char data[2] = {0x00, 0x66};
2571
63
    sc_asn1_put_tag(0x87, data, sizeof(data), p, *outlen - (p - out), &p);
2572
63
    if (file->size == 256) {
2573
36
      out[4] = 0x14;
2574
36
    }
2575
63
  }
2576
2577
327
  out[1] = p - out - 2;
2578
2579
327
  *outlen = p - out;
2580
327
  return 0;
2581
369
}
2582
2583
2584
static int
2585
epass2003_create_file(struct sc_card *card, sc_file_t * file)
2586
388
{
2587
388
  int r;
2588
388
  size_t len;
2589
388
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
2590
388
  struct sc_apdu apdu;
2591
2592
388
  len = SC_MAX_APDU_BUFFER_SIZE;
2593
2594
388
  epass2003_hook_file(file, 1);
2595
2596
388
  if (card->ops->construct_fci == NULL)
2597
388
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2598
2599
388
  r = epass2003_construct_fci(card, file, sbuf, &len);
2600
388
  LOG_TEST_RET(card->ctx, r, "construct_fci() failed");
2601
2602
327
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00);
2603
327
  apdu.lc = len;
2604
327
  apdu.datalen = len;
2605
327
  apdu.data = sbuf;
2606
2607
327
  r = sc_transmit_apdu_t(card, &apdu);
2608
327
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2609
321
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2610
321
  LOG_TEST_RET(card->ctx, r, "APDU sw1/2 wrong");
2611
2612
214
  epass2003_hook_file(file, 0);
2613
214
  return r;
2614
321
}
2615
2616
2617
static int
2618
epass2003_delete_file(struct sc_card *card, const sc_path_t * path)
2619
432
{
2620
432
  int r;
2621
432
  u8 sbuf[2];
2622
432
  struct sc_apdu apdu;
2623
2624
432
  LOG_FUNC_CALLED(card->ctx);
2625
2626
432
  r = sc_select_file(card, path, NULL);
2627
432
  LOG_TEST_RET(card->ctx, r, "Can not select file");
2628
140
  r = epass2003_hook_path((struct sc_path *)path, 1);
2629
140
  LOG_TEST_RET(card->ctx, r, "Can not hook path");
2630
2631
140
  sbuf[0] = path->value[path->len - 2];
2632
140
  sbuf[1] = path->value[path->len - 1];
2633
140
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00);
2634
140
  apdu.lc = 2;
2635
140
  apdu.datalen = 2;
2636
140
  apdu.data = sbuf;
2637
2638
140
  r = sc_transmit_apdu_t(card, &apdu);
2639
140
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2640
137
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2641
137
  LOG_TEST_RET(card->ctx, r, "Delete file failed");
2642
2643
110
  LOG_FUNC_RETURN(card->ctx, r);
2644
110
}
2645
2646
static int
2647
epass2003_list_files(struct sc_card *card, unsigned char *buf, size_t buflen)
2648
0
{
2649
0
  struct sc_apdu apdu;
2650
0
  unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
2651
0
  int r;
2652
2653
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2654
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x34, 0x00, 0x00);
2655
0
  apdu.cla = 0x80;
2656
0
  apdu.le = 0;
2657
0
  apdu.resplen = sizeof(rbuf);
2658
0
  apdu.resp = rbuf;
2659
2660
0
  r = sc_transmit_apdu_t(card, &apdu);
2661
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2662
2663
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2664
0
  LOG_TEST_RET(card->ctx, r, "Card returned error");
2665
2666
0
  if (apdu.resplen == 0x100 && rbuf[0] == 0 && rbuf[1] == 0)
2667
0
    LOG_FUNC_RETURN(card->ctx, 0);
2668
2669
0
  buflen = buflen < apdu.resplen ? buflen : apdu.resplen;
2670
0
  memcpy(buf, rbuf, buflen);
2671
2672
0
  LOG_FUNC_RETURN(card->ctx, (int)buflen);
2673
0
}
2674
2675
2676
static int
2677
internal_write_rsa_key_factor(struct sc_card *card, unsigned short fid, u8 factor,
2678
    sc_pkcs15_bignum_t data)
2679
0
{
2680
0
  int r;
2681
0
  struct sc_apdu apdu;
2682
0
  u8 sbuff[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0};
2683
2684
0
  LOG_FUNC_CALLED(card->ctx);
2685
2686
0
  sbuff[0] = ((fid & 0xff00) >> 8);
2687
0
  sbuff[1] = (fid & 0x00ff);
2688
0
  memcpy(&sbuff[2], data.data, data.len);
2689
//  sc_mem_reverse(&sbuff[2], data.len);
2690
2691
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3, 0xe7, factor, 0x00);
2692
0
  apdu.cla = 0x80;
2693
0
  apdu.lc = apdu.datalen = 2 + data.len;
2694
0
  apdu.data = sbuff;
2695
2696
0
  r = sc_transmit_apdu_t(card, &apdu);
2697
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2698
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2699
0
  LOG_TEST_RET(card->ctx, r, "Write rsa key factor failed");
2700
2701
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2702
0
}
2703
2704
2705
static int
2706
internal_write_rsa_key(struct sc_card *card, unsigned short fid, struct sc_pkcs15_prkey_rsa *rsa)
2707
0
{
2708
0
  int r;
2709
2710
0
  LOG_FUNC_CALLED(card->ctx);
2711
2712
0
  r = internal_write_rsa_key_factor(card, fid, 0x02, rsa->modulus);
2713
0
  LOG_TEST_RET(card->ctx, r, "write n failed");
2714
0
  r = internal_write_rsa_key_factor(card, fid, 0x03, rsa->d);
2715
0
  LOG_TEST_RET(card->ctx, r, "write d failed");
2716
2717
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2718
0
}
2719
2720
2721
static int
2722
hash_data(struct sc_card *card, const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType)
2723
22
{
2724
2725
22
  if ((NULL == data) || (NULL == hash))
2726
0
    return SC_ERROR_INVALID_ARGUMENTS;
2727
2728
22
  if (mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA1) {
2729
22
    unsigned char data_hash[24] = {0};
2730
22
    size_t len = 0;
2731
2732
22
    sha1_digest(card, data, datalen, data_hash);
2733
22
    len = REVERSE_ORDER4(datalen);
2734
22
    memcpy(&data_hash[20], &len, 4);
2735
22
    memcpy(hash, data_hash, 24);
2736
22
  } else if (mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA256) {
2737
0
    unsigned char data_hash[36] = {0};
2738
0
    size_t len = 0;
2739
2740
0
    sha256_digest(card, data, datalen, data_hash);
2741
0
    len = REVERSE_ORDER4(datalen);
2742
0
    memcpy(&data_hash[32], &len, 4);
2743
0
    memcpy(hash, data_hash, 36);
2744
0
  } else {
2745
0
    return SC_ERROR_NOT_SUPPORTED;
2746
0
  }
2747
2748
22
  return SC_SUCCESS;
2749
22
}
2750
2751
2752
static int
2753
install_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid,
2754
    unsigned char useac, unsigned char modifyac, unsigned char EC,
2755
    unsigned char *data, unsigned long dataLen)
2756
22
{
2757
22
  int r;
2758
22
  struct sc_apdu apdu;
2759
22
  unsigned char isapp = 0x00; /* appendable */
2760
22
  unsigned char tmp_data[256] = {0};
2761
2762
22
  tmp_data[0] = ktype;
2763
22
  tmp_data[1] = kid;
2764
22
  tmp_data[2] = useac;
2765
22
  tmp_data[3] = modifyac;
2766
22
  tmp_data[8] = 0xFF;
2767
2768
22
  if (0x04 == ktype || 0x06 == ktype) {
2769
22
    tmp_data[4] = EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_SO;
2770
22
    tmp_data[5] = EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_SO;
2771
22
    tmp_data[7] = (kid == PIN_ID[0] ? EPASS2003_AC_USER : EPASS2003_AC_SO);
2772
22
    tmp_data[9] = (EC << 4) | EC;
2773
22
  }
2774
2775
22
  memcpy(&tmp_data[10], data, dataLen);
2776
22
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xe3, isapp, 0x00);
2777
22
  apdu.cla = 0x80;
2778
22
  apdu.lc = apdu.datalen = 10 + dataLen;
2779
22
  apdu.data = tmp_data;
2780
2781
22
  r = sc_transmit_apdu_t(card, &apdu);
2782
22
  LOG_TEST_RET(card->ctx, r, "APDU install_secret_key failed");
2783
21
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2784
21
  LOG_TEST_RET(card->ctx, r, "install_secret_key failed");
2785
2786
6
  return r;
2787
21
}
2788
2789
2790
static int
2791
internal_install_pre(struct sc_card *card)
2792
0
{
2793
0
  int r;
2794
  /* init key for enc */
2795
0
  r = install_secret_key(card, 0x01, 0x00,
2796
0
             EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE,
2797
0
             EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE,
2798
0
             0, g_init_key_enc, 16);
2799
0
  LOG_TEST_RET(card->ctx, r, "Install init key failed");
2800
2801
  /* init key for mac */
2802
0
  r = install_secret_key(card, 0x02, 0x00,
2803
0
             EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE,
2804
0
             EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE,
2805
0
             0, g_init_key_mac, 16);
2806
0
  LOG_TEST_RET(card->ctx, r, "Install init key failed");
2807
2808
0
  return r;
2809
0
}
2810
2811
2812
/* use external auth secret as pin */
2813
static int
2814
internal_install_pin(struct sc_card *card, sc_epass2003_wkey_data * pin)
2815
22
{
2816
22
  int r;
2817
22
  unsigned char hash[HASH_LEN] = {0};
2818
2819
22
  r = hash_data(card, pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
2820
22
  LOG_TEST_RET(card->ctx, r, "hash data failed");
2821
2822
22
  r = install_secret_key(card, 0x04, pin->key_data.es_secret.kid,
2823
22
             pin->key_data.es_secret.ac[0],
2824
22
             pin->key_data.es_secret.ac[1],
2825
22
             pin->key_data.es_secret.EC, hash, HASH_LEN);
2826
22
  LOG_TEST_RET(card->ctx, r, "Install failed");
2827
2828
6
  return r;
2829
22
}
2830
2831
2832
static int
2833
epass2003_write_key(struct sc_card *card, sc_epass2003_wkey_data * data)
2834
22
{
2835
22
  LOG_FUNC_CALLED(card->ctx);
2836
2837
22
  if (data->type & SC_EPASS2003_KEY) {
2838
0
    if (data->type == SC_EPASS2003_KEY_RSA)
2839
0
      return internal_write_rsa_key(card, data->key_data.es_key.fid,
2840
0
                  data->key_data.es_key.rsa);
2841
0
    else
2842
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2843
22
  } else if (data->type & SC_EPASS2003_SECRET) {
2844
22
    if (data->type == SC_EPASS2003_SECRET_PRE)
2845
0
      return internal_install_pre(card);
2846
22
    else if (data->type == SC_EPASS2003_SECRET_PIN)
2847
22
      return internal_install_pin(card, data);
2848
0
    else
2849
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2850
22
  } else {
2851
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2852
0
  }
2853
2854
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2855
0
}
2856
2857
2858
static int
2859
epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data)
2860
46
{
2861
46
  int r;
2862
46
  size_t len = data->key_length;
2863
46
  struct sc_apdu apdu;
2864
46
  u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0};
2865
46
  u8 sbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0};
2866
2867
46
  LOG_FUNC_CALLED(card->ctx);
2868
2869
46
  if (len == 256) {
2870
30
    sbuf[0] = 0x02;
2871
30
  } else {
2872
16
    sbuf[0] = 0x01;
2873
16
  }
2874
46
  sbuf[1] = (u8) ((len >> 8) & 0xff);
2875
46
  sbuf[2] = (u8) (len & 0xff);
2876
46
  sbuf[3] = (u8) ((data->prkey_id >> 8) & 0xFF);
2877
46
  sbuf[4] = (u8) ((data->prkey_id) & 0xFF);
2878
46
  sbuf[5] = (u8) ((data->pukey_id >> 8) & 0xFF);
2879
46
  sbuf[6] = (u8) ((data->pukey_id) & 0xFF);
2880
2881
  /* generate key */
2882
46
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, 0x00);
2883
46
  apdu.lc = apdu.datalen = 7;
2884
46
  apdu.data = sbuf;
2885
2886
46
  r = sc_transmit_apdu_t(card, &apdu);
2887
46
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2888
45
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2889
45
  LOG_TEST_RET(card->ctx, r, "generate key pair failed");
2890
2891
  /* read public key */
2892
37
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xb4, 0x02, 0x00);
2893
37
  if (len == 256) {
2894
26
    apdu.p1 = 0x00;
2895
26
  }
2896
2897
37
  apdu.cla = 0x80;
2898
37
  apdu.lc = apdu.datalen = 2;
2899
37
  apdu.data = &sbuf[5];
2900
37
  apdu.resp = rbuf;
2901
37
  apdu.resplen = sizeof(rbuf);
2902
37
  apdu.le = 0x00;
2903
2904
37
  r = sc_transmit_apdu_t(card, &apdu);
2905
37
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2906
35
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2907
35
  LOG_TEST_RET(card->ctx, r, "get pukey failed");
2908
2909
30
  if (len < apdu.resplen)
2910
30
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2911
2912
27
  if (256 == len) { /* ECC 256 bit */
2913
20
    size_t xCoordinateLen = rbuf[1];
2914
20
    size_t yCoordinateLen;
2915
20
    unsigned char *tmp;
2916
2917
20
    if (2 + xCoordinateLen + 1 > apdu.resplen) {
2918
5
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
2919
5
    }
2920
15
    yCoordinateLen = rbuf[2 + xCoordinateLen + 1];
2921
15
    if (2 + xCoordinateLen + 2 + yCoordinateLen > apdu.resplen) {
2922
4
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
2923
4
    }
2924
11
    data->modulus_len = xCoordinateLen + yCoordinateLen;
2925
11
    tmp = (u8 *)malloc(data->modulus_len);
2926
11
    if (!tmp) {
2927
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
2928
0
    }
2929
2930
11
    if (0x58 == rbuf[0]) {
2931
5
      memcpy(tmp, &rbuf[2], xCoordinateLen);
2932
6
    } else {
2933
6
      free(tmp);
2934
6
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
2935
6
    }
2936
5
    if (0x59 == rbuf[2 + xCoordinateLen]) {
2937
2
      memcpy(tmp + xCoordinateLen, &rbuf[2+xCoordinateLen+2], yCoordinateLen);
2938
3
    } else {
2939
3
      free(tmp);
2940
3
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
2941
3
    }
2942
2943
2
    data->modulus = tmp;
2944
7
  } else {
2945
7
    data->modulus = (u8 *) malloc(len);
2946
7
    if (!data->modulus) {
2947
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
2948
7
    } else {
2949
7
      memcpy(data->modulus, rbuf, len);
2950
7
    }
2951
7
  }
2952
9
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2953
9
}
2954
2955
2956
static int
2957
epass2003_erase_card(struct sc_card *card)
2958
15
{
2959
15
  static const unsigned char install_magic_pin[26] = {
2960
    /* compare install_secret_key */
2961
15
      0x06, 0x01, 0x10, 0x16, 0x16, 0x16, 0x00, 0x0f, 0xff, 0x66,
2962
15
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2963
15
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2964
15
  };
2965
15
  static const unsigned char magic_pin[16] = {
2966
15
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2967
15
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2968
15
  };
2969
15
  static const unsigned char mf_path[2] = { 0x3f, 0x00 };
2970
15
  sc_apdu_t apdu;
2971
15
  int r;
2972
2973
15
  LOG_FUNC_CALLED(card->ctx);
2974
2975
  /* install magic pin */
2976
15
  sc_format_apdu(card, &apdu, 0x03, 0xe3, 0x00, 0x00);
2977
15
  apdu.cla = 0x80;
2978
15
  apdu.data = install_magic_pin;
2979
15
  apdu.datalen = apdu.lc = sizeof(install_magic_pin);
2980
15
  r = sc_transmit_apdu(card, &apdu);
2981
15
  LOG_TEST_RET(card->ctx, r, "APDU install magic pin failed");
2982
13
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2983
13
  LOG_TEST_RET(card->ctx, r, "install magic pin failed");
2984
2985
  /* verify magic pin */
2986
6
  sc_format_apdu(card, &apdu, 0x03, 0x20, 0x00, 0x01);
2987
6
  apdu.cla = 0;
2988
6
  apdu.data = magic_pin;
2989
6
  apdu.datalen = apdu.lc = sizeof(magic_pin);
2990
6
  r = sc_transmit_apdu(card, &apdu);
2991
6
  LOG_TEST_RET(card->ctx, r, "APDU verify magic pin failed");
2992
5
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2993
5
  LOG_TEST_RET(card->ctx, r, "verify magic pin failed");
2994
2995
  /* delete MF */
2996
3
  sc_format_apdu(card, &apdu, 0x03, 0xe4, 0x00, 0x00);
2997
3
  apdu.cla = 0;
2998
3
  apdu.data = mf_path;
2999
3
  apdu.datalen = apdu.lc = sizeof(mf_path);
3000
3
  r = sc_transmit_apdu(card, &apdu);
3001
3
  LOG_TEST_RET(card->ctx, r, "APDU delete MF failed");
3002
2
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
3003
2
  LOG_TEST_RET(card->ctx, r, "delete MF failed");
3004
3005
1
  LOG_FUNC_RETURN(card->ctx, r);
3006
1
}
3007
3008
3009
static int
3010
epass2003_get_serialnr(struct sc_card *card, sc_serial_number_t * serial)
3011
226
{
3012
226
  u8 rbuf[8];
3013
226
  size_t rbuf_len = sizeof(rbuf);
3014
3015
226
  LOG_FUNC_CALLED(card->ctx);
3016
3017
226
  if (SC_SUCCESS != get_data(card, 0x80, rbuf, rbuf_len))
3018
185
    return SC_ERROR_CARD_CMD_FAILED;
3019
3020
41
  card->serialnr.len = serial->len = 8;
3021
41
  memcpy(card->serialnr.value, rbuf, 8);
3022
41
  memcpy(serial->value, rbuf, 8);
3023
3024
41
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
3025
41
}
3026
3027
3028
static int
3029
epass2003_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
3030
1.50k
{
3031
1.50k
  LOG_FUNC_CALLED(card->ctx);
3032
3033
1.50k
  sc_log(card->ctx, "cmd is %0lx", cmd);
3034
1.50k
  switch (cmd) {
3035
22
  case SC_CARDCTL_ENTERSAFE_WRITE_KEY:
3036
22
    return epass2003_write_key(card, (sc_epass2003_wkey_data *) ptr);
3037
46
  case SC_CARDCTL_ENTERSAFE_GENERATE_KEY:
3038
46
    return epass2003_gen_key(card, (sc_epass2003_gen_key_data *) ptr);
3039
15
  case SC_CARDCTL_ERASE_CARD:
3040
15
    return epass2003_erase_card(card);
3041
226
  case SC_CARDCTL_GET_SERIALNR:
3042
226
    return epass2003_get_serialnr(card, (sc_serial_number_t *) ptr);
3043
1.19k
  default:
3044
1.19k
    return SC_ERROR_NOT_SUPPORTED;
3045
1.50k
  }
3046
1.50k
}
3047
3048
3049
static void
3050
internal_sanitize_pin_info(struct sc_pin_cmd_pin *pin, unsigned int num)
3051
452
{
3052
452
  pin->encoding = SC_PIN_ENCODING_ASCII;
3053
452
  pin->min_length = 4;
3054
452
  pin->max_length = 16;
3055
452
  pin->pad_length = 16;
3056
452
  pin->offset = 5 + num * 16;
3057
452
  pin->pad_char = 0x00;
3058
452
}
3059
3060
3061
static int
3062
get_external_key_maxtries(struct sc_card *card, unsigned char *maxtries)
3063
0
{
3064
0
  unsigned char maxcounter[2] = {0};
3065
0
  static const sc_path_t file_path = {
3066
0
    {0x3f, 0x00, 0x50, 0x15, 0x9f, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 6,
3067
0
    0,
3068
0
    0,
3069
0
    SC_PATH_TYPE_PATH,
3070
0
    {{0}, 0}
3071
0
  };
3072
0
  int ret;
3073
3074
0
  ret = sc_select_file(card, &file_path, NULL);
3075
0
  LOG_TEST_RET(card->ctx, ret, "select max counter file failed");
3076
3077
0
  ret = sc_read_binary(card, 0, maxcounter, 2, 0);
3078
0
  LOG_TEST_RET(card->ctx, ret, "read max counter file failed");
3079
3080
0
  *maxtries = maxcounter[0];
3081
0
  return SC_SUCCESS;
3082
0
}
3083
3084
3085
static int
3086
get_external_key_retries(struct sc_card *card, unsigned char kid, unsigned char *retries)
3087
0
{
3088
0
  int r;
3089
0
  struct sc_apdu apdu;
3090
0
  unsigned char random[16] = {0};
3091
3092
0
  r = sc_get_challenge(card, random, 8);
3093
0
  LOG_TEST_RET(card->ctx, r, "get challenge get_external_key_retries failed");
3094
3095
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x82, 0x01, 0x80 | kid);
3096
0
  apdu.resp = NULL;
3097
0
  apdu.resplen = 0;
3098
3099
0
  r = sc_transmit_apdu_t(card, &apdu);
3100
0
  LOG_TEST_RET(card->ctx, r, "APDU get_external_key_retries failed");
3101
3102
0
  if (retries && ((0x63 == (apdu.sw1 & 0xff)) && (0xC0 == (apdu.sw2 & 0xf0)))) {
3103
0
    *retries = (apdu.sw2 & 0x0f);
3104
0
    r = SC_SUCCESS;
3105
0
  } else {
3106
0
    LOG_TEST_RET(card->ctx, r, "get_external_key_retries failed");
3107
0
    r = SC_ERROR_CARD_CMD_FAILED;
3108
0
  }
3109
3110
0
  return r;
3111
0
}
3112
3113
static int
3114
epass2003_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
3115
0
{
3116
0
  u8 rbuf[16];
3117
0
  size_t out_len;
3118
0
  int r;
3119
3120
0
  LOG_FUNC_CALLED(card->ctx);
3121
3122
0
  r = iso_ops->get_challenge(card, rbuf, sizeof rbuf);
3123
0
  LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed");
3124
3125
0
  if (len < (size_t) r) {
3126
0
    out_len = len;
3127
0
  } else {
3128
0
    out_len = (size_t) r;
3129
0
  }
3130
0
  memcpy(rnd, rbuf, out_len);
3131
3132
0
  LOG_FUNC_RETURN(card->ctx, (int) out_len);
3133
0
}
3134
3135
3136
static int
3137
external_key_auth(struct sc_card *card, unsigned char kid,
3138
    unsigned char *data, size_t datalen)
3139
0
{
3140
0
  int r;
3141
0
  struct sc_apdu apdu;
3142
0
  unsigned char random[16] = {0};
3143
0
  unsigned char tmp_data[16] = {0};
3144
0
  unsigned char hash[HASH_LEN] = {0};
3145
0
  unsigned char iv[16] = {0};
3146
3147
0
  r = sc_get_challenge(card, random, 8);
3148
0
  LOG_TEST_RET(card->ctx, r, "get challenge external_key_auth failed");
3149
3150
0
  r = hash_data(card, data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
3151
0
  LOG_TEST_RET(card->ctx, r, "hash data failed");
3152
3153
0
  r = des3_encrypt_cbc(card, hash, HASH_LEN, iv, random, 8, tmp_data);
3154
0
  LOG_TEST_RET(card->ctx, r, "encryption failed");
3155
3156
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x01, 0x80 | kid);
3157
0
  apdu.lc = apdu.datalen = 8;
3158
0
  apdu.data = tmp_data;
3159
3160
0
  r = sc_transmit_apdu_t(card, &apdu);
3161
0
  LOG_TEST_RET(card->ctx, r, "APDU external_key_auth failed");
3162
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
3163
0
  LOG_TEST_RET(card->ctx, r, "external_key_auth failed");
3164
3165
0
  return r;
3166
0
}
3167
3168
3169
static int
3170
update_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid,
3171
    const unsigned char *data, unsigned long datalen)
3172
0
{
3173
0
  int r;
3174
0
  struct sc_apdu apdu;
3175
0
  unsigned char hash[HASH_LEN] = {0};
3176
0
  unsigned char tmp_data[256] = {0};
3177
0
  unsigned char maxtries = 0;
3178
3179
0
  r = hash_data(card, data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1);
3180
0
  LOG_TEST_RET(card->ctx, r, "hash data failed");
3181
3182
0
  r = get_external_key_maxtries(card, &maxtries);
3183
0
  LOG_TEST_RET(card->ctx, r, "get max counter failed");
3184
3185
0
  tmp_data[0] = (maxtries << 4) | maxtries;
3186
0
  memcpy(&tmp_data[1], hash, HASH_LEN);
3187
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xe5, ktype, kid);
3188
0
  apdu.cla = 0x80;
3189
0
  apdu.lc = apdu.datalen = 1 + HASH_LEN;
3190
0
  apdu.data = tmp_data;
3191
3192
0
  r = sc_transmit_apdu_t(card, &apdu);
3193
0
  LOG_TEST_RET(card->ctx, r, "APDU update_secret_key failed");
3194
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
3195
0
  LOG_TEST_RET(card->ctx, r, "update_secret_key failed");
3196
3197
0
  return r;
3198
0
}
3199
3200
/* use external auth secret as pin */
3201
static int
3202
epass2003_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data)
3203
226
{
3204
226
  int r;
3205
226
  u8 kid;
3206
226
  u8 retries = 0;
3207
226
  u8 pin_low = 3;
3208
226
  unsigned char maxtries = 0;
3209
3210
226
  LOG_FUNC_CALLED(card->ctx);
3211
3212
226
  internal_sanitize_pin_info(&data->pin1, 0);
3213
226
  internal_sanitize_pin_info(&data->pin2, 1);
3214
226
  data->flags |= SC_PIN_CMD_NEED_PADDING;
3215
226
  kid = data->pin_reference;
3216
3217
226
  if (NULL == (unsigned char *)data->pin1.data || 0 == data->pin1.len)
3218
226
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
3219
3220
  /* get pin retries */
3221
0
  if (data->cmd == SC_PIN_CMD_GET_INFO) {
3222
3223
0
    r = get_external_key_retries(card, 0x80 | kid, &retries);
3224
0
    if (r == SC_SUCCESS) {
3225
0
      data->pin1.tries_left = retries;
3226
3227
0
      r = get_external_key_maxtries(card, &maxtries);
3228
0
      LOG_TEST_RET(card->ctx, r, "get max counter failed");
3229
3230
0
      data->pin1.max_tries = maxtries;
3231
0
    }
3232
0
    LOG_TEST_RET(card->ctx, r, "verify pin failed");
3233
0
  } else if (data->cmd == SC_PIN_CMD_UNBLOCK) { /* verify */
3234
0
    r = external_key_auth(card, (kid + 1), (unsigned char *)data->pin1.data,
3235
0
        data->pin1.len);
3236
0
    LOG_TEST_RET(card->ctx, r, "verify pin failed");
3237
0
  } else if (data->cmd == SC_PIN_CMD_CHANGE || data->cmd == SC_PIN_CMD_UNBLOCK) { /* change */
3238
0
    r = external_key_auth(card, kid, (unsigned char *)data->pin1.data,
3239
0
        data->pin1.len);
3240
0
    LOG_TEST_RET(card->ctx, r, "verify pin failed");
3241
3242
0
    r = update_secret_key(card, 0x04, kid, data->pin2.data,
3243
0
        (unsigned long)data->pin2.len);
3244
0
    LOG_TEST_RET(card->ctx, r, "change pin failed");
3245
0
  } else {
3246
0
    r = external_key_auth(card, kid, (unsigned char *)data->pin1.data,
3247
0
        data->pin1.len);
3248
0
    LOG_TEST_RET(card->ctx, r, "verify pin failed");
3249
3250
0
    r = get_external_key_retries(card, 0x80 | kid, &retries);
3251
0
    if (retries < pin_low)
3252
0
      sc_log(card->ctx, "Verification failed (remaining tries: %d)", retries);
3253
3254
0
    LOG_TEST_RET(card->ctx, r, "verify pin failed");
3255
0
  }
3256
3257
0
  if (r == SC_SUCCESS) {
3258
0
    data->pin1.logged_in = SC_PIN_STATE_LOGGED_IN;
3259
0
  }
3260
0
  return r;
3261
0
}
3262
3263
static int
3264
epass2003_logout(struct sc_card *card)
3265
0
{
3266
0
  epass2003_exdata *exdata = NULL;
3267
3268
0
  if (!card->drv_data)
3269
0
    return SC_ERROR_INVALID_ARGUMENTS;
3270
3271
0
  exdata = (epass2003_exdata *)card->drv_data;
3272
0
  if (exdata->sm) {
3273
0
    sc_sm_stop(card);
3274
0
    return epass2003_refresh(card);
3275
0
  }
3276
3277
0
  return SC_ERROR_NOT_SUPPORTED;
3278
0
}
3279
3280
static struct sc_card_driver *sc_get_driver(void)
3281
18.5k
{
3282
18.5k
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
3283
3284
18.5k
  if (iso_ops == NULL)
3285
1
    iso_ops = iso_drv->ops;
3286
3287
18.5k
  epass2003_ops = *iso_ops;
3288
3289
18.5k
  epass2003_ops.match_card = epass2003_match_card;
3290
18.5k
  epass2003_ops.init = epass2003_init;
3291
18.5k
  epass2003_ops.finish = epass2003_finish;
3292
18.5k
  epass2003_ops.write_binary = NULL;
3293
18.5k
  epass2003_ops.write_record = NULL;
3294
18.5k
  epass2003_ops.select_file = epass2003_select_file;
3295
18.5k
  epass2003_ops.get_response = NULL;
3296
18.5k
  epass2003_ops.restore_security_env = epass2003_restore_security_env;
3297
18.5k
  epass2003_ops.set_security_env = epass2003_set_security_env;
3298
18.5k
  epass2003_ops.decipher = epass2003_decipher;
3299
18.5k
  epass2003_ops.compute_signature = epass2003_decipher;
3300
18.5k
  epass2003_ops.create_file = epass2003_create_file;
3301
18.5k
  epass2003_ops.delete_file = epass2003_delete_file;
3302
18.5k
  epass2003_ops.list_files = epass2003_list_files;
3303
18.5k
  epass2003_ops.card_ctl = epass2003_card_ctl;
3304
18.5k
  epass2003_ops.process_fci = epass2003_process_fci;
3305
18.5k
  epass2003_ops.construct_fci = epass2003_construct_fci;
3306
18.5k
  epass2003_ops.pin_cmd = epass2003_pin_cmd;
3307
18.5k
  epass2003_ops.check_sw = epass2003_check_sw;
3308
18.5k
  epass2003_ops.get_challenge = epass2003_get_challenge;
3309
18.5k
  epass2003_ops.logout = epass2003_logout;
3310
18.5k
  return &epass2003_drv;
3311
18.5k
}
3312
3313
struct sc_card_driver *sc_get_epass2003_driver(void)
3314
18.5k
{
3315
18.5k
  return sc_get_driver();
3316
18.5k
}
3317
#endif  /* #ifdef ENABLE_OPENSSL */
3318
#endif  /* #ifdef ENABLE_SM */