Coverage Report

Created: 2025-07-18 06:10

/src/opensc/src/libopensc/cwa14890.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * cwa14890.c: Implementation of Secure Messaging according CWA-14890-1 and CWA-14890-2 standards.
3
 *
4
 * Copyright (C) 2010 Juan Antonio Martinez <jonsito@terra.es>
5
 *
6
 * This work is derived from many sources at OpenSC Project site,
7
 * (see references) and the information made public by Spanish
8
 * Direccion General de la Policia y de la Guardia Civil
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
 */
24
25
#define __CWA14890_C__
26
#ifdef HAVE_CONFIG_H
27
#include "config.h"
28
#endif
29
30
#if defined(ENABLE_OPENSSL) && defined(ENABLE_SM) /* empty file without openssl or sm */
31
32
#include <stdlib.h>
33
#include <string.h>
34
#include <ctype.h>
35
36
#include "opensc.h"
37
#include "cardctl.h"
38
#include "internal.h"
39
#include <openssl/rsa.h>
40
#include <openssl/bn.h>
41
#include <openssl/x509.h>
42
#include <openssl/des.h>
43
#include <openssl/rand.h>
44
#include "cwa14890.h"
45
#include "cwa-dnie.h"
46
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
47
# include <openssl/core_names.h>
48
# include <openssl/param_build.h>
49
# include <openssl/provider.h>
50
#endif
51
52
0
#define MAX_RESP_BUFFER_SIZE 2048
53
54
/**
55
 * Structure used to compose BER-TLV encoded data
56
 * according to iso7816-4 sect 5.2.2.
57
 *
58
 * Notice that current implementation does not handle properly
59
 * multibyte tag id. Just assume that tag is 1-byte length
60
 * Also, encodings for data length longer than 0x01000000 bytes
61
 * are not supported (tag 0x84)
62
 */
63
typedef struct cwa_tlv_st {
64
        u8 *buf;                /** local copy of TLV byte array */
65
        size_t buflen;          /** length of buffer */
66
        unsigned int tag;       /** tag ID */
67
        size_t len;             /** length of data field */
68
        u8 *data;               /** pointer to start of data in buf buffer */
69
} cwa_tlv_t;
70
71
/*********************** utility functions ************************/
72
73
/**
74
 * Dump an APDU before SM translation.
75
 *
76
 * This is mainly for debugging purposes. programmer should disable
77
 * this function in a production environment, as APDU will be shown
78
 * in text-plain on debug traces
79
 *
80
 * @param card Pointer to card driver data structure
81
 * @param apdu APDU to be encoded, or APDU response after decoded
82
 * @param flag 0: APDU is to be encoded: 1; APDU decoded response
83
 */
84
static void cwa_trace_apdu(sc_card_t * card, sc_apdu_t * apdu, int flag)
85
0
{
86
0
  char buf[2048];
87
0
  if (!card || !card->ctx || !apdu || card->ctx->debug < SC_LOG_DEBUG_NORMAL)
88
0
    return;
89
0
  if (flag == 0) { /* apdu command */
90
0
    if (apdu->datalen > 0) { /* apdu data to show */
91
0
      sc_hex_dump(apdu->data, apdu->datalen, buf, sizeof(buf));
92
0
      sc_log(card->ctx,
93
0
             "\nAPDU before encode: ==================================================\nCLA: %02X INS: %02X P1: %02X P2: %02X Lc: %02"SC_FORMAT_LEN_SIZE_T"X Le: %02"SC_FORMAT_LEN_SIZE_T"X DATA: [%5"SC_FORMAT_LEN_SIZE_T"u bytes]\n%s======================================================================\n",
94
0
             apdu->cla, apdu->ins, apdu->p1, apdu->p2,
95
0
             apdu->lc, apdu->le, apdu->datalen, buf);
96
0
    } else { /* apdu data field is empty */
97
0
      sc_log(card->ctx,
98
0
             "\nAPDU before encode: ==================================================\nCLA: %02X INS: %02X P1: %02X P2: %02X Lc: %02"SC_FORMAT_LEN_SIZE_T"X Le: %02"SC_FORMAT_LEN_SIZE_T"X (NO DATA)\n======================================================================\n",
99
0
             apdu->cla, apdu->ins, apdu->p1, apdu->p2,
100
0
             apdu->lc, apdu->le);
101
0
    }
102
0
  } else {   /* apdu response */
103
0
    sc_hex_dump(apdu->resp, apdu->resplen, buf, sizeof(buf));
104
0
    sc_log(card->ctx,
105
0
           "\nAPDU response after decode: ==========================================\nSW1: %02X SW2: %02X RESP: [%5"SC_FORMAT_LEN_SIZE_T"u bytes]\n%s======================================================================\n",
106
0
           apdu->sw1, apdu->sw2, apdu->resplen, buf);
107
0
  }
108
0
}
109
110
/**
111
 * Increase send sequence counter SSC.
112
 *
113
 * @param card smart card info structure
114
 * @return SC_SUCCESS if ok; else error code
115
 *
116
 * TODO: to further study: what about using bignum arithmetic?
117
 */
118
static int cwa_increase_ssc(sc_card_t * card)
119
0
{
120
0
  int n;
121
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
122
123
  /* preliminary checks */
124
0
  if (!card || !card->ctx )
125
0
    return SC_ERROR_INVALID_ARGUMENTS;
126
0
  LOG_FUNC_CALLED(card->ctx);
127
  /* u8 arithmetic; exit loop if no carry */
128
0
  sc_log(card->ctx, "Curr SSC: '%s'", sc_dump_hex(sm->ssc, 8));
129
0
  for (n = 7; n >= 0; n--) {
130
0
    sm->ssc[n]++;
131
0
    if ((sm->ssc[n]) != 0x00)
132
0
      break;
133
0
  }
134
0
  sc_log(card->ctx, "Next SSC: '%s'", sc_dump_hex(sm->ssc, 8));
135
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
136
0
}
137
138
/**
139
 * ISO 7816 padding.
140
 *
141
 * Adds an 0x80 at the end of buffer and as many zeroes to get len
142
 * multiple of 8
143
 * Buffer must be long enough to store additional bytes
144
 *
145
 * @param buffer where to compose data
146
 * @param len pointer to buffer length
147
 */
148
static void cwa_iso7816_padding(u8 * buf, size_t * buflen)
149
0
{
150
0
  buf[*buflen] = 0x80;
151
0
  (*buflen)++;
152
0
  for (; *buflen & 0x07; (*buflen)++)
153
0
    buf[*buflen] = 0x00;
154
0
}
155
156
/**
157
 * compose a BER-TLV data in provided buffer.
158
 *
159
 * Multibyte tag id are not supported
160
 * Also multibyte id 0x84 is unhandled
161
 *
162
 * Notice that TLV is composed starting at offset length from
163
 * the buffer. Consecutive calls to cwa_add_tlv, appends a new
164
 * TLV at the end of the buffer
165
 *
166
 * @param card card info structure
167
 * @param tag tag id
168
 * @param len data length
169
 * @param value data buffer
170
 * @param out pointer to dest data
171
 * @param outlen length of composed tlv data
172
 * @return SC_SUCCESS if ok; else error
173
 */
174
static int cwa_compose_tlv(sc_card_t * card,
175
         u8 tag,
176
         size_t len, u8 * data, u8 ** out, size_t * outlen)
177
0
{
178
0
  u8 *pt;
179
0
  size_t size;
180
0
  sc_context_t *ctx;
181
  /* preliminary checks */
182
0
  if (!card || !card->ctx || !out || !outlen)
183
0
    return SC_ERROR_INVALID_ARGUMENTS;
184
  /* commodity vars */
185
0
  ctx = card->ctx;
186
187
0
  LOG_FUNC_CALLED(ctx);
188
0
  pt = *out;
189
0
  size = *outlen;
190
191
  /* assume tag id is not multibyte */
192
0
  *(pt + size++) = tag;
193
  /* evaluate tag length value according iso7816-4 sect 5.2.2 */
194
0
  if (len < 0x80) {
195
0
    *(pt + size++) = len;
196
0
  } else if (len < 0x00000100) {
197
0
    *(pt + size++) = 0x81;
198
0
    *(pt + size++) = 0xff & len;
199
0
  } else if (len < 0x00010000) {
200
0
    *(pt + size++) = 0x82;
201
0
    *(pt + size++) = 0xff & (len >> 8);
202
0
    *(pt + size++) = 0xff & len;
203
0
  } else if (len < 0x01000000) {
204
0
    *(pt + size++) = 0x83;
205
0
    *(pt + size++) = 0xff & (len >> 16);
206
0
    *(pt + size++) = 0xff & (len >> 8);
207
0
    *(pt + size++) = 0xff & len;
208
0
  } else {   /* do not handle tag length 0x84 */
209
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
210
0
  }
211
  /* copy remaining data to buffer */
212
0
  if (len != 0)
213
0
    memcpy(pt + size, data, len);
214
0
  size += len;
215
0
  *outlen = size;
216
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
217
0
}
218
219
/**
220
 * Parse and APDU Response and extract specific BER-TLV data.
221
 *
222
 * NOTICE that iso7816 sect 5.2.2 states that Tag length may be 1 to n bytes
223
 * length. In this code we'll assume always tag length = 1 byte
224
 *
225
 * FIXME use `sc_asn1_read_tag` or similar instead
226
 *
227
 * @param card card info structure
228
 * @param data Buffer to look for tlv into
229
 * @param datalen Buffer len
230
 * @param tlv  array of TLV structure to store results into
231
 * @return SC_SUCCESS if OK; else error code
232
 */
233
static int cwa_parse_tlv(sc_card_t * card,
234
       u8 * buffer, size_t datalen,
235
       cwa_tlv_t tlv_array[]
236
    )
237
0
{
238
0
  size_t n = 0;
239
0
  size_t next = 0;
240
0
  sc_context_t *ctx = NULL;
241
242
  /* preliminary checks */
243
0
  if (!card || !card->ctx)
244
0
    return SC_ERROR_INVALID_ARGUMENTS;
245
  /* commodity vars */
246
0
  ctx = card->ctx;
247
248
0
  LOG_FUNC_CALLED(ctx);
249
0
  if (!tlv_array)
250
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
251
252
0
  for (n = 0; n < datalen; n += next) {
253
0
    cwa_tlv_t *tlv = NULL;  /* pointer to TLV structure to store info */
254
0
    size_t j = 2; /* TLV has at least two bytes */
255
0
    switch (*(buffer + n)) {
256
0
    case CWA_SM_PLAIN_TAG:
257
0
      tlv = &tlv_array[0];
258
0
      break;  /* 0x81 Plain  */
259
0
    case CWA_SM_CRYPTO_TAG:
260
0
      tlv = &tlv_array[1];
261
0
      break;  /* 0x87 Crypto */
262
0
    case CWA_SM_MAC_TAG:
263
0
      tlv = &tlv_array[2];
264
0
      break;  /* 0x8E MAC CC */
265
0
    case CWA_SM_STATUS_TAG:
266
0
      tlv = &tlv_array[3];
267
0
      break;  /* 0x99 Status */
268
0
    default:  /* CWA_SM_LE_TAG (0x97) is not valid here */
269
0
      sc_log(ctx, "Invalid TLV Tag type: '0x%02X'",
270
0
             *(buffer + n));
271
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
272
0
    }
273
0
    tlv->buf = buffer + n;
274
0
    tlv->tag = 0xff & *(buffer + n);
275
0
    tlv->len = 0; /* temporary */
276
    /* evaluate len and start of data */
277
0
    switch (0xff & *(buffer + n + 1)) {
278
0
    case 0x84:
279
0
      tlv->len = (0xff & *(buffer + n + j++));
280
      /* fall through */
281
0
    case 0x83:
282
0
      tlv->len =
283
0
          (tlv->len << 8) + (0xff & *(buffer + n + j++));
284
      /* fall through */
285
0
    case 0x82:
286
0
      tlv->len =
287
0
          (tlv->len << 8) + (0xff & *(buffer + n + j++));
288
      /* fall through */
289
0
    case 0x81:
290
0
      tlv->len =
291
0
          (tlv->len << 8) + (0xff & *(buffer + n + j++));
292
0
      break;
293
      /* case 0x80 is not standard, but official code uses it */
294
0
    case 0x80:
295
0
      tlv->len =
296
0
          (tlv->len << 8) + (0xff & *(buffer + n + j++));
297
0
      break;
298
0
    default:
299
0
      if ((*(buffer + n + 1) & 0xff) < 0x80) {
300
0
        tlv->len = 0xff & *(buffer + n + 1);
301
0
      } else {
302
0
        sc_log(ctx, "Invalid tag length indicator: %d",
303
0
               *(buffer + n + 1));
304
0
        LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_LENGTH);
305
0
      }
306
0
    }
307
0
    tlv->data = buffer + n + j;
308
0
    tlv->buflen = j + tlv->len;
309
0
    sc_log(ctx, "Found Tag: '0x%02X': Length: '%"SC_FORMAT_LEN_SIZE_T"u' Value:\n%s",
310
0
           tlv->tag, tlv->len, sc_dump_hex(tlv->data, tlv->len));
311
    /* set index to next Tag to jump to */
312
0
    next = tlv->buflen;
313
0
  }
