2 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
11 * RSA low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
18 #include <openssl/bio.h>
19 #include <openssl/bn.h>
20 #include <openssl/rsa.h>
21 #include <openssl/evp.h>
22 #include <openssl/provider.h>
23 #include <openssl/core_names.h>
24 #include "internal/core.h"
25 #include "internal/nelem.h"
26 #include "crypto/evp.h" /* For the internal API */
36 static void tear_down(FIXTURE *fixture)
38 if (fixture != NULL) {
39 OSSL_PROVIDER_unload(fixture->prov1);
40 OSSL_PROVIDER_unload(fixture->prov2);
41 OSSL_LIB_CTX_free(fixture->ctx1);
42 OSSL_LIB_CTX_free(fixture->ctx2);
43 OPENSSL_free(fixture);
47 static FIXTURE *set_up(const char *testcase_name)
51 if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture)))
52 || !TEST_ptr(fixture->ctx1 = OSSL_LIB_CTX_new())
53 || !TEST_ptr(fixture->prov1 = OSSL_PROVIDER_load(fixture->ctx1,
55 || !TEST_ptr(fixture->ctx2 = OSSL_LIB_CTX_new())
56 || !TEST_ptr(fixture->prov2 = OSSL_PROVIDER_load(fixture->ctx2,
70 #define F3 5 /* Extra factor */
73 #define E3 8 /* Extra exponent */
75 #define C2 10 /* Extra coefficient */
78 * We have to do this because OSSL_PARAM_get_ulong() can't handle params
79 * holding data that isn't exactly sizeof(uint32_t) or sizeof(uint64_t),
80 * and because the other end deals with BIGNUM, the resulting param might
81 * be any size. In this particular test, we know that the expected data
82 * fits within an unsigned long, and we want to get the data in that form
83 * to make testing of values easier.
85 static int get_ulong_via_BN(const OSSL_PARAM *p, unsigned long *goal)
88 int ret = 1; /* Ever so hopeful */
90 if (!TEST_true(OSSL_PARAM_get_BN(p, &n))
91 || !TEST_true(BN_bn2nativepad(n, (unsigned char *)goal, sizeof(*goal))))
97 static int export_cb(const OSSL_PARAM *params, void *arg)
99 unsigned long *keydata = arg;
100 const OSSL_PARAM *p = NULL;
105 if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N))
106 || !TEST_true(get_ulong_via_BN(p, &keydata[N]))
107 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E))
108 || !TEST_true(get_ulong_via_BN(p, &keydata[E]))
109 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D))
110 || !TEST_true(get_ulong_via_BN(p, &keydata[D])))
113 if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR1))
114 || !TEST_true(get_ulong_via_BN(p, &keydata[P]))
115 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR2))
116 || !TEST_true(get_ulong_via_BN(p, &keydata[Q]))
117 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR3))
118 || !TEST_true(get_ulong_via_BN(p, &keydata[F3])))
121 if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT1))
122 || !TEST_true(get_ulong_via_BN(p, &keydata[DP]))
123 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT2))
124 || !TEST_true(get_ulong_via_BN(p, &keydata[DQ]))
125 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_EXPONENT3))
126 || !TEST_true(get_ulong_via_BN(p, &keydata[E3])))
129 if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT1))
130 || !TEST_true(get_ulong_via_BN(p, &keydata[QINV]))
131 || !TEST_ptr(p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_COEFFICIENT2))
132 || !TEST_true(get_ulong_via_BN(p, &keydata[C2])))
138 static int test_pass_rsa(FIXTURE *fixture)
143 BIGNUM *bn1 = NULL, *bn2 = NULL, *bn3 = NULL;
144 EVP_PKEY *pk = NULL, *dup_pk = NULL;
145 EVP_KEYMGMT *km = NULL, *km1 = NULL, *km2 = NULL, *km3 = NULL;
146 void *provkey = NULL, *provkey2 = NULL;
147 BIGNUM *bn_primes[1] = { NULL };
148 BIGNUM *bn_exps[1] = { NULL };
149 BIGNUM *bn_coeffs[1] = { NULL };
151 * 32-bit RSA key, extracted from this command,
152 * executed with OpenSSL 1.0.2:
153 * An extra factor was added just for testing purposes.
155 * openssl genrsa 32 | openssl rsa -text
157 static BN_ULONG expected[] = {
169 0 /* Extra, should remain zero */
171 static unsigned long keydata[OSSL_NELEM(expected)] = { 0, };
173 if (!TEST_ptr(rsa = RSA_new()))
176 if (!TEST_ptr(bn1 = BN_new())
177 || !TEST_true(BN_set_word(bn1, expected[N]))
178 || !TEST_ptr(bn2 = BN_new())
179 || !TEST_true(BN_set_word(bn2, expected[E]))
180 || !TEST_ptr(bn3 = BN_new())
181 || !TEST_true(BN_set_word(bn3, expected[D]))
182 || !TEST_true(RSA_set0_key(rsa, bn1, bn2, bn3)))
185 if (!TEST_ptr(bn1 = BN_new())
186 || !TEST_true(BN_set_word(bn1, expected[P]))
187 || !TEST_ptr(bn2 = BN_new())
188 || !TEST_true(BN_set_word(bn2, expected[Q]))
189 || !TEST_true(RSA_set0_factors(rsa, bn1, bn2)))
192 if (!TEST_ptr(bn1 = BN_new())
193 || !TEST_true(BN_set_word(bn1, expected[DP]))
194 || !TEST_ptr(bn2 = BN_new())
195 || !TEST_true(BN_set_word(bn2, expected[DQ]))
196 || !TEST_ptr(bn3 = BN_new())
197 || !TEST_true(BN_set_word(bn3, expected[QINV]))
198 || !TEST_true(RSA_set0_crt_params(rsa, bn1, bn2, bn3)))
200 bn1 = bn2 = bn3 = NULL;
202 if (!TEST_ptr(bn_primes[0] = BN_new())
203 || !TEST_true(BN_set_word(bn_primes[0], expected[F3]))
204 || !TEST_ptr(bn_exps[0] = BN_new())
205 || !TEST_true(BN_set_word(bn_exps[0], expected[E3]))
206 || !TEST_ptr(bn_coeffs[0] = BN_new())
207 || !TEST_true(BN_set_word(bn_coeffs[0], expected[C2]))
208 || !TEST_true(RSA_set0_multi_prime_params(rsa, bn_primes, bn_exps,
212 if (!TEST_ptr(pk = EVP_PKEY_new())
213 || !TEST_true(EVP_PKEY_assign_RSA(pk, rsa)))
217 if (!TEST_ptr(km1 = EVP_KEYMGMT_fetch(fixture->ctx1, "RSA", NULL))
218 || !TEST_ptr(km2 = EVP_KEYMGMT_fetch(fixture->ctx2, "RSA", NULL))
219 || !TEST_ptr(km3 = EVP_KEYMGMT_fetch(fixture->ctx1, "RSA-PSS", NULL))
220 || !TEST_ptr_ne(km1, km2))
223 while (dup_pk == NULL) {
226 /* Check that we can't export an RSA key into a RSA-PSS keymanager */
227 if (!TEST_ptr_null(provkey2 = evp_pkey_export_to_provider(pk, NULL,
232 if (!TEST_ptr(provkey = evp_pkey_export_to_provider(pk, NULL, &km1,
234 || !TEST_true(evp_keymgmt_export(km2, provkey,
235 OSSL_KEYMGMT_SELECT_KEYPAIR,
236 &export_cb, keydata)))
240 * At this point, the hope is that keydata will have all the numbers
244 for (i = 0; i < OSSL_NELEM(expected); i++) {
245 int rv = TEST_int_eq(expected[i], keydata[i]);
248 TEST_info("i = %zu", i);
253 ret = (ret == OSSL_NELEM(expected));
254 if (!ret || !TEST_ptr(dup_pk = EVP_PKEY_dup(pk)))
257 ret = TEST_int_eq(EVP_PKEY_eq(pk, dup_pk), 1);
270 EVP_KEYMGMT_free(km1);
271 EVP_KEYMGMT_free(km2);
272 EVP_KEYMGMT_free(km3);
277 static int (*tests[])(FIXTURE *) = {
281 static int test_pass_key(int n)
283 SETUP_TEST_FIXTURE(FIXTURE, set_up);
284 EXECUTE_TEST(tests[n], tear_down);
288 int setup_tests(void)
290 ADD_ALL_TESTS(test_pass_key, 1);