Coverage Report

Created: 2026-08-31 06:12

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 "asn1.h"
37
#include "opensc.h"
38
#include "cardctl.h"
39
#include "internal.h"
40
#include <openssl/rsa.h>
41
#include <openssl/bn.h>
42
#include <openssl/x509.h>
43
#include <openssl/des.h>
44
#include <openssl/rand.h>
45
#include "cwa14890.h"
46
#include "cwa-dnie.h"
47
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
48
# include <openssl/core_names.h>
49
# include <openssl/param_build.h>
50
# include <openssl/provider.h>
51
#endif
52
53
0
#define MAX_RESP_BUFFER_SIZE 2048
54
55
/**
56
 * Structure used to compose BER-TLV encoded data
57
 * according to iso7816-4 sect 5.2.2.
58
 *
59
 * Notice that current implementation does not handle properly
60
 * multibyte tag id. Just assume that tag is 1-byte length
61
 * Also, encodings for data length longer than 0x01000000 bytes
62
 * are not supported (tag 0x84)
63
 */
64
typedef struct cwa_tlv_st {
65
        u8 *buf;                /** local copy of TLV byte array */
66
        size_t buflen;          /** length of buffer */
67
        unsigned int tag;       /** tag ID */
68
        size_t len;             /** length of data field */
69
        u8 *data;               /** pointer to start of data in buf buffer */
70
} cwa_tlv_t;
71
72
/*********************** utility functions ************************/
73
74
/**
75
 * Dump an APDU before SM translation.
76
 *
77
 * This is mainly for debugging purposes. programmer should disable
78
 * this function in a production environment, as APDU will be shown
79
 * in text-plain on debug traces
80
 *
81
 * @param card Pointer to card driver data structure
82
 * @param apdu APDU to be encoded, or APDU response after decoded
83
 * @param flag 0: APDU is to be encoded: 1; APDU decoded response
84
 */
85
static void cwa_trace_apdu(sc_card_t * card, sc_apdu_t * apdu, int flag)
86
0
{
87
0
  char buf[2048];
88
0
  if (!card || !card->ctx || !apdu || card->ctx->debug < SC_LOG_DEBUG_NORMAL)
89
0
    return;
90
0
  if (flag == 0) { /* apdu command */
91
0
    if (apdu->datalen > 0) { /* apdu data to show */
92
0
      sc_hex_dump(apdu->data, apdu->datalen, buf, sizeof(buf));
93
0
      sc_log(card->ctx,
94
0
          "\nAPDU before encode: ==================================================\n"
95
0
          "CLA: %02X INS: %02X P1: %02X P2: %02X Lc: %02zX Le: %02zX DATA: [%5zu bytes]\n"
96
0
          "%s======================================================================\n",
97
0
          apdu->cla, apdu->ins, apdu->p1, apdu->p2,
98
0
          apdu->lc, apdu->le, apdu->datalen, buf);
99
0
    } else { /* apdu data field is empty */
100
0
      sc_log(card->ctx,
101
0
          "\nAPDU before encode: ==================================================\n"
102
0
          "CLA: %02X INS: %02X P1: %02X P2: %02X Lc: %02zX Le: %02zX (NO DATA)\n"
103
0
          "======================================================================\n",
104
0
          apdu->cla, apdu->ins, apdu->p1, apdu->p2,
105
0
          apdu->lc, apdu->le);
106
0
    }
107
0
  } else {   /* apdu response */
108
0
    sc_hex_dump(apdu->resp, apdu->resplen, buf, sizeof(buf));
109
0
    sc_log(card->ctx,
110
0
        "\nAPDU response after decode: ==========================================\n"
111
0
        "SW1: %02X SW2: %02X RESP: [%5zu bytes]\n"
112
0
        "%s======================================================================\n",
113
0
        apdu->sw1, apdu->sw2, apdu->resplen, buf);
114
0
  }
115
0
}
116
117
/**
118
 * Increase send sequence counter SSC.
119
 *
120
 * @param card smart card info structure
121
 * @return SC_SUCCESS if ok; else error code
122
 *
123
 * TODO: to further study: what about using bignum arithmetic?
124
 */
125
static int cwa_increase_ssc(sc_card_t * card)
126
0
{
127
0
  int n;
128
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
129
130
  /* preliminary checks */
131
0
  if (!card || !card->ctx )
132
0
    return SC_ERROR_INVALID_ARGUMENTS;
133
0
  LOG_FUNC_CALLED(card->ctx);
134
  /* u8 arithmetic; exit loop if no carry */
135
0
  sc_log(card->ctx, "Curr SSC: '%s'", sc_dump_hex(sm->ssc, 8));
136
0
  for (n = 7; n >= 0; n--) {
137
0
    sm->ssc[n]++;
138
0
    if ((sm->ssc[n]) != 0x00)
139
0
      break;
140
0
  }
141
0
  sc_log(card->ctx, "Next SSC: '%s'", sc_dump_hex(sm->ssc, 8));
142
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
143
0
}
144
145
/**
146
 * ISO 7816 padding.
147
 *
148
 * Adds an 0x80 at the end of buffer and as many zeroes to get len
149
 * multiple of 8
150
 * Buffer must be long enough to store additional bytes
151
 *
152
 * @param buffer where to compose data
153
 * @param len pointer to buffer length
154
 */
155
static void cwa_iso7816_padding(u8 * buf, size_t * buflen)
156
0
{
157
0
  buf[*buflen] = 0x80;
158
0
  (*buflen)++;
159
0
  for (; *buflen & 0x07; (*buflen)++)
160
0
    buf[*buflen] = 0x00;
161
0
}
162
163
/**
164
 * compose a BER-TLV data in provided buffer.
165
 *
166
 * Multibyte tag id are not supported
167
 * Also multibyte id 0x84 is unhandled
168
 *
169
 * Notice that TLV is composed starting at offset length from
170
 * the buffer. Consecutive calls to cwa_add_tlv, appends a new
171
 * TLV at the end of the buffer
172
 *
173
 * @param card card info structure
174
 * @param tag tag id
175
 * @param len data length
176
 * @param value data buffer
177
 * @param out pointer to dest data
178
 * @param outlen length of composed tlv data
179
 * @return SC_SUCCESS if ok; else error
180
 */
181
static int cwa_compose_tlv(sc_card_t * card,
182
         u8 tag,
183
         size_t len, u8 * data, u8 ** out, size_t * outlen)
184
0
{
185
0
  u8 *pt;
186
0
  size_t size;
187
0
  sc_context_t *ctx;
188
  /* preliminary checks */
189
0
  if (!card || !card->ctx || !out || !outlen)
190
0
    return SC_ERROR_INVALID_ARGUMENTS;
191
  /* commodity vars */
192
0
  ctx = card->ctx;
193
194
0
  LOG_FUNC_CALLED(ctx);
195
0
  pt = *out;
196
0
  size = *outlen;
197
198
  /* assume tag id is not multibyte */
199
0
  *(pt + size++) = tag;
200
  /* evaluate tag length value according iso7816-4 sect 5.2.2 */
201
0
  if (len < 0x80) {
202
0
    *(pt + size++) = len;
203
0
  } else if (len < 0x00000100) {
204
0
    *(pt + size++) = 0x81;
205
0
    *(pt + size++) = 0xff & len;
206
0
  } else if (len < 0x00010000) {
207
0
    *(pt + size++) = 0x82;
208
0
    *(pt + size++) = 0xff & (len >> 8);
209
0
    *(pt + size++) = 0xff & len;
210
0
  } else if (len < 0x01000000) {
211
0
    *(pt + size++) = 0x83;
212
0
    *(pt + size++) = 0xff & (len >> 16);
213
0
    *(pt + size++) = 0xff & (len >> 8);
214
0
    *(pt + size++) = 0xff & len;
215
0
  } else {   /* do not handle tag length 0x84 */
216
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
217
0
  }
218
  /* copy remaining data to buffer */
219
0
  if (len != 0)
220
0
    memcpy(pt + size, data, len);
221
0
  size += len;
222
0
  *outlen = size;
223
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
224
0
}
225
226
/**
227
 * Parse and APDU Response and extract specific BER-TLV data.
228
 *
229
 * NOTICE that iso7816 sect 5.2.2 states that Tag length may be 1 to n bytes
230
 * length. In this code we'll assume always tag length = 1 byte
231
 *
232
 * FIXME use `sc_asn1_read_tag` or similar instead
233
 *
234
 * @param card card info structure
235
 * @param data Buffer to look for tlv into
236
 * @param datalen Buffer len
237
 * @param tlv  array of TLV structure to store results into
238
 * @return SC_SUCCESS if OK; else error code
239
 */
240
static int cwa_parse_tlv(sc_card_t * card,
241
       u8 * buffer, size_t datalen,
242
       cwa_tlv_t tlv_array[]
243
    )
