Coverage Report

Created: 2026-03-08 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/sm/sm-iso.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2011-2015 Frank Morgner
3
 *
4
 * This file is part of OpenSC.
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
#ifdef HAVE_CONFIG_H
21
#include "config.h"
22
#endif
23
24
#include "sm-iso-internal.h"
25
#include "libopensc/asn1.h"
26
#include "libopensc/log.h"
27
#include "sm/sm-iso.h"
28
#include <stdlib.h>
29
#include <string.h>
30
31
#ifdef ENABLE_SM
32
33
static const struct sc_asn1_entry c_sm_capdu[] = {
34
  { "Cryptogram",
35
    SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x05, SC_ASN1_OPTIONAL, NULL, NULL },
36
  { "Padding-content indicator followed by cryptogram",
37
    SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x07, SC_ASN1_OPTIONAL, NULL, NULL },
38
  { "Protected Le",
39
    SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x17, SC_ASN1_OPTIONAL, NULL, NULL },
40
  { "Cryptographic Checksum",
41
    SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x0E, SC_ASN1_OPTIONAL, NULL, NULL },
42
  { NULL , 0 , 0 , 0 , NULL , NULL }
43
};
44
45
static const struct sc_asn1_entry c_sm_rapdu[] = {
46
  { "Cryptogram",
47
    SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x05, SC_ASN1_OPTIONAL, NULL, NULL },
48
  { "Padding-content indicator followed by cryptogram" ,
49
    SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x07, SC_ASN1_OPTIONAL, NULL, NULL },
50
  { "Processing Status",
51
    SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x19, 0               , NULL, NULL },
52
  { "Cryptographic Checksum",
53
    SC_ASN1_OCTET_STRING, SC_ASN1_CTX|0x0E, SC_ASN1_OPTIONAL, NULL, NULL },
54
  { NULL, 0, 0, 0, NULL, NULL }
55
};
56
57
static int
58
add_iso_pad(const u8 *data, size_t datalen, size_t block_size, u8 **padded)
59
0
{
60
0
  u8 *p;
61
0
  int p_len;
62
63
0
  if (!padded)
64
0
    return SC_ERROR_INVALID_ARGUMENTS;
65
66
  /* calculate length of padded message */
67
0
  p_len = (int)((datalen / block_size) * block_size + block_size);
68
69
0
  p = realloc(*padded, p_len);
70
0
  if (!p)
71
0
    return SC_ERROR_OUT_OF_MEMORY;
72
73
0
  if (*padded != data)
74
0
    memcpy(p, data, datalen);
75
76
0
  *padded = p;
77
78
  /* now add iso padding */
79
0
  memset(p + datalen, 0x80, 1);
80
0
  memset(p + datalen + 1, 0, p_len - datalen - 1);
81
82
0
  return p_len;
83
0
}
84
85
static int
86
add_padding(const struct iso_sm_ctx *ctx, const u8 *data, size_t datalen,
87
    u8 **padded)
88
0
{
89
0
  u8 *p;
90
91
0
  switch (ctx->padding_indicator) {
92
0
    case SM_NO_PADDING:
93
0
      if (*padded != data) {
94
0
        if (datalen != 0) {
95
0
          p = realloc(*padded, datalen);
96
0
          if (!p)
97
0
            return SC_ERROR_OUT_OF_MEMORY;
98
0
          *padded = p;
99
0
          memcpy(*padded, data, datalen);
100
0
        } else {
101
0
          *padded = NULL;
102
0
        }
103
0
      }
104
0
      return (int)datalen;
105
0
    case SM_ISO_PADDING:
106
0
      return add_iso_pad(data, datalen, ctx->block_length, padded);
107
0
    default:
108
0
      return SC_ERROR_INVALID_ARGUMENTS;
109
0
  }
110
0
}
111
112
static int
113
rm_padding(u8 padding_indicator, const u8 *data, size_t datalen)
114
0
{
115
0
  size_t len;
116
117
0
  if (!datalen || !data)
118
0
    return SC_ERROR_INVALID_ARGUMENTS;
119
120
0
  switch (padding_indicator) {
121
0
    case SM_NO_PADDING:
122
0
      len = datalen;
123
0
      break;
124
125
0
    case SM_ISO_PADDING:
126
0
      len = datalen;
127
128
0
      while (len) {
129
0
        len--;
130
0
        if (data[len])
131
0
          break;
132
0
      }
133
134
0
      if (data[len] != 0x80)
135
0
        return SC_ERROR_INVALID_DATA;
136
137
0
      break;
138
139
0
    default:
140
0
      return SC_ERROR_NOT_SUPPORTED;
141
0
  }
142
143
0
  return (int)len;
144
0
}
145
146
static int format_le(size_t le, struct sc_asn1_entry *le_entry,
147
    u8 **lebuf, size_t *le_len)
