Coverage Report

Created: 2026-08-13 06:08

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
0
#define KEY_TYPE_AES  0x01  /* FIPS mode */
81
0
#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
0
#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
0
#define SM_PLAIN        0x00
92
0
#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
0
#define REVERSE_ORDER4(x) (       \
118
0
    ((unsigned long)x & 0xFF000000)>> 24  | \
119
0
    ((unsigned long)x & 0x00FF0000)>>  8  | \
120
0
    ((unsigned long)x & 0x0000FF00)<<  8  | \
121
0
    ((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
0
{
246
0
  const int err_count = sizeof(epass2003_errors)/sizeof(epass2003_errors[0]);
247
0
  int i;
248
249
  /* Handle special cases here */
250
0
  if (sw1 == 0x6C) {
251
0
    sc_log(card->ctx, "Wrong length; correct length is %d", sw2);
252
0
    return SC_ERROR_WRONG_LENGTH;
253
0
  }
254
255
0
  for (i = 0; i < err_count; i++) {
256
0
    if (epass2003_errors[i].SWs == ((sw1 << 8) | sw2)) {
257
0
      sc_log(card->ctx, "%s", epass2003_errors[i].errorstr);
258
0
      return epass2003_errors[i].errorno;
259
0
    }
260
0
  }
261
262
0
  sc_log(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X", sw1, sw2);
263
0
  return SC_ERROR_CARD_CMD_FAILED;
264
0
}
265
266
static int
267
sc_transmit_apdu_t(sc_card_t *card, sc_apdu_t *apdu)
268
0
{
269
0
  size_t resplen = apdu->resplen;
270
0
  int r = sc_transmit_apdu(card, apdu);
271
0
  if ((0x69 == apdu->sw1 && 0x85 == apdu->sw2) || (0x69 == apdu->sw1 && 0x88 == apdu->sw2)) {
272
0
    epass2003_refresh(card);
273
    /* renew old resplen */
274
0
    apdu->resplen = resplen;
275
0
    r = sc_transmit_apdu(card, apdu);
276
0
  }
277
0
  return r;
278
0
}
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
0
{
284
0
  int r = SC_ERROR_INTERNAL;
285
0
  EVP_CIPHER_CTX * ctx = NULL;
286
0
  int outl = 0;
287
0
  int outl_tmp = 0;
288
0
  unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = {0};
289
290
0
  memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH);
291
0
  ctx = EVP_CIPHER_CTX_new();
292
0
  if (ctx == NULL)
293
0
    goto out;
294
295
0
  if (!EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv_tmp) || !EVP_CIPHER_CTX_set_padding(ctx, 0))
296
0
    goto out;
297
298
0
  if (!EVP_EncryptUpdate(ctx, output, &outl, input, (int)length))
299
0
    goto out;
300
301
0
  if (!EVP_EncryptFinal_ex(ctx, output + outl, &outl_tmp))
302
0
    goto out;
303
304
0
  r = SC_SUCCESS;
305
0
out:
306
0
  EVP_CIPHER_CTX_free(ctx);
307
0
  return r;
308
0
}
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
0
{
314
0
  int r = SC_ERROR_INTERNAL;
315
0
  EVP_CIPHER_CTX * ctx = NULL;
316
0
  int outl = 0;
317
0
  int outl_tmp = 0;
318
0
  unsigned char iv_tmp[EVP_MAX_IV_LENGTH] = {0};
319
320
0
  memcpy(iv_tmp, iv, EVP_MAX_IV_LENGTH);
321
0
  ctx = EVP_CIPHER_CTX_new();
322
0
  if (ctx == NULL)
323
0
    goto out;
324
325
0
  if (!EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv_tmp) ||
326
0
      !EVP_CIPHER_CTX_set_padding(ctx, 0))
327
0
    goto out;
328
329
0
  if (!EVP_DecryptUpdate(ctx, output, &outl, input, (int)length))
330
0
    goto out;
331
332
0
  if (!EVP_DecryptFinal_ex(ctx, output + outl, &outl_tmp))
333
0
    goto out;
334
335
0
  r = SC_SUCCESS;
336
0
out:
337
0
  EVP_CIPHER_CTX_free(ctx);
338
0
  return r;
339
0
}
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
0
{
416
0
  size_t mactlen = 0;
417
0
  int r = SC_ERROR_INTERNAL;
418
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
419
0
  CMAC_CTX *ctx = CMAC_CTX_new();
420
0
  if (ctx == NULL) {
421
0
    return SC_ERROR_INTERNAL;
422
0
  }
423
424
0
  if (!CMAC_Init(ctx, key, keysize / 8, EVP_aes_128_cbc(), NULL)) {
425
0
    goto err;
426
0
  }
427
0
  if (!CMAC_Update(ctx, input, length)) {
428
0
    goto err;
429
0
  }
430
0
  if (!CMAC_Final(ctx, output, &mactlen)) {
431
0
    goto err;
432
0
  }
433
0
  r = SC_SUCCESS;
434
0
err:
435
0
  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
0
  return r;
470
0
}
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
0
{
476
0
  unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
477
0
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-ECB");
478
0
  int r;
479
0
  r = openssl_enc(alg, key, iv, input, length, output);
480
0
  sc_evp_cipher_free(alg);
481
0
  if (r != SC_SUCCESS)
482
0
    sc_log_openssl(card->ctx);
483
0
  return r;
484
0
}
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
0
{
491
0
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-CBC");
492
0
  int r;
493
0
  r = openssl_enc(alg, key, iv, input, length, output);
494
0
  sc_evp_cipher_free(alg);
495
0
  if (r != SC_SUCCESS)
496
0
    sc_log_openssl(card->ctx);
497
0
  return r;
498
0
}
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
0
{
519
0
  unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
520
0
  unsigned char bKey[24] = {0};
521
0
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3");
522
0
  int r;
523
524
0
  if (keysize == 16) {
525
0
    memcpy(&bKey[0], key, 16);
526
0
    memcpy(&bKey[16], key, 8);
527
0
  } else {
528
0
    memcpy(&bKey[0], key, 24);
529
0
  }
530
531
0
  r = openssl_enc(alg, bKey, iv, input, length, output);
532
0
  sc_evp_cipher_free(alg);
533
0
  if (r != SC_SUCCESS)
534
0
    sc_log_openssl(card->ctx);
535
0
  return r;
536
0
}
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
0
{
543
0
  unsigned char bKey[24] = {0};
544
0
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3-CBC");
545
0
  int r;
546
547
0
  if (keysize == 16) {
548
0
    memcpy(&bKey[0], key, 16);
549
0
    memcpy(&bKey[16], key, 8);
550
0
  } else {
551
0
    memcpy(&bKey[0], key, 24);
552
0
  }
553
554
0
  r = openssl_enc(EVP_des_ede3_cbc(), bKey, iv, input, length, output);
555
0
  sc_evp_cipher_free(alg);
556
0
  if (r != SC_SUCCESS)
557
0
    sc_log_openssl(card->ctx);
558
0
  return r;
559
0
}
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
0
{
589
0
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-CBC");
590
0
  int r;
591
592
0
  r = openssl_enc(alg, key, iv, input, length, output);
593
0
  sc_evp_cipher_free(alg);
594
0
  if (r != SC_SUCCESS)
595
0
    sc_log_openssl(card->ctx);
596
0
  return r;
597
0
}
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
0
{
604
0
  EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-CBC");
605
0
  int r;
606
607
0
  r = openssl_dec(alg, key, iv, input, length, output);
608
0
  sc_evp_cipher_free(alg);
609
0
  if (r != SC_SUCCESS)
610
0
    sc_log_openssl(card->ctx);
611
0
  return r;
612
0
}
613
614
615
static int
616
openssl_dig(const EVP_MD * digest, const unsigned char *input, size_t length,
617
    unsigned char *output)
618
0
{
619
0
  int r = 0;
620
0
  EVP_MD_CTX *ctx = NULL;
621
0
  unsigned outl = 0;
622
623
0
  ctx = EVP_MD_CTX_create();
624
0
  if (ctx == NULL) {
625
0
    r = SC_ERROR_OUT_OF_MEMORY;
626
0
    goto err;
627
0
  }
628
629
0
  EVP_MD_CTX_init(ctx);
630
0
  if (!EVP_DigestInit_ex(ctx, digest, NULL) ||
631
0
      !EVP_DigestUpdate(ctx, input, length)) {
632
0
    r = SC_ERROR_INTERNAL;
633
0
    goto err;
634
0
  }
635
636
0
  if (!EVP_DigestFinal_ex(ctx, output, &outl)) {
637
0
    r = SC_ERROR_INTERNAL;
638
0
    goto err;
639
0
  }
640
0
  r = SC_SUCCESS;
641
0
err:
642
0
  if (ctx)
643
0
    EVP_MD_CTX_destroy(ctx);
644
645
0
  return r;
646
0
}
647
648
649
static int
650
sha1_digest(struct sc_card *card, const unsigned char *input, size_t length, unsigned char *output)
651
0
{
652
0
  EVP_MD *md = sc_evp_md(card->ctx, "SHA1");
653
0
  int r;
654
655
0
  r = openssl_dig(md, input, length, output);
656
0
  sc_evp_md_free(md);
657
0
  if (r != SC_SUCCESS)
658
0
    sc_log_openssl(card->ctx);
659
0
  return r;
660
0
}
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
0
{
680
0
  int r;
681
0
  struct sc_apdu apdu;
682
0
  unsigned char data[256] = {0};
683
0
  unsigned char tmp_sm;
684
0
  unsigned char isFips;
685
0
  unsigned long blocksize = 0;
686
0
  unsigned char cryptogram[256] = {0}; /* host cryptogram */
687
0
  unsigned char iv[16] = {0};
688
0
  epass2003_exdata *exdata = NULL;
689
690
0
  if (!card->drv_data)
691
0
    return SC_ERROR_INVALID_ARGUMENTS;
692
693
0
  exdata = (epass2003_exdata *)card->drv_data;
694
0
  isFips = exdata->bFipsCertification;
695
696
0
  LOG_FUNC_CALLED(card->ctx);
697
698
0
  if (1 != RAND_bytes(g_random, sizeof(g_random)))
699
0
    return SC_ERROR_INTERNAL;
700
701
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x50, 0x00, 0x00);
702
0
  apdu.cla = 0x80;
703
0
  apdu.lc = apdu.datalen = sizeof(g_random);
