From 91dd74f3d7e3630bb7f298fe4d392f8a6cef9acb Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 29 Mar 2021 14:48:11 +0200 Subject: [PATCH] scd: New function for iso7816 PSO_CSV. * scd/iso7816.c (iso7816_pso_csv): New. --- scd/iso7816.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ scd/iso7816.h | 3 +++ 2 files changed, 64 insertions(+) diff --git a/scd/iso7816.c b/scd/iso7816.c index dcb2845c7..1d654eb71 100644 --- a/scd/iso7816.c +++ b/scd/iso7816.c @@ -628,6 +628,67 @@ iso7816_decipher (int slot, int extended_mode, } +/* Perform the security operation COMPUTE SHARED SECRET. On success 0 + is returned and the shared secret is available in a newly allocated + buffer stored at RESULT with its length stored at RESULTLEN. For + LE see do_generate_keypair. */ +gpg_error_t +iso7816_pso_csv (int slot, int extended_mode, + const unsigned char *data, size_t datalen, int le, + unsigned char **result, size_t *resultlen) +{ + int sw; + unsigned char *buf; + unsigned int nbuf; + + if (!data || !datalen || !result || !resultlen) + return gpg_error (GPG_ERR_INV_VALUE); + *result = NULL; + *resultlen = 0; + + if (!extended_mode) + le = 256; /* Ignore provided Le and use what apdu_send uses. */ + else if (le >= 0 && le < 256) + le = 256; + + /* Data needs to be in BER-TLV format. */ + buf = xtrymalloc (datalen + 4); + if (!buf) + return gpg_error_from_syserror (); + nbuf = 0; + buf[nbuf++] = 0x9c; + if (datalen < 128) + buf[nbuf++] = datalen; + else if (datalen < 256) + { + buf[nbuf++] = 0x81; + buf[nbuf++] = datalen; + } + else + { + buf[nbuf++] = 0x82; + buf[nbuf++] = datalen << 8; + buf[nbuf++] = datalen; + } + memcpy (buf+nbuf, data, datalen); + sw = apdu_send_le (slot, extended_mode, + 0x00, CMD_PSO, 0x80, 0xa6, + datalen+nbuf, (const char *)buf, le, + result, resultlen); + xfree (buf); + if (sw != SW_SUCCESS) + { + /* Make sure that pending buffers are released. */ + xfree (*result); + *result = NULL; + *resultlen = 0; + return map_sw (sw); + } + + return 0; +} + + /* For LE see do_generate_keypair. */ gpg_error_t iso7816_internal_authenticate (int slot, int extended_mode, diff --git a/scd/iso7816.h b/scd/iso7816.h index f7934bb5b..d22f0bec5 100644 --- a/scd/iso7816.h +++ b/scd/iso7816.h @@ -110,6 +110,9 @@ gpg_error_t iso7816_decipher (int slot, int extended_mode, const unsigned char *data, size_t datalen, int le, int padind, unsigned char **result, size_t *resultlen); +gpg_error_t iso7816_pso_csv (int slot, int extended_mode, + const unsigned char *data, size_t datalen, int le, + unsigned char **result, size_t *resultlen); gpg_error_t iso7816_internal_authenticate (int slot, int extended_mode, const unsigned char *data, size_t datalen, int le,