148
0
{
149
0
  u8 *p;
150
151
0
  if (!lebuf || !le_len || !*le_len)
152
0
    return SC_ERROR_INVALID_ARGUMENTS;
153
154
0
  p = realloc(*lebuf, *le_len);
155
0
  if (!p)
156
0
    return SC_ERROR_OUT_OF_MEMORY;
157
0
  *lebuf = p;
158
159
0
  switch (*le_len) {
160
0
    case 1:
161
0
      p[0] = le & 0xff;
162
0
      break;
163
0
    case 2:
164
0
      p[0] = (le >> 8) & 0xff;
165
0
      p[1] = le & 0xff;
166
0
      break;
167
0
    case 3:
168
0
      p[0] = 0x00;
169
0
      p[1] = (le >> 8) & 0xff;
170
0
      p[2] = le & 0xff;
171
0
      break;
172
0
    default:
173
0
      return SC_ERROR_INVALID_ARGUMENTS;
174
0
  }
175
176
0
  sc_format_asn1_entry(le_entry, *lebuf, le_len, SC_ASN1_PRESENT);
177
178
0
  return SC_SUCCESS;
179
0
}
180
181
static int prefix_buf(u8 prefix, u8 *buf, size_t buflen, u8 **cat)
182
0
{
183
0
  u8 *p = NULL;
184
0
  int ptr_same = *cat == buf;
185
186
0
  p = realloc(*cat, buflen + 1);
187
0
  if (!p)
188
0
    return SC_ERROR_OUT_OF_MEMORY;
189
190
0
  if (ptr_same) {
191
0
    memmove(p + 1, p, buflen);
192
0
  } else {
193
0
    memcpy(p + 1, buf, buflen);
194
0
  }
195
0
  p[0] = prefix;
196
197
0
  *cat = p;
198
199
0
  return (int)buflen + 1;
200
0
}
201
202
static int format_data(sc_card_t *card, const struct iso_sm_ctx *ctx,
203
    int prepend_padding_indicator, const u8 *data, size_t datalen,
204
    struct sc_asn1_entry *formatted_encrypted_data_entry,
205
    u8 **formatted_data, size_t *formatted_data_len)
206
0
{
207
0
  int r;
208
0
  u8 *pad_data = NULL;
209
0
  size_t pad_data_len = 0;
210
211
0
  if (!ctx || !formatted_data || !formatted_data_len) {
212
0
    r = SC_ERROR_INVALID_ARGUMENTS;
213
0
    goto err;
214
0
  }
215
216
0
  r = add_padding(ctx, data, datalen, &pad_data);
217
0
  if (r < 0) {
218
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not add padding to data: %s",
219
0
        sc_strerror(r));
220
0
    goto err;
221
0
  }
222
0
  pad_data_len = r;
223
224
0
  sc_log_hex(card->ctx, "Data to encrypt", pad_data, pad_data_len);
225
0
  r = ctx->encrypt(card, ctx, pad_data, pad_data_len, formatted_data);
226
0
  if (r < 0) {
227
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not encrypt the data");
228
0
    goto err;
229
0
  }
230
0
  sc_log_hex(card->ctx, "Cryptogram", *formatted_data, r);