704
0
  apdu.data = g_random; /* host random */
705
0
  if (isFips)
706
0
    apdu.le = apdu.resplen = 29;
707
0
  else
708
0
    apdu.le = apdu.resplen = 28;
709
710
0
  apdu.resp = result; /* card random is result[12~19] */
711
712
0
  tmp_sm = exdata->sm;
713
0
  exdata->sm = SM_PLAIN;
714
0
  r = epass2003_transmit_apdu(card, &apdu);
715
0
  exdata->sm = tmp_sm;
716
0
  LOG_TEST_RET(card->ctx, r, "APDU gen_init_key failed");
717
718
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
719
0
  LOG_TEST_RET(card->ctx, r, "gen_init_key failed");
720
721
  /* Step 1 - Generate Derivation data */
722
0
  if (isFips) {
723
0
    memset(data, 0x00, 15);
724
0
    data[11] = 0x04;
725
0
    data[14] = 0x80;
726
0
    data[15] = 0x01;
727
0
    memcpy(&data[16], g_random, 8);
728
0
    memcpy(&data[24], &result[12 + 1], 8);
729
0
  } else {
730
0
    memcpy(data, &result[16], 4);
731
0
    memcpy(&data[4], g_random, 4);
732
0
    memcpy(&data[8], &result[12], 4);
733
0
    memcpy(&data[12], &g_random[4], 4);
734
0
  }
735
736
  /* Step 2,3 - Create S-ENC/S-MAC Session Key */
737
0
  if (KEY_TYPE_AES == key_type) {
738
0
    if (isFips) {
739
0
      r = aes128_encrypt_cmac(card, key_enc, 128, data, 32, exdata->sk_enc);
740
0
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac enc failed");
741
0
      memset(&data[11], 0x06, 1);
742
0
      r = aes128_encrypt_cmac(card, key_mac, 128, data, 32, exdata->sk_mac);
743
0
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac mac  failed");
744
0
    } else {
745
0
      r = aes128_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc);
746
0
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb enc  failed");
747
0
      r = aes128_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac);
748
0
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb mac  failed");
749
0
    }
750
0
  } else {
751
0
    r = des3_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc);
752
0
    LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed");
753
0
    r = des3_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac);
754
0
    LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed");
755
0
  }
756
757
0
  if (isFips) {
758
0
    data[11] = 0x00;
759
0
    data[14] = 0x40;
760
0
  } else {
761
0
    memcpy(data, g_random, 8);
762
0
    memcpy(&data[8], &result[12], 8);
763
0
    data[16] = 0x80;
764
0
    blocksize = (key_type == KEY_TYPE_AES ? 16 : 8);
765
0
    memset(&data[17], 0x00, blocksize - 1);
766
0
  }
767
768
  /* calculate host cryptogram */
769
0
  if (KEY_TYPE_AES == key_type) {
770
0
    if (isFips) {
771
0
      r = aes128_encrypt_cmac(card, exdata->sk_enc, 128, data, 32, cryptogram);
772
0
    } else {
773
0
      r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram);
774
0
    }
775
0
  } else {
776
0
    r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram);
777
0
  }
778
779
0
  LOG_TEST_RET(card->ctx, r, "calculate host cryptogram failed");
780
781
  /* verify card cryptogram */
782
0
  if (isFips) {
783
0
    if (0 != memcmp(&cryptogram[0], &result[20+1], 8))
784
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED);
785
0
  } else {
786
0
    if (0 != memcmp(&cryptogram[16], &result[20], 8))
787
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_CARD_CMD_FAILED);
788
0
  }
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
0
{
897
0
  struct sc_context *ctx = card->ctx;
898
0
  int r;
899
0
  unsigned char result[256] = {0};
900
0
  unsigned char ran_key[8] = {0};
901
0
  epass2003_exdata *exdata = NULL;
902
903
0
  if (!card->drv_data)
904
0
    return SC_ERROR_INVALID_ARGUMENTS;
905
0
  exdata = (epass2003_exdata *)card->drv_data;
906
907
0
  LOG_FUNC_CALLED(ctx);
908
909
0
  r = gen_init_key(card, key_enc, key_mac, result, exdata->smtype);
910
0
  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
0
{
927
0
  int r = SC_SUCCESS;
928
0
  epass2003_exdata *exdata = NULL;
929
930
0
  if (!card->drv_data)
931
0
    return SC_ERROR_INVALID_ARGUMENTS;
932
933
0
  exdata = (epass2003_exdata *)card->drv_data;
934
935
0
  if (exdata->sm) {
936
0
    card->sm_ctx.sm_mode = 0;
937
0
    r = mutual_auth(card, g_init_key_enc, g_init_key_mac);
938
0
    card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
939
0
    LOG_TEST_RET(card->ctx, r, "mutual_auth failed");
940
0
  }
941
942
0
  return r;
943
0
}
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
0
{
951
0
  size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
952
0
  unsigned char pad[4096] = {0};
953
0
  size_t pad_len;
954
0
  size_t tlv_more;  /* increased tlv length */
955
0
  unsigned char iv[16] = {0};
956
0
  epass2003_exdata *exdata = NULL;
957
0
  int r = 0;
958
959
0
  if (!card->drv_data)
960
0
    return SC_ERROR_INVALID_ARGUMENTS;
961
962
0
  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
0
  if (apdu->lc >= sizeof(pad) - block_size - 5)
966
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_DATA,
967
0
        "ePass2003 secure messaging APDU data too large");
968
969
  /* padding */
970
0
  apdu_buf[block_size] = 0x87;
971
0
  memcpy(pad, apdu->data, apdu->lc);
972
0
  pad[apdu->lc] = 0x80;
973
0
  if ((apdu->lc + 1) % block_size)
974
0
    pad_len = ((apdu->lc + 1) / block_size + 1) * block_size;
975
0
  else
976
0
    pad_len = apdu->lc + 1;
977
978
  /* encode Lc' */
979
0
  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
0
  } else {
987
0
    apdu_buf[block_size + 1] = (unsigned char)pad_len + 1;
988
0
    apdu_buf[block_size + 2] = 0x01;
989
0
    tlv_more = 3;
990
0
  }
991
0
  memcpy(data_tlv, &apdu_buf[block_size], tlv_more);
992
993
  /* encrypt Data */
994
0
  if (KEY_TYPE_AES == key_type) {
995
0
    r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);
996
0
    LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed");
997
0
  } else {
998
0
    r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);
999
0
    LOG_TEST_RET(card->ctx, r, "des3_encrypt_cbc failed");
1000
0
  }
1001
1002
0
  memcpy(data_tlv + tlv_more, apdu_buf + block_size + tlv_more, pad_len);
1003
0
  *data_tlv_len = tlv_more + pad_len;
1004
0
  return 0;
1005
0
}
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
0
{
1013
0
  size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
1014
1015
0
  *(apdu_buf + block_size + data_tlv_len) = 0x97;
1016
0
  if (apdu->le > 0x7F) {
1017
    /* Le' > 0x7E, use extended APDU */
1018
0
    *(apdu_buf + block_size + data_tlv_len + 1) = 2;
1019
0
    *(apdu_buf + block_size + data_tlv_len + 2) = (unsigned char)(apdu->le / 0x100);
1020
0
    *(apdu_buf + block_size + data_tlv_len + 3) = (unsigned char)(apdu->le % 0x100);
1021
0
    memcpy(le_tlv, apdu_buf + block_size + data_tlv_len, 4);
1022
0
    *le_tlv_len = 4;
1023
0
  } else {
1024
0
    *(apdu_buf + block_size + data_tlv_len + 1) = 1;
1025
0
    *(apdu_buf + block_size + data_tlv_len + 2) = (unsigned char)apdu->le;
1026
0
    memcpy(le_tlv, apdu_buf + block_size + data_tlv_len, 3);
1027
0
    *le_tlv_len = 3;
1028
0
  }
1029
0
  return 0;
1030
0
}
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
0
{
1038
0
  size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
1039
0
  unsigned char mac[4096] = {0};
1040
0
  size_t mac_len;
1041
0
  unsigned char icv[16] = {0};
1042
0
  int r ;
1043
0
  int i = (KEY_TYPE_AES == key_type ? 15 : 7);
1044
0
  epass2003_exdata *exdata = NULL;
1045
1046
0
  if (!card->drv_data)
1047
0
    return SC_ERROR_INVALID_ARGUMENTS;
1048
1049
0
  exdata = (epass2003_exdata *)card->drv_data;
1050
1051
0
  if (data_tlv_len + le_tlv_len + block_size + 1 > sizeof(mac)) {
1052
0
    return SC_ERROR_BUFFER_TOO_SMALL;
1053
0
  }
1054
1055
0
  if (0 == data_tlv_len && 0 == le_tlv_len) {
1056
0
    mac_len = block_size;
1057
0
  } else {
1058
    /* padding */
1059
0
    *(apdu_buf + block_size + data_tlv_len + le_tlv_len) = 0x80;
1060
0
    if ((data_tlv_len + le_tlv_len + 1) % block_size) {
1061
0
      mac_len = (((data_tlv_len + le_tlv_len + 1) / block_size) +
1062
0
          1) * block_size + block_size;
1063
0
    } else {
1064
0
      mac_len = data_tlv_len + le_tlv_len + 1 + block_size;
1065
0
    }
1066
0
    memset((apdu_buf + block_size + data_tlv_len + le_tlv_len + 1),
1067
0
           0, (mac_len - (data_tlv_len + le_tlv_len + 1)));
1068
0
  }
1069
1070
  /* increase icv */
1071
0
  for (; i >= 0; i--) {
1072
0
    if (exdata->icv_mac[i] == 0xff) {
1073
0
      exdata->icv_mac[i] = 0;
1074
0
    } else {
1075
0
      exdata->icv_mac[i]++;
1076
0
      break;
1077
0
    }
1078
0
  }
1079
1080
  /* calculate MAC */
1081
0
  memset(icv, 0, sizeof(icv));
1082
0
  memcpy(icv, exdata->icv_mac, 16);
1083
0
  if (KEY_TYPE_AES == key_type) {
1084
0
    if (exdata->bFipsCertification) {
1085
0
      for (int i = 0; i < 16; i++) {
1086
0
        apdu_buf[i] = apdu_buf[i] ^ icv[i];
1087
0
      }
1088
0
      r = aes128_encrypt_cmac(card, exdata->sk_mac, 128, apdu_buf, data_tlv_len + le_tlv_len + block_size, mac);
1089
0
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac failed");
1090
0
      memcpy(mac_tlv + 2, &mac[0 /*ulmacLen-16*/], 8);
1091
0
      for (int j = 0; j < 4; j++) {
1092
0
        apdu_buf[j] = apdu_buf[j] ^ icv[j];
1093
0
      }
1094
0
    } else {
1095
0
      r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac);
1096
0
      LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed");
1097
0
      memcpy(mac_tlv + 2, &mac[mac_len - 16], 8);
1098
0
    }
1099
0
  } else {
1100
0
    unsigned char iv[EVP_MAX_IV_LENGTH] = {0};
1101
0
    unsigned char tmp[8] = {0};
1102
0
    r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac);
