aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/build.info3
-rw-r--r--crypto/evp/p_lib.c160
-rw-r--r--crypto/param_build_set.c111
-rw-r--r--crypto/rsa/build.info3
-rw-r--r--crypto/rsa/rsa_ameth.c17
-rw-r--r--crypto/rsa/rsa_backend.c22
-rw-r--r--crypto/rsa/rsa_mp_names.c76
-rw-r--r--doc/man3/EVP_PKEY_fromdata.pod2
-rw-r--r--doc/man3/EVP_PKEY_gettable_params.pod108
-rw-r--r--doc/man7/provider-keymgmt.pod78
-rw-r--r--include/crypto/rsa.h4
-rw-r--r--include/internal/param_build_set.h27
-rw-r--r--include/openssl/core_names.h31
-rw-r--r--include/openssl/evp.h10
-rw-r--r--providers/implementations/keymgmt/build.info5
-rw-r--r--providers/implementations/keymgmt/ec_kmgmt.c79
-rw-r--r--providers/implementations/keymgmt/ecx_kmgmt.c58
-rw-r--r--providers/implementations/keymgmt/rsa_kmgmt.c156
-rw-r--r--providers/implementations/serializers/serializer_rsa.c1
-rw-r--r--test/evp_pkey_provided_test.c131
-rw-r--r--test/keymgmt_internal_test.c78
-rw-r--r--util/libcrypto.num6
22 files changed, 943 insertions, 223 deletions
diff --git a/crypto/build.info b/crypto/build.info
index a688248acf..baa31ee8e1 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -70,7 +70,8 @@ SOURCE[../providers/libfips.a]=$CORE_COMMON
$UTIL_COMMON=\
cryptlib.c params.c params_from_text.c bsearch.c ex_data.c o_str.c \
ctype.c threads_pthread.c threads_win.c threads_none.c initthread.c \
- context.c sparse_array.c asn1_dsa.c packet.c param_build.c $CPUIDASM
+ context.c sparse_array.c asn1_dsa.c packet.c param_build.c $CPUIDASM \
+ param_build_set.c
$UTIL_DEFINE=$CPUIDDEF
SOURCE[../libcrypto]=$UTIL_COMMON \
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c
index 9ed238e366..b176f100e8 100644
--- a/crypto/evp/p_lib.c
+++ b/crypto/evp/p_lib.c
@@ -1459,3 +1459,163 @@ int evp_pkey_downgrade(EVP_PKEY *pk)
return 0; /* No downgrade, but at least the key is restored */
}
#endif /* FIPS_MODE */
+
+const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *pkey)
+{
+ if (pkey == NULL
+ || pkey->keymgmt == NULL
+ || pkey->keydata == NULL)
+ return 0;
+ return evp_keymgmt_gettable_params(pkey->keymgmt);
+}
+
+/*
+ * For the following methods param->return_size is set to a value
+ * larger than can be returned by the call to evp_keymgmt_get_params().
+ * If it is still this value then the parameter was ignored - and in this
+ * case it returns an error..
+ */
+
+int EVP_PKEY_get_bn_param(EVP_PKEY *pkey, const char *key_name, BIGNUM **bn)
+{
+ int ret = 0;
+ OSSL_PARAM params[2];
+ unsigned char buffer[2048];
+ /*
+ * Use -1 as the terminator here instead of sizeof(buffer) + 1 since
+ * -1 is less likely to be a valid value.
+ */
+ const size_t not_set = (size_t)-1;
+ unsigned char *buf = NULL;
+ size_t buf_sz = 0;
+
+ if (pkey == NULL
+ || pkey->keymgmt == NULL
+ || pkey->keydata == NULL
+ || key_name == NULL
+ || bn == NULL)
+ return 0;
+
+ memset(buffer, 0, sizeof(buffer));
+ params[0] = OSSL_PARAM_construct_BN(key_name, buffer, sizeof(buffer));
+ /* If the return_size is still not_set then we know it was not found */
+ params[0].return_size = not_set;
+ params[1] = OSSL_PARAM_construct_end();
+ if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)) {
+ if (params[0].return_size == not_set
+ || params[0].return_size == 0)
+ return 0;
+ buf_sz = params[0].return_size;
+ /*
+ * If it failed because the buffer was too small then allocate the
+ * required buffer size and retry.
+ */
+ buf = OPENSSL_zalloc(buf_sz);
+ if (buf == NULL)
+ return 0;
+ params[0].data = buf;
+ params[0].data_size = buf_sz;
+
+ if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+ goto err;
+ }
+ /* Fail if the param was not found */
+ if (params[0].return_size == not_set)
+ goto err;
+ ret = OSSL_PARAM_get_BN(params, bn);
+err:
+ OPENSSL_free(buf);
+ return ret;
+}
+
+int EVP_PKEY_get_octet_string_param(EVP_PKEY *pkey, const char *key_name,
+ unsigned char *buf, size_t max_buf_sz,
+ size_t *out_sz)
+{
+ OSSL_PARAM params[2];
+ const size_t not_set = max_buf_sz + 1;
+
+ if (pkey == NULL
+ || pkey->keymgmt == NULL
+ || pkey->keydata == NULL
+ || key_name == NULL)
+ return 0;
+
+ params[0] = OSSL_PARAM_construct_octet_string(key_name, buf, max_buf_sz);
+ params[0].return_size = not_set;
+ params[1] = OSSL_PARAM_construct_end();
+ if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+ return 0;
+ if (params[0].return_size == not_set)
+ return 0;
+ if (out_sz != NULL)
+ *out_sz = params[0].return_size;
+ return 1;
+}
+
+int EVP_PKEY_get_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
+ char *str, size_t max_buf_sz,
+ size_t *out_sz)
+{
+ OSSL_PARAM params[2];
+ const size_t not_set = max_buf_sz + 1;
+
+ if (pkey == NULL
+ || pkey->keymgmt == NULL
+ || pkey->keydata == NULL
+ || key_name == NULL)
+ return 0;
+
+ params[0] = OSSL_PARAM_construct_utf8_string(key_name, str, max_buf_sz);
+ params[0].return_size = not_set;
+ params[1] = OSSL_PARAM_construct_end();
+ if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+ return 0;
+ if (params[0].return_size == not_set)
+ return 0;
+ if (out_sz != NULL)
+ *out_sz = params[0].return_size;
+ return 1;
+}
+
+int EVP_PKEY_get_int_param(EVP_PKEY *pkey, const char *key_name, int *out)
+{
+ OSSL_PARAM params[2];
+ const size_t not_set = sizeof(int) + 1;
+
+ if (pkey == NULL
+ || pkey->keymgmt == NULL
+ || pkey->keydata == NULL
+ || key_name == NULL)
+ return 0;
+
+ params[0] = OSSL_PARAM_construct_int(key_name, out);
+ params[0].return_size = not_set;
+ params[1] = OSSL_PARAM_construct_end();
+ if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+ return 0;
+ if (params[0].return_size == not_set)
+ return 0;
+ return 1;
+}
+
+int EVP_PKEY_get_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t *out)
+{
+ OSSL_PARAM params[2];
+ const size_t not_set = sizeof(size_t) + 1;
+
+ if (pkey == NULL
+ || pkey->keymgmt == NULL
+ || pkey->keydata == NULL
+ || key_name == NULL)
+ return 0;
+
+ params[0] = OSSL_PARAM_construct_size_t(key_name, out);
+ params[0].return_size = not_set;
+ params[1] = OSSL_PARAM_construct_end();
+ if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params))
+ return 0;
+ if (params[0].return_size == not_set)
+ return 0;
+ return 1;
+}
diff --git a/crypto/param_build_set.c b/crypto/param_build_set.c
new file mode 100644
index 0000000000..b74b0d59ee
--- /dev/null
+++ b/crypto/param_build_set.c
@@ -0,0 +1,111 @@
+/*
+ * 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
+ */
+
+/*
+ * Key Management utility functions to share functionality between the export()
+ * and get_params() methods.
+ * export() uses OSSL_PARAM_BLD, and get_params() used the OSSL_PARAM[] to
+ * fill in parameter data for the same key and data fields.
+ */
+
+#include <openssl/core_names.h>
+#include "internal/param_build_set.h"
+
+DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
+
+int ossl_param_build_set_int(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *key, int num)
+{
+ if (bld != NULL)
+ return OSSL_PARAM_BLD_push_int(bld, key, num);
+ p = OSSL_PARAM_locate(p, key);
+ if (p != NULL)
+ return OSSL_PARAM_set_int(p, num);
+ return 1;
+}
+
+int ossl_param_build_set_utf8_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *key, const char *buf)
+{
+ if (bld != NULL)
+ return OSSL_PARAM_BLD_push_utf8_string(bld, key, buf, 0);
+ p = OSSL_PARAM_locate(p, key);
+ if (p != NULL)
+ return OSSL_PARAM_set_utf8_string(p, buf);
+ return 1;
+}
+
+int ossl_param_build_set_octet_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *key,
+ const unsigned char *data,
+ size_t data_len)
+{
+ if (bld != NULL)
+ return OSSL_PARAM_BLD_push_octet_string(bld, key, data, data_len);
+
+ p = OSSL_PARAM_locate(p, key);
+ if (p != NULL)
+ return OSSL_PARAM_set_octet_string(p, data, data_len);
+ return 1;
+}
+
+int ossl_param_build_set_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *key, const BIGNUM *bn, size_t sz)
+{
+ if (bld != NULL)
+ return OSSL_PARAM_BLD_push_BN_pad(bld, key, bn, sz);
+ p = OSSL_PARAM_locate(p, key);
+ if (p != NULL) {
+ if (sz > p->data_size)
+ return 0;
+ /* TODO(3.0) Change to use OSSL_PARAM_set_BN_pad */
+ p->data_size = sz;
+ return OSSL_PARAM_set_BN(p, bn);
+ }
+ return 1;
+}
+
+int ossl_param_build_set_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *key, const BIGNUM *bn)
+{
+ if (bld != NULL)
+ return OSSL_PARAM_BLD_push_BN(bld, key, bn);
+
+ p = OSSL_PARAM_locate(p, key);
+ if (p != NULL)
+ return OSSL_PARAM_set_BN(p, bn) > 0;
+ return 1;
+}
+
+int ossl_param_build_set_multi_key_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *params,
+ const char *names[],
+ STACK_OF(BIGNUM_const) *stk)
+{
+ int i, sz = sk_BIGNUM_const_num(stk);
+ OSSL_PARAM *p;
+
+
+ if (bld != NULL) {
+ for (i = 0; i < sz && names[i] != NULL; ++i) {
+ if (!OSSL_PARAM_BLD_push_BN(bld, names[i],
+ sk_BIGNUM_const_value(stk, i)))
+ return 0;
+ }
+ return 1;
+ }
+
+ for (i = 0; i < sz && names[i] != NULL; ++i) {
+ p = OSSL_PARAM_locate(params, names[i]);
+ if (p != NULL) {
+ if (!OSSL_PARAM_set_BN(p, sk_BIGNUM_const_value(stk, i)))
+ return 0;
+ }
+ }
+ return 1;
+}
diff --git a/crypto/rsa/build.info b/crypto/rsa/build.info
index c1d1a3769b..7921202739 100644
--- a/crypto/rsa/build.info
+++ b/crypto/rsa/build.info
@@ -2,7 +2,8 @@ LIBS=../../libcrypto
$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 rsa_backend.c
+ rsa_x931g.c rsa_sp800_56b_gen.c rsa_sp800_56b_check.c rsa_backend.c \
+ rsa_mp_names.c
SOURCE[../../libcrypto]=$COMMON\
rsa_saos.c rsa_err.c rsa_asn1.c rsa_depr.c rsa_ameth.c rsa_prn.c \
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
index ec8df4a718..fb378ae039 100644
--- a/crypto/rsa/rsa_ameth.c
+++ b/crypto/rsa/rsa_ameth.c
@@ -20,7 +20,7 @@
#include <openssl/bn.h>
#include <openssl/cms.h>
#include <openssl/core_names.h>
-#include "openssl/param_build.h"
+#include <openssl/param_build.h>
#include "crypto/asn1.h"
#include "crypto/evp.h"
#include "crypto/rsa.h"
@@ -1142,27 +1142,24 @@ static int rsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata,
goto err;
selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
- for (i = 0; i < numprimes; i++) {
+ for (i = 0; i < numprimes && rsa_mp_factor_names[i] != NULL; i++) {
const BIGNUM *num = sk_BIGNUM_const_value(primes, i);
- if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_FACTOR,
- num))
+ if (!OSSL_PARAM_BLD_push_BN(tmpl, rsa_mp_factor_names[i], num))
goto err;
}
- for (i = 0; i < numexps; i++) {
+ for (i = 0; i < numexps && rsa_mp_exp_names[i] != NULL; i++) {
const BIGNUM *num = sk_BIGNUM_const_value(exps, i);
- if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_EXPONENT,
- num))
+ if (!OSSL_PARAM_BLD_push_BN(tmpl, rsa_mp_exp_names[i], num))
goto err;
}
- for (i = 0; i < numcoeffs; i++) {
+ for (i = 0; i < numcoeffs && rsa_mp_coeff_names[i] != NULL; i++) {
const BIGNUM *num = sk_BIGNUM_const_value(coeffs, i);
- if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_COEFFICIENT,
- num))
+ if (!OSSL_PARAM_BLD_push_BN(tmpl, rsa_mp_coeff_names[i], num))
goto err;
}
}
diff --git a/crypto/rsa/rsa_backend.c b/crypto/rsa/rsa_backend.c
index f68d38cc1a..57a539c051 100644
--- a/crypto/rsa/rsa_backend.c
+++ b/crypto/rsa/rsa_backend.c
@@ -20,19 +20,23 @@
DEFINE_STACK_OF(BIGNUM)
static int collect_numbers(STACK_OF(BIGNUM) *numbers,
- const OSSL_PARAM params[], const char *key)
+ const OSSL_PARAM params[], const char *names[])
{
const OSSL_PARAM *p = NULL;
+ int i;
if (numbers == NULL)
return 0;
- for (p = params; (p = OSSL_PARAM_locate_const(p, key)) != NULL; p++) {
- BIGNUM *tmp = NULL;
+ for (i = 0; names[i] != NULL; i++){
+ p = OSSL_PARAM_locate_const(params, names[i]);
+ if (p != NULL) {
+ BIGNUM *tmp = NULL;
- if (!OSSL_PARAM_get_BN(p, &tmp)
- || sk_BIGNUM_push(numbers, tmp) == 0)
- return 0;
+ if (!OSSL_PARAM_get_BN(p, &tmp)
+ || sk_BIGNUM_push(numbers, tmp) == 0)
+ return 0;
+ }
}
return 1;
@@ -65,11 +69,11 @@ int rsa_fromdata(RSA *rsa, const OSSL_PARAM params[])
if (is_private) {
if (!collect_numbers(factors = sk_BIGNUM_new_null(), params,
- OSSL_PKEY_PARAM_RSA_FACTOR)
+ rsa_mp_factor_names)
|| !collect_numbers(exps = sk_BIGNUM_new_null(), params,
- OSSL_PKEY_PARAM_RSA_EXPONENT)
+ rsa_mp_exp_names)
|| !collect_numbers(coeffs = sk_BIGNUM_new_null(), params,
- OSSL_PKEY_PARAM_RSA_COEFFICIENT))
+ rsa_mp_coeff_names))
goto err;
/* It's ok if this private key just has n, e and d */
diff --git a/crypto/rsa/rsa_mp_names.c b/crypto/rsa/rsa_mp_names.c
new file mode 100644
index 0000000000..e69321a4b7
--- /dev/null
+++ b/crypto/rsa/rsa_mp_names.c
@@ -0,0 +1,76 @@
+/*
+ * 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 <openssl/core_names.h>
+#include "crypto/rsa.h"
+
+/*
+ * The following tables are constants used during RSA parameter building
+ * operations. It is easier to point to one of these fixed strings than have
+ * to dynamically add and generate the names on the fly.
+ */
+
+/*
+ * A fixed table of names for the RSA prime factors starting with
+ * P,Q and up to 8 additional primes.
+ */
+const char *rsa_mp_factor_names[] = {
+ OSSL_PKEY_PARAM_RSA_FACTOR1,
+ OSSL_PKEY_PARAM_RSA_FACTOR2,
+#ifndef FIPS_MODE
+ OSSL_PKEY_PARAM_RSA_FACTOR3,
+ OSSL_PKEY_PARAM_RSA_FACTOR4,
+ OSSL_PKEY_PARAM_RSA_FACTOR5,
+ OSSL_PKEY_PARAM_RSA_FACTOR6,
+ OSSL_PKEY_PARAM_RSA_FACTOR7,
+ OSSL_PKEY_PARAM_RSA_FACTOR8,
+ OSSL_PKEY_PARAM_RSA_FACTOR9,
+ OSSL_PKEY_PARAM_RSA_FACTOR10,
+#endif
+ NULL
+};
+
+/*
+ * A fixed table of names for the RSA exponents starting with
+ * DP,DQ and up to 8 additional exponents.
+ */
+const char *rsa_mp_exp_names[] = {
+ OSSL_PKEY_PARAM_RSA_EXPONENT1,
+ OSSL_PKEY_PARAM_RSA_EXPONENT2,
+#ifndef FIPS_MODE
+ OSSL_PKEY_PARAM_RSA_EXPONENT3,
+ OSSL_PKEY_PARAM_RSA_EXPONENT4,
+ OSSL_PKEY_PARAM_RSA_EXPONENT5,
+ OSSL_PKEY_PARAM_RSA_EXPONENT6,
+ OSSL_PKEY_PARAM_RSA_EXPONENT7,
+ OSSL_PKEY_PARAM_RSA_EXPONENT8,
+ OSSL_PKEY_PARAM_RSA_EXPONENT9,
+ OSSL_PKEY_PARAM_RSA_EXPONENT10,
+#endif
+ NULL
+};
+
+/*
+ * A fixed table of names for the RSA coefficients starting with
+ * QINV and up to 8 additional exponents.
+ */
+const char *rsa_mp_coeff_names[] = {
+ OSSL_PKEY_PARAM_RSA_COEFFICIENT1,
+ OSSL_PKEY_PARAM_RSA_COEFFICIENT2,
+#ifndef FIPS_MODE
+ OSSL_PKEY_PARAM_RSA_COEFFICIENT3,
+ OSSL_PKEY_PARAM_RSA_COEFFICIENT4,
+ OSSL_PKEY_PARAM_RSA_COEFFICIENT5,
+ OSSL_PKEY_PARAM_RSA_COEFFICIENT6,
+ OSSL_PKEY_PARAM_RSA_COEFFICIENT7,
+ OSSL_PKEY_PARAM_RSA_COEFFICIENT8,
+ OSSL_PKEY_PARAM_RSA_COEFFICIENT9,
+#endif
+ NULL
+};
diff --git a/doc/man3/EVP_PKEY_fromdata.pod b/doc/man3/EVP_PKEY_fromdata.pod
index 2d0059d32f..e3ddf68058 100644
--- a/doc/man3/EVP_PKEY_fromdata.pod
+++ b/doc/man3/EVP_PKEY_fromdata.pod
@@ -52,7 +52,7 @@ not supported by the public key algorithm.
=head1 SEE ALSO
-L<EVP_PKEY_CTX_new(3)>, L<provider(7)>
+L<EVP_PKEY_CTX_new(3)>, L<provider(7)>, L<EVP_PKEY_gettable_params(3)>
=head1 HISTORY
diff --git a/doc/man3/EVP_PKEY_gettable_params.pod b/doc/man3/EVP_PKEY_gettable_params.pod
new file mode 100644
index 0000000000..87d25c7b99
--- /dev/null
+++ b/doc/man3/EVP_PKEY_gettable_params.pod
@@ -0,0 +1,108 @@
+=pod
+
+=head1 NAME
+
+EVP_PKEY_gettable_params, EVP_PKEY_get_int_param, EVP_PKEY_get_size_t_param,
+EVP_PKEY_get_bn_param, EVP_PKEY_get_utf8_string_param,
+EVP_PKEY_get_octet_string_param
+- retrieve key parameters from a key
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *pkey);
+ int EVP_PKEY_get_int_param(EVP_PKEY *pkey, const char *key_name, int *out);
+ int EVP_PKEY_get_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t *out);
+ int EVP_PKEY_get_bn_param(EVP_PKEY *pkey, const char *key_name, BIGNUM **bn);
+ int EVP_PKEY_get_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
+ char *str, size_t max_buf_sz, size_t *out_sz);
+ int EVP_PKEY_get_octet_string_param(EVP_PKEY *pkey, const char *key_name,
+ unsigned char *buf, size_t max_buf_sz,
+ size_t *out_sz);
+
+=head1 DESCRIPTION
+
+EVP_PKEY_gettable_params() returns a constant list of I<params> indicating
+the names and types of key parameters that can be retrieved.
+See L<OSSL_PARAM(3)> for information about parameters.
+
+EVP_PKEY_get_int_param() retrieves a key I<pkey> integer value I<*out>
+associated with a name of I<key_name>.
+
+EVP_PKEY_get_size_t_param() retrieves a key I<pkey> size_t value I<*out>
+associated with a name of I<key_name>.
+
+EVP_PKEY_get_bn_param() retrieves a key I<pkey> BIGNUM value I<**bn>
+associated with a name of I<key_name>. If I<*bn> is NULL then the BIGNUM
+is allocated by the method.
+
+EVP_PKEY_get_utf8_string_param() get a key I<pkey> UTF8 string value int a buffer
+I<str> of maximum size I<max_buf_sz> associated with a name of I<key_name>.
+I<*out_sz> is the returned size of the string if it is not NULL.
+
+EVP_PKEY_get_octet_string_param() copy a I<pkey>'s octet string value into a buffer
+I<buf> of maximum size I<max_buf_sz> associated with a name of I<key_name>.
+I<*out_sz> is the returned size of the buffer if it is not NULL.
+
+=head1 NOTES
+
+These functions only work for B<EVP_PKEY>s that contain a provider side key.
+
+=head1 RETURN VALUES
+
+EVP_PKEY_gettable_params() returns NULL on error or if it is not supported,
+
+All other methods return 1 if a value associated with the key's I<key_name> was
+successfully returned, or 0 if there was an error.
+An error may be returned by methods EVP_PKEY_get_utf8_string_param() and
+EVP_PKEY_get_octet_string_param() if I<max_buf_sz> is not big enough to hold the
+value.
+
+=head1 EXAMPLES
+
+ #include <openssl/evp.h>
+
+ char *curve_name[64];
+ unsigned char pub[256];
+ BIGNUM *bn_priv = NULL;
+
+ /*
+ * NB: assumes 'key' is set up before the next step. In this example the key
+ * is an EC key.
+ */
+
+ if (!EVP_PKEY_get_utf8_string_param(key, OSSL_PKEY_PARAM_EC_NAME,
+ curve_name, sizeof(curve_name), &len)) {
+ /* Error */
+ }
+ if (!EVP_PKEY_get_octet_string_param(key, OSSL_PKEY_PARAM_PUB_KEY,
+ pub, sizeof(pub), &len)) {
+ /* Error */
+ }
+ if (!EVP_PKEY_get_bn_param(key, OSSL_PKEY_PARAM_PRIV_KEY, &bn_priv)) {
+ /* Error */
+ }
+
+
+ BN_clear_free(bn_priv);
+
+=head1 SEE ALSO
+
+L<EVP_PKEY_CTX_new(3)>, L<provider-keymgmt(7)>, L<OSSL_PARAM(3)>
+
+=head1 HISTORY
+
+These functions were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
+
diff --git a/doc/man7/provider-keymgmt.pod b/doc/man7/provider-keymgmt.pod
index 59e538dbac..00596a0a4b 100644
--- a/doc/man7/provider-keymgmt.pod
+++ b/doc/man7/provider-keymgmt.pod
@@ -334,20 +334,74 @@ The RSA "e" value.
The RSA "d" value.
-=item "rsa-factor" (B<OSSL_PKEY_PARAM_RSA_FACTOR>) <unsigned integer>
+=item "rsa-factor1" (B<OSSL_PKEY_PARAM_RSA_FACTOR1>) <unsigned integer>
-An RSA factor. In 2 prime RSA these are often known as "p" or "q". This value
-may be repeated up to 10 times in a single key.
+=item "rsa-factor2" (B<OSSL_PKEY_PARAM_RSA_FACTOR2>) <unsigned integer>
-=item "rsa-exponent" (B<OSSL_PKEY_PARAM_RSA_EXPONENT>) <unsigned integer>
+=item "rsa-factor3" (B<OSSL_PKEY_PARAM_RSA_FACTOR3>) <unsigned integer>
-An RSA CRT (Chinese Remainder Theorem) exponent. This value may be repeated up
-to 10 times in a single key.
+=item "rsa-factor4" (B<OSSL_PKEY_PARAM_RSA_FACTOR4>) <unsigned integer>
-=item "rsa-coefficient" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT>) <unsigned integer>
+=item "rsa-factor5" (B<OSSL_PKEY_PARAM_RSA_FACTOR5>) <unsigned integer>
-An RSA CRT (Chinese Remainder Theorem) coefficient. This value may be repeated
-up to 9 times in a single key.
+=item "rsa-factor6" (B<OSSL_PKEY_PARAM_RSA_FACTOR6>) <unsigned integer>
+
+=item "rsa-factor7" (B<OSSL_PKEY_PARAM_RSA_FACTOR7>) <unsigned integer>
+
+=item "rsa-factor8" (B<OSSL_PKEY_PARAM_RSA_FACTOR8>) <unsigned integer>
+
+=item "rsa-factor9" (B<OSSL_PKEY_PARAM_RSA_FACTOR9>) <unsigned integer>
+
+=item "rsa-factor10" (B<OSSL_PKEY_PARAM_RSA_FACTOR10>) <unsigned integer>
+
+RSA prime factors. The factors are known as "p", "q" and "r_i" in RFC8017.
+Up to eight additional "r_i" prime factors are supported.
+
+=item "rsa-exponent1" (B<OSSL_PKEY_PARAM_RSA_EXPONENT1>) <unsigned integer>
+
+=item "rsa-exponent2" (B<OSSL_PKEY_PARAM_RSA_EXPONENT2>) <unsigned integer>
+
+=item "rsa-exponent3" (B<OSSL_PKEY_PARAM_RSA_EXPONENT3>) <unsigned integer>
+
+=item "rsa-exponent4" (B<OSSL_PKEY_PARAM_RSA_EXPONENT4>) <unsigned integer>
+
+=item "rsa-exponent5" (B<OSSL_PKEY_PARAM_RSA_EXPONENT5>) <unsigned integer>
+
+=item "rsa-exponent6" (B<OSSL_PKEY_PARAM_RSA_EXPONENT6>) <unsigned integer>
+
+=item "rsa-exponent7" (B<OSSL_PKEY_PARAM_RSA_EXPONENT7>) <unsigned integer>
+
+=item "rsa-exponent8" (B<OSSL_PKEY_PARAM_RSA_EXPONENT8>) <unsigned integer>
+
+=item "rsa-exponent9" (B<OSSL_PKEY_PARAM_RSA_EXPONENT9>) <unsigned integer>
+
+=item "rsa-exponent10" (B<OSSL_PKEY_PARAM_RSA_EXPONENT10>) <unsigned integer>
+
+RSA CRT (Chinese Remainder Theorem) exponents. The exponents are known
+as "dP", "dQ" and "d_i in RFC8017".
+Up to eight additional "d_i" exponents are supported.
+
+=item "rsa-coefficient1" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT1>) <unsigned integer>
+
+=item "rsa-coefficient2" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT2>) <unsigned integer>
+
+=item "rsa-coefficient3" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT3>) <unsigned integer>
+
+=item "rsa-coefficient4" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT4>) <unsigned integer>
+
+=item "rsa-coefficient5" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT5>) <unsigned integer>
+
+=item "rsa-coefficient6" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT6>) <unsigned integer>
+
+=item "rsa-coefficient7" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT7>) <unsigned integer>
+
+=item "rsa-coefficient8" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT8>) <unsigned integer>
+
+=item "rsa-coefficient9" (B<OSSL_PKEY_PARAM_RSA_COEFFICIENT9>) <unsigned integer>
+
+RSA CRT (Chinese Remainder Theorem) coefficients. The coefficients are known as
+"qInv" and "t_i".
+Up to eight additional "t_i" exponents are supported.
=back
@@ -427,11 +481,13 @@ The private key value.
See L<OSSL_PARAM(3)> for further details on the parameters structure.
-Parameters currently recognised by built-in keymgmt algorithms
-are as follows.
+The Built-in Import/Export Types listed above are also Information Parameters.
Not all parameters are relevant to, or are understood by all keymgmt
algorithms:
+Parameters currently recognised by built-in keymgmt algorithms
+also include the following.
+
=over 4
=item "bits" (B<OSSL_PKEY_PARAM_BITS>) <integer>
diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h
index a92e666a3d..3a85510be0 100644
--- a/include/crypto/rsa.h
+++ b/include/crypto/rsa.h
@@ -40,4 +40,8 @@ int int_rsa_verify(int dtype, const unsigned char *m,
const unsigned char *rsa_digestinfo_encoding(int md_nid, size_t *len);
const unsigned char *rsa_algorithmidentifier_encoding(int md_nid, size_t *len);
+extern const char *rsa_mp_factor_names[];
+extern const char *rsa_mp_exp_names[];
+extern const char *rsa_mp_coeff_names[];
+
#endif
diff --git a/include/internal/param_build_set.h b/include/internal/param_build_set.h
new file mode 100644
index 0000000000..36d3b914d9
--- /dev/null
+++ b/include/internal/param_build_set.h
@@ -0,0 +1,27 @@
+/*
+ * 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 <openssl/safestack.h>
+#include <openssl/param_build.h>
+
+int ossl_param_build_set_int(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *key, int num);
+int ossl_param_build_set_utf8_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *key, const char *buf);
+int ossl_param_build_set_octet_string(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *key,
+ const unsigned char *data,
+ size_t data_len);
+int ossl_param_build_set_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *key, const BIGNUM *bn);
+int ossl_param_build_set_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *key, const BIGNUM *bn, size_t sz);
+int ossl_param_build_set_multi_key_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p,
+ const char *names[],
+ STACK_OF(BIGNUM_const) *stk);
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 2d48f00da2..c8a88285d8 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -220,6 +220,37 @@ extern "C" {
#define OSSL_PKEY_PARAM_RSA_FACTOR "rsa-factor"
#define OSSL_PKEY_PARAM_RSA_EXPONENT "rsa-exponent"
#define OSSL_PKEY_PARAM_RSA_COEFFICIENT "rsa-coefficient"
+#define OSSL_PKEY_PARAM_RSA_FACTOR1 OSSL_PKEY_PARAM_RSA_FACTOR"1"
+#define OSSL_PKEY_PARAM_RSA_FACTOR2 OSSL_PKEY_PARAM_RSA_FACTOR"2"
+#define OSSL_PKEY_PARAM_RSA_FACTOR3 OSSL_PKEY_PARAM_RSA_FACTOR"3"
+#define OSSL_PKEY_PARAM_RSA_FACTOR4 OSSL_PKEY_PARAM_RSA_FACTOR"4"
+#define OSSL_PKEY_PARAM_RSA_FACTOR5 OSSL_PKEY_PARAM_RSA_FACTOR"5"
+#define OSSL_PKEY_PARAM_RSA_FACTOR6 OSSL_PKEY_PARAM_RSA_FACTOR"6"
+#define OSSL_PKEY_PARAM_RSA_FACTOR7 OSSL_PKEY_PARAM_RSA_FACTOR"7"
+#define OSSL_PKEY_PARAM_RSA_FACTOR8 OSSL_PKEY_PARAM_RSA_FACTOR"8"
+#define OSSL_PKEY_PARAM_RSA_FACTOR9 OSSL_PKEY_PARAM_RSA_FACTOR"9"
+#define OSSL_PKEY_PARAM_RSA_FACTOR10 OSSL_PKEY_PARAM_RSA_FACTOR"10"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT1 OSSL_PKEY_PARAM_RSA_EXPONENT"1"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT2 OSSL_PKEY_PARAM_RSA_EXPONENT"2"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT3 OSSL_PKEY_PARAM_RSA_EXPONENT"3"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT4 OSSL_PKEY_PARAM_RSA_EXPONENT"4"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT5 OSSL_PKEY_PARAM_RSA_EXPONENT"5"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT6 OSSL_PKEY_PARAM_RSA_EXPONENT"6"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT7 OSSL_PKEY_PARAM_RSA_EXPONENT"7"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT8 OSSL_PKEY_PARAM_RSA_EXPONENT"8"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT9 OSSL_PKEY_PARAM_RSA_EXPONENT"9"
+#define OSSL_PKEY_PARAM_RSA_EXPONENT10 OSSL_PKEY_PARAM_RSA_EXPONENT"10"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT1 OSSL_PKEY_PARAM_RSA_COEFFICIENT"1"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT2 OSSL_PKEY_PARAM_RSA_COEFFICIENT"2"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT3 OSSL_PKEY_PARAM_RSA_COEFFICIENT"3"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT4 OSSL_PKEY_PARAM_RSA_COEFFICIENT"4"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT5 OSSL_PKEY_PARAM_RSA_COEFFICIENT"5"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT6 OSSL_PKEY_PARAM_RSA_COEFFICIENT"6"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT7 OSSL_PKEY_PARAM_RSA_COEFFICIENT"7"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT8 OSSL_PKEY_PARAM_RSA_COEFFICIENT"8"
+#define OSSL_PKEY_PARAM_RSA_COEFFICIENT9 OSSL_PKEY_PARAM_RSA_COEFFICIENT"9"
+
+
/* Key generation parameters */
#define OSSL_PKEY_PARAM_RSA_BITS OSSL_PKEY_PARAM_BITS
#define OSSL_PKEY_PARAM_RSA_PRIMES "primes"
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index d461f24999..4903fc5f42 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1593,6 +1593,16 @@ int EVP_PKEY_key_fromdata_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_fromdata(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey, OSSL_PARAM param[]);
const OSSL_PARAM *EVP_PKEY_param_fromdata_settable(EVP_PKEY_CTX *ctx);
const OSSL_PARAM *EVP_PKEY_key_fromdata_settable(EVP_PKEY_CTX *ctx);
+const OSSL_PARAM *EVP_PKEY_gettable_params(EVP_PKEY *pkey);
+int EVP_PKEY_get_int_param(EVP_PKEY *pkey, const char *key_name, int *out);
+int EVP_PKEY_get_size_t_param(EVP_PKEY *pkey, const char *key_name, size_t *out);
+int EVP_PKEY_get_bn_param(EVP_PKEY *pkey, const char *key_name, BIGNUM **bn);
+int EVP_PKEY_get_utf8_string_param(EVP_PKEY *pkey, const char *key_name,
+ char *str, size_t max_buf_sz, size_t *out_sz);
+int EVP_PKEY_get_octet_string_param(EVP_PKEY *pkey, const char *key_name,
+ unsigned char *buf, size_t max_buf_sz,
+ size_t *out_sz);
+
int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx);
int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey);
int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx);
diff --git a/providers/implementations/keymgmt/build.info b/providers/implementations/keymgmt/build.info
index 89d33e32f0..92cac52e11 100644
--- a/providers/implementations/keymgmt/build.info
+++ b/providers/implementations/keymgmt/build.info
@@ -4,7 +4,6 @@
$DH_GOAL=../../libimplementations.a
$DSA_GOAL=../../libimplementations.a
$EC_GOAL=../../libimplementations.a
-$RSA_GOAL=../../libimplementations.a
$ECX_GOAL=../../libimplementations.a
IF[{- !$disabled{dh} -}]
@@ -16,7 +15,9 @@ ENDIF
IF[{- !$disabled{ec} -}]
SOURCE[$EC_GOAL]=ec_kmgmt.c
ENDIF
-SOURCE[$RSA_GOAL]=rsa_kmgmt.c
IF[{- !$disabled{ec} -}]
SOURCE[$ECX_GOAL]=ecx_kmgmt.c
ENDIF
+
+SOURCE[../../libfips.a]=rsa_kmgmt.c
+SOURCE[../../libnonfips.a]=rsa_kmgmt.c
diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c
index 82ef3d3a67..77d4753723 100644
--- a/providers/implementations/keymgmt/ec_kmgmt.c
+++ b/providers/implementations/keymgmt/ec_kmgmt.c
@@ -17,13 +17,12 @@
#include <openssl/core_names.h>
#include <openssl/bn.h>
#include <openssl/objects.h>
-#include <openssl/params.h>
#include "crypto/bn.h"
#include "crypto/ec.h"
-#include "openssl/param_build.h"
#include "prov/implementations.h"
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
+#include "internal/param_build_set.h"
static OSSL_OP_keymgmt_new_fn ec_newdata;
static OSSL_OP_keymgmt_free_fn ec_freedata;
@@ -40,8 +39,8 @@ static OSSL_OP_keymgmt_export_fn ec_export;
static OSSL_OP_keymgmt_export_types_fn ec_export_types;
static OSSL_OP_keymgmt_query_operation_name_fn ec_query_operation_name;
-#define EC_POSSIBLE_SELECTIONS \
- (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS )
+#define EC_POSSIBLE_SELECTIONS \
+ (OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS)
static
const char *ec_query_operation_name(int operation_id)
@@ -56,7 +55,8 @@ const char *ec_query_operation_name(int operation_id)
}
static ossl_inline
-int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
+int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
+ OSSL_PARAM params[])
{
const EC_GROUP *ecg;
int curve_nid;
@@ -71,11 +71,7 @@ int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
curve_nid = EC_GROUP_get_curve_name(ecg);
if (curve_nid == NID_undef) {
- /* explicit parameters */
-
- /*
- * TODO(3.0): should we support explicit parameters curves?
- */
+ /* TODO(3.0): should we support explicit parameters curves? */
return 0;
} else {
/* named curve */
@@ -83,9 +79,10 @@ int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
if ((curve_name = ec_curve_nid2name(curve_nid)) == NULL)
return 0;
+ if (!ossl_param_build_set_utf8_string(tmpl, params,
+ OSSL_PKEY_PARAM_EC_NAME,
+ curve_name))
- if (!OSSL_PARAM_BLD_push_utf8_string(tmpl, OSSL_PKEY_PARAM_EC_NAME,
- curve_name, 0))
return 0;
}
@@ -100,12 +97,13 @@ int domparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
* parameters are exported separately.
*/
static ossl_inline
-int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, int include_private)
+int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl,
+ OSSL_PARAM params[], int include_private,
+ unsigned char **pub_key)
{
const BIGNUM *priv_key = NULL;
const EC_POINT *pub_point = NULL;
const EC_GROUP *ecg = NULL;
- unsigned char *pub_key = NULL;
size_t pub_key_len = 0;
int ret = 0;
@@ -120,10 +118,10 @@ int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, int include_private
/* convert pub_point to a octet string according to the SECG standard */
if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
POINT_CONVERSION_COMPRESSED,
- &pub_key, NULL)) == 0
- || !OSSL_PARAM_BLD_push_octet_string(tmpl,
- OSSL_PKEY_PARAM_PUB_KEY,
- pub_key, pub_key_len))
+ pub_key, NULL)) == 0
+ || !ossl_param_build_set_octet_string(tmpl, params,
+ OSSL_PKEY_PARAM_PUB_KEY,
+ *pub_key, pub_key_len))
goto err;
}
@@ -168,21 +166,20 @@ int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, int include_private
if (ecbits <= 0)
goto err;
sz = (ecbits + 7 ) / 8;
- if (!OSSL_PARAM_BLD_push_BN_pad(tmpl,
- OSSL_PKEY_PARAM_PRIV_KEY,
- priv_key, sz))
+
+ if (!ossl_param_build_set_bn_pad(tmpl, params,
+ OSSL_PKEY_PARAM_PRIV_KEY,
+ priv_key, sz))
goto err;
}
-
ret = 1;
-
err:
- OPENSSL_free(pub_key);
return ret;
}
static ossl_inline
-int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
+int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl,
+ OSSL_PARAM params[])
{
int ecdh_cofactor_mode = 0;
@@ -191,12 +188,9 @@ int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl)
ecdh_cofactor_mode =
(EC_KEY_get_flags(ec) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0;
- if (!OSSL_PARAM_BLD_push_int(tmpl,
- OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
- ecdh_cofactor_mode))
- return 0;
-
- return 1;
+ return ossl_param_build_set_int(tmpl, params,
+ OSSL_PKEY_PARAM_USE_COFACTOR_ECDH,
+ ecdh_cofactor_mode);
}
static
@@ -314,6 +308,7 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
EC_KEY *ec = keydata;
OSSL_PARAM_BLD *tmpl;
OSSL_PARAM *params = NULL;
+ unsigned char *pub_key = NULL;
int ok = 1;
if (ec == NULL)
@@ -346,15 +341,16 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
return 0;
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
- ok = ok && domparams_to_params(ec, tmpl);
+ ok = ok && domparams_to_params(ec, tmpl, NULL);
+
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
int include_private =
selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
- ok = ok && key_to_params(ec, tmpl, include_private);
+ ok = ok && key_to_params(ec, tmpl, NULL, include_private, &pub_key);
}
if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0)
- ok = ok && otherparams_to_params(ec, tmpl);
+ ok = ok && otherparams_to_params(ec, tmpl, NULL);
if (!ok
|| (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
@@ -364,6 +360,7 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
OSSL_PARAM_BLD_free_params(params);
err:
OSSL_PARAM_BLD_free(tmpl);
+ OPENSSL_free(pub_key);
return ok;
}
@@ -423,9 +420,11 @@ const OSSL_PARAM *ec_export_types(int selection)
static
int ec_get_params(void *key, OSSL_PARAM params[])
{
+ int ret;
EC_KEY *eck = key;
const EC_GROUP *ecg = NULL;
OSSL_PARAM *p;
+ unsigned char *pub_key = NULL;
ecg = EC_KEY_get0_group(eck);
if (ecg == NULL)
@@ -485,15 +484,21 @@ int ec_get_params(void *key, OSSL_PARAM params[])
if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode))
return 0;
}
-
- return 1;
+ ret = domparams_to_params(eck, NULL, params)
+ && key_to_params(eck, NULL, params, 1, &pub_key)
+ && otherparams_to_params(eck, NULL, params);
+ OPENSSL_free(pub_key);
+ return ret;
}
static const OSSL_PARAM ec_known_gettable_params[] = {
OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
- OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),
+ EC_IMEXPORTABLE_DOM_PARAMETERS,
+ EC_IMEXPORTABLE_PUBLIC_KEY,
+ EC_IMEXPORTABLE_PRIVATE_KEY,
+ EC_IMEXPORTABLE_OTHER_PARAMETERS,
OSSL_PARAM_END
};
diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c
index be11f0b85e..ca53a93f5e 100644
--- a/providers/implementations/keymgmt/ecx_kmgmt.c
+++ b/providers/implementations/keymgmt/ecx_kmgmt.c
@@ -10,11 +10,10 @@
#include <assert.h>
#include <openssl/core_numbers.h>
#include <openssl/core_names.h>
-#include <openssl/params.h>
-#include "openssl/param_build.h"
#include "crypto/ecx.h"
#include "prov/implementations.h"
#include "prov/providercommon.h"
+#include "internal/param_build_set.h"
static OSSL_OP_keymgmt_new_fn x25519_new_key;
static OSSL_OP_keymgmt_new_fn x448_new_key;
@@ -90,18 +89,21 @@ static int ecx_import(void *keydata, int selection, const OSSL_PARAM params[])
return ok;
}
-static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl)
+static int key_to_params(ECX_KEY *key, OSSL_PARAM_BLD *tmpl,
+ OSSL_PARAM params[])
{
if (key == NULL)
return 0;
- if (!OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PUB_KEY,
- key->pubkey, key->keylen))
+ if (!ossl_param_build_set_octet_string(tmpl, params,
+ OSSL_PKEY_PARAM_PUB_KEY,
+ key->pubkey, key->keylen))
return 0;
if (key->privkey != NULL
- && !OSSL_PARAM_BLD_push_octet_string(tmpl, OSSL_PKEY_PARAM_PRIV_KEY,
- key->privkey, key->keylen))
+ && !ossl_param_build_set_octet_string(tmpl, params,
+ OSSL_PKEY_PARAM_PRIV_KEY,
+ key->privkey, key->keylen))
return 0;
return 1;
@@ -113,7 +115,7 @@ static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
ECX_KEY *key = keydata;
OSSL_PARAM_BLD *tmpl;
OSSL_PARAM *params = NULL;
- int ret;
+ int ret = 0;
if (key == NULL)
return 0;
@@ -123,24 +125,30 @@ static int ecx_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
return 0;
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
- && !key_to_params(key, tmpl)) {
- OSSL_PARAM_BLD_free(tmpl);
- return 0;
- }
+ && !key_to_params(key, tmpl, NULL))
+ goto err;
+
+ if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0
+ && !key_to_params(key, tmpl, NULL))
+ goto err;
params = OSSL_PARAM_BLD_to_param(tmpl);
- OSSL_PARAM_BLD_free(tmpl);
if (params == NULL)
- return 0;
+ goto err;
ret = param_cb(params, cbarg);
OSSL_PARAM_BLD_free_params(params);
+err:
+ OSSL_PARAM_BLD_free(tmpl);
return ret;
}
+#define ECX_KEY_TYPES() \
+OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
+OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
+
static const OSSL_PARAM ecx_key_types[] = {
- OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
- OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+ ECX_KEY_TYPES(),
OSSL_PARAM_END
};
static const OSSL_PARAM *ecx_imexport_types(int selection)
@@ -150,9 +158,10 @@ static const OSSL_PARAM *ecx_imexport_types(int selection)
return NULL;
}
-static int ecx_get_params(OSSL_PARAM params[], int bits, int secbits,
+static int ecx_get_params(void *key, OSSL_PARAM params[], int bits, int secbits,
int size)
{
+ ECX_KEY *ecx = key;
OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
@@ -164,33 +173,38 @@ static int ecx_get_params(OSSL_PARAM params[], int bits, int secbits,
if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
&& !OSSL_PARAM_set_int(p, size))
return 0;
- return 1;
+ return key_to_params(ecx, NULL, params);
}
static int x25519_get_params(void *key, OSSL_PARAM params[])
{
- return ecx_get_params(params, X25519_BITS, X25519_SECURITY_BITS, X25519_KEYLEN);
+ return ecx_get_params(key, params, X25519_BITS, X25519_SECURITY_BITS,
+ X25519_KEYLEN);
}
static int x448_get_params(void *key, OSSL_PARAM params[])
{
- return ecx_get_params(params, X448_BITS, X448_SECURITY_BITS, X448_KEYLEN);
+ return ecx_get_params(key, params, X448_BITS, X448_SECURITY_BITS,
+ X448_KEYLEN);
}
static int ed25519_get_params(void *key, OSSL_PARAM params[])
{
- return ecx_get_params(params, ED25519_BITS, ED25519_SECURITY_BITS, ED25519_KEYLEN);
+ return ecx_get_params(key, params, ED25519_BITS, ED25519_SECURITY_BITS,
+ ED25519_KEYLEN);
}
static int ed448_get_params(void *key, OSSL_PARAM params[])
{
- return ecx_get_params(params, ED448_BITS, ED448_SECURITY_BITS, ED448_KEYLEN);
+ return ecx_get_params(key, params, ED448_BITS, ED448_SECURITY_BITS,
+ ED448_KEYLEN);
}
static const OSSL_PARAM ecx_params[] = {
OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
+ ECX_KEY_TYPES(),
OSSL_PARAM_END
};
diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c
index 50647eb6f5..8ea394115b 100644
--- a/providers/implementations/keymgmt/rsa_kmgmt.c
+++ b/providers/implementations/keymgmt/rsa_kmgmt.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-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
@@ -19,13 +19,11 @@
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
-#include <openssl/params.h>
-#include <openssl/types.h>
-#include "openssl/param_build.h"
#include "prov/implementations.h"
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
#include "crypto/rsa.h"
+#include "internal/param_build_set.h"
static OSSL_OP_keymgmt_new_fn rsa_newdata;
static OSSL_OP_keymgmt_gen_init_fn rsa_gen_init;
@@ -45,32 +43,13 @@ static OSSL_OP_keymgmt_export_fn rsa_export;
static OSSL_OP_keymgmt_export_types_fn rsa_export_types;
#define RSA_DEFAULT_MD "SHA256"
-#define RSA_POSSIBLE_SELECTIONS \
+#define RSA_POSSIBLE_SELECTIONS \
(OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS)
DEFINE_STACK_OF(BIGNUM)
DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
-static int export_numbers(OSSL_PARAM_BLD *tmpl, const char *key,
- STACK_OF(BIGNUM_const) *numbers)
-{
- int i, nnum;
-
- if (numbers == NULL)
- return 0;
-
- nnum = sk_BIGNUM_const_num(numbers);
-
- for (i = 0; i < nnum; i++) {
- if (!OSSL_PARAM_BLD_push_BN(tmpl, key,
- sk_BIGNUM_const_value(numbers, i)))
- return 0;
- }
-
- return 1;
-}
-
-static int key_to_params(RSA *rsa, OSSL_PARAM_BLD *tmpl)
+static int key_to_params(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
{
int ret = 0;
const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL;
@@ -84,21 +63,16 @@ static int key_to_params(RSA *rsa, OSSL_PARAM_BLD *tmpl)
RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
rsa_get0_all_params(rsa, factors, exps, coeffs);
- if (rsa_n != NULL
- && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_N, rsa_n))
- goto err;
- if (rsa_e != NULL
- && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_E, rsa_e))
- goto err;
- if (rsa_d != NULL
- && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_RSA_D, rsa_d))
- goto err;
-
- if (!export_numbers(tmpl, OSSL_PKEY_PARAM_RSA_FACTOR, factors)
- || !export_numbers(tmpl, OSSL_PKEY_PARAM_RSA_EXPONENT, exps)
- || !export_numbers(tmpl, OSSL_PKEY_PARAM_RSA_COEFFICIENT, coeffs))
+ if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_N, rsa_n)
+ || !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_E, rsa_e)
+ || !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_D, rsa_d)
+ || !ossl_param_build_set_multi_key_bn(bld, params, rsa_mp_factor_names,
+ factors)
+ || !ossl_param_build_set_multi_key_bn(bld, params, rsa_mp_exp_names,
+ exps)
+ || !ossl_param_build_set_multi_key_bn(bld, params, rsa_mp_coeff_names,
+ coeffs))
goto err;
-
ret = 1;
err:
sk_BIGNUM_const_free(factors);
@@ -189,20 +163,70 @@ static int rsa_export(void *keydata, int selection,
return 0;
if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
- ok = ok && key_to_params(rsa, tmpl);
+ ok = ok && key_to_params(rsa, tmpl, NULL);
if (!ok
- || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) {
- OSSL_PARAM_BLD_free(tmpl);
- return 0;
- }
- OSSL_PARAM_BLD_free(tmpl);
+ || (params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL)
+ goto err;
ok = param_callback(params, cbarg);
OSSL_PARAM_BLD_free_params(params);
+err:
+ OSSL_PARAM_BLD_free(tmpl);
return ok;
}
+#ifdef FIPS_MODE
+/* In fips mode there are no multi-primes. */
+# define RSA_KEY_MP_TYPES() \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR1, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR2, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT1, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT2, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, NULL, 0),
+#else
+/*
+ * We allow up to 10 prime factors (starting with p, q).
+ * NOTE: there is only 9 OSSL_PKEY_PARAM_RSA_COEFFICIENT
+ */
+# define RSA_KEY_MP_TYPES() \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR1, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR2, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR3, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR4, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR5, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR6, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR7, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR8, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR9, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR10, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT1, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT2, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT3, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT4, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT5, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT6, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT7, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT8, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT9, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT10, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT2, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT3, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT4, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT5, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT6, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT7, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT8, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT9, NULL, 0),
+#endif
+
+#define RSA_KEY_TYPES() \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_N, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, NULL, 0), \
+OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_D, NULL, 0), \
+RSA_KEY_MP_TYPES()
+
/*
* This provider can export everything in an RSA key, so we use the exact
* same type description for export as for import. Other providers might
@@ -211,41 +235,8 @@ static int rsa_export(void *keydata, int selection,
* different arrays.
*/
static const OSSL_PARAM rsa_key_types[] = {
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_N, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_D, NULL, 0),
- /* We tolerate up to 10 factors... */
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR, NULL, 0),
- /* ..., up to 10 CRT exponents... */
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT, NULL, 0),
- /* ..., and up to 9 CRT coefficients */
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
- OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT, NULL, 0),
+ RSA_KEY_TYPES()
+ OSSL_PARAM_END
};
/*
* We lied about the amount of factors, exponents and coefficients, the
@@ -266,7 +257,6 @@ static const OSSL_PARAM *rsa_import_types(int selection)
return rsa_imexport_types(selection);
}
-
static const OSSL_PARAM *rsa_export_types(int selection)
{
return rsa_imexport_types(selection);
@@ -312,8 +302,7 @@ static int rsa_get_params(void *key, OSSL_PARAM params[])
if (!OSSL_PARAM_set_utf8_string(p, RSA_DEFAULT_MD))
return 0;
}
-
- return 1;
+ return key_to_params(rsa, NULL, params);
}
static const OSSL_PARAM rsa_params[] = {
@@ -321,6 +310,7 @@ static const OSSL_PARAM rsa_params[] = {
OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0),
+ RSA_KEY_TYPES()
OSSL_PARAM_END
};
diff --git a/providers/implementations/serializers/serializer_rsa.c b/providers/implementations/serializers/serializer_rsa.c
index ddc7074927..21898f9e3d 100644
--- a/providers/implementations/serializers/serializer_rsa.c
+++ b/providers/implementations/serializers/serializer_rsa.c
@@ -116,4 +116,3 @@ int ossl_prov_print_rsa(BIO *out, RSA *rsa, int priv)
sk_BIGNUM_const_free(coeffs);
return ret;
}
-
diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c
index 6ba61c3cda..9f8d0086f7 100644
--- a/test/evp_pkey_provided_test.c
+++ b/test/evp_pkey_provided_test.c
@@ -7,6 +7,7 @@
* https://www.openssl.org/source/license.html
*/
+#include <string.h> /* memset */
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/serializer.h>
@@ -260,7 +261,7 @@ static int test_print_key_using_serializer(const char *alg, const EVP_PKEY *pk)
static int test_fromdata_rsa(void)
{
- int ret = 0;
+ int ret = 0, i;
EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
EVP_PKEY *pk = NULL, *copy_pk = NULL;
/*
@@ -283,13 +284,15 @@ static int test_fromdata_rsa(void)
OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_N, &key_numbers[N]),
OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_E, &key_numbers[E]),
OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_D, &key_numbers[D]),
- OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR, &key_numbers[P]),
- OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR, &key_numbers[Q]),
- OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT, &key_numbers[DP]),
- OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT, &key_numbers[DQ]),
- OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_COEFFICIENT, &key_numbers[QINV]),
+ OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR1, &key_numbers[P]),
+ OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR2, &key_numbers[Q]),
+ OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT1, &key_numbers[DP]),
+ OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT2, &key_numbers[DQ]),
+ OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &key_numbers[QINV]),
OSSL_PARAM_END
};
+ BIGNUM *bn = BN_new();
+ BIGNUM *bn_from = BN_new();
if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)))
goto err;
@@ -315,10 +318,17 @@ static int test_fromdata_rsa(void)
|| !TEST_false(EVP_PKEY_copy_parameters(copy_pk, pk)))
goto err;
+ for (i = 0; fromdata_params[i].key != NULL; ++i) {
+ if (!TEST_true(BN_set_word(bn_from, key_numbers[i]))
+ || !TEST_true(EVP_PKEY_get_bn_param(pk, fromdata_params[i].key, &bn))
+ || !TEST_BN_eq(bn, bn_from))
+ goto err;
+ }
ret = test_print_key_using_pem("RSA", pk)
&& test_print_key_using_serializer("RSA", pk);
-
err:
+ BN_free(bn_from);
+ BN_free(bn);
EVP_PKEY_free(pk);
EVP_PKEY_free(copy_pk);
EVP_PKEY_CTX_free(key_ctx);
@@ -327,6 +337,59 @@ static int test_fromdata_rsa(void)
return ret;
}
+static int test_evp_pkey_get_bn_param_large(void)
+{
+ int ret = 0;
+ EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
+ EVP_PKEY *pk = NULL;
+ OSSL_PARAM_BLD *bld = NULL;
+ OSSL_PARAM *fromdata_params = NULL;
+ BIGNUM *n = NULL, *e = NULL, *d = NULL, *n_out = NULL;
+ /*
+ * The buffer size chosen here for n_data larger than the buffer used
+ * internally in EVP_PKEY_get_bn_param.
+ */
+ static unsigned char n_data[2050];
+ static const unsigned char e_data[] = {
+ 0x1, 0x00, 0x01
+ };
+ static const unsigned char d_data[]= {
+ 0x99, 0x33, 0x13, 0x7b
+ };
+
+ /* N is a large buffer */
+ memset(n_data, 0xCE, sizeof(n_data));
+
+ if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
+ || !TEST_ptr(n = BN_bin2bn(n_data, sizeof(n_data), NULL))
+ || !TEST_ptr(e = BN_bin2bn(e_data, sizeof(e_data), NULL))
+ || !TEST_ptr(d = BN_bin2bn(d_data, sizeof(d_data), NULL))
+ || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, n))
+ || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, e))
+ || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, d))
+ || !TEST_ptr(fromdata_params = OSSL_PARAM_BLD_to_param(bld))
+ || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL))
+ || !TEST_true(EVP_PKEY_key_fromdata_init(ctx))
+ || !TEST_true(EVP_PKEY_fromdata(ctx, &pk, fromdata_params))
+ || !TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, ""))
+ || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_N, &n_out))
+ || !TEST_BN_eq(n, n_out))
+ goto err;
+ ret = 1;
+ err:
+ BN_free(n_out);
+ BN_free(n);
+ BN_free(e);
+ BN_free(d);
+ EVP_PKEY_free(pk);
+ EVP_PKEY_CTX_free(key_ctx);
+ EVP_PKEY_CTX_free(ctx);
+ OSSL_PARAM_BLD_free_params(fromdata_params);
+ OSSL_PARAM_BLD_free(bld);
+ return ret;
+}
+
+
#ifndef OPENSSL_NO_DH
/* Array indexes used in test_fromdata_dh */
#define PRIV_KEY 0
@@ -412,6 +475,9 @@ static int test_fromdata_ecx(int tst)
EVP_PKEY_CTX *ctx = NULL;
EVP_PKEY *pk = NULL, *copy_pk = NULL;
const char *alg = NULL;
+ size_t len;
+ unsigned char out_pub[ED448_KEYLEN];
+ unsigned char out_priv[ED448_KEYLEN];
/* ED448_KEYLEN > X448_KEYLEN > X25519_KEYLEN == ED25519_KEYLEN */
static unsigned char key_numbers[4][2][ED448_KEYLEN] = {
@@ -580,6 +646,20 @@ static int test_fromdata_ecx(int tst)
|| !TEST_false(EVP_PKEY_copy_parameters(copy_pk, pk)))
goto err;
+ if (!TEST_true(EVP_PKEY_get_octet_string_param(
+ pk, fromdata_params[PRIV_KEY].key,
+ out_priv, sizeof(out_priv), &len))
+ || !TEST_mem_eq(out_priv, len,
+ fromdata_params[PRIV_KEY].data,
+ fromdata_params[PRIV_KEY].data_size)
+ || !TEST_true(EVP_PKEY_get_octet_string_param(
+ pk, fromdata_params[PUB_KEY].key,
+ out_pub, sizeof(out_pub), &len))
+ || !TEST_mem_eq(out_pub, len,
+ fromdata_params[PUB_KEY].data,
+ fromdata_params[PUB_KEY].data_size))
+ goto err;
+
ret = test_print_key_using_pem(alg, pk)
&& test_print_key_using_serializer(alg, pk);
@@ -591,6 +671,8 @@ err:
return ret;
}
+#define CURVE_NAME 2
+
static int test_fromdata_ec(void)
{
int ret = 0;
@@ -598,10 +680,13 @@ static int test_fromdata_ec(void)
EVP_PKEY *pk = NULL, *copy_pk = NULL;
OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
BIGNUM *ec_priv_bn = NULL;
+ BIGNUM *bn_priv = NULL;
OSSL_PARAM *fromdata_params = NULL;
const char *alg = "EC";
+ const char *curve = "prime256v1";
+ /* UNCOMPRESSED FORMAT */
static const unsigned char ec_pub_keydata[] = {
- 0x04,
+ POINT_CONVERSION_UNCOMPRESSED,
0x1b, 0x93, 0x67, 0x55, 0x1c, 0x55, 0x9f, 0x63,
0xd1, 0x22, 0xa4, 0xd8, 0xd1, 0x0a, 0x60, 0x6d,
0x02, 0xa5, 0x77, 0x57, 0xc8, 0xa3, 0x47, 0x73,
@@ -617,6 +702,12 @@ static int test_fromdata_ec(void)
0xcc, 0x0d, 0x9a, 0x24, 0x6c, 0x86, 0x1b, 0x2e,
0xdc, 0x4b, 0x4d, 0x35, 0x43, 0xe1, 0x1b, 0xad
};
+ const int compressed_sz = 1 + (sizeof(ec_pub_keydata) - 1) / 2;
+ unsigned char out_pub[sizeof(ec_pub_keydata)];
+ char out_curve_name[80];
+ const OSSL_PARAM *gettable = NULL;
+ size_t len;
+
if (!TEST_ptr(bld))
goto err;
@@ -625,7 +716,7 @@ static int test_fromdata_ec(void)
goto err;
if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_NAME,
- "prime256v1", 0) <= 0)
+ curve, 0) <= 0)
goto err;
if (OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY,
ec_pub_keydata,
@@ -650,9 +741,30 @@ static int test_fromdata_ec(void)
|| !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
goto err;
+ if (!TEST_ptr(gettable = EVP_PKEY_gettable_params(pk))
+ || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_NAME))
+ || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_PUB_KEY))
+ || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_PRIV_KEY)))
+ goto err;
+
+ if (!EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_EC_NAME,
+ out_curve_name, sizeof(out_curve_name),
+ &len)
+ || !TEST_str_eq(out_curve_name, curve)
+ || !EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_PUB_KEY,
+ out_pub, sizeof(out_pub), &len)
+ || !TEST_true(out_pub[0] == (POINT_CONVERSION_COMPRESSED + 1))
+ || !TEST_mem_eq(out_pub + 1, len - 1,
+ ec_pub_keydata + 1, compressed_sz - 1)
+ || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY,
+ &bn_priv))
+ || !TEST_BN_eq(ec_priv_bn, bn_priv))
+ goto err;
+
ret = test_print_key_using_pem(alg, pk)
&& test_print_key_using_serializer(alg, pk);
err:
+ BN_free(bn_priv);
BN_free(ec_priv_bn);
OSSL_PARAM_BLD_free_params(fromdata_params);
OSSL_PARAM_BLD_free(bld);
@@ -674,6 +786,7 @@ int setup_tests(void)
if (!TEST_ptr(datadir = test_get_argument(0)))
return 0;
+ ADD_TEST(test_evp_pkey_get_bn_param_large);
ADD_TEST(test_fromdata_rsa);
#ifndef OPENSSL_NO_DH
ADD_TEST(test_fromdata_dh);
diff --git a/test/keymgmt_internal_test.c b/test/keymgmt_internal_test.c
index fd60893a45..d30b3a70af 100644
--- a/test/keymgmt_internal_test.c
+++ b/test/keymgmt_internal_test.c
@@ -66,7 +66,7 @@ static FIXTURE *set_up(const char *testcase_name)
#define DQ 7
#define E3 8 /* Extra exponent */
#define QINV 9
-#define C3 10 /* Extra coefficient */
+#define C2 10 /* Extra coefficient */
/*
* We have to do this because OSSL_PARAM_get_ulong() can't handle params
@@ -92,10 +92,6 @@ static int export_cb(const OSSL_PARAM *params, void *arg)
{
unsigned long *keydata = arg;
const OSSL_PARAM *p = NULL;
- int factors_idx;
- int exponents_idx;
- int coefficients_idx;
- int ret = 1; /* Ever so hopeful */
if (keydata == NULL)
return 0;
@@ -106,35 +102,31 @@ static int export_cb(const OSSL_PARAM *params, void *arg)
|| !TEST_true(get_ulong_via_BN(p, &keydata[E]))
|| !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D))
|| !TEST_true(get_ulong_via_BN(p, &keydata[D])))
- ret = 0;
+ return 0;
- for (p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR),
- factors_idx = P;
- p != NULL && factors_idx <= F3;
- p = OSSL_PARAM_locate_const(p + 1, OSSL_PKEY_PARAM_RSA_FACTOR),
- factors_idx++)
- if (!TEST_true(get_ulong_via_BN(p, &keydata[factors_idx])))
- ret = 0;
- for (p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT),
- exponents_idx = DP;
- p != NULL && exponents_idx <= E3;
- p = OSSL_PARAM_locate_const(p + 1, OSSL_PKEY_PARAM_RSA_EXPONENT),
- exponents_idx++)
- if (!TEST_true(get_ulong_via_BN(p, &keydata[exponents_idx])))
- ret = 0;
- for (p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT),
- coefficients_idx = QINV;
- p != NULL && coefficients_idx <= C3;
- p = OSSL_PARAM_locate_const(p + 1, OSSL_PKEY_PARAM_RSA_COEFFICIENT),
- coefficients_idx++)
- if (!TEST_true(get_ulong_via_BN(p, &keydata[coefficients_idx])))
- ret = 0;
-
- if (!TEST_int_le(factors_idx, F3)
- || !TEST_int_le(exponents_idx, E3)
- || !TEST_int_le(coefficients_idx, C3))
- ret = 0;
- return ret;
+ if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR1))
+ || !TEST_true(get_ulong_via_BN(p, &keydata[P]))
+ || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR2))
+ || !TEST_true(get_ulong_via_BN(p, &keydata[Q]))
+ || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR3))
+ || !TEST_true(get_ulong_via_BN(p, &keydata[F3])))
+ return 0;
+
+ if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT1))
+ || !TEST_true(get_ulong_via_BN(p, &keydata[DP]))
+ || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT2))
+ || !TEST_true(get_ulong_via_BN(p, &keydata[DQ]))
+ || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT3))
+ || !TEST_true(get_ulong_via_BN(p, &keydata[E3])))
+ return 0;
+
+ if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT1))
+ || !TEST_true(get_ulong_via_BN(p, &keydata[QINV]))
+ || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT2))
+ || !TEST_true(get_ulong_via_BN(p, &keydata[C2])))
+ return 0;
+
+ return 1;
}
static int test_pass_rsa(FIXTURE *fixture)
@@ -146,9 +138,13 @@ static int test_pass_rsa(FIXTURE *fixture)
EVP_PKEY *pk = NULL;
EVP_KEYMGMT *km1 = NULL, *km2 = NULL;
void *provkey = NULL;
+ BIGNUM *bn_primes[1] = { NULL };
+ BIGNUM *bn_exps[1] = { NULL };
+ BIGNUM *bn_coeffs[1] = { NULL };
/*
* 32-bit RSA key, extracted from this command,
* executed with OpenSSL 1.0.2:
+ * An extra factor was added just for testing purposes.
*
* openssl genrsa 32 | openssl rsa -text
*/
@@ -158,12 +154,12 @@ static int test_pass_rsa(FIXTURE *fixture)
0x7b133399, /* D */
0xe963, /* P */
0xceb7, /* Q */
- 0, /* F3 */
+ 1, /* F3 */
0x8599, /* DP */
0xbd87, /* DQ */
- 0, /* E3 */
+ 2, /* E3 */
0xcc3b, /* QINV */
- 0, /* C3 */
+ 3, /* C3 */
0 /* Extra, should remain zero */
};
static unsigned long keydata[OSSL_NELEM(expected)] = { 0, };
@@ -197,6 +193,16 @@ static int test_pass_rsa(FIXTURE *fixture)
goto err;
bn1 = bn2 = bn3 = NULL;
+ if (!TEST_ptr(bn_primes[0] = BN_new())
+ || !TEST_true(BN_set_word(bn_primes[0], expected[F3]))
+ || !TEST_ptr(bn_exps[0] = BN_new())
+ || !TEST_true(BN_set_word(bn_exps[0], expected[E3]))
+ || !TEST_ptr(bn_coeffs[0] = BN_new())
+ || !TEST_true(BN_set_word(bn_coeffs[0], expected[C2]))
+ || !TEST_true(RSA_set0_multi_prime_params(rsa, bn_primes, bn_exps,
+ bn_coeffs, 1)))
+ goto err;
+
if (!TEST_ptr(pk = EVP_PKEY_new())
|| !TEST_true(EVP_PKEY_assign_RSA(pk, rsa)))
goto err;
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 9fc7cfcf18..cd0a7d806e 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5030,3 +5030,9 @@ SRP_Calc_u_ex ? 3_0_0 EXIST::FUNCTION:SRP
SRP_Calc_x_ex ? 3_0_0 EXIST::FUNCTION:SRP
SRP_Calc_client_key_ex ? 3_0_0 EXIST::FUNCTION:SRP
X509v3_cache_extensions ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_gettable_params ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_get_int_param ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_get_size_t_param ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_get_bn_param ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_get_utf8_string_param ? 3_0_0 EXIST::FUNCTION:
+EVP_PKEY_get_octet_string_param ? 3_0_0 EXIST::FUNCTION: