diff options
-rw-r--r-- | crypto/err/openssl.txt | 11 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 118 | ||||
-rw-r--r-- | crypto/rsa/build.info | 2 | ||||
-rw-r--r-- | crypto/rsa/rsa_aid.c | 98 | ||||
-rw-r--r-- | crypto/rsa/rsa_lib.c | 113 | ||||
-rw-r--r-- | crypto/rsa/rsa_local.h | 4 | ||||
-rw-r--r-- | crypto/rsa/rsa_pmeth.c | 1 | ||||
-rw-r--r-- | crypto/rsa/rsa_sign.c | 40 | ||||
-rw-r--r-- | doc/man3/EVP_PKEY_CTX_ctrl.pod | 59 | ||||
-rw-r--r-- | include/crypto/rsa.h | 8 | ||||
-rw-r--r-- | include/openssl/core_names.h | 26 | ||||
-rw-r--r-- | include/openssl/rsa.h | 10 | ||||
-rw-r--r-- | providers/common/include/prov/providercommonerr.h | 10 | ||||
-rw-r--r-- | providers/common/provider_err.c | 19 | ||||
-rw-r--r-- | providers/defltprov.c | 1 | ||||
-rw-r--r-- | providers/implementations/include/prov/implementations.h | 1 | ||||
-rw-r--r-- | providers/implementations/signature/build.info | 3 | ||||
-rw-r--r-- | providers/implementations/signature/rsa.c | 1113 | ||||
-rw-r--r-- | util/libcrypto.num | 2 |
19 files changed, 1517 insertions, 122 deletions
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index e6a45ac..47a20e8 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2752,6 +2752,7 @@ PROP_R_PARSE_FAILED:108:parse failed PROP_R_STRING_TOO_LONG:109:string too long PROP_R_TRAILING_CHARACTERS:110:trailing characters PROV_R_AES_KEY_SETUP_FAILED:101:aes key setup failed +PROV_R_ALGORITHM_MISMATCH:173:algorithm mismatch PROV_R_BAD_DECRYPT:100:bad decrypt PROV_R_BAD_ENCODING:141:bad encoding PROV_R_BAD_LENGTH:142:bad length @@ -2759,17 +2760,21 @@ PROV_R_BAD_TLS_CLIENT_VERSION:161:bad tls client version PROV_R_BN_ERROR:160:bn error PROV_R_BOTH_MODE_AND_MODE_INT:127:both mode and mode int PROV_R_CIPHER_OPERATION_FAILED:102:cipher operation failed +PROV_R_DIGEST_NOT_ALLOWED:174:digest not allowed PROV_R_FAILED_DURING_DERIVATION:164:failed during derivation PROV_R_FAILED_TO_DECRYPT:162:failed to decrypt PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter +PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\ + illegal or unsupported padding mode PROV_R_INAVLID_UKM_LENGTH:146:inavlid ukm length PROV_R_INVALID_AAD:108:invalid aad PROV_R_INVALID_CONSTANT_LENGTH:157:invalid constant length PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length PROV_R_INVALID_DATA:115:invalid data PROV_R_INVALID_DIGEST:122:invalid digest +PROV_R_INVALID_DIGEST_LENGTH:166:invalid digest length PROV_R_INVALID_ITERATION_COUNT:123:invalid iteration count PROV_R_INVALID_IVLEN:116:invalid ivlen PROV_R_INVALID_IV_LENGTH:109:invalid iv length @@ -2778,12 +2783,17 @@ PROV_R_INVALID_KEYLEN:117:invalid keylen PROV_R_INVALID_KEY_LEN:124:invalid key len PROV_R_INVALID_KEY_LENGTH:105:invalid key length PROV_R_INVALID_MAC:151:invalid mac +PROV_R_INVALID_MGF1_MD:167:invalid mgf1 md PROV_R_INVALID_MODE:125:invalid mode PROV_R_INVALID_MODE_INT:126:invalid mode int +PROV_R_INVALID_PADDING_MODE:168:invalid padding mode +PROV_R_INVALID_PSS_SALTLEN:169:invalid pss saltlen PROV_R_INVALID_SALT_LENGTH:112:invalid salt length PROV_R_INVALID_SEED_LENGTH:154:invalid seed length PROV_R_INVALID_TAG:110:invalid tag PROV_R_INVALID_TAGLEN:118:invalid taglen +PROV_R_INVALID_X931_DIGEST:170:invalid x931 digest +PROV_R_KEY_SIZE_TOO_SMALL:171:key size too small PROV_R_MISSING_CEK_ALG:144:missing cek alg PROV_R_MISSING_CIPHER:155:missing cipher PROV_R_MISSING_CONSTANT:156:missing constant @@ -2801,6 +2811,7 @@ PROV_R_NOT_SUPPORTED:136:not supported PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length PROV_R_NO_KEY_SET:114:no key set PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small +PROV_R_PSS_SALTLEN_TOO_SMALL:172:pss saltlen too small PROV_R_READ_KEY:159:read key PROV_R_TAG_NOTSET:119:tag notset PROV_R_TAG_NOT_NEEDED:120:tag not needed diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index 6be796f..cb64b95 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -786,69 +786,73 @@ static int legacy_ctrl_to_param(EVP_PKEY_CTX *ctx, int keytype, int optype, # ifndef OPENSSL_NO_EC if (keytype == EVP_PKEY_EC) { switch (cmd) { - case EVP_PKEY_CTRL_EC_ECDH_COFACTOR: - if (p1 == -2) { - return EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx); - } else if (p1 < -1 || p1 > 1) { - /* Uses the same return values as EVP_PKEY_CTX_ctrl */ - return -2; - } else { - return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, p1); - } - case EVP_PKEY_CTRL_EC_KDF_TYPE: - if (p1 == -2) { - return EVP_PKEY_CTX_get_ecdh_kdf_type(ctx); - } else { - return EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, p1); - } - case EVP_PKEY_CTRL_GET_EC_KDF_MD: - return EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, p2); - case EVP_PKEY_CTRL_EC_KDF_MD: - return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, p2); - case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN: - return EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, p2); - case EVP_PKEY_CTRL_EC_KDF_OUTLEN: - return EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, p1); - case EVP_PKEY_CTRL_GET_EC_KDF_UKM: - return EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p2); - case EVP_PKEY_CTRL_EC_KDF_UKM: - return EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p2, p1); + case EVP_PKEY_CTRL_EC_ECDH_COFACTOR: + if (p1 == -2) { + return EVP_PKEY_CTX_get_ecdh_cofactor_mode(ctx); + } else if (p1 < -1 || p1 > 1) { + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } else { + return EVP_PKEY_CTX_set_ecdh_cofactor_mode(ctx, p1); + } + case EVP_PKEY_CTRL_EC_KDF_TYPE: + if (p1 == -2) { + return EVP_PKEY_CTX_get_ecdh_kdf_type(ctx); + } else { + return EVP_PKEY_CTX_set_ecdh_kdf_type(ctx, p1); + } + case EVP_PKEY_CTRL_GET_EC_KDF_MD: + return EVP_PKEY_CTX_get_ecdh_kdf_md(ctx, p2); + case EVP_PKEY_CTRL_EC_KDF_MD: + return EVP_PKEY_CTX_set_ecdh_kdf_md(ctx, p2); + case EVP_PKEY_CTRL_GET_EC_KDF_OUTLEN: + return EVP_PKEY_CTX_get_ecdh_kdf_outlen(ctx, p2); + case EVP_PKEY_CTRL_EC_KDF_OUTLEN: + return EVP_PKEY_CTX_set_ecdh_kdf_outlen(ctx, p1); + case EVP_PKEY_CTRL_GET_EC_KDF_UKM: + return EVP_PKEY_CTX_get0_ecdh_kdf_ukm(ctx, p2); + case EVP_PKEY_CTRL_EC_KDF_UKM: + return EVP_PKEY_CTX_set0_ecdh_kdf_ukm(ctx, p2, p1); } } # endif if (keytype == -1) { switch (cmd) { - case EVP_PKEY_CTRL_MD: - return EVP_PKEY_CTX_set_signature_md(ctx, p2); - case EVP_PKEY_CTRL_GET_MD: - return EVP_PKEY_CTX_get_signature_md(ctx, p2); - case EVP_PKEY_CTRL_RSA_PADDING: - return EVP_PKEY_CTX_set_rsa_padding(ctx, p1); - case EVP_PKEY_CTRL_GET_RSA_PADDING: - return EVP_PKEY_CTX_get_rsa_padding(ctx, p2); - case EVP_PKEY_CTRL_RSA_OAEP_MD: - return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2); - case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: - return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2); - case EVP_PKEY_CTRL_RSA_MGF1_MD: - return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2); - case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: - return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2); - case EVP_PKEY_CTRL_RSA_OAEP_LABEL: - return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1); - case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: - return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2); - case EVP_PKEY_CTRL_PKCS7_ENCRYPT: - case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_MD: + return EVP_PKEY_CTX_set_signature_md(ctx, p2); + case EVP_PKEY_CTRL_GET_MD: + return EVP_PKEY_CTX_get_signature_md(ctx, p2); + case EVP_PKEY_CTRL_RSA_PADDING: + return EVP_PKEY_CTX_set_rsa_padding(ctx, p1); + case EVP_PKEY_CTRL_GET_RSA_PADDING: + return EVP_PKEY_CTX_get_rsa_padding(ctx, p2); + case EVP_PKEY_CTRL_RSA_OAEP_MD: + return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_GET_RSA_OAEP_MD: + return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_RSA_MGF1_MD: + return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: + return EVP_PKEY_CTX_get_rsa_oaep_md(ctx, p2); + case EVP_PKEY_CTRL_RSA_OAEP_LABEL: + return EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, p2, p1); + case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: + return EVP_PKEY_CTX_get0_rsa_oaep_label(ctx, (unsigned char **)p2); + case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: + return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, p1); + case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: + return EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, p2); + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: # ifndef OPENSSL_NO_CMS - case EVP_PKEY_CTRL_CMS_DECRYPT: - case EVP_PKEY_CTRL_CMS_ENCRYPT: + case EVP_PKEY_CTRL_CMS_DECRYPT: + case EVP_PKEY_CTRL_CMS_ENCRYPT: # endif - if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) - return 1; - ERR_raise(ERR_LIB_EVP, - EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); - return -2; + if (ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return 1; + ERR_raise(ERR_LIB_EVP, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; } } return 0; @@ -918,6 +922,8 @@ static int legacy_ctrl_str_to_param(EVP_PKEY_CTX *ctx, const char *name, name = OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST; else if (strcmp(name, "rsa_oaep_label") == 0) name = OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL; + else if (strcmp(name, "rsa_pss_saltlen") == 0) + name = OSSL_SIGNATURE_PARAM_PSS_SALTLEN; # ifndef OPENSSL_NO_DH else if (strcmp(name, "dh_pad") == 0) name = OSSL_EXCHANGE_PARAM_PAD; diff --git a/crypto/rsa/build.info b/crypto/rsa/build.info index 274f376..ddb4e6f 100644 --- a/crypto/rsa/build.info +++ b/crypto/rsa/build.info @@ -1,6 +1,6 @@ LIBS=../../libcrypto -$COMMON=rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_pk1.c \ +$COMMON=rsa_ossl.c rsa_gen.c rsa_lib.c rsa_sign.c rsa_aid.c rsa_pk1.c \ rsa_none.c rsa_oaep.c rsa_chk.c rsa_pss.c rsa_x931.c rsa_crpt.c \ rsa_x931g.c rsa_sp800_56b_gen.c rsa_sp800_56b_check.c diff --git a/crypto/rsa/rsa_aid.c b/crypto/rsa/rsa_aid.c new file mode 100644 index 0000000..4b4d3a6 --- /dev/null +++ b/crypto/rsa/rsa_aid.c @@ -0,0 +1,98 @@ +/* + * Copyright 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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <stdlib.h> + +#include <openssl/objects.h> +#include "crypto/rsa.h" + +#define ASN1_SEQUENCE 0x30 +#define ASN1_OID 0x06 + +/* + * -- RFC 2313 + * pkcs-1 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) US(840) rsadsi(113549) pkcs(1) 1 + * } + */ + +/* + * -- RFC 3279 + * md2WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 2 } + * md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 } + * sha1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } + */ +#define ENCODE_ALGORITHMIDENTIFIER_PKCS1(name, n) \ + static const unsigned char algorithmidentifier_##name##_der[] = { \ + ASN1_SEQUENCE, 0x0b, \ + ASN1_OID, 0x09, 1 * 40 + 2, 134, 72, 134, 247, 13, 1, 1, n \ +} +#ifndef FIPS_MODE +ENCODE_ALGORITHMIDENTIFIER_PKCS1(md2, 2); +ENCODE_ALGORITHMIDENTIFIER_PKCS1(md5, 4); +#endif +ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha1, 5); + +/* + * -- RFC 4055 + * sha224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 14 } + * sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 } + * sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 } + * sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } + */ +ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha224, 14); +ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha256, 11); +ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha384, 12); +ENCODE_ALGORITHMIDENTIFIER_PKCS1(sha512, 13); + +/* + * -- https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration + * + * sigAlgs OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 4 3 } + * + * id-rsassa-pkcs1-v1_5-with-sha3-224 ::= { sigAlgs 13 } + * id-rsassa-pkcs1-v1_5-with-sha3-256 ::= { sigAlgs 14 } + * id-rsassa-pkcs1-v1_5-with-sha3-384 ::= { sigAlgs 15 } + * id-rsassa-pkcs1-v1_5-with-sha3-512 ::= { sigAlgs 16 } + */ +#define ENCODE_ALGORITHMIDENTIFIER_SIGALGS(name, n) \ + static const unsigned char algorithmidentifier_##name##_der[] = { \ + ASN1_SEQUENCE, 0x0c, \ + ASN1_OID, 0x0a, 1 * 40 + 2, 16, 134, 72, 1, 101, 3, 4, 3, n \ +} +ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_224, 13); +ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_256, 14); +ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_384, 15); +ENCODE_ALGORITHMIDENTIFIER_SIGALGS(sha3_512, 16); + +#define MD_CASE(name) \ + case NID_##name: \ + *len = sizeof(algorithmidentifier_##name##_der); \ + return algorithmidentifier_##name##_der + +const unsigned char *rsa_algorithmidentifier_encoding(int md_nid, size_t *len) +{ + switch (md_nid) { +#ifndef FIPS_MODE + MD_CASE(md2); + MD_CASE(md5); +#endif + MD_CASE(sha1); + MD_CASE(sha224); + MD_CASE(sha256); + MD_CASE(sha384); + MD_CASE(sha512); + MD_CASE(sha3_224); + MD_CASE(sha3_256); + MD_CASE(sha3_384); + MD_CASE(sha3_512); + default: + return NULL; + } +} diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index c43c9fd..39d7f5f 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -817,12 +817,14 @@ int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode) return -1; /* TODO(3.0): Remove this eventually when no more legacy */ - if (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) - || ctx->op.ciph.ciphprovctx == NULL) + if ((!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + || ctx->op.ciph.ciphprovctx == NULL) + && (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + || ctx->op.sig.sigprovctx == NULL)) return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_RSA_PADDING, pad_mode, NULL); - *p++ = OSSL_PARAM_construct_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, &pad_mode); + *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_PAD_MODE, &pad_mode); *p++ = OSSL_PARAM_construct_end(); return EVP_PKEY_CTX_set_params(ctx, pad_params); @@ -845,12 +847,14 @@ int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode) return -1; /* TODO(3.0): Remove this eventually when no more legacy */ - if (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) - || ctx->op.ciph.ciphprovctx == NULL) + if ((!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx) + || ctx->op.ciph.ciphprovctx == NULL) + && (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + || ctx->op.sig.sigprovctx == NULL)) return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, pad_mode); - *p++ = OSSL_PARAM_construct_int(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, pad_mode); + *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_PAD_MODE, pad_mode); *p++ = OSSL_PARAM_construct_end(); if (!EVP_PKEY_CTX_get_params(ctx, pad_params)) @@ -1026,20 +1030,20 @@ int EVP_PKEY_CTX_set_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, const char *mdname, && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) return -1; - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MGF1_DIGEST, /* - * Cast away the const. This is read - * only so should be safe + * Cast away the const. This is + * read only so should be safe */ (char *)mdname, 0); if (mdprops != NULL) { - *p++ = OSSL_PARAM_construct_utf8_string( - OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS, - /* - * Cast away the const. This is read - * only so should be safe - */ - (char *)mdprops, 0); + *p++ = + OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MGF1_PROPERTIES, + /* + * Cast away the const. This is + * read only so should be safe + */ + (char *)mdprops, 0); } *p++ = OSSL_PARAM_construct_end(); @@ -1065,7 +1069,7 @@ int EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name, && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) return -1; - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST, + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MGF1_DIGEST, name, namelen); *p++ = OSSL_PARAM_construct_end(); @@ -1133,12 +1137,12 @@ int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen) (void *)label); *p++ = OSSL_PARAM_construct_octet_string(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL, - /* - * Cast away the const. This is read - * only so should be safe - */ - (void *)label, - (size_t)llen); + /* + * Cast away the const. This is + * read only so should be safe + */ + (void *)label, + (size_t)llen); *p++ = OSSL_PARAM_construct_end(); if (!EVP_PKEY_CTX_set_params(ctx, rsa_params)) @@ -1183,4 +1187,67 @@ int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label) return (int)labellen; } + +int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen) +{ + OSSL_PARAM pad_params[2], *p = pad_params; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA or RSA-PSS return error */ + if (ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_RSA + && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return -1; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + || ctx->op.sig.sigprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, -1, -1, EVP_PKEY_CTRL_RSA_PSS_SALTLEN, + saltlen, NULL); + + *p++ = + OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, &saltlen); + *p++ = OSSL_PARAM_construct_end(); + + return EVP_PKEY_CTX_set_params(ctx, pad_params); +} + +int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen) +{ + OSSL_PARAM pad_params[2], *p = pad_params; + + if (ctx == NULL || saltlen == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + /* Uses the same return values as EVP_PKEY_CTX_ctrl */ + return -2; + } + + /* If key type not RSA or RSA-PSS return error */ + if (ctx->pmeth != NULL + && ctx->pmeth->pkey_id != EVP_PKEY_RSA + && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) + return -1; + + /* TODO(3.0): Remove this eventually when no more legacy */ + if (!EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx) + || ctx->op.sig.sigprovctx == NULL) + return EVP_PKEY_CTX_ctrl(ctx, -1, -1, + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, + 0, saltlen); + + *p++ = + OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, saltlen); + *p++ = OSSL_PARAM_construct_end(); + + if (!EVP_PKEY_CTX_get_params(ctx, pad_params)) + return 0; + + return 1; + +} #endif diff --git a/crypto/rsa/rsa_local.h b/crypto/rsa/rsa_local.h index e15c1ae..11d7635 100644 --- a/crypto/rsa/rsa_local.h +++ b/crypto/rsa/rsa_local.h @@ -122,10 +122,6 @@ struct rsa_meth_st { BIGNUM *e, BN_GENCB *cb); }; -extern int int_rsa_verify(int dtype, const unsigned char *m, - unsigned int m_len, unsigned char *rm, - size_t *prm_len, const unsigned char *sigbuf, - size_t siglen, RSA *rsa); /* Macros to test if a pkey or ctx is for a PSS key */ #define pkey_is_pss(pkey) (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS) #define pkey_ctx_is_pss(ctx) (ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS) diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c index 1742718..7a298d5 100644 --- a/crypto/rsa/rsa_pmeth.c +++ b/crypto/rsa/rsa_pmeth.c @@ -25,6 +25,7 @@ #include <openssl/x509v3.h> #include <openssl/cms.h> #include "crypto/evp.h" +#include "crypto/rsa.h" #include "rsa_local.h" /* RSA pkey context structure */ diff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c index 31b8ed1..e9c4c55 100644 --- a/crypto/rsa/rsa_sign.c +++ b/crypto/rsa/rsa_sign.c @@ -23,13 +23,20 @@ #ifndef OPENSSL_NO_MD2 # include <openssl/md2.h> /* uses MD2_DIGEST_LENGTH */ #endif +#ifndef OPENSSL_NO_MD4 +# include <openssl/md4.h> /* uses MD4_DIGEST_LENGTH */ +#endif #ifndef OPENSSL_NO_MD5 # include <openssl/md5.h> /* uses MD5_DIGEST_LENGTH */ #endif #ifndef OPENSSL_NO_MDC2 # include <openssl/mdc2.h> /* uses MDC2_DIGEST_LENGTH */ #endif +#ifndef OPENSSL_NO_RMD160 +# include <openssl/ripemd.h> /* uses RIPEMD160_DIGEST_LENGTH */ +#endif #include <openssl/sha.h> /* uses SHA???_DIGEST_LENGTH */ +#include "crypto/rsa.h" #include "rsa_local.h" /* @@ -76,7 +83,7 @@ static const unsigned char digestinfo_##name##_der[] = { \ ASN1_OCTET_STRING, sz \ }; -/* MD2 and MD5 OIDs are of the form: (1 2 840 113549 2 |n|) */ +/* MD2, MD4 and MD5 OIDs are of the form: (1 2 840 113549 2 |n|) */ #define ENCODE_DIGESTINFO_MD(name, n, sz) \ static const unsigned char digestinfo_##name##_der[] = { \ ASN1_SEQUENCE, 0x10 + sz, \ @@ -90,6 +97,9 @@ static const unsigned char digestinfo_##name##_der[] = { \ # ifndef OPENSSL_NO_MD2 ENCODE_DIGESTINFO_MD(md2, 0x02, MD2_DIGEST_LENGTH) # endif +# ifndef OPENSSL_NO_MD4 +ENCODE_DIGESTINFO_MD(md4, 0x03, MD4_DIGEST_LENGTH) +# endif # ifndef OPENSSL_NO_MD5 ENCODE_DIGESTINFO_MD(md5, 0x05, MD5_DIGEST_LENGTH) # endif @@ -103,6 +113,18 @@ static const unsigned char digestinfo_mdc2_der[] = { ASN1_OCTET_STRING, MDC2_DIGEST_LENGTH }; # endif +# ifndef OPENSSL_NO_RMD160 +/* RIPEMD160 (1 3 36 3 3 1 2) */ +static const unsigned char digestinfo_ripemd160_der[] = { + ASN1_SEQUENCE, 0x0c + RIPEMD160_DIGEST_LENGTH, + ASN1_SEQUENCE, 0x08, + ASN1_OID, 0x04, 1 * 40 + 3, 36, 3, 3, 1, 2, + ASN1_NULL, 0x00, + ASN1_OCTET_STRING, RIPEMD160_DIGEST_LENGTH +}; +# endif +#endif /* FIPS_MODE */ + /* SHA-1 (1 3 14 3 2 26) */ static const unsigned char digestinfo_sha1_der[] = { ASN1_SEQUENCE, 0x0d + SHA_DIGEST_LENGTH, @@ -112,8 +134,6 @@ static const unsigned char digestinfo_sha1_der[] = { ASN1_OCTET_STRING, SHA_DIGEST_LENGTH }; -#endif /* FIPS_MODE */ - ENCODE_DIGESTINFO_SHA(sha256, 0x01, SHA256_DIGEST_LENGTH) ENCODE_DIGESTINFO_SHA(sha384, 0x02, SHA384_DIGEST_LENGTH) ENCODE_DIGESTINFO_SHA(sha512, 0x03, SHA512_DIGEST_LENGTH) @@ -130,9 +150,9 @@ ENCODE_DIGESTINFO_SHA(sha3_512, 0x0a, SHA512_DIGEST_LENGTH) *len = sizeof(digestinfo_##name##_der); \ return digestinfo_##name##_der; -static const unsigned char *digestinfo_encoding(int nid, size_t *len) +const unsigned char *rsa_digestinfo_encoding(int md_nid, size_t *len) { - switch (nid) { + switch (md_nid) { #ifndef FIPS_MODE # ifndef OPENSSL_NO_MDC2 MD_CASE(mdc2) @@ -140,11 +160,17 @@ static const unsigned char *digestinfo_encoding(int nid, size_t *len) # ifndef OPENSSL_NO_MD2 MD_CASE(md2) # endif +# ifndef OPENSSL_NO_MD4 + MD_CASE(md4) +# endif # ifndef OPENSSL_NO_MD5 MD_CASE(md5) # endif - MD_CASE(sha1) +# ifndef OPENSSL_NO_RMD160 + MD_CASE(ripemd160) +# endif #endif /* FIPS_MODE */ + MD_CASE(sha1) MD_CASE(sha224) MD_CASE(sha256) MD_CASE(sha384) @@ -183,7 +209,7 @@ static int encode_pkcs1(unsigned char **out, size_t *out_len, int type, RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_UNKNOWN_ALGORITHM_TYPE); return 0; } - di_prefix = digestinfo_encoding(type, &di_prefix_len); + di_prefix = rsa_digestinfo_encoding(type, &di_prefix_len); if (di_prefix == NULL) { RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod index 8334cfc..08b6f69 100644 --- a/doc/man3/EVP_PKEY_CTX_ctrl.pod +++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod @@ -94,8 +94,8 @@ EVP_PKEY_CTX_set1_id, EVP_PKEY_CTX_get1_id, EVP_PKEY_CTX_get1_id_len int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad); int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad); - int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int len); - int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *len); + int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen); + int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen); int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int mbits); int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp); int EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes); @@ -211,8 +211,8 @@ B<optype> is a mask indicating which operations the control can be applied to. The control command is indicated in B<cmd> and any additional arguments in B<p1> and B<p2>. -For B<cmd> = B<EVP_PKEY_CTRL_SET_MAC_KEY>, B<p1> is the length of the MAC key, -and B<p2> is MAC key. This is used by Poly1305, SipHash, HMAC and CMAC. +For I<cmd> = B<EVP_PKEY_CTRL_SET_MAC_KEY>, I<p1> is the length of the MAC key, +and I<p2> is the MAC key. This is used by Poly1305, SipHash, HMAC and CMAC. Applications will not normally call EVP_PKEY_CTX_ctrl() directly but will instead call one of the algorithm specific macros below. @@ -272,20 +272,36 @@ buffer is expected to be the algorithm identifier byte. The EVP_PKEY_CTX_get_rsa_padding() function gets the RSA padding mode for B<ctx>. -The EVP_PKEY_CTX_set_rsa_pss_saltlen() macro sets the RSA PSS salt length to -B<len>. As its name implies it is only supported for PSS padding. Three special -values are supported: B<RSA_PSS_SALTLEN_DIGEST> sets the salt length to the -digest length, B<RSA_PSS_SALTLEN_MAX> sets the salt length to the maximum -permissible value. When verifying B<RSA_PSS_SALTLEN_AUTO> causes the salt length -to be automatically determined based on the B<PSS> block structure. If this -macro is not called maximum salt length is used when signing and auto detection -when verifying is used by default. +The EVP_PKEY_CTX_set_rsa_pss_saltlen() function sets the RSA PSS salt +length to I<saltlen>. As its name implies it is only supported for PSS +padding. If this function is not called then the maximum salt length +is used when signing and auto detection when verifying. Three special +values are supported: -The EVP_PKEY_CTX_get_rsa_pss_saltlen() macro gets the RSA PSS salt length -for B<ctx>. The padding mode must have been set to B<RSA_PKCS1_PSS_PADDING>. +=over 4 + +=item B<RSA_PSS_SALTLEN_DIGEST> + +sets the salt length to the digest length. + +=item B<RSA_PSS_SALTLEN_MAX> + +sets the salt length to the maximum permissible value. + +=item B<RSA_PSS_SALTLEN_AUTO> + +causes the salt length to be automatically determined based on the +B<PSS> block structure when verifying. When signing, it has the same +meaning as B<RSA_PSS_SALTLEN_MAX>. + +=back + +The EVP_PKEY_CTX_get_rsa_pss_saltlen() function gets the RSA PSS salt length +for B<ctx>. The padding mode must already have been set to +B<RSA_PKCS1_PSS_PADDING>. The EVP_PKEY_CTX_set_rsa_keygen_bits() macro sets the RSA key length for -RSA key generation to B<bits>. If not specified 1024 bits is used. +RSA key generation to I<bits>. If not specified 2048 bits is used. The EVP_PKEY_CTX_set_rsa_keygen_pubexp() macro sets the public exponent value for RSA key generation to B<pubexp>. Currently it should be an odd integer. The @@ -374,12 +390,12 @@ negotiated protocol version. Otherwise it should be left unset. =head2 DSA parameters The EVP_PKEY_CTX_set_dsa_paramgen_bits() macro sets the number of bits used -for DSA parameter generation to B<nbits>. If not specified, 1024 is used. +for DSA parameter generation to I<nbits>. If not specified, 2048 is used. The EVP_PKEY_CTX_set_dsa_paramgen_q_bits() macro sets the number of bits in the -subprime parameter B<q> for DSA parameter generation to B<qbits>. If not -specified, 160 is used. If a digest function is specified below, this parameter -is ignored and instead, the number of bits in B<q> matches the size of the +subprime parameter I<q> for DSA parameter generation to I<qbits>. If not +specified, 224 is used. If a digest function is specified below, this parameter +is ignored and instead, the number of bits in I<q> matches the size of the digest. The EVP_PKEY_CTX_set_dsa_paramgen_md() macro sets the digest function used for @@ -598,8 +614,9 @@ EVP_PKEY_CTX_set_dh_pad(), EVP_PKEY_CTX_set_rsa_padding(), EVP_PKEY_CTX_get_rsa_padding(), EVP_PKEY_CTX_get_rsa_mgf1_md(), EVP_PKEY_CTX_set_rsa_mgf1_md(), EVP_PKEY_CTX_set_rsa_oaep_md(), EVP_PKEY_CTX_get_rsa_oaep_md(), EVP_PKEY_CTX_set0_rsa_oaep_label(), -EVP_PKEY_CTX_get0_rsa_oaep_label() were macros in OpenSSL 1.1.1 and below. From -OpenSSL 3.0 they are functions. +EVP_PKEY_CTX_get0_rsa_oaep_label(), EVP_PKEY_CTX_set_rsa_pss_saltlen(), +EVP_PKEY_CTX_get_rsa_pss_saltlen(), were macros in OpenSSL 1.1.1 and below. +From OpenSSL 3.0 they are functions. EVP_PKEY_CTX_get_rsa_oaep_md_name(), EVP_PKEY_CTX_get_rsa_mgf1_md_name(), EVP_PKEY_CTX_set_rsa_mgf1_md_name() and EVP_PKEY_CTX_set_rsa_oaep_md_name() were diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h index 97fd0f7..51ac014 100644 --- a/include/crypto/rsa.h +++ b/include/crypto/rsa.h @@ -29,4 +29,12 @@ int rsa_validate_public(const RSA *key); int rsa_validate_private(const RSA *key); int rsa_validate_pairwise(const RSA *key); +int int_rsa_verify(int dtype, const unsigned char *m, + unsigned int m_len, unsigned char *rm, + size_t *prm_len, const unsigned char *sigbuf, + size_t siglen, RSA *rsa); + +const unsigned char *rsa_digestinfo_encoding(int md_nid, size_t *len); +const unsigned char *rsa_algorithmidentifier_encoding(int md_nid, size_t *len); + #endif diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index b2befd8..5e3a13a 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -88,11 +88,16 @@ extern "C" { /* Known DIGEST names (not a complete list) */ #define OSSL_DIGEST_NAME_MD5 "MD5" +#define OSSL_DIGEST_NAME_MD5_SHA1 "MD5-SHA1" #define OSSL_DIGEST_NAME_SHA1 "SHA1" #define OSSL_DIGEST_NAME_SHA2_224 "SHA2-224" #define OSSL_DIGEST_NAME_SHA2_256 "SHA2-256" #define OSSL_DIGEST_NAME_SHA2_384 "SHA2-384" #define OSSL_DIGEST_NAME_SHA2_512 "SHA2-512" +#define OSSL_DIGEST_NAME_MD2 "MD2" +#define OSSL_DIGEST_NAME_MD4 "MD4" +#define OSSL_DIGEST_NAME_MDC2 "MDC2" +#define OSSL_DIGEST_NAME_RIPEMD160 "RIPEMD160" #define OSSL_DIGEST_NAME_SHA3_224 "SHA3-224" #define OSSL_DIGEST_NAME_SHA3_256 "SHA3-256" #define OSSL_DIGEST_NAME_SHA3_384 "SHA3-384" @@ -171,6 +176,14 @@ extern "C" { #define OSSL_PKEY_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES #define OSSL_PKEY_PARAM_DEFAULT_DIGEST "default-digest" /* utf8 string */ #define OSSL_PKEY_PARAM_MANDATORY_DIGEST "mandatory-digest" /* utf8 string */ +#define OSSL_PKEY_PARAM_PAD_MODE "pad-mode" +#define OSSL_PKEY_PARAM_DIGEST OSSL_ALG_PARAM_DIGEST +#define OSSL_PKEY_PARAM_PROPERTIES OSSL_ALG_PARAM_PROPERTIES +#define OSSL_PKEY_PARAM_DIGEST_SIZE "digest-size" +#define OSSL_PKEY_PARAM_MGF1_DIGEST "mgf1-digest" +#define OSSL_PKEY_PARAM_MGF1_PROPERTIES "mgf1-properties" + +/* Diffie-Hellman/DSA public/private key */ #define OSSL_PKEY_PARAM_PUB_KEY "pub" #define OSSL_PKEY_PARAM_PRIV_KEY "priv" @@ -234,15 +247,22 @@ extern "C" { /* Signature parameters */ #define OSSL_SIGNATURE_PARAM_ALGORITHM_ID "algorithm-id" +#define OSSL_SIGNATURE_PARAM_PAD_MODE OSSL_PKEY_PARAM_PAD_MODE #define OSSL_SIGNATURE_PARAM_DIGEST OSSL_PKEY_PARAM_DIGEST #define OSSL_SIGNATURE_PARAM_PROPERTIES OSSL_PKEY_PARAM_PROPERTIES +#define OSSL_SIGNATURE_PARAM_PSS_SALTLEN "pss-saltlen" +#define OSSL_SIGNATURE_PARAM_MGF1_DIGEST OSSL_PKEY_PARAM_MGF1_DIGEST +#define OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES \ + OSSL_PKEY_PARAM_MGF1_PROPERTIES /* Asym cipher parameters */ -#define OSSL_ASYM_CIPHER_PARAM_PAD_MODE "pad-mode" +#define OSSL_ASYM_CIPHER_PARAM_PAD_MODE OSSL_PKEY_PARAM_PAD_MODE +#define OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST \ + OSSL_PKEY_PARAM_MGF1_DIGEST +#define OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS \ + OSSL_PKEY_PARAM_MGF1_PROPERTIES #define OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST OSSL_ALG_PARAM_DIGEST #define OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS "digest-props" -#define OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST "mgf1-digest" -#define OSSL_ASYM_CIPHER_PARAM_MGF1_DIGEST_PROPS "mgf1-digest-props" #define OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL "oaep-label" #define OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL_LEN "oaep-label-len" #define OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION "tls-client-version" diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h index 12ee011..1f0687d 100644 --- a/include/openssl/rsa.h +++ b/include/openssl/rsa.h @@ -108,9 +108,9 @@ extern "C" { int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode); int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode); -# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ - RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ - EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL) +int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen); +int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen); + /* Salt length matches digest */ # define RSA_PSS_SALTLEN_DIGEST -1 /* Verify only: auto detect salt length */ @@ -124,10 +124,6 @@ int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode); EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN, \ EVP_PKEY_CTRL_RSA_PSS_SALTLEN, len, NULL) -# define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \ - RSA_pkey_ctx_ctrl(ctx, (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ - EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, plen) - # define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN, \ EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h index 6586d65..19ecab1 100644 --- a/providers/common/include/prov/providercommonerr.h +++ b/providers/common/include/prov/providercommonerr.h @@ -50,6 +50,7 @@ int ERR_load_PROV_strings(void); * PROV reason codes. */ # define PROV_R_AES_KEY_SETUP_FAILED 101 +# define PROV_R_ALGORITHM_MISMATCH 173 # define PROV_R_BAD_DECRYPT 100 # define PROV_R_BAD_ENCODING 141 # define PROV_R_BAD_LENGTH 142 @@ -57,17 +58,20 @@ int ERR_load_PROV_strings(void); # define PROV_R_BN_ERROR 160 # define PROV_R_BOTH_MODE_AND_MODE_INT 127 # define PROV_R_CIPHER_OPERATION_FAILED 102 +# define PROV_R_DIGEST_NOT_ALLOWED 174 # define PROV_R_FAILED_DURING_DERIVATION 164 # define PROV_R_FAILED_TO_DECRYPT 162 # define PROV_R_FAILED_TO_GENERATE_KEY 121 # define PROV_R_FAILED_TO_GET_PARAMETER 103 # define PROV_R_FAILED_TO_SET_PARAMETER 104 +# define PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 165 # define PROV_R_INAVLID_UKM_LENGTH 146 # define PROV_R_INVALID_AAD 108 # define PROV_R_INVALID_CONSTANT_LENGTH 157 # define PROV_R_INVALID_CUSTOM_LENGTH 111 # define PROV_R_INVALID_DATA 115 # define PROV_R_INVALID_DIGEST 122 +# define PROV_R_INVALID_DIGEST_LENGTH 166 # define PROV_R_INVALID_ITERATION_COUNT 123 # define PROV_R_INVALID_IVLEN 116 # define PROV_R_INVALID_IV_LENGTH 109 @@ -76,12 +80,17 @@ int ERR_load_PROV_strings(void); # define PROV_R_INVALID_KEY_LEN 124 # define PROV_R_INVALID_KEY_LENGTH 105 # define PROV_R_INVALID_MAC 151 +# define PROV_R_INVALID_MGF1_MD 167 # define PROV_R_INVALID_MODE 125 # define PROV_R_INVALID_MODE_INT 126 +# define PROV_R_INVALID_PADDING_MODE 168 +# define PROV_R_INVALID_PSS_SALTLEN 169 # define PROV_R_INVALID_SALT_LENGTH 112 # define PROV_R_INVALID_SEED_LENGTH 154 # define PROV_R_INVALID_TAG 110 # define PROV_R_INVALID_TAGLEN 118 +# define PROV_R_INVALID_X931_DIGEST 170 +# define PROV_R_KEY_SIZE_TOO_SMALL 171 # define PROV_R_MISSING_CEK_ALG 144 # define PROV_R_MISSING_CIPHER 155 # define PROV_R_MISSING_CONSTANT 156 @@ -99,6 +108,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_NOT_XOF_OR_INVALID_LENGTH 113 # define PROV_R_NO_KEY_SET 114 # define PROV_R_OUTPUT_BUFFER_TOO_SMALL 106 +# define PROV_R_PSS_SALTLEN_TOO_SMALL 172 # define PROV_R_READ_KEY 159 # define PROV_R_TAG_NOTSET 119 # define PROV_R_TAG_NOT_NEEDED 120 diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index 792697c..f73f823 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -16,6 +16,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_AES_KEY_SETUP_FAILED), "aes key setup failed"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ALGORITHM_MISMATCH), + "algorithm mismatch"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_DECRYPT), "bad decrypt"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_ENCODING), "bad encoding"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_LENGTH), "bad length"}, @@ -26,6 +28,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "both mode and mode int"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_CIPHER_OPERATION_FAILED), "cipher operation failed"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_DIGEST_NOT_ALLOWED), + "digest not allowed"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_DURING_DERIVATION), "failed during derivation"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_DECRYPT), "failed to decrypt"}, @@ -35,6 +39,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "failed to get parameter"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SET_PARAMETER), "failed to set parameter"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), + "illegal or unsupported padding mode"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INAVLID_UKM_LENGTH), "inavlid ukm length"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_AAD), "invalid aad"}, @@ -44,6 +50,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "invalid custom length"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DATA), "invalid data"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST), "invalid digest"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST_LENGTH), + "invalid digest length"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_ITERATION_COUNT), "invalid iteration count"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_IVLEN), "invalid ivlen"}, @@ -54,14 +62,23 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY_LENGTH), "invalid key length"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MAC), "invalid mac"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MGF1_MD), "invalid mgf1 md"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MODE), "invalid mode"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MODE_INT), "invalid mode int"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PADDING_MODE), + "invalid padding mode"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PSS_SALTLEN), + "invalid pss saltlen"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SALT_LENGTH), "invalid salt length"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SEED_LENGTH), "invalid seed length"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAG), "invalid tag"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAGLEN), "invalid taglen"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_X931_DIGEST), + "invalid x931 digest"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_KEY_SIZE_TOO_SMALL), + "key size too small"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CEK_ALG), "missing cek alg"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CIPHER), "missing cipher"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CONSTANT), "missing constant"}, @@ -83,6 +100,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NO_KEY_SET), "no key set"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_OUTPUT_BUFFER_TOO_SMALL), "output buffer too small"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PSS_SALTLEN_TOO_SMALL), + "pss saltlen too small"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_READ_KEY), "read key"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOTSET), "tag notset"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOT_NEEDED), "tag not needed"}, diff --git a/providers/defltprov.c b/providers/defltprov.c index 0b2390a..5bebf66 100644 --- a/providers/defltprov.c +++ b/providers/defltprov.c @@ -384,6 +384,7 @@ static const OSSL_ALGORITHM deflt_signature[] = { #ifndef OPENSSL_NO_DSA { "DSA:dsaEncryption", "provider=default", dsa_signature_functions }, #endif + { "RSA:rsaEncryption", "default=yes", rsa_signature_functions }, { NULL, NULL, NULL } }; diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h index ec0507d..6d6a26d 100644 --- a/providers/implementations/include/prov/implementations.h +++ b/providers/implementations/include/prov/implementations.h @@ -269,6 +269,7 @@ extern const OSSL_DISPATCH ecdh_keyexch_functions[]; /* Signature */ extern const OSSL_DISPATCH dsa_signature_functions[]; +extern const OSSL_DISPATCH rsa_signature_functions[]; /* Asym Cipher */ extern const OSSL_DISPATCH rsa_asym_cipher_functions[]; diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info index a9687fc..22b55dc 100644 --- a/providers/implementations/signature/build.info +++ b/providers/implementations/signature/build.info @@ -2,9 +2,12 @@ # switch each to the Legacy provider when needed. $DSA_GOAL=../../libimplementations.a +$RSA_GOAL=../../libimplementations.a IF[{- !$disabled{dsa} -}] SOURCE[$DSA_GOAL]=dsa.c ENDIF +SOURCE[$RSA_GOAL]=rsa.c + diff --git a/providers/implementations/signature/rsa.c b/providers/implementations/signature/rsa.c new file mode 100644 index 0000000..3f941b1 --- /dev/null +++ b/providers/implementations/signature/rsa.c @@ -0,0 +1,1113 @@ +/* + * Copyright 2019 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 + * in the file LICENSE in the source distribution or at + * 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 <string.h> +#include <openssl/crypto.h> +#include <openssl/core_numbers.h> +#include <openssl/core_names.h> +#include <openssl/err.h> +#include <openssl/rsa.h> +#include <openssl/params.h> +#include <openssl/evp.h> +#include "internal/cryptlib.h" +#include "internal/nelem.h" +#include "internal/sizes.h" +#include "crypto/rsa.h" +#include "prov/providercommonerr.h" +#include "prov/implementations.h" +#include "prov/provider_ctx.h" + +static OSSL_OP_signature_newctx_fn rsa_newctx; +static OSSL_OP_signature_sign_init_fn rsa_signature_init; +static OSSL_OP_signature_verify_init_fn rsa_signature_init; +static OSSL_OP_signature_verify_recover_init_fn rsa_signature_init; +static OSSL_OP_signature_sign_fn rsa_sign; +static OSSL_OP_signature_verify_fn rsa_verify; +static OSSL_OP_signature_verify_recover_fn rsa_verify_recover; +static OSSL_OP_signature_digest_sign_init_fn rsa_digest_signverify_init; +static OSSL_OP_signature_digest_sign_update_fn rsa_digest_signverify_update; +static OSSL_OP_signature_digest_sign_final_fn rsa_digest_sign_final; +static OSSL_OP_signature_digest_verify_init_fn rsa_digest_signverify_init; +static OSSL_OP_signature_digest_verify_update_fn rsa_digest_signverify_update; +static OSSL_OP_signature_digest_verify_final_fn rsa_digest_verify_final; +static OSSL_OP_signature_freectx_fn rsa_freectx; +static OSSL_OP_signature_dupctx_fn rsa_dupctx; +static OSSL_OP_signature_get_ctx_params_fn rsa_get_ctx_params; +static OSSL_OP_signature_gettable_ctx_params_fn rsa_gettable_ctx_params; +static OSSL_OP_signature_set_ctx_params_fn rsa_set_ctx_params; +static OSSL_OP_signature_settable_ctx_params_fn rsa_settable_ctx_params; +static OSSL_OP_signature_get_ctx_md_params_fn rsa_get_ctx_md_params; +static OSSL_OP_signature_gettable_ctx_md_params_fn rsa_gettable_ctx_md_params; +static OSSL_OP_signature_set_ctx_md_params_fn rsa_set_ctx_md_params; +static OSSL_OP_signature_settable_ctx_md_params_fn rsa_settable_ctx_md_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. + * We happen to know that our KEYMGMT simply passes RSA structures, so + * we use that here too. + */ + +typedef struct { + OPENSSL_CTX *libctx; + RSA *rsa; + + /* + * Flag to determine if the hash function can be changed (1) or not (0) + * Because it's dangerous to change during a DigestSign or DigestVerify + * operation, this flag is cleared by their Init function, and set again + * by their Final function. + */ + unsigned int flag_allow_md : 1; + + /* The Algorithm Identifier of the combined signature agorithm */ + unsigned char aid[128]; + size_t aid_len; + + /* main digest */ + EVP_MD *md; + EVP_MD_CTX *mdctx; + int mdnid; + char mdname[OSSL_MAX_NAME_SIZE]; /* Purely informational */ + + /* RSA padding mode */ + int pad_mode; + /* message digest for MGF1 */ + EVP_MD *mgf1_md; + char mgf1_mdname[OSSL_MAX_NAME_SIZE]; /* Purely informational */ + /* PSS salt length */ + int saltlen; + /* Minimum salt length or -1 if no PSS parameter restriction */ + int min_saltlen; + + /* Temp buffer */ + unsigned char *tbuf; + +} PROV_RSA_CTX; + +static size_t rsa_get_md_size(const PROV_RSA_CTX *prsactx) +{ + if (prsactx->md != NULL) + return EVP_MD_size(prsactx->md); + return 0; +} + +static int rsa_get_md_nid(const EVP_MD *md) +{ + /* + * Because the RSA library deals with NIDs, we need to translate. + * We do so using EVP_MD_is_a(), and therefore need a name to NID + * map. + */ + static const OSSL_ITEM name_to_nid[] = { + { NID_sha1, OSSL_DIGEST_NAME_SHA1 }, + { NID_sha224, OSSL_DIGEST_NAME_SHA2_224 }, + { NID_sha256, OSSL_DIGEST_NAME_SHA2_256 }, + { NID_sha384, OSSL_DIGEST_NAME_SHA2_384 }, + { NID_sha512, OSSL_DIGEST_NAME_SHA2_512 }, + { NID_md5, OSSL_DIGEST_NAME_MD5 }, + { NID_md5_sha1, OSSL_DIGEST_NAME_MD5_SHA1 }, + { NID_md2, OSSL_DIGEST_NAME_MD2 }, + { NID_md4, OSSL_DIGEST_NAME_MD4 }, + { NID_mdc2, OSSL_DIGEST_NAME_MDC2 }, + { NID_ripemd160, OSSL_DIGEST_NAME_RIPEMD160 }, + { NID_sha3_224, OSSL_DIGEST_NAME_SHA3_224 }, + { NID_sha3_256, OSSL_DIGEST_NAME_SHA3_256 }, + { NID_sha3_384, OSSL_DIGEST_NAME_SHA3_384 }, + { NID_sha3_512, OSSL_DIGEST_NAME_SHA3_512 }, + }; + size_t i; + int mdnid = NID_undef; + + if (md == NULL) + goto end; + + for (i = 0; i < OSSL_NELEM(name_to_nid); i++) { + if (EVP_MD_is_a(md, name_to_nid[i].ptr)) { + mdnid = (int)name_to_nid[i].id; + break; + } + } + + if (mdnid == NID_undef) + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); + + end: + return mdnid; +} + +static int rsa_check_padding(int mdnid, int padding) +{ + if (padding == RSA_NO_PADDING) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE); + return 0; + } + + if (padding == RSA_X931_PADDING) { + if (RSA_X931_hash_id(mdnid) == -1) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_X931_DIGEST); + return 0; + } + } + + return 1; +} + +static void *rsa_newctx(void *provctx) +{ + PROV_RSA_CTX *prsactx = OPENSSL_zalloc(sizeof(PROV_RSA_CTX)); + + if (prsactx == NULL) + return NULL; + + prsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + prsactx->flag_allow_md = 1; + return prsactx; +} + +/* True if PSS parameters are restricted */ +#define rsa_pss_restricted(prsactx) (prsactx->min_saltlen != -1) + +static int rsa_signature_init(void *vprsactx, void *vrsa) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (prsactx == NULL || vrsa == NULL || !RSA_up_ref(vrsa)) + return 0; + + RSA_free(prsactx->rsa); + prsactx->rsa = vrsa; + if (RSA_get0_pss_params(prsactx->rsa) != NULL) + prsactx->pad_mode = RSA_PKCS1_PSS_PADDING; + else + prsactx->pad_mode = RSA_PKCS1_PADDING; + /* Maximum for sign, auto for verify */ + prsactx->saltlen = RSA_PSS_SALTLEN_AUTO; + prsactx->min_saltlen = -1; + + return 1; +} + +static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname, + const char *mdprops) +{ + if (mdname != NULL) { + EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops); + int md_nid = rsa_get_md_nid(md); + size_t algorithmidentifier_len = 0; + const unsigned char *algorithmidentifier = NULL; + + if (md == NULL) + return 0; + + if (!rsa_check_padding(md_nid, ctx->pad_mode)) { + EVP_MD_free(md); + return 0; + } + + EVP_MD_CTX_free(ctx->mdctx); + EVP_MD_free(ctx->md); + ctx->md = NULL; + ctx->mdctx = NULL; + ctx->mdname[0] = '\0'; + ctx->aid[0] = '\0'; + ctx->aid_len = 0; + + algorithmidentifier = + rsa_algorithmidentifier_encoding(md_nid, &algorithmidentifier_len); + + ctx->md = md; + ctx->mdnid = md_nid; + OPENSSL_strlcpy(ctx->mdname, mdname, sizeof(ctx->mdname)); + if (algorithmidentifier != NULL) { + memcpy(ctx->aid, algorithmidentifier, algorithmidentifier_len); + ctx->aid_len = algorithmidentifier_len; + } + } + + return 1; +} + +static int rsa_setup_mgf1_md(PROV_RSA_CTX *ctx, const char *mdname, + const char *props) +{ + if (ctx->mgf1_mdname[0] != '\0') + EVP_MD_free(ctx->mgf1_md); + + if ((ctx->mgf1_md = EVP_MD_fetch(ctx->libctx, mdname, props)) == NULL) + return 0; + OPENSSL_strlcpy(ctx->mgf1_mdname, mdname, sizeof(ctx->mgf1_mdname)); + + return 1; +} + +static int setup_tbuf(PROV_RSA_CTX *ctx) +{ + if (ctx->tbuf != NULL) + return 1; + if ((ctx->tbuf = OPENSSL_malloc(RSA_size(ctx->rsa))) == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +static void clean_tbuf(PROV_RSA_CTX *ctx) +{ + if (ctx->tbuf != NULL) + OPENSSL_cleanse(ctx->tbuf, RSA_size(ctx->rsa)); +} + +static void free_tbuf(PROV_RSA_CTX *ctx) +{ + OPENSSL_clear_free(ctx->tbuf, RSA_size(ctx->rsa)); + ctx->tbuf = NULL; +} + +static int rsa_sign(void *vprsactx, unsigned char *sig, size_t *siglen, + size_t sigsize, const unsigned char *tbs, size_t tbslen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + int ret; + size_t rsasize = RSA_size(prsactx->rsa); + size_t mdsize = rsa_get_md_size(prsactx); + + if (sig == NULL) { + *siglen = rsasize; + return 1; + } + + if (sigsize < (size_t)rsasize) + return 0; + + if (mdsize != 0) { + if (tbslen != mdsize) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH); + return 0; + } + + if (EVP_MD_is_a(prsactx->md, OSSL_DIGEST_NAME_MDC2)) { + unsigned int sltmp; + + if (prsactx->pad_mode != RSA_PKCS1_PADDING) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, + "only PKCS#1 padding supported with MDC2"); + return 0; + } + ret = RSA_sign_ASN1_OCTET_STRING(0, tbs, tbslen, sig, &sltmp, + prsactx->rsa); + + if (ret <= 0) { + ERR_raise(ERR_LIB_PROV, ERR_LIB_RSA); + return 0; + } + ret = sltmp; + goto end; + } + + switch (prsactx->pad_mode) { + case RSA_X931_PADDING: + if ((size_t)RSA_size(prsactx->rsa) < tbslen + 1) { + ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL); + return 0; + } + if (!setup_tbuf(prsactx)) { + ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(prsactx->tbuf, tbs, tbslen); + prsactx->tbuf[tbslen] = RSA_X931_hash_id(prsactx->mdnid); + ret = RSA_private_encrypt(tbslen + 1, prsactx->tbuf, + sig, prsactx->rsa, RSA_X931_PADDING); + clean_tbuf(prsactx); + break; + + case RSA_PKCS1_PADDING: + { + unsigned int sltmp; + + ret = RSA_sign(prsactx->mdnid, tbs, tbslen, sig, &sltmp, + prsactx->rsa); + if (ret <= 0) { + ERR_raise(ERR_LIB_PROV, ERR_LIB_RSA); + return 0; + } + ret = sltmp; + } + break; + + case RSA_PKCS1_PSS_PADDING: + /* Check PSS restrictions */ + if (rsa_pss_restricted(prsactx)) { + switch (prsactx->saltlen) { + case RSA_PSS_SALTLEN_DIGEST: + if (prsactx->min_saltlen > EVP_MD_size(prsactx->md)) { + ERR_raise(ERR_LIB_PROV, PROV_R_PSS_SALTLEN_TOO_SMALL); + return 0; + } + /* FALLTHRU */ + default: + if (prsactx->saltlen >= 0 + && prsactx->saltlen < prsactx->min_saltlen) { + ERR_raise(ERR_LIB_PROV, PROV_R_PSS_SALTLEN_TOO_SMALL); + return 0; + } + break; + } + } + if (!setup_tbuf(prsactx)) + return 0; + if (!RSA_padding_add_PKCS1_PSS_mgf1(prsactx->rsa, + prsactx->tbuf, tbs, + prsactx->md, prsactx->mgf1_md, + prsactx->saltlen)) { + ERR_raise(ERR_LIB_PROV, ERR_LIB_RSA); + return 0; + } + ret = RSA_private_encrypt(RSA_size(prsactx->rsa), prsactx->tbuf, + sig, prsactx->rsa, RSA_NO_PADDING); + clean_tbuf(prsactx); + break; + + default: + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, + "Only X.931, PKCS#1 v1.5 or PSS padding allowed"); + return 0; + } + } else { + ret = RSA_private_encrypt(tbslen, tbs, sig, prsactx->rsa, + prsactx->pad_mode); + } + +#ifdef LEGACY_MODE + end: +#endif + if (ret <= 0) { + ERR_raise(ERR_LIB_PROV, ERR_LIB_RSA); + return 0; + } + + *siglen = ret; + return 1; +} + +static int rsa_verify_recover(void *vprsactx, + unsigned char *rout, + size_t *routlen, + size_t routsize, + const unsigned char *sig, + size_t siglen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + int ret; + + if (rout == NULL) { + *routlen = RSA_size(prsactx->rsa); + return 1; + } + + if (prsactx->md != NULL) { + switch (prsactx->pad_mode) { + case RSA_X931_PADDING: + if (!setup_tbuf(prsactx)) + return 0; + ret = RSA_public_decrypt(siglen, sig, prsactx->tbuf, prsactx->rsa, + RSA_X931_PADDING); + if (ret < 1) { + ERR_raise(ERR_LIB_PROV, ERR_LIB_RSA); + return 0; + } + ret--; + if (prsactx->tbuf[ret] != RSA_X931_hash_id(prsactx->mdnid)) { + ERR_raise(ERR_LIB_PROV, PROV_R_ALGORITHM_MISMATCH); + return 0; + } + if (ret != EVP_MD_size(prsactx->md)) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH, + "Should be %d, but got %d", + EVP_MD_size(prsactx->md), ret); + return 0; + } + + *routlen = ret; + if (routsize < (size_t)ret) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + memcpy(rout, prsactx->tbuf, ret); + break; + + case RSA_PKCS1_PADDING: + { + size_t sltmp; + + ret = int_rsa_verify(prsactx->mdnid, NULL, 0, rout, &sltmp, + sig, siglen, prsactx->rsa); + if (ret <= 0) { + ERR_raise(ERR_LIB_PROV, ERR_LIB_RSA); + return 0; + } + ret = sltmp; + } + break; + + default: + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, + "Only X.931 or PKCS#1 v1.5 padding allowed"); + return 0; + } + } else { + ret = RSA_public_decrypt(siglen, sig, rout, prsactx->rsa, + prsactx->pad_mode); + if (ret < 0) { + ERR_raise(ERR_LIB_PROV, ERR_LIB_RSA); + return 0; + } + } + *routlen = ret; + return 1; +} + +static int rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + size_t rslen; + + if (prsactx->md != NULL) { + switch (prsactx->pad_mode) { + case RSA_PKCS1_PADDING: + if (!RSA_verify(prsactx->mdnid, tbs, tbslen, sig, siglen, + prsactx->rsa)) { + ERR_raise(ERR_LIB_PROV, ERR_LIB_RSA); + return 0; + } + return 1; + case RSA_X931_PADDING: + if (rsa_verify_recover(prsactx, NULL, &rslen, 0, sig, siglen) <= 0) + return 0; + break; + case RSA_PKCS1_PSS_PADDING: + { + int ret; + size_t mdsize; + + /* Check PSS restrictions */ + if (rsa_pss_restricted(prsactx)) { + switch (prsactx->saltlen) { + case RSA_PSS_SALTLEN_AUTO: + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PSS_SALTLEN); + return 0; + case RSA_PSS_SALTLEN_DIGEST: + if (prsactx->min_saltlen > EVP_MD_size(prsactx->md)) { + ERR_raise(ERR_LIB_PROV, + PROV_R_PSS_SALTLEN_TOO_SMALL); + return 0; + } + /* FALLTHRU */ + default: + if (prsactx->saltlen >= 0 + && prsactx->saltlen < prsactx->min_saltlen) { + ERR_raise(ERR_LIB_PROV, PROV_R_PSS_SALTLEN_TOO_SMALL); + return 0; + } + break; + } + } + + /* + * We need to check this for the RSA_verify_PKCS1_PSS_mgf1() + * call + */ + mdsize = rsa_get_md_size(prsactx); + if (tbslen != mdsize) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST_LENGTH, + "Should be %d, but got %d", + mdsize, tbslen); + return 0; + } + + if (!setup_tbuf(prsactx)) + return 0; + ret = RSA_public_decrypt(siglen, sig, prsactx->tbuf, + prsactx->rsa, RSA_NO_PADDING); + if (ret <= 0) { + ERR_raise(ERR_LIB_PROV, ERR_LIB_RSA); + return 0; + } + ret = RSA_verify_PKCS1_PSS_mgf1(prsactx->rsa, tbs, + prsactx->md, prsactx->mgf1_md, + prsactx->tbuf, + prsactx->saltlen); + if (ret <= 0) { + ERR_raise(ERR_LIB_PROV, ERR_LIB_RSA); + return 0; + } + return 1; + } + default: + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_PADDING_MODE, + "Only X.931, PKCS#1 v1.5 or PSS padding allowed"); + return 0; + } + } else { + if (!setup_tbuf(prsactx)) + return 0; + rslen = RSA_public_decrypt(siglen, sig, prsactx->tbuf, prsactx->rsa, + prsactx->pad_mode); + if (rslen == 0) { + ERR_raise(ERR_LIB_PROV, ERR_LIB_RSA); + return 0; + } + } + + if ((rslen != tbslen) || memcmp(tbs, prsactx->tbuf, rslen)) + return 0; + + return 1; +} + +static int rsa_digest_signverify_init(void *vprsactx, const char *mdname, + const char *props, void *vrsa) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + prsactx->flag_allow_md = 0; + if (!rsa_signature_init(vprsactx, vrsa) + || !rsa_setup_md(prsactx, mdname, props)) + return 0; + + prsactx->mdctx = EVP_MD_CTX_new(); + if (prsactx->mdctx == NULL) + goto error; + + if (!EVP_DigestInit_ex(prsactx->mdctx, prsactx->md, NULL)) + goto error; + + return 1; + + error: + EVP_MD_CTX_free(prsactx->mdctx); + EVP_MD_free(prsactx->md); + prsactx->mdctx = NULL; + prsactx->md = NULL; + return 0; +} + +int rsa_digest_signverify_update(void *vprsactx, const unsigned char *data, + size_t datalen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (prsactx == NULL || prsactx->mdctx == NULL) + return 0; + + return EVP_DigestUpdate(prsactx->mdctx, data, datalen); +} + +int rsa_digest_sign_final(void *vprsactx, unsigned char *sig, size_t *siglen, + size_t sigsize) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int dlen = 0; + + prsactx->flag_allow_md = 1; + if (prsactx == NULL || prsactx->mdctx == NULL) + return 0; + + /* + * If sig is NULL then we're just finding out the sig size. Other fields + * are ignored. Defer to rsa_sign. + */ + if (sig != NULL) { + /* + * TODO(3.0): There is the possibility that some externally provided + * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow - + * but that problem is much larger than just in RSA. + */ + if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) + return 0; + } + + return rsa_sign(vprsactx, sig, siglen, sigsize, digest, (size_t)dlen); +} + + +int rsa_digest_verify_final(void *vprsactx, const unsigned char *sig, + size_t siglen) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int dlen = 0; + + prsactx->flag_allow_md = 1; + if (prsactx == NULL || prsactx->mdctx == NULL) + return 0; + + /* + * TODO(3.0): There is the possibility that some externally provided + * digests exceed EVP_MAX_MD_SIZE. We should probably handle that somehow - + * but that problem is much larger than just in RSA. + */ + if (!EVP_DigestFinal_ex(prsactx->mdctx, digest, &dlen)) + return 0; + + return rsa_verify(vprsactx, sig, siglen, digest, (size_t)dlen); +} + +static void rsa_freectx(void *vprsactx) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (prsactx == NULL) + return; + + RSA_free(prsactx->rsa); + EVP_MD_CTX_free(prsactx->mdctx); + EVP_MD_free(prsactx->md); + EVP_MD_free(prsactx->mgf1_md); + free_tbuf(prsactx); + + OPENSSL_clear_free(prsactx, sizeof(prsactx)); +} + +static void *rsa_dupctx(void *vprsactx) +{ + PROV_RSA_CTX *srcctx = (PROV_RSA_CTX *)vprsactx; + PROV_RSA_CTX *dstctx; + + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); + if (dstctx == NULL) + return NULL; + + *dstctx = *srcctx; + dstctx->rsa = NULL; + dstctx->md = NULL; + dstctx->mdctx = NULL; + dstctx->tbuf = NULL; + + if (srcctx->rsa != NULL && !RSA_up_ref(srcctx->rsa)) + goto err; + dstctx->rsa = srcctx->rsa; + + if (srcctx->md != NULL && !EVP_MD_up_ref(srcctx->md)) + goto err; + dstctx->md = srcctx->md; + + if (srcctx->mgf1_md != NULL && !EVP_MD_up_ref(srcctx->mgf1_md)) + goto err; + dstctx->mgf1_md = srcctx->mgf1_md; + + if (srcctx->mdctx != NULL) { + dstctx->mdctx = EVP_MD_CTX_new(); + if (dstctx->mdctx == NULL + || !EVP_MD_CTX_copy_ex(dstctx->mdctx, srcctx->mdctx)) + goto err; + } + + return dstctx; + err: + rsa_freectx(dstctx); + return NULL; +} + +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) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); + if (p != NULL + && !OSSL_PARAM_set_octet_string(p, prsactx->aid, prsactx->aid_len)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_PAD_MODE); + if (p != NULL) + switch (p->data_type) { + case OSSL_PARAM_INTEGER: + 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_SIGNATURE_PARAM_DIGEST); + if (p != NULL && !OSSL_PARAM_set_utf8_string(p, prsactx->mdname)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_MGF1_DIGEST); + if (p != NULL && !OSSL_PARAM_set_utf8_string(p, prsactx->mgf1_mdname)) + return 0; + + p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_PSS_SALTLEN); + if (p != NULL) { + if (p->data_type == OSSL_PARAM_INTEGER) { + if (!OSSL_PARAM_set_int(p, prsactx->saltlen)) + return 0; + } else if (p->data_type == OSSL_PARAM_UTF8_STRING) { + switch (prsactx->saltlen) { + case RSA_PSS_SALTLEN_DIGEST: + if (!OSSL_PARAM_set_utf8_string(p, "digest")) + return 0; + break; + case RSA_PSS_SALTLEN_MAX: + if (!OSSL_PARAM_set_utf8_string(p, "max")) + return 0; + break; + case RSA_PSS_SALTLEN_AUTO: + if (!OSSL_PARAM_set_utf8_string(p, "auto")) + return 0; + break; + default: + if (BIO_snprintf(p->data, p->data_size, "%d", prsactx->saltlen) + <= 0) + return 0; + break; + } + } + } + + return 1; +} + +static const OSSL_PARAM known_gettable_ctx_params[] = { + OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *rsa_gettable_ctx_params(void) +{ + return known_gettable_ctx_params; +} + +static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + const OSSL_PARAM *p; + + if (prsactx == NULL || params == NULL) + return 0; + + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST); + /* Not allowed during certain operations */ + if (p != NULL && !prsactx->flag_allow_md) + return 0; + if (p != NULL) { + char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname; + char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops; + const OSSL_PARAM *propsp = + OSSL_PARAM_locate_const(params, + OSSL_SIGNATURE_PARAM_PROPERTIES); + + if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) + return 0; + if (propsp != NULL + && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops))) + return 0; + + /* TODO(3.0) PSS check needs more work */ + if (rsa_pss_restricted(prsactx)) { + /* TODO(3.0) figure out what to do for prsactx->md == NULL */ + if (prsactx->md == NULL || EVP_MD_is_a(prsactx->md, mdname)) + return 1; + ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED); + return 0; + } + + /* non-PSS code follows */ + if (!rsa_setup_md(prsactx, mdname, mdprops)) + return 0; + } + + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PAD_MODE); + if (p != NULL) { + 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; + } + + switch (pad_mode) { + case RSA_PKCS1_OAEP_PADDING: + /* + * OAEP padding is for asymmetric cipher only so is not compatible + * with signature use. + */ + ERR_raise_data(ERR_LIB_PROV, + PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE, + "OAEP padding not allowed for signing / verifying"); + return 0; + case RSA_PKCS1_PSS_PADDING: + if (prsactx->mdname[0] == '\0') + rsa_setup_md(prsactx, "SHA1", ""); + goto cont; + case RSA_PKCS1_PADDING: + case RSA_SSLV23_PADDING: + case RSA_NO_PADDING: + case RSA_X931_PADDING: + if (RSA_get0_pss_params(prsactx->rsa) != NULL) { + ERR_raise_data(ERR_LIB_PROV, + PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE, + "X.931 padding not allowed with RSA-PSS"); + return 0; + } + cont: + if (!rsa_check_padding(prsactx->mdnid, pad_mode)) + return 0; + break; + default: + return 0; + } + prsactx->pad_mode = pad_mode; + } + + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_PSS_SALTLEN); + if (p != NULL) { + int saltlen; + + if (prsactx->pad_mode != RSA_PKCS1_PSS_PADDING) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED, + "PSS saltlen can only be specified if " + "PSS padding has been specified first"); + return 0; + } + + switch (p->data_type) { + case OSSL_PARAM_INTEGER: /* Support for legacy pad mode number */ + if (!OSSL_PARAM_get_int(p, &saltlen)) + return 0; + break; + case OSSL_PARAM_UTF8_STRING: + if (strcmp(p->data, "digest") == 0) + saltlen = RSA_PSS_SALTLEN_DIGEST; + else if (strcmp(p->data, "max") == 0) + saltlen = RSA_PSS_SALTLEN_MAX; + else if (strcmp(p->data, "auto") == 0) + saltlen = RSA_PSS_SALTLEN_AUTO; + else + saltlen = atoi(p->data); + break; + default: + return 0; + } + + /* + * RSA_PSS_SALTLEN_MAX seems curiously named in this check. + * Contrary to what it's name suggests, it's the currently + * lowest saltlen number possible. + */ + if (saltlen < RSA_PSS_SALTLEN_MAX) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_PSS_SALTLEN); + return 0; + } + + prsactx->saltlen = saltlen; + } + + p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_MGF1_DIGEST); + if (p != NULL) { + char mdname[OSSL_MAX_NAME_SIZE] = "", *pmdname = mdname; + char mdprops[OSSL_MAX_PROPQUERY_SIZE] = "", *pmdprops = mdprops; + const OSSL_PARAM *propsp = + OSSL_PARAM_locate_const(params, + OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES); + + if (!OSSL_PARAM_get_utf8_string(p, &pmdname, sizeof(mdname))) + return 0; + if (propsp != NULL + && !OSSL_PARAM_get_utf8_string(propsp, &pmdprops, sizeof(mdprops))) + return 0; + + if (prsactx->pad_mode != RSA_PKCS1_PSS_PADDING) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_MGF1_MD); + return 0; + } + + /* TODO(3.0) PSS check needs more work */ + if (rsa_pss_restricted(prsactx)) { + /* TODO(3.0) figure out what to do for prsactx->md == NULL */ + if (prsactx->mgf1_md == NULL + || EVP_MD_is_a(prsactx->mgf1_md, mdname)) + return 1; + ERR_raise(ERR_LIB_PROV, PROV_R_DIGEST_NOT_ALLOWED); + return 0; + } + + /* non-PSS code follows */ + if (!rsa_setup_mgf1_md(prsactx, mdname, mdprops)) + return 0; + } + + return 1; +} + +static const OSSL_PARAM known_settable_ctx_params[] = { + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *rsa_settable_ctx_params(void) +{ + /* + * TODO(3.0): Should this function return a different set of settable ctx + * params if the ctx is being used for a DigestSign/DigestVerify? In that + * case it is not allowed to set the digest size/digest name because the + * digest is explicitly set as part of the init. + */ + return known_settable_ctx_params; +} + +static int rsa_get_ctx_md_params(void *vprsactx, OSSL_PARAM *params) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (prsactx->mdctx == NULL) + return 0; + + return EVP_MD_CTX_get_params(prsactx->mdctx, params); +} + +static const OSSL_PARAM *rsa_gettable_ctx_md_params(void *vprsactx) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (prsactx->md == NULL) + return 0; + + return EVP_MD_gettable_ctx_params(prsactx->md); +} + +static int rsa_set_ctx_md_params(void *vprsactx, const OSSL_PARAM params[]) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (prsactx->mdctx == NULL) + return 0; + + return EVP_MD_CTX_set_params(prsactx->mdctx, params); +} + +static const OSSL_PARAM *rsa_settable_ctx_md_params(void *vprsactx) +{ + PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + + if (prsactx->md == NULL) + return 0; + + return EVP_MD_settable_ctx_params(prsactx->md); +} + +const OSSL_DISPATCH rsa_signature_functions[] = { + { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))rsa_newctx }, + { OSSL_FUNC_SIGNATURE_SIGN_INIT, (void (*)(void))rsa_signature_init }, + { OSSL_FUNC_SIGNATURE_SIGN, (void (*)(void))rsa_sign }, + { OSSL_FUNC_SIGNATURE_VERIFY_INIT, (void (*)(void))rsa_signature_init }, + { OSSL_FUNC_SIGNATURE_VERIFY, (void (*)(void))rsa_verify }, + { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT, (void (*)(void))rsa_signature_init }, + { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER, (void (*)(void))rsa_verify_recover }, + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, + (void (*)(void))rsa_digest_signverify_init }, + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, + (void (*)(void))rsa_digest_signverify_update }, + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, + (void (*)(void))rsa_digest_sign_final }, + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, + (void (*)(void))rsa_digest_signverify_init }, + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, + (void (*)(void))rsa_digest_signverify_update }, + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, + (void (*)(void))rsa_digest_verify_final }, + { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))rsa_freectx }, + { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))rsa_dupctx }, + { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))rsa_get_ctx_params }, + { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, + (void (*)(void))rsa_gettable_ctx_params }, + { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, (void (*)(void))rsa_set_ctx_params }, + { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, + (void (*)(void))rsa_settable_ctx_params }, + { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, + (void (*)(void))rsa_get_ctx_md_params }, + { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, + (void (*)(void))rsa_gettable_ctx_md_params }, + { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, + (void (*)(void))rsa_set_ctx_md_params }, + { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, + (void (*)(void))rsa_settable_ctx_md_params }, + { 0, NULL } +}; diff --git a/util/libcrypto.num b/util/libcrypto.num index db4532f..6c8487e 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4945,3 +4945,5 @@ EVP_PKEY_CTX_set_ecdh_kdf_outlen ? 3_0_0 EXIST::FUNCTION:EC EVP_PKEY_CTX_get_ecdh_kdf_outlen ? 3_0_0 EXIST::FUNCTION:EC EVP_PKEY_CTX_set0_ecdh_kdf_ukm ? 3_0_0 EXIST::FUNCTION:EC EVP_PKEY_CTX_get0_ecdh_kdf_ukm ? 3_0_0 EXIST::FUNCTION:EC +EVP_PKEY_CTX_set_rsa_pss_saltlen ? 3_0_0 EXIST::FUNCTION:RSA +EVP_PKEY_CTX_get_rsa_pss_saltlen ? 3_0_0 EXIST::FUNCTION:RSA |