1103
0
    LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 1 failed");
1104
0
    r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp);
1105
0
    LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed");
1106
0
    memset(iv, 0x00, sizeof iv);
1107
0
    r = des_encrypt_cbc(card, exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2);
1108
0
    LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 2 failed");
1109
0
  }
1110
1111
0
  *mac_tlv_len = 2 + 8;
1112
0
  return 0;
1113
0
}
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
0
{
1203
0
  size_t block_size = 0;
1204
0
  unsigned char dataTLV[4096] = {0};
1205
0
  size_t data_tlv_len = 0;
1206
0
  unsigned char le_tlv[256] = {0};
1207
0
  size_t le_tlv_len = 0;
1208
0
  size_t mac_tlv_len = 10;
1209
0
  size_t tmp_lc = 0;
1210
0
  size_t tmp_le = 0;
1211
0
  size_t expected_total_len;
1212
0
  unsigned char mac_tlv[256] = {0};
1213
0
  epass2003_exdata *exdata = NULL;
1214
1215
0
  mac_tlv[0] = 0x8E;
1216
0
  mac_tlv[1] = 8;
1217
  /* size_t plain_le = 0; */
1218
0
  if (!card->drv_data)
1219
0
    return SC_ERROR_INVALID_ARGUMENTS;
1220
0
  exdata = (epass2003_exdata*)card->drv_data;
1221
0
  block_size = (KEY_TYPE_DES == exdata->smtype ? 16 : 8);
1222
1223
0
  sm->cse = SC_APDU_CASE_4_SHORT;
1224
0
  apdu_buf[0] = (unsigned char)plain->cla;
1225
0
  apdu_buf[1] = (unsigned char)plain->ins;
1226
0
  apdu_buf[2] = (unsigned char)plain->p1;
1227
0
  apdu_buf[3] = (unsigned char)plain->p2;
1228
  /* plain_le = plain->le; */
1229
  /* padding */
1230
0
  if (exdata->bFipsCertification && plain->lc == 0 && apdu_buf[1] == 0x82 && apdu_buf[2] == 0x01) {
1231
0
    apdu_buf[4] = 0x00;
1232
0
  } else {
1233
0
    apdu_buf[4] = 0x80;
1234
0
  }
1235
0
  memset(&apdu_buf[5], 0x00, block_size - 5);
1236
1237
  /* Data -> Data' */
1238
0
  if (plain->lc != 0)
1239
0
    if (0 != construct_data_tlv(card, plain, apdu_buf, dataTLV, &data_tlv_len, exdata->smtype))
1240
0
      return -1;
1241
1242
0
  if (plain->le != 0 || (plain->le == 0 && plain->resplen != 0))
1243
0
    if (0 != construct_le_tlv(plain, apdu_buf, data_tlv_len, le_tlv,
1244
0
             &le_tlv_len, exdata->smtype))
1245
0
      return -1;
1246
1247
0
  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
0
  } else {
1251
0
    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
0
  }
1254
1255
0
  memset(apdu_buf + 4, 0, *apdu_buf_len - 4);
1256
0
  sm->lc = sm->datalen = data_tlv_len + le_tlv_len + mac_tlv_len;
1257
0
  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
0
  } else {
1264
0
    apdu_buf[4] = (unsigned char)sm->lc;
1265
0
    tmp_lc = 1;
1266
0
  }
1267
1268
  /* 2 is for Le extension in the worst case */
1269
0
  expected_total_len = 4 + tmp_lc + data_tlv_len + le_tlv_len + mac_tlv_len + 2;
1270
1271
0
  if (expected_total_len > *apdu_buf_len) {
1272
0
      return SC_ERROR_BUFFER_TOO_SMALL;
1273
0
  }
1274
1275
0
  memcpy(apdu_buf + 4 + tmp_lc, dataTLV, data_tlv_len);
1276
0
  memcpy(apdu_buf + 4 + tmp_lc + data_tlv_len, le_tlv, le_tlv_len);
1277
0
  memcpy(apdu_buf + 4 + tmp_lc + data_tlv_len + le_tlv_len, mac_tlv, mac_tlv_len);
1278
0
  memcpy((unsigned char *)sm->data, apdu_buf + 4 + tmp_lc, sm->datalen);
1279
0
  *apdu_buf_len = 0;
1280
1281
0
  if (4 == le_tlv_len) {
1282
0
    sm->cse = SC_APDU_CASE_4_EXT;
1283
0
    *(apdu_buf + 4 + tmp_lc + sm->lc) = (unsigned char)(plain->le / 0x100);
1284
0
    *(apdu_buf + 4 + tmp_lc + sm->lc + 1) = (unsigned char)(plain->le % 0x100);
1285
0
    tmp_le = 2;
1286
0
  } else if (3 == le_tlv_len) {
1287
0
    *(apdu_buf + 4 + tmp_lc + sm->lc) = (unsigned char)plain->le;
1288
0
    tmp_le = 1;
1289
0
  }
1290
1291
0
  *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
0
  return 0;
1294
0
}
1295
1296
1297
static int
1298
epass2003_sm_wrap_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm)
1299
0
{
1300
0
  unsigned char buf[4096] = {0}; /* APDU buffer */
1301
0
  size_t buf_len = sizeof(buf);
1302
0
  epass2003_exdata *exdata = NULL;
1303
1304
0
  if (!card->drv_data)
1305
0
    return SC_ERROR_INVALID_ARGUMENTS;
1306
1307
0
  exdata = (epass2003_exdata *)card->drv_data;
1308
1309
0
  LOG_FUNC_CALLED(card->ctx);
1310
1311
0
  if (exdata->sm)
1312
0
    plain->cla |= 0x0C;
1313
1314
0
  sm->cse = plain->cse;
1315
0
  sm->cla = plain->cla;
1316
0
  sm->ins = plain->ins;
1317
0
  sm->p1 = plain->p1;
1318
0
  sm->p2 = plain->p2;
1319
0
  sm->lc = plain->lc;
1320
0
  sm->le = plain->le;
1321
0
  sm->control = plain->control;
1322
0
  sm->flags = plain->flags;
1323
1324
0
  switch (sm->cla & 0x0C) {
1325
0
  case 0x00:
1326
0
  case 0x04:
1327
0
    sm->datalen = plain->datalen;
1328
0
    memcpy((void *)sm->data, plain->data, plain->datalen);
1329
0
    sm->resplen = plain->resplen;
1330
0
    memcpy(sm->resp, plain->resp, plain->resplen);
1331
0
    break;
1332
0
  case 0x0C:
1333
0
    memset(buf, 0, sizeof(buf));
1334
0
    if (0 != encode_apdu(card, plain, sm, buf, &buf_len))
1335
0
      return SC_ERROR_CARD_CMD_FAILED;
1336
0
    break;
1337
0
  default:
1338
0
    return SC_ERROR_INCORRECT_PARAMETERS;
1339
0
  }
1340
1341
0
  return SC_SUCCESS;
1342
0
}
1343
1344
static int
1345
epass2003_check_response_mac_and_sw(struct sc_card *card, struct sc_apdu *sm)
1346
0
{
1347
0
  unsigned char iv[16];
1348
0
  unsigned char *data = NULL, *mac = NULL;
1349
0
  size_t blocksize, mac_len;
1350
0
  int ret = -1;
1351
0
  size_t taglen;
1352
0
  const u8 *tag;
1353
0
  epass2003_exdata *exdata;
1354
0
  unsigned char *in = sm->resp;
1355
0
  unsigned char *alt_in;
1356
0
  size_t inlen = sm->resplen;
1357
0
  size_t len_correction;
1358
1359
  /* card/ctx/drv_data is already checked by caller */
1360
0
  exdata = (epass2003_exdata *)card->drv_data;
1361
1362
  /* The SM must contain at least TLV encoded SW and MAC fields. */
1363
0
  if (inlen < 14 )
1364
0
    return ret;
1365
1366
  /* compare BER-TLV encoded SW (TAG 0x99) and raw SW */
1367
0
  alt_in = in;
1368
0
  tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x99, &taglen);
1369
0
  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
0
    if (0x01 == in[2] && 0x82 != in[1]) {
1377
0
      sc_log(card->ctx, "Workaround, wrong BER-TLV ?");
1378
0
      len_correction = in[1] + 2;
1379
0
      if (inlen < len_correction)
1380
0
        return ret;
1381
0
      inlen -= len_correction;
1382
0
      alt_in += len_correction;
1383
0
      tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x99, &taglen);
1384
0
      if (tag == NULL || taglen != 2)
1385
0
        return ret;
1386
0
    } else {
1387
0
      return ret;
1388
0
    }
1389
0
  }
1390
0
  if (sm->sw1 != tag[0] || sm->sw2 != tag[1])
1391
0
    return ret;
1392
1393
  /* no documentation/real hardware to test, the response is accepted without MAC check */
1394
0
  if (exdata->bFipsCertification) {
1395
0
    sc_log(card->ctx, "Warning, MAC is not checked");
1396
0
    return 0;
1397
0
  }
1398
0
  tag = sc_asn1_find_tag(card->ctx, alt_in, inlen, 0x8e, &taglen);
1399
0
  if (tag == NULL || taglen != 8)
1400
0
    return ret;
1401
1402
0
  if (KEY_TYPE_AES == exdata->smtype)
1403
0
    blocksize = 16;
1404
0
  else
1405
0
    blocksize = 8;
1406
1407
0
  mac_len = tag - in - 2;
1408
0
  if (NULL == (data = calloc(1, mac_len + blocksize)))
1409
0
    goto end;
1410
0
  if (NULL == (mac = malloc(mac_len + blocksize)))
1411
0
    goto end;
1412
1413
  /* copy response to buffer and append padding */
1414
0
  memcpy(data, in, mac_len);
1415
0
  data[mac_len++] = 0x80;
1416
1417
0
  if (mac_len % blocksize)
1418
0
    mac_len += (blocksize - (mac_len % blocksize));
1419
1420
  /* calculate MAC */
1421
0
  memcpy(iv, exdata->icv_mac, blocksize);
1422
1423
0
  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
0
  } else {
1427
0
    uint8_t tmp[8];
1428
0
    uint8_t iv0[EVP_MAX_IV_LENGTH];
1429
0
    if (des_encrypt_cbc(card, exdata->sk_mac, 8, iv, data, mac_len, mac))
1430
0
      goto end;
1431
0
    memset(iv0, 0, EVP_MAX_IV_LENGTH);
1432
0
    if (des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv0, &mac[mac_len - 8], 8, tmp))
1433
0
      goto end;
1434
0
    memset(iv0, 0, EVP_MAX_IV_LENGTH);
1435
0
    if (des_encrypt_cbc(card, exdata->sk_mac, 8, iv0, tmp, 8, &mac[mac_len - 8]))
1436
0
      goto end;
1437
0
  }
1438
  /* compare MAC */
1439
0
  if (!memcmp(tag, mac + mac_len - blocksize, 8))
1440
0
    ret = 0;
1441
0
end:
1442
0
  if (data)
1443
0
    free(data);
1444
0
  if (mac)
1445
0
    free(mac);
1446
0
  return ret;
1447
0
}
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
0
{
1510
0
  int r;
1511
0
  size_t len = 0;
1512
0
  epass2003_exdata *exdata = NULL;
1513
1514
0
  if (!card->drv_data)
1515
0
    return SC_ERROR_INVALID_ARGUMENTS;
1516
1517
0
  exdata = (epass2003_exdata *)card->drv_data;
1518
1519
0
  LOG_FUNC_CALLED(card->ctx);
1520
1521
  /* verify MAC, and check if SW1,2 match SW1,2 encapsulated in SM */
1522
0
  if (exdata->sm) {
1523
0
    if (epass2003_check_response_mac_and_sw(card, sm)) {
1524
0
      sc_log(card->ctx, "MAC or SW incorrect");
1525
0
      return SC_ERROR_CARD_CMD_FAILED;
1526
0
    }
1527
0
  }
1528
0
  r = sc_check_sw(card, sm->sw1, sm->sw2);
1529
0
  if (r == SC_SUCCESS) {
1530
0
    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
0
    } else {
1535
0
      memcpy(plain->resp, sm->resp, sm->resplen);
1536
0
      len = sm->resplen;
1537
0
    }
1538
0
  }
1539
1540
0
  plain->resplen = len;
1541
0
  plain->sw1 = sm->sw1;
1542
0
  plain->sw2 = sm->sw2;
1543
1544
0
  sc_log(card->ctx,
1545
0
         "unwrapped APDU: resplen %"SC_FORMAT_LEN_SIZE_T"u, SW %02X%02X",
1546
0
         plain->resplen, plain->sw1, plain->sw2);
1547
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1548
0
}
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
0
{
1555
0
  struct sc_context *ctx = card->ctx;
1556
0
  int rv = SC_SUCCESS;
1557
1558
0
  LOG_FUNC_CALLED(ctx);
1559
0
  if (!sm_apdu)
1560
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1561
0
  if (!(*sm_apdu))
1562
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1563
1564
1565
0
  if (plain)
1566
0
    rv = epass2003_sm_unwrap_apdu(card, *sm_apdu, plain);
1567
1568
0
  if ((*sm_apdu)->data) {
1569
0
    unsigned char * p = (unsigned char *)((*sm_apdu)->data);
1570
0
    free(p);
1571
0
  }
1572
0
  if ((*sm_apdu)->resp) {
1573
0
    free((*sm_apdu)->resp);
1574
0
  }
1575
1576
0
  free(*sm_apdu);
1577
0
  *sm_apdu = NULL;
1578
1579
0
  LOG_FUNC_RETURN(ctx, rv);
1580
0
}
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
0
{
1587
0
  struct sc_context *ctx = card->ctx;
1588
0
  struct sc_apdu *apdu = NULL;
1589
0
  int rv;
1590
1591
0
  LOG_FUNC_CALLED(ctx);
1592
0
  if (!plain || !sm_apdu)
1593
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1594
1595
0
  *sm_apdu = NULL;
1596
  //construct new SM apdu from original apdu
1597
0
  apdu = calloc(1, sizeof(struct sc_apdu));
1598
0
  if (!apdu) {
1599
0
    rv = SC_ERROR_OUT_OF_MEMORY;
1600
0
    goto err;
1601
0
  }
1602
0
  apdu->data = calloc (1, SC_MAX_EXT_APDU_BUFFER_SIZE);
1603
0
  if (!apdu->data) {
1604
0
    rv = SC_ERROR_OUT_OF_MEMORY;
1605
0
    goto err;
1606
0
  }
1607
0
  apdu->resp = calloc (1, SC_MAX_EXT_APDU_BUFFER_SIZE);
1608
0
  if (!apdu->resp) {
1609
0
    rv = SC_ERROR_OUT_OF_MEMORY;
1610
0
    goto err;
1611
0
  }
1612
0
  apdu->datalen = SC_MAX_EXT_APDU_BUFFER_SIZE;
1613
0
  apdu->resplen = SC_MAX_EXT_APDU_BUFFER_SIZE;
1614
1615
0
  rv = epass2003_sm_wrap_apdu(card, plain, apdu);
1616
0
  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
0
  *sm_apdu = apdu;
1623
0
  apdu = NULL;
1624
0
err:
1625
0
  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
0
  LOG_FUNC_RETURN(ctx, rv);
1632
0
}
1633
1634
1635
static int
1636
epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu)
1637
0
{
1638
0
  int r;
1639
1640
0
  LOG_FUNC_CALLED(card->ctx);
1641
1642
0
  r = sc_transmit_apdu_t(card, apdu);
1643
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1644
1645
0
  return r;
1646
0
}
1647
1648
1649
static int
1650
get_data(struct sc_card *card, unsigned char type, unsigned char *data, size_t datalen)
1651
0
{
1652
0
  int r;
1653
0
  struct sc_apdu apdu;
1654
0
  unsigned char resp[SC_MAX_APDU_BUFFER_SIZE] = {0};
1655
0
  size_t resplen = SC_MAX_APDU_BUFFER_SIZE;
1656
0
  epass2003_exdata *exdata = NULL;
1657
1658
0
  if (!card->drv_data)
1659
0
    return SC_ERROR_INVALID_ARGUMENTS;
1660
1661
0
  exdata = (epass2003_exdata *)card->drv_data;
1662
1663
0
  LOG_FUNC_CALLED(card->ctx);
1664
1665
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, type);
1666
0
  apdu.resp = resp;
1667
0
  apdu.le = 0;
1668
0
  apdu.resplen = resplen;
1669
0
  if (0x86 == type) {
1670
    /* No SM temporarily */
1671
0
    unsigned char tmp_sm = exdata->sm;
1672
0
    exdata->sm = SM_PLAIN;
1673
0
    r = sc_transmit_apdu(card, &apdu);
1674
0
    exdata->sm = tmp_sm;
1675
0
  } else {
1676
0
    r = sc_transmit_apdu_t(card, &apdu);
1677
0
  }
1678
0
  LOG_TEST_RET(card->ctx, r, "APDU get_data failed");
1679
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1680
0
  LOG_TEST_RET(card->ctx, r, "get_data failed");
1681
1682
0
  memcpy(data, resp, datalen);
1683
0
  return r;
1684
0
}
1685
1686
/* card driver functions */
1687
1688
static int epass2003_match_card(struct sc_card *card)
1689
9
{
1690
9
  int r;
1691
1692
9
  LOG_FUNC_CALLED(card->ctx);
1693
9
  r = _sc_match_atr(card, epass2003_atrs, &card->type);
1694
9
  if (r < 0)
1695
9
    return 0;
1696
1697
0
  return 1;
1698
9
}
1699
1700
1701
static int
1702
epass2003_init(struct sc_card *card)
1703
0
{
1704
0
  unsigned int flags;
1705
0
  unsigned int ext_flags;
1706
0
  unsigned char data[SC_MAX_APDU_BUFFER_SIZE] = {0};
1707
0
  size_t datalen = SC_MAX_APDU_BUFFER_SIZE;
1708
0
  epass2003_exdata *exdata = NULL;
1709
0
  void *old_drv_data = card->drv_data;
1710
1711
0
  LOG_FUNC_CALLED(card->ctx);
1712
1713
0
  card->name = "epass2003";
1714
0
  card->cla = 0x00;
1715
0
  exdata = (epass2003_exdata *)calloc(1, sizeof(epass2003_exdata));
1716
0
  if (!exdata)
1717
0
    return SC_ERROR_OUT_OF_MEMORY;
1718
1719
0
  card->drv_data = exdata;
1720
1721
0
  exdata->sm = SM_SCP01;
1722
1723
  /* decide FIPS/Non-FIPS mode */
1724
0
  if (SC_SUCCESS != get_data(card, 0x86, data, datalen)) {
1725
0
    free(exdata);
1726
0
    card->drv_data = old_drv_data;
1727
0
    return SC_ERROR_INVALID_CARD;
1728
0
  }
1729
1730
0
  if (memcmp(&data[32], "\x87\x01\x01", 3) == 0 && memcmp(&data[0], "\x80\x01\x01", 3) == 0) {
1731
0
    exdata->bFipsCertification = 0x01;
1732
0
  } else {
1733
0
    exdata->bFipsCertification = 0x00;
1734
0
  }
1735
1736
0
  if (0x01 == data[2])
1737
0
    exdata->smtype = KEY_TYPE_AES;
1738
0
  else
1739
0
    exdata->smtype = KEY_TYPE_DES;
1740
1741
0
  if (0x84 == data[14]) {
1742
0
    if (0x00 == data[16]) {
1743
0
      exdata->sm = SM_PLAIN;
1744
0
    }
1745
0
  }
1746
1747
  /* mutual authentication */
1748
0
  card->max_recv_size = 0xD8;
1749
0
  card->max_send_size = 0xE8;
1750
1751
0
  card->sm_ctx.ops.open = epass2003_refresh;
1752
0
  card->sm_ctx.ops.get_sm_apdu = epass2003_sm_get_wrapped_apdu;
1753
0
  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
0
  epass2003_refresh(card);
1757
1758
0
  card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
1759
1760
0
  flags = SC_ALGORITHM_ONBOARD_KEY_GEN | SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_HASH_NONE;
1761
1762
0
  _sc_card_add_rsa_alg(card, 512, flags, 0);
1763
0
  _sc_card_add_rsa_alg(card, 768, flags, 0);
1764
0
  _sc_card_add_rsa_alg(card, 1024, flags, 0);
1765
0
  _sc_card_add_rsa_alg(card, 2048, flags, 0);
1766
1767
  //set EC Alg Flags
1768
0
  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
0
  ext_flags = 0;
1770
0
  _sc_card_add_ec_alg(card, 256, flags, ext_flags, NULL);
1771
1772
0
  card->caps = SC_CARD_CAP_RNG | SC_CARD_CAP_APDU_EXT;
1773
1774
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1775
0
}
1776
1777
static int
1778
epass2003_finish(sc_card_t *card)
1779
0
{
1780
0
  epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
1781
1782
0
  if (exdata)
1783
0
    free(exdata);
1784
0
  return SC_SUCCESS;
1785
0
}
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
0
{
1792
0
  u8 fid_h = 0;
1793
0
  u8 fid_l = 0;
1794
1795
0
  if (!path || path->len < 2)
1796
0
    return -1;
1797
0
  fid_h = path->value[path->len - 2];
1798
0
  fid_l = path->value[path->len - 1];
1799
1800
0
  switch (fid_h) {
1801
0
  case 0x29:
1802
0
  case 0x30:
1803
0
  case 0x31:
1804
0
  case 0x32:
1805
0
  case 0x33:
1806
0
  case 0x34:
1807
0
    if (inc)
1808
0
      fid_l = fid_l * FID_STEP;
1809
0
    else
1810
0
      fid_l = fid_l / FID_STEP;
1811
0
    path->value[path->len - 1] = fid_l;
1812
0
    return 1;
1813
0
  default:
1814
0
    break;
1815
0
  }
1816
0
  return 0;
1817
0
}
1818
1819
1820
static int
1821
epass2003_hook_file(struct sc_file *file, int inc)
1822
0
{
1823
0
  int fidl = file->id & 0xff;
1824
0
  int fidh = file->id & 0xff00;
1825
0
  int rv = 0;
1826
1827
0
  rv = epass2003_hook_path(&file->path, inc);
1828
1829
0
  if (rv > 0) {
1830
0
    if (inc)
1831
0
      file->id = fidh + fidl * FID_STEP;
1832
0
    else
1833
0
      file->id = fidh + fidl / FID_STEP;
1834
0
  }
1835
0
  if (rv < 0)
1836
0
    return rv;
1837
0
  return SC_SUCCESS;
1838
0
}
1839
1840
1841
static int
1842
epass2003_select_fid_(struct sc_card *card, sc_path_t * in_path, sc_file_t ** file_out)
1843
0
{
1844
0
  struct sc_apdu apdu;
1845
0
  u8 buf[SC_MAX_APDU_BUFFER_SIZE] = {0};
1846
0
  u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
1847
0
  int r;
1848
0
  size_t pathlen;
1849
0
  sc_file_t *file = NULL;
1850
1851
0
  r = epass2003_hook_path(in_path, 1);
1852
0
  LOG_TEST_RET(card->ctx, r, "Can not hook path");
1853
1854
0
  memcpy(path, in_path->value, in_path->len);
1855
0
  pathlen = in_path->len;
1856
1857
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x00);
1858
1859
0
  switch (in_path->type) {
1860
0
  case SC_PATH_TYPE_FILE_ID:
1861
0
    apdu.p1 = 0;
1862
0
    if (pathlen != 2)
1863
0
      return SC_ERROR_INVALID_ARGUMENTS;
1864
0
    break;
1865
0
  default:
1866
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1867
0
  }
1868
0
  apdu.p2 = 0;    /* first record, return FCI */
1869
0
  apdu.lc = pathlen;
1870
0
  apdu.data = path;
1871
0
  apdu.datalen = pathlen;
1872
1873
0
  if (file_out != NULL) {
1874
0
    apdu.resp = buf;
1875
0
    apdu.resplen = sizeof(buf);
1876
0
    apdu.le = 0;
1877
0
  } else {
1878
0
    apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT;
1879
0
  }
1880
1881
0
  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
0
    apdu.resplen = 0x18;
1885
0
    memcpy(apdu.resp,
1886
0
           "\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
0
           apdu.resplen);
1888
0
    apdu.resp[9] = path[1];
1889
0
    apdu.sw1 = 0x90;
1890
0
    apdu.sw2 = 0x00;
1891
0
  }
1892
0
  else {
1893
0
    r = sc_transmit_apdu_t(card, &apdu);
1894
0
    LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1895
0
  }
1896
1897
0
  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
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1904
0
  if (r)
1905
0
    LOG_FUNC_RETURN(card->ctx, r);
1906
0
  if (apdu.resplen < 2)
1907
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1908
1909
0
  switch (apdu.resp[0]) {
1910
0
  case 0x6F:
1911
0
    file = sc_file_new();
1912
0
    if (file == NULL)
1913
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
1914
0
    file->path = *in_path;
1915
0
    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
0
    if ((size_t) apdu.resp[1] + 2 <= apdu.resplen)
1921
0
      card->ops->process_fci(card, file, apdu.resp + 2, apdu.resp[1]);
1922
0
    epass2003_hook_file(file, 0);
1923
0
    *file_out = file;
1924
0
    break;
1925
0
  case 0x00:    /* proprietary coding */
1926
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1927
0
    break;
1928
0
  default:
1929
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1930
0
  }
1931
0
  return 0;
1932
0
}
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
0
{
1939
0
  int r;
1940
0
  sc_file_t *file = NULL;
1941
0
  sc_path_t path;
1942
1943
0
  memset(&path, 0, sizeof(path));
1944
0
  path.type = SC_PATH_TYPE_FILE_ID;
1945
0
  path.value[0] = id_hi;
1946
0
  path.value[1] = id_lo;
1947
0
  path.len = 2;
1948
1949
0
  r = epass2003_select_fid_(card, &path, &file);
1950
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1951
1952
0
  if (file_out) {
1953
0
    *file_out = file;
1954
0
  } else {
1955
0
    sc_file_free(file);
1956
0
  }
1957
1958
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1959
0
}
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
0
{
1965
0
  int r = 0;
1966
1967
0
  r = iso_ops->select_file(card, in_path, file_out);
1968
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
1969
1970
0
  if (file_out) {
1971
0
    sc_file_t *file = *file_out;
1972
1973
0
    file->type = SC_FILE_TYPE_DF;
1974
0
    file->ef_structure = SC_FILE_EF_UNKNOWN;
1975
0
    file->path.len = 0;
1976
0
    file->size = 0;
1977
    /* AID */
1978
0
    memcpy(file->name, in_path->value, in_path->len);
1979
0
    file->namelen = in_path->len;
1980
0
    file->id = 0x0000;
1981
0
  }
1982
1983
0
  LOG_FUNC_RETURN(card->ctx, r);
1984
0
}
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
0
{
1991
0
  u8 n_pathbuf[SC_MAX_PATH_SIZE];
1992
0
  const u8 *path = pathbuf;
1993
0
  size_t pathlen = len;
1994
0
  unsigned int i;
1995
0
  int r;
1996
1997
0
  if (pathlen % 2 != 0 || pathlen > 6 || pathlen <= 0)
1998
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1999
2000
  /* if pathlen == 6 then the first FID must be MF (== 3F00) */
2001
0
  if (pathlen == 6 && (path[0] != 0x3f || path[1] != 0x00))
2002
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2003
2004
  /* unify path (the first FID should be MF) */
2005
0
  if (path[0] != 0x3f || path[1] != 0x00) {
2006
0
    n_pathbuf[0] = 0x3f;
2007
0
    n_pathbuf[1] = 0x00;
2008
0
    memcpy(n_pathbuf + 2, path, pathlen);
2009
0
    path = n_pathbuf;
2010
0
    pathlen += 2;
2011
0
  }
2012
2013
0
  for (i = 0; i < pathlen - 2; i += 2) {
2014
0
    r = epass2003_select_fid(card, path[i], path[i + 1], NULL);
2015
0
    LOG_TEST_RET(card->ctx, r, "SELECT FILE (DF-ID) failed");
2016
0
  }
2017
2018
0
  return epass2003_select_fid(card, path[pathlen - 2], path[pathlen - 1], file_out);
2019
0
}
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
0
{
2026
0
  LOG_FUNC_CALLED(card->ctx);
2027
2028
0
  switch (in_path->type) {
2029
0
  case SC_PATH_TYPE_FILE_ID:
2030
0
    if (in_path->len != 2)
2031
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2032
0
    return epass2003_select_fid(card, in_path->value[0], in_path->value[1], file_out);
2033
0
  case SC_PATH_TYPE_DF_NAME:
2034
0
    return epass2003_select_aid(card, in_path, file_out);
2035
0
  case SC_PATH_TYPE_PATH:
2036
0
    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
0
  }
2040
0
}
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
0
{
2229
0
  if (e == NULL)
2230
0
    return SC_ERROR_OBJECT_NOT_FOUND;
2231
2232
0
  switch (e->method) {
2233
0
  case SC_AC_NONE:
2234
0
    LOG_FUNC_RETURN(card->ctx, EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE);
2235
0
  case SC_AC_NEVER:
2236
0
    LOG_FUNC_RETURN(card->ctx, EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_NOONE);
2237
0
  default:
2238
0
    LOG_FUNC_RETURN(card->ctx, EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER);
2239
0
  }
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
0
{
2248
0
  int i;
2249
0
  int found = 0;
2250
2251
0
  unsigned int method;
2252
0
  unsigned long  keyref;
2253
2254
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2255
2256
0
  switch (file->sec_attr[index]) {
2257
0
  case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_EVERYONE):
2258
0
    method = SC_AC_NONE;
2259
0
    keyref = SC_AC_KEY_REF_NONE;
2260
0
    break;
2261
0
  case (EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_USER):
2262
0
    method = SC_AC_CHV;
2263
0
    keyref = 1;
2264
0
    break;
2265
0
  default:
2266
0
    sc_log(card->ctx, "Unknown value 0x%2.2x in file->sec_attr[%d]", file->sec_attr[index], index);
2267
0
    method = SC_AC_NEVER;
2268
0
    keyref = SC_AC_KEY_REF_NONE;
2269
0
    break;
2270
0
  }
2271
2272
0
  for (i = 0; i < (int)(sizeof(sec_attr_to_acl_entry) / sizeof(sec_attr_to_acl_entries_t)); i++) {
2273
0
    const sec_attr_to_acl_entries_t *e = &sec_attr_to_acl_entry[i];
2274
2275
0
    if (index == e->index && file->type == e->file_type
2276
0
        && file->ef_structure == e->file_ef_structure) {
2277
        /* may add multiple entries */
2278
0
      sc_file_add_acl_entry(file, e->op, method, keyref);
2279
0
      found++;
2280
0
    }
2281
0
  }
2282
0
  if (found != 1) {
2283
0
    sc_log(card->ctx,"found %d entries ", found);
2284
0
  }
2285
2286
0
  return 0;
2287
0
}
2288
2289
static int
2290
epass2003_process_fci(struct sc_card *card, sc_file_t * file, const u8 * buf, size_t buflen)
2291
0
{
2292
0
  sc_context_t *ctx = card->ctx;
2293
0
  size_t taglen, len = buflen;
2294
0
  const u8 *tag = NULL, *p = buf;
2295
2296
0
  sc_log(ctx, "processing FCI bytes");
2297
0
  tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen);
2298
0
  if (tag != NULL && taglen == 2) {
2299
0
    file->id = (tag[0] << 8) | tag[1];
2300
0
    sc_log(ctx, "  file identifier: 0x%02X%02X", tag[0], tag[1]);
2301
0
  }
2302
2303
0
  tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen);
2304
0
  if (tag != NULL && taglen > 0 && taglen < 3) {
2305
0
    file->size = tag[0];
2306
0
    if (taglen == 2)
2307
0
      file->size = (file->size << 8) + tag[1];
2308
0
    sc_log(ctx, "  bytes in file: %"SC_FORMAT_LEN_SIZE_T"u",
2309
0
         file->size);
2310
0
  }
2311
2312
0
  if (tag == NULL) {
2313
0
    tag = sc_asn1_find_tag(ctx, p, len, 0x81, &taglen);
2314
0
    if (tag != NULL && taglen >= 2) {
2315
0
      int bytes = (tag[0] << 8) + tag[1];
2316
2317
0
      sc_log(ctx, "  bytes in file: %d", bytes);
2318
0
      file->size = bytes;
2319
0
    }
2320
0
  }
2321
2322
0
  tag = sc_asn1_find_tag(ctx, p, len, 0x82, &taglen);
2323
0
  if (tag != NULL) {
2324
0
    if (taglen > 0) {
2325
0
      unsigned char byte = tag[0];
2326
0
      const char *type;
2327
2328
0
      if (byte == 0x38) {
2329
0
        type = "DF";
2330
0
        file->type = SC_FILE_TYPE_DF;
2331
0
      } else if (0x01 <= byte && byte <= 0x07) {
2332
0
        type = "working EF";
2333
0
        file->type = SC_FILE_TYPE_WORKING_EF;
2334
0
        switch (byte) {
2335
0
        case 0x01:
2336
0
          file->ef_structure = SC_FILE_EF_TRANSPARENT;
2337
0
          break;
2338
0
        case 0x02:
2339
0
          file->ef_structure = SC_FILE_EF_LINEAR_FIXED;
2340
0
          break;
2341
0
        case 0x04:
2342
0
          file->ef_structure = SC_FILE_EF_LINEAR_FIXED;
2343
0
          break;
2344
0
        default:
2345
0
          break;
2346
0
        }
2347
2348
0
      } else if (0x10 == byte) {
2349
0
        type = "BSO";
2350
0
        file->type = SC_FILE_TYPE_BSO;
2351
0
      } else if (0x11 <= byte) {
2352
0
        type = "internal EF";
2353
0
        file->type = SC_FILE_TYPE_INTERNAL_EF;
2354
0
        switch (byte) {
2355
0
        case 0x11:
2356
0
          break;
2357
0
        case 0x12:
2358
0
          break;
2359
0
        default:
2360
0
          break;
2361
0
        }
2362
0
      } else {
2363
0
        type = "unknown";
2364
0
        file->type = SC_FILE_TYPE_INTERNAL_EF;
2365
0
      }
2366
0
      sc_log(ctx, "type %s, EF structure %d", type, byte);
2367
0
    }
2368
0
  }
2369
2370
0
  tag = sc_asn1_find_tag(ctx, p, len, 0x84, &taglen);
2371
0
  if (tag != NULL && taglen > 0 && taglen <= 16) {
2372
0
    memcpy(file->name, tag, taglen);
2373
0
    file->namelen = taglen;
2374
2375
0
    sc_log_hex(ctx, "File name", file->name, file->namelen);
2376
0
    if (!file->type)
2377
0
      file->type = SC_FILE_TYPE_DF;
2378
0
  }
2379
2380
0
  tag = sc_asn1_find_tag(ctx, p, len, 0x85, &taglen);
2381
0
  if (tag != NULL && taglen)
2382
0
    sc_file_set_prop_attr(file, tag, taglen);
2383
0
  else
2384
0
    file->prop_attr_len = 0;
2385
2386
0
  tag = sc_asn1_find_tag(ctx, p, len, 0xA5, &taglen);
2387
0
  if (tag != NULL && taglen)
2388
0
    sc_file_set_prop_attr(file, tag, taglen);
2389
2390
0
  tag = sc_asn1_find_tag(ctx, p, len, 0x86, &taglen);
2391
0
  if (tag != NULL && taglen) {
2392
0
    unsigned int i;
2393
0
    sc_file_set_sec_attr(file, tag, taglen);
2394
0
    for (i = 0; i< taglen; i++)
2395
0
      if (tag[i] != 0xff) /* skip unused entries */
2396
0
        sec_attr_to_entry(card, file, i);
2397
0
  }
2398
2399
0
  tag = sc_asn1_find_tag(ctx, p, len, 0x8A, &taglen);
2400
0
  if (tag != NULL && taglen == 1) {
2401
0
    if (tag[0] == 0x01)
2402
0
      file->status = SC_FILE_STATUS_CREATION;
2403
0
    else if (tag[0] == 0x07 || tag[0] == 0x05)
2404
0
      file->status = SC_FILE_STATUS_ACTIVATED;
2405
0
    else if (tag[0] == 0x06 || tag[0] == 0x04)
2406
0
      file->status = SC_FILE_STATUS_INVALIDATED;
2407
0
  }
2408
0
  file->magic = SC_FILE_MAGIC;
2409
2410
0
  return 0;
2411
0
}
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
0
{
2418
0
  u8 *p = out;
2419
0
  u8 buf[64];
2420
0
  unsigned char ops[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2421
0
  int rv;
2422
0
  unsigned ii;
2423
2424
0
  if (*outlen < 2)
2425
0
    return SC_ERROR_BUFFER_TOO_SMALL;
2426
2427
0
  *p++ = 0x62;
2428
0
  p++;
2429
0
  if (file->type == SC_FILE_TYPE_WORKING_EF) {
2430
0
    if (file->ef_structure == SC_FILE_EF_TRANSPARENT) {
2431
0
      buf[0] = (file->size >> 8) & 0xFF;
2432
0
      buf[1] = file->size & 0xFF;
2433
0
      sc_asn1_put_tag(0x80, buf, 2, p, *outlen - (p - out), &p);
2434
0
    }
2435
0
  }
2436
0
  if (file->type == SC_FILE_TYPE_DF) {
2437
0
    buf[0] = 0x38;
2438
0
    buf[1] = 0x00;
2439
0
    sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2440
0
  }
2441
0
  else if (file->type == SC_FILE_TYPE_WORKING_EF) {
2442
0
    buf[0] = file->ef_structure & 7;
2443
0
    if (file->ef_structure == SC_FILE_EF_TRANSPARENT) {
2444
0
      buf[1] = 0x00;
2445
0
      sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2446
0
    } else if (file->ef_structure == SC_FILE_EF_LINEAR_FIXED ||
2447
0
        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
0
    } else {
2454
0
      return SC_ERROR_NOT_SUPPORTED;
2455
0
    }
2456
2457
0
  }
2458
0
  else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
2459
0
    if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
2460
0
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) {
2461
0
      buf[0] = 0x11;
2462
0
      buf[1] = 0x00;
2463
0
    } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2464
0
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2465
0
      buf[0] = 0x12;
2466
0
      buf[1] = 0x00;
2467
0
    } else {
2468
0
      return SC_ERROR_NOT_SUPPORTED;
2469
0
    }
2470
0
    sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2471
0
  } else if (file->type == SC_FILE_TYPE_BSO) {
2472
0
    buf[0] = 0x10;
2473
0
    buf[1] = 0x00;
2474
0
    sc_asn1_put_tag(0x82, buf, 2, p, *outlen - (p - out), &p);
2475
0
  }
2476
2477
0
  buf[0] = (file->id >> 8) & 0xFF;
2478
0
  buf[1] = file->id & 0xFF;
2479
0
  sc_asn1_put_tag(0x83, buf, 2, p, *outlen - (p - out), &p);
2480
0
  if (file->type == SC_FILE_TYPE_DF) {
2481
0
    if (file->namelen != 0) {
2482
0
      sc_asn1_put_tag(0x84, file->name, file->namelen, p, *outlen - (p - out), &p);
2483
0
    } else {
2484
0
      return SC_ERROR_INVALID_ARGUMENTS;
2485
0
    }
2486
0
  }
2487
0
  if (file->type == SC_FILE_TYPE_DF) {
2488
0
    unsigned char data[2] = {0x00, 0x7F};
2489
    /* 127 files at most */
2490
0
    sc_asn1_put_tag(0x85, data, sizeof(data), p, *outlen - (p - out), &p);
2491
0
  } else if (file->type == SC_FILE_TYPE_BSO) {
2492
0
    buf[0] = file->size & 0xff;
2493
0
    sc_asn1_put_tag(0x85, buf, 1, p, *outlen - (p - out), &p);
2494
0
  } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
2495
0
    if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
2496
0
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2497
0
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT ||
2498
0
        file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2499