314
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);  /* mark no error */
315
0
}
316
317
/*********************** authentication routines *******************/
318
319
/**
320
 * Verify certificates provided by card.
321
 *
322
 * This routine uses Root CA public key data From Annex III of manual
323
 * to verify intermediate CA icc certificate provided by card
324
 * if verify success, then extract public keys from intermediate CA
325
 * and verify icc certificate
326
 *
327
 * @param card pointer to sc_card_contex
328
 * @param sub_ca_cert icc intermediate CA certificate read from card
329
 * @param icc_ca icc certificate from card
330
 * @return SC_SUCCESS if verification is ok; else error code
331
 */
332
static int cwa_verify_icc_certificates(sc_card_t * card,
333
               cwa_provider_t * provider,
334
               X509 * sub_ca_cert, X509 * icc_cert)
335
0
{
336
0
  char *msg = NULL;
337
0
  int res = SC_SUCCESS;
338
0
  EVP_PKEY *root_ca_key = NULL;
339
0
  EVP_PKEY *sub_ca_key = NULL;
340
0
  sc_context_t *ctx = NULL;
341
342
  /* safety check */
343
0
  if (!card || !card->ctx || !provider)
344
0
    return SC_ERROR_INVALID_ARGUMENTS;
345
0
  ctx = card->ctx;
346
0
  LOG_FUNC_CALLED(ctx);
347
0
  if (!sub_ca_cert || !icc_cert) /* check received arguments */
348
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
349
350
  /* retrieve root ca pkey from provider */
351
0
  res = provider->cwa_get_root_ca_pubkey(card, &root_ca_key);
352
0
  if (res != SC_SUCCESS) {
353
0
    msg = "Cannot get root CA public key";
354
0
    res = SC_ERROR_INTERNAL;
355
0
    goto verify_icc_certificates_end;
356
0
  }
357
358
  /* verify sub_ca_cert against root_ca_key */
359
0
  res = X509_verify(sub_ca_cert, root_ca_key);
360
0
  if (!res) {
361
0
    sc_log_openssl(ctx);
362
0
    msg = "Cannot verify icc Sub-CA certificate";
363
0
    res = SC_ERROR_SM_AUTHENTICATION_FAILED;
364
0
    goto verify_icc_certificates_end;
365
0
  }
366
367
  /* extract sub_ca_key from sub_ca_cert */
368
0
  if (!(sub_ca_key = X509_get_pubkey(sub_ca_cert))) {
369
0
    sc_log_openssl(ctx);
370
0
    msg = "Cannot extract public key icc Sub-CA certificate";
371
0
    res = SC_ERROR_INTERNAL;
372
0
    goto verify_icc_certificates_end;
373
0
  }
374
375
  /* verify icc_cert against sub_ca_key */
376
0
  res = X509_verify(icc_cert, sub_ca_key);
377
0
  if (!res) {
378
0
    sc_log_openssl(ctx);
379
0
    msg = "Cannot verify icc certificate";
380
0
    res = SC_ERROR_SM_AUTHENTICATION_FAILED;
381
0
    goto verify_icc_certificates_end;
382
0
  }
383
384
  /* arriving here means certificate verification success */
385
0
  res = SC_SUCCESS;
386
0
 verify_icc_certificates_end:
387
0
  if (root_ca_key)
388
0
    EVP_PKEY_free(root_ca_key);
389
0
  if (sub_ca_key)
390
0
    EVP_PKEY_free(sub_ca_key);
391
0
  if (res != SC_SUCCESS) {
392
0
    sc_log(ctx, "%s", msg);
393
0
  }
394
0
  LOG_FUNC_RETURN(ctx, res);
395
0
}
396
397
/**
398
 * Verify CVC certificates in SM establishment process.
399
 *
400
 * This is done by mean of 00 2A 00 AE
401
 * (Perform Security Operation: Verify Certificate )
402
 *
403
 * @param card pointer to card data
404
 * @param cert Certificate in CVC format
405
 * @param len  length of CVC certificate
406
 * @return SC_SUCCESS if ok; else error code
407
 */
408
static int cwa_verify_cvc_certificate(sc_card_t * card,
409
              const u8 * cert, size_t len)
410
0
{
411
0
  sc_apdu_t apdu;
412
0
  int result = SC_SUCCESS;
413
0
  sc_context_t *ctx = NULL;
414
415
  /* safety check */
416
0
  if (!card || !card->ctx)
417
0
    return SC_ERROR_INVALID_ARGUMENTS;
418
0
  ctx = card->ctx;
419
0
  LOG_FUNC_CALLED(ctx);
420
0
  if (!cert || (len <= 0)) /* check received arguments */
421
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
422
423
  /* compose apdu for Perform Security Operation (Verify cert) cmd */
424
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x00, 0xAE, 0, len,
425
0
          NULL, 0, cert, len);
426
427
  /* send composed apdu and parse result */
428
0
  result = sc_transmit_apdu(card, &apdu);
429
0
  LOG_TEST_RET(ctx, result, "Verify CVC certificate failed");
430
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
431
0
  LOG_FUNC_RETURN(ctx, result);
432
0
}
433
434
/**
435
 * Alternate implementation for set_security environment.
436
 *
437
 * Used to handle raw apdu data in set_security_env() on SM establishment
438
 * Standard set_security_env() method has sc_security_env->buffer limited
439
 * to 8 bytes; so cannot send some of required SM commands.
440
 *
441
 * @param card pointer to card data
442
 * @param p1 apdu P1 parameter
443
 * @param p2 apdu P2 parameter
444
 * @param buffer raw data to be inserted in apdu
445
 * @param length size of buffer
446
 * @return SC_SUCCESS if ok; else error code
447
 */
448
static int cwa_set_security_env(sc_card_t * card,
449
        u8 p1, u8 p2, u8 * buffer, size_t length)
450
0
{
451
0
  sc_apdu_t apdu;
452
0
  int result = SC_SUCCESS;
453
0
  sc_context_t *ctx = NULL;
454
455
  /* safety check */
456
0
  if (!card || !card->ctx)
457
0
    return SC_ERROR_INVALID_ARGUMENTS;
458
0
  ctx = card->ctx;
459
0
  LOG_FUNC_CALLED(ctx);
460
0
  if (!buffer || (length <= 0)) /* check received arguments */
461
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
462
463
  /* compose apdu for Manage Security Environment cmd */
464
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, p1, p2, 0, length,
465
0
          NULL, 0, buffer, length);
466
467
  /* send composed apdu and parse result */
468
0
  result = sc_transmit_apdu(card, &apdu);
469
0
  LOG_TEST_RET(ctx, result, "SM Set Security Environment failed");
470
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
471
0
  LOG_FUNC_RETURN(ctx, result);
472
0
}
473
474
/**
475
 * SM internal authenticate.
476
 *
477
 * Internal (Card) authentication (let the card verify sent ifd certs)
478
 *
479
 * @param card pointer to card data
480
 * @param sig signature buffer
481
 * @param dig_len signature buffer length
482
 * @param data data to be sent in apdu
483
 * @param datalen length of data to send
484
 * @return SC_SUCCESS if OK: else error code
485
 */
486
static int cwa_internal_auth(sc_card_t * card, u8 * sig, size_t sig_len, u8 * data, size_t datalen)
487
0
{
488
0
  sc_apdu_t apdu;
489
0
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
490
0
  int result = SC_SUCCESS;
491
0
  sc_context_t *ctx = NULL;
492
493
  /* safety check */
494
0
  if (!card || !card->ctx)
495
0
    return SC_ERROR_INVALID_ARGUMENTS;
496
0
  ctx = card->ctx;
497
0
  LOG_FUNC_CALLED(ctx);
498
0
  if (!data || (datalen <= 0)) /* check received arguments */
499
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
500
501
  /* compose apdu for Internal Authenticate cmd */
502
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0x00, 0x00, 0x80, datalen,
503
0
          rbuf, sizeof(rbuf), data, datalen);
504
505
  /* send composed apdu and parse result */
506
0
  result = sc_transmit_apdu(card, &apdu);
507
0
  LOG_TEST_RET(ctx, result, "SM internal auth failed");
508
509
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
510
0
  LOG_TEST_RET(ctx, result, "SM internal auth invalid response");
511
512
0
  if (apdu.resplen != sig_len) /* invalid number of bytes received */
513
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
514
0
  memcpy(sig, apdu.resp, apdu.resplen); /* copy result to buffer */
515
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
516
0
}
517
518
/**
519
 * Compose signature data for external auth according CWA-14890.
520
 *
521
 * This code prepares data to be sent to ICC for external
522
 * authentication procedure
523
 *
524
 * Store resulting data  into sm->sig
525
 *
526
 * @param card pointer to st_card_t card data information
527
 * @param icc_pubkey public key of card
528
 * @param ifd_privkey private key of ifd
529
 * @param sn_icc card serial number
530
 * @param sig signature buffer
531
 * @param sig_len signature buffer length
532
 * @return SC_SUCCESS if ok; else errorcode
533
 */
534
static int cwa_prepare_external_auth(sc_card_t * card,
535
             EVP_PKEY *icc_pubkey,
536
             EVP_PKEY *ifd_privkey,
537
             u8 * sig,
538
             size_t sig_len)