231
232
0
  if (prepend_padding_indicator) {
233
0
    r = prefix_buf(ctx->padding_indicator, *formatted_data, r, formatted_data);
234
0
    if (r < 0) {
235
0
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not prepend padding indicator to formatted "
236
0
          "data: %s", sc_strerror(r));
237
0
      goto err;
238
0
    }
239
0
  }
240
241
0
  *formatted_data_len = r;
242
0
  sc_format_asn1_entry(formatted_encrypted_data_entry,
243
0
      *formatted_data, formatted_data_len, SC_ASN1_PRESENT);
244
245
0
  r = SC_SUCCESS;
246
247
0
err:
248
0
  if (pad_data) {
249
0
    sc_mem_clear(pad_data, pad_data_len);
250
0
    free(pad_data);
251
0
  }
252
253
0
  return r;
254
0
}
255
256
static int format_head(const struct iso_sm_ctx *ctx, const sc_apdu_t *apdu,
257
    u8 **formatted_head)
258
0
{
259
0
  u8 *p;
260
261
0
  if (!apdu || !formatted_head)
262
0
    return SC_ERROR_INVALID_ARGUMENTS;
263
264
0
  p = realloc(*formatted_head, 4);
265
0
  if (!p)
266
0
    return SC_ERROR_OUT_OF_MEMORY;
267
268
0
  p[0] = apdu->cla;
269
0
  p[1] = apdu->ins;
270
0
  p[2] = apdu->p1;
271
0
  p[3] = apdu->p2;
272
0
  *formatted_head = p;
273
274
0
  return add_padding(ctx, *formatted_head, 4, formatted_head);
275
0
}
276
277
static int sm_encrypt(const struct iso_sm_ctx *ctx, sc_card_t *card,
278
    const sc_apdu_t *apdu, sc_apdu_t **psm_apdu)