0
      buf[0] = (file->size >> 8) & 0xFF;
2500
0
      buf[1] = file->size & 0xFF;
2501
0
      sc_asn1_put_tag(0x85, buf, 2, p, *outlen - (p - out), &p);
2502
0
    }
2503
0
  }
2504
0
  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
0
  } else {
2509
0
    sc_log(card->ctx, "SC_FILE_ACL");
2510
0
    if (file->type == SC_FILE_TYPE_DF) {
2511
0
      ops[0] = SC_AC_OP_LIST_FILES;
2512
0
      ops[1] = SC_AC_OP_CREATE;
2513
0
      ops[3] = SC_AC_OP_DELETE;
2514
0
    } else if (file->type == SC_FILE_TYPE_WORKING_EF) {
2515
0
      if (file->ef_structure == SC_FILE_EF_TRANSPARENT) {
2516
0
        ops[0] = SC_AC_OP_READ;
2517
0
        ops[1] = SC_AC_OP_UPDATE;
2518
0
        ops[3] = SC_AC_OP_DELETE;
2519
0
      } 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
0
    } else if (file->type == SC_FILE_TYPE_BSO) {
2529
0
      ops[0] = SC_AC_OP_UPDATE;
2530
0
      ops[3] = SC_AC_OP_DELETE;
2531
0
    } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) {
2532
0
      if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT ||
2533
0
          file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_CRT) {
2534
0
        ops[1] = SC_AC_OP_UPDATE;
2535
0
        ops[2] = SC_AC_OP_CRYPTO;
2536
0
        ops[3] = SC_AC_OP_DELETE;
2537
0
      } else if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2538
0
          file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2539
0
        ops[0] = SC_AC_OP_READ;
2540
0
        ops[1] = SC_AC_OP_UPDATE;
2541
0
        ops[2] = SC_AC_OP_CRYPTO;
2542
0
        ops[3] = SC_AC_OP_DELETE;
2543
0
      }
2544
0
    } else {
2545
0
      return SC_ERROR_NOT_SUPPORTED;
2546
0
    }
2547
2548
0
    for (ii = 0; ii < sizeof(ops); ii++) {
2549
0
      const struct sc_acl_entry *entry;
2550
2551
0
      buf[ii] = 0xFF;
2552
0
      if (ops[ii] == 0xFF)
2553
0
        continue;
2554
0
      entry = sc_file_get_acl_entry(file, ops[ii]);
2555
2556
0
      rv = acl_to_ac_byte(card, entry);
2557
0
      LOG_TEST_RET(card->ctx, rv, "Invalid ACL");
2558
2559
0
      buf[ii] = rv;
2560
0
    }
2561
0
    sc_asn1_put_tag(0x86, buf, sizeof(ops), p, *outlen - (p - out), &p);
2562
0
    if (file->size == 256) {
2563
0
      out[4]= 0x13;
2564
0
    }
2565
0
  }
2566
2567
  /* VT ??? */
2568
0
  if (file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC ||
2569
0
      file->ef_structure == SC_CARDCTL_OBERTHUR_KEY_EC_PUBLIC) {
2570
0
    unsigned char data[2] = {0x00, 0x66};
2571
0
    sc_asn1_put_tag(0x87, data, sizeof(data), p, *outlen - (p - out), &p);
2572
0
    if (file->size == 256) {
2573
0
      out[4] = 0x14;
2574
0
    }
2575
0
  }
2576
2577
0
  out[1] = p - out - 2;
2578
2579
0
  *outlen = p - out;
2580
0
  return 0;
2581
0
}
2582
2583
2584
static int
2585
epass2003_create_file(struct sc_card *card, sc_file_t * file)
2586
0
{
2587
0
  int r;
2588
0
  size_t len;
2589
0
  u8 sbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
2590
0
  struct sc_apdu apdu;
2591
2592
0
  len = SC_MAX_APDU_BUFFER_SIZE;
2593
2594
0
  epass2003_hook_file(file, 1);
2595
2596
0
  if (card->ops->construct_fci == NULL)
2597
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2598
2599
0
  r = epass2003_construct_fci(card, file, sbuf, &len);
2600
0
  LOG_TEST_RET(card->ctx, r, "construct_fci() failed");
2601
2602
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00);
2603
0
  apdu.lc = len;
2604
0
  apdu.datalen = len;
2605
0
  apdu.data = sbuf;
2606
2607
0
  r = sc_transmit_apdu_t(card, &apdu);
2608
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2609
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2610
0
  LOG_TEST_RET(card->ctx, r, "APDU sw1/2 wrong");
2611
2612
0
  epass2003_hook_file(file, 0);
2613
0
  return r;
2614
0
}
2615
2616
2617
static int
2618
epass2003_delete_file(struct sc_card *card, const sc_path_t * path)
2619
0
{
2620
0
  int r;
2621
0
  u8 sbuf[2];
2622
0
  struct sc_apdu apdu;
2623
2624
0
  LOG_FUNC_CALLED(card->ctx);
2625
2626
0
  r = sc_select_file(card, path, NULL);
2627
0
  LOG_TEST_RET(card->ctx, r, "Can not select file");
2628
0
  r = epass2003_hook_path((struct sc_path *)path, 1);
2629
0
  LOG_TEST_RET(card->ctx, r, "Can not hook path");
2630
2631
0
  sbuf[0] = path->value[path->len - 2];
2632
0
  sbuf[1] = path->value[path->len - 1];
2633
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00);
2634
0
  apdu.lc = 2;
2635
0
  apdu.datalen = 2;
2636
0
  apdu.data = sbuf;
2637
2638
0
  r = sc_transmit_apdu_t(card, &apdu);
2639
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2640
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2641
0
  LOG_TEST_RET(card->ctx, r, "Delete file failed");
2642
2643
0
  LOG_FUNC_RETURN(card->ctx, r);
2644
0
}
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
0
{
2724
2725
0
  if ((NULL == data) || (NULL == hash))
2726
0
    return SC_ERROR_INVALID_ARGUMENTS;
2727
2728
0
  if (mechanismType & SC_ALGORITHM_ECDSA_HASH_SHA1) {
2729
0
    unsigned char data_hash[24] = {0};
2730
0
    size_t len = 0;
2731
2732
0
    sha1_digest(card, data, datalen, data_hash);
2733
0
    len = REVERSE_ORDER4(datalen);
2734
0
    memcpy(&data_hash[20], &len, 4);
2735
0
    memcpy(hash, data_hash, 24);
2736
0
  } 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
0
  return SC_SUCCESS;
2749
0
}
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
0
{
2757
0
  int r;
2758
0
  struct sc_apdu apdu;
2759
0
  unsigned char isapp = 0x00; /* appendable */
2760
0
  unsigned char tmp_data[256] = {0};
2761
2762
0
  tmp_data[0] = ktype;
2763
0
  tmp_data[1] = kid;
2764
0
  tmp_data[2] = useac;
2765
0
  tmp_data[3] = modifyac;
2766
0
  tmp_data[8] = 0xFF;
2767
2768
0
  if (0x04 == ktype || 0x06 == ktype) {
2769
0
    tmp_data[4] = EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_SO;
2770
0
    tmp_data[5] = EPASS2003_AC_MAC_NOLESS | EPASS2003_AC_SO;
2771
0
    tmp_data[7] = (kid == PIN_ID[0] ? EPASS2003_AC_USER : EPASS2003_AC_SO);
2772
0
    tmp_data[9] = (EC << 4) | EC;
2773
0
  }
2774
2775
0
  memcpy(&tmp_data[10], data, dataLen);
2776
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xe3, isapp, 0x00);
2777
0
  apdu.cla = 0x80;
2778
0
  apdu.lc = apdu.datalen = 10 + dataLen;
2779
0
  apdu.data = tmp_data;
2780
2781
0
  r = sc_transmit_apdu_t(card, &apdu);
2782
0
  LOG_TEST_RET(card->ctx, r, "APDU install_secret_key failed");
2783
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2784
0
  LOG_TEST_RET(card->ctx, r, "install_secret_key failed");
2785
2786
0
  return r;
2787
0
}
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
0
{
2816
0
  int r;
2817
0
  unsigned char hash[HASH_LEN] = {0};
2818
2819
0
  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
0
  LOG_TEST_RET(card->ctx, r, "hash data failed");
2821
2822
0
  r = install_secret_key(card, 0x04, pin->key_data.es_secret.kid,
2823
0
             pin->key_data.es_secret.ac[0],
2824
0
             pin->key_data.es_secret.ac[1],
2825
0
             pin->key_data.es_secret.EC, hash, HASH_LEN);
2826
0
  LOG_TEST_RET(card->ctx, r, "Install failed");
2827
2828
0
  return r;
2829
0
}
2830
2831
2832
static int
2833
epass2003_write_key(struct sc_card *card, sc_epass2003_wkey_data * data)
2834
0
{
2835
0
  LOG_FUNC_CALLED(card->ctx);
2836
2837
0
  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
0
  } else if (data->type & SC_EPASS2003_SECRET) {
2844
0
    if (data->type == SC_EPASS2003_SECRET_PRE)
2845
0
      return internal_install_pre(card);
2846
0
    else if (data->type == SC_EPASS2003_SECRET_PIN)
2847
0
      return internal_install_pin(card, data);
2848
0
    else
2849
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2850
0
  } 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
0
{
2861
0
  int r;
2862
0
  size_t len = data->key_length;
2863
0
  struct sc_apdu apdu;
2864
0
  u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0};
2865
0
  u8 sbuf[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0};
2866
2867
0
  LOG_FUNC_CALLED(card->ctx);
2868
2869
0
  if (len == 256) {
2870
0
    sbuf[0] = 0x02;
2871
0
  } else {
2872
0
    sbuf[0] = 0x01;
2873
0
  }
2874
0
  sbuf[1] = (u8) ((len >> 8) & 0xff);
2875
0
  sbuf[2] = (u8) (len & 0xff);
2876
0
  sbuf[3] = (u8) ((data->prkey_id >> 8) & 0xFF);
2877
0
  sbuf[4] = (u8) ((data->prkey_id) & 0xFF);
2878
0
  sbuf[5] = (u8) ((data->pukey_id >> 8) & 0xFF);
2879
0
  sbuf[6] = (u8) ((data->pukey_id) & 0xFF);
2880
2881
  /* generate key */
2882
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, 0x00);
2883
0
  apdu.lc = apdu.datalen = 7;