244
0
{
245
0
  const u8 *p = buffer;
246
0
  size_t left = datalen;
247
0
  sc_context_t *ctx = NULL;
248
249
  /* preliminary checks */
250
0
  if (!card || !card->ctx)
251
0
    return SC_ERROR_INVALID_ARGUMENTS;
252
  /* commodity vars */
253
0
  ctx = card->ctx;
254
255
0
  LOG_FUNC_CALLED(ctx);
256
0
  if (!tlv_array)
257
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
258
259
0
  while (left > 0) {
260
0
    unsigned int cla = 0, tag_val = 0;
261
0
    size_t tag_len = 0, header_len;
262
0
    const u8 *tlv_start = p;
263
0
    cwa_tlv_t *tlv = NULL;
264
0
    u8 raw_tag;
265
266
0
    int r = sc_asn1_read_tag(&p, left, &cla, &tag_val, &tag_len);
267
0
    if (r != SC_SUCCESS) {
268
0
      sc_log(ctx, "Failed to parse ASN.1 tag");
269
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
270
0
    }
271
272
0
    header_len = (p - tlv_start);
273
0
    left -= header_len;
274
275
0
    raw_tag = (cla | tag_val);
276
0
    switch (raw_tag) {
277
0
    case CWA_SM_PLAIN_TAG:
278
0
      tlv = &tlv_array[0];
279
0
      break;  /* 0x81 Plain  */
280
0
    case CWA_SM_CRYPTO_TAG:
281
0
      tlv = &tlv_array[1];
282
0
      break;  /* 0x87 Crypto */
283
0
    case CWA_SM_MAC_TAG:
284
0
      tlv = &tlv_array[2];
285
0
      break;  /* 0x8E MAC CC */
286
0
    case CWA_SM_STATUS_TAG:
287
0
      tlv = &tlv_array[3];
288
0
      break;  /* 0x99 Status */
289
0
    default:  /* CWA_SM_LE_TAG (0x97) is not valid here */
290
0
      sc_log(ctx, "Invalid TLV Tag type: '0x%02X'", raw_tag);
291
0
      LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
292
0
    }
293
0
    tlv->buf = (u8 *)tlv_start;
294
0
    tlv->tag = raw_tag;
295
0
    tlv->len = tag_len;
296
0
    tlv->data = (u8 *)p;
297
0
    tlv->buflen = header_len + tag_len;
298
0
    sc_log(ctx, "Found Tag: '0x%02X': Length: '%zu' Value:\n%s",
299
0
        tlv->tag, tlv->len, sc_dump_hex(tlv->data, tlv->len));
300
    /* set index to next Tag to jump to */
301
0
    p += tag_len;
302
0
    left -= tag_len;
303
0
  }
304
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);  /* mark no error */
305
0
}
306
307
/*********************** authentication routines *******************/
308
309
/**
310
 * Verify certificates provided by card.
311
 *
312
 * This routine uses Root CA public key data From Annex III of manual
313
 * to verify intermediate CA icc certificate provided by card
314
 * if verify success, then extract public keys from intermediate CA
315
 * and verify icc certificate
316
 *
317
 * @param card pointer to sc_card_contex
318
 * @param sub_ca_cert icc intermediate CA certificate read from card
319
 * @param icc_ca icc certificate from card
320
 * @return SC_SUCCESS if verification is ok; else error code
321
 */
322
static int cwa_verify_icc_certificates(sc_card_t * card,
323
               cwa_provider_t * provider,
324
               X509 * sub_ca_cert, X509 * icc_cert)
325
0
{
326
0
  char *msg = NULL;
327
0
  int res = SC_SUCCESS;
328
0
  EVP_PKEY *root_ca_key = NULL;
329
0
  EVP_PKEY *sub_ca_key = NULL;
330
0
  sc_context_t *ctx = NULL;
331
332
  /* safety check */
333
0
  if (!card || !card->ctx || !provider)
334
0
    return SC_ERROR_INVALID_ARGUMENTS;
335
0
  ctx = card->ctx;
336
0
  LOG_FUNC_CALLED(ctx);
337
0
  if (!sub_ca_cert || !icc_cert) /* check received arguments */
338
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
339
340
  /* retrieve root ca pkey from provider */
341
0
  res = provider->cwa_get_root_ca_pubkey(card, &root_ca_key);
342
0
  if (res != SC_SUCCESS) {
343
0
    msg = "Cannot get root CA public key";
344
0
    res = SC_ERROR_INTERNAL;
345
0
    goto verify_icc_certificates_end;
346
0
  }
347
348
  /* verify sub_ca_cert against root_ca_key */
349
0
  res = X509_verify(sub_ca_cert, root_ca_key);
350
0
  if (!res) {
351
0
    sc_log_openssl(ctx);
352
0
    msg = "Cannot verify icc Sub-CA certificate";
353
0
    res = SC_ERROR_SM_AUTHENTICATION_FAILED;
354
0
    goto verify_icc_certificates_end;
355
0
  }
356
357
  /* extract sub_ca_key from sub_ca_cert */
358
0
  if (!(sub_ca_key = X509_get_pubkey(sub_ca_cert))) {
359
0
    sc_log_openssl(ctx);
360
0
    msg = "Cannot extract public key icc Sub-CA certificate";
361
0
    res = SC_ERROR_INTERNAL;
362
0
    goto verify_icc_certificates_end;
363
0
  }
364
365
  /* verify icc_cert against sub_ca_key */
366
0
  res = X509_verify(icc_cert, sub_ca_key);
367
0
  if (!res) {
368
0
    sc_log_openssl(ctx);
369
0
    msg = "Cannot verify icc certificate";
370
0
    res = SC_ERROR_SM_AUTHENTICATION_FAILED;
371
0
    goto verify_icc_certificates_end;
372
0
  }
373
374
  /* arriving here means certificate verification success */
375
0
  res = SC_SUCCESS;
376
0
 verify_icc_certificates_end:
377
0
  if (root_ca_key)
378
0
    EVP_PKEY_free(root_ca_key);
379
0
  if (sub_ca_key)
380
0
    EVP_PKEY_free(sub_ca_key);
381
0
  if (res != SC_SUCCESS) {
382
0
    sc_log(ctx, "%s", msg);
383
0
  }
384
0
  LOG_FUNC_RETURN(ctx, res);
385
0
}
386
387
/**
388
 * Verify CVC certificates in SM establishment process.
389
 *
390
 * This is done by mean of 00 2A 00 AE
391
 * (Perform Security Operation: Verify Certificate )
392
 *
393
 * @param card pointer to card data
394
 * @param cert Certificate in CVC format
395
 * @param len  length of CVC certificate
396
 * @return SC_SUCCESS if ok; else error code
397
 */
398
static int cwa_verify_cvc_certificate(sc_card_t * card,
399
              const u8 * cert, size_t len)
400
0
{
401
0
  sc_apdu_t apdu;
402
0
  int result = SC_SUCCESS;
403
0
  sc_context_t *ctx = NULL;
404
405
  /* safety check */
406
0
  if (!card || !card->ctx)
407
0
    return SC_ERROR_INVALID_ARGUMENTS;
408
0
  ctx = card->ctx;
409
0
  LOG_FUNC_CALLED(ctx);
410
0
  if (!cert || (len <= 0)) /* check received arguments */
411
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
412
413
  /* compose apdu for Perform Security Operation (Verify cert) cmd */
414
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x00, 0xAE, 0, len,
415
0
          NULL, 0, cert, len);
416
417
  /* send composed apdu and parse result */
418
0
  result = sc_transmit_apdu(card, &apdu);
419
0
  LOG_TEST_RET(ctx, result, "Verify CVC certificate failed");
420
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
421
0
  LOG_FUNC_RETURN(ctx, result);
422
0
}
423
424
/**
425
 * Alternate implementation for set_security environment.
426
 *
427
 * Used to handle raw apdu data in set_security_env() on SM establishment
428
 * Standard set_security_env() method has sc_security_env->buffer limited
429
 * to 8 bytes; so cannot send some of required SM commands.
430
 *
431
 * @param card pointer to card data
432
 * @param p1 apdu P1 parameter
433
 * @param p2 apdu P2 parameter
434
 * @param buffer raw data to be inserted in apdu
435
 * @param length size of buffer
436
 * @return SC_SUCCESS if ok; else error code
437
 */
438
static int cwa_set_security_env(sc_card_t * card,
439
        u8 p1, u8 p2, u8 * buffer, size_t length)
440
0
{
441
0
  sc_apdu_t apdu;
442
0
  int result = SC_SUCCESS;
443
0
  sc_context_t *ctx = NULL;
444
445
  /* safety check */
446
0
  if (!card || !card->ctx)
447
0
    return SC_ERROR_INVALID_ARGUMENTS;
448
0
  ctx = card->ctx;
449
0
  LOG_FUNC_CALLED(ctx);
450
0
  if (!buffer || (length <= 0)) /* check received arguments */
451
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
452
453
  /* compose apdu for Manage Security Environment cmd */
454
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, p1, p2, 0, length,
455
0
          NULL, 0, buffer, length);
456
457
  /* send composed apdu and parse result */
458
0
  result = sc_transmit_apdu(card, &apdu);
459
0
  LOG_TEST_RET(ctx, result, "SM Set Security Environment failed");
460
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
461
0
  LOG_FUNC_RETURN(ctx, result);
