Coverage Report

Created: 2025-12-14 06:58

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/cwa14890.c
Line
Count
Source
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
952
{
1102
952
  u8 *cert = NULL;
1103
952
  size_t certlen;
1104
1105
952
  int res = SC_SUCCESS;
1106
952
  char *msg = "Success";
1107
1108
  /* data to get and parse certificates */
1109
952
  X509 *icc_cert = NULL;
1110
952
  X509 *ca_cert = NULL;
1111
952
  EVP_PKEY *icc_pubkey = NULL;
1112
952
  EVP_PKEY *ifd_privkey = NULL;
1113
952
  sc_context_t *ctx = NULL;
1114
952
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
1115
952
  u8 sig[128];
1116
1117
  /* several buffer and buffer pointers */
1118
952
  u8 *buffer = NULL;
1119
952
  size_t bufferlen;
1120
952
  u8 *tlv = NULL;   /* buffer to compose TLV messages */
1121
952
  size_t tlvlen = 0;
1122
952
  u8 rndbuf[16]; /* 8 RND.IFD + 8 SN.IFD */
1123
1124
  /* preliminary checks */
1125
952
  if (!card || !card->ctx )
1126
0
    return SC_ERROR_INVALID_ARGUMENTS;
1127
952
  if (!provider)
1128
0
    return SC_ERROR_SM_NOT_INITIALIZED;
1129
  /* commodity vars */
1130
952
  ctx = card->ctx;
1131
1132
952
  LOG_FUNC_CALLED(ctx);
1133
1134
  /* check requested initialization method */
1135
952
  switch (flag) {
1136
952
  case CWA_SM_OFF: /* disable SM */
1137
952
    card->sm_ctx.sm_mode = SM_MODE_NONE;
1138
952
    sc_log(ctx, "Setting CWA SM status to none");
1139
    /* request the Master File to provoke an SM error and close the channel */
1140
952
    res = sc_select_file(card, sc_get_mf_path(), NULL);
1141
952
    if (res == SC_ERROR_SM)
1142
13
      res = SC_SUCCESS;
1143
952
    LOG_FUNC_RETURN(ctx, res);
1144
0
  case CWA_SM_ON: /* force sm initialization process */
1145
0
    sc_log(ctx, "CWA SM initialization requested");
1146
0
    break;
1147
0
  default:
1148
0
    sc_log(ctx, "Invalid provided SM initialization flag");
1149
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1150
952
  }
1151
1152
  /* OK: lets start process */
1153
1154
  /* call provider pre-operation method */
1155
0
  sc_log(ctx, "CreateSecureChannel pre-operations");
1156
0
  if (provider->cwa_create_pre_ops) {
1157
0
    res = provider->cwa_create_pre_ops(card, provider);
1158
0
    if (res != SC_SUCCESS) {
1159
0
      msg = "Create SM: provider pre_ops() failed";
1160
0
      sc_log(ctx, "%s", msg);
1161
0
      goto csc_end;
1162
0
    }
1163
0
  }
1164
1165
  /* retrieve icc serial number */
1166
0
  sc_log(ctx, "Retrieve ICC serial number");
1167
0
  if (provider->cwa_get_sn_icc) {
1168
0
    res = provider->cwa_get_sn_icc(card);
1169
0
    if (res != SC_SUCCESS) {
1170
0
      msg = "Retrieve ICC failed";
1171
0
      sc_log(ctx, "%s", msg);
1172
0
      goto csc_end;
1173
0
    }
1174
0
  } else {
1175
0
    msg = "Don't know how to obtain ICC serial number";
1176
0
    sc_log(ctx, "%s", msg);
1177
0
    res = SC_ERROR_INTERNAL;
1178
0
    goto csc_end;
1179
0
  }
1180
1181
  /*
1182
   * Notice that this code inverts ICC and IFD certificate standard
1183
   * checking sequence.
1184
   */
1185
1186
  /* Read Intermediate CA from card */
1187
0
  if (!provider->cwa_get_icc_intermediate_ca_cert) {
1188
0
    sc_log(ctx,
1189
0
           "Step 8.4.1.6: Skip Retrieving ICC intermediate CA");
1190
0
    ca_cert = NULL;
1191
0
  } else {
1192
0
    sc_log(ctx, "Step 8.4.1.7: Retrieving ICC intermediate CA");
1193
0
    res =
1194
0
        provider->cwa_get_icc_intermediate_ca_cert(card, &ca_cert);
1195
0
    if (res != SC_SUCCESS) {
1196
0
      msg =
1197
0
          "Cannot get ICC intermediate CA certificate from provider";
1198
0
      goto csc_end;
1199
0
    }
1200
0
  }
1201
1202
  /* Read ICC certificate from card */
1203
0
  sc_log(ctx, "Step 8.4.1.8: Retrieve ICC certificate");
1204
0
  res = provider->cwa_get_icc_cert(card, &icc_cert);
1205
0
  if (res != SC_SUCCESS) {
1206
0
    msg = "Cannot get ICC certificate from provider";
1207
0
    goto csc_end;
1208
0
  }
1209
1210
  /* Verify icc Card certificate chain */
1211
  /* Notice that Some implementations doesn't verify cert chain
1212
   * but simply verifies that icc_cert is a valid certificate */
1213
0
  if (ca_cert) {
1214
0
    sc_log(ctx, "Verifying ICC certificate chain");
1215
0
    res =
1216
0
        cwa_verify_icc_certificates(card, provider, ca_cert,
1217
0
            icc_cert);
1218
0
    if (res != SC_SUCCESS) {
1219
0
      res = SC_ERROR_SM_AUTHENTICATION_FAILED;
1220
0
      msg = "Icc Certificates verification failed";
1221
0
      goto csc_end;
1222
0
    }
1223
0
  } else {
1224
0
    sc_log(ctx, "Cannot verify Certificate chain. skip step");
1225
0
  }
1226
1227
  /* Extract public key from ICC certificate */
1228
0
  if (!(icc_pubkey = X509_get_pubkey(icc_cert))) {
1229
0
    res = SC_ERROR_INTERNAL;
1230
0
    sc_log_openssl(ctx);
1231
0
    msg = "Cannot extract public key from ICC certificate";
1232
0
    goto csc_end;
1233
0
  }
1234
1235
  /* Select Root CA in card for ifd certificate verification */
1236
0
  sc_log(ctx,
1237
0
         "Step 8.4.1.2: Select Root CA in card for IFD cert verification");
1238
0
  res = provider->cwa_get_root_ca_pubkey_ref(card, &buffer, &bufferlen);
1239
0
  if (res != SC_SUCCESS) {
1240
0
    msg = "Cannot get Root CA key reference from provider";
1241
0
    goto csc_end;
1242
0
  }
1243
0
  tlvlen = 0;
1244
0
  tlv = calloc(10 + bufferlen, sizeof(u8));
1245
0
  if (!tlv) {
1246
0
    msg = "calloc error";
1247
0
    res = SC_ERROR_OUT_OF_MEMORY;
1248
0
    goto csc_end;
1249
0
  }
1250
0
  res = cwa_compose_tlv(card, 0x83, bufferlen, buffer, &tlv, &tlvlen);
1251
0
  if (res != SC_SUCCESS) {
1252
0
    msg = "Cannot compose tlv for setting Root CA key reference";
1253
0
    goto csc_end;
1254
0
  }
1255
0
  res = cwa_set_security_env(card, 0x81, 0xB6, tlv, tlvlen);
1256
0
  if (res != SC_SUCCESS) {
1257
0
    msg = "Select Root CA key ref failed";
1258
0
    goto csc_end;
1259
0
  }
1260
1261
  /* Send IFD intermediate CA in CVC format C_CV_CA */
1262
0
  sc_log(ctx,
1263
0
         "Step 8.4.1.3: Send CVC IFD intermediate CA Cert for ICC verification");
1264
0
  res = provider->cwa_get_cvc_ca_cert(card, &cert, &certlen);
1265
0
  if (res != SC_SUCCESS) {
1266
0
    msg = "Get CVC CA cert from provider failed";
1267
0
    goto csc_end;
1268
0
  }
1269
0
  res = cwa_verify_cvc_certificate(card, cert, certlen);
1270
0
  if (res != SC_SUCCESS) {
1271
0
    msg = "Verify CVC CA failed";
1272
0
    goto csc_end;
1273
0
  }
1274
1275
  /* select public key reference for sent IFD intermediate CA certificate */
1276
0
  sc_log(ctx,
1277
0
         "Step 8.4.1.4: Select Intermediate CA pubkey ref for ICC verification");
1278
0
  res =
1279
0
      provider->cwa_get_intermediate_ca_pubkey_ref(card, &buffer,
1280
0
               &bufferlen);
1281
0
  if (res != SC_SUCCESS) {
1282
0
    msg = "Cannot get intermediate CA key reference from provider";
1283
0
    goto csc_end;
1284
0
  }
1285
0
  tlvlen = 0;
1286
0
  free(tlv);
1287
0
  tlv = calloc(10 + bufferlen, sizeof(u8));
1288
0
  if (!tlv) {
1289
0
    msg = "calloc error";
1290
0
    res = SC_ERROR_OUT_OF_MEMORY;
1291
0
    goto csc_end;
1292
0
  }
1293
0
  res = cwa_compose_tlv(card, 0x83, bufferlen, buffer, &tlv, &tlvlen);
1294
0
  if (res != SC_SUCCESS) {
1295
0
    msg =
1296
0
        "Cannot compose tlv for setting intermediate CA key reference";
1297
0
    goto csc_end;
1298
0
  }
1299
0
  res = cwa_set_security_env(card, 0x81, 0xB6, tlv, tlvlen);
1300
0
  if (res != SC_SUCCESS) {
1301
0
    msg = "Select CVC CA pubk failed";
1302
0
    goto csc_end;
1303
0
  }
1304
1305
  /* Send IFD certificate in CVC format C_CV_IFD */
1306
0
  sc_log(ctx,
1307
0
         "Step 8.4.1.5: Send CVC IFD Certificate for ICC verification");
1308
0
  res = provider->cwa_get_cvc_ifd_cert(card, &cert, &certlen);
1309
0
  if (res != SC_SUCCESS) {
1310
0
    msg = "Get CVC IFD cert from provider failed";
1311
0
    goto csc_end;
1312
0
  }
1313
0
  res = cwa_verify_cvc_certificate(card, cert, certlen);
1314
0
  if (res != SC_SUCCESS) {
1315
0
    msg = "Verify CVC IFD failed";
1316
0
    goto csc_end;
1317
0
  }
1318
1319
  /* remember that this code changes IFD and ICC Cert verification steps */
1320
1321
  /* select public key of ifd certificate and icc private key */
1322
0
  sc_log(ctx,
1323
0
         "Step 8.4.1.9: Send IFD pubk and ICC privk key references for Internal Auth");
1324
0
  res = provider->cwa_get_ifd_pubkey_ref(card, &buffer, &bufferlen);
1325
0
  if (res != SC_SUCCESS) {
1326
0
    msg = "Cannot get ifd public key reference from provider";
1327
0
    goto csc_end;
1328
0
  }
1329
0
  tlvlen = 0;
1330
0
  free(tlv);
1331
0
  tlv = calloc(10 + bufferlen, sizeof(u8));
1332
0
  if (!tlv) {
1333
0
    msg = "calloc error";
1334
0
    res = SC_ERROR_OUT_OF_MEMORY;
1335
0
    goto csc_end;
1336
0
  }
1337
0
  res = cwa_compose_tlv(card, 0x83, bufferlen, buffer, &tlv, &tlvlen);
1338
0
  if (res != SC_SUCCESS) {
1339
0
    msg = "Cannot compose tlv for setting ifd pubkey reference";
1340
0
    goto csc_end;
1341
0
  }
1342
0
  res = provider->cwa_get_icc_privkey_ref(card, &buffer, &bufferlen);
1343
0
  if (res != SC_SUCCESS) {
1344
0
    msg = "Cannot get icc private key reference from provider";
1345
0
    goto csc_end;
1346
0
  }
1347
  /* add this tlv to old one; do not call calloc */
1348
0
  res = cwa_compose_tlv(card, 0x84, bufferlen, buffer, &tlv, &tlvlen);
1349
0
  if (res != SC_SUCCESS) {
1350
0
    msg = "Cannot compose tlv for setting ifd pubkey reference";
1351
0
    goto csc_end;
1352
0
  }
1353
1354
0
  res = cwa_set_security_env(card, 0xC1, 0xA4, tlv, tlvlen);
1355
0
  if (res != SC_SUCCESS) {
1356
0
    msg = "Select CVC IFD pubk failed";
1357
0
    goto csc_end;
1358
0
  }
1359
1360
  /* Internal (Card) authentication (let the card verify sent ifd certs)
1361
     SN.IFD equals 8 lsb bytes of ifd.pubk ref according cwa14890 sec 8.4.1 */
1362
0
  sc_log(ctx, "Step 8.4.1.10: Perform Internal authentication");
1363
0
  res = provider->cwa_get_sn_ifd(card);
1364
0
  if (res != SC_SUCCESS) {
1365
0
    msg = "Cannot get ifd serial number from provider";
1366
0
    goto csc_end;
1367
0
  }
1368
  /* generate 8 random bytes */
1369
0
  if (RAND_bytes(sm->ifd.rnd, 8) != 1) {
1370
0
    msg = "Cannot generate random data";
1371
0
    res = SC_ERROR_INTERNAL;
1372
0
    goto csc_end;
1373
0
  }
1374
0
  memcpy(rndbuf, sm->ifd.rnd, 8); /* insert RND.IFD into rndbuf */
1375
0
  memcpy(rndbuf + 8, sm->ifd.sn, 8);  /* insert SN.IFD into rndbuf */
1376
0
  res = cwa_internal_auth(card, sig, 128, rndbuf, 16);
1377
0
  if (res != SC_SUCCESS) {
1378
0
    msg = "Internal auth cmd failed";
1379
0
    goto csc_end;
1380
0
  }
1381
1382
  /* retrieve ifd private key from provider */
1383
0
  res = provider->cwa_get_ifd_privkey(card, &ifd_privkey);
1384
0
  if (res != SC_SUCCESS) {
1385
0
    msg = "Cannot retrieve IFD private key from provider";
1386
0
    res = SC_ERROR_SM_NO_SESSION_KEYS;
1387
0
    goto csc_end;
1388
0
  }
1389
1390
  /* verify received signature */
1391
0
  sc_log(ctx, "Verify Internal Auth command response");
1392
0
  res = cwa_verify_internal_auth(card, icc_pubkey,  /* evaluated icc public key */
1393
0
               ifd_privkey, /* evaluated from DGP's Manual Annex 3 Data */
1394
0
               rndbuf,  /* RND.IFD || SN.IFD */
1395
0
               16,  /* rndbuf length; should be 16 */
1396
0
               sig, 128
1397
0
      );
1398
0
  if (res != SC_SUCCESS) {
1399
0
    msg = "Internal Auth Verify failed";
1400
0
    goto csc_end;
1401
0
  }
1402
1403
  /* get challenge: retrieve 8 random bytes from card */
1404
0
  sc_log(ctx, "Step 8.4.1.11: Prepare External Auth: Get Challenge");
1405
0
  res = sc_get_challenge(card, sm->icc.rnd, sizeof(sm->icc.rnd));
1406
0
  if (res != SC_SUCCESS) {
1407
0
    msg = "Get Challenge failed";
1408
0
    goto csc_end;
1409
0
  }
1410
1411
  /* compose signature data for external auth */
1412
0
  res = cwa_prepare_external_auth(card, icc_pubkey, ifd_privkey, sig, 128);
1413
0
  if (res != SC_SUCCESS) {
1414
0
    msg = "Prepare external auth failed";
1415
0
    goto csc_end;
1416
0
  }
1417
1418
  /* External (IFD)  authentication */
1419
0
  sc_log(ctx, "Step 8.4.1.12: Perform External (IFD) Authentication");
1420
0
  res = cwa_external_auth(card, sig, 128);
1421
0
  if (res != SC_SUCCESS) {
1422
0
    msg = "External auth cmd failed";
1423
0
    goto csc_end;
1424
0
  }
1425
1426
  /* Session key generation */
1427
0
  sc_log(ctx, "Step 8.4.2: Compute Session Keys");
1428
0
  res = cwa_compute_session_keys(card);
1429
0
  if (res != SC_SUCCESS) {
1430
0
    msg = "Session Key generation failed";
1431
0
    goto csc_end;
1432
0
  }
1433
1434
  /* call provider post-operation method */
1435
0
  sc_log(ctx, "CreateSecureChannel post-operations");
1436
0
  if (provider->cwa_create_post_ops) {
1437
0
    res = provider->cwa_create_post_ops(card, provider);
1438
0
    if (res != SC_SUCCESS) {
1439
0
      sc_log(ctx, "Create SM: provider post_ops() failed");
1440
0
      goto csc_end;
1441
0
    }
1442
0
  }
1443
1444
  /* arriving here means ok: cleanup */
1445
0
  res = SC_SUCCESS;
1446
0
 csc_end:
1447
0
  free(tlv);
1448
0
  X509_free(icc_cert);
1449
0
  X509_free(ca_cert);
1450
0
  EVP_PKEY_free(icc_pubkey);
1451
0
  EVP_PKEY_free(ifd_privkey);
1452
  /* setup SM state according result */
1453
0
  if (res != SC_SUCCESS) {
1454
0
    sc_log(ctx, "%s", msg);
1455
0
    card->sm_ctx.sm_mode = SM_MODE_NONE;
1456
0
  } else {
1457
0
    card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
1458
0
  }
1459
0
  LOG_FUNC_RETURN(ctx, res);
1460
0
}
1461
1462
/******************* SM internal APDU encoding / decoding functions ******/
1463
1464
/**
1465
 * Encode an APDU.
1466
 *
1467
 * Calling this functions means that It's has been verified
1468
 * That source apdu needs encoding
1469
 * Based on section 9 of CWA-14890 and Sect 6 of iso7816-4 standards
1470
 * And DNIe's manual
1471
 *
1472
 * @param card card info structure
1473
 * @param sm Secure Messaging state information
1474
 * @param from APDU to be encoded
1475
 * @param to where to store encoded apdu
1476
 * @return SC_SUCCESS if ok; else error code
1477
 */
