diff --git a/.gitignore b/.gitignore index 01558bd..5696511 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/opensc-0.22.0.tar.gz +SOURCES/opensc-0.23.0.tar.gz diff --git a/.opensc.metadata b/.opensc.metadata index 07684ce..20c01e3 100644 --- a/.opensc.metadata +++ b/.opensc.metadata @@ -1 +1 @@ -d920880c72462619e0a1a629e0a637155b75a352 SOURCES/opensc-0.22.0.tar.gz +5a5367ef33efcc35ed420b191b4d1bc3aa34a538 SOURCES/opensc-0.23.0.tar.gz diff --git a/SOURCES/opensc-0.19.0-pinpad.patch b/SOURCES/opensc-0.19.0-pinpad.patch index f531b8b..03329b3 100644 --- a/SOURCES/opensc-0.19.0-pinpad.patch +++ b/SOURCES/opensc-0.19.0-pinpad.patch @@ -3,7 +3,7 @@ diff -up opensc-0.19.0/etc/opensc.conf.pinpad opensc-0.19.0/etc/opensc.conf +++ opensc-0.19.0/etc/opensc.conf 2018-10-22 14:33:59.939410701 +0200 @@ -4,4 +4,9 @@ app default { framework pkcs15 { - # use_file_caching = true; + # use_file_caching = public; } + reader_driver pcsc { + # The pinpad is disabled by default, diff --git a/SOURCES/opensc-0.22.0-detect-empty.patch b/SOURCES/opensc-0.22.0-detect-empty.patch deleted file mode 100644 index 671aba2..0000000 --- a/SOURCES/opensc-0.22.0-detect-empty.patch +++ /dev/null @@ -1,62 +0,0 @@ -From fe198e8b3837aa4c960e75d0e2a41020ad4dc9f9 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 24 Sep 2021 13:33:26 +0200 -Subject: [PATCH 1/9] pkcs11: Unbreak detection of unenrolled cards - -This was broken since 58b03b68, which tried to sanitize some states, -but caused C_GetTokenInfo returning CKR_TOKEN_NOT_RECOGNIZED instead -of empty token information. - -Note, that this has effect only if the configuration options -enable_default_driver and pkcs11_enable_InitToken are turned on. -Otherwise it still returns CKR_TOKEN_NOT_RECOGNIZED. ---- - src/pkcs11/framework-pkcs15.c | 17 +++++++++-------- - 1 file changed, 9 insertions(+), 8 deletions(-) - -diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c -index 74fe7b3c49..4205e41739 100644 ---- a/src/pkcs11/framework-pkcs15.c -+++ b/src/pkcs11/framework-pkcs15.c -@@ -544,9 +544,7 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) - { - struct sc_pkcs11_slot *slot; - struct pkcs15_fw_data *fw_data = NULL; -- struct sc_pkcs15_card *p15card = NULL; - struct sc_pkcs15_object *auth; -- struct sc_pkcs15_auth_info *pin_info; - CK_RV rv; - - sc_log(context, "C_GetTokenInfo(%lx)", slotID); -@@ -578,12 +576,6 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) - rv = sc_to_cryptoki_error(SC_ERROR_INTERNAL, "C_GetTokenInfo"); - goto out; - } -- p15card = fw_data->p15_card; -- if (!p15card) { -- rv = sc_to_cryptoki_error(SC_ERROR_INVALID_CARD, "C_GetTokenInfo"); -- goto out; -- } -- - /* User PIN flags are cleared before re-calculation */ - slot->token_info.flags &= ~(CKF_USER_PIN_COUNT_LOW|CKF_USER_PIN_FINAL_TRY|CKF_USER_PIN_LOCKED); - auth = slot_data_auth(slot->fw_data); -@@ -591,8 +583,17 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) - "C_GetTokenInfo() auth. object %p, token-info flags 0x%lX", auth, - slot->token_info.flags); - if (auth) { -+ struct sc_pkcs15_card *p15card = NULL; -+ struct sc_pkcs15_auth_info *pin_info = NULL; -+ - pin_info = (struct sc_pkcs15_auth_info*) auth->data; - -+ p15card = fw_data->p15_card; -+ if (!p15card) { -+ rv = sc_to_cryptoki_error(SC_ERROR_INVALID_CARD, "C_GetTokenInfo"); -+ goto out; -+ } -+ - sc_pkcs15_get_pin_info(p15card, auth); - - if (pin_info->tries_left >= 0) { - diff --git a/SOURCES/opensc-0.22.0-file-cache.patch b/SOURCES/opensc-0.22.0-file-cache.patch index 3702537..67b7f5f 100644 --- a/SOURCES/opensc-0.22.0-file-cache.patch +++ b/SOURCES/opensc-0.22.0-file-cache.patch @@ -5,8 +5,8 @@ diff -up opensc-0.22.0/etc/opensc.conf.file-cache opensc-0.22.0/etc/opensc.conf # debug = 3; # debug_file = opensc-debug.txt; framework pkcs15 { -- # use_file_caching = true; -+ use_file_caching = true; +- # use_file_caching = public; ++ use_file_caching = public; } reader_driver pcsc { # The pinpad is disabled by default, @@ -18,6 +18,6 @@ diff -up opensc-0.22.0/etc/opensc.conf.file-cache opensc-0.22.0/etc/opensc.conf +# brings more trouble than use so disable that: +app pkcs15-init { + framework pkcs15 { -+ use_file_caching = false; ++ use_file_caching = no; + } +} diff --git a/SOURCES/opensc-0.23.0-cardos-pkcs15init.patch b/SOURCES/opensc-0.23.0-cardos-pkcs15init.patch new file mode 100644 index 0000000..8d3d4fd --- /dev/null +++ b/SOURCES/opensc-0.23.0-cardos-pkcs15init.patch @@ -0,0 +1,50 @@ +From 81944d1529202bd28359bede57c0a15deb65ba8a Mon Sep 17 00:00:00 2001 +From: fullwaywang +Date: Mon, 29 May 2023 10:38:48 +0800 +Subject: [PATCH] pkcs15init: correct left length calculation to fix buffer + overrun bug. Fixes #2785 + +--- + src/pkcs15init/pkcs15-cardos.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c +index 9715cf390f..f41f73c349 100644 +--- a/src/pkcs15init/pkcs15-cardos.c ++++ b/src/pkcs15init/pkcs15-cardos.c +@@ -872,7 +872,7 @@ static int cardos_have_verifyrc_package(sc_card_t *card) + sc_apdu_t apdu; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + int r; +- const u8 *p = rbuf, *q; ++ const u8 *p = rbuf, *q, *pp; + size_t len, tlen = 0, ilen = 0; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x88); +@@ -888,13 +888,13 @@ static int cardos_have_verifyrc_package(sc_card_t *card) + return 0; + + while (len != 0) { +- p = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen); +- if (p == NULL) ++ pp = sc_asn1_find_tag(card->ctx, p, len, 0xe1, &tlen); ++ if (pp == NULL) + return 0; + if (card->type == SC_CARD_TYPE_CARDOS_M4_3) { + /* the verifyRC package on CardOS 4.3B use Manufacturer ID 0x01 */ + /* and Package Number 0x07 */ +- q = sc_asn1_find_tag(card->ctx, p, tlen, 0x01, &ilen); ++ q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x01, &ilen); + if (q == NULL || ilen != 4) + return 0; + if (q[0] == 0x07) +@@ -902,7 +902,7 @@ static int cardos_have_verifyrc_package(sc_card_t *card) + } else if (card->type == SC_CARD_TYPE_CARDOS_M4_4) { + /* the verifyRC package on CardOS 4.4 use Manufacturer ID 0x03 */ + /* and Package Number 0x02 */ +- q = sc_asn1_find_tag(card->ctx, p, tlen, 0x03, &ilen); ++ q = sc_asn1_find_tag(card->ctx, pp, tlen, 0x03, &ilen); + if (q == NULL || ilen != 4) + return 0; + if (q[0] == 0x02) + diff --git a/SOURCES/opensc-0.23.0-openpgp.patch b/SOURCES/opensc-0.23.0-openpgp.patch new file mode 100644 index 0000000..de7fa67 --- /dev/null +++ b/SOURCES/opensc-0.23.0-openpgp.patch @@ -0,0 +1,225 @@ +From 3b580b6fff9ac463ecc6e996cfaf573f62749368 Mon Sep 17 00:00:00 2001 +From: Frank Morgner +Date: Fri, 14 Apr 2023 12:02:54 +0200 +Subject: [PATCH 1/2] openpgp: identify OpenPGP compliance with bcd_version + rather than card type + +--- + src/libopensc/card-openpgp.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c +index fad32f0ce7..2ea5dc9d36 100644 +--- a/src/libopensc/card-openpgp.c ++++ b/src/libopensc/card-openpgp.c +@@ -1780,13 +1780,18 @@ pgp_get_pubkey_pem(sc_card_t *card, unsigned int tag, u8 *buf, size_t buf_len) + * p1: number of an instance (DO 7F21: 0x00 for AUT, 0x01 for DEC and 0x02 for SIG) + */ + static int +-pgp_select_data(sc_card_t *card, u8 p1){ ++pgp_select_data(sc_card_t *card, u8 p1) ++{ + sc_apdu_t apdu; + u8 apdu_data[6]; + int r; ++ struct pgp_priv_data *priv = DRVDATA(card); + + LOG_FUNC_CALLED(card->ctx); + ++ if (priv->bcd_version < OPENPGP_CARD_3_0) ++ LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); ++ + sc_log(card->ctx, "select data with: %u", p1); + + // create apdu data (taken from spec: SELECT DATA 7.2.5.) +@@ -2179,8 +2184,7 @@ pgp_set_security_env(sc_card_t *card, + /* The SC_SEC_ENV_ALG_PRESENT is set always so let it pass for GNUK */ + if ((env->flags & SC_SEC_ENV_ALG_PRESENT) + && (env->algorithm != SC_ALGORITHM_RSA) +- && (priv->bcd_version < OPENPGP_CARD_3_0) +- && (card->type != SC_CARD_TYPE_OPENPGP_GNUK)) ++ && (priv->bcd_version < OPENPGP_CARD_3_0)) + LOG_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, + "only RSA algorithm supported"); + +@@ -2944,13 +2948,13 @@ pgp_update_card_algorithms(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *ke + { + sc_algorithm_info_t *algo; + u8 id = key_info->key_id; ++ struct pgp_priv_data *priv = DRVDATA(card); + + LOG_FUNC_CALLED(card->ctx); + + /* protect incompatible cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA +- && card->type < SC_CARD_TYPE_OPENPGP_V3 +- && card->type != SC_CARD_TYPE_OPENPGP_GNUK) ++ && priv->bcd_version < OPENPGP_CARD_3_0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + + if (id > card->algorithm_count) { +@@ -2992,13 +2996,13 @@ pgp_gen_key(sc_card_t *card, sc_cardctl_openpgp_keygen_info_t *key_info) + size_t apdu_le; + size_t resplen = 0; + int r = SC_SUCCESS; ++ struct pgp_priv_data *priv = DRVDATA(card); + + LOG_FUNC_CALLED(card->ctx); + + /* protect incompatible cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA +- && card->type < SC_CARD_TYPE_OPENPGP_V3 +- && card->type != SC_CARD_TYPE_OPENPGP_GNUK) ++ && priv->bcd_version < OPENPGP_CARD_3_0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + if (key_info->algorithm == SC_OPENPGP_KEYALGO_EDDSA + && card->type != SC_CARD_TYPE_OPENPGP_GNUK) +@@ -3358,13 +3362,13 @@ pgp_store_key(sc_card_t *card, sc_cardctl_openpgp_keystore_info_t *key_info) + u8 *data = NULL; + size_t len = 0; + int r; ++ struct pgp_priv_data *priv = DRVDATA(card); + + LOG_FUNC_CALLED(card->ctx); + + /* protect incompatible cards against non-RSA */ + if (key_info->algorithm != SC_OPENPGP_KEYALGO_RSA +- && card->type < SC_CARD_TYPE_OPENPGP_V3 +- && card->type != SC_CARD_TYPE_OPENPGP_GNUK) ++ && priv->bcd_version < OPENPGP_CARD_3_0) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED); + + /* Validate */ + +From 9eccc1494d8303ffe42beb772732df218875e3ac Mon Sep 17 00:00:00 2001 +From: Frank Morgner +Date: Fri, 14 Apr 2023 12:09:55 +0200 +Subject: [PATCH 2/2] openpgp: ignore errors on SELECT DATA for OpenPGP 2 and + below + +fixes https://github.com/OpenSC/OpenSC/issues/2752 +--- + src/libopensc/pkcs15-openpgp.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c +index e2f3442238..9d3fd746a0 100644 +--- a/src/libopensc/pkcs15-openpgp.c ++++ b/src/libopensc/pkcs15-openpgp.c +@@ -556,14 +556,9 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) + memset(&cert_info, 0, sizeof(cert_info)); + memset(&cert_obj, 0, sizeof(cert_obj)); + +- /* only try to SELECT DATA for OpenPGP >= v3 */ +- if (card->type >= SC_CARD_TYPE_OPENPGP_V3) { +- r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i); +- if (r < 0) { +- free(buffer); +- LOG_TEST_RET(card->ctx, r, "Failed OpenPGP - select data"); +- } +- } ++ /* try to SELECT DATA. Will only work for OpenPGP >= v3, errors are non-critical */ ++ sc_card_ctl(card, SC_CARDCTL_OPENPGP_SELECT_DATA, &i); ++ + sc_format_path(certs[i].path, &cert_info.path); + + /* Certificate ID. We use the same ID as the authentication key */ + +commit e8fba322a2f4d06ec5c74fe80f9e2b0e9fdefec6 +Author: Jakub Jelen +Date: Fri May 19 16:49:00 2023 +0200 + + openpgp: Fix fingerprint calculation + + fixes https://github.com/OpenSC/OpenSC/issues/2775 + +diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c +index cc454cef..496e38e6 100644 +--- a/src/libopensc/card-openpgp.c ++++ b/src/libopensc/card-openpgp.c +@@ -2697,15 +2697,23 @@ pgp_calculate_and_store_fingerprint(sc_card_t *card, time_t ctime, + + /* RSA */ + if (key_info->algorithm == SC_OPENPGP_KEYALGO_RSA) { ++ unsigned short bytes_length = 0; ++ + *p = 1; /* Algorithm ID, RSA */ + p += 1; ++ ++ /* Modulus */ ++ bytes_length = BYTES4BITS(key_info->u.rsa.modulus_len); + ushort2bebytes(p, (unsigned short)key_info->u.rsa.modulus_len); + p += 2; +- memcpy(p, key_info->u.rsa.modulus, (BYTES4BITS(key_info->u.rsa.modulus_len))); +- p += (key_info->u.rsa.modulus_len >> 3); +- ushort2bebytes(++p, (unsigned short)key_info->u.rsa.exponent_len); ++ memcpy(p, key_info->u.rsa.modulus, bytes_length); ++ p += bytes_length; ++ ++ /* Exponent */ ++ bytes_length = BYTES4BITS(key_info->u.rsa.exponent_len); ++ ushort2bebytes(p, (unsigned short)key_info->u.rsa.exponent_len); + p += 2; +- memcpy(p, key_info->u.rsa.exponent, (BYTES4BITS(key_info->u.rsa.exponent_len))); ++ memcpy(p, key_info->u.rsa.exponent, bytes_length); + } + /* ECC */ + else if (key_info->algorithm == SC_OPENPGP_KEYALGO_ECDH + +commit 891f10e49de1a5ee038b1cb2fb59dce40429e6c2 +Author: Jakub Jelen +Date: Fri May 19 17:53:35 2023 +0200 + + openpgp: Fix modulus length calculation in pkc15init layer + +diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h +index 5a0a19c5..ba685a30 100644 +--- a/src/libopensc/pkcs15.h ++++ b/src/libopensc/pkcs15.h +@@ -373,7 +373,7 @@ struct sc_pkcs15_prkey_info { + unsigned int usage, access_flags; + int native, key_reference; + /* convert to union if other types are supported */ +- size_t modulus_length; /* RSA */ ++ size_t modulus_length; /* RSA, in bits */ + size_t field_length; /* EC in bits */ + + unsigned int algo_refs[SC_MAX_SUPPORTED_ALGORITHMS]; +diff --git a/src/pkcs15init/pkcs15-openpgp.c b/src/pkcs15init/pkcs15-openpgp.c +index c75bcbda..3e060be5 100644 +--- a/src/pkcs15init/pkcs15-openpgp.c ++++ b/src/pkcs15init/pkcs15-openpgp.c +@@ -235,7 +235,7 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj, + + /* Prepare buffer */ + key_info.u.rsa.modulus_len = required->modulus_length; +- key_info.u.rsa.modulus = calloc(required->modulus_length >> 3, 1); ++ key_info.u.rsa.modulus = calloc(BYTES4BITS(required->modulus_length), 1); + if (key_info.u.rsa.modulus == NULL) + LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_ENOUGH_MEMORY); + +@@ -252,18 +252,18 @@ static int openpgp_generate_key_rsa(sc_card_t *card, sc_pkcs15_object_t *obj, + + pubkey->algorithm = SC_ALGORITHM_RSA; + sc_log(ctx, "Set output modulus info"); +- pubkey->u.rsa.modulus.len = key_info.u.rsa.modulus_len; +- pubkey->u.rsa.modulus.data = calloc(key_info.u.rsa.modulus_len, 1); ++ pubkey->u.rsa.modulus.len = BYTES4BITS(key_info.u.rsa.modulus_len); ++ pubkey->u.rsa.modulus.data = calloc(pubkey->u.rsa.modulus.len, 1); + if (pubkey->u.rsa.modulus.data == NULL) + goto err; +- memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, key_info.u.rsa.modulus_len); ++ memcpy(pubkey->u.rsa.modulus.data, key_info.u.rsa.modulus, BYTES4BITS(key_info.u.rsa.modulus_len)); + + sc_log(ctx, "Set output exponent info"); +- pubkey->u.rsa.exponent.len = key_info.u.rsa.exponent_len; +- pubkey->u.rsa.exponent.data = calloc(BYTES4BITS(key_info.u.rsa.exponent_len), 1); ++ pubkey->u.rsa.exponent.len = BYTES4BITS(key_info.u.rsa.exponent_len); ++ pubkey->u.rsa.exponent.data = calloc(pubkey->u.rsa.exponent.len, 1); + if (pubkey->u.rsa.exponent.data == NULL) + goto err; +- memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, BYTES4BITS(key_info.u.rsa.exponent_len)); ++ memcpy(pubkey->u.rsa.exponent.data, key_info.u.rsa.exponent, pubkey->u.rsa.exponent.len); + + err: + free(key_info.u.rsa.modulus); diff --git a/SOURCES/opensc-0.23.0-openssl-ctx.patch b/SOURCES/opensc-0.23.0-openssl-ctx.patch new file mode 100644 index 0000000..7244f89 --- /dev/null +++ b/SOURCES/opensc-0.23.0-openssl-ctx.patch @@ -0,0 +1,3047 @@ +From 739fa81050989c3f85ca883ec76542b71cae7edc Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 12 Dec 2022 12:23:20 +0100 +Subject: [PATCH] Avoid memory leak + +Thanks coverity: CID 382262 +--- + src/sm/sm-common.c | 24 ++++++++++++++---------- + src/smm/sm-global-platform.c | 3 +-- + 2 files changed, 15 insertions(+), 12 deletions(-) + +diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c +index ce60a83a4..caada2b7e 100644 +--- a/src/sm/sm-common.c ++++ b/src/sm/sm-common.c +@@ -363,11 +363,9 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, + int tmplen; + #endif + +- + if (!out || !out_len) + return -1; + +- + *out_len = data_len + 7; + *out_len -= *out_len % 8; + +@@ -385,29 +383,35 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, + for (ii=0; iicard_challenge + 4, 4); +@@ -108,7 +108,6 @@ sc_gp_get_session_key(struct sc_context *ctx, struct sm_gp_session *gp_session, + if (sm_encrypt_des_ecb3(key, deriv, 16, &out, &out_len)) { + if (ctx) + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM GP get session key: des_ecb3 encryption error"); +- free(out); + return NULL; + } + else if (out==NULL || out_len!=16) { +-- +2.39.2 + + + +From 7efc2c8be8178e352af682b91f7ebe3c3ca1d8b6 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 13:29:42 -0500 +Subject: [PATCH 01/20] Add support to initialize custom OpenSSL context + +Add an openssl custom libcontext to sc_context_t and intitalize it if we +are using OpenSSL 3.0+ + +Signed-off-by: Simo Sorce +--- + src/libopensc/ctx.c | 47 +++++++++++++++++++++++++++++++++- + src/libopensc/opensc.h | 6 +++++ + src/libopensc/sc-ossl-compat.h | 14 ++++++++++ + 3 files changed, 66 insertions(+), 1 deletion(-) + +diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c +index 5b637b8e88..c1643bc489 100644 +--- a/src/libopensc/ctx.c ++++ b/src/libopensc/ctx.c +@@ -804,6 +804,40 @@ int sc_context_repair(sc_context_t **ctx_out) + return SC_SUCCESS; + } + ++#ifdef USE_OPENSSL3_LIBCTX ++static int sc_openssl3_init(sc_context_t *ctx) ++{ ++ ctx->ossl3ctx = calloc(1, sizeof(ossl3ctx_t)); ++ if (ctx->ossl3ctx == NULL) ++ return SC_ERROR_OUT_OF_MEMORY; ++ ctx->ossl3ctx->libctx = OSSL_LIB_CTX_new(); ++ if (ctx->ossl3ctx->libctx == NULL) { ++ return SC_ERROR_INTERNAL; ++ } ++ ctx->ossl3ctx->defprov = OSSL_PROVIDER_load(ctx->ossl3ctx->libctx, ++ "default"); ++ if (ctx->ossl3ctx->defprov == NULL) { ++ OSSL_LIB_CTX_free(ctx->ossl3ctx->libctx); ++ free(ctx->ossl3ctx); ++ ctx->ossl3ctx = NULL; ++ return SC_ERROR_INTERNAL; ++ } ++ return SC_SUCCESS; ++} ++ ++static void sc_openssl3_deinit(sc_context_t *ctx) ++{ ++ if (ctx->ossl3ctx == NULL) ++ return; ++ if (ctx->ossl3ctx->defprov) ++ OSSL_PROVIDER_unload(ctx->ossl3ctx->defprov); ++ if (ctx->ossl3ctx->libctx) ++ OSSL_LIB_CTX_free(ctx->ossl3ctx->libctx); ++ free(ctx->ossl3ctx); ++ ctx->ossl3ctx = NULL; ++} ++#endif ++ + int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) + { + sc_context_t *ctx; +@@ -858,6 +892,15 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) + sc_log(ctx, "==================================="); /* first thing in the log */ + sc_log(ctx, "opensc version: %s", sc_get_version()); + ++#ifdef USE_OPENSSL3_LIBCTX ++ r = sc_openssl3_init(ctx); ++ if (r != SC_SUCCESS) { ++ del_drvs(&opts); ++ sc_release_context(ctx); ++ return r; ++ } ++#endif ++ + #ifdef ENABLE_PCSC + ctx->reader_driver = sc_get_pcsc_driver(); + #elif defined(ENABLE_CRYPTOTOKENKIT) +@@ -923,7 +966,6 @@ int sc_wait_for_event(sc_context_t *ctx, unsigned int event_mask, sc_reader_t ** + return SC_ERROR_NOT_SUPPORTED; + } + +- + int sc_release_context(sc_context_t *ctx) + { + unsigned int i; +@@ -948,6 +990,9 @@ int sc_release_context(sc_context_t *ctx) + if (drv->dll) + sc_dlclose(drv->dll); + } ++#ifdef USE_OPENSSL3_LIBCTX ++ sc_openssl3_deinit(ctx); ++#endif + if (ctx->preferred_language != NULL) + free(ctx->preferred_language); + if (ctx->mutex != NULL) { +diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h +index c58550d602..958edcb98d 100644 +--- a/src/libopensc/opensc.h ++++ b/src/libopensc/opensc.h +@@ -867,6 +867,8 @@ typedef struct { + #define SC_CTX_FLAG_DISABLE_POPUPS 0x00000010 + #define SC_CTX_FLAG_DISABLE_COLORS 0x00000020 + ++typedef struct ossl3ctx ossl3ctx_t; ++ + typedef struct sc_context { + scconf_context *conf; + scconf_block *conf_blocks[3]; +@@ -889,6 +891,10 @@ typedef struct sc_context { + sc_thread_context_t *thread_ctx; + void *mutex; + ++#ifdef ENABLE_OPENSSL ++ ossl3ctx_t *ossl3ctx; ++#endif ++ + unsigned int magic; + } sc_context_t; + +diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h +index 4425da93f3..1b98b9f04d 100644 +--- a/src/libopensc/sc-ossl-compat.h ++++ b/src/libopensc/sc-ossl-compat.h +@@ -65,6 +65,20 @@ extern "C" { + #define FIPS_mode() EVP_default_properties_is_fips_enabled(NULL) + #endif + ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ ++#define USE_OPENSSL3_LIBCTX ++ ++#include ++#include ++ ++typedef struct ossl3ctx { ++ OSSL_LIB_CTX *libctx; ++ OSSL_PROVIDER *defprov; ++} ossl3ctx_t; ++ ++#endif ++ + #ifdef __cplusplus + } + #endif /* __cplusplus */ + +From 04ccab829e21c7540bd6129f4cc2066cc8e427ba Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 13:30:48 -0500 +Subject: [PATCH 02/20] Convert pkcs11/openssl.c to use the custom osslctx + +Signed-off-by: Simo Sorce +--- + src/libopensc/sc-ossl-compat.h | 40 ++++++++++++++ + src/pkcs11/openssl.c | 96 ++++++++++++++++++++++++---------- + 2 files changed, 109 insertions(+), 27 deletions(-) + +diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h +index 1b98b9f04d..8e976184b6 100644 +--- a/src/libopensc/sc-ossl-compat.h ++++ b/src/libopensc/sc-ossl-compat.h +@@ -71,14 +71,54 @@ extern "C" { + + #include + #include ++#include + + typedef struct ossl3ctx { + OSSL_LIB_CTX *libctx; + OSSL_PROVIDER *defprov; + } ossl3ctx_t; + ++static inline EVP_MD *_sc_evp_md(ossl3ctx_t *ctx, const char *algorithm) ++{ ++ return EVP_MD_fetch(ctx->libctx, algorithm, NULL); ++} ++#define sc_evp_md(ctx, alg) _sc_evp_md((ctx)->ossl3ctx, alg) ++ ++static inline void sc_evp_md_free(EVP_MD *md) ++{ ++ EVP_MD_free(md); ++} ++ ++static inline EVP_PKEY_CTX *_sc_evp_pkey_ctx_new(ossl3ctx_t *ctx, ++ EVP_PKEY *pkey) ++{ ++ return EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, NULL); ++} ++#define sc_evp_pkey_ctx_new(ctx, pkey) \ ++ _sc_evp_pkey_ctx_new((ctx)->ossl3ctx, pkey) ++ ++#else /* OPENSSL < 3 */ ++ ++#include ++ ++static inline EVP_MD *sc_evp_md(void *unused, const char *algorithm) ++{ ++ return (EVP_MD *)EVP_get_digestbyname(algorithm); ++} ++ ++static inline void sc_evp_md_free(EVP_MD *md) ++{ ++ return; ++} ++ ++static inline EVP_PKEY_CTX *sc_evp_pkey_ctx_new(void *unused, EVP_PKEY *pkey) ++{ ++ return EVP_PKEY_CTX_new(pkey, NULL); ++} ++ + #endif + ++ + #ifdef __cplusplus + } + #endif /* __cplusplus */ +diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c +index 6879e9e061..f62c32fa3f 100644 +--- a/src/pkcs11/openssl.c ++++ b/src/pkcs11/openssl.c +@@ -231,6 +231,23 @@ static void * dup_mem(void *in, size_t in_len) + return out; + } + ++static CK_RV ossl_md_copy(const void *src, void **dst) ++{ ++#if OPENSSL_VERSION_NUMBER >= 0x30000000L ++ int ret = EVP_MD_up_ref((EVP_MD *)src); ++ if (ret != 1) { ++ return CKR_GENERAL_ERROR; ++ } ++#endif ++ *dst = (EVP_MD *)src; ++ return CKR_OK; ++} ++ ++static void ossl_md_free(const void *md) ++{ ++ sc_evp_md_free((EVP_MD *)md); ++} ++ + void + sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) + { +@@ -287,38 +304,52 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *p11card) + #endif /* !defined(OPENSSL_NO_ENGINE) */ + #endif /* OPENSSL_VERSION_NUMBER < 0x30000000L */ + +- openssl_sha1_mech.mech_data = EVP_sha1(); ++ openssl_sha1_mech.mech_data = sc_evp_md(context, "sha1"); ++ openssl_sha1_mech.free_mech_data = ossl_md_free; ++ openssl_sha1_mech.copy_mech_data = ossl_md_copy; + mt = dup_mem(&openssl_sha1_mech, sizeof openssl_sha1_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(&mt); + +- openssl_sha224_mech.mech_data = EVP_sha224(); ++ openssl_sha224_mech.mech_data = sc_evp_md(context, "sha224"); ++ openssl_sha224_mech.free_mech_data = ossl_md_free; ++ openssl_sha224_mech.copy_mech_data = ossl_md_copy; + mt = dup_mem(&openssl_sha224_mech, sizeof openssl_sha224_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(&mt); + +- openssl_sha256_mech.mech_data = EVP_sha256(); ++ openssl_sha256_mech.mech_data = sc_evp_md(context, "sha256"); ++ openssl_sha256_mech.free_mech_data = ossl_md_free; ++ openssl_sha256_mech.copy_mech_data = ossl_md_copy; + mt = dup_mem(&openssl_sha256_mech, sizeof openssl_sha256_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(&mt); + +- openssl_sha384_mech.mech_data = EVP_sha384(); ++ openssl_sha384_mech.mech_data = sc_evp_md(context, "sha384"); ++ openssl_sha384_mech.free_mech_data = ossl_md_free; ++ openssl_sha384_mech.copy_mech_data = ossl_md_copy; + mt = dup_mem(&openssl_sha384_mech, sizeof openssl_sha384_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(&mt); + +- openssl_sha512_mech.mech_data = EVP_sha512(); ++ openssl_sha512_mech.mech_data = sc_evp_md(context, "sha512"); ++ openssl_sha512_mech.free_mech_data = ossl_md_free; ++ openssl_sha512_mech.copy_mech_data = ossl_md_copy; + mt = dup_mem(&openssl_sha512_mech, sizeof openssl_sha512_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(&mt); + + if (!FIPS_mode()) { +- openssl_md5_mech.mech_data = EVP_md5(); ++ openssl_md5_mech.mech_data = sc_evp_md(context, "md5"); ++ openssl_md5_mech.free_mech_data = ossl_md_free; ++ openssl_md5_mech.copy_mech_data = ossl_md_copy; + mt = dup_mem(&openssl_md5_mech, sizeof openssl_md5_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(&mt); + +- openssl_ripemd160_mech.mech_data = EVP_ripemd160(); ++ openssl_ripemd160_mech.mech_data = sc_evp_md(context, "ripemd160"); ++ openssl_ripemd160_mech.free_mech_data = ossl_md_free; ++ openssl_ripemd160_mech.copy_mech_data = ossl_md_copy; + mt = dup_mem(&openssl_ripemd160_mech, sizeof openssl_ripemd160_mech); + sc_pkcs11_register_mechanism(p11card, mt, NULL); + sc_pkcs11_free_mechanism(&mt); +@@ -654,22 +685,22 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len + || mech->mechanism == CKM_ECDSA_SHA384 + || mech->mechanism == CKM_ECDSA_SHA512) { + EVP_MD_CTX *mdctx; +- const EVP_MD *md; ++ EVP_MD *md = NULL; + switch (mech->mechanism) { + case CKM_ECDSA_SHA1: +- md = EVP_sha1(); ++ md = sc_evp_md(context, "sha1"); + break; + case CKM_ECDSA_SHA224: +- md = EVP_sha224(); ++ md = sc_evp_md(context, "sha224"); + break; + case CKM_ECDSA_SHA256: +- md = EVP_sha256(); ++ md = sc_evp_md(context, "sha256"); + break; + case CKM_ECDSA_SHA384: +- md = EVP_sha384(); ++ md = sc_evp_md(context, "sha384"); + break; + case CKM_ECDSA_SHA512: +- md = EVP_sha512(); ++ md = sc_evp_md(context, "sha512"); + break; + default: + EVP_PKEY_free(pkey); +@@ -679,11 +710,13 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len + mdbuf = calloc(1, mdbuf_len); + if (mdbuf == NULL) { + EVP_PKEY_free(pkey); ++ sc_evp_md_free(md); + return CKR_DEVICE_MEMORY; + } + if ((mdctx = EVP_MD_CTX_new()) == NULL) { + free(mdbuf); + EVP_PKEY_free(pkey); ++ sc_evp_md_free(md); + return CKR_GENERAL_ERROR; + } + if (!EVP_DigestInit(mdctx, md) +@@ -691,10 +724,12 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len + || !EVP_DigestFinal(mdctx, mdbuf, &mdbuf_len)) { + EVP_PKEY_free(pkey); + EVP_MD_CTX_free(mdctx); ++ sc_evp_md_free(md); + free(mdbuf); + return CKR_GENERAL_ERROR; + } + EVP_MD_CTX_free(mdctx); ++ sc_evp_md_free(md); + data = mdbuf; + data_len = mdbuf_len; + } +@@ -702,7 +737,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len + res = 0; + r = sc_asn1_sig_value_rs_to_sequence(NULL, signat, signat_len, + &signat_tmp, &signat_len_tmp); +- ctx = EVP_PKEY_CTX_new(pkey, NULL); ++ ctx = sc_evp_pkey_ctx_new(context, pkey); + if (r == 0 && EVP_PKEY_base_id(pkey) == EVP_PKEY_EC && ctx && EVP_PKEY_verify_init(ctx) == 1) + res = EVP_PKEY_verify(ctx, signat_tmp, signat_len_tmp, data, data_len); + +@@ -721,7 +756,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len + } else { + unsigned char *rsa_out = NULL, pad; + size_t rsa_outlen = 0; +- EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pkey, NULL); ++ EVP_PKEY_CTX *ctx = sc_evp_pkey_ctx_new(context, pkey); + if (!ctx) { + EVP_PKEY_free(pkey); + return CKR_DEVICE_MEMORY; +@@ -783,7 +818,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len + mech->mechanism == CKM_SHA384_RSA_PKCS_PSS || + mech->mechanism == CKM_SHA512_RSA_PKCS_PSS) { + CK_RSA_PKCS_PSS_PARAMS* param = NULL; +- const EVP_MD *mgf_md, *pss_md; ++ EVP_MD *mgf_md = NULL, *pss_md = NULL; + unsigned char digest[EVP_MAX_MD_SIZE]; + + if (mech->pParameter == NULL) { +@@ -796,19 +831,19 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len + param = (CK_RSA_PKCS_PSS_PARAMS*)mech->pParameter; + switch (param->mgf) { + case CKG_MGF1_SHA1: +- mgf_md = EVP_sha1(); ++ mgf_md = sc_evp_md(context, "sha1"); + break; + case CKG_MGF1_SHA224: +- mgf_md = EVP_sha224(); ++ mgf_md = sc_evp_md(context, "sha224"); + break; + case CKG_MGF1_SHA256: +- mgf_md = EVP_sha256(); ++ mgf_md = sc_evp_md(context, "sha256"); + break; + case CKG_MGF1_SHA384: +- mgf_md = EVP_sha384(); ++ mgf_md = sc_evp_md(context, "sha384"); + break; + case CKG_MGF1_SHA512: +- mgf_md = EVP_sha512(); ++ mgf_md = sc_evp_md(context, "sha512"); + break; + default: + free(rsa_out); +@@ -818,21 +853,22 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len + + switch (param->hashAlg) { + case CKM_SHA_1: +- pss_md = EVP_sha1(); ++ pss_md = sc_evp_md(context, "sha1"); + break; + case CKM_SHA224: +- pss_md = EVP_sha224(); ++ pss_md = sc_evp_md(context, "sha224"); + break; + case CKM_SHA256: +- pss_md = EVP_sha256(); ++ pss_md = sc_evp_md(context, "sha256"); + break; + case CKM_SHA384: +- pss_md = EVP_sha384(); ++ pss_md = sc_evp_md(context, "sha384"); + break; + case CKM_SHA512: +- pss_md = EVP_sha512(); ++ pss_md = sc_evp_md(context, "sha512"); + break; + default: ++ sc_evp_md_free(mgf_md); + free(rsa_out); + EVP_PKEY_free(pkey); + return CKR_MECHANISM_PARAM_INVALID; +@@ -848,6 +884,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len + unsigned int tmp_len; + + if (!md_ctx || !EVP_DigestFinal(md_ctx, tmp, &tmp_len)) { ++ sc_evp_md_free(mgf_md); ++ sc_evp_md_free(pss_md); + free(rsa_out); + EVP_PKEY_free(pkey); + return CKR_GENERAL_ERROR; +@@ -865,13 +903,15 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len + else + sLen = param->sLen; + +- if ((ctx = EVP_PKEY_CTX_new(pkey, NULL)) == NULL || ++ if ((ctx = sc_evp_pkey_ctx_new(context, pkey)) == NULL || + EVP_PKEY_verify_init(ctx) != 1 || + EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING) != 1 || + EVP_PKEY_CTX_set_signature_md(ctx, pss_md) != 1 || + EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, sLen) != 1 || + EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, mgf_md) != 1) { + sc_log(context, "Failed to initialize EVP_PKEY_CTX"); ++ sc_evp_md_free(mgf_md); ++ sc_evp_md_free(pss_md); + free(rsa_out); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); +@@ -883,6 +923,8 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, unsigned int pubkey_len + rv = CKR_OK; + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); ++ sc_evp_md_free(mgf_md); ++ sc_evp_md_free(pss_md); + free(rsa_out); + sc_log(context, "Returning %lu", rv); + return rv; + +From 25a916bbeeda1827f0d1cc631b41d5a3da032f60 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 15:05:13 -0500 +Subject: [PATCH 03/20] Load also the legacy provider + +This is not ideal, but some of the code uses legacy algorithms that are +not available without this provider. + +The code that depends on those legacy algorithms will fail if the legacy +provider is not available (which is a legitimate choice by the admin and/or +system integrator). Therefore we just report an error but do not fail +initialization if the legacy provider is not available. + +Signed-off-by: Simo Sorce +--- + src/libopensc/ctx.c | 7 +++++++ + src/libopensc/sc-ossl-compat.h | 1 + + 2 files changed, 8 insertions(+) + +diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c +index c1643bc489..6d4a7c5593 100644 +--- a/src/libopensc/ctx.c ++++ b/src/libopensc/ctx.c +@@ -822,6 +822,11 @@ static int sc_openssl3_init(sc_context_t *ctx) + ctx->ossl3ctx = NULL; + return SC_ERROR_INTERNAL; + } ++ ctx->ossl3ctx->legacyprov = OSSL_PROVIDER_load(ctx->ossl3ctx->libctx, ++ "legacy"); ++ if (ctx->ossl3ctx->legacyprov == NULL) { ++ sc_log(ctx, "Failed to load OpenSSL Legacy provider"); ++ } + return SC_SUCCESS; + } + +@@ -829,6 +834,8 @@ static void sc_openssl3_deinit(sc_context_t *ctx) + { + if (ctx->ossl3ctx == NULL) + return; ++ if (ctx->ossl3ctx->legacyprov) ++ OSSL_PROVIDER_unload(ctx->ossl3ctx->legacyprov); + if (ctx->ossl3ctx->defprov) + OSSL_PROVIDER_unload(ctx->ossl3ctx->defprov); + if (ctx->ossl3ctx->libctx) +diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h +index 8e976184b6..579d7f83f9 100644 +--- a/src/libopensc/sc-ossl-compat.h ++++ b/src/libopensc/sc-ossl-compat.h +@@ -76,6 +76,7 @@ extern "C" { + typedef struct ossl3ctx { + OSSL_LIB_CTX *libctx; + OSSL_PROVIDER *defprov; ++ OSSL_PROVIDER *legacyprov; + } ossl3ctx_t; + + static inline EVP_MD *_sc_evp_md(ossl3ctx_t *ctx, const char *algorithm) + +From 0a111e41634cf6bbb3dad7c0d4c90b173bd20b74 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 14:47:26 -0500 +Subject: [PATCH 04/20] Add wrappers for EVP_CIPHERs + +Signed-off-by: Simo Sorce +--- + src/libopensc/sc-ossl-compat.h | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/src/libopensc/sc-ossl-compat.h b/src/libopensc/sc-ossl-compat.h +index 579d7f83f9..942de1175f 100644 +--- a/src/libopensc/sc-ossl-compat.h ++++ b/src/libopensc/sc-ossl-compat.h +@@ -98,6 +98,17 @@ static inline EVP_PKEY_CTX *_sc_evp_pkey_ctx_new(ossl3ctx_t *ctx, + #define sc_evp_pkey_ctx_new(ctx, pkey) \ + _sc_evp_pkey_ctx_new((ctx)->ossl3ctx, pkey) + ++static inline EVP_CIPHER *_sc_evp_cipher(ossl3ctx_t *ctx, const char *algorithm) ++{ ++ return EVP_CIPHER_fetch(ctx->libctx, algorithm, NULL); ++} ++#define sc_evp_cipher(ctx, alg) _sc_evp_cipher((ctx)->ossl3ctx, alg) ++ ++static inline void sc_evp_cipher_free(EVP_CIPHER *cipher) ++{ ++ EVP_CIPHER_free(cipher); ++} ++ + #else /* OPENSSL < 3 */ + + #include +@@ -117,6 +128,16 @@ static inline EVP_PKEY_CTX *sc_evp_pkey_ctx_new(void *unused, EVP_PKEY *pkey) + return EVP_PKEY_CTX_new(pkey, NULL); + } + ++static inline EVP_CIPHER *sc_evp_cipher(void *unused, const char *algorithm) ++{ ++ return (EVP_CIPHER *)EVP_get_cipherbyname(algorithm); ++} ++ ++static inline void sc_evp_cipher_free(EVP_CIPHER *cipher) ++{ ++ return; ++} ++ + #endif + + + +From 92d178216e9ab5737102805e9dfbb06bbd446332 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 14:48:46 -0500 +Subject: [PATCH 05/20] Convert card entersafe to use openssl libctx + +Signed-off-by: Simo Sorce +--- + src/libopensc/card-entersafe.c | 29 +++++++++++++++++++++-------- + 1 file changed, 21 insertions(+), 8 deletions(-) + +diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c +index 24f2c75877..ec81f0eaa1 100644 +--- a/src/libopensc/card-entersafe.c ++++ b/src/libopensc/card-entersafe.c +@@ -199,6 +199,8 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, + u8 *buff, size_t buffsize) + { + EVP_CIPHER_CTX * ctx = NULL; ++ EVP_CIPHER *alg = NULL; ++ + u8 iv[8]={0}; + int len; + +@@ -220,20 +222,27 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, + LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY); + EVP_CIPHER_CTX_set_padding(ctx,0); + +- if(keylen == 8) +- EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, key, iv); +- else if (keylen == 16) +- EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, key, iv); +- else ++ if (keylen == 8) { ++ alg = sc_evp_cipher(card->ctx, "DES-ECB"); ++ EVP_EncryptInit_ex(ctx, alg, NULL, key, iv); ++ } else if (keylen == 16) { ++ alg = sc_evp_cipher(card->ctx, "DES-EDE"); ++ EVP_EncryptInit_ex(ctx, alg, NULL, key, iv); ++ } else { ++ EVP_CIPHER_CTX_free(ctx); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); +- ++ } ++ + len = apdu->lc; + if(!EVP_EncryptUpdate(ctx, buff, &len, buff, buffsize)){ ++ sc_evp_cipher_free(alg); ++ EVP_CIPHER_CTX_free(ctx); + sc_log(card->ctx, "entersafe encryption error."); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + apdu->lc = len; + ++ sc_evp_cipher_free(alg); + EVP_CIPHER_CTX_free(ctx); + + if(apdu->lc!=buffsize) +@@ -258,6 +267,7 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, + size_t tmpsize=0,tmpsize_rounded=0; + int outl=0; + EVP_CIPHER_CTX * ctx = NULL; ++ EVP_CIPHER *alg = NULL; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + +@@ -301,7 +311,8 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, + goto out; + } + EVP_CIPHER_CTX_set_padding(ctx,0); +- EVP_EncryptInit_ex(ctx, EVP_des_cbc(), NULL, key, iv); ++ alg = sc_evp_cipher(card->ctx, "DES-CBC"); ++ EVP_EncryptInit_ex(ctx, alg, NULL, key, iv); + + if(tmpsize_rounded>8){ + if(!EVP_EncryptUpdate(ctx,tmp_rounded,&outl,tmp_rounded,tmpsize_rounded-8)){ +@@ -338,8 +349,10 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, + free(tmp); + if(tmp_rounded) + free(tmp_rounded); +- if (ctx) ++ if (ctx) { ++ sc_evp_cipher_free(alg); + EVP_CIPHER_CTX_free(ctx); ++ } + + SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r); + } + +From f16cdd1dc816c4fc6210edc3f23990b556515119 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 15:41:59 -0500 +Subject: [PATCH 06/20] Convert card epass2003 to use openssl libctx + +Signed-off-by: Simo Sorce +--- + src/libopensc/card-epass2003.c | 188 +++++++++++++++++++++------------ + 1 file changed, 119 insertions(+), 69 deletions(-) + +diff --git a/src/libopensc/card-epass2003.c b/src/libopensc/card-epass2003.c +index d8a88fa376..335dba7dfb 100644 +--- a/src/libopensc/card-epass2003.c ++++ b/src/libopensc/card-epass2003.c +@@ -238,7 +238,7 @@ static const sec_attr_to_acl_entries_t sec_attr_to_acl_entry[] = { + static int epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu); + static int epass2003_select_file(struct sc_card *card, const sc_path_t * in_path, sc_file_t ** file_out); + int epass2003_refresh(struct sc_card *card); +-static int hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType); ++static int hash_data(struct sc_card *card, const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType); + + static int + epass2003_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2) +@@ -337,8 +337,8 @@ openssl_dec(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned + } + + static int +-aes128_encrypt_cmac_ft(const unsigned char *key, int keysize, +- const unsigned char *input, size_t length, unsigned char *output,unsigned char *iv) ++aes128_encrypt_cmac_ft(struct sc_card *card, const unsigned char *key, int keysize, ++ const unsigned char *input, size_t length, unsigned char *output,unsigned char *iv) + { + unsigned char data1[32] = {0}; + unsigned char data2[32] = {0}; +@@ -354,10 +354,13 @@ aes128_encrypt_cmac_ft(const unsigned char *key, int keysize, + int r = SC_ERROR_INTERNAL; + unsigned char out[32] = {0}; + unsigned char iv0[EVP_MAX_IV_LENGTH] = {0}; +- r = openssl_enc(EVP_aes_128_ecb(), key, iv0, data1, 16, out); +- if( r != SC_SUCCESS) ++ EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-ECB"); ++ r = openssl_enc(alg, key, iv0, data1, 16, out); ++ if (r != SC_SUCCESS) { ++ sc_evp_cipher_free(alg); + return r; +- ++ } ++ + check = out[0]; + enc1 = BN_new(); + lenc1 = BN_new(); +@@ -396,12 +399,14 @@ aes128_encrypt_cmac_ft(const unsigned char *key, int keysize, + for (int i=0;i<16;i++){ + data2[i]=data2[i]^k2Bin[offset + i]; + } +- return openssl_enc(EVP_aes_128_cbc(), key, iv, data2, 16, output); ++ r = openssl_enc(alg, key, iv, data2, 16, output); ++ sc_evp_cipher_free(alg); ++ return r; + } + + static int +-aes128_encrypt_cmac(const unsigned char *key, int keysize, +- const unsigned char *input, size_t length, unsigned char *output) ++aes128_encrypt_cmac(struct sc_card *card, const unsigned char *key, int keysize, ++ const unsigned char *input, size_t length, unsigned char *output) + { + size_t mactlen = 0; + int r = SC_ERROR_INTERNAL; +@@ -424,7 +429,7 @@ aes128_encrypt_cmac(const unsigned char *key, int keysize, + err: + CMAC_CTX_free(ctx); + #else +- EVP_MAC *mac = EVP_MAC_fetch(NULL, "cmac", NULL); ++ EVP_MAC *mac = EVP_MAC_fetch(card->ctx->ossl3ctx->libctx, "cmac", NULL); + if(mac == NULL){ + return r; + } +@@ -456,36 +461,50 @@ aes128_encrypt_cmac(const unsigned char *key, int keysize, + } + + static int +-aes128_encrypt_ecb(const unsigned char *key, int keysize, ++aes128_encrypt_ecb(struct sc_card *card, const unsigned char *key, int keysize, + const unsigned char *input, size_t length, unsigned char *output) + { + unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; +- return openssl_enc(EVP_aes_128_ecb(), key, iv, input, length, output); ++ EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-ECB"); ++ int r; ++ r = openssl_enc(alg, key, iv, input, length, output); ++ sc_evp_cipher_free(alg); ++ return r; + } + + + static int +-aes128_encrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[16], ++aes128_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[16], + const unsigned char *input, size_t length, unsigned char *output) + { +- return openssl_enc(EVP_aes_128_cbc(), key, iv, input, length, output); ++ EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-CBC"); ++ int r; ++ r = openssl_enc(alg, key, iv, input, length, output); ++ sc_evp_cipher_free(alg); ++ return r; + } + + + static int +-aes128_decrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[16], ++aes128_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[16], + const unsigned char *input, size_t length, unsigned char *output) + { +- return openssl_dec(EVP_aes_128_cbc(), key, iv, input, length, output); ++ EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "AES-128-CBC"); ++ int r; ++ r = openssl_dec(alg, key, iv, input, length, output); ++ sc_evp_cipher_free(alg); ++ return r; + } + + + static int +-des3_encrypt_ecb(const unsigned char *key, int keysize, ++des3_encrypt_ecb(struct sc_card *card, const unsigned char *key, int keysize, + const unsigned char *input, int length, unsigned char *output) + { + unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; + unsigned char bKey[24] = { 0 }; ++ EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3"); ++ int r; + + if (keysize == 16) { + memcpy(&bKey[0], key, 16); +@@ -495,15 +514,19 @@ des3_encrypt_ecb(const unsigned char *key, int keysize, + memcpy(&bKey[0], key, 24); + } + +- return openssl_enc(EVP_des_ede3(), bKey, iv, input, length, output); ++ r = openssl_enc(alg, bKey, iv, input, length, output); ++ sc_evp_cipher_free(alg); ++ return r; + } + + + static int +-des3_encrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], ++des3_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], + const unsigned char *input, size_t length, unsigned char *output) + { + unsigned char bKey[24] = { 0 }; ++ EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); ++ int r; + + if (keysize == 16) { + memcpy(&bKey[0], key, 16); +@@ -513,15 +536,20 @@ des3_encrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX + memcpy(&bKey[0], key, 24); + } + +- return openssl_enc(EVP_des_ede3_cbc(), bKey, iv, input, length, output); ++ r = openssl_enc(EVP_des_ede3_cbc(), bKey, iv, input, length, output); ++ sc_evp_cipher_free(alg); ++ return r; + } + + + static int +-des3_decrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], ++des3_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], + const unsigned char *input, size_t length, unsigned char *output) + { + unsigned char bKey[24] = { 0 }; ++ EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); ++ int r; ++ + if (keysize == 16) { + memcpy(&bKey[0], key, 16); + memcpy(&bKey[16], key, 8); +@@ -530,23 +558,35 @@ des3_decrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX + memcpy(&bKey[0], key, 24); + } + +- return openssl_dec(EVP_des_ede3_cbc(), bKey, iv, input, length, output); ++ r = openssl_dec(alg, bKey, iv, input, length, output); ++ sc_evp_cipher_free(alg); ++ return r; + } + + + static int +-des_encrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], ++des_encrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], + const unsigned char *input, size_t length, unsigned char *output) + { +- return openssl_enc(EVP_des_cbc(), key, iv, input, length, output); ++ EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-CBC"); ++ int r; ++ ++ r = openssl_enc(alg, key, iv, input, length, output); ++ sc_evp_cipher_free(alg); ++ return r; + } + + + static int +-des_decrypt_cbc(const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], ++des_decrypt_cbc(struct sc_card *card, const unsigned char *key, int keysize, unsigned char iv[EVP_MAX_IV_LENGTH], + const unsigned char *input, size_t length, unsigned char *output) + { +- return openssl_dec(EVP_des_cbc(), key, iv, input, length, output); ++ EVP_CIPHER *alg = sc_evp_cipher(card->ctx, "DES-CBC"); ++ int r; ++ ++ r = openssl_dec(alg, key, iv, input, length, output); ++ sc_evp_cipher_free(alg); ++ return r; + } + + +@@ -585,15 +625,25 @@ openssl_dig(const EVP_MD * digest, const unsigned char *input, size_t length, + + + static int +-sha1_digest(const unsigned char *input, size_t length, unsigned char *output) ++sha1_digest(struct sc_card *card, const unsigned char *input, size_t length, unsigned char *output) + { +- return openssl_dig(EVP_sha1(), input, length, output); ++ EVP_MD *md = sc_evp_md(card->ctx, "SHA1"); ++ int r; ++ ++ r = openssl_dig(md, input, length, output); ++ sc_evp_md_free(md); ++ return r; + } + + static int +-sha256_digest(const unsigned char *input, size_t length, unsigned char *output) ++sha256_digest(struct sc_card *card, const unsigned char *input, size_t length, unsigned char *output) + { +- return openssl_dig(EVP_sha256(), input, length, output); ++ EVP_MD *md = sc_evp_md(card->ctx, "SHA256"); ++ int r; ++ ++ r = openssl_dig(md, input, length, output); ++ sc_evp_md_free(md); ++ return r; + } + + +@@ -658,22 +708,22 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma + /* Step 2,3 - Create S-ENC/S-MAC Session Key */ + if (KEY_TYPE_AES == key_type) { + if(isFips){ +- r = aes128_encrypt_cmac(key_enc, 128, data, 32, exdata->sk_enc); ++ r = aes128_encrypt_cmac(card, key_enc, 128, data, 32, exdata->sk_enc); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac enc failed"); + memset(&data[11], 0x06, 1); +- r = aes128_encrypt_cmac(key_mac, 128, data, 32, exdata->sk_mac); ++ r = aes128_encrypt_cmac(card, key_mac, 128, data, 32, exdata->sk_mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac mac failed"); + }else{ +- r = aes128_encrypt_ecb(key_enc, 16, data, 16, exdata->sk_enc); ++ r = aes128_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb enc failed"); +- r = aes128_encrypt_ecb(key_mac, 16, data, 16, exdata->sk_mac); ++ r = aes128_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_ecb mac failed"); + } + } + else { +- r = des3_encrypt_ecb(key_enc, 16, data, 16, exdata->sk_enc); ++ r = des3_encrypt_ecb(card, key_enc, 16, data, 16, exdata->sk_enc); + LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed"); +- r = des3_encrypt_ecb(key_mac, 16, data, 16, exdata->sk_mac); ++ r = des3_encrypt_ecb(card, key_mac, 16, data, 16, exdata->sk_mac); + LOG_TEST_RET(card->ctx, r, "des3_encrypt_ecb failed"); + } + +@@ -693,14 +743,14 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma + if (KEY_TYPE_AES == key_type) + { + if(isFips){ +- r = aes128_encrypt_cmac(exdata->sk_enc, 128, data, 32, cryptogram); ++ r = aes128_encrypt_cmac(card, exdata->sk_enc, 128, data, 32, cryptogram); + } + else{ +- r = aes128_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); ++ r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); + } + } + else +- r = des3_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); ++ r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram); + + LOG_TEST_RET(card->ctx, r, "calculate host cryptogram failed"); + +@@ -758,13 +808,13 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ + /* calculate host cryptogram */ + if (KEY_TYPE_AES == key_type) { + if(isFips){ +- r = aes128_encrypt_cmac(exdata->sk_enc, 128, data, 32, cryptogram); ++ r = aes128_encrypt_cmac(card, exdata->sk_enc, 128, data, 32, cryptogram); + } + else{ +- r = aes128_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram); ++ r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram); + } + } else { +- r = des3_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram); ++ r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, data, 16 + blocksize,cryptogram); + } + + LOG_TEST_RET(card->ctx, r, "calculate host cryptogram failed"); +@@ -783,14 +833,14 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_ + memset(iv, 0x00, 16); + if (KEY_TYPE_AES == key_type) { + if(isFips){ +- r = aes128_encrypt_cmac(exdata->sk_mac, 128, data, 13, mac); ++ r = aes128_encrypt_cmac(card, exdata->sk_mac, 128, data, 13, mac); + } + else{ +- r = aes128_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac); ++ r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, iv, data, 16, mac); + } + i = 0; + } else { +- r = des3_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac); ++ r = des3_encrypt_cbc(card, exdata->sk_mac, 16, iv, data, 16, mac); + i = 8; + } + +@@ -923,10 +973,10 @@ construct_data_tlv(struct sc_card *card, struct sc_apdu *apdu, unsigned char *ap + + /* encrypt Data */ + if (KEY_TYPE_AES == key_type) { +- r = aes128_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); ++ r = aes128_encrypt_cbc(card, exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); + } else { +- r = des3_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); ++ r = des3_encrypt_cbc(card, exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more); + LOG_TEST_RET(card->ctx, r, "des3_encrypt_cbc failed"); + } + +@@ -1018,7 +1068,7 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv + { + apdu_buf[i]=apdu_buf[i]^icv[i]; + } +- r = aes128_encrypt_cmac(exdata->sk_mac, 128, apdu_buf, data_tlv_len+le_tlv_len+block_size, mac); ++ r = aes128_encrypt_cmac(card, exdata->sk_mac, 128, apdu_buf, data_tlv_len+le_tlv_len+block_size, mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac failed"); + memcpy(mac_tlv+2, &mac[0/*ulmacLen-16*/], 8); + for (int j=0;j<4;j++) +@@ -1027,7 +1077,7 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv + } + } + else{ +- r = aes128_encrypt_cbc(exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); ++ r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); + memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); + } +@@ -1035,12 +1085,12 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv + else { + unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; + unsigned char tmp[8] = { 0 }; +- r = des_encrypt_cbc(exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); ++ r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); + LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 1 failed"); +- r = des_decrypt_cbc(&exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); ++ r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); + LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed"); + memset(iv, 0x00, sizeof iv); +- r = des_encrypt_cbc(exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); ++ r = des_encrypt_cbc(card, exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); + LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc 2 failed"); + } + +@@ -1051,7 +1101,7 @@ construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv + /* MAC(TLV case 1) */ + static int + construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_len, +- unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type) ++ unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type) + { + int r; + size_t block_size = 4; +@@ -1100,13 +1150,13 @@ construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t da + if (KEY_TYPE_AES == key_type) { + if(exdata->bFipsCertification) + { +- r = aes128_encrypt_cmac_ft(exdata->sk_mac, 128, apdu_buf,data_tlv_len+le_tlv_len+block_size, mac, &icv[0]); ++ r = aes128_encrypt_cmac_ft(card, exdata->sk_mac, 128, apdu_buf,data_tlv_len+le_tlv_len+block_size, mac, &icv[0]); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cmac_ft failed"); + memcpy(mac_tlv+2, &mac[0/*ulmacLen-16*/], 8); + } + else + { +- r = aes128_encrypt_cbc(exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); ++ r = aes128_encrypt_cbc(card, exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac); + LOG_TEST_RET(card->ctx, r, "aes128_encrypt_cbc failed"); + memcpy(mac_tlv + 2, &mac[mac_len - 16], 8); + } +@@ -1115,12 +1165,12 @@ construct_mac_tlv_case1(struct sc_card *card, unsigned char *apdu_buf, size_t da + { + unsigned char iv[EVP_MAX_IV_LENGTH] = { 0 }; + unsigned char tmp[8] = { 0 }; +- r = des_encrypt_cbc(exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); ++ r = des_encrypt_cbc(card, exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac); + LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed"); +- r = des_decrypt_cbc(&exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); ++ r = des_decrypt_cbc(card, &exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp); + LOG_TEST_RET(card->ctx, r, "des_decrypt_cbc failed"); + memset(iv, 0x00, sizeof iv); +- r = des_encrypt_cbc(exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); ++ r = des_encrypt_cbc(card, exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2); + LOG_TEST_RET(card->ctx, r, "des_encrypt_cbc failed"); + } + +@@ -1329,9 +1379,9 @@ decrypt_response(struct sc_card *card, unsigned char *in, size_t inlen, unsigned + + /* decrypt */ + if (KEY_TYPE_AES == exdata->smtype) +- aes128_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); ++ aes128_decrypt_cbc(card, exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); + else +- des3_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); ++ des3_decrypt_cbc(card, exdata->sk_enc, 16, iv, &in[i], cipher_len - 1, plaintext); + + /* unpadding */ + while (0x80 != plaintext[cipher_len - 2] && (cipher_len > 2)) +@@ -2118,7 +2168,7 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data + { + if(exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA1) + { +- r = hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA1); ++ r = hash_data(card, data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA1); + LOG_TEST_RET(card->ctx, r, "hash_data failed"); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); + apdu.data = sbuf; +@@ -2127,7 +2177,7 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data + } + else if (exdata->ecAlgFlags & SC_ALGORITHM_ECDSA_HASH_SHA256) + { +- r = hash_data(data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA256); ++ r = hash_data(card, data, datalen, sbuf, SC_ALGORITHM_ECDSA_HASH_SHA256); + LOG_TEST_RET(card->ctx, r, "hash_data failed"); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3,0x2A, 0x9E, 0x9A); + apdu.data = sbuf; +@@ -2717,7 +2767,7 @@ internal_write_rsa_key(struct sc_card *card, unsigned short fid, struct sc_pkcs1 + + + static int +-hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType) ++hash_data(struct sc_card *card, const unsigned char *data, size_t datalen, unsigned char *hash, unsigned int mechanismType) + { + + if ((NULL == data) || (NULL == hash)) +@@ -2728,7 +2778,7 @@ hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsign + unsigned char data_hash[24] = { 0 }; + size_t len = 0; + +- sha1_digest(data, datalen, data_hash); ++ sha1_digest(card, data, datalen, data_hash); + len = REVERSE_ORDER4(datalen); + memcpy(&data_hash[20], &len, 4); + memcpy(hash, data_hash, 24); +@@ -2738,7 +2788,7 @@ hash_data(const unsigned char *data, size_t datalen, unsigned char *hash, unsign + unsigned char data_hash[36] = { 0 }; + size_t len = 0; + +- sha256_digest(data, datalen, data_hash); ++ sha256_digest(card, data, datalen, data_hash); + len = REVERSE_ORDER4(datalen); + memcpy(&data_hash[32], &len, 4); + memcpy(hash, data_hash, 36); +@@ -2819,7 +2869,7 @@ internal_install_pin(struct sc_card *card, sc_epass2003_wkey_data * pin) + int r; + unsigned char hash[HASH_LEN] = { 0 }; + +- r = hash_data(pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); ++ r = hash_data(card, pin->key_data.es_secret.key_val, pin->key_data.es_secret.key_len, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); + LOG_TEST_RET(card->ctx, r, "hash data failed"); + + r = install_secret_key(card, 0x04, pin->key_data.es_secret.kid, +@@ -3165,10 +3215,10 @@ external_key_auth(struct sc_card *card, unsigned char kid, + r = sc_get_challenge(card, random, 8); + LOG_TEST_RET(card->ctx, r, "get challenge external_key_auth failed"); + +- r = hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); ++ r = hash_data(card, data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); + LOG_TEST_RET(card->ctx, r, "hash data failed"); + +- des3_encrypt_cbc(hash, HASH_LEN, iv, random, 8, tmp_data); ++ des3_encrypt_cbc(card, hash, HASH_LEN, iv, random, 8, tmp_data); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x01, 0x80 | kid); + apdu.lc = apdu.datalen = 8; + apdu.data = tmp_data; +@@ -3192,7 +3242,7 @@ update_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid, + unsigned char tmp_data[256] = { 0 }; + unsigned char maxtries = 0; + +- r = hash_data(data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); ++ r = hash_data(card, data, datalen, hash, SC_ALGORITHM_ECDSA_HASH_SHA1); + LOG_TEST_RET(card->ctx, r, "hash data failed"); + + r = get_external_key_maxtries(card, &maxtries); + +From 129c72af12c348fc22653b6beba70440af455af0 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 16:09:15 -0500 +Subject: [PATCH 07/20] Remove call to load legacy provider from cwa14890 + +Library code should *never* arbitrarily load the legacy provider in the +default application context. It may literally break or make an +application vulnerable by sneaking in unexpected algorithms. + +This is not needed anymore given we will use an opensc specific context +that will not affect the rest of the application (or other libraries). + +Signed-off-by: Simo Sorce +--- + src/libopensc/card-authentic.c | 1 - + src/libopensc/cwa14890.c | 24 ------------------------ + 2 files changed, 25 deletions(-) + +diff --git a/src/libopensc/card-authentic.c b/src/libopensc/card-authentic.c +index 2c16144de6..d7bb92a496 100644 +--- a/src/libopensc/card-authentic.c ++++ b/src/libopensc/card-authentic.c +@@ -39,7 +39,6 @@ + #include "authentic.h" + + #include +-#include + #include + #include + #include +diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c +index c859a956bd..f3f0c5859c 100644 +--- a/src/libopensc/cwa14890.c ++++ b/src/libopensc/cwa14890.c +@@ -49,10 +49,6 @@ + # include + #endif + +-#if OPENSSL_VERSION_NUMBER >= 0x30000000L +- static OSSL_PROVIDER *legacy_provider = NULL; +-#endif +- + #define MAX_RESP_BUFFER_SIZE 2048 + + /** +@@ -1618,16 +1614,6 @@ int cwa_encode_apdu(sc_card_t * card, + tmplen = 0; + key = sm_session->session_mac; + +-#if OPENSSL_VERSION_NUMBER >= 0x30000000L +- if (!legacy_provider) { +- if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { +- msg = "Failed to load legacy provider"; +- res = SC_ERROR_INTERNAL; +- goto encode_end; +- } +- } +-#endif +- + if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { + msg = "Error in DES ECB encryption"; +@@ -1860,16 +1846,6 @@ int cwa_decode_response(sc_card_t * card, + /* set up key for mac computing */ + key = sm_session->session_mac; + +-#if OPENSSL_VERSION_NUMBER >= 0x30000000L +- if (!legacy_provider) { +- if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { +- msg = "Failed to load legacy provider"; +- res = SC_ERROR_INTERNAL; +- goto response_decode_end; +- } +- } +-#endif +- + if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { + msg = "Error in DES ECB encryption"; + +From 28cebc986ec9d6b2ab61a11be72dd19e012d32d4 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 16:26:54 -0500 +Subject: [PATCH 08/20] Convert card cwa14890 to use openssl libctx + +Signed-off-by: Simo Sorce +--- + src/libopensc/cwa-dnie.c | 6 +++--- + src/libopensc/cwa14890.c | 30 ++++++++++++++++++++++++------ + 2 files changed, 27 insertions(+), 9 deletions(-) + +diff --git a/src/libopensc/cwa-dnie.c b/src/libopensc/cwa-dnie.c +index 81092c6b9c..fff0e13df1 100644 +--- a/src/libopensc/cwa-dnie.c ++++ b/src/libopensc/cwa-dnie.c +@@ -695,8 +695,8 @@ static int dnie_get_root_ca_pubkey(sc_card_t * card, EVP_PKEY ** root_ca_key) + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *params = NULL; +- +- ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); ++ ++ ctx = EVP_PKEY_CTX_new_from_name(card->ctx->ossl3ctx->libctx, "RSA", NULL); + if (!ctx) { + #endif + sc_log(card->ctx, "Cannot create data for root CA public key"); +@@ -895,7 +895,7 @@ static int dnie_get_privkey(sc_card_t * card, EVP_PKEY ** ifd_privkey, + EVP_PKEY_CTX *ctx = NULL; + + LOG_FUNC_CALLED(card->ctx); +- ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); ++ ctx = EVP_PKEY_CTX_new_from_name(card->ctx->ossl3ctx->libctx, "RSA", NULL); + + if (!ctx) { + #endif +diff --git a/src/libopensc/cwa14890.c b/src/libopensc/cwa14890.c +index f3f0c5859c..b8662f4ff1 100644 +--- a/src/libopensc/cwa14890.c ++++ b/src/libopensc/cwa14890.c +@@ -1471,6 +1471,7 @@ int cwa_encode_apdu(sc_card_t * card, + u8 *cryptbuf = NULL; + + EVP_CIPHER_CTX *cctx = NULL; ++ EVP_CIPHER *alg = NULL; + unsigned char *key = NULL; + int tmplen = 0; + +@@ -1561,7 +1562,9 @@ int cwa_encode_apdu(sc_card_t * card, + *cryptbuf = 0x01; + key = sm_session->session_enc; + +- if (EVP_EncryptInit_ex(cctx, EVP_des_ede_cbc(), NULL, key, iv) != 1 || ++ alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC"); ++ ++ if (EVP_EncryptInit_ex(cctx, alg, NULL, key, iv) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || + EVP_EncryptUpdate(cctx, cryptbuf + 1, &dlen, msgbuf, dlen) != 1 || + EVP_EncryptFinal_ex(cctx, cryptbuf + 1 + dlen, &tmplen) != 1) { +@@ -1614,7 +1617,9 @@ int cwa_encode_apdu(sc_card_t * card, + tmplen = 0; + key = sm_session->session_mac; + +- if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || ++ sc_evp_cipher_free(alg); ++ alg = sc_evp_cipher(card->ctx, "DES-ECB"); ++ if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { + msg = "Error in DES ECB encryption"; + res = SC_ERROR_INTERNAL; +@@ -1639,7 +1644,10 @@ int cwa_encode_apdu(sc_card_t * card, + } + + /* and apply 3DES to result */ +- if (EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) != 1 || ++ sc_evp_cipher_free(alg); ++ alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB"); ++ ++ if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || + EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || + EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { +@@ -1673,6 +1681,7 @@ int cwa_encode_apdu(sc_card_t * card, + if (from->resp != to->resp) + free(to->resp); + encode_end_apdu_valid: ++ sc_evp_cipher_free(alg); + if (cctx) + EVP_CIPHER_CTX_free(cctx); + if (msg) +@@ -1718,6 +1727,7 @@ int cwa_decode_response(sc_card_t * card, + struct sm_cwa_session * sm_session = &card->sm_ctx.info.session.cwa; + + EVP_CIPHER_CTX *cctx = NULL; ++ EVP_CIPHER *alg = NULL; + unsigned char *key = NULL; + int tmplen = 0; + +@@ -1846,7 +1856,8 @@ int cwa_decode_response(sc_card_t * card, + /* set up key for mac computing */ + key = sm_session->session_mac; + +- if (EVP_EncryptInit_ex(cctx, EVP_des_ecb(), NULL, key, NULL) != 1 || ++ alg = sc_evp_cipher(card->ctx, "DES-ECB"); ++ if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1) { + msg = "Error in DES ECB encryption"; + res = SC_ERROR_INTERNAL; +@@ -1872,7 +1883,10 @@ int cwa_decode_response(sc_card_t * card, + } + + /* finally apply 3DES to result */ +- if (EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) != 1 || ++ sc_evp_cipher_free(alg); ++ alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB"); ++ ++ if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || + EVP_EncryptUpdate(cctx, macbuf, &tmplen, macbuf, 8) != 1 || + EVP_EncryptFinal_ex(cctx, macbuf + tmplen, &tmplen) != 1) { +@@ -1928,7 +1942,10 @@ int cwa_decode_response(sc_card_t * card, + + /* decrypt into response buffer + * by using 3DES CBC by mean of kenc and iv={0,...0} */ +- if (EVP_DecryptInit_ex(cctx, EVP_des_ede_cbc(), NULL, key, iv) != 1 || ++ sc_evp_cipher_free(alg); ++ alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC"); ++ ++ if (EVP_DecryptInit_ex(cctx, alg, NULL, key, iv) != 1 || + EVP_CIPHER_CTX_set_padding(cctx, 0) != 1 || + EVP_DecryptUpdate(cctx, apdu->resp, &dlen, &e_tlv->data[1], e_tlv->len - 1) != 1 || + EVP_DecryptFinal_ex(cctx, apdu->resp + dlen, &tmplen) != 1) { +@@ -1957,6 +1974,7 @@ int cwa_decode_response(sc_card_t * card, + res = SC_SUCCESS; + + response_decode_end: ++ sc_evp_cipher_free(alg); + EVP_CIPHER_CTX_free(cctx); + if (buffer) + free(buffer); + +From 7e305908dba5b4fb305ebb0c44bc9eb0418479a2 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 16:34:53 -0500 +Subject: [PATCH 09/20] Convert card GIDS to use openssl libctx + +Signed-off-by: Simo Sorce +--- + src/libopensc/card-gids.c | 26 +++++++++++++++++++------- + 1 file changed, 19 insertions(+), 7 deletions(-) + +diff --git a/src/libopensc/card-gids.c b/src/libopensc/card-gids.c +index f25e37de45..f41af2707e 100644 +--- a/src/libopensc/card-gids.c ++++ b/src/libopensc/card-gids.c +@@ -1959,14 +1959,9 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { + u8 buffer3[16+16+8]; + int buffer3size = 40; + sc_apdu_t apdu; +- const EVP_CIPHER *cipher; ++ EVP_CIPHER *cipher; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); +- // this is CBC instead of ECB +- cipher = EVP_des_ede3_cbc(); +- if (!cipher) { +- LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); +- } + + // select the admin key + sc_format_apdu(card, &apdu, SC_APDU_CASE_3, INS_MANAGE_SECURITY_ENVIRONMENT, 0xC1, 0xA4); +@@ -2008,23 +2003,28 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { + if (ctx == NULL) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } +- ++ cipher = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); + if (!EVP_EncryptInit(ctx, cipher, key, NULL)) { + EVP_CIPHER_CTX_free(ctx); ++ sc_evp_cipher_free(cipher); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + EVP_CIPHER_CTX_set_padding(ctx,0); + if (!EVP_EncryptUpdate(ctx, buffer2, &buffer2size, buffer, sizeof(buffer))) { + EVP_CIPHER_CTX_free(ctx); ++ sc_evp_cipher_free(cipher); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + + if(!EVP_EncryptFinal(ctx, buffer2+buffer2size, &buffer2size)) { + EVP_CIPHER_CTX_free(ctx); ++ sc_evp_cipher_free(cipher); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; ++ sc_evp_cipher_free(cipher); ++ cipher = NULL; + // send it to the card + sc_format_apdu(card, &apdu, SC_APDU_CASE_4, INS_GENERAL_AUTHENTICATE, 0x00, 0x00); + apdu.lc = sizeof(apduSendReponse); +@@ -2047,36 +2047,48 @@ static int gids_authenticate_admin(sc_card_t *card, u8* key) { + if (ctx == NULL) { + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } ++ cipher = sc_evp_cipher(card->ctx, "DES-EDE3-CBC"); + if (!EVP_DecryptInit(ctx, cipher, key, NULL)) { ++ sc_evp_cipher_free(cipher); + EVP_CIPHER_CTX_free(ctx); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + } + EVP_CIPHER_CTX_set_padding(ctx,0); + if (!EVP_DecryptUpdate(ctx, buffer3, &buffer3size, apdu.resp + 4, apdu.resplen - 4)) { + sc_log(card->ctx, "unable to decrypt data"); ++ sc_evp_cipher_free(cipher); + EVP_CIPHER_CTX_free(ctx); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); + } + if(!EVP_DecryptFinal(ctx, buffer3+buffer3size, &buffer3size)) { + sc_log(card->ctx, "unable to decrypt final data"); ++ sc_evp_cipher_free(cipher); + EVP_CIPHER_CTX_free(ctx); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); + } + sc_log(card->ctx, "data has been decrypted using the key"); + if (memcmp(buffer3, randomR1, 16) != 0) { + sc_log(card->ctx, "R1 doesn't match"); ++ sc_evp_cipher_free(cipher); ++ EVP_CIPHER_CTX_free(ctx); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); + } + if (memcmp(buffer3 + 16, randomR2, 16) != 0) { + sc_log(card->ctx, "R2 doesn't match"); ++ sc_evp_cipher_free(cipher); ++ EVP_CIPHER_CTX_free(ctx); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); + } + if (buffer[39] != 0x80) { + sc_log(card->ctx, "Padding not found"); ++ sc_evp_cipher_free(cipher); ++ EVP_CIPHER_CTX_free(ctx); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT); + } + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; ++ sc_evp_cipher_free(cipher); ++ cipher = NULL; + + LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); + #endif + +From 04ee97407fd3fc3c968d793c05951f6b14be67ba Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 16:40:29 -0500 +Subject: [PATCH 10/20] Convert card GPK to use openssl libctx + +Signed-off-by: Simo Sorce +--- + src/libopensc/card-gpk.c | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c +index 7571e0c042..2e5673359f 100644 +--- a/src/libopensc/card-gpk.c ++++ b/src/libopensc/card-gpk.c +@@ -733,6 +733,7 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu, + unsigned int len = 0, i; + int r = SC_SUCCESS, outl; + EVP_CIPHER_CTX *ctx = NULL; ++ EVP_CIPHER *alg = NULL; + + ctx = EVP_CIPHER_CTX_new(); + if (ctx == NULL) +@@ -756,7 +757,8 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu, + /* Set IV */ + memset(in, 0x00, 8); + +- EVP_EncryptInit_ex(ctx, EVP_des_ede_cbc(), NULL, priv->key, in); ++ alg = sc_evp_cipher(card->ctx, "DES-EDE-CBC"); ++ EVP_EncryptInit_ex(ctx, alg, NULL, priv->key, in); + for (i = 0; i < len; i += 8) { + if (!EVP_EncryptUpdate(ctx, out, &outl, &block[i], 8)) { + r = SC_ERROR_INTERNAL; +@@ -764,6 +766,7 @@ gpk_compute_crycks(sc_card_t *card, sc_apdu_t *apdu, + } + } + EVP_CIPHER_CTX_free(ctx); ++ sc_evp_cipher_free(alg); + + memcpy((u8 *) (apdu->data + apdu->datalen), out + 5, 3); + apdu->datalen += 3; +@@ -885,11 +888,12 @@ gpk_create_file(sc_card_t *card, sc_file_t *file) + * Set the secure messaging key following a Select FileKey + */ + static int +-gpk_set_filekey(const u8 *key, const u8 *challenge, ++gpk_set_filekey(sc_card_t *card, const u8 *key, const u8 *challenge, + const u8 *r_rn, u8 *kats) + { + int r = SC_SUCCESS, outl; + EVP_CIPHER_CTX * ctx = NULL; ++ EVP_CIPHER * alg = NULL; + u8 out[16]; + + memcpy(out, key+8, 8); +@@ -899,7 +903,8 @@ gpk_set_filekey(const u8 *key, const u8 *challenge, + if (ctx == NULL) + return SC_ERROR_INTERNAL; + +- EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, key, NULL); ++ alg = sc_evp_cipher(card->ctx, "DES-EDE"); ++ EVP_EncryptInit_ex(ctx, alg, NULL, key, NULL); + if (!EVP_EncryptUpdate(ctx, kats, &outl, r_rn+4, 8)) + r = SC_ERROR_INTERNAL; + +@@ -907,7 +912,7 @@ gpk_set_filekey(const u8 *key, const u8 *challenge, + r = SC_ERROR_INTERNAL; + if (r == SC_SUCCESS) { + EVP_CIPHER_CTX_reset(ctx); +- EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, out, NULL); ++ EVP_EncryptInit_ex(ctx, alg, NULL, out, NULL); + if (!EVP_EncryptUpdate(ctx, kats+8, &outl, r_rn+4, 8)) + r = SC_ERROR_INTERNAL; + if (!EVP_CIPHER_CTX_reset(ctx)) +@@ -921,13 +926,14 @@ gpk_set_filekey(const u8 *key, const u8 *challenge, + */ + if (r == SC_SUCCESS) { + EVP_CIPHER_CTX_reset(ctx); +- EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, kats, NULL); ++ EVP_EncryptInit_ex(ctx, alg, NULL, kats, NULL); + if (!EVP_EncryptUpdate(ctx, out, &outl, challenge, 8)) + r = SC_ERROR_INTERNAL; + if (memcmp(r_rn, out+4, 4) != 0) + r = SC_ERROR_INVALID_ARGUMENTS; + } + ++ sc_evp_cipher_free(alg); + if (ctx) + EVP_CIPHER_CTX_free(ctx); + +@@ -974,7 +980,7 @@ gpk_select_key(sc_card_t *card, int key_sfi, const u8 *buf, size_t buflen) + if (apdu.resplen != 12) { + r = SC_ERROR_UNKNOWN_DATA_RECEIVED; + } else +- if ((r = gpk_set_filekey(buf, rnd, resp, priv->key)) == 0) { ++ if ((r = gpk_set_filekey(card, buf, rnd, resp, priv->key)) == 0) { + priv->key_set = 1; + priv->key_reference = key_sfi; + } +@@ -1521,6 +1527,7 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) + u8 temp[256]; + int r = SC_SUCCESS, outl; + EVP_CIPHER_CTX * ctx; ++ EVP_CIPHER * alg; + + sc_log(card->ctx, "gpk_pkfile_load(fid=%04x, len=%d, datalen=%d)\n", + args->file->id, args->len, args->datalen); +@@ -1549,6 +1556,7 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) + return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; + } + ++ alg = sc_evp_cipher(card->ctx, "DES-EDE"); + EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, priv->key, NULL); + for (n = 0; n < args->datalen; n += 8) { + if (!EVP_EncryptUpdate(ctx, temp+n, &outl, args->data + n, 8)) { +@@ -1556,6 +1564,7 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) + break; + } + } ++ sc_evp_cipher_free(alg); + if (ctx) + EVP_CIPHER_CTX_free(ctx); + if (r != SC_SUCCESS) + +From fdfb50cf2e54871bdc929b6e5a40730ca1cae4d8 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 16:42:47 -0500 +Subject: [PATCH 11/20] Convert card IASECC to use openssl libctx + +Signed-off-by: Simo Sorce +--- + src/libopensc/card-iasecc.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/src/libopensc/card-iasecc.c b/src/libopensc/card-iasecc.c +index 1347ed2393..d8c0863b99 100644 +--- a/src/libopensc/card-iasecc.c ++++ b/src/libopensc/card-iasecc.c +@@ -3169,7 +3169,7 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i + + int r = SC_ERROR_INTERNAL; + EVP_MD_CTX *mdctx = NULL; +- const EVP_MD *md = NULL; ++ EVP_MD *md = NULL; + SHA_CTX *md_data = NULL; + unsigned int md_out_len; + SHA_LONG pre_hash_Nl, *hh[5] = {NULL, NULL, NULL, NULL, NULL}; +@@ -3186,9 +3186,9 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i + in_len); + memset(out, 0, sizeof(struct iasecc_qsign_data)); + +- md = EVP_get_digestbyname("SHA1"); ++ md = sc_evp_md(ctx, "SHA1"); + mdctx = EVP_MD_CTX_new(); +- if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) { ++ if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) { + sc_log(ctx, "EVP_DigestInit_ex failed"); + goto err; + } +@@ -3250,6 +3250,7 @@ iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t i + ERR_print_errors_fp(ctx->debug_file); + end: + EVP_MD_CTX_free(mdctx); ++ sc_evp_md_free(md); + + LOG_FUNC_RETURN(ctx, r); + +@@ -3267,7 +3268,7 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t + + int r = SC_ERROR_INTERNAL; + EVP_MD_CTX *mdctx = NULL; +- const EVP_MD *md = NULL; ++ EVP_MD *md = NULL; + SHA256_CTX *md_data; + unsigned int md_out_len; + +@@ -3284,7 +3285,7 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t + in_len); + memset(out, 0, sizeof(struct iasecc_qsign_data)); + +- md = EVP_get_digestbyname("SHA256"); ++ md = sc_evp_md(ctx, "SHA256"); + mdctx = EVP_MD_CTX_new(); + if (EVP_DigestInit_ex(mdctx, md, NULL) != 1) { + sc_log(ctx, "EVP_DigestInit_ex failed"); +@@ -3342,6 +3343,7 @@ iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t + ERR_print_errors_fp(ctx->debug_file); + end: + EVP_MD_CTX_free(mdctx); ++ sc_evp_md_free(md); + + LOG_FUNC_RETURN(ctx, r); + + +From a7dc2ae2290f9b760bf38ccef510293ea6aa15bd Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 16:45:15 -0500 +Subject: [PATCH 12/20] Convert card oberthur to use openssl libctx + +Signed-off-by: Simo Sorce +--- + src/libopensc/card-oberthur.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c +index 1fc40f7b35..35312ed0d5 100644 +--- a/src/libopensc/card-oberthur.c ++++ b/src/libopensc/card-oberthur.c +@@ -1336,6 +1336,7 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a + const unsigned char in[8] = {0,0,0,0,0,0,0,0}; + unsigned char out[8]; + EVP_CIPHER_CTX * ctx = NULL; ++ EVP_CIPHER *alg = NULL; + + if (args->len!=8 && args->len!=24) + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS); +@@ -1346,11 +1347,13 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a + + p2 = 0; + if (args->len == 24) +- EVP_EncryptInit_ex(ctx, EVP_des_ede(), NULL, args->data, NULL); ++ alg = sc_evp_cipher(card->ctx, "DES-EDE"); + else +- EVP_EncryptInit_ex(ctx, EVP_des_ecb(), NULL, args->data, NULL); ++ alg = sc_evp_cipher(card->ctx, "DES-ECB"); ++ EVP_EncryptInit_ex(ctx, alg, NULL, args->data, NULL); + rv = EVP_EncryptUpdate(ctx, out, &outl, in, 8); + EVP_CIPHER_CTX_free(ctx); ++ sc_evp_cipher_free(alg); + if (rv == 0) { + sc_log(card->ctx, "OpenSSL encryption error."); + LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL); + +From 3a505e2217499729c52319bdb26fea93a4fdf5ec Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 16:53:37 -0500 +Subject: [PATCH 13/20] Convert card PIV to use openssl libctx + +Signed-off-by: Simo Sorce +--- + src/libopensc/card-piv.c | 34 +++++++++++++++++++++++----------- + 1 file changed, 23 insertions(+), 11 deletions(-) + +diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c +index dffb9e3ebc..aadd4ec242 100644 +--- a/src/libopensc/card-piv.c ++++ b/src/libopensc/card-piv.c +@@ -1428,17 +1428,27 @@ static int piv_write_binary(sc_card_t *card, unsigned int idx, + */ + + #ifdef ENABLE_OPENSSL +-static const EVP_CIPHER *get_cipher_for_algo(int alg_id) ++static EVP_CIPHER *get_cipher_for_algo(sc_card_t *card, int alg_id) + { ++ const char *algo; + switch (alg_id) { +- case 0x0: return EVP_des_ede3_ecb(); +- case 0x1: return EVP_des_ede3_ecb(); /* 2TDES */ +- case 0x3: return EVP_des_ede3_ecb(); +- case 0x8: return EVP_aes_128_ecb(); +- case 0xA: return EVP_aes_192_ecb(); +- case 0xC: return EVP_aes_256_ecb(); ++ case 0x0: ++ case 0x1: /* 2TDES */ ++ case 0x3: ++ algo = "DES-EDE3-ECB"; ++ break; ++ case 0x8: ++ algo = "AES-128-ECB"; ++ break; ++ case 0xA: ++ algo = "AES-192-ECB"; ++ break; ++ case 0xC: ++ algo = "AES-256-ECB"; ++ break; + default: return NULL; + } ++ return sc_evp_cipher(card->ctx, algo); + } + + static int get_keylen(unsigned int alg_id, size_t *size) +@@ -1604,7 +1614,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, + EVP_CIPHER_CTX * ctx = NULL; + + u8 sbuf[255]; +- const EVP_CIPHER *cipher; ++ EVP_CIPHER *cipher = NULL; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + +@@ -1614,7 +1624,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, + goto err; + } + +- cipher = get_cipher_for_algo(alg_id); ++ cipher = get_cipher_for_algo(card, alg_id); + if(!cipher) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for: %02x\n", alg_id); + r = SC_ERROR_INVALID_ARGUMENTS; +@@ -1850,6 +1860,7 @@ static int piv_general_mutual_authenticate(sc_card_t *card, + r = SC_SUCCESS; + + err: ++ sc_evp_cipher_free(cipher); + if (ctx) + EVP_CIPHER_CTX_free(ctx); + if (locked) +@@ -1897,7 +1908,7 @@ static int piv_general_external_authenticate(sc_card_t *card, + size_t cypher_text_len = 0; + u8 sbuf[255]; + EVP_CIPHER_CTX * ctx = NULL; +- const EVP_CIPHER *cipher; ++ EVP_CIPHER *cipher = NULL; + + SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); + +@@ -1909,7 +1920,7 @@ static int piv_general_external_authenticate(sc_card_t *card, + + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Selected cipher for algorithm id: %02x\n", alg_id); + +- cipher = get_cipher_for_algo(alg_id); ++ cipher = get_cipher_for_algo(card, alg_id); + if(!cipher) { + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for: %02x\n", alg_id); + r = SC_ERROR_INVALID_ARGUMENTS; +@@ -2059,6 +2070,7 @@ static int piv_general_external_authenticate(sc_card_t *card, + sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Got response challenge\n"); + + err: ++ sc_evp_cipher_free(cipher); + if (ctx) + EVP_CIPHER_CTX_free(ctx); + + +From 600695ca5b8cec95330567fe1bfaa07e1609c8d0 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 16:59:16 -0500 +Subject: [PATCH 14/20] Convert card westcos to use openssl libctx + +Signed-off-by: Simo Sorce +--- + src/libopensc/card-westcos.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c +index 633d471d73..108599336b 100644 +--- a/src/libopensc/card-westcos.c ++++ b/src/libopensc/card-westcos.c +@@ -659,6 +659,7 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, + int r; + #ifdef ENABLE_OPENSSL + EVP_CIPHER_CTX *cctx = NULL; ++ EVP_CIPHER *alg = NULL; + int tmplen = 0; + if ((cctx = EVP_CIPHER_CTX_new()) == NULL) + return SC_ERROR_INTERNAL; +@@ -671,19 +672,25 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, + if (r) + return r; + #ifdef ENABLE_OPENSSL +- if (EVP_EncryptInit_ex(cctx, EVP_des_ede_ecb(), NULL, key, NULL) != 1 || ++ if ((cctx = EVP_CIPHER_CTX_new()) == NULL) ++ return SC_ERROR_INTERNAL; ++ alg = sc_evp_cipher(card->ctx, "DES-EDE-ECB"); ++ if (EVP_EncryptInit_ex(cctx, alg, NULL, key, NULL) != 1 || + EVP_CIPHER_CTX_set_padding(cctx,0) != 1 || + EVP_EncryptUpdate(cctx, result, &tmplen, buf, *len) != 1) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_ERROR_INTERNAL; + } + *len = tmplen; + if (EVP_EncryptFinal_ex(cctx, result + tmplen, &tmplen) != 1) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_ERROR_INTERNAL; + } + *len += tmplen; + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_SUCCESS; + #else + return SC_ERROR_NOT_SUPPORTED; +@@ -1185,7 +1192,11 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, + idx += r; + } while (1); + BIO_set_mem_eof_return(mem, -1); ++#if OPENSSL_VERSION_NUMBER < 0x30000000L + if (!(pkey = d2i_PrivateKey_bio(mem, NULL))) { ++#else ++ if (!(pkey = d2i_PrivateKey_ex_bio(mem, NULL, card->ctx->ossl3ctx->libctx, NULL))) { ++#endif + sc_log(card->ctx, + "RSA key invalid, %lu\n", ERR_get_error()); + r = SC_ERROR_UNKNOWN; + +From febaf33f2a3a382852293f5ec8fd7e62b86d8eb8 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 17:17:03 -0500 +Subject: [PATCH 15/20] Convert padding.c to use openssllibctx + +Signed-off-by: Simo Sorce +--- + src/libopensc/padding.c | 90 ++++++++++++++++++++++++++--------------- + 1 file changed, 57 insertions(+), 33 deletions(-) + +diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c +index 826e726783..17745d61a4 100644 +--- a/src/libopensc/padding.c ++++ b/src/libopensc/padding.c +@@ -231,8 +231,8 @@ static int mgf1(u8 *mask, size_t len, u8 *seed, size_t seedLen, const EVP_MD *dg + } + + /* forward declarations */ +-static const EVP_MD *mgf1_flag2md(unsigned int mgf1); +-static const EVP_MD *hash_flag2md(unsigned int hash); ++static EVP_MD *mgf1_flag2md(sc_context_t *ctx, unsigned int mgf1); ++static EVP_MD *hash_flag2md(sc_context_t *ctx, unsigned int hash); + + /* check/remove OAEP - RFC 8017 padding */ + int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigned long flags, uint8_t *param, size_t paramlen) +@@ -240,7 +240,7 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigne + size_t i,j; + size_t mdlen, dblen; + u8 seed[EVP_MAX_MD_SIZE]; +- const EVP_MD *mgf1_md, *hash_md; ++ EVP_MD *mgf1_md = NULL, *hash_md = NULL; + u8 db[512]; /* up to RSA 4096 */ + u8 label[EVP_MAX_MD_SIZE]; + EVP_MD_CTX *md_ctx; +@@ -251,7 +251,7 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigne + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + + /* https://www.rfc-editor.org/rfc/pdfrfc/rfc8017.txt.pdf, page 26, 3.a. */ +- hash_md = hash_flag2md(flags); ++ hash_md = hash_flag2md(ctx, flags); + if (!hash_md) + return SC_ERROR_NOT_SUPPORTED; + +@@ -263,32 +263,45 @@ int sc_pkcs1_strip_oaep_padding(sc_context_t *ctx, u8 *data, size_t len, unsigne + hash_len = 0; + EVP_MD_CTX_free(md_ctx); + } ++ sc_evp_md_free(hash_md); ++ hash_md = NULL; + if (!hash_len) + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); + +- mgf1_md = mgf1_flag2md(flags); ++ mgf1_md = mgf1_flag2md(ctx, flags); + if (!mgf1_md) + return SC_ERROR_NOT_SUPPORTED; + + mdlen = EVP_MD_size(mgf1_md); + +- if (len < 2 * mdlen + 2) ++ if (len < 2 * mdlen + 2) { ++ sc_evp_md_free(mgf1_md); + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); ++ } + +- if (*data != 0) ++ if (*data != 0) { ++ sc_evp_md_free(mgf1_md); + LOG_FUNC_RETURN(ctx, SC_ERROR_WRONG_PADDING); ++ } + + dblen = len - 1 - mdlen; +- if (dblen > sizeof(db)) ++ if (dblen > sizeof(db)) { ++ sc_evp_md_free(mgf1_md); + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); ++ } + +- if (mgf1(seed, mdlen, data + mdlen + 1, dblen, mgf1_md)) ++ if (mgf1(seed, mdlen, data + mdlen + 1, dblen, mgf1_md)) { ++ sc_evp_md_free(mgf1_md); + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); ++ } + for (i = 0; i < mdlen; i++) + seed[i] ^= data[i + 1]; + +- if (mgf1(db, dblen, seed, mdlen, mgf1_md)) ++ if (mgf1(db, dblen, seed, mdlen, mgf1_md)) { ++ sc_evp_md_free(mgf1_md); + LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL); ++ } ++ sc_evp_md_free(mgf1_md); + for (i = 0; i < dblen; i++) { + db[i] ^= data[i + mdlen + 1]; + /* clear lHash' if same as lHash */ +@@ -369,37 +382,37 @@ int sc_pkcs1_strip_digest_info_prefix(unsigned int *algorithm, + + #ifdef ENABLE_OPENSSL + +-static const EVP_MD* hash_flag2md(unsigned int hash) ++static EVP_MD* hash_flag2md(sc_context_t *ctx, unsigned int hash) + { + switch (hash & SC_ALGORITHM_RSA_HASHES) { + case SC_ALGORITHM_RSA_HASH_SHA1: +- return EVP_sha1(); ++ return sc_evp_md(ctx, "SHA1"); + case SC_ALGORITHM_RSA_HASH_SHA224: +- return EVP_sha224(); ++ return sc_evp_md(ctx, "SHA224"); + case SC_ALGORITHM_RSA_HASH_SHA256: +- return EVP_sha256(); ++ return sc_evp_md(ctx, "SHA256"); + case SC_ALGORITHM_RSA_HASH_SHA384: +- return EVP_sha384(); ++ return sc_evp_md(ctx, "SHA384"); + case SC_ALGORITHM_RSA_HASH_SHA512: +- return EVP_sha512(); ++ return sc_evp_md(ctx, "SHA512"); + default: + return NULL; + } + } + +-static const EVP_MD* mgf1_flag2md(unsigned int mgf1) ++static EVP_MD* mgf1_flag2md(sc_context_t *ctx, unsigned int mgf1) + { + switch (mgf1 & SC_ALGORITHM_MGF1_HASHES) { + case SC_ALGORITHM_MGF1_SHA1: +- return EVP_sha1(); ++ return sc_evp_md(ctx, "SHA1"); + case SC_ALGORITHM_MGF1_SHA224: +- return EVP_sha224(); ++ return sc_evp_md(ctx, "SHA224"); + case SC_ALGORITHM_MGF1_SHA256: +- return EVP_sha256(); ++ return sc_evp_md(ctx, "SHA256"); + case SC_ALGORITHM_MGF1_SHA384: +- return EVP_sha384(); ++ return sc_evp_md(ctx, "SHA384"); + case SC_ALGORITHM_MGF1_SHA512: +- return EVP_sha512(); ++ return sc_evp_md(ctx, "SHA512"); + default: + return NULL; + } +@@ -408,13 +421,13 @@ static const EVP_MD* mgf1_flag2md(unsigned int mgf1) + /* large enough up to RSA 4096 */ + #define PSS_MAX_SALT_SIZE 512 + /* add PKCS#1 v2.0 PSS padding */ +-static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, ++static int sc_pkcs1_add_pss_padding(sc_context_t *scctx, unsigned int hash, unsigned int mgf1_hash, + const u8 *in, size_t in_len, u8 *out, size_t *out_len, size_t mod_bits, size_t sLen) + { + /* hLen = sLen in our case */ + int rv = SC_ERROR_INTERNAL, i, j, hlen, dblen, plen, round, mgf_rounds; + int mgf1_hlen; +- const EVP_MD* md, *mgf1_md; ++ EVP_MD* md = NULL, *mgf1_md = NULL; + EVP_MD_CTX* ctx = NULL; + u8 buf[8]; + u8 salt[PSS_MAX_SALT_SIZE], mask[EVP_MAX_MD_SIZE]; +@@ -423,22 +436,30 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, + if (*out_len < mod_length) + return SC_ERROR_BUFFER_TOO_SMALL; + +- md = hash_flag2md(hash); ++ md = hash_flag2md(scctx, hash); + if (md == NULL) + return SC_ERROR_NOT_SUPPORTED; + hlen = EVP_MD_size(md); + dblen = mod_length - hlen - 1; /* emLen - hLen - 1 */ + plen = mod_length - sLen - hlen - 1; +- if (in_len != (unsigned)hlen) ++ if (in_len != (unsigned)hlen) { ++ sc_evp_md_free(md); + return SC_ERROR_INVALID_ARGUMENTS; +- if (sLen + (unsigned)hlen + 2 > mod_length) ++ } ++ if (sLen + (unsigned)hlen + 2 > mod_length) { + /* RSA key too small for chosen hash (1296 bits or higher needed for + * signing SHA-512 hashes) */ ++ sc_evp_md_free(md); + return SC_ERROR_NOT_SUPPORTED; +- if (sLen > PSS_MAX_SALT_SIZE) ++ } ++ if (sLen > PSS_MAX_SALT_SIZE) { ++ sc_evp_md_free(md); + return SC_ERROR_INVALID_ARGUMENTS; +- if (RAND_bytes(salt, sLen) != 1) ++ } ++ if (RAND_bytes(salt, sLen) != 1) { ++ sc_evp_md_free(md); + return SC_ERROR_INTERNAL; ++ } + + /* Hash M' to create H */ + if (!(ctx = EVP_MD_CTX_create())) +@@ -464,7 +485,7 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, + * *the first part is masked later */ + + /* Construct the DB mask block by block and XOR it in. */ +- mgf1_md = mgf1_flag2md(mgf1_hash); ++ mgf1_md = mgf1_flag2md(scctx, mgf1_hash); + if (mgf1_md == NULL) + return SC_ERROR_NOT_SUPPORTED; + mgf1_hlen = EVP_MD_size(mgf1_md); +@@ -499,6 +520,8 @@ static int sc_pkcs1_add_pss_padding(unsigned int hash, unsigned int mgf1_hash, + done: + OPENSSL_cleanse(salt, sizeof(salt)); + OPENSSL_cleanse(mask, sizeof(mask)); ++ sc_evp_md_free(md); ++ sc_evp_md_free(mgf1_md); + if (ctx) { + EVP_MD_CTX_destroy(ctx); + } +@@ -537,7 +560,7 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, + size_t mod_len = (mod_bits + 7) / 8; + #ifdef ENABLE_OPENSSL + size_t sLen; +- const EVP_MD* md; ++ EVP_MD* md = NULL; + unsigned int mgf1_hash; + #endif + +@@ -586,9 +609,10 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, + hash_algo = hash_len2algo(tmp_len); + } + /* sLen is by default same as hash length */ +- if (!(md = hash_flag2md(hash_algo))) ++ if (!(md = hash_flag2md(ctx, hash_algo))) + return SC_ERROR_NOT_SUPPORTED; + sLen = EVP_MD_size(md); ++ sc_evp_md_free(md); + /* if application provide sLen, use it */ + if (pMechanism != NULL) { + CK_MECHANISM *mech = (CK_MECHANISM *)pMechanism; +@@ -598,7 +622,7 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, + sLen = pss_params->sLen; + } + } +- rv = sc_pkcs1_add_pss_padding(hash_algo, mgf1_hash, ++ rv = sc_pkcs1_add_pss_padding(ctx, hash_algo, mgf1_hash, + tmp, tmp_len, out, out_len, mod_bits, sLen); + #else + rv = SC_ERROR_NOT_SUPPORTED; + +From cabcb2130243c5c67c6f79f0e153eee17c2fe464 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 17:51:52 -0500 +Subject: [PATCH 16/20] Convert pkcs15-westcos.c to use OpenSSL libctx + +Signed-off-by: Simo Sorce +--- + src/pkcs15init/pkcs15-westcos.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c +index fb8f8bda83..6f55c90744 100644 +--- a/src/pkcs15init/pkcs15-westcos.c ++++ b/src/pkcs15init/pkcs15-westcos.c +@@ -235,7 +235,11 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, + return SC_ERROR_NOT_SUPPORTED; + } + ++#if OPENSSL_VERSION_NUMBER < 0x30000000L + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); ++#else ++ pctx = EVP_PKEY_CTX_new_from_name(profile->card->ctx->ossl3ctx->libctx, "RSA", NULL); ++#endif + mem = BIO_new(BIO_s_mem()); + bn = BN_new(); + if (pctx == NULL || mem == NULL || bn == NULL) { + +From bfdb928ba49a0bde84ab0aa74934e01551fb836b Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 18:05:10 -0500 +Subject: [PATCH 17/20] Remove call to load legacy provider from libsm + +Library code should *never* arbitrarily load the legacy provider in the +default application context. It may literally break or make an +application vulnerable by sneaking in unexpected algorithms. + +This is not needed anymore given we will use an opensc specific context +that will not affect the rest of the application (or other libraries). + +Signed-off-by: Simo Sorce +--- + src/sm/sm-common.c | 13 ------------- + 1 file changed, 13 deletions(-) + +diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c +index caada2b7ee..af16d44cab 100644 +--- a/src/sm/sm-common.c ++++ b/src/sm/sm-common.c +@@ -122,13 +122,6 @@ DES_3cbc_encrypt(sm_des_cblock *input, sm_des_cblock *output, long length, + } + memcpy(*iv,icv_out,sizeof(sm_des_cblock)); + } +-#else +-#include +- +-/* The single-DES algorithm is not available in the default provider anymore +- * so we need to load the legacy provider. This is not done on the application +- * start, but only as needed */ +-static OSSL_PROVIDER *legacy_provider = NULL; + #endif + + +@@ -206,12 +199,6 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, + + cctx = EVP_CIPHER_CTX_new(); + if (l > 8) { +- if (!legacy_provider) { +- if (!(legacy_provider = OSSL_PROVIDER_try_load(NULL, "legacy", 1))) { +- EVP_CIPHER_CTX_free(cctx); +- return SC_ERROR_INTERNAL; +- } +- } + if (!EVP_EncryptInit_ex2(cctx, EVP_des_cbc(), key, iv, NULL)) { + EVP_CIPHER_CTX_free(cctx); + return SC_ERROR_INTERNAL; + +From 432c7ab2c58c56cb7251c68067e09a8edf880806 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Wed, 15 Feb 2023 18:27:08 -0500 +Subject: [PATCH 18/20] Convert libsm to use openssl libctx + +Signed-off-by: Simo Sorce +--- + src/sm/sm-common.c | 56 +++++++++++++++++++++++++++------ + src/sm/sm-common.h | 9 ++++-- + src/smm/sm-card-authentic.c | 2 +- + src/smm/sm-cwa14890.c | 2 +- + src/smm/sm-global-platform.c | 18 +++++------ + src/smm/sm-module.h | 7 +++-- + src/tests/unittests/sm.c | 60 ++++++++++++++++++------------------ + 7 files changed, 99 insertions(+), 55 deletions(-) + +diff --git a/src/sm/sm-common.c b/src/sm/sm-common.c +index af16d44cab..c488c50e33 100644 +--- a/src/sm/sm-common.c ++++ b/src/sm/sm-common.c +@@ -47,6 +47,7 @@ + #include "libopensc/opensc.h" + #include "libopensc/asn1.h" + #include "libopensc/log.h" ++#include "libopensc/sc-ossl-compat.h" + + #include "sm-common.h" + +@@ -126,7 +127,8 @@ DES_3cbc_encrypt(sm_des_cblock *input, sm_des_cblock *output, long length, + + + unsigned int +-DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, ++DES_cbc_cksum_3des_emv96(struct sc_context *ctx, ++ const unsigned char *in, sm_des_cblock *output, + long length, unsigned char *key, + sm_const_des_cblock *ivec) + { +@@ -191,6 +193,7 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, + return(tout1); + #else + EVP_CIPHER_CTX *cctx = NULL; ++ EVP_CIPHER *alg = NULL; + unsigned char outv[8], tmpout[4]; + int tmplen; + +@@ -199,8 +202,10 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, + + cctx = EVP_CIPHER_CTX_new(); + if (l > 8) { +- if (!EVP_EncryptInit_ex2(cctx, EVP_des_cbc(), key, iv, NULL)) { ++ alg = sc_evp_cipher(ctx, "DES-CBC"); ++ if (!EVP_EncryptInit_ex2(cctx, alg, key, iv, NULL)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_ERROR_INTERNAL; + } + /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ +@@ -208,29 +213,37 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, + for (; l > 8; l -= 8, in += 8) { + if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, 8)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_ERROR_INTERNAL; + } + } + if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_ERROR_INTERNAL; + } ++ sc_evp_cipher_free(alg); ++ alg = NULL; + } + + /* We need to return first 4 bytes from here */ + memcpy(tmpout, outv, 4); +- if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, outv, NULL)) { ++ alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); ++ if (!EVP_EncryptInit_ex2(cctx, alg, key, outv, NULL)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_ERROR_INTERNAL; + } + /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ + EVP_CIPHER_CTX_set_padding(cctx, 0); + if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, l)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_ERROR_INTERNAL; + } + if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_ERROR_INTERNAL; + } + if (out != NULL) { +@@ -238,6 +251,7 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, + memcpy(out+4, outv+4, 4); + } + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return ((outv[7] << 0L) & 0x000000FF) | + ((outv[6] << 8L) & 0x0000FF00) | + ((outv[5] << 16L) & 0x00FF0000) | +@@ -247,7 +261,8 @@ DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, + + + unsigned int +-DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, ++DES_cbc_cksum_3des(struct sc_context *ctx, ++ const unsigned char *in, sm_des_cblock *output, + long length, unsigned char *key, + sm_const_des_cblock *ivec) + { +@@ -302,6 +317,7 @@ DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, + return(tout1); + #else + EVP_CIPHER_CTX *cctx = NULL; ++ EVP_CIPHER *alg = NULL; + unsigned char outv[8]; + int tmplen = 0; + +@@ -309,8 +325,10 @@ DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, + memcpy(outv, iv, sizeof outv); + + cctx = EVP_CIPHER_CTX_new(); +- if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, iv, NULL)) { ++ alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); ++ if (!EVP_EncryptInit_ex2(cctx, alg, key, iv, NULL)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_ERROR_INTERNAL; + } + /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ +@@ -318,17 +336,20 @@ DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, + for (; l > 0; l -= 8, in += 8) { + if (!EVP_EncryptUpdate(cctx, outv, &tmplen, in, 8)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_ERROR_INTERNAL; + } + } + if (!EVP_EncryptFinal_ex(cctx, outv + tmplen, &tmplen)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_ERROR_INTERNAL; + } + if (out != NULL) { + memcpy(out, outv, sizeof outv); + } + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return ((outv[7] << 0L) & 0x000000FF) | + ((outv[6] << 8L) & 0x0000FF00) | + ((outv[5] << 16L) & 0x00FF0000) | +@@ -338,7 +359,8 @@ DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, + + + int +-sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, ++sm_encrypt_des_ecb3(struct sc_context *ctx, ++ unsigned char *key, unsigned char *data, int data_len, + unsigned char **out, int *out_len) + { + #if OPENSSL_VERSION_NUMBER < 0x30000000L +@@ -347,6 +369,7 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, + DES_key_schedule ks,ks2; + #else + EVP_CIPHER_CTX *cctx = NULL; ++ EVP_CIPHER *alg = NULL; + int tmplen; + #endif + +@@ -377,7 +400,8 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, + if (cctx == NULL) { + goto err; + } +- if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_ecb(), key, NULL, NULL)) { ++ alg = sc_evp_cipher(ctx, "DES-EDE-ECB"); ++ if (!EVP_EncryptInit_ex2(cctx, alg, key, NULL, NULL)) { + goto err; + } + /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ +@@ -392,10 +416,12 @@ sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, + } + *out_len += tmplen; + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + return SC_SUCCESS; + + err: + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + free(*out); + return SC_ERROR_INTERNAL; + #endif +@@ -415,6 +441,7 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, + #else + unsigned char icv[] = {0x00 ,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + EVP_CIPHER_CTX *cctx = NULL; ++ EVP_CIPHER *alg = NULL; + int tmplen; + #endif + +@@ -441,24 +468,29 @@ sm_decrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, + (sm_des_cblock *)(*out + st), 8, &ks, &ks2, &icv, DES_DECRYPT); + #else + cctx = EVP_CIPHER_CTX_new(); +- if (!EVP_DecryptInit_ex2(cctx, EVP_des_ede_cbc(), key, icv, NULL)) { ++ alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); ++ if (!EVP_DecryptInit_ex2(cctx, alg, key, icv, NULL)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); + } + /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ + EVP_CIPHER_CTX_set_padding(cctx, 0); + if (!EVP_DecryptUpdate(cctx, *out, &tmplen, data, data_len)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); + } + *out_len = tmplen; + + if (!EVP_DecryptFinal_ex(cctx, *out + *out_len, &tmplen)) { + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); + } + *out_len += tmplen; + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + #endif + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_SUCCESS); + } +@@ -477,6 +509,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, + #else + unsigned char icv[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + EVP_CIPHER_CTX *cctx = NULL; ++ EVP_CIPHER *alg = NULL; + int tmplen; + #endif + unsigned char *data; +@@ -527,9 +560,11 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, + DES_3cbc_encrypt((sm_des_cblock *)(data + st), (sm_des_cblock *)(*out + st), 8, &ks, &ks2, &icv, DES_ENCRYPT); + #else + cctx = EVP_CIPHER_CTX_new(); +- if (!EVP_EncryptInit_ex2(cctx, EVP_des_ede_cbc(), key, icv, NULL)) { ++ alg = sc_evp_cipher(ctx, "DES-EDE-CBC"); ++ if (!EVP_EncryptInit_ex2(cctx, alg, key, icv, NULL)) { + free(*out); + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); + } + /* Disable padding, otherwise it will fail to decrypt non-padded inputs */ +@@ -537,6 +572,7 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, + if (!EVP_EncryptUpdate(cctx, *out, &tmplen, data, data_len)) { + free(*out); + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); + } + *out_len = tmplen; +@@ -544,10 +580,12 @@ sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, + if (!EVP_EncryptFinal_ex(cctx, *out + *out_len, &tmplen)) { + free(*out); + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_SM, SC_ERROR_INTERNAL); + } + *out_len += tmplen; + EVP_CIPHER_CTX_free(cctx); ++ sc_evp_cipher_free(alg); + #endif + + free(data); +diff --git a/src/sm/sm-common.h b/src/sm/sm-common.h +index af096865cb..750c38b9a0 100644 +--- a/src/sm/sm-common.h ++++ b/src/sm/sm-common.h +@@ -30,12 +30,15 @@ extern "C" { + + #include "libopensc/sm.h" + +-unsigned int DES_cbc_cksum_3des(const unsigned char *in, sm_des_cblock *output, long length, ++unsigned int DES_cbc_cksum_3des(struct sc_context *ctx, ++ const unsigned char *in, sm_des_cblock *output, long length, + unsigned char *key, sm_const_des_cblock *ivec); +-unsigned int DES_cbc_cksum_3des_emv96(const unsigned char *in, sm_des_cblock *output, ++unsigned int DES_cbc_cksum_3des_emv96(struct sc_context *ctx, ++ const unsigned char *in, sm_des_cblock *output, + long length, unsigned char *key, + sm_const_des_cblock *ivec); +-int sm_encrypt_des_ecb3(unsigned char *key, unsigned char *data, int data_len, ++int sm_encrypt_des_ecb3(struct sc_context *ctx, ++ unsigned char *key, unsigned char *data, int data_len, + unsigned char **out, int *out_len); + int sm_encrypt_des_cbc3(struct sc_context *ctx, unsigned char *key, + const unsigned char *in, size_t in_len, +diff --git a/src/smm/sm-card-authentic.c b/src/smm/sm-card-authentic.c +index b5fc420b15..a58ff5d4c5 100644 +--- a/src/smm/sm-card-authentic.c ++++ b/src/smm/sm-card-authentic.c +@@ -78,7 +78,7 @@ sm_oberthur_diversify_keyset(struct sc_context *ctx, struct sm_info *sm_info, + + sc_debug(ctx, SC_LOG_DEBUG_SM, "key_buf:%s", sc_dump_hex(key_buff, 16)); + +- rv = sm_encrypt_des_ecb3(master_key, key_buff, sizeof(key_buff), &tmp, &tmp_len); ++ rv = sm_encrypt_des_ecb3(ctx, master_key, key_buff, sizeof(key_buff), &tmp, &tmp_len); + LOG_TEST_RET(ctx, rv, "GP init session: cannot derive key"); + + memcpy(keys[ii], tmp, sizeof(gp_keyset->enc)); +diff --git a/src/smm/sm-cwa14890.c b/src/smm/sm-cwa14890.c +index c245ae3989..3d58ddad1b 100644 +--- a/src/smm/sm-cwa14890.c ++++ b/src/smm/sm-cwa14890.c +@@ -71,7 +71,7 @@ sm_cwa_get_mac(struct sc_context *ctx, unsigned char *key, sm_des_cblock *icv, + sc_debug(ctx, SC_LOG_DEBUG_SM, "sm_cwa_get_mac() data to MAC(%i) %s", in_len, sc_dump_hex(buf, in_len)); + sc_debug(ctx, SC_LOG_DEBUG_SM, "sm_cwa_get_mac() ICV %s", sc_dump_hex((unsigned char *)icv, 8)); + +- DES_cbc_cksum_3des_emv96(buf, out, in_len, key, icv); ++ DES_cbc_cksum_3des_emv96(ctx, buf, out, in_len, key, icv); + + free(buf); + LOG_FUNC_RETURN(ctx, SC_SUCCESS); +diff --git a/src/smm/sm-global-platform.c b/src/smm/sm-global-platform.c +index d91c9a7e4a..a8f8a8bc94 100644 +--- a/src/smm/sm-global-platform.c ++++ b/src/smm/sm-global-platform.c +@@ -105,7 +105,7 @@ sc_gp_get_session_key(struct sc_context *ctx, struct sm_gp_session *gp_session, + memcpy(deriv + 8, gp_session->card_challenge, 4); + memcpy(deriv + 12, gp_session->host_challenge + 4, 4); + +- if (sm_encrypt_des_ecb3(key, deriv, 16, &out, &out_len)) { ++ if (sm_encrypt_des_ecb3(ctx, key, deriv, 16, &out, &out_len)) { + if (ctx) + sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "SM GP get session key: des_ecb3 encryption error"); + return NULL; +@@ -123,7 +123,7 @@ sc_gp_get_session_key(struct sc_context *ctx, struct sm_gp_session *gp_session, + + + int +-sm_gp_get_cryptogram(unsigned char *session_key, ++sm_gp_get_cryptogram(struct sc_context *ctx, unsigned char *session_key, + unsigned char *left, unsigned char *right, + unsigned char *out, int out_len) + { +@@ -137,7 +137,7 @@ sm_gp_get_cryptogram(unsigned char *session_key, + memcpy(block + 8, right, 8); + memcpy(block + 16, "\x80\0\0\0\0\0\0\0",8); + +- DES_cbc_cksum_3des(block,&cksum, sizeof(block), session_key, &cksum); ++ DES_cbc_cksum_3des(ctx, block, &cksum, sizeof(block), session_key, &cksum); + + memcpy(out, cksum, 8); + +@@ -146,7 +146,7 @@ sm_gp_get_cryptogram(unsigned char *session_key, + + + int +-sm_gp_get_mac(unsigned char *key, sm_des_cblock *icv, ++sm_gp_get_mac(struct sc_context *ctx, unsigned char *key, sm_des_cblock *icv, + unsigned char *in, int in_len, sm_des_cblock *out) + { + int len; +@@ -161,7 +161,7 @@ sm_gp_get_mac(unsigned char *key, sm_des_cblock *icv, + len = in_len + 8; + len -= (len%8); + +- DES_cbc_cksum_3des(block, out, len, key, icv); ++ DES_cbc_cksum_3des(ctx, block, out, len, key, icv); + + free(block); + return 0; +@@ -211,7 +211,7 @@ sm_gp_init_session(struct sc_context *ctx, struct sm_gp_session *gp_session, + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP init session: session KEK: %s", sc_dump_hex(gp_session->session_kek, 16)); + + memset(cksum, 0, sizeof(cksum)); +- rv = sm_gp_get_cryptogram(gp_session->session_enc, gp_session->host_challenge, gp_session->card_challenge, cksum, sizeof(cksum)); ++ rv = sm_gp_get_cryptogram(ctx, gp_session->session_enc, gp_session->host_challenge, gp_session->card_challenge, cksum, sizeof(cksum)); + LOG_TEST_RET(ctx, rv, "SM GP init session: cannot get cryptogram"); + + sc_debug(ctx, SC_LOG_DEBUG_SM, "SM GP init session: cryptogram: %s", sc_dump_hex(cksum, 8)); +@@ -264,7 +264,7 @@ sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info, + rv = sm_gp_init_session(ctx, gp_session, init_data + 20, 8); + LOG_TEST_RET(ctx, rv, "SM GP authentication: init session error"); + +- rv = sm_gp_get_cryptogram(gp_session->session_enc, ++ rv = sm_gp_get_cryptogram(ctx, gp_session->session_enc, + gp_session->card_challenge, gp_session->host_challenge, + host_cryptogram, sizeof(host_cryptogram)); + LOG_TEST_RET(ctx, rv, "SM GP authentication: get host cryptogram error"); +@@ -286,7 +286,7 @@ sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info, + + memcpy(raw_apdu + offs, host_cryptogram, 8); + offs += 8; +- rv = sm_gp_get_mac(gp_session->session_mac, &gp_session->mac_icv, raw_apdu, offs, &mac); ++ rv = sm_gp_get_mac(ctx, gp_session->session_mac, &gp_session->mac_icv, raw_apdu, offs, &mac); + LOG_TEST_RET(ctx, rv, "SM GP authentication: get MAC error"); + + memcpy(new_rapdu->sbuf, host_cryptogram, 8); +@@ -391,7 +391,7 @@ sm_gp_securize_apdu(struct sc_context *ctx, struct sm_info *sm_info, + + memcpy(buff + 5, apdu_data, apdu->datalen); + +- rv = sm_gp_get_mac(gp_session->session_mac, &gp_session->mac_icv, buff, 5 + apdu->datalen, &mac); ++ rv = sm_gp_get_mac(ctx, gp_session->session_mac, &gp_session->mac_icv, buff, 5 + apdu->datalen, &mac); + LOG_TEST_GOTO_ERR(ctx, rv, "SM GP securize APDU: get MAC error"); + + if (gp_level == SM_GP_SECURITY_MAC) { +diff --git a/src/smm/sm-module.h b/src/smm/sm-module.h +index c12734a36d..4d11ee994d 100644 +--- a/src/smm/sm-module.h ++++ b/src/smm/sm-module.h +@@ -34,9 +34,12 @@ extern "C" { + #include "sm/sm-common.h" + + /* Global Platform definitions */ +-int sm_gp_get_mac(unsigned char *key, sm_des_cblock *icv, unsigned char *in, int in_len, ++int sm_gp_get_mac(struct sc_context *ctx, ++ unsigned char *key, sm_des_cblock *icv, ++ unsigned char *in, int in_len, + sm_des_cblock *out); +-int sm_gp_get_cryptogram(unsigned char *session_key, unsigned char *left, unsigned char *right, ++int sm_gp_get_cryptogram(struct sc_context *ctx, unsigned char *session_key, ++ unsigned char *left, unsigned char *right, + unsigned char *out, int out_len); + int sm_gp_external_authentication(struct sc_context *ctx, struct sm_info *sm_info, + unsigned char *init_data, size_t init_len, +diff --git a/src/tests/unittests/sm.c b/src/tests/unittests/sm.c +index ab6e819e40..a21661e6b5 100644 +--- a/src/tests/unittests/sm.c ++++ b/src/tests/unittests/sm.c +@@ -174,6 +174,7 @@ static void torture_sm_crypt_des_cbc3_force_pad(void **state) + + static void torture_sm_encrypt_des_ecb3(void **state) + { ++ sc_context_t *ctx = *state; + /* Test vector from + * https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-20.pdf + * 5.2.1.1 The Variable Plaintext Known Answer Test -TCBC Mode +@@ -187,9 +188,7 @@ static void torture_sm_encrypt_des_ecb3(void **state) + int out_len = 0; + int rv; + +- (void)state; +- +- rv = sm_encrypt_des_ecb3(key, plain, sizeof(plain), &out, &out_len); ++ rv = sm_encrypt_des_ecb3(ctx, key, plain, sizeof(plain), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); +@@ -197,7 +196,7 @@ static void torture_sm_encrypt_des_ecb3(void **state) + out = NULL; + out_len = 0; + +- rv = sm_encrypt_des_ecb3(key, ciphertext, sizeof(ciphertext), &out, &out_len); ++ rv = sm_encrypt_des_ecb3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +@@ -205,6 +204,7 @@ static void torture_sm_encrypt_des_ecb3(void **state) + + static void torture_sm_encrypt_des_ecb3_multiblock(void **state) + { ++ sc_context_t *ctx = *state; + /* not a test vector -- generated by openssl 1.1.1 */ + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ +@@ -219,9 +219,7 @@ static void torture_sm_encrypt_des_ecb3_multiblock(void **state) + int out_len = 0; + int rv; + +- (void)state; +- +- rv = sm_encrypt_des_ecb3(key, plain, sizeof(plain), &out, &out_len); ++ rv = sm_encrypt_des_ecb3(ctx, key, plain, sizeof(plain), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_int_equal(out_len, sizeof(ciphertext)); + assert_memory_equal(out, ciphertext, sizeof(ciphertext)); +@@ -229,7 +227,7 @@ static void torture_sm_encrypt_des_ecb3_multiblock(void **state) + out = NULL; + out_len = 0; + +- rv = sm_encrypt_des_ecb3(key, ciphertext, sizeof(ciphertext), &out, &out_len); ++ rv = sm_encrypt_des_ecb3(ctx, key, ciphertext, sizeof(ciphertext), &out, &out_len); + assert_int_equal(rv, SC_SUCCESS); + assert_memory_equal(out, plain, sizeof(plain)); + free(out); +@@ -237,6 +235,7 @@ static void torture_sm_encrypt_des_ecb3_multiblock(void **state) + + static void torture_DES_cbc_cksum_3des(void **state) + { ++ sc_context_t *ctx = *state; + /* not a test vector -- generated by openssl 1.1.1 */ + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ +@@ -251,19 +250,18 @@ static void torture_DES_cbc_cksum_3des(void **state) + unsigned char checksum[8]; + unsigned long sum; + +- (void)state; +- +- sum = DES_cbc_cksum_3des(plain, &checksum, sizeof(plain), key, &iv); ++ sum = DES_cbc_cksum_3des(ctx, plain, &checksum, sizeof(plain), key, &iv); + assert_int_equal(sum, sum_ref); + assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref)); + + /* The checksum argument is not required */ +- sum = DES_cbc_cksum_3des(plain, NULL, sizeof(plain), key, &iv); ++ sum = DES_cbc_cksum_3des(ctx, plain, NULL, sizeof(plain), key, &iv); + assert_int_equal(sum, sum_ref); + } + + static void torture_DES_cbc_cksum_3des_multiblock(void **state) + { ++ sc_context_t *ctx = *state; + /* not a test vector -- generated by openssl 1.1.1 */ + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ +@@ -280,19 +278,18 @@ static void torture_DES_cbc_cksum_3des_multiblock(void **state) + unsigned char checksum[8]; + unsigned long sum; + +- (void)state; +- +- sum = DES_cbc_cksum_3des(plain, &checksum, sizeof(plain), key, &iv); ++ sum = DES_cbc_cksum_3des(ctx, plain, &checksum, sizeof(plain), key, &iv); + assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref)); + assert_int_equal(sum, sum_ref); + + /* The checksum argument is not required */ +- sum = DES_cbc_cksum_3des(plain, NULL, sizeof(plain), key, &iv); ++ sum = DES_cbc_cksum_3des(ctx, plain, NULL, sizeof(plain), key, &iv); + assert_int_equal(sum, sum_ref); + } + + static void torture_DES_cbc_cksum_3des_emv96(void **state) + { ++ sc_context_t *ctx = *state; + /* not a test vector -- generated by openssl 1.1.1 */ + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ +@@ -307,19 +304,18 @@ static void torture_DES_cbc_cksum_3des_emv96(void **state) + unsigned char checksum[8]; + unsigned long sum; + +- (void)state; +- +- sum = DES_cbc_cksum_3des_emv96(plain, &checksum, sizeof(plain), key, &iv); ++ sum = DES_cbc_cksum_3des_emv96(ctx, plain, &checksum, sizeof(plain), key, &iv); + assert_int_equal(sum, sum_ref); + assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref)); + + /* The checksum argument is not required */ +- sum = DES_cbc_cksum_3des_emv96(plain, NULL, sizeof(plain), key, &iv); ++ sum = DES_cbc_cksum_3des_emv96(ctx, plain, NULL, sizeof(plain), key, &iv); + assert_int_equal(sum, sum_ref); + } + + static void torture_DES_cbc_cksum_3des_emv96_multiblock(void **state) + { ++ sc_context_t *ctx = *state; + /* not a test vector -- generated by openssl 1.1.1 */ + unsigned char key[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, /* KEY1 */ +@@ -336,14 +332,12 @@ static void torture_DES_cbc_cksum_3des_emv96_multiblock(void **state) + unsigned char checksum[8] = {0}; + unsigned long sum; + +- (void)state; +- +- sum = DES_cbc_cksum_3des_emv96(plain, &checksum, sizeof(plain), key, &iv); ++ sum = DES_cbc_cksum_3des_emv96(ctx, plain, &checksum, sizeof(plain), key, &iv); + assert_memory_equal(checksum, checksum_ref, sizeof(checksum_ref)); + assert_int_equal(sum, sum_ref); + + /* The checksum argument is not required */ +- sum = DES_cbc_cksum_3des_emv96(plain, NULL, sizeof(plain), key, &iv); ++ sum = DES_cbc_cksum_3des_emv96(ctx, plain, NULL, sizeof(plain), key, &iv); + assert_int_equal(sum, sum_ref); + } + +@@ -361,14 +355,20 @@ int main(void) + cmocka_unit_test_setup_teardown(torture_sm_crypt_des_cbc3_force_pad, + setup_sc_context, teardown_sc_context), + /* sm_encrypt_des_ecb3 */ +- cmocka_unit_test(torture_sm_encrypt_des_ecb3), +- cmocka_unit_test(torture_sm_encrypt_des_ecb3_multiblock), ++ cmocka_unit_test_setup_teardown(torture_sm_encrypt_des_ecb3, ++ setup_sc_context, teardown_sc_context), ++ cmocka_unit_test_setup_teardown(torture_sm_encrypt_des_ecb3_multiblock, ++ setup_sc_context, teardown_sc_context), + /* DES_cbc_cksum_3des */ +- cmocka_unit_test(torture_DES_cbc_cksum_3des), +- cmocka_unit_test(torture_DES_cbc_cksum_3des_multiblock), ++ cmocka_unit_test_setup_teardown(torture_DES_cbc_cksum_3des, ++ setup_sc_context, teardown_sc_context), ++ cmocka_unit_test_setup_teardown(torture_DES_cbc_cksum_3des_multiblock, ++ setup_sc_context, teardown_sc_context), + /* DES_cbc_cksum_3des_emv96 */ +- cmocka_unit_test(torture_DES_cbc_cksum_3des_emv96), +- cmocka_unit_test(torture_DES_cbc_cksum_3des_emv96_multiblock), ++ cmocka_unit_test_setup_teardown(torture_DES_cbc_cksum_3des_emv96, ++ setup_sc_context, teardown_sc_context), ++ cmocka_unit_test_setup_teardown(torture_DES_cbc_cksum_3des_emv96_multiblock, ++ setup_sc_context, teardown_sc_context), + }; + + rc = cmocka_run_group_tests(tests, NULL, NULL); + +From 842910535ecd7268ff915546ac45e395828d1b76 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 16 Feb 2023 09:05:56 -0500 +Subject: [PATCH 19/20] Protect from nested initializations + +If a library used by the module itself tries, somehow to also +initializae the module, return a hard error. Nested Initializations are +not permitted. + +Signed-off-by: Simo Sorce +--- + src/pkcs11/pkcs11-global.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c +index 48ef7823f0..e47f644b0a 100644 +--- a/src/pkcs11/pkcs11-global.c ++++ b/src/pkcs11/pkcs11-global.c +@@ -59,6 +59,7 @@ pid_t initialized_pid = (pid_t)-1; + static int in_finalize = 0; + extern CK_FUNCTION_LIST pkcs11_function_list; + extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0; ++int nesting = 0; + + #ifdef PKCS11_THREAD_LOCKING + +@@ -306,12 +307,21 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) + in_finalize = 0; + #endif + ++ /* protect from nesting */ ++ nesting++; ++ if (nesting > 1) { ++ sc_log(context, "C_Initialize(): Nested init detected"); ++ nesting--; ++ return CKR_GENERAL_ERROR; ++ } ++ + /* protect from multiple threads tryng to setup locking */ + C_INITIALIZE_M_LOCK + + if (context != NULL) { + sc_log(context, "C_Initialize(): Cryptoki already initialized\n"); + C_INITIALIZE_M_UNLOCK ++ nesting--; + return CKR_CRYPTOKI_ALREADY_INITIALIZED; + } + +@@ -366,6 +376,7 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) + /* protect from multiple threads tryng to setup locking */ + C_INITIALIZE_M_UNLOCK + ++ nesting--; + return rv; + } + + +From 31809ef5eb12b37db23fed6a295484fac86cd178 Mon Sep 17 00:00:00 2001 +From: Simo Sorce +Date: Thu, 16 Feb 2023 17:13:19 -0500 +Subject: [PATCH 20/20] Add thread locking protection for nesting check + +Signed-off-by: Simo Sorce +--- + src/pkcs11/pkcs11-global.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c +index e47f644b0a..cbc7445bb9 100644 +--- a/src/pkcs11/pkcs11-global.c ++++ b/src/pkcs11/pkcs11-global.c +@@ -308,20 +308,24 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) + #endif + + /* protect from nesting */ ++ C_INITIALIZE_M_LOCK + nesting++; + if (nesting > 1) { + sc_log(context, "C_Initialize(): Nested init detected"); + nesting--; ++ C_INITIALIZE_M_UNLOCK + return CKR_GENERAL_ERROR; + } ++ C_INITIALIZE_M_UNLOCK ++ /* protect from nesting */ + + /* protect from multiple threads tryng to setup locking */ + C_INITIALIZE_M_LOCK + + if (context != NULL) { + sc_log(context, "C_Initialize(): Cryptoki already initialized\n"); +- C_INITIALIZE_M_UNLOCK + nesting--; ++ C_INITIALIZE_M_UNLOCK + return CKR_CRYPTOKI_ALREADY_INITIALIZED; + } + +@@ -374,9 +378,9 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) + } + + /* protect from multiple threads tryng to setup locking */ ++ nesting--; + C_INITIALIZE_M_UNLOCK + +- nesting--; + return rv; + } + + diff --git a/SOURCES/opensc-0.23.0-pkcs11-tool-import.patch b/SOURCES/opensc-0.23.0-pkcs11-tool-import.patch new file mode 100644 index 0000000..2905005 --- /dev/null +++ b/SOURCES/opensc-0.23.0-pkcs11-tool-import.patch @@ -0,0 +1,212 @@ +From 99f7b82f187ca3512ceae6270c391243d018fdac Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Thu, 1 Dec 2022 20:08:53 +0100 +Subject: [PATCH 1/4] pkcs11-tool: Fix private key import + +--- + src/tools/pkcs11-tool.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c +index aae205fe2c..cfee8526d5 100644 +--- a/src/tools/pkcs11-tool.c ++++ b/src/tools/pkcs11-tool.c +@@ -3669,13 +3669,13 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) + RSA_get0_factors(r, &r_p, &r_q); + RSA_get0_crt_params(r, &r_dmp1, &r_dmq1, &r_iqmp); + #else +- if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &r_d) != 1 || ++ if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_D, &r_d) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1, &r_p) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &r_q) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &r_dmp1) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &r_dmq1) != 1 || +- EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT3, &r_iqmp) != 1) { + util_fatal("OpenSSL error during RSA private key parsing"); ++ EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &r_iqmp) != 1) { + } + #endif + RSA_GET_BN(rsa, private_exponent, r_d); + +From 4a6e1d1dcd18757502027b1c5d2fb2cbaca28407 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Thu, 1 Dec 2022 20:11:41 +0100 +Subject: [PATCH 2/4] pkcs11-tool: Log more information on OpenSSL errors + +--- + src/tools/pkcs11-tool.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c +index cfee8526d5..f2e6b1dd91 100644 +--- a/src/tools/pkcs11-tool.c ++++ b/src/tools/pkcs11-tool.c +@@ -3641,10 +3641,8 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) + const BIGNUM *r_dmp1, *r_dmq1, *r_iqmp; + r = EVP_PKEY_get1_RSA(pkey); + if (!r) { +- if (private) +- util_fatal("OpenSSL error during RSA private key parsing"); +- else +- util_fatal("OpenSSL error during RSA public key parsing"); ++ util_fatal("OpenSSL error during RSA %s key parsing: %s", private ? "private" : "public", ++ ERR_error_string(ERR_peek_last_error(), NULL)); + } + + RSA_get0_key(r, &r_n, &r_e, NULL); +@@ -3654,10 +3652,8 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) + BIGNUM *r_dmp1 = NULL, *r_dmq1 = NULL, *r_iqmp = NULL; + if (EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_N, &r_n) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_E, &r_e) != 1) { +- if (private) +- util_fatal("OpenSSL error during RSA private key parsing"); +- else +- util_fatal("OpenSSL error during RSA public key parsing"); ++ util_fatal("OpenSSL error during RSA %s key parsing: %s", private ? "private" : "public", ++ ERR_error_string(ERR_peek_last_error(), NULL)); + } + #endif + RSA_GET_BN(rsa, modulus, r_n); +@@ -3674,8 +3670,9 @@ parse_rsa_pkey(EVP_PKEY *pkey, int private, struct rsakey_info *rsa) + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2, &r_q) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT1, &r_dmp1) != 1 || + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_EXPONENT2, &r_dmq1) != 1 || +- util_fatal("OpenSSL error during RSA private key parsing"); + EVP_PKEY_get_bn_param(pkey, OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &r_iqmp) != 1) { ++ util_fatal("OpenSSL error during RSA private key parsing: %s", ++ ERR_error_string(ERR_peek_last_error(), NULL)); + } + #endif + RSA_GET_BN(rsa, private_exponent, r_d); + +From 267da3e81f1fc23a9ccce1462ab5deb1a4d4aec5 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Thu, 1 Dec 2022 20:38:31 +0100 +Subject: [PATCH 3/4] Reproducer for broken pkcs11-tool key import + +--- + tests/Makefile.am | 10 ++++--- + tests/test-pkcs11-tool-import.sh | 48 ++++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+), 4 deletions(-) + create mode 100755 tests/test-pkcs11-tool-import.sh + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index d378e2ee00..9d8a24c321 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -14,8 +14,9 @@ dist_noinst_SCRIPTS = common.sh \ + test-pkcs11-tool-test-threads.sh \ + test-pkcs11-tool-sign-verify.sh \ + test-pkcs11-tool-allowed-mechanisms.sh \ +- test-pkcs11-tool-sym-crypt-test.sh\ +- test-pkcs11-tool-unwrap-wrap-test.sh ++ test-pkcs11-tool-sym-crypt-test.sh \ ++ test-pkcs11-tool-unwrap-wrap-test.sh \ ++ test-pkcs11-tool-import.sh + + .NOTPARALLEL: + TESTS = \ +@@ -25,8 +26,9 @@ TESTS = \ + test-pkcs11-tool-test.sh \ + test-pkcs11-tool-test-threads.sh \ + test-pkcs11-tool-allowed-mechanisms.sh \ +- test-pkcs11-tool-sym-crypt-test.sh\ +- test-pkcs11-tool-unwrap-wrap-test.sh ++ test-pkcs11-tool-sym-crypt-test.sh \ ++ test-pkcs11-tool-unwrap-wrap-test.sh \ ++ test-pkcs11-tool-import.sh + XFAIL_TESTS = \ + test-pkcs11-tool-test-threads.sh \ + test-pkcs11-tool-test.sh +diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh +new file mode 100755 +index 0000000000..76ff8e51be +--- /dev/null ++++ b/tests/test-pkcs11-tool-import.sh +@@ -0,0 +1,48 @@ ++#!/bin/bash ++SOURCE_PATH=${SOURCE_PATH:-..} ++ ++source $SOURCE_PATH/tests/common.sh ++ ++echo "=======================================================" ++echo "Setup SoftHSM" ++echo "=======================================================" ++if [[ ! -f $P11LIB ]]; then ++ echo "WARNING: The SoftHSM is not installed. Can not run this test" ++ exit 77; ++fi ++card_setup ++ ++ID="0100" ++OPTS="" ++for KEYTYPE in "RSA" "EC"; do ++ echo "=======================================================" ++ echo "Generate and import $KEYTYPE keys" ++ echo "=======================================================" ++ if [ "$KEYTYPE" == "RSA" ]; then ++ ID="0100" ++ elif [ "$KEYTYPE" == "EC" ]; then ++ ID="0200" ++ OPTS="-pkeyopt ec_paramgen_curve:P-521" ++ fi ++ openssl genpkey -out "${KEYTYPE}_private.der" -outform DER -algorithm $KEYTYPE $OPTS ++ assert $? "Failed to generate private $KEYTYPE key" ++ $PKCS11_TOOL --write-object "${KEYTYPE}_private.der" --id "$ID" --type privkey \ ++ --label "$KEYTYPE" -p "$PIN" --module "$P11LIB" ++ assert $? "Failed to write private $KEYTYPE key" ++ ++ openssl pkey -in "${KEYTYPE}_private.der" -out "${KEYTYPE}_public.der" -pubout -inform DER -outform DER ++ assert $? "Failed to convert private $KEYTYPE key to public" ++ $PKCS11_TOOL --write-object "${KEYTYPE}_public.der" --id "$ID" --type pubkey --label "$KEYTYPE" \ ++ -p $PIN --module $P11LIB ++ assert $? "Failed to write public $KEYTYPE key" ++ # certificate import already tested in all other tests ++ ++ rm "${KEYTYPE}_private.der" "${KEYTYPE}_public.der" ++done ++ ++echo "=======================================================" ++echo "Cleanup" ++echo "=======================================================" ++card_cleanup ++ ++exit $ERRORS + +From 63a7bceeca43ece1eee201ef7a974b20b294ba4e Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 2 Dec 2022 18:07:43 +0100 +Subject: [PATCH 4/4] Simplify the new test +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Co-authored-by: Veronika Hanulíková <61348757+xhanulik@users.noreply.github.com> +--- + tests/test-pkcs11-tool-import.sh | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/tests/test-pkcs11-tool-import.sh b/tests/test-pkcs11-tool-import.sh +index 76ff8e51be..c90b3b4926 100755 +--- a/tests/test-pkcs11-tool-import.sh ++++ b/tests/test-pkcs11-tool-import.sh +@@ -12,15 +12,13 @@ if [[ ! -f $P11LIB ]]; then + fi + card_setup + +-ID="0100" +-OPTS="" + for KEYTYPE in "RSA" "EC"; do + echo "=======================================================" + echo "Generate and import $KEYTYPE keys" + echo "=======================================================" +- if [ "$KEYTYPE" == "RSA" ]; then +- ID="0100" +- elif [ "$KEYTYPE" == "EC" ]; then ++ ID="0100" ++ OPTS="" ++ if [ "$KEYTYPE" == "EC" ]; then + ID="0200" + OPTS="-pkeyopt ec_paramgen_curve:P-521" + fi + diff --git a/SOURCES/opensc-32b-arch.patch b/SOURCES/opensc-32b-arch.patch deleted file mode 100644 index 70213b1..0000000 --- a/SOURCES/opensc-32b-arch.patch +++ /dev/null @@ -1,33 +0,0 @@ -commit 6bc05d7037041e543d627248ca9df90723426ce1 -Author: Jakub Jelen -Date: Tue Aug 10 16:30:40 2021 +0200 - - p11test: Fix invalid format string on 32b architectures - -diff --git a/src/tests/p11test/p11test.c b/src/tests/p11test/p11test.c -index dbac167d..49de6a93 100644 ---- a/src/tests/p11test/p11test.c -+++ b/src/tests/p11test/p11test.c -@@ -139,7 +139,7 @@ int main(int argc, char** argv) { - return -1; - } - -- debug_print("Card info:\n\tPIN %s\n\tPIN LENGTH %lu\n\t", -+ debug_print("Card info:\n\tPIN %s\n\tPIN LENGTH %zu\n\t", - token.pin, token.pin_length); - - return cmocka_run_group_tests(readonly_tests_without_initialization, -diff --git a/src/tests/p11test/p11test_case_pss_oaep.c b/src/tests/p11test/p11test_case_pss_oaep.c -index 1d876a5b..5a6ae9d0 100644 ---- a/src/tests/p11test/p11test_case_pss_oaep.c -+++ b/src/tests/p11test/p11test_case_pss_oaep.c -@@ -402,7 +402,7 @@ int oaep_encrypt_decrypt_test(test_cert_t *o, token_info_t *info, test_mech_t *m - if (message_length < 0) { - mech->usage_flags &= ~CKF_DECRYPT; - debug_print(" [SKIP %s ] Too small modulus (%ld bits)" -- " or too large hash %s (%lu B) for OAEP", o->id_str, -+ " or too large hash %s (%zu B) for OAEP", o->id_str, - o->bits, get_mechanism_name(mech->hash), - get_hash_length(mech->hash)); - return 0; - diff --git a/SOURCES/opensc-gcc11.patch b/SOURCES/opensc-gcc11.patch deleted file mode 100644 index fb670c3..0000000 --- a/SOURCES/opensc-gcc11.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c -index d251495c..e48f3189 100644 ---- a/src/tools/opensc-explorer.c -+++ b/src/tools/opensc-explorer.c -@@ -2030,9 +2030,9 @@ static int do_put_data(int argc, char **argv) - static int do_apdu(int argc, char **argv) - { - sc_apdu_t apdu; -- u8 buf[SC_MAX_EXT_APDU_BUFFER_SIZE]; -+ u8 buf[SC_MAX_EXT_APDU_BUFFER_SIZE] = {0}; - u8 rbuf[SC_MAX_EXT_APDU_BUFFER_SIZE]; -- size_t len, i; -+ size_t len = 0, i; - int r; - - if (argc < 1) diff --git a/SPECS/opensc.spec b/SPECS/opensc.spec index a749e2c..9b6e0cd 100644 --- a/SPECS/opensc.spec +++ b/SPECS/opensc.spec @@ -2,7 +2,7 @@ %define nssdb %{_sysconfdir}/pki/nssdb Name: opensc -Version: 0.22.0 +Version: 0.23.0 Release: 2%{?dist} Summary: Smart card library and applications @@ -11,16 +11,20 @@ URL: https://github.com/OpenSC/OpenSC/wiki Source0: https://github.com/OpenSC/OpenSC/releases/download/%{version}/%{name}-%{version}.tar.gz Source1: opensc.module Patch1: opensc-0.19.0-pinpad.patch -# https://github.com/OpenSC/OpenSC/pull/2241/ -Patch5: %{name}-gcc11.patch -# https://github.com/OpenSC/OpenSC/pull/2343 -Patch7: %{name}-32b-arch.patch # File caching by default (#2000626) -Patch8: %{name}-%{version}-file-cache.patch -# https://github.com/OpenSC/OpenSC/pull/2414 (#2007029) -Patch9: %{name}-%{version}-detect-empty.patch +Patch8: %{name}-0.22.0-file-cache.patch +# https://github.com/OpenSC/OpenSC/pull/2656 +Patch9: %{name}-0.23.0-pkcs11-tool-import.patch +# https://github.com/OpenSC/OpenSC/pull/2712 +Patch10: %{name}-0.23.0-openssl-ctx.patch +# https://github.com/OpenSC/OpenSC/pull/2753 +# https://github.com/OpenSC/OpenSC/commit/e8fba322a2f4d06ec5c74fe80f9e2b0e9fdefec6 +# https://github.com/OpenSC/OpenSC/commit/891f10e49de1a5ee038b1cb2fb59dce40429e6c2 +Patch11: %{name}-0.23.0-openpgp.patch +# https://github.com/OpenSC/OpenSC/commit/81944d1529202bd28359bede57c0a15deb65ba8a +Patch12: %{name}-0.23.0-cardos-pkcs15init.patch -BuildRequires: make +BuildRequires: make BuildRequires: pcsc-lite-devel BuildRequires: readline-devel BuildRequires: openssl-devel @@ -31,6 +35,7 @@ BuildRequires: bash-completion BuildRequires: zlib-devel # For tests BuildRequires: libcmocka-devel +BuildRequires: vim-common %if ! 0%{?rhel} BuildRequires: softhsm %endif @@ -56,10 +61,11 @@ every software/card that does so, too. %prep %setup -q %patch1 -p1 -b .pinpad -%patch5 -p1 -b .gcc11 -%patch7 -p1 -b .32b %patch8 -p1 -b .file-cache -%patch9 -p1 -b .detect-empty +%patch9 -p1 -b .pkcs11-tool-import +%patch10 -p1 -b .ossl3context +%patch11 -p1 -b .openpgp +%patch12 -p1 -b .cardos-pkcs15init cp -p src/pkcs15init/README ./README.pkcs15init cp -p src/scconf/README.scconf . @@ -75,21 +81,19 @@ sed -i -e 's/opensc.conf/opensc-%{_arch}.conf/g' src/libopensc/Makefile.in sed -i -e 's|"/lib /usr/lib\b|"/%{_lib} %{_libdir}|' configure # lib64 rpaths %set_build_flags CFLAGS="$CFLAGS -Wstrict-aliasing=2 -Wno-deprecated-declarations" -%configure --disable-static \ +%configure --disable-static \ --disable-autostart-items \ --disable-notify \ --disable-assert \ --enable-pcsc \ --enable-cmocka \ - --enable-sm \ - --with-pcsc-provider=libpcsclite.so.1 + --enable-sm %make_build %check make check - %install %make_install install -Dpm 644 %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/p11-kit/modules/opensc.module @@ -119,9 +123,6 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libopensc.so # remove the .pc file so we do not confuse users #1673139 rm -f $RPM_BUILD_ROOT%{_libdir}/pkgconfig/*.pc rm -f $RPM_BUILD_ROOT%{_libdir}/libsmm-local.so -%if 0%{?rhel} && 0%{?rhel} < 7 -rm -rf %{buildroot}%{_datadir}/bash-completion/ -%endif # the npa-tool builds to nothing since we do not have OpenPACE library rm -rf %{buildroot}%{_bindir}/npa-tool @@ -132,7 +133,6 @@ rm -rf %{buildroot}%{_bindir}/pkcs11-register rm -rf %{buildroot}%{_mandir}/man1/pkcs11-register.1* # Remove the notification files -rm %{buildroot}%{_bindir}/opensc-notify rm %{buildroot}%{_datadir}/applications/org.opensc.notify.desktop rm %{buildroot}%{_mandir}/man1/opensc-notify.1* @@ -140,9 +140,7 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1* %files %doc COPYING NEWS README* -%if ! 0%{?rhel} || 0%{?rhel} >= 7 %{_datadir}/bash-completion/* -%endif %ifarch %{ix86} %{_mandir}/man5/opensc-%{_arch}.conf.5* @@ -209,6 +207,14 @@ rm %{buildroot}%{_mandir}/man1/opensc-notify.1* %changelog +* Thu May 25 2023 Jakub Jelen - 0.23.0-2 +- Fix regression in handling OpenPGP cards +- Fix CVE-2023-2977: buffer overrun in pkcs15init for cardos + +* Wed Mar 08 2023 Jakub Jelen - 0.23.0-1 +- Rebase to latest 0.23.0 release (#2100409) +- Use separate OpenSSL context to work better from inside of OpenSSL providers + * Fri Oct 08 2021 Jakub Jelen - 0.22.0-2 - Unbreak detection of unentrolled smart cards (#2007029) - Enable file caching by default except for pkcs15-init (#2000626)