From 31a796d1cc884c727a226d3dfba6a1ad7a50b865 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Sun, 2 Feb 2020 13:09:09 +0100 Subject: [PATCH] PROV: Implement padding mode words in the RSA ASYM_CIPHER implementation Because the libcrypto code has relinquished control of exact words to express padding mode choices, we re-implement them in the appropriate provider implementation. For the sake of legacy controls, we maintain support for the numeric form of the padding mode, but leave that support otherwise undeclared. Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/10947) --- crypto/err/openssl.txt | 1 + .../common/include/prov/providercommonerr.h | 3 +- providers/common/provider_err.c | 4 +- .../implementations/asymciphers/rsa_enc.c | 72 +++++++++++++++++-- 4 files changed, 72 insertions(+), 8 deletions(-) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index eb8d32dcff..b59c8ba1c6 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2766,6 +2766,7 @@ PROV_R_TAG_NOTSET:119:tag notset PROV_R_TAG_NOT_NEEDED:120:tag not needed PROV_R_UNABLE_TO_LOAD_SHA1:143:unable to load sha1 PROV_R_UNABLE_TO_LOAD_SHA256:147:unable to load sha256 +PROV_R_UNKNOWN_PADDING_TYPE:163:unknown padding type PROV_R_UNSUPPORTED_CEK_ALG:145:unsupported cek alg PROV_R_UNSUPPORTED_KEY_SIZE:153:unsupported key size PROV_R_UNSUPPORTED_MAC_TYPE:137:unsupported mac type diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h index d97b735ca9..21d7f54a57 100644 --- a/providers/common/include/prov/providercommonerr.h +++ b/providers/common/include/prov/providercommonerr.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -103,6 +103,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_TAG_NOT_NEEDED 120 # define PROV_R_UNABLE_TO_LOAD_SHA1 143 # define PROV_R_UNABLE_TO_LOAD_SHA256 147 +# define PROV_R_UNKNOWN_PADDING_TYPE 163 # define PROV_R_UNSUPPORTED_CEK_ALG 145 # define PROV_R_UNSUPPORTED_KEY_SIZE 153 # define PROV_R_UNSUPPORTED_MAC_TYPE 137 diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index eba3dbef5f..fcb0722070 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -88,6 +88,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "unable to load sha1"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_LOAD_SHA256), "unable to load sha256"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNKNOWN_PADDING_TYPE), + "unknown padding type"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_CEK_ALG), "unsupported cek alg"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_KEY_SIZE), diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c index 77f807e7ef..c72571d6bb 100644 --- a/providers/implementations/asymciphers/rsa_enc.c +++ b/providers/implementations/asymciphers/rsa_enc.c @@ -37,6 +37,16 @@ static OSSL_OP_asym_cipher_gettable_ctx_params_fn rsa_gettable_ctx_params; static OSSL_OP_asym_cipher_set_ctx_params_fn rsa_set_ctx_params; static OSSL_OP_asym_cipher_settable_ctx_params_fn rsa_settable_ctx_params; +static OSSL_ITEM padding_item[] = { + { RSA_PKCS1_PADDING, "pkcs1" }, + { RSA_SSLV23_PADDING, "sslv23" }, + { RSA_NO_PADDING, "none" }, + { RSA_PKCS1_OAEP_PADDING, "oaep" }, /* Correct spelling first */ + { RSA_PKCS1_OAEP_PADDING, "oeap" }, + { RSA_X931_PADDING, "x931" }, + { RSA_PKCS1_PSS_PADDING, "pss" }, + { 0, NULL } +}; /* * What's passed as an actual key is defined by the KEYMGMT interface. @@ -263,8 +273,35 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) return 0; p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_PAD_MODE); - if (p != NULL && !OSSL_PARAM_set_int(p, prsactx->pad_mode)) - return 0; + if (p != NULL) + switch (p->data_type) { + case OSSL_PARAM_INTEGER: /* Support for legacy pad mode number */ + if (!OSSL_PARAM_set_int(p, prsactx->pad_mode)) + return 0; + break; + case OSSL_PARAM_UTF8_STRING: + { + int i; + const char *word = NULL; + + for (i = 0; padding_item[i].id != 0; i++) { + if (prsactx->pad_mode == (int)padding_item[i].id) { + word = padding_item[i].ptr; + break; + } + } + + if (word != NULL) { + if (!OSSL_PARAM_set_utf8_string(p, word)) + return 0; + } else { + ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); + } + } + break; + default: + return 0; + } p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST); if (p != NULL && !OSSL_PARAM_set_utf8_string(p, prsactx->oaep_md == NULL @@ -304,7 +341,7 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) static const OSSL_PARAM known_gettable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0), - OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL), + OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL, 0), OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0), OSSL_PARAM_DEFN(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, OSSL_PARAM_OCTET_PTR, NULL, 0), @@ -326,7 +363,6 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) char mdname[OSSL_MAX_NAME_SIZE]; char mdprops[OSSL_MAX_PROPQUERY_SIZE] = { '\0' }; char *str = mdname; - int pad_mode; if (prsactx == NULL || params == NULL) return 0; @@ -353,8 +389,32 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_PAD_MODE); if (p != NULL) { - if (!OSSL_PARAM_get_int(p, &pad_mode)) + int pad_mode = 0; + + switch (p->data_type) { + case OSSL_PARAM_INTEGER: /* Support for legacy pad mode number */ + if (!OSSL_PARAM_get_int(p, &pad_mode)) + return 0; + break; + case OSSL_PARAM_UTF8_STRING: + { + int i; + + if (p->data == NULL) + return 0; + + for (i = 0; padding_item[i].id != 0; i++) { + if (strcmp(p->data, padding_item[i].ptr) == 0) { + pad_mode = padding_item[i].id; + break; + } + } + } + break; + default: return 0; + } + /* * PSS padding is for signatures only so is not compatible with * asymmetric cipher use. @@ -426,7 +486,7 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0), - OSSL_PARAM_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL), + OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, NULL, 0), OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, NULL, 0), OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS, NULL, 0), OSSL_PARAM_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, NULL, 0), -- 2.25.1