1 /*
2 * iasecc.h Support for IAS/ECC smart cards
3 *
4 * Copyright (C) 2010 Viktor Tarasov <vtarasov@opentrust.com>
5 * OpenTrust <www.opentrust.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 #include <string.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25
26 #include "internal.h"
27 #include "asn1.h"
28 #include "cardctl.h"
29 #include "common/compat_strlcpy.h"
30
31 #include "sm.h"
32 #include "iasecc.h"
33 #include "authentic.h"
34
35
36 #ifdef ENABLE_SM
37
38 static int
sm_save_sc_context(struct sc_card * card,struct sm_info * sm_info)39 sm_save_sc_context (struct sc_card *card, struct sm_info *sm_info)
40 {
41 struct sc_context *ctx;
42 struct sc_card_cache *cache;
43
44 if (!card || !sm_info)
45 return SC_ERROR_INVALID_ARGUMENTS;
46
47 ctx = card->ctx;
48 cache = &card->cache;
49
50 sc_log(ctx, "SM save context: cache(valid:%i,current_df:%p)", cache->valid, cache->current_df);
51 if (cache->valid && cache->current_df) {
52 sm_info->current_path_df = cache->current_df->path;
53 if (cache->current_df->path.type == SC_PATH_TYPE_DF_NAME) {
54 if (cache->current_df->path.aid.len) {
55 sm_info->current_aid = cache->current_df->path.aid;
56 }
57 else {
58 memcpy(sm_info->current_aid.value, cache->current_df->path.value, cache->current_df->path.len);
59 sm_info->current_aid.len = cache->current_df->path.len;
60 }
61 }
62 }
63
64 if (cache->valid && cache->current_ef)
65 sm_info->current_path_ef = cache->current_ef->path;
66
67 return SC_SUCCESS;
68 }
69
70
71 static int
sm_restore_sc_context(struct sc_card * card,struct sm_info * sm_info)72 sm_restore_sc_context(struct sc_card *card, struct sm_info *sm_info)
73 {
74 int rv = SC_SUCCESS;
75
76 if (sm_info->current_path_df.type == SC_PATH_TYPE_DF_NAME && sm_info->current_path_df.len)
77 rv = sc_select_file(card, &sm_info->current_path_df, NULL);
78
79 if (sm_info->current_path_ef.len && rv == SC_SUCCESS)
80 rv = sc_select_file(card, &sm_info->current_path_ef, NULL);
81
82 memset(&sm_info->current_path_df, 0, sizeof(sm_info->current_path_df));
83 memset(&sm_info->current_path_ef, 0, sizeof(sm_info->current_path_ef));
84
85 return rv;
86 }
87
88 static int
iasecc_sm_transmit_apdus(struct sc_card * card,struct sc_remote_data * rdata,unsigned char * out,size_t * out_len)89 iasecc_sm_transmit_apdus(struct sc_card *card, struct sc_remote_data *rdata,
90 unsigned char *out, size_t *out_len)
91 {
92 struct sc_context *ctx = card->ctx;
93 struct sc_remote_apdu *rapdu = rdata->data;
94 int rv = SC_SUCCESS, offs = 0;
95
96 LOG_FUNC_CALLED(ctx);
97 sc_log(ctx, "iasecc_sm_transmit_apdus() rdata-length %i", rdata->length);
98
99 while (rapdu) {
100 sc_log(ctx, "iasecc_sm_transmit_apdus() rAPDU flags 0x%lX", rapdu->apdu.flags);
101 rv = sc_transmit_apdu(card, &rapdu->apdu);
102 LOG_TEST_RET(ctx, rv, "iasecc_sm_transmit_apdus() failed to execute r-APDU");
103 rv = sc_check_sw(card, rapdu->apdu.sw1, rapdu->apdu.sw2);
104 if (rv < 0 && !(rapdu->flags & SC_REMOTE_APDU_FLAG_NOT_FATAL))
105 LOG_TEST_RET(ctx, rv, "iasecc_sm_transmit_apdus() fatal error %i");
106
107 if (out && out_len && (rapdu->flags & SC_REMOTE_APDU_FLAG_RETURN_ANSWER)) {
108 int len = rapdu->apdu.resplen > (*out_len - offs) ? (*out_len - offs) : rapdu->apdu.resplen;
109
110 memcpy(out + offs, rapdu->apdu.resp, len);
111 offs += len;
112 /* TODO: decode and gather data answers */
113 }
114
115 rapdu = rapdu->next;
116 }
117
118 if (out_len)
119 *out_len = offs;
120
121 LOG_FUNC_RETURN(ctx, rv);
122 }
123
124
125 /* Big TODO: do SM release in all handles, clean the saved card context -- current DF, EF, etc. */
126 static int
sm_release(struct sc_card * card,struct sc_remote_data * rdata,unsigned char * out,size_t out_len)127 sm_release (struct sc_card *card, struct sc_remote_data *rdata,
128 unsigned char *out, size_t out_len)
129 {
130 struct sc_context *ctx = card->ctx;
131 struct sm_info *sm_info = &card->sm_ctx.info;
132 int rv;
133
134 LOG_FUNC_CALLED(ctx);
135 if (!card->sm_ctx.module.ops.finalize)
136 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
137
138 rv = card->sm_ctx.module.ops.finalize(ctx, sm_info, rdata, out, out_len);
139
140 sm_restore_sc_context(card, sm_info);
141 LOG_FUNC_RETURN(ctx, rv);
142 }
143 #endif
144
145
146 int
iasecc_sm_external_authentication(struct sc_card * card,unsigned skey_ref,int * tries_left)147 iasecc_sm_external_authentication(struct sc_card *card, unsigned skey_ref, int *tries_left)
148 {
149 struct sc_context *ctx = card->ctx;
150 #ifdef ENABLE_SM
151 struct sm_info *sm_info = &card->sm_ctx.info;
152 struct sm_cwa_session *cwa_session = &sm_info->session.cwa;
153 struct sc_remote_data rdata;
154 struct sc_apdu apdu;
155 unsigned char sbuf[0x100];
156 int rv, offs;
157
158 LOG_FUNC_CALLED(ctx);
159 sc_log(ctx, "iasecc_sm_external_authentication(): SKey ref %i", skey_ref);
160
161 if (card->sm_ctx.sm_mode == SM_MODE_NONE)
162 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Cannot do 'External Authentication' without SM activated ");
163
164 strlcpy(sm_info->config_section, card->sm_ctx.config_section, sizeof(sm_info->config_section));
165 sm_info->cmd = SM_CMD_EXTERNAL_AUTH;
166 sm_info->serialnr = card->serialnr;
167 sm_info->card_type = card->type;
168 sm_info->sm_type = SM_TYPE_CWA14890;
169 cwa_session->params.crt_at.usage = IASECC_UQB_AT_EXTERNAL_AUTHENTICATION;
170 cwa_session->params.crt_at.algo = IASECC_ALGORITHM_ROLE_AUTH;
171 cwa_session->params.crt_at.refs[0] = skey_ref;
172
173 offs = 0;
174 sbuf[offs++] = IASECC_CRT_TAG_ALGO;
175 sbuf[offs++] = 0x01;
176 sbuf[offs++] = IASECC_ALGORITHM_ROLE_AUTH;
177 sbuf[offs++] = IASECC_CRT_TAG_REFERENCE;
178 sbuf[offs++] = 0x01;
179 sbuf[offs++] = skey_ref;
180
181 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x81, 0xA4);
182 apdu.data = sbuf;
183 apdu.datalen = offs;
184 apdu.lc = offs;
185
186 rv = sc_transmit_apdu(card, &apdu);
187 LOG_TEST_RET(ctx, rv, "iasecc_sm_external_authentication(): APDU transmit failed");
188 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
189 LOG_TEST_RET(ctx, rv, "iasecc_sm_external_authentication(): set SE error");
190
191 rv = sc_get_challenge(card, cwa_session->card_challenge, sizeof(cwa_session->card_challenge));
192 LOG_TEST_RET(ctx, rv, "iasecc_sm_external_authentication(): set SE error");
193
194 sc_remote_data_init(&rdata);
195
196 if (!card->sm_ctx.module.ops.initialize)
197 LOG_TEST_RET(ctx, SC_ERROR_SM_NOT_INITIALIZED, "No SM module");
198 rv = card->sm_ctx.module.ops.initialize(ctx, sm_info, &rdata);
199 LOG_TEST_RET(ctx, rv, "SM: INITIALIZE failed");
200
201 sc_log(ctx, "sm_iasecc_external_authentication(): rdata length %i\n", rdata.length);
202
203 rv = iasecc_sm_transmit_apdus (card, &rdata, NULL, 0);
204 if (rv == SC_ERROR_PIN_CODE_INCORRECT && tries_left)
205 *tries_left = (rdata.data + rdata.length - 1)->apdu.sw2 & 0x0F;
206 LOG_TEST_RET(ctx, rv, "sm_iasecc_external_authentication(): execute failed");
207
208 LOG_FUNC_RETURN(ctx, rv);
209 #else
210 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of SM and External Authentication");
211 return SC_ERROR_NOT_SUPPORTED;
212 #endif
213 }
214
215
216 #ifdef ENABLE_SM
217 static int
iasecc_sm_se_mutual_authentication(struct sc_card * card,unsigned se_num)218 iasecc_sm_se_mutual_authentication(struct sc_card *card, unsigned se_num)
219 {
220 struct sc_context *ctx = card->ctx;
221 struct sm_info *sm_info = &card->sm_ctx.info;
222 struct iasecc_se_info se;
223 struct sc_crt *crt = &sm_info->session.cwa.params.crt_at;
224 struct sc_apdu apdu;
225 unsigned char sbuf[0x100];
226 int rv, offs;
227
228 memset(&se, 0, sizeof(se));
229
230 se.reference = se_num;
231 crt->usage = IASECC_UQB_AT_MUTUAL_AUTHENTICATION;
232 crt->tag = IASECC_CRT_TAG_AT;
233
234 rv = iasecc_se_get_info(card, &se);
235 LOG_TEST_RET(ctx, rv, "Get SE info error");
236
237 rv = iasecc_se_get_crt(card, &se, crt);
238 LOG_TEST_RET(ctx, rv, "Cannot get authentication CRT");
239
240 sc_file_free(se.df);
241
242 /* MSE SET Mutual Authentication SK scheme */
243 offs = 0;
244 sbuf[offs++] = IASECC_CRT_TAG_ALGO;
245 sbuf[offs++] = 0x01;
246 sbuf[offs++] = crt->algo;
247 sbuf[offs++] = IASECC_CRT_TAG_REFERENCE;
248 sbuf[offs++] = 0x01;
249 sbuf[offs++] = crt->refs[0];
250
251 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xC1, 0xA4);
252 apdu.data = sbuf;
253 apdu.datalen = offs;
254 apdu.lc = offs;
255
256 rv = sc_transmit_apdu(card, &apdu);
257 LOG_TEST_RET(ctx, rv, "SM set SE mutual auth.: APDU transmit failed");
258 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
259 LOG_TEST_RET(ctx, rv, "SM set SE mutual auth.: set SE error");
260
261 LOG_FUNC_RETURN(ctx, rv);
262 }
263 #endif
264
265
266 int
iasecc_sm_initialize(struct sc_card * card,unsigned se_num,unsigned cmd)267 iasecc_sm_initialize(struct sc_card *card, unsigned se_num, unsigned cmd)
268 {
269 struct sc_context *ctx = card->ctx;
270 #ifdef ENABLE_SM
271 struct sm_info *sm_info = &card->sm_ctx.info;
272 struct sm_cwa_session *cwa_session = &sm_info->session.cwa;
273 struct sc_remote_data rdata;
274 int rv;
275
276 LOG_FUNC_CALLED(ctx);
277
278 strlcpy(sm_info->config_section, card->sm_ctx.config_section, sizeof(sm_info->config_section));
279 sm_info->cmd = cmd;
280 sm_info->serialnr = card->serialnr;
281 sm_info->card_type = card->type;
282 sm_info->sm_type = SM_TYPE_CWA14890;
283
284 rv = iasecc_sm_se_mutual_authentication(card, se_num);
285 LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() MUTUAL AUTHENTICATION failed");
286
287 rv = sc_get_challenge(card, cwa_session->card_challenge, SM_SMALL_CHALLENGE_LEN);
288 LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() GET CHALLENGE failed");
289
290 sc_remote_data_init(&rdata);
291
292 rv = sm_save_sc_context(card, sm_info);
293 LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() cannot save current context");
294
295 if (!card->sm_ctx.module.ops.initialize)
296 LOG_TEST_RET(ctx, SC_ERROR_SM_NOT_INITIALIZED, "iasecc_sm_initialize() no SM module");
297 rv = card->sm_ctx.module.ops.initialize(ctx, sm_info, &rdata);
298 LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() INITIALIZE failed");
299
300
301 if (rdata.length == 1) {
302 rdata.data->flags |= SC_REMOTE_APDU_FLAG_RETURN_ANSWER;
303 rdata.data->apdu.flags &= ~SC_APDU_FLAGS_NO_GET_RESP;
304 }
305 else {
306 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "TODO: SM init with more then one APDU");
307 }
308
309 cwa_session->mdata_len = sizeof(cwa_session->mdata);
310 rv = iasecc_sm_transmit_apdus (card, &rdata, cwa_session->mdata, &cwa_session->mdata_len);
311 if (rv == SC_ERROR_PIN_CODE_INCORRECT)
312 sc_log(ctx, "SM initialization failed, %i tries left", (rdata.data + rdata.length - 1)->apdu.sw2 & 0x0F);
313 LOG_TEST_RET(ctx, rv, "iasecc_sm_initialize() transmit APDUs failed");
314
315 rdata.free(&rdata);
316
317 sc_log(ctx, "MA data(len:%"SC_FORMAT_LEN_SIZE_T"u) '%s'",
318 cwa_session->mdata_len,
319 sc_dump_hex(cwa_session->mdata, cwa_session->mdata_len));
320 if (cwa_session->mdata_len != 0x48)
321 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "iasecc_sm_initialize() invalid MUTUAL AUTHENTICATE result data");
322
323 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
324 #else
325 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
326 return SC_ERROR_NOT_SUPPORTED;
327 #endif
328 }
329
330
331 #ifdef ENABLE_SM
332 static int
iasecc_sm_cmd(struct sc_card * card,struct sc_remote_data * rdata)333 iasecc_sm_cmd(struct sc_card *card, struct sc_remote_data *rdata)
334 {
335 #define AUTH_SM_APDUS_MAX 12
336 #define ENCODED_APDUS_MAX_LENGTH (AUTH_SM_APDUS_MAX * (SC_MAX_APDU_BUFFER_SIZE * 2 + 64) + 32)
337 struct sc_context *ctx = card->ctx;
338 struct sm_info *sm_info = &card->sm_ctx.info;
339 struct sm_cwa_session *session = &sm_info->session.cwa;
340 struct sc_remote_apdu *rapdu = NULL;
341 int rv;
342
343 LOG_FUNC_CALLED(ctx);
344 if (!card->sm_ctx.module.ops.get_apdus)
345 LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
346
347 rv = card->sm_ctx.module.ops.get_apdus(ctx, sm_info, session->mdata, session->mdata_len, rdata);
348 LOG_TEST_RET(ctx, rv, "iasecc_sm_cmd() 'GET APDUS' failed");
349
350 sc_log(ctx, "iasecc_sm_cmd() %i remote APDUs to transmit", rdata->length);
351 for (rapdu = rdata->data; rapdu; rapdu = rapdu->next) {
352 struct sc_apdu *apdu = &rapdu->apdu;
353
354 sc_log(ctx,
355 "iasecc_sm_cmd() apdu->ins:0x%X, resplen %"SC_FORMAT_LEN_SIZE_T"u",
356 apdu->ins, apdu->resplen);
357 if (!apdu->ins)
358 break;
359 rv = sc_transmit_apdu(card, apdu);
360 if (rv < 0) {
361 sc_log(ctx, "iasecc_sm_cmd() APDU transmit error rv:%i", rv);
362 break;
363 }
364
365 rv = sc_check_sw(card, apdu->sw1, apdu->sw2);
366 if (rv < 0 && !(rapdu->flags & SC_REMOTE_APDU_FLAG_NOT_FATAL)) {
367 sc_log(ctx, "iasecc_sm_cmd() APDU error rv:%i", rv);
368 break;
369 }
370 sc_log(ctx,
371 "iasecc_sm_cmd() apdu->resplen %"SC_FORMAT_LEN_SIZE_T"u",
372 apdu->resplen);
373 }
374
375 LOG_FUNC_RETURN(ctx, rv);
376 }
377 #endif
378
379
380 int
iasecc_sm_rsa_generate(struct sc_card * card,unsigned se_num,struct iasecc_sdo * sdo)381 iasecc_sm_rsa_generate(struct sc_card *card, unsigned se_num, struct iasecc_sdo *sdo)
382 {
383 struct sc_context *ctx = card->ctx;
384 #ifdef ENABLE_SM
385 struct sm_info *sm_info = &card->sm_ctx.info;
386 struct sc_remote_data rdata;
387 int rv;
388
389 LOG_FUNC_CALLED(ctx);
390 sc_log(ctx, "iasecc_sm_rsa_generate() SE#%i, SDO(class:%X,ref:%X)", se_num, sdo->sdo_class, sdo->sdo_ref);
391
392 rv = iasecc_sm_initialize(card, se_num, SM_CMD_RSA_GENERATE);
393 LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_generate() SM initialize failed");
394
395 sm_info->cmd_data = sdo;
396
397 sc_remote_data_init(&rdata);
398 rv = iasecc_sm_cmd(card, &rdata);
399 LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_generate() SM cmd failed");
400
401 rv = sm_release (card, &rdata, NULL, 0);
402 LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_generate() SM release failed");
403
404 rdata.free(&rdata);
405 LOG_FUNC_RETURN(ctx, rv);
406 #else
407 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
408 return SC_ERROR_NOT_SUPPORTED;
409 #endif
410 }
411
412
413 int
iasecc_sm_rsa_update(struct sc_card * card,unsigned se_num,struct iasecc_sdo_rsa_update * udata)414 iasecc_sm_rsa_update(struct sc_card *card, unsigned se_num, struct iasecc_sdo_rsa_update *udata)
415 {
416 struct sc_context *ctx = card->ctx;
417 #ifdef ENABLE_SM
418 struct sm_info *sm_info = &card->sm_ctx.info;
419 struct sc_remote_data rdata;
420 int rv;
421
422 LOG_FUNC_CALLED(ctx);
423 sc_log(ctx, "SM update RSA: SE#: 0x%X, SDO(class:0x%X:ref:%X)", se_num,
424 udata->sdo_prv_key->sdo_class, udata->sdo_prv_key->sdo_ref);
425
426 rv = iasecc_sm_initialize(card, se_num, SM_CMD_RSA_UPDATE);
427 LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_update() SM initialize failed");
428
429 sm_info->cmd_data = udata;
430
431 sc_remote_data_init(&rdata);
432 rv = iasecc_sm_cmd(card, &rdata);
433 LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_update() SM cmd failed");
434
435 rv = sm_release (card, &rdata, NULL, 0);
436 LOG_TEST_RET(ctx, rv, "iasecc_sm_rsa_update() SM release failed");
437
438 rdata.free(&rdata);
439 LOG_FUNC_RETURN(ctx, rv);
440 #else
441 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
442 return SC_ERROR_NOT_SUPPORTED;
443 #endif
444 }
445
446
447 int
iasecc_sm_pin_verify(struct sc_card * card,unsigned se_num,struct sc_pin_cmd_data * data,int * tries_left)448 iasecc_sm_pin_verify(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_data *data, int *tries_left)
449 {
450 struct sc_context *ctx = card->ctx;
451 #ifdef ENABLE_SM
452 struct sm_info *sm_info = &card->sm_ctx.info;
453 struct sc_remote_data rdata;
454 int rv;
455
456 LOG_FUNC_CALLED(ctx);
457 sc_log(ctx, "iasecc_sm_pin_verify() SE#%i, PIN(ref:%i,len:%i)", se_num, data->pin_reference, data->pin1.len);
458
459 rv = iasecc_sm_initialize(card, se_num, SM_CMD_PIN_VERIFY);
460 LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_verify() SM INITIALIZE failed");
461
462 sm_info->cmd_data = data;
463
464 sc_remote_data_init(&rdata);
465 rv = iasecc_sm_cmd(card, &rdata);
466 if (rv && rdata.length && tries_left)
467 if (rdata.data->apdu.sw1 == 0x63 && (rdata.data->apdu.sw2 & 0xF0) == 0xC0)
468 *tries_left = rdata.data->apdu.sw2 & 0x0F;
469
470 LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_verify() SM 'PIN VERIFY' failed");
471
472 rv = sm_release (card, &rdata, NULL, 0);
473 LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_verify() SM release failed");
474
475 rdata.free(&rdata);
476 LOG_FUNC_RETURN(ctx, rv);
477 #else
478 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
479 return SC_ERROR_NOT_SUPPORTED;
480 #endif
481 }
482
483
484 int
iasecc_sm_sdo_update(struct sc_card * card,unsigned se_num,struct iasecc_sdo_update * update)485 iasecc_sm_sdo_update(struct sc_card *card, unsigned se_num, struct iasecc_sdo_update *update)
486 {
487 struct sc_context *ctx = card->ctx;
488 #ifdef ENABLE_SM
489 struct sm_info *sm_info = &card->sm_ctx.info;
490 struct sc_remote_data rdata;
491 int rv;
492
493 LOG_FUNC_CALLED(ctx);
494 sc_log(ctx, "iasecc_sm_sdo_update() SE#%i, SDO(class:0x%X,ref:%i)", se_num, update->sdo_class, update->sdo_ref);
495
496 rv = iasecc_sm_initialize(card, se_num, SM_CMD_SDO_UPDATE);
497 LOG_TEST_RET(ctx, rv, "iasecc_sm_sdo_update() SM INITIALIZE failed");
498
499 sc_log(ctx, "current DF '%s'", sc_print_path(&sm_info->current_path_df));
500
501 sm_info->cmd_data = update;
502
503 sc_remote_data_init(&rdata);
504 rv = iasecc_sm_cmd(card, &rdata);
505 LOG_TEST_RET(ctx, rv, "iasecc_sm_sdo_update() SM 'SDO UPDATE' failed");
506
507 rv = sm_release (card, &rdata, NULL, 0);
508 LOG_TEST_RET(ctx, rv, "iasecc_sm_sdo_update() SM release failed");
509
510 rdata.free(&rdata);
511 LOG_FUNC_RETURN(ctx, rv);
512 #else
513 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
514 return SC_ERROR_NOT_SUPPORTED;
515 #endif
516 }
517
518
519 int
iasecc_sm_pin_reset(struct sc_card * card,unsigned se_num,struct sc_pin_cmd_data * data)520 iasecc_sm_pin_reset(struct sc_card *card, unsigned se_num, struct sc_pin_cmd_data *data)
521 {
522 struct sc_context *ctx = card->ctx;
523 #ifdef ENABLE_SM
524 struct sm_info *sm_info = &card->sm_ctx.info;
525 struct sc_remote_data rdata;
526 int rv;
527
528 LOG_FUNC_CALLED(ctx);
529 sc_log(ctx, "iasecc_sm_pin_reset() SE#%i, PIN(ref:%i,len:%i)", se_num, data->pin_reference, data->pin2.len);
530
531 rv = iasecc_sm_initialize(card, se_num, SM_CMD_PIN_RESET);
532 LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_reset() SM INITIALIZE failed");
533
534 sm_info->cmd_data = data;
535
536 sc_remote_data_init(&rdata);
537 rv = iasecc_sm_cmd(card, &rdata);
538 LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_reset() SM 'PIN RESET' failed");
539
540 rv = sm_release (card, &rdata, NULL, 0);
541 LOG_TEST_RET(ctx, rv, "iasecc_sm_pin_reset() SM release failed");
542
543 rdata.free(&rdata);
544 LOG_FUNC_RETURN(ctx, rv);
545 #else
546 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
547 return SC_ERROR_NOT_SUPPORTED;
548 #endif
549 }
550
551
552 int
iasecc_sm_create_file(struct sc_card * card,unsigned se_num,unsigned char * fcp,size_t fcp_len)553 iasecc_sm_create_file(struct sc_card *card, unsigned se_num, unsigned char *fcp, size_t fcp_len)
554 {
555 struct sc_context *ctx = card->ctx;
556 #ifdef ENABLE_SM
557 struct sm_info *sm_info = &card->sm_ctx.info;
558 struct sc_remote_data rdata;
559 struct iasecc_sm_cmd_create_file cmd_data;
560 int rv;
561
562 LOG_FUNC_CALLED(ctx);
563 sc_log(ctx,
564 "iasecc_sm_create_file() SE#%i, fcp(%"SC_FORMAT_LEN_SIZE_T"u) '%s'",
565 se_num, fcp_len, sc_dump_hex(fcp, fcp_len));
566
567 rv = iasecc_sm_initialize(card, se_num, SM_CMD_FILE_CREATE);
568 LOG_TEST_RET(ctx, rv, "iasecc_sm_create_file() SM INITIALIZE failed");
569
570 cmd_data.data = fcp;
571 cmd_data.size = fcp_len;
572 sm_info->cmd_data = &cmd_data;
573
574 sc_remote_data_init(&rdata);
575 rv= iasecc_sm_cmd(card, &rdata);
576 LOG_TEST_RET(ctx, rv, "iasecc_sm_create_file() SM 'UPDATE BINARY' failed");
577
578 rv = sm_release (card, &rdata, NULL, 0);
579 LOG_TEST_RET(ctx, rv, "iasecc_sm_create_file() SM release failed");
580
581 rdata.free(&rdata);
582 LOG_FUNC_RETURN(ctx, rv);
583 #else
584 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
585 return SC_ERROR_NOT_SUPPORTED;
586 #endif
587 }
588
589 int
iasecc_sm_read_binary(struct sc_card * card,unsigned se_num,size_t offs,unsigned char * buff,size_t count)590 iasecc_sm_read_binary(struct sc_card *card, unsigned se_num, size_t offs, unsigned char *buff, size_t count)
591 {
592 struct sc_context *ctx = card->ctx;
593 #ifdef ENABLE_SM
594 struct sm_info *sm_info = &card->sm_ctx.info;
595 struct sc_remote_data rdata;
596 struct iasecc_sm_cmd_update_binary cmd_data;
597 int rv;
598
599 LOG_FUNC_CALLED(ctx);
600 sc_log(ctx,
601 "SM read binary: acl:%X, offs:%"SC_FORMAT_LEN_SIZE_T"u, count:%"SC_FORMAT_LEN_SIZE_T"u",
602 se_num, offs, count);
603
604 rv = iasecc_sm_initialize(card, se_num, SM_CMD_FILE_READ);
605 LOG_TEST_RET(ctx, rv, "iasecc_sm_read_binary() SM INITIALIZE failed");
606
607 cmd_data.offs = offs;
608 cmd_data.count = count;
609 sm_info->cmd_data = &cmd_data;
610
611 sc_remote_data_init(&rdata);
612 rv = iasecc_sm_cmd(card, &rdata);
613 LOG_TEST_RET(ctx, rv, "iasecc_sm_read_binary() SM 'READ BINARY' failed");
614
615 sc_log(ctx, "IAS/ECC decode answer() rdata length %i", rdata.length);
616
617 rv = sm_release (card, &rdata, buff, count);
618 LOG_TEST_RET(ctx, rv, "iasecc_sm_read_binary() SM release failed");
619
620 rdata.free(&rdata);
621 LOG_FUNC_RETURN(ctx, rv);
622 #else
623 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
624 return SC_ERROR_NOT_SUPPORTED;
625 #endif
626 }
627
628
629 int
iasecc_sm_update_binary(struct sc_card * card,unsigned se_num,size_t offs,const unsigned char * buff,size_t count)630 iasecc_sm_update_binary(struct sc_card *card, unsigned se_num, size_t offs,
631 const unsigned char *buff, size_t count)
632 {
633 struct sc_context *ctx = card->ctx;
634 #ifdef ENABLE_SM
635 struct sm_info *sm_info = &card->sm_ctx.info;
636 struct sc_remote_data rdata;
637 struct iasecc_sm_cmd_update_binary cmd_data;
638 int rv;
639
640 LOG_FUNC_CALLED(ctx);
641 sc_log(ctx,
642 "SM update binary: acl:%X, offs:%"SC_FORMAT_LEN_SIZE_T"u, count:%"SC_FORMAT_LEN_SIZE_T"u",
643 se_num, offs, count);
644
645 rv = iasecc_sm_initialize(card, se_num, SM_CMD_FILE_UPDATE);
646 LOG_TEST_RET(ctx, rv, "iasecc_sm_update_binary() SM INITIALIZE failed");
647
648 cmd_data.offs = offs;
649 cmd_data.count = count;
650 cmd_data.data = buff;
651 sm_info->cmd_data = &cmd_data;
652
653 sc_remote_data_init(&rdata);
654 rv = iasecc_sm_cmd(card, &rdata);
655 LOG_TEST_RET(ctx, rv, "iasecc_sm_update_binary() SM 'UPDATE BINARY' failed");
656
657 rv = sm_release (card, &rdata, NULL, 0);
658 LOG_TEST_RET(ctx, rv, "iasecc_sm_update_binary() SM release failed");
659
660 rdata.free(&rdata);
661 LOG_FUNC_RETURN(ctx, count);
662 #else
663 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
664 return SC_ERROR_NOT_SUPPORTED;
665 #endif
666 }
667
668
669 int
iasecc_sm_delete_file(struct sc_card * card,unsigned se_num,unsigned int file_id)670 iasecc_sm_delete_file(struct sc_card *card, unsigned se_num, unsigned int file_id)
671 {
672 struct sc_context *ctx = card->ctx;
673 #ifdef ENABLE_SM
674 struct sm_info *sm_info = &card->sm_ctx.info;
675 struct sc_remote_data rdata;
676 int rv;
677
678 LOG_FUNC_CALLED(ctx);
679 sc_log(ctx, "SM delete file: SE#:%X, file-id:%X", se_num, file_id);
680
681 rv = iasecc_sm_initialize(card, se_num, SM_CMD_FILE_DELETE);
682 LOG_TEST_RET(ctx, rv, "iasecc_sm_delete_file() SM INITIALIZE failed");
683
684 sm_info->cmd_data = (void *)(uintptr_t)file_id;
685
686 sc_remote_data_init(&rdata);
687 rv = iasecc_sm_cmd(card, &rdata);
688 LOG_TEST_RET(ctx, rv, "iasecc_sm_delete_file() SM 'FILE DELETE' failed");
689
690 rv = sm_release (card, &rdata, NULL, 0);
691 LOG_TEST_RET(ctx, rv, "iasecc_sm_delete_file() SM release failed");
692
693 rdata.free(&rdata);
694 LOG_FUNC_RETURN(ctx, rv);
695 #else
696 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
697 return SC_ERROR_NOT_SUPPORTED;
698 #endif
699 }
700
701
702