/*
- * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2021 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
*/
#include "internal/deprecated.h"
-#include <stdio.h>
#include <openssl/crypto.h>
#include <openssl/core_names.h>
-#include <openssl/engine.h>
+#ifndef FIPS_MODULE
+# include <openssl/engine.h>
+#endif
#include <openssl/evp.h>
+#include <openssl/param_build.h>
#include "internal/cryptlib.h"
#include "internal/refcount.h"
-#include "openssl/param_build.h"
#include "crypto/bn.h"
#include "crypto/evp.h"
#include "crypto/rsa.h"
BN_clear_free(r->iqmp);
#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
- rsa_acvp_test_free(r->acvp_test);
+ ossl_rsa_acvp_test_free(r->acvp_test);
#endif
#ifndef FIPS_MODULE
RSA_PSS_PARAMS_free(r->pss);
- sk_RSA_PRIME_INFO_pop_free(r->prime_infos, rsa_multip_info_free);
+ sk_RSA_PRIME_INFO_pop_free(r->prime_infos, ossl_rsa_multip_info_free);
#endif
BN_BLINDING_free(r->blinding);
BN_BLINDING_free(r->mt_blinding);
- OPENSSL_free(r->bignum_data);
OPENSSL_free(r);
}
return r->libctx;
}
+void ossl_rsa_set0_libctx(RSA *r, OSSL_LIB_CTX *libctx)
+{
+ r->libctx = libctx;
+}
+
#ifndef FIPS_MODULE
int RSA_set_ex_data(RSA *r, int idx, void *arg)
{
* \cdot(log_e(nBits \cdot log_e(2))^{2/3} - 4.69}{log_e(2)}
* The two cube roots are merged together here.
*/
-uint16_t ifc_ffc_compute_security_bits(int n)
+uint16_t ossl_ifc_ffc_compute_security_bits(int n)
{
uint64_t x;
uint32_t lx;
- uint16_t y;
+ uint16_t y, cap;
- /* Look for common values as listed in SP 800-56B rev 2 Appendix D */
+ /*
+ * Look for common values as listed in standards.
+ * These values are not exactly equal to the results from the formulae in
+ * the standards but are defined to be canonical.
+ */
switch (n) {
- case 2048:
+ case 2048: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */
return 112;
- case 3072:
+ case 3072: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */
return 128;
- case 4096:
+ case 4096: /* SP 800-56B rev 2 Appendix D */
return 152;
- case 6144:
+ case 6144: /* SP 800-56B rev 2 Appendix D */
return 176;
- case 8192:
+ case 7680: /* FIPS 140-2 IG 7.5 */
+ return 192;
+ case 8192: /* SP 800-56B rev 2 Appendix D */
return 200;
+ case 15360: /* FIPS 140-2 IG 7.5 */
+ return 256;
}
+
/*
* The first incorrect result (i.e. not accurate or off by one low) occurs
* for n = 699668. The true value here is 1200. Instead of using this n
if (n < 8)
return 0;
+ /*
+ * To ensure that the output is non-decreasing with respect to n,
+ * a cap needs to be applied to the two values where the function over
+ * estimates the strength (according to the above fast path).
+ */
+ if (n <= 7680)
+ cap = 192;
+ else if (n <= 15360)
+ cap = 256;
+ else
+ cap = 1200;
+
x = n * (uint64_t)log_2;
lx = ilog_e(x);
y = (uint16_t)((mul2(c1_923, icbrt64(mul2(mul2(x, lx), lx))) - c4_690)
/ log_2);
- return (y + 4) & ~7;
+ y = (y + 4) & ~7;
+ if (y > cap)
+ y = cap;
+ return y;
}
/* This ought to mean that we have private key at hand. */
int ex_primes = sk_RSA_PRIME_INFO_num(rsa->prime_infos);
- if (ex_primes <= 0 || (ex_primes + 2) > rsa_multip_cap(bits))
+ if (ex_primes <= 0 || (ex_primes + 2) > ossl_rsa_multip_cap(bits))
return 0;
}
#endif
- return ifc_ffc_compute_security_bits(bits);
+ return ossl_ifc_ffc_compute_security_bits(bits);
}
int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d)
old = r->prime_infos;
for (i = 0; i < pnum; i++) {
- pinfo = rsa_multip_info_new();
+ pinfo = ossl_rsa_multip_info_new();
if (pinfo == NULL)
goto err;
if (primes[i] != NULL && exps[i] != NULL && coeffs[i] != NULL) {
BN_set_flags(pinfo->d, BN_FLG_CONSTTIME);
BN_set_flags(pinfo->t, BN_FLG_CONSTTIME);
} else {
- rsa_multip_info_free(pinfo);
+ ossl_rsa_multip_info_free(pinfo);
goto err;
}
(void)sk_RSA_PRIME_INFO_push(prime_infos, pinfo);
r->prime_infos = prime_infos;
- if (!rsa_multip_calc_product(r)) {
+ if (!ossl_rsa_multip_calc_product(r)) {
r->prime_infos = old;
goto err;
}
* be freed in that case. So currently, stay consistent
* with other *set0* functions: just free it...
*/
- sk_RSA_PRIME_INFO_pop_free(old, rsa_multip_info_free);
+ sk_RSA_PRIME_INFO_pop_free(old, ossl_rsa_multip_info_free);
}
r->version = RSA_ASN1_VERSION_MULTI;
return 1;
err:
/* r, d, t should not be freed */
- sk_RSA_PRIME_INFO_pop_free(prime_infos, rsa_multip_info_free_ex);
+ sk_RSA_PRIME_INFO_pop_free(prime_infos, ossl_rsa_multip_info_free_ex);
return 0;
}
#endif
#endif
}
+/* Internal */
+int ossl_rsa_set0_pss_params(RSA *r, RSA_PSS_PARAMS *pss)
+{
+#ifdef FIPS_MODULE
+ return 0;
+#else
+ RSA_PSS_PARAMS_free(r->pss);
+ r->pss = pss;
+ return 1;
+#endif
+}
+
/* Internal */
RSA_PSS_PARAMS_30 *ossl_rsa_get0_pss_params_30(RSA *r)
{
if (!ossl_assert(prime != NULL && exp != NULL && coeff != NULL))
goto err;
- /* Using rsa_multip_info_new() is wasteful, so allocate directly */
+ /* Using ossl_rsa_multip_info_new() is wasteful, so allocate directly */
if ((pinfo = OPENSSL_zalloc(sizeof(*pinfo))) == NULL) {
ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE);
goto err;
r->prime_infos = prime_infos;
- if (!rsa_multip_calc_product(r)) {
+ if (!ossl_rsa_multip_calc_product(r)) {
r->prime_infos = old_infos;
goto err;
}
* be freed in that case. So currently, stay consistent
* with other *set0* functions: just free it...
*/
- sk_RSA_PRIME_INFO_pop_free(old_infos, rsa_multip_info_free);
+ sk_RSA_PRIME_INFO_pop_free(old_infos, ossl_rsa_multip_info_free);
}
#endif
#ifndef FIPS_MODULE
err:
/* r, d, t should not be freed */
- sk_RSA_PRIME_INFO_pop_free(prime_infos, rsa_multip_info_free_ex);
+ sk_RSA_PRIME_INFO_pop_free(prime_infos, ossl_rsa_multip_info_free_ex);
return 0;
#endif
}
}
#ifndef FIPS_MODULE
-int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode)
+/* Helpers to set or get diverse hash algorithm names */
+static int int_set_rsa_md_name(EVP_PKEY_CTX *ctx,
+ /* For checks */
+ int keytype, int optype,
+ /* For EVP_PKEY_CTX_set_params() */
+ const char *mdkey, const char *mdname,
+ const char *propkey, const char *mdprops)
{
- OSSL_PARAM pad_params[2], *p = pad_params;
+ OSSL_PARAM params[3], *p = params;
- if (ctx == NULL) {
+ if (ctx == NULL || mdname == NULL || (ctx->operation & optype) == 0) {
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_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);
+ /* If key type not RSA return error */
+ switch (keytype) {
+ case -1:
+ if (!EVP_PKEY_CTX_is_a(ctx, "RSA")
+ && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS"))
+ return -1;
+ break;
+ default:
+ if (!EVP_PKEY_CTX_is_a(ctx, evp_pkey_type2name(keytype)))
+ return -1;
+ break;
+ }
- *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_PAD_MODE, &pad_mode);
+ /* Cast away the const. This is read only so should be safe */
+ *p++ = OSSL_PARAM_construct_utf8_string(mdkey, (char *)mdname, 0);
+ if (evp_pkey_ctx_is_provided(ctx) && mdprops != NULL) {
+ /* Cast away the const. This is read only so should be safe */
+ *p++ = OSSL_PARAM_construct_utf8_string(propkey, (char *)mdprops, 0);
+ }
*p++ = OSSL_PARAM_construct_end();
- return EVP_PKEY_CTX_set_params(ctx, pad_params);
+ return evp_pkey_ctx_set_params_strict(ctx, params);
}
-int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode)
+/* Helpers to set or get diverse hash algorithm names */
+static int int_get_rsa_md_name(EVP_PKEY_CTX *ctx,
+ /* For checks */
+ int keytype, int optype,
+ /* For EVP_PKEY_CTX_get_params() */
+ const char *mdkey,
+ char *mdname, size_t mdnamesize)
{
- OSSL_PARAM pad_params[2], *p = pad_params;
+ OSSL_PARAM params[2], *p = params;
- if (ctx == NULL || pad_mode == NULL) {
+ if (ctx == NULL || mdname == NULL || (ctx->operation & optype) == 0) {
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_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);
+ /* If key type not RSA return error */
+ switch (keytype) {
+ case -1:
+ if (!EVP_PKEY_CTX_is_a(ctx, "RSA")
+ && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS"))
+ return -1;
+ break;
+ default:
+ if (!EVP_PKEY_CTX_is_a(ctx, evp_pkey_type2name(keytype)))
+ return -1;
+ break;
+ }
- *p++ = OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_PAD_MODE, pad_mode);
+ /* Cast away the const. This is read only so should be safe */
+ *p++ = OSSL_PARAM_construct_utf8_string(mdkey, (char *)mdname, mdnamesize);
*p++ = OSSL_PARAM_construct_end();
- if (!EVP_PKEY_CTX_get_params(ctx, pad_params))
- return 0;
-
- return 1;
-
+ return evp_pkey_ctx_get_params_strict(ctx, params);
}
-int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
+int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int pad_mode)
{
- const char *name;
-
- if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
- ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
- /* Uses the same return values as EVP_PKEY_CTX_ctrl */
- return -2;
- }
+ return RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING,
+ pad_mode, NULL);
+}
- /* If key type not RSA return error */
- if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
- return -1;
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
+int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *pad_mode)
+{
+ return RSA_pkey_ctx_ctrl(ctx, -1, EVP_PKEY_CTRL_GET_RSA_PADDING,
+ 0, pad_mode);
+}
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.ciph.ciphprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
- EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md);
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
+int EVP_PKEY_CTX_set_rsa_pss_keygen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
+{
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
+ EVP_PKEY_CTRL_MD, 0, (void *)(md));
+}
- name = (md == NULL) ? "" : EVP_MD_name(md);
+int EVP_PKEY_CTX_set_rsa_pss_keygen_md_name(EVP_PKEY_CTX *ctx,
+ const char *mdname,
+ const char *mdprops)
+{
+ return int_set_rsa_md_name(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
+ OSSL_PKEY_PARAM_RSA_DIGEST, mdname,
+ OSSL_PKEY_PARAM_RSA_DIGEST_PROPS, mdprops);
+}
- return EVP_PKEY_CTX_set_rsa_oaep_md_name(ctx, name, NULL);
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
+int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
+{
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
+ EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)(md));
}
int EVP_PKEY_CTX_set_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, const char *mdname,
const char *mdprops)
{
- OSSL_PARAM rsa_params[3], *p = rsa_params;
-
- if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
- 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 return error */
- if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
- return -1;
-
-
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST,
- /*
- * 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_OAEP_DIGEST_PROPS,
- /*
- * Cast away the const. This is read
- * only so should be safe
- */
- (char *)mdprops, 0);
- }
- *p++ = OSSL_PARAM_construct_end();
-
- return EVP_PKEY_CTX_set_params(ctx, rsa_params);
+ return
+ int_set_rsa_md_name(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
+ OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST, mdname,
+ OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST_PROPS, mdprops);
}
int EVP_PKEY_CTX_get_rsa_oaep_md_name(EVP_PKEY_CTX *ctx, char *name,
- size_t namelen)
+ size_t namesize)
{
- OSSL_PARAM rsa_params[2], *p = rsa_params;
-
- if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
- 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 return error */
- if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
- return -1;
-
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST,
- name, namelen);
- *p++ = OSSL_PARAM_construct_end();
-
- if (!EVP_PKEY_CTX_get_params(ctx, rsa_params))
- return -1;
-
- return 1;
+ return int_get_rsa_md_name(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
+ OSSL_ASYM_CIPHER_PARAM_OAEP_DIGEST,
+ name, namesize);
}
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
{
- /* 80 should be big enough */
- char name[80] = "";
-
- if (ctx == NULL || md == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
- 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 return error */
- if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
- return -1;
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.ciph.ciphprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
- EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)md);
-
- if (EVP_PKEY_CTX_get_rsa_oaep_md_name(ctx, name, sizeof(name)) <= 0)
- return -1;
-
- /* May be NULL meaning "unknown" */
- *md = evp_get_digestbyname_ex(ctx->libctx, name);
-
- return 1;
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
+ EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void *)md);
}
-static int int_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx,
- /* For EVP_PKEY_CTX_ctrl() */
- int keytype, int optype, int cmd,
- const EVP_MD *md,
- /* For EVP_PKEY_CTX_set_params() */
- const char *mdname, const char *mdprops)
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
+int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
{
- OSSL_PARAM rsa_params[3], *p = rsa_params;
-
- if (ctx == NULL || (ctx->operation & optype) == 0) {
- 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 return error */
- if (ctx->pmeth != NULL
- && (keytype == -1
- ? (ctx->pmeth->pkey_id != EVP_PKEY_RSA
- && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
- : ctx->pmeth->pkey_id != keytype))
- return -1;
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (cmd != -1) {
- 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)
- || (EVP_PKEY_CTX_IS_GEN_OP(ctx)
- && ctx->op.keymgmt.genctx == NULL))
- return EVP_PKEY_CTX_ctrl(ctx, keytype, optype, cmd, 0, (void *)md);
-
- mdname = (md == NULL) ? "" : EVP_MD_name(md);
- }
-
-
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MGF1_DIGEST,
- /*
- * 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_PKEY_PARAM_MGF1_PROPERTIES,
- /*
- * Cast away the const. This is
- * read only so should be safe
- */
- (char *)mdprops, 0);
- }
- *p++ = OSSL_PARAM_construct_end();
-
- return EVP_PKEY_CTX_set_params(ctx, rsa_params);
+ return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
+ EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md));
}
-int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
+int EVP_PKEY_CTX_set_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, const char *mdname,
+ const char *mdprops)
{
- return int_set_rsa_mgf1_md(ctx, -1,
+ return int_set_rsa_md_name(ctx, -1,
EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
- EVP_PKEY_CTRL_RSA_MGF1_MD, md, NULL, NULL);
+ OSSL_PKEY_PARAM_MGF1_DIGEST, mdname,
+ OSSL_PKEY_PARAM_MGF1_PROPERTIES, mdprops);
}
-int EVP_PKEY_CTX_set_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, const char *mdname,
- const char *mdprops)
+int EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name,
+ size_t namesize)
{
- return int_set_rsa_mgf1_md(ctx, -1,
+ return int_get_rsa_md_name(ctx, -1,
EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
- -1, NULL, mdname, mdprops);
+ OSSL_PKEY_PARAM_MGF1_DIGEST, name, namesize);
}
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md)
{
- return int_set_rsa_mgf1_md(ctx, EVP_PKEY_RSA_PSS,
- EVP_PKEY_OP_KEYGEN, EVP_PKEY_CTRL_RSA_MGF1_MD,
- md, NULL, NULL);
+ return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
+ EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)(md));
}
int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md_name(EVP_PKEY_CTX *ctx,
const char *mdname)
{
- return int_set_rsa_mgf1_md(ctx, EVP_PKEY_RSA_PSS,
- EVP_PKEY_OP_TYPE_CRYPT | EVP_PKEY_OP_TYPE_SIG,
- -1, NULL, mdname, NULL);
-}
-
-int EVP_PKEY_CTX_get_rsa_mgf1_md_name(EVP_PKEY_CTX *ctx, char *name,
- size_t namelen)
-{
- OSSL_PARAM rsa_params[2], *p = rsa_params;
-
- if (ctx == NULL
- || (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
- && !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx))) {
- 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;
-
- *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_MGF1_DIGEST,
- name, namelen);
- *p++ = OSSL_PARAM_construct_end();
-
- if (!EVP_PKEY_CTX_get_params(ctx, rsa_params))
- return -1;
-
- return 1;
+ return int_set_rsa_md_name(ctx, EVP_PKEY_RSA_PSS, EVP_PKEY_OP_KEYGEN,
+ OSSL_PKEY_PARAM_MGF1_DIGEST, mdname,
+ NULL, NULL);
}
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **md)
{
- /* 80 should be big enough */
- char name[80] = "";
-
- if (ctx == NULL
- || (!EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)
- && !EVP_PKEY_CTX_IS_SIGNATURE_OP(ctx))) {
- 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_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,
- EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
- EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)md);
-
- if (EVP_PKEY_CTX_get_rsa_mgf1_md_name(ctx, name, sizeof(name)) <= 0)
- return -1;
-
- /* May be NULL meaning "unknown" */
- *md = evp_get_digestbyname_ex(ctx->libctx, name);
-
- return 1;
+ return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
+ EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)(md));
}
int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, void *label, int llen)
}
/* If key type not RSA return error */
- if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
+ if (!EVP_PKEY_CTX_is_a(ctx, "RSA"))
return -1;
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.ciph.ciphprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
- EVP_PKEY_CTRL_RSA_OAEP_LABEL, llen,
- (void *)label);
-
+ /* Cast away the const. This is read only so should be safe */
*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);
+ (void *)label, (size_t)llen);
*p++ = OSSL_PARAM_construct_end();
- if (!EVP_PKEY_CTX_set_params(ctx, rsa_params))
+ if (!evp_pkey_ctx_set_params_strict(ctx, rsa_params))
return 0;
+ /* Ownership is supposed to be transfered to the callee. */
OPENSSL_free(label);
return 1;
}
int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, unsigned char **label)
{
- OSSL_PARAM rsa_params[3], *p = rsa_params;
+ OSSL_PARAM rsa_params[2], *p = rsa_params;
size_t labellen;
if (ctx == NULL || !EVP_PKEY_CTX_IS_ASYM_CIPHER_OP(ctx)) {
}
/* If key type not RSA return error */
- if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
+ if (!EVP_PKEY_CTX_is_a(ctx, "RSA"))
return -1;
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.ciph.ciphprovctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT,
- EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0,
- (void *)label);
-
*p++ = OSSL_PARAM_construct_octet_ptr(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL,
(void **)label, 0);
- *p++ = OSSL_PARAM_construct_size_t(OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL_LEN,
- &labellen);
*p++ = OSSL_PARAM_construct_end();
if (!EVP_PKEY_CTX_get_params(ctx, rsa_params))
return -1;
+ labellen = rsa_params[0].return_size;
if (labellen > INT_MAX)
return -1;
return (int)labellen;
}
-static int int_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen,
- int keytype, int optype)
-{
- OSSL_PARAM pad_params[2], *p = pad_params;
-
- if (ctx == NULL || (ctx->operation & optype) == 0) {
- 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
- && (keytype == -1
- ? (ctx->pmeth->pkey_id != EVP_PKEY_RSA
- && ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS)
- : ctx->pmeth->pkey_id != keytype))
- 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)
- || (EVP_PKEY_CTX_IS_GEN_OP(ctx)
- && ctx->op.keymgmt.genctx == NULL))
- return EVP_PKEY_CTX_ctrl(ctx, keytype, optype,
- 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);
-}
-
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int saltlen)
{
- return int_set_rsa_pss_saltlen(ctx, saltlen, -1, EVP_PKEY_OP_TYPE_SIG);
+ /*
+ * For some reason, the optype was set to this:
+ *
+ * EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY
+ *
+ * However, we do use RSA-PSS with the whole gamut of diverse signature
+ * and verification operations, so the optype gets upgraded to this:
+ *
+ * EVP_PKEY_OP_TYPE_SIG
+ */
+ return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG,
+ EVP_PKEY_CTRL_RSA_PSS_SALTLEN, saltlen, NULL);
}
-int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int saltlen)
+/*
+ * This one is currently implemented as an EVP_PKEY_CTX_ctrl() wrapper,
+ * simply because that's easier.
+ */
+int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen)
{
- return int_set_rsa_pss_saltlen(ctx, saltlen, EVP_PKEY_RSA_PSS,
- EVP_PKEY_OP_KEYGEN);
+ /*
+ * Because of circumstances, the optype is updated from:
+ *
+ * EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY
+ *
+ * to:
+ *
+ * EVP_PKEY_OP_TYPE_SIG
+ */
+ return RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG,
+ EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, saltlen);
}
-int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *saltlen)
+int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int saltlen)
{
OSSL_PARAM pad_params[2], *p = pad_params;
- if (ctx == NULL || saltlen == NULL) {
+ if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
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)
+ if (!EVP_PKEY_CTX_is_a(ctx, "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_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;
-
+ return evp_pkey_ctx_set_params_strict(ctx, pad_params);
}
int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits)
}
/* If key type not RSA return error */
- if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
+ if (!EVP_PKEY_CTX_is_a(ctx, "RSA")
+ && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS"))
return -1;
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.keymgmt.genctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
- EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL);
-
*p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits2);
*p++ = OSSL_PARAM_construct_end();
- if (!EVP_PKEY_CTX_set_params(ctx, params))
- return 0;
-
- return 1;
+ return evp_pkey_ctx_set_params_strict(ctx, params);
}
-static int evp_pkey_ctx_set_rsa_keygen_pubexp_intern(EVP_PKEY_CTX *ctx,
- BIGNUM *pubexp,
- int copy)
+int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp)
{
- OSSL_PARAM_BLD *tmpl;
- OSSL_PARAM *params;
- int ret;
-
- if (ctx == NULL || !EVP_PKEY_CTX_IS_GEN_OP(ctx)) {
- 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 return error */
- if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
- return -1;
-
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.keymgmt.genctx == NULL) {
- if (copy == 1)
- pubexp = BN_dup(pubexp);
- ret = EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
+ int ret = RSA_pkey_ctx_ctrl(ctx, EVP_PKEY_OP_KEYGEN,
EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp);
- if ((copy == 1) && (ret <= 0))
- BN_free(pubexp);
- return ret;
- }
-
- if ((tmpl = OSSL_PARAM_BLD_new()) == NULL)
- return 0;
- if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, pubexp)
- || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
- OSSL_PARAM_BLD_free(tmpl);
- return 0;
- }
- OSSL_PARAM_BLD_free(tmpl);
-
- ret = EVP_PKEY_CTX_set_params(ctx, params);
- OSSL_PARAM_BLD_free_params(params);
/*
* Satisfy memory semantics for pre-3.0 callers of
* EVP_PKEY_CTX_set_rsa_keygen_pubexp(): their expectation is that input
* pubexp BIGNUM becomes managed by the EVP_PKEY_CTX on success.
*/
- if ((copy == 0) && (ret > 0))
+ if (ret > 0 && evp_pkey_ctx_is_provided(ctx)) {
+ BN_free(ctx->rsa_pubexp);
ctx->rsa_pubexp = pubexp;
+ }
return ret;
}
-int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp)
-{
- return evp_pkey_ctx_set_rsa_keygen_pubexp_intern(ctx, pubexp, 0);
-}
-
int EVP_PKEY_CTX_set1_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *pubexp)
{
- return evp_pkey_ctx_set_rsa_keygen_pubexp_intern(ctx, pubexp, 1);
+ int ret = 0;
+
+ /*
+ * When we're dealing with a provider, there's no need to duplicate
+ * pubexp, as it gets copied when transforming to an OSSL_PARAM anyway.
+ */
+ if (evp_pkey_ctx_is_legacy(ctx)) {
+ pubexp = BN_dup(pubexp);
+ if (pubexp == NULL)
+ return 0;
+ }
+ ret = EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
+ EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp);
+ if (evp_pkey_ctx_is_legacy(ctx) && ret <= 0)
+ BN_free(pubexp);
+ return ret;
}
int EVP_PKEY_CTX_set_rsa_keygen_primes(EVP_PKEY_CTX *ctx, int primes)
}
/* If key type not RSA return error */
- if (ctx->pmeth != NULL && ctx->pmeth->pkey_id != EVP_PKEY_RSA)
+ if (!EVP_PKEY_CTX_is_a(ctx, "RSA")
+ && !EVP_PKEY_CTX_is_a(ctx, "RSA-PSS"))
return -1;
- /* TODO(3.0): Remove this eventually when no more legacy */
- if (ctx->op.keymgmt.genctx == NULL)
- return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN,
- EVP_PKEY_CTRL_RSA_KEYGEN_PRIMES, primes,
- NULL);
-
*p++ = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_PRIMES, &primes2);
*p++ = OSSL_PARAM_construct_end();
- if (!EVP_PKEY_CTX_set_params(ctx, params))
- return 0;
-
- return 1;
+ return evp_pkey_ctx_set_params_strict(ctx, params);
}
#endif