462
0
}
463
464
/**
465
 * SM internal authenticate.
466
 *
467
 * Internal (Card) authentication (let the card verify sent ifd certs)
468
 *
469
 * @param card pointer to card data
470
 * @param sig signature buffer
471
 * @param dig_len signature buffer length
472
 * @param data data to be sent in apdu
473
 * @param datalen length of data to send
474
 * @return SC_SUCCESS if OK: else error code
475
 */
476
static int cwa_internal_auth(sc_card_t * card, u8 * sig, size_t sig_len, u8 * data, size_t datalen)
477
0
{
478
0
  sc_apdu_t apdu;
479
0
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
480
0
  int result = SC_SUCCESS;
481
0
  sc_context_t *ctx = NULL;
482
483
  /* safety check */
484
0
  if (!card || !card->ctx)
485
0
    return SC_ERROR_INVALID_ARGUMENTS;
486
0
  ctx = card->ctx;
487
0
  LOG_FUNC_CALLED(ctx);
488
0
  if (!data || (datalen <= 0)) /* check received arguments */
489
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
490
491
  /* compose apdu for Internal Authenticate cmd */
492
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0x00, 0x00, 0x80, datalen,
493
0
          rbuf, sizeof(rbuf), data, datalen);
494
495
  /* send composed apdu and parse result */
496
0
  result = sc_transmit_apdu(card, &apdu);
497
0
  LOG_TEST_RET(ctx, result, "SM internal auth failed");
498
499
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
500
0
  LOG_TEST_RET(ctx, result, "SM internal auth invalid response");
501
502
0
  if (apdu.resplen != sig_len) /* invalid number of bytes received */
503
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
504
0
  memcpy(sig, apdu.resp, apdu.resplen); /* copy result to buffer */
505
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
506
0
}
507
508
/**
509
 * Compose signature data for external auth according CWA-14890.
510
 *
511
 * This code prepares data to be sent to ICC for external
512
 * authentication procedure
513
 *
514
 * Store resulting data  into sm->sig
515
 *
516
 * @param card pointer to st_card_t card data information
517
 * @param icc_pubkey public key of card
518
 * @param ifd_privkey private key of ifd
519
 * @param sn_icc card serial number
520
 * @param sig signature buffer
521
 * @param sig_len signature buffer length
522
 * @return SC_SUCCESS if ok; else errorcode
523
 */
524
static int cwa_prepare_external_auth(sc_card_t * card,
525
             EVP_PKEY *icc_pubkey,
526
             EVP_PKEY *ifd_privkey,
527
             u8 * sig,
528
             size_t sig_len)
529
0
{
530
  /* we have to compose following message:
531
     data = E[PK.ICC.AUT](SIGMIN)
532
     SIGMIN = min ( SIG, N.IFD-SIG )
533
     SIG= DS[SK.IFD.AUT] (
534
     0x6A  || - padding according iso 9796-2
535
     PRND2 || - (74 bytes) random data to make buffer 128 bytes length
536
     Kifd  || - (32 bytes)- ifd random generated key
537
     sha1_hash(
538
     PRND2   ||
539
     Kifd    ||
540
     RND.ICC || - (8 bytes) response to get_challenge() cmd
541
     SN.ICC  - (8 bytes) serial number from get_serialnr() cmd
542
     ) ||
543
     0xBC - iso 9796-2 padding
544
     ) - total: 128 bytes
545
546
     then, we should encrypt with our private key and then with icc pub key
547
     returning resulting data
548
   */
549
0
  char *msg = NULL;   /* to store error messages */
550
0
  int res = SC_SUCCESS;
551
0
  u8 *buf1 = NULL;   /* where to encrypt with icc pub key */
552
0
  u8 *buf2 = NULL;   /* where to encrypt with ifd pub key */
553
0
  u8 *buf3 = NULL;   /* where to compose message to be encrypted */
554
0
  size_t len1 = 128, len2 = 128, len3 = 128;
555
0
  u8 *sha_buf = NULL;   /* to compose message to be sha'd */
556
0
  u8 *sha_data = NULL;   /* sha signature data */
557
0
  BIGNUM *bn = NULL;
558
0
  BIGNUM *bnsub = NULL;
559
0
  BIGNUM *bnres = NULL;
560
0
  sc_context_t *ctx = NULL;
561
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
562
0
  EVP_PKEY_CTX *pctx = NULL;
563
564
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
565
0
  const BIGNUM *ifd_privkey_n = NULL;
566
0
  const RSA *rsa_ifd_privkey = EVP_PKEY_get0_RSA(ifd_privkey);
567
0
  if (!rsa_ifd_privkey) {
568
0
    res = SC_ERROR_INTERNAL;
569
0
    msg = "Can not extract RSA object ifd priv";
570
0
    goto prepare_external_auth_end;
571
0
  }
572
#else
573
  BIGNUM *ifd_privkey_n = NULL;
574
#endif
575
576
  /* safety check */
577
0
  if (!card || !card->ctx)
578
0
    return SC_ERROR_INVALID_ARGUMENTS;
579
0
  ctx = card->ctx;
580
0
  LOG_FUNC_CALLED(ctx);
581
  /* check received arguments */
582
0
  if (!icc_pubkey || !ifd_privkey || !sm)
583
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
584
0
  buf1 = calloc(128, sizeof(u8));
585
0
  buf2 = calloc(128, sizeof(u8));
586
0
  buf3 = calloc(128, sizeof(u8));
587
0
  sha_buf = calloc(74 + 32 + 8 + 8, sizeof(u8));
588
0
  sha_data = calloc(SHA_DIGEST_LENGTH, sizeof(u8));
589
  /* alloc() resources */
590
0
  if (!buf1 || !buf2 || !buf3 || !sha_buf || !sha_data) {
591
0
    msg = "prepare external auth: calloc error";
592
0
    res = SC_ERROR_OUT_OF_MEMORY;
593
0
    goto prepare_external_auth_end;
594
0
  }
595
596
  /* compose buffer data */
597
0
  buf3[0] = 0x6A;   /* iso padding */
598
0
  if (RAND_bytes(buf3 + 1, 74) != 1 ||     /* pRND */
599
0
      RAND_bytes(sm->ifd.k, 32) != 1) { /* Kifd */
600
0
    sc_log_openssl(ctx);
601
0
    msg = "prepare external auth: random data error";
602
0
    res = SC_ERROR_INTERNAL;
603
0
    goto prepare_external_auth_end;
604
0
  }
605
0
  memcpy(buf3 + 1 + 74, sm->ifd.k, 32); /* copy Kifd into buffer */
606
  /* prepare data to be hashed */
607
0
  memcpy(sha_buf, buf3 + 1, 74);  /* copy pRND into sha_buf */
608
0
  memcpy(sha_buf + 74, buf3 + 1 + 74, 32);  /* copy kifd into sha_buf */
609
0
  memcpy(sha_buf + 74 + 32, sm->icc.rnd, 8);  /* copy 8 byte icc challenge */
610
0
  memcpy(sha_buf + 74 + 32 + 8, sm->icc.sn, 8); /* copy serialnr, 8 bytes */
611
0
  SHA1(sha_buf, 74 + 32 + 8 + 8, sha_data);
612
  /* copy hashed data into buffer */
613
0
  memcpy(buf3 + 1 + 74 + 32, sha_data, SHA_DIGEST_LENGTH);
614
0
  buf3[127] = 0xBC; /* iso padding */
615
616
  /* decrypt with ifd private key */
617
0
  pctx = EVP_PKEY_CTX_new(ifd_privkey, NULL);
618
0
  if (!pctx ||
619
0
      EVP_PKEY_decrypt_init(pctx) != 1 ||
620
0
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 ||
621
0
    EVP_PKEY_decrypt(pctx, buf2, &len2, buf3, 128) != 1) {
622
0
    sc_log_openssl(ctx);
623
0
    msg = "Prepare external auth: ifd_privk decrypt failed";
624
0
    res = SC_ERROR_SM_ENCRYPT_FAILED;
625
0
    EVP_PKEY_CTX_free(pctx);
626
0
    goto prepare_external_auth_end;
627
0
  }
628
0
  EVP_PKEY_CTX_free(pctx);
629
0
  pctx = NULL;
630
631
  /* evaluate value of minsig and store into buf3 */
632
0
  bn = BN_bin2bn(buf2, (int)len2, NULL);
633
0
  bnsub = BN_new();
634
0
  if (!bn || !bnsub) {
635
0
    sc_log_openssl(ctx);
636
0
    msg = "Prepare external auth: BN creation failed";
637
0
    res = SC_ERROR_INTERNAL;
638
0
    goto prepare_external_auth_end;
639
0
  }
640
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
641
0
  RSA_get0_key(rsa_ifd_privkey, &ifd_privkey_n, NULL, NULL);
642
#else
643
  if (EVP_PKEY_get_bn_param(ifd_privkey, OSSL_PKEY_PARAM_RSA_N, &ifd_privkey_n) != 1) {
644
    sc_log_openssl(ctx);
645
    msg = "Prepare external auth: BN get param failed";
646
    res = SC_ERROR_INTERNAL;
647
    goto prepare_external_auth_end;
648
  }
649
#endif
650
651
0
  res = BN_sub(bnsub, ifd_privkey_n, bn); /* eval N.IFD-SIG */
652
0
  if (res == 0) {   /* 1:success 0 fail */
653
0
    sc_log_openssl(ctx);
654
0
    msg = "Prepare external auth: BN sigmin evaluation failed";
655
0
    res = SC_ERROR_INTERNAL;
656
0
    goto prepare_external_auth_end;
657
0
  }
658
0
  bnres = (BN_cmp(bn, bnsub) < 0) ? bn : bnsub; /* choose min(SIG,N.IFD-SIG) */
659
0
  if (BN_num_bytes(bnres) > 128) {
660
0
    sc_log_openssl(ctx);
661
0
    msg = "Prepare external auth: BN sigmin result is too big";
662
0
    res = SC_ERROR_INTERNAL;
663
0
    goto prepare_external_auth_end;
664
0
  }
665
0
  len3 = BN_bn2bin(bnres, buf3);  /* convert result back into buf3 */
666
0
  if (len3 <= 0) {
667
0
    sc_log_openssl(ctx);
668
0
    msg = "Prepare external auth: BN to buffer conversion failed";
669
0
    res = SC_ERROR_INTERNAL;
670
0
    goto prepare_external_auth_end;
671
0
  }
672
673
  /* re-encrypt result with icc public key */
674
0
  pctx = EVP_PKEY_CTX_new(icc_pubkey, NULL);
675
0
  if (!pctx ||
676
0
      EVP_PKEY_encrypt_init(pctx) != 1 ||
677
0
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 ||
678
0
      EVP_PKEY_encrypt(pctx, buf1, &len1, buf3, 128) != 1 ||
679
0
      (size_t)len1 != sig_len) {
680
0
    sc_log_openssl(ctx);
681
0
    msg = "Prepare external auth: icc_pubk encrypt failed";
682
0
    res = SC_ERROR_SM_ENCRYPT_FAILED;
683
0
    EVP_PKEY_CTX_free(pctx);
684
0
    goto prepare_external_auth_end;
685
0
  }
686
0
  EVP_PKEY_CTX_free(pctx);
687
688
  /* process done: copy result into cwa_internal buffer and return success */
689
0
  memcpy(sig, buf1, len1);
690
0
  res = SC_SUCCESS;
691
692
0
 prepare_external_auth_end:
693
0
  BN_free(bn);
694
0
  BN_free(bnsub);
695
0
  if (buf1) {
696
0
    sc_mem_clear(buf1, 128);
697
0
    free(buf1);
698
0
  }
699
0
  if (buf2) {
700
0
    sc_mem_clear(buf2, 128);
701
0
    free(buf2);
702
0
  }
703
0
  if (buf3) {
704
0
    sc_mem_clear(buf3, 128);
705
0
    free(buf3);
706
0
  }
707
0
  if (sha_buf) {
708
0
    sc_mem_clear(sha_buf, 74 + 32 + 8 + 1 + 7);
709
0
    free(sha_buf);
710
0
  }
711
0
  free(sha_data);
712
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
713
  BN_clear_free(ifd_privkey_n);
714
#endif
715
716
0
  if (res != SC_SUCCESS) {
717
0
    sc_log(ctx, "%s", msg);
718
0
  }
719
0
  LOG_FUNC_RETURN(ctx, res);
720
0
}
721
722
/**
723
 * SM external authenticate.
724
 *
725
 * Perform external (IFD) authenticate procedure (8.4.1.2)
726
 *
727
 * @param card pointer to card data
728
 * @param sig signature buffer
729
 * @param sig signature buffer length
730
 * @return SC_SUCCESS if OK: else error code
731
 */