539
0
{
540
  /* we have to compose following message:
541
     data = E[PK.ICC.AUT](SIGMIN)
542
     SIGMIN = min ( SIG, N.IFD-SIG )
543
     SIG= DS[SK.IFD.AUT] (
544
     0x6A  || - padding according iso 9796-2
545
     PRND2 || - (74 bytes) random data to make buffer 128 bytes length
546
     Kifd  || - (32 bytes)- ifd random generated key
547
     sha1_hash(
548
     PRND2   ||
549
     Kifd    ||
550
     RND.ICC || - (8 bytes) response to get_challenge() cmd
551
     SN.ICC  - (8 bytes) serial number from get_serialnr() cmd
552
     ) ||
553
     0xBC - iso 9796-2 padding
554
     ) - total: 128 bytes
555
556
     then, we should encrypt with our private key and then with icc pub key
557
     returning resulting data
558
   */
559
0
  char *msg = NULL;   /* to store error messages */
560
0
  int res = SC_SUCCESS;
561
0
  u8 *buf1 = NULL;    /* where to encrypt with icc pub key */
562
0
  u8 *buf2 = NULL;    /* where to encrypt with ifd pub key */
563
0
  u8 *buf3 = NULL;    /* where to compose message to be encrypted */
564
0
  size_t len1 = 128, len2 = 128, len3 = 128;
565
0
  u8 *sha_buf = NULL;   /* to compose message to be sha'd */
566
0
  u8 *sha_data = NULL;    /* sha signature data */
567
0
  BIGNUM *bn = NULL;
568
0
  BIGNUM *bnsub = NULL;
569
0
  BIGNUM *bnres = NULL;
570
0
  sc_context_t *ctx = NULL;
571
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
572
0
  EVP_PKEY_CTX *pctx = NULL;
573
574
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
575
0
  const BIGNUM *ifd_privkey_n = NULL;
576
0
  const RSA *rsa_ifd_privkey = EVP_PKEY_get0_RSA(ifd_privkey);
577
0
  if (!rsa_ifd_privkey) {
578
0
    res = SC_ERROR_INTERNAL;
579
0
    msg = "Can not extract RSA object ifd priv";
580
0
    goto prepare_external_auth_end;
581
0
  }
582
#else
583
  BIGNUM *ifd_privkey_n = NULL;
584
#endif
585
586
  /* safety check */
587
0
  if (!card || !card->ctx)
588
0
    return SC_ERROR_INVALID_ARGUMENTS;
589
0
  ctx = card->ctx;
590
0
  LOG_FUNC_CALLED(ctx);
591
  /* check received arguments */
592
0
  if (!icc_pubkey || !ifd_privkey || !sm)
593
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
594
0
  buf1 = calloc(128, sizeof(u8));
595
0
  buf2 = calloc(128, sizeof(u8));
596
0
  buf3 = calloc(128, sizeof(u8));
597
0
  sha_buf = calloc(74 + 32 + 8 + 8, sizeof(u8));
598
0
  sha_data = calloc(SHA_DIGEST_LENGTH, sizeof(u8));
599
  /* alloc() resources */
600
0
  if (!buf1 || !buf2 || !buf3 || !sha_buf || !sha_data) {
601
0
    msg = "prepare external auth: calloc error";
602
0
    res = SC_ERROR_OUT_OF_MEMORY;
603
0
    goto prepare_external_auth_end;
604
0
  }
605
606
  /* compose buffer data */
607
0
  buf3[0] = 0x6A;   /* iso padding */
608
0
  if (RAND_bytes(buf3 + 1, 74) != 1 ||     /* pRND */
609
0
      RAND_bytes(sm->ifd.k, 32) != 1) { /* Kifd */
610
0
    sc_log_openssl(ctx);
611
0
    msg = "prepare external auth: random data error";
612
0
    res = SC_ERROR_INTERNAL;
613
0
    goto prepare_external_auth_end;
614
0
  }
615
0
  memcpy(buf3 + 1 + 74, sm->ifd.k, 32); /* copy Kifd into buffer */
616
  /* prepare data to be hashed */
617
0
  memcpy(sha_buf, buf3 + 1, 74);  /* copy pRND into sha_buf */
618
0
  memcpy(sha_buf + 74, buf3 + 1 + 74, 32);  /* copy kifd into sha_buf */
619
0
  memcpy(sha_buf + 74 + 32, sm->icc.rnd, 8);  /* copy 8 byte icc challenge */
620
0
  memcpy(sha_buf + 74 + 32 + 8, sm->icc.sn, 8); /* copy serialnr, 8 bytes */
621
0
  SHA1(sha_buf, 74 + 32 + 8 + 8, sha_data);
622
  /* copy hashed data into buffer */
623
0
  memcpy(buf3 + 1 + 74 + 32, sha_data, SHA_DIGEST_LENGTH);
624
0
  buf3[127] = 0xBC; /* iso padding */
625
626
  /* decrypt with ifd private key */
627
0
  pctx = EVP_PKEY_CTX_new(ifd_privkey, NULL);
628
0
  if (!pctx ||
629
0
      EVP_PKEY_decrypt_init(pctx) != 1 ||
630
0
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 ||
631
0
    EVP_PKEY_decrypt(pctx, buf2, &len2, buf3, 128) != 1) {
632
0
    sc_log_openssl(ctx);
633
0
    msg = "Prepare external auth: ifd_privk decrypt failed";
634
0
    res = SC_ERROR_SM_ENCRYPT_FAILED;
635
0
    EVP_PKEY_CTX_free(pctx);
636
0
    goto prepare_external_auth_end;
637
0
  }
638
0
  EVP_PKEY_CTX_free(pctx);
639
0
  pctx = NULL;
640
641
  /* evaluate value of minsig and store into buf3 */
642
0
  bn = BN_bin2bn(buf2, (int)len2, NULL);
643
0
  bnsub = BN_new();
644
0
  if (!bn || !bnsub) {
645
0
    sc_log_openssl(ctx);
646
0
    msg = "Prepare external auth: BN creation failed";
647
0
    res = SC_ERROR_INTERNAL;
648
0
    goto prepare_external_auth_end;
649
0
  }
650
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
651
0
  RSA_get0_key(rsa_ifd_privkey, &ifd_privkey_n, NULL, NULL);
652
#else
653
  if (EVP_PKEY_get_bn_param(ifd_privkey, OSSL_PKEY_PARAM_RSA_N, &ifd_privkey_n) != 1) {
654
    sc_log_openssl(ctx);
655
    msg = "Prepare external auth: BN get param failed";
656
    res = SC_ERROR_INTERNAL;
657
    goto prepare_external_auth_end;
658
  }
659
#endif
660
661
0
  res = BN_sub(bnsub, ifd_privkey_n, bn); /* eval N.IFD-SIG */
662
0
  if (res == 0) {   /* 1:success 0 fail */
663
0
    sc_log_openssl(ctx);
664
0
    msg = "Prepare external auth: BN sigmin evaluation failed";
665
0
    res = SC_ERROR_INTERNAL;
666
0
    goto prepare_external_auth_end;
667
0
  }
668
0
  bnres = (BN_cmp(bn, bnsub) < 0) ? bn : bnsub; /* choose min(SIG,N.IFD-SIG) */
669
0
  if (BN_num_bytes(bnres) > 128) {
670
0
    sc_log_openssl(ctx);
671
0
    msg = "Prepare external auth: BN sigmin result is too big";
672
0
    res = SC_ERROR_INTERNAL;
673
0
    goto prepare_external_auth_end;
674
0
  }
675
0
  len3 = BN_bn2bin(bnres, buf3);  /* convert result back into buf3 */
676
0
  if (len3 <= 0) {
677
0
    sc_log_openssl(ctx);
678
0
    msg = "Prepare external auth: BN to buffer conversion failed";
679
0
    res = SC_ERROR_INTERNAL;
680
0
    goto prepare_external_auth_end;
681
0
  }
682
683
  /* re-encrypt result with icc public key */
684
0
  pctx = EVP_PKEY_CTX_new(icc_pubkey, NULL);
685
0
  if (!pctx ||
686
0
      EVP_PKEY_encrypt_init(pctx) != 1 ||
687
0
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 ||
688
0
      EVP_PKEY_encrypt(pctx, buf1, &len1, buf3, 128) != 1 ||
689
0
      (size_t)len1 != sig_len) {
690
0
    sc_log_openssl(ctx);
691
0
    msg = "Prepare external auth: icc_pubk encrypt failed";
692
0
    res = SC_ERROR_SM_ENCRYPT_FAILED;
693
0
    EVP_PKEY_CTX_free(pctx);
694
0
    goto prepare_external_auth_end;
695
0
  }
696
0
  EVP_PKEY_CTX_free(pctx);
697
698
  /* process done: copy result into cwa_internal buffer and return success */
699
0
  memcpy(sig, buf1, len1);
700
0
  res = SC_SUCCESS;
701
702
0
 prepare_external_auth_end:
703
0
  BN_free(bn);
704
0
  BN_free(bnsub);
705
0
  if (buf1) {
706
0
    sc_mem_clear(buf1, 128);
707
0
    free(buf1);
708
0
  }
709
0
  if (buf2) {
710
0
    sc_mem_clear(buf2, 128);
711
0
    free(buf2);
712
0
  }
713
0
  if (buf3) {
714
0
    sc_mem_clear(buf3, 128);
715
0
    free(buf3);
716
0
  }
717
0
  if (sha_buf) {
718
0
    sc_mem_clear(sha_buf, 74 + 32 + 8 + 1 + 7);
719
0
    free(sha_buf);
720
0
  }
721
0
  free(sha_data);
722
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
723
  BN_clear_free(ifd_privkey_n);
724
#endif
725
726
0
  if (res != SC_SUCCESS) {
727
0
    sc_log(ctx, "%s", msg);
728
0
  }
729
0
  LOG_FUNC_RETURN(ctx, res);
730
0
}
731
732
/**
733
 * SM external authenticate.
734
 *
735
 * Perform external (IFD) authenticate procedure (8.4.1.2)
736
 *
737
 * @param card pointer to card data
738
 * @param sig signature buffer
739
 * @param sig signature buffer length
740
 * @return SC_SUCCESS if OK: else error code
741
 */
742
static int cwa_external_auth(sc_card_t * card, u8 * sig, size_t sig_len)
743
0
{
744
0
  sc_apdu_t apdu;
745
0
  int result = SC_SUCCESS;
746
0
  sc_context_t *ctx = NULL;
747
748
  /* safety check */
749
0
  if (!card || !card->ctx)
750
0
    return SC_ERROR_INVALID_ARGUMENTS;
751
0
  ctx = card->ctx;
752
0
  LOG_FUNC_CALLED(ctx);
753
754
  /* compose apdu for External Authenticate cmd */
755
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x00, 0x00, 0, sig_len,
756
0
          NULL, 0, sig, sig_len);
757
758
  /* send composed apdu and parse result */
759
0
  result = sc_transmit_apdu(card, &apdu);
760
0
  LOG_TEST_RET(ctx, result, "SM external auth failed");
761
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
762
0
  LOG_TEST_RET(ctx, result, "SM external auth invalid response");
763
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
764
0
}
765
766
/**
767
 * SM creation of session keys.
768
 *
769
 * Compute Kenc,Kmac, and SSC  and store it into sm data
770
 *
771
 * @param card pointer to sc_card_t data
772
 * @return SC_SUCCESS if ok; else error code
773
 */
774
static int cwa_compute_session_keys(sc_card_t * card)
775
0
{
776
777
0
  char *msg = NULL;
778
0
  int n = 0;
779
0
  int res = SC_SUCCESS;
780
0
  u8 *kseed;    /* to compose kifd ^ kicc */
781
0
  u8 *data;   /* to compose kenc and kmac to be hashed */
782
0
  u8 *sha_data;   /* to store hash result */
783
0
  u8 kenc[4] = { 0x00, 0x00, 0x00, 0x01 };
784
0
  u8 kmac[4] = { 0x00, 0x00, 0x00, 0x02 };
785
0
  sc_context_t *ctx = NULL;
786
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
787
788
  /* safety check */
789
0
  if (!card || !card->ctx)
790
0
    return SC_ERROR_INVALID_ARGUMENTS;
791
0
  ctx = card->ctx;
792
0
  LOG_FUNC_CALLED(ctx);
793
  /* Just a literal transcription of cwa14890-1 sections 8.7.2 to 8.9 */
794
0
  kseed = calloc(32, sizeof(u8));
795
0
  data = calloc(32 + 4, sizeof(u8));
796
0
  sha_data = calloc(SHA_DIGEST_LENGTH, sizeof(u8));
797
0
  if (!kseed || !data || !sha_data) {
798
0
    msg = "Compute Session Keys: calloc() failed";
799
0
    res = SC_ERROR_OUT_OF_MEMORY;
800
0
    goto compute_session_keys_end;
801
0
  }
802
  /* compose kseed  (cwa-14890-1 sect 8.7.2) */
803
0
  for (n = 0; n < 32; n++)
804
0
    *(kseed + n) = sm->icc.k[n] ^ sm->ifd.k[n];
805
806
  /* evaluate kenc (cwa-14890-1 sect 8.8) */
807
0
  memcpy(data, kseed, 32);
808
0
  memcpy(data + 32, kenc, 4);
809
0
  SHA1(data, 32 + 4, sha_data);
810
0
  memcpy(sm->session_enc, sha_data, 16);  /* kenc=16 fsb sha((kifd^kicc)||00000001) */
811
812
  /* evaluate kmac */
813
0
  memset(data, 0, 32 + 4);
814
0
  memset(sha_data, 0, SHA_DIGEST_LENGTH); /* clear buffers */
815
816
0
  memcpy(data, kseed, 32);
817
0
  memcpy(data + 32, kmac, 4);
818
0
  SHA1(data, 32 + 4, sha_data);
819
0
  memcpy(sm->session_mac, sha_data, 16);  /* kmac=16 fsb sha((kifd^kicc)||00000002) */
820
821
  /* evaluate send sequence counter  (cwa-14890-1 sect 8.9 & 9.6 */
822
0
  memcpy(sm->ssc, sm->icc.rnd + 4, 4);  /* 4 least significant bytes of rndicc */
823
0
  memcpy(sm->ssc + 4, sm->ifd.rnd + 4, 4);  /* 4 least significant bytes of rndifd */
824
825
  /* arriving here means process ok */
826
0
  res = SC_SUCCESS;
827
828
0
 compute_session_keys_end:
829
0
  if (kseed) {
830
0
    sc_mem_clear(kseed, 32);
831
0
    free(kseed);
832
0
  }
833
0
  if (data) {
834
0
    sc_mem_clear(data, 32 + 4);
835
0
    free(data);
836
0
  }
837
0
  free(sha_data);
838
0
  if (res != SC_SUCCESS)
839
0
    sc_log(ctx, "%s", msg);
840
0
  else {
841
0
    sc_log(ctx, "Kenc: %s", sc_dump_hex(sm->session_enc, 16));
842
0
    sc_log(ctx, "Kmac: %s", sc_dump_hex(sm->session_mac, 16));
843
0
    sc_log(ctx, "SSC:  %s", sc_dump_hex(sm->ssc, 8));
844
0
  }
845
0
  LOG_FUNC_RETURN(ctx, res);
846
0
}
847
848
/*
849
 * Compare signature for internal auth procedure.
850
 *
851
 * @param data Received data to be checked
852
 * @param dlen data length
853
 * @param expected results
854
 * @return SC_SUCCESS or error code
855
 */