2884
0
  apdu.data = sbuf;
2885
2886
0
  r = sc_transmit_apdu_t(card, &apdu);
2887
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2888
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2889
0
  LOG_TEST_RET(card->ctx, r, "generate key pair failed");
2890
2891
  /* read public key */
2892
0
  sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xb4, 0x02, 0x00);
2893
0
  if (len == 256) {
2894
0
    apdu.p1 = 0x00;
2895
0
  }
2896
2897
0
  apdu.cla = 0x80;
2898
0
  apdu.lc = apdu.datalen = 2;
2899
0
  apdu.data = &sbuf[5];
2900
0
  apdu.resp = rbuf;
2901
0
  apdu.resplen = sizeof(rbuf);
2902
0
  apdu.le = 0x00;
2903
2904
0
  r = sc_transmit_apdu_t(card, &apdu);
2905
0
  LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
2906
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2907
0
  LOG_TEST_RET(card->ctx, r, "get pukey failed");
2908
2909
0
  if (len < apdu.resplen)
2910
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2911
2912
0
  if (256 == len) { /* ECC 256 bit */
2913
0
    size_t xCoordinateLen = rbuf[1];
2914
0
    size_t yCoordinateLen;
2915
0
    unsigned char *tmp;
2916
2917
0
    if (2 + xCoordinateLen + 1 > apdu.resplen) {
2918
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
2919
0
    }
2920
0
    yCoordinateLen = rbuf[2 + xCoordinateLen + 1];
2921
0
    if (2 + xCoordinateLen + 2 + yCoordinateLen > apdu.resplen) {
2922
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_DATA);
2923
0
    }
2924
0
    data->modulus_len = xCoordinateLen + yCoordinateLen;
2925
0
    tmp = (u8 *)malloc(data->modulus_len);
2926
0
    if (!tmp) {
2927
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
2928
0
    }
2929
2930
0
    if (0x58 == rbuf[0]) {
2931
0
      memcpy(tmp, &rbuf[2], xCoordinateLen);
2932
0
    } else {
2933
0
      free(tmp);
2934
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
2935
0
    }
2936
0
    if (0x59 == rbuf[2 + xCoordinateLen]) {
2937
0
      memcpy(tmp + xCoordinateLen, &rbuf[2+xCoordinateLen+2], yCoordinateLen);
2938
0
    } else {
2939
0
      free(tmp);
2940
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
2941
0
    }
2942
2943
0
    data->modulus = tmp;
2944
0
  } else {
2945
0
    data->modulus = (u8 *) malloc(len);
2946
0
    if (!data->modulus) {
2947
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
2948
0
    } else {
2949
0
      memcpy(data->modulus, rbuf, len);
2950
0
    }
2951
0
  }
2952
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2953
0
}
2954
2955
2956
static int
2957
epass2003_erase_card(struct sc_card *card)
2958
0
{
2959
0
  static const unsigned char install_magic_pin[26] = {
2960
    /* compare install_secret_key */
2961
0
      0x06, 0x01, 0x10, 0x16, 0x16, 0x16, 0x00, 0x0f, 0xff, 0x66,
2962
0
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2963
0
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2964
0
  };
2965
0
  static const unsigned char magic_pin[16] = {
2966
0
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2967
0
      0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
2968
0
  };
2969
0
  static const unsigned char mf_path[2] = { 0x3f, 0x00 };
2970
0
  sc_apdu_t apdu;
2971
0
  int r;
2972
2973
0
  LOG_FUNC_CALLED(card->ctx);
2974
2975
  /* install magic pin */
2976
0
  sc_format_apdu(card, &apdu, 0x03, 0xe3, 0x00, 0x00);
2977
0
  apdu.cla = 0x80;
2978
0
  apdu.data = install_magic_pin;
2979
0
  apdu.datalen = apdu.lc = sizeof(install_magic_pin);
2980
0
  r = sc_transmit_apdu(card, &apdu);
2981
0
  LOG_TEST_RET(card->ctx, r, "APDU install magic pin failed");
2982
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2983
0
  LOG_TEST_RET(card->ctx, r, "install magic pin failed");
2984
2985
  /* verify magic pin */
2986
0
  sc_format_apdu(card, &apdu, 0x03, 0x20, 0x00, 0x01);
2987
0
  apdu.cla = 0;
2988
0
  apdu.data = magic_pin;
2989
0
  apdu.datalen = apdu.lc = sizeof(magic_pin);
2990
0
  r = sc_transmit_apdu(card, &apdu);
2991
0
  LOG_TEST_RET(card->ctx, r, "APDU verify magic pin failed");
2992
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
2993
0
  LOG_TEST_RET(card->ctx, r, "verify magic pin failed");
2994
2995
  /* delete MF */
2996
0
  sc_format_apdu(card, &apdu, 0x03, 0xe4, 0x00, 0x00);
2997
0
  apdu.cla = 0;
2998
0
  apdu.data = mf_path;
2999
0
  apdu.datalen = apdu.lc = sizeof(mf_path);
3000
0
  r = sc_transmit_apdu(card, &apdu);
3001
0
  LOG_TEST_RET(card->ctx, r, "APDU delete MF failed");
3002
0
  r = sc_check_sw(card, apdu.sw1, apdu.sw2);
3003
0
  LOG_TEST_RET(card->ctx, r, "delete MF failed");
3004
3005
0
  LOG_FUNC_RETURN(card->ctx, r);
3006
0
}
3007
3008
3009
static int
3010
epass2003_get_serialnr(struct sc_card *card, sc_serial_number_t * serial)
3011
0
{
3012
0
  u8 rbuf[8];
3013
0
  size_t rbuf_len = sizeof(rbuf);
3014
3015
0
  LOG_FUNC_CALLED(card->ctx);
3016
3017
0
  if (SC_SUCCESS != get_data(card, 0x80, rbuf, rbuf_len))
3018
0
    return SC_ERROR_CARD_CMD_FAILED;
3019
3020
0
  card->serialnr.len = serial->len = 8;
3021
0
  memcpy(card->serialnr.value, rbuf, 8);
3022
0
  memcpy(serial->value, rbuf, 8);
3023
3024
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
3025
0
}
3026
3027
3028
static int
3029
epass2003_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
3030
0
{
3031
0
  LOG_FUNC_CALLED(card->ctx);
3032
3033
0
  sc_log(card->ctx, "cmd is %0lx", cmd);
3034
0
  switch (cmd) {
3035
0
  case SC_CARDCTL_ENTERSAFE_WRITE_KEY:
3036
0
    return epass2003_write_key(card, (sc_epass2003_wkey_data *) ptr);
3037
0
  case SC_CARDCTL_ENTERSAFE_GENERATE_KEY:
3038
0
    return epass2003_gen_key(card, (sc_epass2003_gen_key_data *) ptr);
3039
0
  case SC_CARDCTL_ERASE_CARD:
3040
0
    return epass2003_erase_card(card);
3041
0
  case SC_CARDCTL_GET_SERIALNR:
3042
0
    return epass2003_get_serialnr(card, (sc_serial_number_t *) ptr);
3043
0
  default:
3044
0
    return SC_ERROR_NOT_SUPPORTED;
3045
0
  }
3046
0
}
3047
3048
3049
static void
3050
internal_sanitize_pin_info(struct sc_pin_cmd_pin *pin, unsigned int num)
3051
0
{
3052
0
  pin->encoding = SC_PIN_ENCODING_ASCII;
3053
0
  pin->min_length = 4;
3054
0
  pin->max_length = 16;
3055
0
  pin->pad_length = 16;
3056
0
  pin->offset = 5 + num * 16;
3057
0
  pin->pad_char = 0x00;
3058
0
}
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
0
{
3204
0
  int r;
3205
0
  u8 kid;
3206
0
  u8 retries = 0;
3207
0
  u8 pin_low = 3;
3208
0
  unsigned char maxtries = 0;
3209
3210
0
  LOG_FUNC_CALLED(card->ctx);
3211
3212
0
  internal_sanitize_pin_info(&data->pin1, 0);
3213
0
  internal_sanitize_pin_info(&data->pin2, 1);
3214
0
  data->flags |= SC_PIN_CMD_NEED_PADDING;
3215
0
  kid = data->pin_reference;
3216
3217
0
  if (NULL == (unsigned char *)data->pin1.data || 0 == data->pin1.len)
3218
0
    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
291
{
3282
291
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
3283
3284
291
  if (iso_ops == NULL)
3285
1
    iso_ops = iso_drv->ops;
3286
3287
291
  epass2003_ops = *iso_ops;
3288
3289
291
  epass2003_ops.match_card = epass2003_match_card;
3290
291
  epass2003_ops.init = epass2003_init;
3291
291
  epass2003_ops.finish = epass2003_finish;
3292
291
  epass2003_ops.write_binary = NULL;
3293
291
  epass2003_ops.write_record = NULL;
3294
291
  epass2003_ops.select_file = epass2003_select_file;
3295
291
  epass2003_ops.get_response = NULL;
3296
291
  epass2003_ops.restore_security_env = epass2003_restore_security_env;
3297
291
  epass2003_ops.set_security_env = epass2003_set_security_env;
3298
291
  epass2003_ops.decipher = epass2003_decipher;
3299
291
  epass2003_ops.compute_signature = epass2003_decipher;
3300
291
  epass2003_ops.create_file = epass2003_create_file;
3301
291
  epass2003_ops.delete_file = epass2003_delete_file;
3302
291
  epass2003_ops.list_files = epass2003_list_files;
3303
291
  epass2003_ops.card_ctl = epass2003_card_ctl;
3304
291
  epass2003_ops.process_fci = epass2003_process_fci;
3305
291
  epass2003_ops.construct_fci = epass2003_construct_fci;
3306
291
  epass2003_ops.pin_cmd = epass2003_pin_cmd;
3307
291
  epass2003_ops.check_sw = epass2003_check_sw;
3308
291
  epass2003_ops.get_challenge = epass2003_get_challenge;
3309
291
  epass2003_ops.logout = epass2003_logout;
3310
291
  return &epass2003_drv;
3311
291
}
3312
3313
struct sc_card_driver *sc_get_epass2003_driver(void)
3314
291
{
3315
291
  return sc_get_driver();
3316
291
}
3317
#endif  /* #ifdef ENABLE_OPENSSL */
3318
#endif  /* #ifdef ENABLE_SM */