279
0
{
280
0
  struct sc_asn1_entry sm_capdu[5];
281
0
  u8 *p, *le = NULL, *sm_data = NULL, *fdata = NULL, *mac_data = NULL,
282
0
     *asn1 = NULL, *mac = NULL, *resp_data = NULL;
283
0
  size_t sm_data_len, fdata_len, mac_data_len, asn1_len, mac_len, le_len;
284
0
  int r;
285
0
  sc_apdu_t *sm_apdu = NULL;
286
287
0
  if (!apdu || !ctx || !card || !card->reader || !psm_apdu) {
288
0
    r = SC_ERROR_INVALID_ARGUMENTS;
289
0
    goto err;
290
0
  }
291
292
0
  if ((apdu->cla & 0x0C) == 0x0C) {
293
0
    r = SC_ERROR_INVALID_ARGUMENTS;
294
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Given APDU is already protected with some secure messaging");
295
0
    goto err;
296
0
  }
297
298
0
  sc_copy_asn1_entry(c_sm_capdu, sm_capdu);
299
300
0
  sm_apdu = malloc(sizeof(sc_apdu_t));
301
0
  if (!sm_apdu) {
302
0
    r = SC_ERROR_OUT_OF_MEMORY;
303
0
    goto err;
304
0
  }
305
0
  sm_apdu->control = apdu->control;
306
0
  sm_apdu->flags = apdu->flags;
307
0
  sm_apdu->cla = apdu->cla|0x0C;
308
0
  sm_apdu->ins = apdu->ins;
309
0
  sm_apdu->p1 = apdu->p1;
310
0
  sm_apdu->p2 = apdu->p2;
311
0
  r = format_head(ctx, sm_apdu, &mac_data);
312
0
  if (r < 0) {
313
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format header of SM apdu");
314
0
    goto err;
315
0
  }
316
0
  mac_data_len = r;
317
318
0
  switch (apdu->cse) {
319
0
    case SC_APDU_CASE_1:
320
0
      break;
321
0
  case SC_APDU_CASE_2_SHORT:
322
0
      le_len = 1;
323
0
      r = format_le(apdu->le, sm_capdu + 2, &le, &le_len);
324
0
      if (r < 0) {
325
0
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu");
326
0
        goto err;
327
0
      }
328
0
      sc_log_hex(card->ctx, "Protected Le (plain)", le, le_len);
329
0
      break;
330
0
  case SC_APDU_CASE_2_EXT:
331
0
      if (card->reader->active_protocol == SC_PROTO_T0) {
332
        /* T0 extended APDUs look just like short APDUs */
333
0
        le_len = 1;
334
0
        r = format_le(apdu->le, sm_capdu + 2, &le, &le_len);
335
0
        if (r < 0) {
336
0
          sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu");
337
0
          goto err;
338
0
        }
339
0
      } else {
340
        /* in case of T1 always use 2 bytes for length */
341
0
        le_len = 2;
342
0
        r = format_le(apdu->le, sm_capdu + 2, &le, &le_len);
343
0
        if (r < 0) {
344
0
          sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu");
345
0
          goto err;
346
0
        }
347
0
      }
348
0
      sc_log_hex(card->ctx, "Protected Le (plain)", le, le_len);
349
0
      break;
350
0
    case SC_APDU_CASE_3_SHORT:
351
0
    case SC_APDU_CASE_3_EXT:
352
0
      if (apdu->ins & 1) {
353
0
        r = format_data(card, ctx, 0, apdu->data, apdu->datalen,
354
0
            sm_capdu + 0, &fdata, &fdata_len);
355
0
      } else {
356
0
        r = format_data(card, ctx, 1, apdu->data, apdu->datalen,
357
0
            sm_capdu + 1, &fdata, &fdata_len);
358
0
      }
359
0
      if (r < 0) {
360
0
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu");
361
0
        goto err;
362
0
      }
363
0
      sc_log_hex(card->ctx, "Padding-content indicator followed by cryptogram (plain)",
364
0
          fdata, fdata_len);
365
0
      break;
366
0
    case SC_APDU_CASE_4_SHORT:
367
      /* in case of T0 no Le byte is added */
368
0
      if (card->reader->active_protocol != SC_PROTO_T0) {
369
0
        le_len = 1;
370
0
        r = format_le(apdu->le, sm_capdu + 2, &le, &le_len);
371
0
        if (r < 0) {
372
0
          sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu");
373
0
          goto err;
374
0
        }
375
0
        sc_log_hex(card->ctx, "Protected Le (plain)", le, le_len);
376
0
      }
377
378
0
      if (apdu->ins & 1) {
379
0
        r = format_data(card, ctx, 0, apdu->data, apdu->datalen,
380
0
            sm_capdu + 0, &fdata, &fdata_len);
381
0
      } else {
382
0
        r = format_data(card, ctx, 1, apdu->data, apdu->datalen,
383
0
            sm_capdu + 1, &fdata, &fdata_len);
384
0
      }
385
0
      if (r < 0) {
386
0
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu");
387
0
        goto err;
388
0
      }
389
0
      sc_log_hex(card->ctx, "Padding-content indicator followed by cryptogram (plain)",
390
0
          fdata, fdata_len);
391
0
      break;
392
0
    case SC_APDU_CASE_4_EXT:
393
0
      if (card->reader->active_protocol == SC_PROTO_T0) {
394
        /* again a T0 extended case 4 APDU looks just
395
         * like a short APDU, the additional data is
396
         * transferred using ENVELOPE and GET RESPONSE */
397
0
      } else {
398
        /* only 2 bytes are use to specify the length of the
399
         * expected data */
400
0
        le_len = 2;
401
0
        r = format_le(apdu->le, sm_capdu + 2, &le, &le_len);
402
0
        if (r < 0) {
403
0
          sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format Le of SM apdu");
404
0
          goto err;
405
0
        }
406
0
        sc_log_hex(card->ctx, "Protected Le (plain)", le, le_len);
407
0
      }
408
409
0
      if (apdu->ins & 1) {
410
0
        r = format_data(card, ctx, 0, apdu->data, apdu->datalen,
411
0
            sm_capdu + 0, &fdata, &fdata_len);
412
0
      } else {
413
0
        r = format_data(card, ctx, 1, apdu->data, apdu->datalen,
414
0
            sm_capdu + 1, &fdata, &fdata_len);
415
0
      }
416
0
      if (r < 0) {
417
0
        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not format data of SM apdu");
418
0
        goto err;
419
0
      }
420
0
      sc_log_hex(card->ctx, "Padding-content indicator followed by cryptogram (plain)",
421
0
          fdata, fdata_len);
422
0
      break;
423
0
    default:
424
0
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Unhandled apdu case");
425
0
      r = SC_ERROR_INVALID_DATA;
426
0
      goto err;
427
0
  }
428
429
430
0
  r = sc_asn1_encode(card->ctx, sm_capdu, (u8 **) &asn1, &asn1_len);
431
0
  if (r < 0) {
432
0
    goto err;
433
0
  }
434
0
  if (asn1_len) {
435
0
    p = realloc(mac_data, mac_data_len + asn1_len);
436
0
    if (!p) {
437
0
      r = SC_ERROR_OUT_OF_MEMORY;
438
0
      goto err;
439
0
    }
440
0
    mac_data = p;
441
0
    memcpy(mac_data + mac_data_len, asn1, asn1_len);
442
0
    mac_data_len += asn1_len;
443
0
    r = add_padding(ctx, mac_data, mac_data_len, &mac_data);
444
0
    if (r < 0) {
445
0
      goto err;
446
0
    }
447
0
    mac_data_len = r;
448
0
  }
449
0
  sc_log_hex(card->ctx, "Data to authenticate", mac_data, mac_data_len);
450
451
0
  r = ctx->authenticate(card, ctx, mac_data, mac_data_len,
452
0
      &mac);
453
0
  if (r < 0) {
454
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not get authentication code");
455
0
    goto err;
456
0
  }
457
0
  mac_len = r;
458
0
  sc_log_hex(card->ctx, "Cryptographic Checksum (plain)", mac, mac_len);
459
460
461
  /* format SM apdu */
462
0
  sc_format_asn1_entry(sm_capdu + 3, mac, &mac_len, SC_ASN1_PRESENT);
463
0
  r = sc_asn1_encode(card->ctx, sm_capdu, (u8 **) &sm_data, &sm_data_len);
464
0
  if (r < 0)
465
0
    goto err;
466
0
  sm_apdu->data = sm_data;
467
0
  sm_apdu->datalen = sm_data_len;
468
0
  sm_apdu->lc = sm_data_len;
469
0
  sm_apdu->le = 0;
470
  /* for encrypted APDUs we usually get authenticated status bytes (4B), a
471
   * MAC (2B without data) and a cryptogram with padding indicator (2B tag
472
   * and indicator, max. 2B/3B ASN.1 length, without data). The cryptogram is
473
   * always padded to the block size. */
474
0
  if (apdu->cse & SC_APDU_EXT) {
475
0
    sm_apdu->cse = SC_APDU_CASE_4_EXT;
476
0
    sm_apdu->resplen = 4 + 2 + mac_len + 2 + 3 + ((apdu->resplen+1)/ctx->block_length+1)*ctx->block_length;
477
0
    if (sm_apdu->resplen > SC_MAX_EXT_APDU_RESP_SIZE)
478
0
      sm_apdu->resplen = SC_MAX_EXT_APDU_RESP_SIZE;
479
0
  } else {
480
0
    sm_apdu->cse = SC_APDU_CASE_4_SHORT;
481
0
    sm_apdu->resplen = 4 + 2 + mac_len + 2 + 2 + ((apdu->resplen+1)/ctx->block_length+1)*ctx->block_length;
482
0
    if (sm_apdu->resplen > SC_MAX_APDU_RESP_SIZE)
483
0
      sm_apdu->resplen = SC_MAX_APDU_RESP_SIZE;
484
0
  }
485
0
  resp_data = calloc(1, sm_apdu->resplen);
486
0
  if (!resp_data) {
487
0
    r = SC_ERROR_OUT_OF_MEMORY;
488
0
    goto err;
489
0
  }
490
0
  sm_apdu->resp = resp_data;
491
0
  sc_log_hex(card->ctx, "ASN.1 encoded encrypted APDU data", sm_apdu->data, sm_apdu->datalen);
492
493
0
  *psm_apdu = sm_apdu;
494
495
0
err:
496
0
  free(fdata);
497
0
  free(asn1);
498
0
  free(mac_data);
499
0
  free(mac);
500
0
  free(le);
501
0
  if (r < 0) {
502
0
    free(resp_data);
503
0
    free(sm_apdu);
504
0
    free(sm_data);
505
0
  }
506
507
0
  return r;
508
0
}
509
510
static int sm_decrypt(const struct iso_sm_ctx *ctx, sc_card_t *card,
511
    const sc_apdu_t *sm_apdu, sc_apdu_t *apdu)