732
static int cwa_external_auth(sc_card_t * card, u8 * sig, size_t sig_len)
733
0
{
734
0
  sc_apdu_t apdu;
735
0
  int result = SC_SUCCESS;
736
0
  sc_context_t *ctx = NULL;
737
738
  /* safety check */
739
0
  if (!card || !card->ctx)
740
0
    return SC_ERROR_INVALID_ARGUMENTS;
741
0
  ctx = card->ctx;
742
0
  LOG_FUNC_CALLED(ctx);
743
744
  /* compose apdu for External Authenticate cmd */
745
0
  dnie_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x00, 0x00, 0, sig_len,
746
0
          NULL, 0, sig, sig_len);
747
748
  /* send composed apdu and parse result */
749
0
  result = sc_transmit_apdu(card, &apdu);
750
0
  LOG_TEST_RET(ctx, result, "SM external auth failed");
751
0
  result = sc_check_sw(card, apdu.sw1, apdu.sw2);
752
0
  LOG_TEST_RET(ctx, result, "SM external auth invalid response");
753
0
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
754
0
}
755
756
/**
757
 * SM creation of session keys.
758
 *
759
 * Compute Kenc,Kmac, and SSC  and store it into sm data
760
 *
761
 * @param card pointer to sc_card_t data
762
 * @return SC_SUCCESS if ok; else error code
763
 */
764
static int cwa_compute_session_keys(sc_card_t * card)
765
0
{
766
767
0
  char *msg = NULL;
768
0
  int n = 0;
769
0
  int res = SC_SUCCESS;
770
0
  u8 *kseed;    /* to compose kifd ^ kicc */
771
0
  u8 *data;   /* to compose kenc and kmac to be hashed */
772
0
  u8 *sha_data;   /* to store hash result */
773
0
  u8 kenc[4] = { 0x00, 0x00, 0x00, 0x01 };
774
0
  u8 kmac[4] = { 0x00, 0x00, 0x00, 0x02 };
775
0
  sc_context_t *ctx = NULL;
776
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
777
778
  /* safety check */
779
0
  if (!card || !card->ctx)
780
0
    return SC_ERROR_INVALID_ARGUMENTS;
781
0
  ctx = card->ctx;
782
0
  LOG_FUNC_CALLED(ctx);
783
  /* Just a literal transcription of cwa14890-1 sections 8.7.2 to 8.9 */
784
0
  kseed = calloc(32, sizeof(u8));
785
0
  data = calloc(32 + 4, sizeof(u8));
786
0
  sha_data = calloc(SHA_DIGEST_LENGTH, sizeof(u8));
787
0
  if (!kseed || !data || !sha_data) {
788
0
    msg = "Compute Session Keys: calloc() failed";
789
0
    res = SC_ERROR_OUT_OF_MEMORY;
790
0
    goto compute_session_keys_end;
791
0
  }
792
  /* compose kseed  (cwa-14890-1 sect 8.7.2) */
793
0
  for (n = 0; n < 32; n++)
794
0
    *(kseed + n) = sm->icc.k[n] ^ sm->ifd.k[n];
795
796
  /* evaluate kenc (cwa-14890-1 sect 8.8) */
797
0
  memcpy(data, kseed, 32);
798
0
  memcpy(data + 32, kenc, 4);
799
0
  SHA1(data, 32 + 4, sha_data);
800
0
  memcpy(sm->session_enc, sha_data, 16);  /* kenc=16 fsb sha((kifd^kicc)||00000001) */
801
802
  /* evaluate kmac */
803
0
  memset(data, 0, 32 + 4);
804
0
  memset(sha_data, 0, SHA_DIGEST_LENGTH); /* clear buffers */
805
806
0
  memcpy(data, kseed, 32);
807
0
  memcpy(data + 32, kmac, 4);
808
0
  SHA1(data, 32 + 4, sha_data);
809
0
  memcpy(sm->session_mac, sha_data, 16);  /* kmac=16 fsb sha((kifd^kicc)||00000002) */
810
811
  /* evaluate send sequence counter  (cwa-14890-1 sect 8.9 & 9.6 */
812
0
  memcpy(sm->ssc, sm->icc.rnd + 4, 4);  /* 4 least significant bytes of rndicc */
813
0
  memcpy(sm->ssc + 4, sm->ifd.rnd + 4, 4);  /* 4 least significant bytes of rndifd */
814
815
  /* arriving here means process ok */
816
0
  res = SC_SUCCESS;
817
818
0
 compute_session_keys_end:
819
0
  if (kseed) {
820
0
    sc_mem_clear(kseed, 32);
821
0
    free(kseed);
822
0
  }
823
0
  if (data) {
824
0
    sc_mem_clear(data, 32 + 4);
825
0
    free(data);
826
0
  }
827
0
  free(sha_data);
828
0
  if (res != SC_SUCCESS)
829
0
    sc_log(ctx, "%s", msg);
830
0
  else {
831
0
    sc_log(ctx, "Kenc: %s", sc_dump_hex(sm->session_enc, 16));
832
0
    sc_log(ctx, "Kmac: %s", sc_dump_hex(sm->session_mac, 16));
833
0
    sc_log(ctx, "SSC:  %s", sc_dump_hex(sm->ssc, 8));
834
0
  }
835
0
  LOG_FUNC_RETURN(ctx, res);
836
0
}
837
838
/*
839
 * Compare signature for internal auth procedure.
840
 *
841
 * @param data Received data to be checked
842
 * @param dlen data length
843
 * @param expected results
844
 * @return SC_SUCCESS or error code
845
 */