1478
int cwa_encode_apdu(sc_card_t * card,
1479
        cwa_provider_t * provider, sc_apdu_t * from, sc_apdu_t * to)
1480
0
{
1481
0
  u8 *apdubuf = NULL;   /* to store resulting apdu */
1482
0
  size_t apdulen, tlv_len;
1483
0
  u8 *ccbuf = NULL;   /* where to store data to eval cryptographic checksum CC */
1484
0
  size_t cclen = 0;
1485
0
  u8 macbuf[8];   /* to store and compute CC */
1486
0
  char *msg = NULL;
1487
1488
0
  size_t i, j;    /* for xor loops */
1489
0
  int res = SC_SUCCESS;
1490
0
  sc_context_t *ctx = NULL;
1491
0
  struct sm_cwa_session * sm_session = &card->sm_ctx.info.session.cwa;
1492
0
  u8 *msgbuf = NULL; /* to encrypt apdu data */
1493
0
  u8 *cryptbuf = NULL;
1494
1495
0
  EVP_CIPHER_CTX *cctx = NULL;
1496
0
  EVP_CIPHER *alg = NULL;
1497
0
  unsigned char *key = NULL;
1498
0
  int tmplen = 0;
1499
1500
  /* mandatory check */
1501
0
  if (!card || !card->ctx || !provider)
1502
0
    return SC_ERROR_INVALID_ARGUMENTS;
1503
0
  ctx = card->ctx;
1504
1505
0
  LOG_FUNC_CALLED(ctx);
1506
  /* check remaining arguments */
1507
0
  if (!from || !to || !sm_session)
1508
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_SM_NOT_INITIALIZED);
1509
0
  if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT)