856
static int cwa_compare_signature(u8 * data, size_t dlen, u8 * ifd_data)
857
0
{
858
0
  u8 *buf = calloc(74 + 32 + 32, sizeof(u8));
859
0
  u8 *sha = calloc(SHA_DIGEST_LENGTH, sizeof(u8));
860
0
  int res = SC_SUCCESS;
861
0
  if (!buf || !sha) {
862
0
    res = SC_ERROR_OUT_OF_MEMORY;
863
0
    goto compare_signature_end;
864
0
  }
865
0
  res = SC_ERROR_INVALID_DATA;
866
0
  if (dlen != 128)
867
0
    goto compare_signature_end; /* check length */
868
0
  if (data[0] != 0x6a)
869
0
    goto compare_signature_end; /* iso 9796-2 padding */
870
0
  if (data[127] != 0xBC)
871
0
    goto compare_signature_end; /* iso 9796-2 padding */
872
0
  memcpy(buf, data + 1, 74 + 32);
873
0
  memcpy(buf + 74 + 32, ifd_data, 16);
874
0
  SHA1(buf, 74 + 32 + 16, sha);
875
0
  if (memcmp(data + 127 - SHA_DIGEST_LENGTH, sha, SHA_DIGEST_LENGTH) == 0)
876
0
    res = SC_SUCCESS;
877
0
 compare_signature_end:
878
0
  free(buf);
879
0
  free(sha);
880
0
  return res;
881
0
}
882
883
/**
884
 * check the result of internal_authenticate operation.
885
 *
886
 * Checks icc received data from internal auth procedure against
887
 * expected results
888
 *
889
 * @param card Pointer to sc_card_t data
890
 * @param icc_pubkey icc public key
891
 * @param ifd_privkey ifd private key
892
 * @param ifdbuf buffer containing ( RND.IFD || SN.IFD )
893
 * @param ifdlen buffer length; should be 16
894
 * @param sig signature buffer
895
 * @param sig_len signature buffer length
896
 * @return SC_SUCCESS if ok; else error code
897
 */
898
static int cwa_verify_internal_auth(sc_card_t * card,
899
            EVP_PKEY *icc_pubkey,
900
            EVP_PKEY *ifd_privkey,
901
            u8 * ifdbuf,
902
            size_t ifdlen,
903
            u8 * sig,
904
            size_t sig_len)
905
0
{
906
0
  int res = SC_SUCCESS;
907
0
  char *msg = NULL;
908
0
  u8 *buf1 = NULL;  /* to decrypt with our private key */
909
0
  u8 *buf2 = NULL;  /* to try SIGNUM==SIG */
910
0
  u8 *buf3 = NULL;  /* to try SIGNUM==N.ICC-SIG */
911
0
  size_t len1 = 128, len2 = 128, len3 = 128;
912
0
  BIGNUM *bn = NULL;
913
0
  BIGNUM *sigbn = NULL;
914
0
  sc_context_t *ctx = NULL;
915
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
916
0
  EVP_PKEY_CTX *pctx = NULL;
917
918
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
919
0
  const BIGNUM *icc_pubkey_n = NULL;
920
0
  const RSA *rsa_icc_pubkey = EVP_PKEY_get0_RSA(icc_pubkey);
921
0
  if (!rsa_icc_pubkey) {
922
0
    res = SC_ERROR_INTERNAL;
923
0
    msg = "Can not extract RSA object icc pub";
924
0
    goto verify_internal_done;
925
0
  }
926
#else
927
  BIGNUM *icc_pubkey_n = NULL;
928
#endif
929
930
0
  if (!card || !card->ctx)
931
0
    return SC_ERROR_INVALID_ARGUMENTS;
932
0
  ctx = card->ctx;
933
0
  LOG_FUNC_CALLED(ctx);
934
0
  if (!ifdbuf || (ifdlen != 16)) {
935
0
    res = SC_ERROR_INVALID_ARGUMENTS;
936
0
    msg = "Null buffers received as parameters";
937
0
    goto verify_internal_done;
938
0
  }
939
0
  if (!icc_pubkey || !ifd_privkey) {
940
0
    res = SC_ERROR_SM_NO_SESSION_KEYS;
941
0
    msg = "Either provided icc_pubk or ifd_privk are null";
942
0
    goto verify_internal_done;
943
0
  }
944
0
  buf1 = (u8 *) calloc(128, sizeof(u8));  /* 128: RSA key len in bytes */
945
0
  buf2 = (u8 *) calloc(128, sizeof(u8));
946
0
  buf3 = (u8 *) calloc(128, sizeof(u8));
947
0
  if (!buf1 || !buf2 || !buf3) {
948
0
    msg = "Verify Signature: calloc() error";
949
0
    res = SC_ERROR_OUT_OF_MEMORY;
950
0
    goto verify_internal_done;
951
0
  }
952
953
  /*
954
     We have received data with this format:
955
     sigbuf = E[PK.IFD.AUT](SIGMIN)
956
     SIGMIN = min ( SIG, N.ICC-SIG )
957
     SIG= DS[SK.ICC.AUT] (
958
     0x6A  ||
959
     PRND1 ||
960
     Kicc  ||
961
     sha1_hash(PRND1 || Kicc || RND.IFD || SN.IFD) ||
962
     0xBC
963
     )
964
     So we should reverse the process and try to get valid results
965
   */
966
967
  /* decrypt data with our ifd priv key */
968
0
  pctx = EVP_PKEY_CTX_new(ifd_privkey, NULL);
969
0
  if (!pctx ||
970
0
      EVP_PKEY_decrypt_init(pctx) != 1 ||
971
0
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 ||
972
0
      EVP_PKEY_decrypt(pctx, buf1, &len1, sig, sig_len) != 1) {
973
0
    sc_log_openssl(ctx);
974
0
    msg = "Verify Signature: decrypt with ifd privk failed";
975
0
    res = SC_ERROR_SM_ENCRYPT_FAILED;
976
0
    EVP_PKEY_CTX_free(pctx);
977
0
    goto verify_internal_done;
978
0
  }
979
0
  EVP_PKEY_CTX_free(pctx);
980
0
  pctx = NULL;
981
982
  /* OK: now we have SIGMIN in buf1 */
983
  /* check if SIGMIN data matches SIG or N.ICC-SIG */
984
  /* evaluate DS[SK.ICC.AUTH](SIG) trying to decrypt with icc pubk */
985
0
  pctx = EVP_PKEY_CTX_new(icc_pubkey, NULL);
986
0
  if (!pctx ||
987
0
      EVP_PKEY_encrypt_init(pctx) != 1 ||
988
0
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 ||
989
0
      EVP_PKEY_encrypt(pctx, buf3, &len3, buf1, len1) != 1) {
990
0
    EVP_PKEY_CTX_free(pctx);
991
0
    sc_log_openssl(ctx);
992
0
    goto verify_nicc_sig; /* evaluate N.ICC-SIG and retry */
993
0
  }
994
995
0
  EVP_PKEY_CTX_free(pctx);
996
997
0
  res = cwa_compare_signature(buf3, len3, ifdbuf);
998
0
  if (res == SC_SUCCESS)
999
0
    goto verify_internal_ok;
1000
1001
0
 verify_nicc_sig:
1002
  /*
1003
   * Arriving here means need to evaluate N.ICC-SIG
1004
   * So convert buffers to bignums to operate
1005
   */
1006
0
  bn = BN_bin2bn(buf1, (int)len1, NULL);  /* create BN data */
1007
0
  sigbn = BN_new();
1008
0
  if (!bn || !sigbn) {
1009
0
    sc_log_openssl(ctx);
1010
0
    msg = "Verify Signature: cannot bignums creation error";
1011
0
    res = SC_ERROR_OUT_OF_MEMORY;
1012
0
    goto verify_internal_done;
1013
0
  }
1014
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
1015
0
  RSA_get0_key(rsa_icc_pubkey, &icc_pubkey_n, NULL, NULL);
1016
#else
1017
  if (EVP_PKEY_get_bn_param(icc_pubkey, OSSL_PKEY_PARAM_RSA_N, &icc_pubkey_n) != 1) {
1018
    sc_log_openssl(ctx);
1019
    msg = "Verify Signature: BN get param failed";
1020
    res = SC_ERROR_INTERNAL;
1021
    goto verify_internal_done;
1022
  }
1023
#endif
1024
0
  res = BN_sub(sigbn, icc_pubkey_n, bn);  /* eval N.ICC-SIG */
1025
0
  if (!res) {
1026
0
    sc_log_openssl(ctx);
1027
0
    msg = "Verify Signature: evaluation of N.ICC-SIG failed";
1028
0
    res = SC_ERROR_INTERNAL;
1029
0
    goto verify_internal_done;
1030
0
  }
1031
0
  len2 = BN_bn2bin(sigbn, buf2);  /* copy result to buffer */
1032
0
  if (len2 <= 0) {
1033
0
    sc_log_openssl(ctx);
1034
0
    msg = "Verify Signature: cannot convert bignum to buffer";
1035
0
    res = SC_ERROR_INTERNAL;
1036
0
    goto verify_internal_done;
1037
0
  }
1038
  /* ok: check again with new data */
1039
  /* evaluate DS[SK.ICC.AUTH](I.ICC-SIG) trying to decrypt with icc pubk */
1040
0
  pctx = EVP_PKEY_CTX_new(icc_pubkey, NULL);
1041
0
  if (!pctx ||
1042
0
    EVP_PKEY_encrypt_init(pctx) != 1 ||
1043
0
    EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 ||
1044
0
    EVP_PKEY_encrypt(pctx, buf3, &len3, buf2, len2) != 1) {
1045
0
    sc_log_openssl(ctx);
1046
0
    msg = "Verify Signature: cannot get valid SIG data";
1047
0
    res = SC_ERROR_INVALID_DATA;
1048
0
    EVP_PKEY_CTX_free(pctx);
1049
0
    goto verify_internal_done;
1050
0
  }
1051
0
  EVP_PKEY_CTX_free(pctx);
1052
0
  pctx = NULL;
1053
1054
0
  res = cwa_compare_signature(buf3, len3, ifdbuf);
1055
0
  if (res != SC_SUCCESS) {
1056
0
    msg = "Verify Signature: cannot get valid SIG data";
1057
0
    res = SC_ERROR_INVALID_DATA;
1058
0
    goto verify_internal_done;
1059
0
  }
1060
  /* arriving here means OK: complete data structures */
1061
0
 verify_internal_ok:
1062
0
  memcpy(sm->icc.k, buf3 + 1 + 74, 32); /* extract Kicc from buf3 */
1063
0
  res = SC_SUCCESS;
1064
0
 verify_internal_done:
1065
0
  free(buf1);
1066
0
  free(buf2);
1067
0
  free(buf3);
1068
0
  BN_free(bn);
1069
0
  BN_free(sigbn);
1070
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1071
  BN_clear_free(icc_pubkey_n);
1072
#endif
1073
0
  if (res != SC_SUCCESS) {
1074
0
    sc_log(ctx, "%s", msg);
1075
0
  }
1076
0
  LOG_FUNC_RETURN(ctx, res);
1077
0
}
1078
1079
/**
1080
 * Create Secure Messaging channel.
1081
 *
1082
 * This is the main entry point for CWA14890 SM channel creation.
1083
 * It closely follows cwa standard, with a minor modification:
1084
 * - ICC serial number is taken at the beginning of SM creation
1085
 * - ICC and IFD certificate agreement process is reversed, to allow
1086
 * card to retain key references on further process (this behavior
1087
 * is also defined in standard)
1088
 *
1089
 * Based on Several documents:
1090
 * - "Understanding the DNIe"
1091
 * - "Manual de comandos del DNIe"
1092
 * - ISO7816-4 and CWA14890-{1,2}
1093
 *
1094
 * @param card card info structure
1095
 * @param provider cwa14890 info provider
1096
 * @param flag requested init method ( OFF, COLD, WARM )
1097
 * @return SC_SUCCESS if OK; else error code
1098
 */
1099
int cwa_create_secure_channel(sc_card_t * card,
1100
            cwa_provider_t * provider, int flag)