512
0
{
513
0
  int r;
514
0
  struct sc_asn1_entry sm_rapdu[5];
515
0
  struct sc_asn1_entry my_sm_rapdu[5];
516
0
  u8 sw[2], mac[8], fdata[SC_MAX_EXT_APDU_BUFFER_SIZE];
517
0
  size_t sw_len = sizeof sw, mac_len = sizeof mac, fdata_len = sizeof fdata,
518
0
       buf_len, asn1_len, fdata_offset = 0;
519
0
  const u8 *buf;
520
0
  u8 *data = NULL, *mac_data = NULL, *asn1 = NULL;
521
522
0
  sc_copy_asn1_entry(c_sm_rapdu, sm_rapdu);
523
0
  sc_format_asn1_entry(sm_rapdu + 0, fdata, &fdata_len, 0);
524
0
  sc_format_asn1_entry(sm_rapdu + 1, fdata, &fdata_len, 0);
525
0
  sc_format_asn1_entry(sm_rapdu + 2, sw, &sw_len, 0);
526
0
  sc_format_asn1_entry(sm_rapdu + 3, mac, &mac_len, 0);
527
528
0
  r = sc_asn1_decode(card->ctx, sm_rapdu, sm_apdu->resp, sm_apdu->resplen,
529
0
      &buf, &buf_len);
530
0
  if (r < 0)
531
0
    goto err;
532
0
  if (buf_len > 0) {
533
0
    r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
534
0
    goto err;
535
0
  }
536
537
538
0
  if (sm_rapdu[3].flags & SC_ASN1_PRESENT) {
539
    /* copy from sm_apdu to my_sm_apdu, but leave mac at default */
540
0
    sc_copy_asn1_entry(sm_rapdu, my_sm_rapdu);
541
0
    sc_copy_asn1_entry(&c_sm_rapdu[3], &my_sm_rapdu[3]);
542
543
0
    r = sc_asn1_encode(card->ctx, my_sm_rapdu, &asn1, &asn1_len);
544
0
    if (r < 0)
545
0
      goto err;
546
0
    r = add_padding(ctx, asn1, asn1_len, &mac_data);
547
0
    if (r < 0) {
548
0
      goto err;
549
0
    }
550
551
0
    r = ctx->verify_authentication(card, ctx, mac, mac_len,
552
0
        mac_data, r);
553
0
    if (r < 0)
554
0
      goto err;
555
0
  } else {
556
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Cryptographic Checksum missing");
557
0
    r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
558
0
    goto err;
559
0
  }
560
561
562
0
  if (sm_rapdu[1].flags & SC_ASN1_PRESENT) {
563
0
    if (ctx->padding_indicator != fdata[0]) {
564
0
      r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
565
0
      goto err;
566
0
    }
567
0
    fdata_offset = 1;
568
0
  }
569
0
  if (sm_rapdu[0].flags & SC_ASN1_PRESENT
570
0
      || sm_rapdu[1].flags & SC_ASN1_PRESENT) {
571
0
    r = ctx->decrypt(card, ctx, fdata + fdata_offset,
572
0
        fdata_len - fdata_offset, &data);
573
0
    if (r < 0)
574
0
      goto err;
575
0
    buf_len = r;
576
577
0
    r = rm_padding(ctx->padding_indicator, data, buf_len);
578
0
    if (r < 0) {
579
0
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not remove padding");
580
0
      goto err;
581
0
    }
582
583
0
    if (apdu->resplen < (size_t) r || (r && !apdu->resp)) {
584
0
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
585
0
          "Response of SM APDU %"SC_FORMAT_LEN_SIZE_T"u byte%s too long",
586
0
          r-apdu->resplen,
587
0
          r-apdu->resplen < 2 ? "" : "s");
588
0
      r = SC_ERROR_OUT_OF_MEMORY;
589
0
      goto err;
590
0
    }
591
0
    memcpy(apdu->resp, data, r);
592
0
    apdu->resplen = r;
593
0
  } else {
594
0
    apdu->resplen = 0;
595
0
  }