1510
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_SM_INVALID_LEVEL);
1511
1512
  /* reserve extra bytes for padding and tlv header */
1513
0
  msgbuf = calloc(12 + from->lc, sizeof(u8)); /* to encrypt apdu data */
1514
0
  cryptbuf = calloc(12 + from->lc, sizeof(u8));
1515
0
  if (!msgbuf || !cryptbuf) {
1516
0
    res = SC_ERROR_OUT_OF_MEMORY;
1517
0
    goto err;
1518
0
  }
1519
1520
  /* check if APDU is already encoded */
1521
0
  if ((from->cla & 0x0C) != 0) {
1522
0
    memcpy(to, from, sizeof(sc_apdu_t));
1523
0
    res = SC_SUCCESS; /* already encoded */
1524
0
    goto encode_end;
1525
0
  }
1526
0
  if (from->ins == 0xC0) {
1527
0
    memcpy(to, from, sizeof(sc_apdu_t));
1528
0
    res = SC_SUCCESS; /* dont encode GET Response cmd */
1529
0
    goto encode_end;
1530
0
  }
1531
1532
  /* trace APDU before encoding process */
1533
0
  cwa_trace_apdu(card, from, 0);
1534
1535
  /* reserve enough space for apdulen+tlv bytes
1536
   * to-be-crypted buffer and result apdu buffer */