846
static int cwa_compare_signature(u8 * data, size_t dlen, u8 * ifd_data)
847
0
{
848
0
  u8 *buf = calloc(74 + 32 + 32, sizeof(u8));
849
0
  u8 *sha = calloc(SHA_DIGEST_LENGTH, sizeof(u8));
850
0
  int res = SC_SUCCESS;
851
0
  if (!buf || !sha) {
852
0
    res = SC_ERROR_OUT_OF_MEMORY;
853
0
    goto compare_signature_end;
854
0
  }
855
0
  res = SC_ERROR_INVALID_DATA;
856
0
  if (dlen != 128)
857
0
    goto compare_signature_end; /* check length */
858
0
  if (data[0] != 0x6a)
859
0
    goto compare_signature_end; /* iso 9796-2 padding */
860
0
  if (data[127] != 0xBC)
861
0
    goto compare_signature_end; /* iso 9796-2 padding */
862
0
  memcpy(buf, data + 1, 74 + 32);
863
0
  memcpy(buf + 74 + 32, ifd_data, 16);
864
0
  SHA1(buf, 74 + 32 + 16, sha);
865
0
  if (memcmp(data + 127 - SHA_DIGEST_LENGTH, sha, SHA_DIGEST_LENGTH) == 0)
866
0
    res = SC_SUCCESS;
867
0
 compare_signature_end:
868
0
  free(buf);
869
0
  free(sha);
870
0
  return res;
871
0
}
872
873
/**
874
 * check the result of internal_authenticate operation.
875
 *
876
 * Checks icc received data from internal auth procedure against
877
 * expected results
878
 *
879
 * @param card Pointer to sc_card_t data
880
 * @param icc_pubkey icc public key
881
 * @param ifd_privkey ifd private key
882
 * @param ifdbuf buffer containing ( RND.IFD || SN.IFD )
883
 * @param ifdlen buffer length; should be 16
884
 * @param sig signature buffer
885
 * @param sig_len signature buffer length
886
 * @return SC_SUCCESS if ok; else error code
887
 */
888
static int cwa_verify_internal_auth(sc_card_t * card,
889
            EVP_PKEY *icc_pubkey,
890
            EVP_PKEY *ifd_privkey,
891
            u8 * ifdbuf,
892
            size_t ifdlen,
893
            u8 * sig,
894
            size_t sig_len)
895
0
{
896
0
  int res = SC_SUCCESS;
897
0
  char *msg = NULL;
898
0
  u8 *buf1 = NULL; /* to decrypt with our private key */
899
0
  u8 *buf2 = NULL; /* to try SIGNUM==SIG */
900
0
  u8 *buf3 = NULL; /* to try SIGNUM==N.ICC-SIG */
901
0
  size_t len1 = 128, len2 = 128, len3 = 128, bn_len = 0;
902
0
  BIGNUM *bn = NULL;
903
0
  BIGNUM *sigbn = NULL;
904
0
  sc_context_t *ctx = NULL;
905
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
906
0
  EVP_PKEY_CTX *pctx = NULL;
907
908
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
909
0
  const BIGNUM *icc_pubkey_n = NULL;
910
0
  const RSA *rsa_icc_pubkey = EVP_PKEY_get0_RSA(icc_pubkey);
911
0
  if (!rsa_icc_pubkey) {
912
0
    res = SC_ERROR_INTERNAL;
913
0
    msg = "Can not extract RSA object icc pub";
914
0
    goto verify_internal_done;
915
0
  }
916
#else
917
  BIGNUM *icc_pubkey_n = NULL;
918
#endif
919
920
0
  if (!card || !card->ctx)
921
0
    return SC_ERROR_INVALID_ARGUMENTS;
922
0
  ctx = card->ctx;
923
0
  LOG_FUNC_CALLED(ctx);
924
0
  if (!ifdbuf || (ifdlen != 16)) {
925
0
    res = SC_ERROR_INVALID_ARGUMENTS;
926
0
    msg = "Null buffers received as parameters";
927
0
    goto verify_internal_done;
928
0
  }
929
0
  if (!icc_pubkey || !ifd_privkey) {
930
0
    res = SC_ERROR_SM_NO_SESSION_KEYS;
931
0
    msg = "Either provided icc_pubk or ifd_privk are null";
932
0
    goto verify_internal_done;
933
0
  }
934
0
  buf1 = (u8 *) calloc(128, sizeof(u8));  /* 128: RSA key len in bytes */
935
0
  buf2 = (u8 *) calloc(128, sizeof(u8));
936
0
  buf3 = (u8 *) calloc(128, sizeof(u8));
937
0
  if (!buf1 || !buf2 || !buf3) {
938
0
    msg = "Verify Signature: calloc() error";
939
0
    res = SC_ERROR_OUT_OF_MEMORY;
940
0
    goto verify_internal_done;
941
0
  }
942
943
  /*
944
     We have received data with this format:
945
     sigbuf = E[PK.IFD.AUT](SIGMIN)
946
     SIGMIN = min ( SIG, N.ICC-SIG )
947
     SIG= DS[SK.ICC.AUT] (
948
     0x6A  ||
949
     PRND1 ||
950
     Kicc  ||
951
     sha1_hash(PRND1 || Kicc || RND.IFD || SN.IFD) ||
952
     0xBC
953
     )
954
     So we should reverse the process and try to get valid results
955
   */
956
957
  /* decrypt data with our ifd priv key */
958
0
  pctx = EVP_PKEY_CTX_new(ifd_privkey, NULL);
959
0
  if (!pctx ||
960
0
      EVP_PKEY_decrypt_init(pctx) != 1 ||
961
0
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 ||
962
0
      EVP_PKEY_decrypt(pctx, buf1, &len1, sig, sig_len) != 1) {
963
0
    sc_log_openssl(ctx);
964
0
    msg = "Verify Signature: decrypt with ifd privk failed";
965
0
    res = SC_ERROR_SM_ENCRYPT_FAILED;
966
0
    EVP_PKEY_CTX_free(pctx);
967
0
    goto verify_internal_done;
968
0
  }
969
0
  EVP_PKEY_CTX_free(pctx);
970
0
  pctx = NULL;
971
972
  /* OK: now we have SIGMIN in buf1 */
973
  /* check if SIGMIN data matches SIG or N.ICC-SIG */
974
  /* evaluate DS[SK.ICC.AUTH](SIG) trying to decrypt with icc pubk */
975
0
  pctx = EVP_PKEY_CTX_new(icc_pubkey, NULL);
976
0
  if (!pctx ||
977
0
      EVP_PKEY_encrypt_init(pctx) != 1 ||
978
0
      EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 ||
979
0
      EVP_PKEY_encrypt(pctx, buf3, &len3, buf1, len1) != 1) {
980
0
    EVP_PKEY_CTX_free(pctx);
981
0
    sc_log_openssl(ctx);
982
0
    goto verify_nicc_sig; /* evaluate N.ICC-SIG and retry */
983
0
  }
984
985
0
  EVP_PKEY_CTX_free(pctx);
986
987
0
  res = cwa_compare_signature(buf3, len3, ifdbuf);
988
0
  if (res == SC_SUCCESS)
989
0
    goto verify_internal_ok;
990
991
0
 verify_nicc_sig:
992
  /*
993
   * Arriving here means need to evaluate N.ICC-SIG
994
   * So convert buffers to bignums to operate
995
   */
996
0
  bn = BN_bin2bn(buf1, (int)len1, NULL);  /* create BN data */
997
0
  sigbn = BN_new();
998
0
  if (!bn || !sigbn) {
999
0
    sc_log_openssl(ctx);
1000
0
    msg = "Verify Signature: cannot bignums creation error";
1001
0
    res = SC_ERROR_OUT_OF_MEMORY;
1002
0
    goto verify_internal_done;
1003
0
  }
1004
0
#if OPENSSL_VERSION_NUMBER < 0x30000000L
1005
0
  RSA_get0_key(rsa_icc_pubkey, &icc_pubkey_n, NULL, NULL);
1006
#else
1007
  if (EVP_PKEY_get_bn_param(icc_pubkey, OSSL_PKEY_PARAM_RSA_N, &icc_pubkey_n) != 1) {
1008
    sc_log_openssl(ctx);
1009
    msg = "Verify Signature: BN get param failed";
1010
    res = SC_ERROR_INTERNAL;
1011
    goto verify_internal_done;
1012
  }
1013
#endif
1014
0
  res = BN_sub(sigbn, icc_pubkey_n, bn);  /* eval N.ICC-SIG */
1015
0
  if (!res) {
1016
0
    sc_log_openssl(ctx);
1017
0
    msg = "Verify Signature: evaluation of N.ICC-SIG failed";
1018
0
    res = SC_ERROR_INTERNAL;
1019
0
    goto verify_internal_done;
1020
0
  }
1021
0
  bn_len = (size_t)BN_num_bytes(sigbn);
1022
0
  if (bn_len == 0 || bn_len > len2) {
1023
0
    msg = "Verify Signature: unsupported RSA size";
1024
0
    res = SC_ERROR_INVALID_DATA;
1025
0
    goto verify_internal_done;
1026
0
  }
1027
0
  len2 = BN_bn2bin(sigbn, buf2);  /* copy result to buffer */
1028
0
  if (len2 <= 0) {
1029
0
    sc_log_openssl(ctx);
1030
0
    msg = "Verify Signature: cannot convert bignum to buffer";
1031
0
    res = SC_ERROR_INTERNAL;
1032
0
    goto verify_internal_done;
1033
0
  }
1034
  /* ok: check again with new data */
1035
  /* evaluate DS[SK.ICC.AUTH](I.ICC-SIG) trying to decrypt with icc pubk */
1036
0
  pctx = EVP_PKEY_CTX_new(icc_pubkey, NULL);
1037
0
  if (!pctx ||
1038
0
    EVP_PKEY_encrypt_init(pctx) != 1 ||
1039
0
    EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_NO_PADDING) != 1 ||
1040
0
    EVP_PKEY_encrypt(pctx, buf3, &len3, buf2, len2) != 1) {
1041
0
    sc_log_openssl(ctx);
1042
0
    msg = "Verify Signature: cannot get valid SIG data";
1043
0
    res = SC_ERROR_INVALID_DATA;
1044
0
    EVP_PKEY_CTX_free(pctx);
1045
0
    goto verify_internal_done;
1046
0
  }