1101
0
{
1102
0
  u8 *cert = NULL;
1103
0
  size_t certlen;
1104
1105
0
  int res = SC_SUCCESS;
1106
0
  char *msg = "Success";
1107
1108
  /* data to get and parse certificates */
1109
0
  X509 *icc_cert = NULL;
1110
0
  X509 *ca_cert = NULL;
1111
0
  EVP_PKEY *icc_pubkey = NULL;
1112
0
  EVP_PKEY *ifd_privkey = NULL;
1113
0
  sc_context_t *ctx = NULL;
1114
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
1115
0
  u8 sig[128];
1116
1117
  /* several buffer and buffer pointers */
1118
0
  u8 *buffer = NULL;
1119
0
  size_t bufferlen;
1120
0
  u8 *tlv = NULL;   /* buffer to compose TLV messages */
1121
0
  size_t tlvlen = 0;
1122
0
  u8 rndbuf[16]; /* 8 RND.IFD + 8 SN.IFD */
1123
1124
  /* preliminary checks */
1125
0
  if (!card || !card->ctx )
1126
0
    return SC_ERROR_INVALID_ARGUMENTS;
1127
0
  if (!provider)
1128
0
    return SC_ERROR_SM_NOT_INITIALIZED;
1129
  /* commodity vars */
1130
0
  ctx = card->ctx;
1131
1132
0
  LOG_FUNC_CALLED(ctx);
1133
1134
  /* check requested initialization method */
1135
0
  switch (flag) {
1136
0
  case CWA_SM_OFF: /* disable SM */
1137
0
    card->sm_ctx.sm_mode = SM_MODE_NONE;
1138
0
    sc_log(ctx, "Setting CWA SM status to none");
1139
0
    LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1140
0
  case CWA_SM_ON: /* force sm initialization process */
1141
0
    sc_log(ctx, "CWA SM initialization requested");
1142
0
    break;
1143
0
  default:
1144
0
    sc_log(ctx, "Invalid provided SM initialization flag");
1145
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1146
0
  }
1147
1148
  /* OK: lets start process */
1149
1150
  /* call provider pre-operation method */
1151
0
  sc_log(ctx, "CreateSecureChannel pre-operations");
1152
0
  if (provider->cwa_create_pre_ops) {
1153
0
    res = provider->cwa_create_pre_ops(card, provider);
1154
0
    if (res != SC_SUCCESS) {
1155
0
      msg = "Create SM: provider pre_ops() failed";
1156
0
      sc_log(ctx, "%s", msg);
1157
0
      goto csc_end;
1158
0
    }
1159
0
  }
1160
1161
  /* retrieve icc serial number */
1162
0
  sc_log(ctx, "Retrieve ICC serial number");
1163
0
  if (provider->cwa_get_sn_icc) {
1164
0
    res = provider->cwa_get_sn_icc(card);
1165
0
    if (res != SC_SUCCESS) {
1166
0
      msg = "Retrieve ICC failed";
1167
0
      sc_log(ctx, "%s", msg);
1168
0
      goto csc_end;
1169
0
    }
1170
0
  } else {
1171
0
    msg = "Don't know how to obtain ICC serial number";
1172
0
    sc_log(ctx, "%s", msg);
1173
0
    res = SC_ERROR_INTERNAL;
1174
0
    goto csc_end;
1175
0
  }
1176
1177
  /*
1178
   * Notice that this code inverts ICC and IFD certificate standard
1179
   * checking sequence.
1180
   */
1181
1182
  /* Read Intermediate CA from card */
1183
0
  if (!provider->cwa_get_icc_intermediate_ca_cert) {
1184
0
    sc_log(ctx,
1185
0
           "Step 8.4.1.6: Skip Retrieving ICC intermediate CA");
1186
0
    ca_cert = NULL;
1187
0
  } else {
1188
0
    sc_log(ctx, "Step 8.4.1.7: Retrieving ICC intermediate CA");
1189
0
    res =
1190
0
        provider->cwa_get_icc_intermediate_ca_cert(card, &ca_cert);
1191
0
    if (res != SC_SUCCESS) {
1192
0
      msg =
1193
0
          "Cannot get ICC intermediate CA certificate from provider";
1194
0
      goto csc_end;
1195
0
    }
1196
0
  }
1197
1198
  /* Read ICC certificate from card */
1199
0
  sc_log(ctx, "Step 8.4.1.8: Retrieve ICC certificate");
1200
0
  res = provider->cwa_get_icc_cert(card, &icc_cert);
1201
0
  if (res != SC_SUCCESS) {
1202
0
    msg = "Cannot get ICC certificate from provider";
1203
0
    goto csc_end;
1204
0
  }
1205
1206
  /* Verify icc Card certificate chain */
1207
  /* Notice that Some implementations doesn't verify cert chain
1208
   * but simply verifies that icc_cert is a valid certificate */
1209
0
  if (ca_cert) {
1210
0
    sc_log(ctx, "Verifying ICC certificate chain");
1211
0
    res =
1212
0
        cwa_verify_icc_certificates(card, provider, ca_cert,
1213
0
            icc_cert);
1214
0
    if (res != SC_SUCCESS) {
1215
0
      res = SC_ERROR_SM_AUTHENTICATION_FAILED;
1216
0
      msg = "Icc Certificates verification failed";
1217
0
      goto csc_end;
1218
0
    }
1219
0
  } else {
1220
0
    sc_log(ctx, "Cannot verify Certificate chain. skip step");
1221
0
  }
1222
1223
  /* Extract public key from ICC certificate */
1224
0
  if (!(icc_pubkey = X509_get_pubkey(icc_cert))) {
1225
0
    res = SC_ERROR_INTERNAL;
1226
0
    sc_log_openssl(ctx);
1227
0
    msg = "Cannot extract public key from ICC certificate";
1228
0
    goto csc_end;
1229
0
  }
1230
1231
  /* Select Root CA in card for ifd certificate verification */
1232
0
  sc_log(ctx,
1233
0
         "Step 8.4.1.2: Select Root CA in card for IFD cert verification");
1234
0
  res = provider->cwa_get_root_ca_pubkey_ref(card, &buffer, &bufferlen);
1235
0
  if (res != SC_SUCCESS) {
1236
0
    msg = "Cannot get Root CA key reference from provider";
1237
0
    goto csc_end;
1238
0
  }
1239
0
  tlvlen = 0;
1240
0
  tlv = calloc(10 + bufferlen, sizeof(u8));
1241
0
  if (!tlv) {
1242
0
    msg = "calloc error";
1243
0
    res = SC_ERROR_OUT_OF_MEMORY;
1244
0
    goto csc_end;
1245
0
  }
1246
0
  res = cwa_compose_tlv(card, 0x83, bufferlen, buffer, &tlv, &tlvlen);
1247
0
  if (res != SC_SUCCESS) {
1248
0
    msg = "Cannot compose tlv for setting Root CA key reference";
1249
0
    goto csc_end;
1250
0
  }
1251
0
  res = cwa_set_security_env(card, 0x81, 0xB6, tlv, tlvlen);
1252
0
  if (res != SC_SUCCESS) {
1253
0
    msg = "Select Root CA key ref failed";
1254
0
    goto csc_end;
1255
0
  }
1256
1257
  /* Send IFD intermediate CA in CVC format C_CV_CA */
1258
0
  sc_log(ctx,
1259
0
         "Step 8.4.1.3: Send CVC IFD intermediate CA Cert for ICC verification");
1260
0
  res = provider->cwa_get_cvc_ca_cert(card, &cert, &certlen);
1261
0
  if (res != SC_SUCCESS) {
1262
0
    msg = "Get CVC CA cert from provider failed";
1263
0
    goto csc_end;
1264
0
  }
1265
0
  res = cwa_verify_cvc_certificate(card, cert, certlen);
1266
0
  if (res != SC_SUCCESS) {
1267
0
    msg = "Verify CVC CA failed";
1268
0
    goto csc_end;
1269
0
  }
1270
1271
  /* select public key reference for sent IFD intermediate CA certificate */
1272
0
  sc_log(ctx,
1273
0
         "Step 8.4.1.4: Select Intermediate CA pubkey ref for ICC verification");
1274
0
  res =
1275
0
      provider->cwa_get_intermediate_ca_pubkey_ref(card, &buffer,
1276
0
               &bufferlen);
1277
0
  if (res != SC_SUCCESS) {
1278
0
    msg = "Cannot get intermediate CA key reference from provider";
1279
0
    goto csc_end;
1280
0
  }
1281
0
  tlvlen = 0;
1282
0
  free(tlv);
1283
0
  tlv = calloc(10 + bufferlen, sizeof(u8));
1284
0
  if (!tlv) {
1285
0
    msg = "calloc error";
1286
0
    res = SC_ERROR_OUT_OF_MEMORY;
1287
0
    goto csc_end;
1288
0
  }
1289
0
  res = cwa_compose_tlv(card, 0x83, bufferlen, buffer, &tlv, &tlvlen);
1290
0
  if (res != SC_SUCCESS) {
1291
0
    msg =
1292
0
        "Cannot compose tlv for setting intermediate CA key reference";
1293
0
    goto csc_end;
1294
0
  }
1295
0
  res = cwa_set_security_env(card, 0x81, 0xB6, tlv, tlvlen);
1296
0
  if (res != SC_SUCCESS) {
1297
0
    msg = "Select CVC CA pubk failed";
1298
0
    goto csc_end;
1299
0
  }
1300
1301
  /* Send IFD certificate in CVC format C_CV_IFD */
1302
0
  sc_log(ctx,
1303
0
         "Step 8.4.1.5: Send CVC IFD Certificate for ICC verification");
1304
0
  res = provider->cwa_get_cvc_ifd_cert(card, &cert, &certlen);
1305
0
  if (res != SC_SUCCESS) {
1306
0
    msg = "Get CVC IFD cert from provider failed";
1307
0
    goto csc_end;
1308
0
  }
1309
0
  res = cwa_verify_cvc_certificate(card, cert, certlen);
1310
0
  if (res != SC_SUCCESS) {
1311
0
    msg = "Verify CVC IFD failed";
1312
0
    goto csc_end;
1313
0
  }
1314
1315
  /* remember that this code changes IFD and ICC Cert verification steps */
1316
1317
  /* select public key of ifd certificate and icc private key */
1318
0
  sc_log(ctx,
1319
0
         "Step 8.4.1.9: Send IFD pubk and ICC privk key references for Internal Auth");
1320
0
  res = provider->cwa_get_ifd_pubkey_ref(card, &buffer, &bufferlen);
1321
0
  if (res != SC_SUCCESS) {
1322
0
    msg = "Cannot get ifd public key reference from provider";
1323
0
    goto csc_end;
1324
0
  }
1325
0
  tlvlen = 0;
1326
0
  free(tlv);
1327
0
  tlv = calloc(10 + bufferlen, sizeof(u8));
1328
0
  if (!tlv) {
1329
0
    msg = "calloc error";
1330
0
    res = SC_ERROR_OUT_OF_MEMORY;
1331
0
    goto csc_end;
1332
0
  }
1333
0
  res = cwa_compose_tlv(card, 0x83, bufferlen, buffer, &tlv, &tlvlen);
1334
0
  if (res != SC_SUCCESS) {
1335
0
    msg = "Cannot compose tlv for setting ifd pubkey reference";
1336
0
    goto csc_end;
1337
0
  }
1338
0
  res = provider->cwa_get_icc_privkey_ref(card, &buffer, &bufferlen);
1339
0
  if (res != SC_SUCCESS) {
1340
0
    msg = "Cannot get icc private key reference from provider";
1341
0
    goto csc_end;
1342
0
  }
1343
  /* add this tlv to old one; do not call calloc */
1344
0
  res = cwa_compose_tlv(card, 0x84, bufferlen, buffer, &tlv, &tlvlen);
1345
0
  if (res != SC_SUCCESS) {
1346
0
    msg = "Cannot compose tlv for setting ifd pubkey reference";
1347
0
    goto csc_end;
1348
0
  }
1349
1350
0
  res = cwa_set_security_env(card, 0xC1, 0xA4, tlv, tlvlen);
1351
0
  if (res != SC_SUCCESS) {
1352
0
    msg = "Select CVC IFD pubk failed";
1353
0
    goto csc_end;
1354
0
  }
1355
1356
  /* Internal (Card) authentication (let the card verify sent ifd certs)
1357
     SN.IFD equals 8 lsb bytes of ifd.pubk ref according cwa14890 sec 8.4.1 */
1358
0
  sc_log(ctx, "Step 8.4.1.10: Perform Internal authentication");
1359
0
  res = provider->cwa_get_sn_ifd(card);
1360
0
  if (res != SC_SUCCESS) {
1361
0
    msg = "Cannot get ifd serial number from provider";
1362
0
    goto csc_end;
1363
0
  }
1364
  /* generate 8 random bytes */
1365
0
  if (RAND_bytes(sm->ifd.rnd, 8) != 1) {
1366
0
    msg = "Cannot generate random data";
1367
0
    res = SC_ERROR_INTERNAL;
1368
0
    goto csc_end;
1369
0
  }
1370
0
  memcpy(rndbuf, sm->ifd.rnd, 8); /* insert RND.IFD into rndbuf */
1371
0
  memcpy(rndbuf + 8, sm->ifd.sn, 8);  /* insert SN.IFD into rndbuf */
1372
0
  res = cwa_internal_auth(card, sig, 128, rndbuf, 16);
1373
0
  if (res != SC_SUCCESS) {
1374
0
    msg = "Internal auth cmd failed";
1375
0
    goto csc_end;
1376
0
  }
1377
1378
  /* retrieve ifd private key from provider */
1379
0
  res = provider->cwa_get_ifd_privkey(card, &ifd_privkey);
1380
0
  if (res != SC_SUCCESS) {
1381
0
    msg = "Cannot retrieve IFD private key from provider";
1382
0
    res = SC_ERROR_SM_NO_SESSION_KEYS;
1383
0
    goto csc_end;
1384
0
  }
1385
1386
  /* verify received signature */
1387
0
  sc_log(ctx, "Verify Internal Auth command response");
1388
0
  res = cwa_verify_internal_auth(card, icc_pubkey,  /* evaluated icc public key */
1389
0
               ifd_privkey, /* evaluated from DGP's Manual Annex 3 Data */
1390
0
               rndbuf,  /* RND.IFD || SN.IFD */
1391
0
               16,  /* rndbuf length; should be 16 */
1392
0
               sig, 128
1393
0
      );
1394
0
  if (res != SC_SUCCESS) {
1395
0
    msg = "Internal Auth Verify failed";
1396
0
    goto csc_end;
1397
0
  }
1398
1399
  /* get challenge: retrieve 8 random bytes from card */
1400
0
  sc_log(ctx, "Step 8.4.1.11: Prepare External Auth: Get Challenge");
1401
0
  res = sc_get_challenge(card, sm->icc.rnd, sizeof(sm->icc.rnd));
1402
0
  if (res != SC_SUCCESS) {
1403
0
    msg = "Get Challenge failed";
1404
0
    goto csc_end;
1405
0
  }
1406
1407
  /* compose signature data for external auth */
1408
0
  res = cwa_prepare_external_auth(card, icc_pubkey, ifd_privkey, sig, 128);
1409
0
  if (res != SC_SUCCESS) {
1410
0
    msg = "Prepare external auth failed";
1411
0
    goto csc_end;
1412
0
  }
1413
1414
  /* External (IFD)  authentication */
1415
0
  sc_log(ctx, "Step 8.4.1.12: Perform External (IFD) Authentication");
1416
0
  res = cwa_external_auth(card, sig, 128);
1417
0
  if (res != SC_SUCCESS) {
1418
0
    msg = "External auth cmd failed";
1419
0
    goto csc_end;
1420
0
  }
1421
1422
  /* Session key generation */
1423
0
  sc_log(ctx, "Step 8.4.2: Compute Session Keys");
1424
0
  res = cwa_compute_session_keys(card);
1425
0
  if (res != SC_SUCCESS) {
1426
0
    msg = "Session Key generation failed";
1427
0
    goto csc_end;
1428
0
  }
1429
1430
  /* call provider post-operation method */
1431
0
  sc_log(ctx, "CreateSecureChannel post-operations");
1432
0
  if (provider->cwa_create_post_ops) {
1433
0
    res = provider->cwa_create_post_ops(card, provider);
1434
0
    if (res != SC_SUCCESS) {
1435
0
      sc_log(ctx, "Create SM: provider post_ops() failed");
1436
0
      goto csc_end;
1437
0
    }
1438
0
  }
1439
1440
  /* arriving here means ok: cleanup */
1441
0
  res = SC_SUCCESS;
1442
0
 csc_end:
1443
0
  free(tlv);
1444
0
  X509_free(icc_cert);
1445
0
  X509_free(ca_cert);
1446
0
  EVP_PKEY_free(icc_pubkey);
1447
0
  EVP_PKEY_free(ifd_privkey);
1448
  /* setup SM state according result */
1449
0
  if (res != SC_SUCCESS) {
1450
0
    sc_log(ctx, "%s", msg);
1451
0
    card->sm_ctx.sm_mode = SM_MODE_NONE;
1452
0
  } else {
1453
0
    card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
1454
0
  }
1455
0
  LOG_FUNC_RETURN(ctx, res);
1456
0
}
1457
1458
/******************* SM internal APDU encoding / decoding functions ******/
1459
1460
/**
1461
 * Encode an APDU.
1462
 *
1463
 * Calling this functions means that It's has been verified
1464
 * That source apdu needs encoding
1465
 * Based on section 9 of CWA-14890 and Sect 6 of iso7816-4 standards
1466
 * And DNIe's manual
1467
 *
1468
 * @param card card info structure
1469
 * @param sm Secure Messaging state information
1470
 * @param from APDU to be encoded
1471
 * @param to where to store encoded apdu
1472
 * @return SC_SUCCESS if ok; else error code
1473
 */