1537
   /* TODO DEE add 4 more bytes for testing.... */
1538
0
  apdubuf = calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen),
1539
0
       sizeof(u8));
1540
0
  ccbuf = calloc(MAX(SC_MAX_APDU_BUFFER_SIZE, 20 + from->datalen),
1541
0
       sizeof(u8));
1542
  /* always create a new buffer for the encoded response */
1543
0
  to->resp = calloc(MAX_RESP_BUFFER_SIZE, sizeof(u8));
1544
0
  to->resplen = MAX_RESP_BUFFER_SIZE;
1545
0
  if (!apdubuf || !ccbuf || (!from->resp && !to->resp)) {
1546
0
    res = SC_ERROR_OUT_OF_MEMORY;
1547
0
    goto err;
1548
0
  }
1549
1550
  /* set up data on destination apdu */
1551
0
  to->cse = SC_APDU_CASE_4_SHORT;
1552
0
  to->cla = from->cla | 0x0C; /* mark apdu as encoded */
1553
0
  to->ins = from->ins;
1554
0
  to->p1 = from->p1;
1555
0
  to->p2 = from->p2;
1556
0
  to->le = from->le;
1557
0
  if (!to->le)
1558
0
    to->le = 255;
1559
0
  to->lc = 0;   /* to be evaluated */
1560
  /* fill buffer with header info */
1561
0
  *(ccbuf + cclen++) = to->cla;
1562
0
  *(ccbuf + cclen++) = to->ins;
1563
0
  *(ccbuf + cclen++) = to->p1;
1564
0
  *(ccbuf + cclen++) = to->p2;
1565
0
  cwa_iso7816_padding(ccbuf, &cclen); /* pad header (4 bytes pad) */
1566
1567
0
  if (!(cctx = EVP_CIPHER_CTX_new())) {
1568
0
    res = SC_ERROR_INTERNAL;
1569
0
    goto err;
1570
0
  }
1571
1572
  /* if no data, skip data encryption step */
1573
0
  if (from->lc != 0) {
1574
0
    unsigned char iv[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1575
0
    int dlen = (int)from->lc;
1576
0
    size_t len = dlen;
1577
1578
    /* pad message */
1579
0
    memcpy(msgbuf, from->data, dlen);
1580
0
    cwa_iso7816_padding(msgbuf, &len);
1581
0
    dlen = (int)len;
1582
1583
    /* start kriptbuff with iso padding indicator */
1584
0
    *cryptbuf = 0x01;
1585
0
    key = sm_session->session_enc;
1586
1587
0
    alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC");
1588
1589
0
    if (!alg ||
1590
0
        EVP_EncryptInit_ex(cctx, alg, NULL, key, iv) != 1 ||
1591
0
        EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 ||
1592
0
        EVP_EncryptUpdate(cctx, cryptbuf + 1, &dlen, msgbuf, dlen) != 1 ||
1593
0
        EVP_EncryptFinal_ex(cctx, cryptbuf + 1 + dlen, &tmplen) != 1) {
1594
0
      msg = "Error in encrypting APDU";
1595
0
      res = SC_ERROR_INTERNAL;
1596
0
      goto encode_end;
1597
0
    }
1598
0
    dlen += tmplen;
1599
1600
    /* compose data TLV and add to result buffer */
1601
0
    res = cwa_compose_tlv(card, 0x87, dlen + 1, cryptbuf, &ccbuf, &cclen);
1602
0
    if (res != SC_SUCCESS) {
1603
0
      msg = "Error in compose tag 8x87 TLV";
1604
0
      goto encode_end;
1605
0
    }
1606
0
  } else if ((0xff & from->le) > 0) {
1607
    /* if le byte is declared, compose and add Le TLV */
1608
    /* FIXME: For DNIe we must not send the le bytes
1609
       when le == 256 but this goes against the standard
1610
       and might break other cards reusing this code */
1611
    /* NOTE: In FNMT MultiPKCS11 code this is an if, i.e.,
1612
       the le is only sent if no data (lc) is set.
1613
       In DNIe 3.0 pin verification sending both TLV return
1614
       69 88 "SM Data Object incorrect". For the moment it is
1615
       fixed sendind le=0 in pin verification apdu */
1616
0
    u8 le = 0xff & from->le;
1617
0
    res = cwa_compose_tlv(card, 0x97, 1, &le, &ccbuf, &cclen);
1618
0
    if (res != SC_SUCCESS) {
1619
0
      msg = "Encode APDU compose_tlv(0x97) failed";
1620
0
      goto encode_end;
1621
0
    }
1622
0
  }
1623
  /* copy current data to apdu buffer (skip header and header padding) */
1624
0
  if (cclen < 8) {
1625
0
    res = SC_ERROR_INTERNAL;
1626
0
    msg = "Incorrect checksum length";
1627
0
    goto encode_end;
1628
0
  }
1629
0
  memcpy(apdubuf, ccbuf + 8, cclen - 8);
1630
0
  apdulen = cclen - 8;
1631
  /* pad again ccbuffer to compute CC */
1632
0
  cwa_iso7816_padding(ccbuf, &cclen);
1633
1634
  /* sc_log(ctx,"data to compose mac: %s",sc_dump_hex(ccbuf,cclen)); */
1635
  /* compute MAC Cryptographic Checksum using kmac and increased SSC */
1636
0
  res = cwa_increase_ssc(card); /* increase send sequence counter */
1637
0
  if (res != SC_SUCCESS) {
1638
0
    msg = "Error in computing SSC";
1639
0
    goto encode_end;
1640
0
  }
1641
1642
0
  memcpy(macbuf, sm_session->ssc, 8); /* start with computed SSC */
1643
1644
0
  tmplen = 0;
1645
0
  key = sm_session->session_mac;
1646
1647
0
  sc_evp_cipher_free(alg);
1648
0
  alg = sc_evp_cipher(card->ctx, "DES-ECB");
1649
0
  if (!alg ||
1650
0
      EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 ||
1651
0
      EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) {
1652
0
    msg = "Error in DES ECB encryption";
1653
0
    res = SC_ERROR_INTERNAL;
1654
0
    goto encode_end;
1655
0
  }
1656
1657
0
  for (i = 0; i < cclen; i += 8) { /* divide data in 8 byte blocks */
1658
    /* compute DES */
1659
0
    if (EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf , 8) != 1) {
1660
0
      msg = "Error in DES ECB encryption";
1661
0
      res = SC_ERROR_INTERNAL;
1662
0
      goto encode_end;
1663
0
    }
1664
    /* XOR with next data and repeat */
1665
0
    for (j = 0; j < 8; j++)
1666
0
      macbuf[j] ^= ccbuf[i + j];
1667
0
  }