1047
0
  EVP_PKEY_CTX_free(pctx);
1048
0
  pctx = NULL;
1049
1050
0
  res = cwa_compare_signature(buf3, len3, ifdbuf);
1051
0
  if (res != SC_SUCCESS) {
1052
0
    msg = "Verify Signature: cannot get valid SIG data";
1053
0
    res = SC_ERROR_INVALID_DATA;
1054
0
    goto verify_internal_done;
1055
0
  }
1056
  /* arriving here means OK: complete data structures */
1057
0
 verify_internal_ok:
1058
0
  memcpy(sm->icc.k, buf3 + 1 + 74, 32); /* extract Kicc from buf3 */
1059
0
  res = SC_SUCCESS;
1060
0
 verify_internal_done:
1061
0
  free(buf1);
1062
0
  free(buf2);
1063
0
  free(buf3);
1064
0
  BN_free(bn);
1065
0
  BN_free(sigbn);
1066
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
1067
  BN_clear_free(icc_pubkey_n);
1068
#endif
1069
0
  if (res != SC_SUCCESS) {
1070
0
    sc_log(ctx, "%s", msg);
1071
0
  }
1072
0
  LOG_FUNC_RETURN(ctx, res);
1073
0
}
1074
1075
/**
1076
 * Create Secure Messaging channel.
1077
 *
1078
 * This is the main entry point for CWA14890 SM channel creation.
1079
 * It closely follows cwa standard, with a minor modification:
1080
 * - ICC serial number is taken at the beginning of SM creation
1081
 * - ICC and IFD certificate agreement process is reversed, to allow
1082
 * card to retain key references on further process (this behavior
1083
 * is also defined in standard)
1084
 *
1085
 * Based on Several documents:
1086
 * - "Understanding the DNIe"
1087
 * - "Manual de comandos del DNIe"
1088
 * - ISO7816-4 and CWA14890-{1,2}
1089
 *
1090
 * @param card card info structure
1091
 * @param provider cwa14890 info provider
1092
 * @param flag requested init method ( OFF, COLD, WARM )
1093
 * @return SC_SUCCESS if OK; else error code
1094
 */
1095
int cwa_create_secure_channel(sc_card_t * card,
1096
            cwa_provider_t * provider, int flag)
1097
0
{
1098
0
  u8 *cert = NULL;
1099
0
  size_t certlen;
1100
1101
0
  int res = SC_SUCCESS;
1102
0
  char *msg = "Success";
1103
1104
  /* data to get and parse certificates */
1105
0
  X509 *icc_cert = NULL;
1106
0
  X509 *ca_cert = NULL;
1107
0
  EVP_PKEY *icc_pubkey = NULL;
1108
0
  EVP_PKEY *ifd_privkey = NULL;
1109
0
  sc_context_t *ctx = NULL;
1110
0
  struct sm_cwa_session * sm = &card->sm_ctx.info.session.cwa;
1111
0
  u8 sig[128];
1112
1113
  /* several buffer and buffer pointers */
1114
0
  u8 *buffer = NULL;
1115
0
  size_t bufferlen;
1116
0
  u8 *tlv = NULL;   /* buffer to compose TLV messages */
1117
0
  size_t tlvlen = 0;
1118
0
  u8 rndbuf[16]; /* 8 RND.IFD + 8 SN.IFD */
1119
1120
  /* preliminary checks */
1121
0
  if (!card || !card->ctx )
1122
0
    return SC_ERROR_INVALID_ARGUMENTS;
1123
0
  if (!provider)
1124
0
    return SC_ERROR_SM_NOT_INITIALIZED;
1125
  /* commodity vars */
1126
0
  ctx = card->ctx;
1127
1128
0
  LOG_FUNC_CALLED(ctx);
1129
1130
  /* check requested initialization method */
1131
0
  switch (flag) {
1132
0
  case CWA_SM_OFF: /* disable SM */
1133
0
    card->sm_ctx.sm_mode = SM_MODE_NONE;
1134
0
    sc_log(ctx, "Setting CWA SM status to none");
1135
    /* request the Master File to provoke an SM error and close the channel */
1136
0
    res = sc_select_file(card, sc_get_mf_path(), NULL);
1137
0
    if (res == SC_ERROR_SM)
1138
0
      res = SC_SUCCESS;
1139
0
    LOG_FUNC_RETURN(ctx, res);
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: %zu", 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 APDU */
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
    to->resp = NULL;
1708
0
  }
1709
0
encode_end_apdu_valid:
1710
0
  sc_evp_cipher_free(alg);
1711
0
  EVP_CIPHER_CTX_free(cctx);
1712
0
  if (msg) {
1713
0
    sc_log_openssl(ctx);
1714
0
    sc_log(ctx, "%s", msg);
1715
0
  }
1716
0
  free(msgbuf);
1717
0
  free(cryptbuf);
1718
0
  free(ccbuf);
1719
0
  LOG_FUNC_RETURN(ctx, res);
1720
0
}
1721
1722
/**
1723
 * Decode an APDU response.
1724
 *
1725
 * Calling this functions means that It's has been verified
1726
 * That apdu response comes in TLV encoded format and needs decoding
1727
 * Based on section 9 of CWA-14890 and Sect 6 of iso7816-4 standards
1728
 * And DNIe's manual
1729
 *
1730
 * @param card card info structure
1731
 * @param sm Secure Messaging state information
1732
 * @param from APDU with response to be decoded
1733
 * @param to where to store decoded apdu
1734
 * @return SC_SUCCESS if ok; else error code
1735
 */
1736
int cwa_decode_response(sc_card_t * card,
1737
      cwa_provider_t * provider,
1738
      sc_apdu_t * apdu)
1739
0
{
1740
0
  size_t i, j, tlv_len;
1741
0
  cwa_tlv_t tlv_array[4];
1742
0
  cwa_tlv_t *p_tlv = &tlv_array[0]; /* to store plain data (Tag 0x81) */
1743
0
  cwa_tlv_t *e_tlv = &tlv_array[1]; /* to store pad encoded data (Tag 0x87) */
1744
0
  cwa_tlv_t *m_tlv = &tlv_array[2]; /* to store mac CC (Tag 0x8E) */
1745
0
  cwa_tlv_t *s_tlv = &tlv_array[3]; /* to store sw1-sw2 status (Tag 0x99) */
1746
0
  u8 *buffer = NULL; /* buffer for data. pointers to this buffer are in tlv_array */
1747
0
  u8 *ccbuf = NULL; /* buffer for mac CC calculation */
1748
0
  size_t cclen = 0; /* ccbuf len */
1749
0
  u8 macbuf[8];   /* where to calculate mac */
1750
0
  size_t resplen = 0; /* respbuf length */
1751
0
  int res = SC_SUCCESS;
1752
0
  char *msg = NULL; /* to store error messages */
1753
0
  sc_context_t *ctx = NULL;
1754
0
  struct sm_cwa_session * sm_session = &card->sm_ctx.info.session.cwa;
1755
1756
0
  EVP_CIPHER_CTX *cctx = NULL;
1757
0
  EVP_CIPHER *alg = NULL;
1758
0
  unsigned char *key = NULL;
1759
0
  int tmplen = 0;
1760
1761
0
  if ((cctx = EVP_CIPHER_CTX_new()) == NULL) {
1762
0
    sc_log_openssl(ctx);
1763
0
    return SC_ERROR_INTERNAL;
1764
0
  }
1765
1766
  /* mandatory check */
1767
0
  if (!card || !card->ctx || !provider)
1768
0
    return SC_ERROR_INVALID_ARGUMENTS;
1769
0
  ctx = card->ctx;
1770
1771
0
  LOG_FUNC_CALLED(ctx);
1772
  /* check remaining arguments */
1773
0
  if ((apdu == NULL) || (sm_session == NULL))
1774
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_SM_NOT_INITIALIZED);
1775
0
  if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT)
1776
0
    LOG_FUNC_RETURN(ctx, SC_ERROR_SM_INVALID_LEVEL);
