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