596
597
0
  if (sm_rapdu[2].flags & SC_ASN1_PRESENT) {
598
0
    if (sw_len != 2) {
599
0
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Length of processing status bytes must be 2");
600
0
      r = SC_ERROR_ASN1_END_OF_CONTENTS;
601
0
      goto err;
602
0
    }
603
0
    apdu->sw1 = sw[0];
604
0
    apdu->sw2 = sw[1];
605
0
  } else {
606
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Authenticated status bytes are missing");
607
0
    r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
608
0
    goto err;
609
0
  }
610
611
0
  sc_log(card->ctx,  "Decrypted APDU sw1=%02x sw2=%02x",
612
0
      apdu->sw1, apdu->sw2);
613
0
  sc_log_hex(card->ctx, "Decrypted APDU response data",
614
0
      apdu->resp, apdu->resplen);
615
616
0
  r = SC_SUCCESS;
617
618
0
err:
619
0
  free(asn1);
620
0
  free(mac_data);
621
0
  if (data) {
622
0
    sc_mem_clear(data, buf_len);
623
0
    free(data);
624
0
  }
625
626
0
  return r;
627
0
}
628
629
static int iso_add_sm(struct iso_sm_ctx *sctx, sc_card_t *card,
630
    sc_apdu_t *apdu, sc_apdu_t **sm_apdu)