1474
int cwa_encode_apdu(sc_card_t * card,
1475
        cwa_provider_t * provider, sc_apdu_t * from, sc_apdu_t * to)
1476
0
{
1477
0
  u8 *apdubuf = NULL;   /* to store resulting apdu */
1478
0
  size_t apdulen, tlv_len;
1479
0
  u8 *ccbuf = NULL;   /* where to store data to eval cryptographic checksum CC */
1480
0
  size_t cclen = 0;
1481
0
  u8 macbuf[8];   /* to store and compute CC */
1482
0
  char *msg = NULL;
1483
1484
0
  size_t i, j;    /* for xor loops */
1485
0
  int res = SC_SUCCESS;
1486
0
  sc_context_t *ctx = NULL;
1487
0
  struct sm_cwa_session * sm_session = &card->sm_ctx.info.session.cwa;
1488
0
  u8 *msgbuf = NULL;  /* to encrypt apdu data */
1489
0
  u8 *cryptbuf = NULL;
1490
1491
0
  EVP_CIPHER_CTX *cctx = NULL;
1492
0
  EVP_CIPHER *alg = NULL;
1493
0
  unsigned char *key = NULL;
1494
0
  int tmplen = 0;
1495
1496
  /* mandatory check */
1497
0
  if (!card || !card->ctx || !provider)
1498
0
    return SC_ERROR_INVALID_ARGUMENTS;
1499
0
  ctx = card->ctx;
1500
1501
0
  LOG_FUNC_CALLED(ctx);
1502
  /* check remaining arguments */
1503
0
  if (!from || !to || !sm_session)
1504
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_SM_NOT_INITIALIZED);
1505
0
  if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT)
1506
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_SM_INVALID_LEVEL);
1507
1508
  /* reserve extra bytes for padding and tlv header */
1509
0
  msgbuf = calloc(12 + from->lc, sizeof(u8)); /* to encrypt apdu data */
1510
0
  cryptbuf = calloc(12 + from->lc, sizeof(u8));
1511
0
  if (!msgbuf || !cryptbuf) {
1512
0
    res = SC_ERROR_OUT_OF_MEMORY;
1513
0
    goto err;
1514
0
  }
1515
1516
  /* check if APDU is already encoded */
1517
0
  if ((from->cla & 0x0C) != 0) {
1518
0
    memcpy(to, from, sizeof(sc_apdu_t));
1519
0
    res = SC_SUCCESS; /* already encoded */
1520
0
    goto encode_end;
1521
0
  }
1522
0
  if (from->ins == 0xC0) {
1523
0
    memcpy(to, from, sizeof(sc_apdu_t));
1524
0
    res = SC_SUCCESS; /* dont encode GET Response cmd */
1525
0
    goto encode_end;
1526
0
  }
1527
1528
  /* trace APDU before encoding process */
1529
0
  cwa_trace_apdu(card, from, 0);
1530
1531
  /* reserve enough space for apdulen+tlv bytes
1532
   * to-be-crypted buffer and result apdu buffer */
1533
   /* TODO DEE add 4 more bytes for testing.... */
1534
0
  apdubuf = calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen),
1535
0
       sizeof(u8));
1536
0
  ccbuf = calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen),
1537
0
       sizeof(u8));
1538
  /* always create a new buffer for the encoded response */
1539
0
  to->resp = calloc(MAX_RESP_BUFFER_SIZE, sizeof(u8));
1540
0
  to->resplen = MAX_RESP_BUFFER_SIZE;
1541
0
  if (!apdubuf || !ccbuf || (!from->resp && !to->resp)) {
1542
0
    res = SC_ERROR_OUT_OF_MEMORY;
1543
0
    goto err;
1544
0
  }
1545
1546
  /* set up data on destination apdu */
1547
0
  to->cse = SC_APDU_CASE_4_SHORT;
1548
0
  to->cla = from->cla | 0x0C; /* mark apdu as encoded */
1549
0
  to->ins = from->ins;
1550
0
  to->p1 = from->p1;
1551
0
  to->p2 = from->p2;
1552
0
  to->le = from->le;
1553
0
  if (!to->le)
1554
0
    to->le = 255;
1555
0
  to->lc = 0;   /* to be evaluated */
1556
  /* fill buffer with header info */
1557
0
  *(ccbuf + cclen++) = to->cla;
1558
0
  *(ccbuf + cclen++) = to->ins;
1559
0
  *(ccbuf + cclen++) = to->p1;
1560
0
  *(ccbuf + cclen++) = to->p2;
1561
0
  cwa_iso7816_padding(ccbuf, &cclen); /* pad header (4 bytes pad) */
1562
1563
0
  if (!(cctx = EVP_CIPHER_CTX_new())) {
1564
0
    res = SC_ERROR_INTERNAL;
1565
0
    goto err;
1566
0
  }
1567
1568
  /* if no data, skip data encryption step */
1569
0
  if (from->lc != 0) {
1570
0
    unsigned char iv[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1571
0
    int dlen = (int)from->lc;
1572
0
    size_t len = dlen;
1573
1574
    /* pad message */
1575
0
    memcpy(msgbuf, from->data, dlen);
1576
0
    cwa_iso7816_padding(msgbuf, &len);
1577
0
    dlen = (int)len;
1578
1579
    /* start kriptbuff with iso padding indicator */
1580
0
    *cryptbuf = 0x01;
1581
0
    key = sm_session->session_enc;
1582
1583
0
    alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC");
1584
1585
0
    if (!alg ||
1586
0
        EVP_EncryptInit_ex(cctx, alg, NULL, key, iv) != 1 ||
1587
0
        EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 ||
1588
0
        EVP_EncryptUpdate(cctx, cryptbuf + 1, &dlen, msgbuf, dlen) != 1 ||
1589
0
        EVP_EncryptFinal_ex(cctx, cryptbuf + 1 + dlen, &tmplen) != 1) {
1590
0
      msg = "Error in encrypting APDU";
1591
0
      res = SC_ERROR_INTERNAL;
1592
0
      goto encode_end;
1593
0
    }
1594
0
    dlen += tmplen;
1595
1596
    /* compose data TLV and add to result buffer */
1597
0
    res = cwa_compose_tlv(card, 0x87, dlen + 1, cryptbuf, &ccbuf, &cclen);
1598
0
    if (res != SC_SUCCESS) {
1599
0
      msg = "Error in compose tag 8x87 TLV";
1600
0
      goto encode_end;
1601
0
    }
1602
0
  } else if ((0xff & from->le) > 0) {
1603
    /* if le byte is declared, compose and add Le TLV */
1604
    /* FIXME: For DNIe we must not send the le bytes
1605
       when le == 256 but this goes against the standard
1606
       and might break other cards reusing this code */
1607
    /* NOTE: In FNMT MultiPKCS11 code this is an if, i.e.,
1608
       the le is only sent if no data (lc) is set.
1609
       In DNIe 3.0 pin verification sending both TLV return
1610
       69 88 "SM Data Object incorrect". For the moment it is
1611
       fixed sendind le=0 in pin verification apdu */
1612
0
    u8 le = 0xff & from->le;
1613
0
    res = cwa_compose_tlv(card, 0x97, 1, &le, &ccbuf, &cclen);
1614
0
    if (res != SC_SUCCESS) {
1615
0
      msg = "Encode APDU compose_tlv(0x97) failed";
1616
0
      goto encode_end;
1617
0
    }
1618
0
  }
1619
  /* copy current data to apdu buffer (skip header and header padding) */
1620
0
  if (cclen < 8) {
1621
0
    res = SC_ERROR_INTERNAL;
1622
0
    msg = "Incorrect checksum length";
1623
0
    goto encode_end;
1624
0
  }
1625
0
  memcpy(apdubuf, ccbuf + 8, cclen - 8);
1626
0
  apdulen = cclen - 8;
1627
  /* pad again ccbuffer to compute CC */
1628
0
  cwa_iso7816_padding(ccbuf, &cclen);
1629
1630
  /* sc_log(ctx,"data to compose mac: %s",sc_dump_hex(ccbuf,cclen)); */
1631
  /* compute MAC Cryptographic Checksum using kmac and increased SSC */
1632
0
  res = cwa_increase_ssc(card); /* increase send sequence counter */
1633
0
  if (res != SC_SUCCESS) {
1634
0
    msg = "Error in computing SSC";
1635
0
    goto encode_end;
1636
0
  }
1637
1638
0
  memcpy(macbuf, sm_session->ssc, 8); /* start with computed SSC */
1639
1640
0
  tmplen = 0;
1641
0
  key = sm_session->session_mac;
1642
1643
0
  sc_evp_cipher_free(alg);
1644
0
  alg = sc_evp_cipher(card->ctx, "DES-ECB");
1645
0
  if (!alg ||
1646
0
      EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 ||
1647
0
      EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) {
1648
0
    msg = "Error in DES ECB encryption";
1649
0
    res = SC_ERROR_INTERNAL;
1650
0
    goto encode_end;
1651
0
  }
1652
1653
0
  for (i = 0; i < cclen; i += 8) { /* divide data in 8 byte blocks */
1654
    /* compute DES */
1655
0
    if (EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf , 8) != 1) {
1656
0
      msg = "Error in DES ECB encryption";
1657
0
      res = SC_ERROR_INTERNAL;
1658
0
      goto encode_end;
1659
0
    }
1660
    /* XOR with next data and repeat */
1661
0
    for (j = 0; j < 8; j++)
1662
0
      macbuf[j] ^= ccbuf[i + j];
1663
0
  }