1668
0
  if (EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) {
1669
0
    msg = "Error in DES ECB encryption";
1670
0
    res = SC_ERROR_INTERNAL;
1671
0
    goto encode_end;
1672
0
  }
1673
1674
  /* and apply 3DES to result */
1675
0
  sc_evp_cipher_free(alg);
1676
0
  alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB");
1677
1678
0
  if (!alg ||
1679
0
      EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 ||
1680
0
      EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 ||
1681
0
      EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 ||
1682
0
      EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) {
1683
0
    msg = "Error in 3DEC ECB encryption";
1684
0
    res = SC_ERROR_INTERNAL;
1685
0
    goto encode_end;
1686
0
  }
1687
1688
  /* compose and add computed MAC TLV to result buffer */
1689
0
  tlv_len = (card->atr.value[15] >= DNIE_30_VERSION)? 8 : 4;
1690
0
  sc_log(ctx, "Using TLV length: %"SC_FORMAT_LEN_SIZE_T"u", tlv_len);
1691
0
  res = cwa_compose_tlv(card, 0x8E, tlv_len, macbuf, &apdubuf, &apdulen);
1692
0
  if (res != SC_SUCCESS) {
1693
0
    msg = "Encode APDU compose_tlv(0x87) failed";
1694
0
    goto encode_end;
1695
0
  }
1696
1697
  /* rewrite resulting APDU */
1698
0
  to->lc = apdulen;
1699
0
  to->data = apdubuf;
1700
0
  to->datalen = apdulen;
1701
1702
  /* that's all folks */
1703
0
  res = SC_SUCCESS;
1704
0
  goto encode_end_apdu_valid;
1705
1706
0
err:
1707
0
encode_end:
1708
0
  free(apdubuf);
1709
0
  if (from->resp != to->resp) {
1710
0
    free(to->resp);
1711
0
    to->resp = NULL;
1712
0
  }
1713
0
encode_end_apdu_valid:
1714
0
  sc_evp_cipher_free(alg);
1715
0
  EVP_CIPHER_CTX_free(cctx);
1716
0
  if (msg) {
1717
0
    sc_log_openssl(ctx);
1718
0
    sc_log(ctx, "%s", msg);
1719
0
  }
1720
0
  free(msgbuf);
1721
0
  free(cryptbuf);
1722
0
  free(ccbuf);
1723
0
  LOG_FUNC_RETURN(ctx, res);
1724
0
}
1725
1726
/**
1727
 * Decode an APDU response.
1728
 *
1729
 * Calling this functions means that It's has been verified
1730
 * That apdu response comes in TLV encoded format and needs decoding
1731
 * Based on section 9 of CWA-14890 and Sect 6 of iso7816-4 standards
1732
 * And DNIe's manual
1733
 *
1734
 * @param card card info structure
1735
 * @param sm Secure Messaging state information
1736
 * @param from APDU with response to be decoded
1737
 * @param to where to store decoded apdu
1738
 * @return SC_SUCCESS if ok; else error code
1739
 */
1740
int cwa_decode_response(sc_card_t * card,
1741
      cwa_provider_t * provider,
1742
      sc_apdu_t * apdu)