631
0
{
632
0
  if (!card || !sctx)
633
0
    return SC_ERROR_INVALID_ARGUMENTS;
634
635
0
  if ((apdu->cla & 0x0C) == 0x0C) {
636
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Given APDU is already protected with some secure messaging. Closing own SM context.");
637
0
    LOG_TEST_RET(card->ctx, sc_sm_stop(card),
638
0
        "Could not close ISO SM session");
639
0
    return SC_ERROR_SM_NOT_APPLIED;
640
0
  }
641
642
0
  if (sctx->pre_transmit)
643
0
    LOG_TEST_RET(card->ctx, sctx->pre_transmit(card, sctx, apdu),
644
0
        "Could not complete SM specific pre transmit routine");
645
0
  LOG_TEST_RET(card->ctx, sm_encrypt(sctx, card, apdu, sm_apdu),
646
0
      "Could not encrypt APDU");
647
648
0
  return SC_SUCCESS;
649
0
}
650
651
static int iso_rm_sm(struct iso_sm_ctx *sctx, sc_card_t *card,
652
    sc_apdu_t *sm_apdu, sc_apdu_t *apdu)
653
0
{
654
0
  if (!sctx)
655
0
    LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS,
656
0
      "Invalid SM context. No SM processing performed.");
657
658
0
  if (sctx->post_transmit)
659
0
    LOG_TEST_RET(card->ctx, sctx->post_transmit(card, sctx, sm_apdu),
660
0
        "Could not complete SM specific post transmit routine");
661
0
  LOG_TEST_RET(card->ctx, sm_decrypt(sctx, card, sm_apdu, apdu),
662
0
      "Could not decrypt APDU");
663
0
  if (sctx->finish)
664
0
    LOG_TEST_RET(card->ctx, sctx->finish(card, sctx, apdu),
665
0
        "Could not complete SM specific post transmit routine");
666
667
0
  return SC_SUCCESS;