1664
0
  if (EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) {
1665
0
    msg = "Error in DES ECB encryption";
1666
0
    res = SC_ERROR_INTERNAL;
1667
0
    goto encode_end;
1668
0
  }
1669
1670
  /* and apply 3DES to result */
1671
0
  sc_evp_cipher_free(alg);
1672
0
  alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB");
1673
1674
0
  if (!alg ||
1675
0
      EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 ||
1676
0
      EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 ||
1677
0
      EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 ||
1678
0
      EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) {
1679
0
    msg = "Error in 3DEC ECB encryption";
1680
0
    res = SC_ERROR_INTERNAL;
1681
0
    goto encode_end;
1682
0
  }
1683
1684
  /* compose and add computed MAC TLV to result buffer */
1685
0
  tlv_len = (card->atr.value[15] >= DNIE_30_VERSION)? 8 : 4;
1686
0
  sc_log(ctx, "Using TLV length: %"SC_FORMAT_LEN_SIZE_T"u", tlv_len);
1687
0
  res = cwa_compose_tlv(card, 0x8E, tlv_len, macbuf, &apdubuf, &apdulen);
1688
0
  if (res != SC_SUCCESS) {
1689
0
    msg = "Encode APDU compose_tlv(0x87) failed";
1690
0
    goto encode_end;
1691
0
  }
1692
1693
  /* rewrite resulting header */
1694
0
  to->lc = apdulen;
1695
0
  to->data = apdubuf;
1696
0
  to->datalen = apdulen;
1697
1698
  /* that's all folks */
1699
0
  res = SC_SUCCESS;
1700
0
  goto encode_end_apdu_valid;
1701
1702
0
err:
1703
0
encode_end:
1704
0
  free(apdubuf);
1705
0
  if (from->resp != to->resp)
1706
0
    free(to->resp);
1707
0
encode_end_apdu_valid:
1708
0
  sc_evp_cipher_free(alg);
1709
0
  EVP_CIPHER_CTX_free(cctx);
1710
0
  if (msg) {
1711
0
    sc_log_openssl(ctx);
1712
0
    sc_log(ctx, "%s", msg);
1713
0
  }
1714
0
  free(msgbuf);
1715
0
  free(cryptbuf);
1716
0
  free(ccbuf);
1717
0
  LOG_FUNC_RETURN(ctx, res);
1718
0
}
1719
1720
/**
1721
 * Decode an APDU response.
1722
 *
1723
 * Calling this functions means that It's has been verified
1724
 * That apdu response comes in TLV encoded format and needs decoding
1725
 * Based on section 9 of CWA-14890 and Sect 6 of iso7816-4 standards
1726
 * And DNIe's manual
1727
 *
1728
 * @param card card info structure
1729
 * @param sm Secure Messaging state information
1730
 * @param from APDU with response to be decoded
1731
 * @param to where to store decoded apdu
1732
 * @return SC_SUCCESS if ok; else error code
1733
 */
1734
int cwa_decode_response(sc_card_t * card,
1735
      cwa_provider_t * provider,
1736
      sc_apdu_t * apdu)
1737
0
{
1738
0
  size_t i, j, tlv_len;
1739
0
  cwa_tlv_t tlv_array[4];
1740
0
  cwa_tlv_t *p_tlv = &tlv_array[0]; /* to store plain data (Tag 0x81) */
1741
0
  cwa_tlv_t *e_tlv = &tlv_array[1]; /* to store pad encoded data (Tag 0x87) */
1742
0
  cwa_tlv_t *m_tlv = &tlv_array[2]; /* to store mac CC (Tag 0x8E) */
1743
0
  cwa_tlv_t *s_tlv = &tlv_array[3]; /* to store sw1-sw2 status (Tag 0x99) */
1744
0
  u8 *buffer = NULL;  /* buffer for data. pointers to this buffer are in tlv_array */
1745
0
  u8 *ccbuf = NULL; /* buffer for mac CC calculation */
1746
0
  size_t cclen = 0; /* ccbuf len */
1747
0
  u8 macbuf[8];   /* where to calculate mac */
1748
0
  size_t resplen = 0; /* respbuf length */
1749
0
  int res = SC_SUCCESS;
1750
0
  char *msg = NULL; /* to store error messages */
1751
0
  sc_context_t *ctx = NULL;
1752
0
  struct sm_cwa_session * sm_session = &card->sm_ctx.info.session.cwa;
1753
1754
0
  EVP_CIPHER_CTX *cctx = NULL;
1755
0
  EVP_CIPHER *alg = NULL;
1756
0
  unsigned char *key = NULL;
1757
0
  int tmplen = 0;
1758
1759
0
  if ((cctx = EVP_CIPHER_CTX_new()) == NULL) {
1760
0
    sc_log_openssl(ctx);
1761
0
    return SC_ERROR_INTERNAL;
1762
0
  }
1763
1764
  /* mandatory check */
1765
0
  if (!card || !card->ctx || !provider)
1766
0
    return SC_ERROR_INVALID_ARGUMENTS;
1767
0
  ctx = card->ctx;
1768
1769
0
  LOG_FUNC_CALLED(ctx);
1770
  /* check remaining arguments */
1771
0
  if ((apdu == NULL) || (sm_session == NULL))
1772
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_SM_NOT_INITIALIZED);
1773
0
  if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT)
1774
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_SM_INVALID_LEVEL);
1775
1776
  /* cwa14890 sect 9.3: check SW1 or SW2 for SM related errors */
1777
0
  if (apdu->sw1 == 0x69) {
1778
0
    if ((apdu->sw2 == 0x88) || (apdu->sw2 == 0x87)) {
1779
      /* configure the driver to re-establish the SM */
1780
0
      msg = "SM related errors in APDU response";
1781
0
      cwa_create_secure_channel(card, provider, CWA_SM_OFF);
1782
0
      res = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
1783
0
      goto response_decode_end;
1784
0
    }
1785
0
  }
1786
  /* if response is null/empty assume unencoded apdu */
1787
0
  if (!apdu->resp || (apdu->resplen == 0)) {
1788
0
    sc_log(ctx, "Empty APDU response: assume not cwa encoded");
1789
0
    return SC_SUCCESS;
1790
0
  }
1791
  /* checks if apdu response needs decoding by checking tags in response */
1792
0
  switch (*apdu->resp) {
1793
0
  case CWA_SM_PLAIN_TAG:
1794
0
  case CWA_SM_CRYPTO_TAG:
1795
0
  case CWA_SM_MAC_TAG:
1796
0
  case CWA_SM_LE_TAG:
1797
0
  case CWA_SM_STATUS_TAG:
1798
0
    break;    /* cwa tags found: continue decoding */
1799
0
  default:    /* else apdu response seems not to be cwa encoded */
1800
0
    sc_log(card->ctx, "APDU Response seems not to be cwa encoded");
1801
0
    return SC_SUCCESS; /* let process continue */
1802
0
  }
1803
1804
  /* parse response to find TLV's data and check results */
1805
0
  memset(tlv_array, 0, 4 * sizeof(cwa_tlv_t));
1806
  /* create buffer and copy data into */
1807
0
  buffer = calloc(apdu->resplen, sizeof(u8));
1808
0
  if (!buffer) {
1809
0
    msg = "Cannot allocate space for response buffer";
1810
0
    res = SC_ERROR_OUT_OF_MEMORY;
1811
0
    goto response_decode_end;
1812
0
  }
1813
0
  memcpy(buffer, apdu->resp, apdu->resplen);
1814
1815
0
  res = cwa_parse_tlv(card, buffer, apdu->resplen, tlv_array);
1816
0
  if (res != SC_SUCCESS) {
1817
0
    msg = "Error in TLV parsing";
1818
0
    goto response_decode_end;
1819
0
  }
1820
1821
  /* check consistency of received TLV's */
1822
0
  if (p_tlv->buf && e_tlv->buf) {
1823
0
    msg =
1824
0
        "Plain and Encoded data are mutually exclusive in apdu response";
1825
0
    res = SC_ERROR_INVALID_DATA;
1826
0
    goto response_decode_end;
1827
0
  }
1828
0
  if (!m_tlv->buf) {
1829
0
    msg = "No MAC TAG found in apdu response";
1830
0
    res = SC_ERROR_INVALID_DATA;
1831
0
    goto response_decode_end;
1832
0
  }
1833
0
  tlv_len = (card->atr.value[15] >= DNIE_30_VERSION)? 8 : 4;
1834
0
  if (m_tlv->len != tlv_len) {
1835
0
    msg = "Invalid MAC TAG Length";
1836
0
    res = SC_ERROR_INVALID_DATA;
1837
0
    goto response_decode_end;
1838
0
  }
1839
1840
  /* compose buffer to evaluate mac */
1841
1842
  /* reserve enough space for data+status+padding */
1843
0
  ccbuf =
1844
0
      calloc(e_tlv->buflen + s_tlv->buflen + p_tlv->buflen + 8,
1845
0
       sizeof(u8));
1846
0
  if (!ccbuf) {
1847
0
    msg = "Cannot allocate space for mac checking";
1848
0
    res = SC_ERROR_OUT_OF_MEMORY;
1849
0
    goto response_decode_end;
1850
0
  }
1851
  /* copy data into buffer */
1852
0
  cclen = 0;
1853
0
  if (e_tlv->buf) { /* encoded data */
1854
0
    memcpy(ccbuf, e_tlv->buf, e_tlv->buflen);
1855
0
    cclen = e_tlv->buflen;
1856
0
  }
1857
0
  if (p_tlv->buf) { /* plain data */
1858
0
    memcpy(ccbuf, p_tlv->buf, p_tlv->buflen);
1859
0
    cclen += p_tlv->buflen;
1860
0
  }
1861
0
  if (s_tlv->buf) { /* response status */
1862
0
    if (s_tlv->len != 2) {
1863
0
      msg = "Invalid SW TAG length";
1864
0
      res = SC_ERROR_INVALID_DATA;
1865
0
      goto response_decode_end;
1866
0
    }
1867
0
    memcpy(ccbuf + cclen, s_tlv->buf, s_tlv->buflen);
1868
0
    cclen += s_tlv->buflen;
1869
0
    apdu->sw1 = s_tlv->data[0];
1870
0
    apdu->sw2 = s_tlv->data[1];
1871
0
  }    /* if no response status tag, use sw1 and sw2 from apdu */
1872
  /* add iso7816 padding */
1873
0
  cwa_iso7816_padding(ccbuf, &cclen);
1874
1875
  /* evaluate mac by mean of kmac and increased SendSequence Counter SSC */
1876
1877
  /* increase SSC */
1878
0
  res = cwa_increase_ssc(card); /* increase send sequence counter */
1879
0
  if (res != SC_SUCCESS) {
1880
0
    msg = "Error in computing SSC";
1881
0
    goto response_decode_end;
1882
0
  }