1743
0
{
1744
0
  size_t i, j, tlv_len;
1745
0
  cwa_tlv_t tlv_array[4];
1746
0
  cwa_tlv_t *p_tlv = &tlv_array[0]; /* to store plain data (Tag 0x81) */
1747
0
  cwa_tlv_t *e_tlv = &tlv_array[1]; /* to store pad encoded data (Tag 0x87) */
1748
0
  cwa_tlv_t *m_tlv = &tlv_array[2]; /* to store mac CC (Tag 0x8E) */
1749
0
  cwa_tlv_t *s_tlv = &tlv_array[3]; /* to store sw1-sw2 status (Tag 0x99) */
1750
0
  u8 *buffer = NULL; /* buffer for data. pointers to this buffer are in tlv_array */
1751
0
  u8 *ccbuf = NULL; /* buffer for mac CC calculation */
1752
0
  size_t cclen = 0; /* ccbuf len */
1753
0
  u8 macbuf[8];   /* where to calculate mac */
1754
0
  size_t resplen = 0; /* respbuf length */
1755
0
  int res = SC_SUCCESS;
1756
0
  char *msg = NULL; /* to store error messages */
1757
0
  sc_context_t *ctx = NULL;
1758
0
  struct sm_cwa_session * sm_session = &card->sm_ctx.info.session.cwa;
1759
1760
0
  EVP_CIPHER_CTX *cctx = NULL;
1761
0
  EVP_CIPHER *alg = NULL;
1762
0
  unsigned char *key = NULL;
1763
0
  int tmplen = 0;
1764
1765
0
  if ((cctx = EVP_CIPHER_CTX_new()) == NULL) {
1766
0
    sc_log_openssl(ctx);
1767
0
    return SC_ERROR_INTERNAL;
1768
0
  }
1769
1770
  /* mandatory check */
1771
0
  if (!card || !card->ctx || !provider)
1772
0
    return SC_ERROR_INVALID_ARGUMENTS;
1773
0
  ctx = card->ctx;
1774
1775
0
  LOG_FUNC_CALLED(ctx);
1776
  /* check remaining arguments */
1777
0
  if ((apdu == NULL) || (sm_session == NULL))
1778
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_SM_NOT_INITIALIZED);
1779
0
  if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT)
1780
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_SM_INVALID_LEVEL);
1781
1782
  /* cwa14890 sect 9.3: check SW1 or SW2 for SM related errors */
1783
0
  if (apdu->sw1 == 0x69) {
1784
0
    if ((apdu->sw2 == 0x88) || (apdu->sw2 == 0x87)) {
1785
      /* configure the driver to re-establish the SM */
1786
0
      msg = "SM related errors in APDU response";
1787
0
      cwa_create_secure_channel(card, provider, CWA_SM_OFF);
1788
0
      res = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
1789
0
      goto response_decode_end;
1790
0
    }
1791
0
  }
1792
  /* if response is null/empty assume unencoded apdu */
1793
0
  if (!apdu->resp || (apdu->resplen == 0)) {
1794
0
    sc_log(ctx, "Empty APDU response: assume not cwa encoded");
1795
0
    return SC_SUCCESS;
1796
0
  }
1797
  /* checks if apdu response needs decoding by checking tags in response */
1798
0
  switch (*apdu->resp) {
1799
0
  case CWA_SM_PLAIN_TAG:
1800
0
  case CWA_SM_CRYPTO_TAG:
1801
0
  case CWA_SM_MAC_TAG:
1802
0
  case CWA_SM_LE_TAG:
1803
0
  case CWA_SM_STATUS_TAG:
1804
0
    break;    /* cwa tags found: continue decoding */
1805
0
  default:    /* else apdu response seems not to be cwa encoded */
1806
0
    sc_log(card->ctx, "APDU Response seems not to be cwa encoded");
1807
0
    return SC_SUCCESS; /* let process continue */
1808
0
  }
1809
1810
  /* parse response to find TLV's data and check results */
1811
0
  memset(tlv_array, 0, 4 * sizeof(cwa_tlv_t));
1812
  /* create buffer and copy data into */
1813
0
  buffer = calloc(apdu->resplen, sizeof(u8));
1814
0
  if (!buffer) {
1815
0
    msg = "Cannot allocate space for response buffer";
1816
0
    res = SC_ERROR_OUT_OF_MEMORY;
1817
0
    goto response_decode_end;
1818
0
  }
1819
0
  memcpy(buffer, apdu->resp, apdu->resplen);
1820
1821
0
  res = cwa_parse_tlv(card, buffer, apdu->resplen, tlv_array);
1822
0
  if (res != SC_SUCCESS) {
1823
0
    msg = "Error in TLV parsing";
1824
0
    goto response_decode_end;
1825
0
  }
1826
1827
  /* check consistency of received TLV's */
1828
0
  if (p_tlv->buf && e_tlv->buf) {
1829
0
    msg =
1830
0
        "Plain and Encoded data are mutually exclusive in apdu response";
1831
0
    res = SC_ERROR_INVALID_DATA;
1832
0
    goto response_decode_end;
1833
0
  }
1834
0
  if (!m_tlv->buf) {
1835
0
    msg = "No MAC TAG found in apdu response";
1836
0
    res = SC_ERROR_INVALID_DATA;
1837
0
    goto response_decode_end;
1838
0
  }
1839
0
  tlv_len = (card->atr.value[15] >= DNIE_30_VERSION)? 8 : 4;
1840
0
  if (m_tlv->len != tlv_len) {
1841
0
    msg = "Invalid MAC TAG Length";
1842
0
    res = SC_ERROR_INVALID_DATA;
1843
0
    goto response_decode_end;
1844
0
  }
1845
1846
  /* compose buffer to evaluate mac */
1847
1848
  /* reserve enough space for data+status+padding */
1849
0
  ccbuf =
1850
0
      calloc(e_tlv->buflen + s_tlv->buflen + p_tlv->buflen + 8,
1851
0
       sizeof(u8));
1852
0
  if (!ccbuf) {
1853
0
    msg = "Cannot allocate space for mac checking";
1854
0
    res = SC_ERROR_OUT_OF_MEMORY;
1855
0
    goto response_decode_end;
1856
0
  }
1857
  /* copy data into buffer */
1858
0
  cclen = 0;
1859
0
  if (e_tlv->buf) { /* encoded data */
1860
0
    memcpy(ccbuf, e_tlv->buf, e_tlv->buflen);
1861
0
    cclen = e_tlv->buflen;
1862
0
  }
1863
0
  if (p_tlv->buf) { /* plain data */
1864
0
    memcpy(ccbuf, p_tlv->buf, p_tlv->buflen);
1865
0
    cclen += p_tlv->buflen;
1866
0
  }
1867
0
  if (s_tlv->buf) { /* response status */
1868
0
    if (s_tlv->len != 2) {
1869
0
      msg = "Invalid SW TAG length";
1870
0
      res = SC_ERROR_INVALID_DATA;
1871
0
      goto response_decode_end;
1872
0
    }
1873
0
    memcpy(ccbuf + cclen, s_tlv->buf, s_tlv->buflen);
1874
0
    cclen += s_tlv->buflen;
1875
0
    apdu->sw1 = s_tlv->data[0];
1876
0
    apdu->sw2 = s_tlv->data[1];
1877
0
  }    /* if no response status tag, use sw1 and sw2 from apdu */
1878
  /* add iso7816 padding */
1879
0
  cwa_iso7816_padding(ccbuf, &cclen);
1880
1881
  /* evaluate mac by mean of kmac and increased SendSequence Counter SSC */
1882
1883
  /* increase SSC */