1777
1778
  /* cwa14890 sect 9.3: check SW1 or SW2 for SM related errors */
1779
0
  if (apdu->sw1 == 0x69) {
1780
0
    if ((apdu->sw2 == 0x88) || (apdu->sw2 == 0x87)) {
1781
      /* configure the driver to re-establish the SM */
1782
0
      msg = "SM related errors in APDU response";
1783
0
      cwa_create_secure_channel(card, provider, CWA_SM_OFF);
1784
0
      res = SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
1785
0
      goto response_decode_end;
1786
0
    }
1787
0
  }
1788
  /* if response is null/empty assume unencoded apdu */
1789
0
  if (!apdu->resp || (apdu->resplen == 0)) {
1790
0
    sc_log(ctx, "Empty APDU response: assume not cwa encoded");
1791
0
    return SC_SUCCESS;
1792
0
  }
1793
  /* checks if apdu response needs decoding by checking tags in response */
1794
0
  switch (*apdu->resp) {
1795
0
  case CWA_SM_PLAIN_TAG:
1796
0
  case CWA_SM_CRYPTO_TAG:
1797
0
  case CWA_SM_MAC_TAG:
1798
0
  case CWA_SM_LE_TAG:
1799
0
  case CWA_SM_STATUS_TAG:
1800
0
    break;    /* cwa tags found: continue decoding */
1801
0
  default:    /* else apdu response seems not to be cwa encoded */
1802
0
    sc_log(card->ctx, "APDU Response seems not to be cwa encoded");
1803
0
    return SC_SUCCESS; /* let process continue */
1804
0
  }
1805
1806
  /* parse response to find TLV's data and check results */
1807
0
  memset(tlv_array, 0, 4 * sizeof(cwa_tlv_t));
1808
  /* create buffer and copy data into */
1809
0
  buffer = calloc(apdu->resplen, sizeof(u8));
1810
0
  if (!buffer) {
1811
0
    msg = "Cannot allocate space for response buffer";
1812
0
    res = SC_ERROR_OUT_OF_MEMORY;
1813
0
    goto response_decode_end;
1814
0
  }
1815
0
  memcpy(buffer, apdu->resp, apdu->resplen);
1816
1817
0
  res = cwa_parse_tlv(card, buffer, apdu->resplen, tlv_array);
1818
0
  if (res != SC_SUCCESS) {
1819
0
    msg = "Error in TLV parsing";
1820
0
    goto response_decode_end;
1821
0
  }
1822
1823
  /* check consistency of received TLV's */
1824
0
  if (p_tlv->buf && e_tlv->buf) {
1825
0
    msg =
1826
0
        "Plain and Encoded data are mutually exclusive in apdu response";
1827
0
    res = SC_ERROR_INVALID_DATA;
1828
0
    goto response_decode_end;
1829
0
  }
1830
0
  if (!m_tlv->buf) {
1831
0
    msg = "No MAC TAG found in apdu response";
1832
0
    res = SC_ERROR_INVALID_DATA;
1833
0
    goto response_decode_end;
1834
0
  }
1835
0
  tlv_len = (card->atr.value[15] >= DNIE_30_VERSION)? 8 : 4;
1836
0
  if (m_tlv->len != tlv_len) {
1837
0
    msg = "Invalid MAC TAG Length";
1838
0
    res = SC_ERROR_INVALID_DATA;
1839
0
    goto response_decode_end;
1840
0
  }
1841
1842
  /* compose buffer to evaluate mac */
1843
1844
  /* reserve enough space for data+status+padding */
1845
0
  ccbuf =
1846
0
      calloc(e_tlv->buflen + s_tlv->buflen + p_tlv->buflen + 8,
1847
0
       sizeof(u8));
1848
0
  if (!ccbuf) {
1849
0
    msg = "Cannot allocate space for mac checking";
1850
0
    res = SC_ERROR_OUT_OF_MEMORY;
1851
0
    goto response_decode_end;
1852
0
  }
1853
  /* copy data into buffer */
1854
0
  cclen = 0;
1855
0
  if (e_tlv->buf) { /* encoded data */
1856
0
    memcpy(ccbuf, e_tlv->buf, e_tlv->buflen);
1857
0
    cclen = e_tlv->buflen;
1858
0
  }
1859
0
  if (p_tlv->buf) { /* plain data */
1860
0
    memcpy(ccbuf, p_tlv->buf, p_tlv->buflen);
1861
0
    cclen += p_tlv->buflen;
1862
0
  }
1863
0
  if (s_tlv->buf) { /* response status */
1864
0
    if (s_tlv->len != 2) {
1865
0
      msg = "Invalid SW TAG length";
1866
0
      res = SC_ERROR_INVALID_DATA;
1867
0
      goto response_decode_end;
1868
0
    }
1869
0
    memcpy(ccbuf + cclen, s_tlv->buf, s_tlv->buflen);
1870
0
    cclen += s_tlv->buflen;
1871
0
    apdu->sw1 = s_tlv->data[0];
1872
0
    apdu->sw2 = s_tlv->data[1];
1873
0
  }    /* if no response status tag, use sw1 and sw2 from apdu */
1874
  /* add iso7816 padding */
1875
0
  cwa_iso7816_padding(ccbuf, &cclen);
1876
1877
  /* evaluate mac by mean of kmac and increased SendSequence Counter SSC */
1878
1879
  /* increase SSC */
1880
0
  res = cwa_increase_ssc(card); /* increase send sequence counter */
1881
0
  if (res != SC_SUCCESS) {
1882
0
    msg = "Error in computing SSC";
1883
0
    goto response_decode_end;
1884
0
  }
1885
  /* set up key for mac computing */
1886
0
  key = sm_session->session_mac;
1887
1888
0
  alg = sc_evp_cipher(card->ctx, "DES-ECB");
1889
0
  if (!alg ||
1890
0
      EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 ||
1891
0
      EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) {
1892
0
    sc_log_openssl(ctx);
1893
0
    msg = "Error in DES ECB encryption";
1894
0
    res = SC_ERROR_INTERNAL;
1895
0
    goto response_decode_end;
1896
0
  }
1897
1898
0
  memcpy(macbuf, sm_session->ssc, 8); /* start with computed SSC */
1899
0
  for (i = 0; i < cclen; i += 8) { /* divide data in 8 byte blocks */
1900
    /* compute DES */
1901
0
    if (EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1) {
1902
0
      sc_log_openssl(ctx);
1903
0
      msg = "Error in DES ECB encryption";
1904
0
      res = SC_ERROR_INTERNAL;
1905
0
      goto response_decode_end;
1906
0
    }
1907
    /* XOR with data and repeat */
1908
0
    for (j = 0; j < 8; j++)
1909
0
      macbuf[j] ^= ccbuf[i + j];
1910
0
  }
1911
0
  if (EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) {
1912
0
    sc_log_openssl(ctx);
1913
0
    msg = "Error in DES ECB encryption";
1914
0
    res = SC_ERROR_INTERNAL;
1915
0
    goto response_decode_end;
1916
0
  }
1917
1918
  /* finally apply 3DES to result */
1919
0
  sc_evp_cipher_free(alg);
1920
0
  alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB");
1921
1922
0
  if (!alg ||
1923
0
      EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 ||
1924
0
      EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 ||
1925
0
      EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 ||
1926
0
      EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) {
1927
0
    sc_log_openssl(ctx);
1928
0
    msg = "Error in 3DEC ECB encryption";
1929
0
    res = SC_ERROR_INTERNAL;
1930
0
    goto response_decode_end;
1931
0
  }
1932
1933
  /* check evaluated mac with provided by apdu response */
1934
1935
0
  res = memcmp(m_tlv->data, macbuf, 4); /* check first 4 bytes */
1936
0
  if (res != 0) {
1937
0
    msg = "Error in MAC CC checking: value doesn't match";
1938
0
    res = SC_ERROR_SM_ENCRYPT_FAILED;
1939
0
    goto response_decode_end;
1940
0
  }
1941
1942
  /* allocate response buffer */
1943
0
  resplen = 10 + MAX(p_tlv->len, e_tlv->len); /* estimate response buflen */
1944
0
  if (apdu->resplen < resplen) {
1945
0
    msg = "Cannot allocate buffer to store response";
1946
0
    res = SC_ERROR_BUFFER_TOO_SMALL;
1947
0
    goto response_decode_end;
1948
0
  }
1949
0
  apdu->resplen = resplen;
1950
1951
  /* fill destination response apdu buffer with data */
1952
1953
  /* if plain data, just copy TLV data into apdu response */
1954
0
  if (p_tlv->buf) { /* plain data */
1955
0
    memcpy(apdu->resp, p_tlv->data, p_tlv->len);
1956
0
    apdu->resplen = p_tlv->len;
1957
0
  }
1958
1959
  /* if encoded data, decode and store into apdu response */
