X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=providers%2Fimplementations%2Fasymciphers%2Frsa_enc.c;h=02833c70198664691cec7830628951b684056afb;hb=HEAD;hp=c72571d6bb0b8c619f938aa948ef826a5d2e0288;hpb=31a796d1cc884c727a226d3dfba6a1ad7a50b865;p=openssl.git diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c index c72571d6bb..71bfa344d4 100644 --- a/providers/implementations/asymciphers/rsa_enc.c +++ b/providers/implementations/asymciphers/rsa_enc.c @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2023 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 @@ -7,44 +7,50 @@ * https://www.openssl.org/source/license.html */ +/* + * RSA low level APIs are deprecated for public use, but still ok for + * internal use. + */ +#include "internal/deprecated.h" + #include #include -#include +#include #include #include #include #include +#include /* Just for SSL_MAX_MASTER_KEY_LENGTH */ -#include +#include #include "internal/constant_time.h" #include "internal/sizes.h" #include "crypto/rsa.h" -#include "prov/providercommonerr.h" #include "prov/provider_ctx.h" #include "prov/implementations.h" +#include "prov/providercommon.h" +#include "prov/securitycheck.h" #include -static OSSL_OP_asym_cipher_newctx_fn rsa_newctx; -static OSSL_OP_asym_cipher_encrypt_init_fn rsa_init; -static OSSL_OP_asym_cipher_encrypt_fn rsa_encrypt; -static OSSL_OP_asym_cipher_decrypt_init_fn rsa_init; -static OSSL_OP_asym_cipher_decrypt_fn rsa_decrypt; -static OSSL_OP_asym_cipher_freectx_fn rsa_freectx; -static OSSL_OP_asym_cipher_dupctx_fn rsa_dupctx; -static OSSL_OP_asym_cipher_get_ctx_params_fn rsa_get_ctx_params; -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_FUNC_asym_cipher_newctx_fn rsa_newctx; +static OSSL_FUNC_asym_cipher_encrypt_init_fn rsa_encrypt_init; +static OSSL_FUNC_asym_cipher_encrypt_fn rsa_encrypt; +static OSSL_FUNC_asym_cipher_decrypt_init_fn rsa_decrypt_init; +static OSSL_FUNC_asym_cipher_decrypt_fn rsa_decrypt; +static OSSL_FUNC_asym_cipher_freectx_fn rsa_freectx; +static OSSL_FUNC_asym_cipher_dupctx_fn rsa_dupctx; +static OSSL_FUNC_asym_cipher_get_ctx_params_fn rsa_get_ctx_params; +static OSSL_FUNC_asym_cipher_gettable_ctx_params_fn rsa_gettable_ctx_params; +static OSSL_FUNC_asym_cipher_set_ctx_params_fn rsa_set_ctx_params; +static OSSL_FUNC_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_PADDING, OSSL_PKEY_RSA_PAD_MODE_PKCSV15 }, + { RSA_NO_PADDING, OSSL_PKEY_RSA_PAD_MODE_NONE }, + { RSA_PKCS1_OAEP_PADDING, OSSL_PKEY_RSA_PAD_MODE_OAEP }, /* Correct spelling first */ { RSA_PKCS1_OAEP_PADDING, "oeap" }, - { RSA_X931_PADDING, "x931" }, - { RSA_PKCS1_PSS_PADDING, "pss" }, + { RSA_X931_PADDING, OSSL_PKEY_RSA_PAD_MODE_X931 }, { 0, NULL } }; @@ -55,9 +61,10 @@ static OSSL_ITEM padding_item[] = { */ typedef struct { - OPENSSL_CTX *libctx; + OSSL_LIB_CTX *libctx; RSA *rsa; int pad_mode; + int operation; /* OAEP message digest */ EVP_MD *oaep_md; /* message digest for MGF1 */ @@ -68,29 +75,64 @@ typedef struct { /* TLS padding */ unsigned int client_version; unsigned int alt_version; + /* PKCS#1 v1.5 decryption mode */ + unsigned int implicit_rejection; } PROV_RSA_CTX; static void *rsa_newctx(void *provctx) { - PROV_RSA_CTX *prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX)); + PROV_RSA_CTX *prsactx; + if (!ossl_prov_is_running()) + return NULL; + prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX)); if (prsactx == NULL) return NULL; - prsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + prsactx->libctx = PROV_LIBCTX_OF(provctx); return prsactx; } -static int rsa_init(void *vprsactx, void *vrsa) +static int rsa_init(void *vprsactx, void *vrsa, const OSSL_PARAM params[], + int operation) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; - if (prsactx == NULL || vrsa == NULL || !RSA_up_ref(vrsa)) + if (!ossl_prov_is_running() || prsactx == NULL || vrsa == NULL) + return 0; + + if (!ossl_rsa_check_key(prsactx->libctx, vrsa, operation)) + return 0; + + if (!RSA_up_ref(vrsa)) return 0; RSA_free(prsactx->rsa); prsactx->rsa = vrsa; - prsactx->pad_mode = RSA_PKCS1_PADDING; - return 1; + prsactx->operation = operation; + prsactx->implicit_rejection = 1; + + switch (RSA_test_flags(prsactx->rsa, RSA_FLAG_TYPE_MASK)) { + case RSA_FLAG_TYPE_RSA: + prsactx->pad_mode = RSA_PKCS1_PADDING; + break; + default: + /* This should not happen due to the check above */ + ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); + return 0; + } + return rsa_set_ctx_params(prsactx, params); +} + +static int rsa_encrypt_init(void *vprsactx, void *vrsa, + const OSSL_PARAM params[]) +{ + return rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_ENCRYPT); +} + +static int rsa_decrypt_init(void *vprsactx, void *vrsa, + const OSSL_PARAM params[]) +{ + return rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_DECRYPT); } static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, @@ -99,6 +141,9 @@ static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; int ret; + if (!ossl_prov_is_running()) + return 0; + if (out == NULL) { size_t len = RSA_size(prsactx->rsa); @@ -114,15 +159,23 @@ static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen, int rsasize = RSA_size(prsactx->rsa); unsigned char *tbuf; - if ((tbuf = OPENSSL_malloc(rsasize)) == NULL) { - PROVerr(0, ERR_R_MALLOC_FAILURE); + if ((tbuf = OPENSSL_malloc(rsasize)) == NULL) return 0; + if (prsactx->oaep_md == NULL) { + prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA-1", NULL); + if (prsactx->oaep_md == NULL) { + OPENSSL_free(tbuf); + ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); + return 0; + } } - ret = RSA_padding_add_PKCS1_OAEP_mgf1(tbuf, rsasize, in, inlen, - prsactx->oaep_label, - prsactx->oaep_labellen, - prsactx->oaep_md, - prsactx->mgf1_md); + ret = + ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(prsactx->libctx, tbuf, + rsasize, in, inlen, + prsactx->oaep_label, + prsactx->oaep_labellen, + prsactx->oaep_md, + prsactx->mgf1_md); if (!ret) { OPENSSL_free(tbuf); @@ -147,8 +200,12 @@ static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; int ret; + int pad_mode; size_t len = RSA_size(prsactx->rsa); + if (!ossl_prov_is_running()) + return 0; + if (prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) { if (out == NULL) { *outlen = SSL_MAX_MASTER_KEY_LENGTH; @@ -178,10 +235,8 @@ static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, || prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) { unsigned char *tbuf; - if ((tbuf = OPENSSL_malloc(len)) == NULL) { - PROVerr(0, ERR_R_MALLOC_FAILURE); + if ((tbuf = OPENSSL_malloc(len)) == NULL) return 0; - } ret = RSA_private_decrypt(inlen, in, tbuf, prsactx->rsa, RSA_NO_PADDING); /* @@ -194,6 +249,14 @@ static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, return 0; } if (prsactx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + if (prsactx->oaep_md == NULL) { + prsactx->oaep_md = EVP_MD_fetch(prsactx->libctx, "SHA-1", NULL); + if (prsactx->oaep_md == NULL) { + OPENSSL_free(tbuf); + ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); + return 0; + } + } ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, outsize, tbuf, len, len, prsactx->oaep_label, @@ -204,17 +267,21 @@ static int rsa_decrypt(void *vprsactx, unsigned char *out, size_t *outlen, /* RSA_PKCS1_WITH_TLS_PADDING */ if (prsactx->client_version <= 0) { ERR_raise(ERR_LIB_PROV, PROV_R_BAD_TLS_CLIENT_VERSION); + OPENSSL_free(tbuf); return 0; } - ret = rsa_padding_check_PKCS1_type_2_TLS(out, outsize, - tbuf, len, - prsactx->client_version, - prsactx->alt_version); + ret = ossl_rsa_padding_check_PKCS1_type_2_TLS( + prsactx->libctx, out, outsize, tbuf, len, + prsactx->client_version, prsactx->alt_version); } OPENSSL_free(tbuf); } else { - ret = RSA_private_decrypt(inlen, in, out, prsactx->rsa, - prsactx->pad_mode); + if ((prsactx->implicit_rejection == 0) && + (prsactx->pad_mode == RSA_PKCS1_PADDING)) + pad_mode = RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING; + else + pad_mode = prsactx->pad_mode; + ret = RSA_private_decrypt(inlen, in, out, prsactx->rsa, pad_mode); } *outlen = constant_time_select_s(constant_time_msb_s(ret), *outlen, ret); ret = constant_time_select_int(constant_time_msb(ret), 0, 1); @@ -229,6 +296,7 @@ static void rsa_freectx(void *vprsactx) EVP_MD_free(prsactx->oaep_md); EVP_MD_free(prsactx->mgf1_md); + OPENSSL_free(prsactx->oaep_label); OPENSSL_free(prsactx); } @@ -238,6 +306,9 @@ static void *rsa_dupctx(void *vprsactx) PROV_RSA_CTX *srcctx = (PROV_RSA_CTX *)vprsactx; PROV_RSA_CTX *dstctx; + if (!ossl_prov_is_running()) + return NULL; + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); if (dstctx == NULL) return NULL; @@ -269,7 +340,7 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; OSSL_PARAM *p; - if (prsactx == NULL || params == NULL) + if (prsactx == NULL) return 0; p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_PAD_MODE); @@ -306,7 +377,7 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST); if (p != NULL && !OSSL_PARAM_set_utf8_string(p, prsactx->oaep_md == NULL ? "" - : EVP_MD_name(prsactx->oaep_md))) + : EVP_MD_get0_name(prsactx->oaep_md))) return 0; p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST); @@ -316,16 +387,14 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) if (!OSSL_PARAM_set_utf8_string(p, mgf1_md == NULL ? "" - : EVP_MD_name(mgf1_md))) + : EVP_MD_get0_name(mgf1_md))) return 0; } p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL); - if (p != NULL && !OSSL_PARAM_set_octet_ptr(p, prsactx->oaep_label, 0)) - return 0; - - p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL_LEN); - if (p != NULL && !OSSL_PARAM_set_size_t(p, prsactx->oaep_labellen)) + if (p != NULL && + !OSSL_PARAM_set_octet_ptr(p, prsactx->oaep_label, + prsactx->oaep_labellen)) return 0; p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION); @@ -336,6 +405,10 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) if (p != NULL && !OSSL_PARAM_set_uint(p, prsactx->alt_version)) return 0; + p = OSSL_PARAM_locate(params, OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION); + if (p != NULL && !OSSL_PARAM_set_uint(p, prsactx->implicit_rejection)) + return 0; + return 1; } @@ -345,13 +418,14 @@ static const OSSL_PARAM known_gettable_ctx_params[] = { 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), - OSSL_PARAM_size_t(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL_LEN, NULL), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL), + OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION, NULL), OSSL_PARAM_END }; -static const OSSL_PARAM *rsa_gettable_ctx_params(void) +static const OSSL_PARAM *rsa_gettable_ctx_params(ossl_unused void *vprsactx, + ossl_unused void *provctx) { return known_gettable_ctx_params; } @@ -362,20 +436,23 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) const OSSL_PARAM *p; char mdname[OSSL_MAX_NAME_SIZE]; char mdprops[OSSL_MAX_PROPQUERY_SIZE] = { '\0' }; - char *str = mdname; + char *str = NULL; - if (prsactx == NULL || params == NULL) + if (prsactx == NULL) return 0; + if (params == NULL) + return 1; p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST); if (p != NULL) { + str = mdname; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdname))) return 0; - str = mdprops; p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS); if (p != NULL) { + str = mdprops; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) return 0; } @@ -431,13 +508,14 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST); if (p != NULL) { + str = mdname; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdname))) return 0; - str = mdprops; p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS); if (p != NULL) { + str = mdprops; if (!OSSL_PARAM_get_utf8_string(p, &str, sizeof(mdprops))) return 0; } else { @@ -480,31 +558,42 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) return 0; prsactx->alt_version = alt_version; } + p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION); + if (p != NULL) { + unsigned int implicit_rejection; + + if (!OSSL_PARAM_get_uint(p, &implicit_rejection)) + return 0; + prsactx->implicit_rejection = implicit_rejection; + } return 1; } static const OSSL_PARAM known_settable_ctx_params[] = { OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS, NULL, 0), 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), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL), OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL), + OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION, NULL), OSSL_PARAM_END }; -static const OSSL_PARAM *rsa_settable_ctx_params(void) +static const OSSL_PARAM *rsa_settable_ctx_params(ossl_unused void *vprsactx, + ossl_unused void *provctx) { return known_settable_ctx_params; } -const OSSL_DISPATCH rsa_asym_cipher_functions[] = { +const OSSL_DISPATCH ossl_rsa_asym_cipher_functions[] = { { OSSL_FUNC_ASYM_CIPHER_NEWCTX, (void (*)(void))rsa_newctx }, - { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, (void (*)(void))rsa_init }, + { OSSL_FUNC_ASYM_CIPHER_ENCRYPT_INIT, (void (*)(void))rsa_encrypt_init }, { OSSL_FUNC_ASYM_CIPHER_ENCRYPT, (void (*)(void))rsa_encrypt }, - { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, (void (*)(void))rsa_init }, + { OSSL_FUNC_ASYM_CIPHER_DECRYPT_INIT, (void (*)(void))rsa_decrypt_init }, { OSSL_FUNC_ASYM_CIPHER_DECRYPT, (void (*)(void))rsa_decrypt }, { OSSL_FUNC_ASYM_CIPHER_FREECTX, (void (*)(void))rsa_freectx }, { OSSL_FUNC_ASYM_CIPHER_DUPCTX, (void (*)(void))rsa_dupctx }, @@ -516,5 +605,5 @@ const OSSL_DISPATCH rsa_asym_cipher_functions[] = { (void (*)(void))rsa_set_ctx_params }, { OSSL_FUNC_ASYM_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))rsa_settable_ctx_params }, - { 0, NULL } + OSSL_DISPATCH_END };