1883
  /* set up key for mac computing */
1884
0
  key = sm_session->session_mac;
1885
1886
0
  alg = sc_evp_cipher(card->ctx, "DES-ECB");
1887
0
  if (!alg ||
1888
0
      EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 ||
1889
0
      EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) {
1890
0
    sc_log_openssl(ctx);
1891
0
    msg = "Error in DES ECB encryption";
1892
0
    res = SC_ERROR_INTERNAL;
1893
0
    goto response_decode_end;
1894
0
  }
1895
1896
0
  memcpy(macbuf, sm_session->ssc, 8); /* start with computed SSC */
1897
0
  for (i = 0; i < cclen; i += 8) { /* divide data in 8 byte blocks */
1898
    /* compute DES */
1899
0
    if (EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1) {
1900
0
      sc_log_openssl(ctx);
1901
0
      msg = "Error in DES ECB encryption";
1902
0
      res = SC_ERROR_INTERNAL;
1903
0
      goto response_decode_end;
1904
0
    }
1905
    /* XOR with data and repeat */
1906
0
    for (j = 0; j < 8; j++)
1907
0
      macbuf[j] ^= ccbuf[i + j];
1908
0
  }
1909
0
  if (EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) {
1910
0
    sc_log_openssl(ctx);
1911
0
    msg = "Error in DES ECB encryption";
1912
0
    res = SC_ERROR_INTERNAL;
1913
0
    goto response_decode_end;
1914
0
  }
1915
1916
  /* finally apply 3DES to result */
1917
0
  sc_evp_cipher_free(alg);
1918
0
  alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB");
1919
1920
0
  if (!alg ||
1921
0
      EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 ||
1922
0
      EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 ||
1923
0
      EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 ||
1924
0
      EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) {
1925
0
    sc_log_openssl(ctx);
1926
0
    msg = "Error in 3DEC ECB encryption";
1927
0
    res = SC_ERROR_INTERNAL;
1928
0
    goto response_decode_end;
1929
0
  }
1930
1931
  /* check evaluated mac with provided by apdu response */
1932
1933
0
  res = memcmp(m_tlv->data, macbuf, 4); /* check first 4 bytes */
1934
0
  if (res != 0) {
1935
0
    msg = "Error in MAC CC checking: value doesn't match";
1936
0
    res = SC_ERROR_SM_ENCRYPT_FAILED;
1937
0
    goto response_decode_end;
1938
0
  }
1939
1940
  /* allocate response buffer */
1941
0
  resplen = 10 + MAX(p_tlv->len, e_tlv->len); /* estimate response buflen */
1942
0
  if (apdu->resplen < resplen) {
1943
0
    msg = "Cannot allocate buffer to store response";
1944
0
    res = SC_ERROR_BUFFER_TOO_SMALL;
1945
0
    goto response_decode_end;
1946
0
  }
1947
0
  apdu->resplen = resplen;
1948
1949
  /* fill destination response apdu buffer with data */
1950
1951
  /* if plain data, just copy TLV data into apdu response */
1952
0
  if (p_tlv->buf) { /* plain data */
1953
0
    memcpy(apdu->resp, p_tlv->data, p_tlv->len);
1954
0
    apdu->resplen = p_tlv->len;
1955
0
  }
1956
1957
  /* if encoded data, decode and store into apdu response */
1958
0
  else if (e_tlv->buf) { /* encoded data */
1959
0
    unsigned char iv[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1960
0
    int dlen = (int)apdu->resplen;
1961
    /* check data len */
1962
0
    if ((e_tlv->len < 9) || ((e_tlv->len - 1) % 8) != 0) {
1963
0
      msg = "Invalid length for Encoded data TLV";
1964
0
      res = SC_ERROR_INVALID_DATA;
1965
0
      goto response_decode_end;
1966
0
    }
1967
    /* first byte is padding info; check value */
1968
0
    if (e_tlv->data[0] != 0x01) {
1969
0
      msg = "Encoded TLV: Invalid padding info value";
1970
0
      res = SC_ERROR_INVALID_DATA;
1971
0
      goto response_decode_end;
1972
0
    }
1973
    /* prepare keys to decode */
1974
0
    key = sm_session->session_enc;
1975
1976
    /* decrypt into response buffer
1977
     * by using 3DES CBC by mean of kenc and iv={0,...0} */
1978
0
    sc_evp_cipher_free(alg);
1979
0
    alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC");
1980
1981
0
    if (!alg ||
1982
0
        EVP_DecryptInit_ex(cctx, alg, NULL, key, iv) != 1 ||
1983
0
        EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 ||
1984
0
        EVP_DecryptUpdate(cctx, apdu->resp, &dlen, &e_tlv->data[1], (int)(e_tlv->len - 1)) != 1 ||
1985
0
        EVP_DecryptFinal_ex(cctx, apdu->resp + dlen, &tmplen) != 1) {
1986
0
      sc_log_openssl(ctx);
1987
0
      res = SC_ERROR_INTERNAL;
1988
0
      msg = "Can not decrypt 3DES CBC";
1989
0
      goto response_decode_end;
1990
0
    }
1991
0
    apdu->resplen = dlen + tmplen;
1992
1993
    /* remove iso padding from response length */
1994
0
    for (; (apdu->resplen > 0) && *(apdu->resp + apdu->resplen - 1) == 0x00; apdu->resplen--) ;  /* empty loop */
1995
1996
0
    if (*(apdu->resp + apdu->resplen - 1) != 0x80) { /* check padding byte */
1997
0
      msg = "Decrypted TLV has no 0x80 iso padding indicator!";
1998
0
      res = SC_ERROR_INVALID_DATA;
1999
0
      goto response_decode_end;
2000
0
    }
2001
    /* everything ok: remove ending 0x80 from response */
2002
0
    apdu->resplen--;
2003
0
  }
2004
2005
0
  else
2006
0
    apdu->resplen = 0; /* neither plain, nor encoded data */
2007
2008
  /* that's all folks */
2009
0
  res = SC_SUCCESS;
2010
2011
0
 response_decode_end:
2012
0
  sc_evp_cipher_free(alg);
2013
0
  EVP_CIPHER_CTX_free(cctx);
2014
0
  free(buffer);
2015
0
  free(ccbuf);
2016
0
  if (msg) {
2017
0
    sc_log(ctx, "%s", msg);
2018
0
  } else {
2019
0
    cwa_trace_apdu(card, apdu, 1);
2020
0
  }      /* trace apdu response */
2021
0
  LOG_FUNC_RETURN(ctx, res);
2022
0
}
2023
2024
/********************* default provider for cwa14890 ****************/
2025
2026
/* pre and post operations */
2027
2028
static int default_create_pre_ops(sc_card_t * card, cwa_provider_t * provider)
2029
0
{
2030
0
  return SC_SUCCESS;
2031
0
}
2032
2033
static int default_create_post_ops(sc_card_t * card, cwa_provider_t * provider)
2034
0
{
2035
0
  return SC_SUCCESS;
2036
0
}
2037
2038
static int default_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key)
2039
0
{
2040
0
  return SC_ERROR_NOT_SUPPORTED;
2041
0
}
2042
2043
/* retrieve CVC intermediate CA certificate and length */
2044
static int default_get_cvc_ca_cert(sc_card_t * card, u8 ** cert,
2045
           size_t * length)
2046
0
{
2047
0
  return SC_ERROR_NOT_SUPPORTED;
2048
0
}
2049
2050
/* retrieve CVC IFD certificate and length */
2051
static int default_get_cvc_ifd_cert(sc_card_t * card, u8 ** cert,
2052
            size_t * length)
2053
0
{
2054
0
  return SC_ERROR_NOT_SUPPORTED;
2055
0
}
2056
2057
static int default_get_ifd_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey)
2058
0
{
2059
0
  return SC_ERROR_NOT_SUPPORTED;
2060
0
}
2061
2062
/* get ICC intermediate CA  path */
2063
static int default_get_icc_intermediate_ca_cert(sc_card_t * card, X509 ** cert)
2064
0
{
2065
0
  return SC_ERROR_NOT_SUPPORTED;
2066
0
}
2067
2068
/* get ICC certificate path */
2069
static int default_get_icc_cert(sc_card_t * card, X509 ** cert)
2070
0
{
2071
0
  return SC_ERROR_NOT_SUPPORTED;
2072
0
}
2073
2074
/* Retrieve key reference for Root CA to validate CVC intermediate CA certs */
2075
static int default_get_root_ca_pubkey_ref(sc_card_t * card, u8 ** buf,
2076
            size_t * len)
2077
0
{
2078
0
  return SC_ERROR_NOT_SUPPORTED;
2079
0
}
2080
2081
/* Retrieve key reference for intermediate CA to validate IFD certs */
2082
static int default_get_intermediate_ca_pubkey_ref(sc_card_t * card, u8 ** buf,
2083
              size_t * len)
2084
0
{
2085
0
  return SC_ERROR_NOT_SUPPORTED;
2086
0
}
2087
2088
/* Retrieve key reference for IFD certificate */
2089
static int default_get_ifd_pubkey_ref(sc_card_t * card, u8 ** buf, size_t * len)
2090
0
{
2091
0
  return SC_ERROR_NOT_SUPPORTED;
2092
0
}
2093
2094
/* Retrieve key reference for ICC privkey */
2095
static int default_get_icc_privkey_ref(sc_card_t * card, u8 ** buf,
2096
               size_t * len)
2097
0
{
2098
0
  return SC_ERROR_NOT_SUPPORTED;
2099
0
}
2100
2101
/* Retrieve SN.IFD (8 bytes left padded with zeroes if needed) */
2102
static int default_get_sn_ifd(sc_card_t * card)
2103
0
{
2104
0
  return SC_ERROR_NOT_SUPPORTED;
2105
0
}
2106
2107
/* Retrieve SN.ICC (8 bytes left padded with zeroes if needed) */
2108
static int default_get_sn_icc(sc_card_t * card)
2109
0
{
2110
0
  return SC_ERROR_NOT_SUPPORTED;
2111
0
}
2112
2113
static cwa_provider_t default_cwa_provider = {
2114
2115
    /************ data related with SM operations *************************/
2116
2117
    /************ operations related with secure channel creation *********/
2118
2119
  /* pre and post operations */
2120
  default_create_pre_ops,
2121
  default_create_post_ops,
2122
2123
  /* Get ICC intermediate CA  path */
2124
  default_get_icc_intermediate_ca_cert,
2125
  /* Get ICC certificate path */
2126
  default_get_icc_cert,
2127
2128
  /* Obtain RSA public key from RootCA */
2129
  default_get_root_ca_pubkey,
2130
  /* Obtain RSA IFD private key */
2131
  default_get_ifd_privkey,
2132
2133
  /* Retrieve CVC intermediate CA certificate and length */
2134
  default_get_cvc_ca_cert,
2135
  /* Retrieve CVC IFD certificate and length */
2136
  default_get_cvc_ifd_cert,
2137
2138
  /* Get public key references for Root CA to validate intermediate CA cert */
2139
  default_get_root_ca_pubkey_ref,
2140
2141
  /* Get public key reference for IFD intermediate CA certificate */
2142
  default_get_intermediate_ca_pubkey_ref,
2143
2144
  /* Get public key reference for IFD CVC certificate */
2145
  default_get_ifd_pubkey_ref,
2146
2147
  /* Get ICC private key reference */
2148
  default_get_icc_privkey_ref,
2149
2150
  /* Get IFD Serial Number */
2151
  default_get_sn_ifd,
2152
2153
  /* Get ICC Serial Number */
2154
  default_get_sn_icc,
2155
2156
2157
};
2158
2159
/**
2160
 * Get a copy of default cwa provider.
2161
 *
2162
 * @param card pointer to card info structure
2163
 * @return copy of default provider or null on error
2164
 */
2165
cwa_provider_t *cwa_get_default_provider(sc_card_t * card)
2166
0
{
2167
0
  cwa_provider_t *res = NULL;
2168
0
  if (!card || !card->ctx)
2169
0
    return NULL;
2170
0
  LOG_FUNC_CALLED(card->ctx);
2171
0
  res = calloc(1, sizeof(cwa_provider_t));
2172
0
  if (!res) {
2173
0
    sc_log(card->ctx, "Cannot allocate space for cwa_provider");
2174
0
    return NULL;
2175
0
  }
2176
0
  memcpy(res, &default_cwa_provider, sizeof(cwa_provider_t));
2177
0
  return res;
2178
0
}
2179
2180
/* end of cwa14890.c */
2181
#undef __CWA14890_C__
2182
2183
#endif        /* ENABLE_OPENSSL */