1960
0
  else if (e_tlv->buf) { /* encoded data */
1961
0
    unsigned char iv[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
1962
0
    int dlen = (int)apdu->resplen;
1963
    /* check data len */
1964
0
    if ((e_tlv->len < 9) || ((e_tlv->len - 1) % 8) != 0) {
1965
0
      msg = "Invalid length for Encoded data TLV";
1966
0
      res = SC_ERROR_INVALID_DATA;
1967
0
      goto response_decode_end;
1968
0
    }
1969
    /* first byte is padding info; check value */
1970
0
    if (e_tlv->data[0] != 0x01) {
1971
0
      msg = "Encoded TLV: Invalid padding info value";
1972
0
      res = SC_ERROR_INVALID_DATA;
1973
0
      goto response_decode_end;
1974
0
    }
1975
    /* prepare keys to decode */
1976
0
    key = sm_session->session_enc;
1977
1978
    /* decrypt into response buffer
1979
     * by using 3DES CBC by mean of kenc and iv={0,...0} */
1980
0
    sc_evp_cipher_free(alg);
1981
0
    alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC");
1982
1983
0
    if (!alg ||
1984
0
        EVP_DecryptInit_ex(cctx, alg, NULL, key, iv) != 1 ||
1985
0
        EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 ||
1986
0
        EVP_DecryptUpdate(cctx, apdu->resp, &dlen, &e_tlv->data[1], (int)(e_tlv->len - 1)) != 1 ||
1987
0
        EVP_DecryptFinal_ex(cctx, apdu->resp + dlen, &tmplen) != 1) {
1988
0
      sc_log_openssl(ctx);
1989
0
      res = SC_ERROR_INTERNAL;
1990
0
      msg = "Can not decrypt 3DES CBC";
1991
0
      goto response_decode_end;
1992
0
    }
1993
0
    apdu->resplen = dlen + tmplen;
1994
1995
    /* remove iso padding from response length */
1996
0
    for (; (apdu->resplen > 0) && *(apdu->resp + apdu->resplen - 1) == 0x00; apdu->resplen--) ;  /* empty loop */
1997
1998
0
    if (*(apdu->resp + apdu->resplen - 1) != 0x80) { /* check padding byte */
1999
0
      msg = "Decrypted TLV has no 0x80 iso padding indicator!";
2000
0
      res = SC_ERROR_INVALID_DATA;
2001
0
      goto response_decode_end;
2002
0
    }
2003
    /* everything ok: remove ending 0x80 from response */
2004
0
    apdu->resplen--;
2005
0
  }
2006
2007
0
  else
2008
0
    apdu->resplen = 0; /* neither plain, nor encoded data */
2009
2010
  /* that's all folks */
2011
0
  res = SC_SUCCESS;
2012
2013
0
 response_decode_end:
2014
0
  sc_evp_cipher_free(alg);
2015
0
  EVP_CIPHER_CTX_free(cctx);
2016
0
  free(buffer);
2017
0
  free(ccbuf);
2018
0
  if (msg) {
2019
0
    sc_log(ctx, "%s", msg);
2020
0
  } else {
2021
0
    cwa_trace_apdu(card, apdu, 1);
2022
0
  }      /* trace apdu response */
2023
0
  LOG_FUNC_RETURN(ctx, res);
2024
0
}
2025
2026
/********************* default provider for cwa14890 ****************/
2027
2028
/* pre and post operations */
2029
2030
static int default_create_pre_ops(sc_card_t * card, cwa_provider_t * provider)
2031
0
{
2032
0
  return SC_SUCCESS;
2033
0
}
2034
2035
static int default_create_post_ops(sc_card_t * card, cwa_provider_t * provider)
2036
0
{
2037
0
  return SC_SUCCESS;
2038
0
}
2039
2040
static int default_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key)
2041
0
{
2042
0
  return SC_ERROR_NOT_SUPPORTED;
2043
0
}
2044
2045
/* retrieve CVC intermediate CA certificate and length */
2046
static int default_get_cvc_ca_cert(sc_card_t * card, u8 ** cert,
2047
           size_t * length)
2048
0
{
2049
0
  return SC_ERROR_NOT_SUPPORTED;
2050
0
}
2051
2052
/* retrieve CVC IFD certificate and length */
2053
static int default_get_cvc_ifd_cert(sc_card_t * card, u8 ** cert,
2054
            size_t * length)
2055
0
{
2056
0
  return SC_ERROR_NOT_SUPPORTED;
2057
0
}
2058
2059
static int default_get_ifd_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey)
2060
0
{
2061
0
  return SC_ERROR_NOT_SUPPORTED;
2062
0
}
2063
2064
/* get ICC intermediate CA  path */
2065
static int default_get_icc_intermediate_ca_cert(sc_card_t * card, X509 ** cert)
2066
0
{
2067
0
  return SC_ERROR_NOT_SUPPORTED;
2068
0
}
2069
2070
/* get ICC certificate path */
2071
static int default_get_icc_cert(sc_card_t * card, X509 ** cert)
2072
0
{
2073
0
  return SC_ERROR_NOT_SUPPORTED;
2074
0
}
2075
2076
/* Retrieve key reference for Root CA to validate CVC intermediate CA certs */
2077
static int default_get_root_ca_pubkey_ref(sc_card_t * card, u8 ** buf,
2078
            size_t * len)
2079
0
{
2080
0
  return SC_ERROR_NOT_SUPPORTED;
2081
0
}
2082
2083
/* Retrieve key reference for intermediate CA to validate IFD certs */
2084
static int default_get_intermediate_ca_pubkey_ref(sc_card_t * card, u8 ** buf,
2085
              size_t * len)
2086
0
{
2087
0
  return SC_ERROR_NOT_SUPPORTED;
2088
0
}
2089
2090
/* Retrieve key reference for IFD certificate */
2091
static int default_get_ifd_pubkey_ref(sc_card_t * card, u8 ** buf, size_t * len)
2092
0
{
2093
0
  return SC_ERROR_NOT_SUPPORTED;
2094
0
}
2095
2096
/* Retrieve key reference for ICC privkey */
2097
static int default_get_icc_privkey_ref(sc_card_t * card, u8 ** buf,
2098
               size_t * len)
2099
0
{
2100
0
  return SC_ERROR_NOT_SUPPORTED;
2101
0
}
2102
2103
/* Retrieve SN.IFD (8 bytes left padded with zeroes if needed) */
2104
static int default_get_sn_ifd(sc_card_t * card)
2105
0
{
2106
0
  return SC_ERROR_NOT_SUPPORTED;
2107
0
}
2108
2109
/* Retrieve SN.ICC (8 bytes left padded with zeroes if needed) */
2110
static int default_get_sn_icc(sc_card_t * card)
2111
0
{
2112
0
  return SC_ERROR_NOT_SUPPORTED;
2113
0
}
2114
2115
static cwa_provider_t default_cwa_provider = {
2116
2117
    /************ data related with SM operations *************************/
2118
2119
    /************ operations related with secure channel creation *********/
2120
2121
  /* pre and post operations */
2122
  default_create_pre_ops,
2123
  default_create_post_ops,
2124
2125
  /* Get ICC intermediate CA  path */
2126
  default_get_icc_intermediate_ca_cert,
2127
  /* Get ICC certificate path */
2128
  default_get_icc_cert,
2129
2130
  /* Obtain RSA public key from RootCA */
2131
  default_get_root_ca_pubkey,
2132
  /* Obtain RSA IFD private key */
2133
  default_get_ifd_privkey,
2134
2135
  /* Retrieve CVC intermediate CA certificate and length */
2136
  default_get_cvc_ca_cert,
2137
  /* Retrieve CVC IFD certificate and length */
2138
  default_get_cvc_ifd_cert,
2139
2140
  /* Get public key references for Root CA to validate intermediate CA cert */
2141
  default_get_root_ca_pubkey_ref,
2142
2143
  /* Get public key reference for IFD intermediate CA certificate */
2144
  default_get_intermediate_ca_pubkey_ref,
2145
2146
  /* Get public key reference for IFD CVC certificate */
2147
  default_get_ifd_pubkey_ref,
2148
2149
  /* Get ICC private key reference */
2150
  default_get_icc_privkey_ref,
2151
2152
  /* Get IFD Serial Number */
2153
  default_get_sn_ifd,
2154
2155
  /* Get ICC Serial Number */
2156
  default_get_sn_icc,
2157
2158
2159
};
2160
2161
/**
2162
 * Get a copy of default cwa provider.
2163
 *
2164
 * @param card pointer to card info structure
2165
 * @return copy of default provider or null on error
2166
 */
2167
cwa_provider_t *cwa_get_default_provider(sc_card_t * card)
2168
0
{
2169
0
  cwa_provider_t *res = NULL;
2170
0
  if (!card || !card->ctx)
2171
0
    return NULL;
2172
0
  LOG_FUNC_CALLED(card->ctx);
2173
0
  res = calloc(1, sizeof(cwa_provider_t));
2174
0
  if (!res) {
2175
0
    sc_log(card->ctx, "Cannot allocate space for cwa_provider");
2176
0
    return NULL;
2177
0
  }
2178
0
  memcpy(res, &default_cwa_provider, sizeof(cwa_provider_t));
2179
0
  return res;
2180
0
}
2181
2182
/* end of cwa14890.c */
2183
#undef __CWA14890_C__
2184
2185
#endif        /* ENABLE_OPENSSL */