1884
0
  res = cwa_increase_ssc(card); /* increase send sequence counter */
1885
0
  if (res != SC_SUCCESS) {
1886
0
    msg = "Error in computing SSC";
1887
0
    goto response_decode_end;
1888
0
  }
1889
  /* set up key for mac computing */
1890
0
  key = sm_session->session_mac;
1891
1892
0
  alg = sc_evp_cipher(card->ctx, "DES-ECB");
1893
0
  if (!alg ||
1894
0
      EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 ||
1895
0
      EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) {
1896
0
    sc_log_openssl(ctx);
1897
0
    msg = "Error in DES ECB encryption";
1898
0
    res = SC_ERROR_INTERNAL;
1899
0
    goto response_decode_end;
1900
0
  }
1901
1902
0
  memcpy(macbuf, sm_session->ssc, 8); /* start with computed SSC */
1903
0
  for (i = 0; i < cclen; i += 8) { /* divide data in 8 byte blocks */
1904
    /* compute DES */
1905
0
    if (EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1) {
1906
0
      sc_log_openssl(ctx);
1907
0
      msg = "Error in DES ECB encryption";
1908
0
      res = SC_ERROR_INTERNAL;
1909
0
      goto response_decode_end;
1910
0
    }
1911
    /* XOR with data and repeat */
1912
0
    for (j = 0; j < 8; j++)
1913
0
      macbuf[j] ^= ccbuf[i + j];
1914
0
  }
1915
0
  if (EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) {
1916
0
    sc_log_openssl(ctx);
1917
0
    msg = "Error in DES ECB encryption";
1918
0
    res = SC_ERROR_INTERNAL;
1919
0
    goto response_decode_end;
1920
0
  }
1921
1922
  /* finally apply 3DES to result */
1923
0
  sc_evp_cipher_free(alg);
1924
0
  alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB");
1925
1926
0
  if (!alg ||
1927
0
      EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 ||
1928
0
      EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 ||
1929
0
      EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 ||
1930
0
      EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) {
1931
0
    sc_log_openssl(ctx);
1932
0
    msg = "Error in 3DEC ECB encryption";
1933
0
    res = SC_ERROR_INTERNAL;
1934
0
    goto response_decode_end;
1935
0
  }
1936
1937
  /* check evaluated mac with provided by apdu response */
1938
1939
0
  res = memcmp(m_tlv->data, macbuf, 4); /* check first 4 bytes */
1940
0
  if (res != 0) {
1941
0
    msg = "Error in MAC CC checking: value doesn't match";
1942
0
    res = SC_ERROR_SM_ENCRYPT_FAILED;
1943
0
    goto response_decode_end;
1944
0
  }
1945
1946
  /* allocate response buffer */
1947
0
  resplen = 10 + MAX(p_tlv->len, e_tlv->len); /* estimate response buflen */
1948
0
  if (apdu->resplen < resplen) {
1949
0
    msg = "Cannot allocate buffer to store response";
1950
0
    res = SC_ERROR_BUFFER_TOO_SMALL;
1951
0
    goto response_decode_end;
1952
0
  }
1953
0
  apdu->resplen = resplen;
1954
1955
  /* fill destination response apdu buffer with data */
1956
1957
  /* if plain data, just copy TLV data into apdu response */
1958
0
  if (p_tlv->buf) { /* plain data */
1959
0
    memcpy(apdu->resp, p_tlv->data, p_tlv->len);
1960
0
    apdu->resplen = p_tlv->len;
1961
0
  }
1962
1963
  /* if encoded data, decode and store into apdu response */
1964
0
  else if (e_tlv->buf) { /* encoded data */
1965
0
    unsigned char iv[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1966
0
    int dlen = (int)apdu->resplen;
1967
    /* check data len */
1968
0
    if ((e_tlv->len < 9) || ((e_tlv->len - 1) % 8) != 0) {
1969
0
      msg = "Invalid length for Encoded data TLV";
1970
0
      res = SC_ERROR_INVALID_DATA;
1971
0
      goto response_decode_end;
1972
0
    }
1973
    /* first byte is padding info; check value */
1974
0
    if (e_tlv->data[0] != 0x01) {
1975
0
      msg = "Encoded TLV: Invalid padding info value";
1976
0
      res = SC_ERROR_INVALID_DATA;
1977
0
      goto response_decode_end;
1978
0
    }
1979
    /* prepare keys to decode */
1980
0
    key = sm_session->session_enc;
1981
1982
    /* decrypt into response buffer
1983
     * by using 3DES CBC by mean of kenc and iv={0,...0} */
1984
0
    sc_evp_cipher_free(alg);
1985
0
    alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC");
1986
1987
0
    if (!alg ||
1988
0
        EVP_DecryptInit_ex(cctx, alg, NULL, key, iv) != 1 ||
1989
0
        EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 ||
1990
0
        EVP_DecryptUpdate(cctx, apdu->resp, &dlen, &e_tlv->data[1], (int)(e_tlv->len - 1)) != 1 ||
1991
0
        EVP_DecryptFinal_ex(cctx, apdu->resp + dlen, &tmplen) != 1) {
1992
0
      sc_log_openssl(ctx);
1993
0
      res = SC_ERROR_INTERNAL;
1994
0
      msg = "Can not decrypt 3DES CBC";
1995
0
      goto response_decode_end;
1996
0
    }
1997
0
    apdu->resplen = dlen + tmplen;
1998
1999
    /* remove iso padding from response length */
2000
0
    for (; (apdu->resplen > 0) && *(apdu->resp + apdu->resplen - 1) == 0x00; apdu->resplen--) ;  /* empty loop */
2001
2002
0
    if (*(apdu->resp + apdu->resplen - 1) != 0x80) { /* check padding byte */
2003
0
      msg = "Decrypted TLV has no 0x80 iso padding indicator!";
2004
0
      res = SC_ERROR_INVALID_DATA;
2005
0
      goto response_decode_end;
2006
0
    }
2007
    /* everything ok: remove ending 0x80 from response */
2008
0
    apdu->resplen--;
2009
0
  }
2010
2011
0
  else
2012
0
    apdu->resplen = 0; /* neither plain, nor encoded data */
2013
2014
  /* that's all folks */
2015
0
  res = SC_SUCCESS;
2016
2017
0
 response_decode_end:
2018
0
  sc_evp_cipher_free(alg);
2019
0
  EVP_CIPHER_CTX_free(cctx);
2020
0
  free(buffer);
2021
0
  free(ccbuf);
2022
0
  if (msg) {
2023
0
    sc_log(ctx, "%s", msg);
2024
0
  } else {
2025
0
    cwa_trace_apdu(card, apdu, 1);
2026
0
  }      /* trace apdu response */
2027
0
  LOG_FUNC_RETURN(ctx, res);
2028
0
}
2029
2030
/********************* default provider for cwa14890 ****************/
2031
2032
/* pre and post operations */
2033
2034
static int default_create_pre_ops(sc_card_t * card, cwa_provider_t * provider)
2035
0
{
2036
0
  return SC_SUCCESS;
2037
0
}
2038
2039
static int default_create_post_ops(sc_card_t * card, cwa_provider_t * provider)
2040
0
{
2041
0
  return SC_SUCCESS;
2042
0
}
2043
2044
static int default_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key)
2045
0
{
2046
0
  return SC_ERROR_NOT_SUPPORTED;
2047
0
}
2048
2049
/* retrieve CVC intermediate CA certificate and length */
2050
static int default_get_cvc_ca_cert(sc_card_t * card, u8 ** cert,
2051
           size_t * length)
