Coverage Report

Created: 2025-12-07 06:37

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