668
0
}
669
670
int iso_sm_close(struct sc_card *card)
671
0
{
672
0
  if (card) {
673
0
    iso_sm_ctx_clear_free(card->sm_ctx.info.cmd_data);
674
0
    card->sm_ctx.info.cmd_data = NULL;
675
0
  }
676
677
0
  return SC_SUCCESS;
678
0
}
679
680
int iso_get_sm_apdu(struct sc_card *card, struct sc_apdu *apdu, struct sc_apdu **sm_apdu)
681
0
{
682
0
  return iso_add_sm(card->sm_ctx.info.cmd_data, card, apdu, sm_apdu);
683
0
}
684
685
int iso_free_sm_apdu(struct sc_card *card, struct sc_apdu *apdu, struct sc_apdu **sm_apdu)
686
0
{
687
0
  struct sc_apdu *p;
688
0
  int r;
689
690
0
  if (!sm_apdu)
691
0
    return SC_ERROR_INVALID_ARGUMENTS;
692
693
0
  p = *sm_apdu;
694
695
0
  r = iso_rm_sm(card->sm_ctx.info.cmd_data, card, p, apdu);
696
697
0
  if (p) {
698
0
    free((unsigned char *) p->data);
699
0
    free((unsigned char *) p->resp);
700
0
  }
701
0
  free(*sm_apdu);
702
0
  *sm_apdu = NULL;
703
704
0
  return r;
705
0
}
706
707
struct iso_sm_ctx *iso_sm_ctx_create(void)
708
0
{
709
0
  struct iso_sm_ctx *sctx = malloc(sizeof *sctx);
710
0
  if (!sctx)
711
0
    return NULL;
712
713
0
  sctx->priv_data = NULL;
714
0
  sctx->padding_indicator = SM_ISO_PADDING;
715
0
  sctx->block_length = 0;
716
0
  sctx->authenticate = NULL;
717
0
  sctx->verify_authentication = NULL;
718
0
  sctx->encrypt = NULL;
719
0
  sctx->decrypt = NULL;
720
0
  sctx->pre_transmit = NULL;
721
0
  sctx->post_transmit = NULL;
722
0
  sctx->finish = NULL;
723
0
  sctx->clear_free = NULL;
724
725
0
  return sctx;
726
0
}
727
728
void iso_sm_ctx_clear_free(struct iso_sm_ctx *sctx)
729
0
{
730
0
  if (sctx && sctx->clear_free)
731
0
    sctx->clear_free(sctx);
732
0
  free(sctx);
733
0
}
734
735
int iso_sm_start(struct sc_card *card, struct iso_sm_ctx *sctx)
736
0
{
737
0
  if (!card)
738
0
    return SC_ERROR_INVALID_ARGUMENTS;
739
740
0
  if (card->sm_ctx.ops.close)
741
0
    card->sm_ctx.ops.close(card);
742
743
0
  card->sm_ctx.info.cmd_data = sctx;
744
0
  card->sm_ctx.ops.close = iso_sm_close;
745
0
  card->sm_ctx.ops.free_sm_apdu = iso_free_sm_apdu;
746
0
  card->sm_ctx.ops.get_sm_apdu = iso_get_sm_apdu;
747
0
  card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
748
749
0
  return SC_SUCCESS;
750
0
}
751
752
#else
753
754
int iso_sm_close(struct sc_card *card)
755
{
756
  return SC_ERROR_NOT_SUPPORTED;
757
}
758
759
int iso_get_sm_apdu(struct sc_card *card, struct sc_apdu *apdu, struct sc_apdu **sm_apdu)
760
{
761
  return SC_ERROR_NOT_SUPPORTED;
762
}
763
764
struct iso_sm_ctx *iso_sm_ctx_create(void)
765
{
766
  return NULL;
767
}
768
769
void iso_sm_ctx_clear_free(struct iso_sm_ctx *sctx)
770
{
771
}
772
773
int iso_sm_start(struct sc_card *card, struct iso_sm_ctx *sctx)
774
{
775
  return SC_ERROR_NOT_SUPPORTED;
776
}
777
778
#endif