2052
0
{
2053
0
  return SC_ERROR_NOT_SUPPORTED;
2054
0
}
2055
2056
/* retrieve CVC IFD certificate and length */
2057
static int default_get_cvc_ifd_cert(sc_card_t * card, u8 ** cert,
2058
            size_t * length)
2059
0
{
2060
0
  return SC_ERROR_NOT_SUPPORTED;
2061
0
}
2062
2063
static int default_get_ifd_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey)
2064
0
{
2065
0
  return SC_ERROR_NOT_SUPPORTED;
2066
0
}
2067
2068
/* get ICC intermediate CA  path */
2069
static int default_get_icc_intermediate_ca_cert(sc_card_t * card, X509 ** cert)
2070
0
{
2071
0
  return SC_ERROR_NOT_SUPPORTED;
2072
0
}
2073
2074
/* get ICC certificate path */
2075
static int default_get_icc_cert(sc_card_t * card, X509 ** cert)
2076
0
{
2077
0
  return SC_ERROR_NOT_SUPPORTED;
2078
0
}
2079
2080
/* Retrieve key reference for Root CA to validate CVC intermediate CA certs */
2081
static int default_get_root_ca_pubkey_ref(sc_card_t * card, u8 ** buf,
2082
            size_t * len)
2083
0
{
2084
0
  return SC_ERROR_NOT_SUPPORTED;
2085
0
}
2086
2087
/* Retrieve key reference for intermediate CA to validate IFD certs */
2088
static int default_get_intermediate_ca_pubkey_ref(sc_card_t * card, u8 ** buf,
2089
              size_t * len)
2090
0
{
2091
0
  return SC_ERROR_NOT_SUPPORTED;
2092
0
}
2093
2094
/* Retrieve key reference for IFD certificate */
2095
static int default_get_ifd_pubkey_ref(sc_card_t * card, u8 ** buf, size_t * len)
2096
0
{
2097
0
  return SC_ERROR_NOT_SUPPORTED;
2098
0
}
2099
2100
/* Retrieve key reference for ICC privkey */
2101
static int default_get_icc_privkey_ref(sc_card_t * card, u8 ** buf,
2102
               size_t * len)
2103
0
{
2104
0
  return SC_ERROR_NOT_SUPPORTED;
2105
0
}
2106
2107
/* Retrieve SN.IFD (8 bytes left padded with zeroes if needed) */
2108
static int default_get_sn_ifd(sc_card_t * card)
2109
0
{
2110
0
  return SC_ERROR_NOT_SUPPORTED;
2111
0
}
2112
2113
/* Retrieve SN.ICC (8 bytes left padded with zeroes if needed) */
2114
static int default_get_sn_icc(sc_card_t * card)
2115
0
{
2116
0
  return SC_ERROR_NOT_SUPPORTED;
2117
0
}
2118
2119
static cwa_provider_t default_cwa_provider = {
2120
2121
    /************ data related with SM operations *************************/
2122
2123
    /************ operations related with secure channel creation *********/
2124
2125
  /* pre and post operations */
2126
  default_create_pre_ops,
2127
  default_create_post_ops,
2128
2129
  /* Get ICC intermediate CA  path */
2130
  default_get_icc_intermediate_ca_cert,
2131
  /* Get ICC certificate path */
2132
  default_get_icc_cert,
2133
2134
  /* Obtain RSA public key from RootCA */
2135
  default_get_root_ca_pubkey,
2136
  /* Obtain RSA IFD private key */
2137
  default_get_ifd_privkey,
2138
2139
  /* Retrieve CVC intermediate CA certificate and length */
2140
  default_get_cvc_ca_cert,
2141
  /* Retrieve CVC IFD certificate and length */
2142
  default_get_cvc_ifd_cert,
2143
2144
  /* Get public key references for Root CA to validate intermediate CA cert */
2145
  default_get_root_ca_pubkey_ref,
2146
2147
  /* Get public key reference for IFD intermediate CA certificate */
2148
  default_get_intermediate_ca_pubkey_ref,
2149
2150
  /* Get public key reference for IFD CVC certificate */
2151
  default_get_ifd_pubkey_ref,
2152
2153
  /* Get ICC private key reference */
2154
  default_get_icc_privkey_ref,
2155
2156
  /* Get IFD Serial Number */
2157
  default_get_sn_ifd,
2158
2159
  /* Get ICC Serial Number */
2160
  default_get_sn_icc,
2161
2162
2163
};
2164
2165
/**
2166
 * Get a copy of default cwa provider.
2167
 *
2168
 * @param card pointer to card info structure
2169
 * @return copy of default provider or null on error
2170
 */
2171
cwa_provider_t *cwa_get_default_provider(sc_card_t * card)
2172
487
{
2173
487
  cwa_provider_t *res = NULL;
2174
487
  if (!card || !card->ctx)
2175
0
    return NULL;
2176
487
  LOG_FUNC_CALLED(card->ctx);
2177
487
  res = calloc(1, sizeof(cwa_provider_t));
2178
487
  if (!res) {
2179
0
    sc_log(card->ctx, "Cannot allocate space for cwa_provider");
2180
0
    return NULL;
2181
0
  }
2182
487
  memcpy(res, &default_cwa_provider, sizeof(cwa_provider_t));
2183
487
  return res;
2184
487
}
2185
2186
/* end of cwa14890.c */
2187
#undef __CWA14890_C__
2188
2189
#endif        /* ENABLE_OPENSSL */