blob: 77414dbc271d81946ef5f9469d751eeae5088f8a [file] [log] [blame]
Richard Levitte5a02d132019-10-17 00:26:44 +02001/*
Matt Caswell33388b42020-04-23 13:55:52 +01002 * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
Richard Levitte5a02d132019-10-17 00:26:44 +02003 *
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
8 */
9
Richard Levitted7e498a2020-10-04 16:34:31 +020010/*
11 * RSA low level APIs are deprecated for public use, but still ok for
12 * internal use.
13 */
14#include "internal/deprecated.h"
15
Richard Levitte5a02d132019-10-17 00:26:44 +020016#include <string.h>
17
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>
Richard Levitte1640d482019-11-08 15:24:42 +010024#include "internal/core.h"
Richard Levitte5a02d132019-10-17 00:26:44 +020025#include "internal/nelem.h"
26#include "crypto/evp.h" /* For the internal API */
27#include "testutil.h"
28
29typedef struct {
Dr. Matthias St. Pierreb4250012020-10-15 12:55:50 +030030 OSSL_LIB_CTX *ctx1;
Richard Levitte5a02d132019-10-17 00:26:44 +020031 OSSL_PROVIDER *prov1;
Dr. Matthias St. Pierreb4250012020-10-15 12:55:50 +030032 OSSL_LIB_CTX *ctx2;
Richard Levitte5a02d132019-10-17 00:26:44 +020033 OSSL_PROVIDER *prov2;
34} FIXTURE;
35
36static void tear_down(FIXTURE *fixture)
37{
38 if (fixture != NULL) {
39 OSSL_PROVIDER_unload(fixture->prov1);
40 OSSL_PROVIDER_unload(fixture->prov2);
Dr. Matthias St. Pierreb4250012020-10-15 12:55:50 +030041 OSSL_LIB_CTX_free(fixture->ctx1);
42 OSSL_LIB_CTX_free(fixture->ctx2);
Richard Levitte5a02d132019-10-17 00:26:44 +020043 OPENSSL_free(fixture);
44 }
45}
46
47static FIXTURE *set_up(const char *testcase_name)
48{
49 FIXTURE *fixture;
50
51 if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture)))
Dr. Matthias St. Pierreb4250012020-10-15 12:55:50 +030052 || !TEST_ptr(fixture->ctx1 = OSSL_LIB_CTX_new())
Richard Levitte5a02d132019-10-17 00:26:44 +020053 || !TEST_ptr(fixture->prov1 = OSSL_PROVIDER_load(fixture->ctx1,
54 "default"))
Dr. Matthias St. Pierreb4250012020-10-15 12:55:50 +030055 || !TEST_ptr(fixture->ctx2 = OSSL_LIB_CTX_new())
Richard Levitte5a02d132019-10-17 00:26:44 +020056 || !TEST_ptr(fixture->prov2 = OSSL_PROVIDER_load(fixture->ctx2,
57 "default"))) {
58 tear_down(fixture);
59 return NULL;
60 }
61 return fixture;
62}
63
Richard Levitte1640d482019-11-08 15:24:42 +010064/* Array indexes */
Richard Levitte5a02d132019-10-17 00:26:44 +020065#define N 0
66#define E 1
67#define D 2
68#define P 3
69#define Q 4
70#define F3 5 /* Extra factor */
71#define DP 6
72#define DQ 7
73#define E3 8 /* Extra exponent */
74#define QINV 9
Shane Lontis96ebe522020-04-01 15:51:18 +100075#define C2 10 /* Extra coefficient */
Richard Levitte5a02d132019-10-17 00:26:44 +020076
Richard Levitte1640d482019-11-08 15:24:42 +010077/*
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.
84 */
85static int get_ulong_via_BN(const OSSL_PARAM *p, unsigned long *goal)
86{
87 BIGNUM *n = NULL;
88 int ret = 1; /* Ever so hopeful */
89
90 if (!TEST_true(OSSL_PARAM_get_BN(p, &n))
91 || !TEST_true(BN_bn2nativepad(n, (unsigned char *)goal, sizeof(*goal))))
92 ret = 0;
93 BN_free(n);
94 return ret;
95}
96
97static int export_cb(const OSSL_PARAM *params, void *arg)
98{
99 unsigned long *keydata = arg;
100 const OSSL_PARAM *p = NULL;
Richard Levitte1640d482019-11-08 15:24:42 +0100101
102 if (keydata == NULL)
103 return 0;
104
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])))
Shane Lontis96ebe522020-04-01 15:51:18 +1000111 return 0;
Richard Levitte1640d482019-11-08 15:24:42 +0100112
Shane Lontis96ebe522020-04-01 15:51:18 +1000113 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])))
119 return 0;
Richard Levitte1640d482019-11-08 15:24:42 +0100120
Shane Lontis96ebe522020-04-01 15:51:18 +1000121 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])))
127 return 0;
128
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])))
133 return 0;
134
135 return 1;
Richard Levitte1640d482019-11-08 15:24:42 +0100136}
137
138static int test_pass_rsa(FIXTURE *fixture)
139{
Richard Levitte5a02d132019-10-17 00:26:44 +0200140 size_t i;
141 int ret = 0;
142 RSA *rsa = NULL;
143 BIGNUM *bn1 = NULL, *bn2 = NULL, *bn3 = NULL;
144 EVP_PKEY *pk = NULL;
145 EVP_KEYMGMT *km1 = NULL, *km2 = NULL;
Richard Levitte72ec9642020-02-03 15:36:15 +0100146 void *provkey = NULL;
Shane Lontis96ebe522020-04-01 15:51:18 +1000147 BIGNUM *bn_primes[1] = { NULL };
148 BIGNUM *bn_exps[1] = { NULL };
149 BIGNUM *bn_coeffs[1] = { NULL };
Richard Levitte5a02d132019-10-17 00:26:44 +0200150 /*
151 * 32-bit RSA key, extracted from this command,
152 * executed with OpenSSL 1.0.2:
Shane Lontis96ebe522020-04-01 15:51:18 +1000153 * An extra factor was added just for testing purposes.
Richard Levitte5a02d132019-10-17 00:26:44 +0200154 *
155 * openssl genrsa 32 | openssl rsa -text
156 */
157 static BN_ULONG expected[] = {
158 0xbc747fc5, /* N */
159 0x10001, /* E */
160 0x7b133399, /* D */
161 0xe963, /* P */
162 0xceb7, /* Q */
Shane Lontis96ebe522020-04-01 15:51:18 +1000163 1, /* F3 */
Richard Levitte5a02d132019-10-17 00:26:44 +0200164 0x8599, /* DP */
165 0xbd87, /* DQ */
Shane Lontis96ebe522020-04-01 15:51:18 +1000166 2, /* E3 */
Richard Levitte5a02d132019-10-17 00:26:44 +0200167 0xcc3b, /* QINV */
Shane Lontis96ebe522020-04-01 15:51:18 +1000168 3, /* C3 */
Richard Levitte5a02d132019-10-17 00:26:44 +0200169 0 /* Extra, should remain zero */
170 };
171 static unsigned long keydata[OSSL_NELEM(expected)] = { 0, };
Richard Levitte5a02d132019-10-17 00:26:44 +0200172
173 if (!TEST_ptr(rsa = RSA_new()))
174 goto err;
175
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)))
183 goto err;
184
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)))
190 goto err;
191
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)))
199 goto err;
200 bn1 = bn2 = bn3 = NULL;
201
Shane Lontis96ebe522020-04-01 15:51:18 +1000202 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,
209 bn_coeffs, 1)))
210 goto err;
211
Richard Levitte5a02d132019-10-17 00:26:44 +0200212 if (!TEST_ptr(pk = EVP_PKEY_new())
213 || !TEST_true(EVP_PKEY_assign_RSA(pk, rsa)))
214 goto err;
215 rsa = NULL;
216
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_ne(km1, km2))
220 goto err;
221
Richard Levitteacb90ba2020-03-21 06:21:26 +0100222 if (!TEST_ptr(provkey = evp_pkey_export_to_provider(pk, NULL, &km1, NULL))
223 || !TEST_true(evp_keymgmt_export(km2, provkey,
224 OSSL_KEYMGMT_SELECT_KEYPAIR,
225 &export_cb, keydata)))
Richard Levitte5a02d132019-10-17 00:26:44 +0200226 goto err;
227
228 /*
229 * At this point, the hope is that keydata will have all the numbers
230 * from the key.
231 */
232
Richard Levitte1640d482019-11-08 15:24:42 +0100233 for (i = 0; i < OSSL_NELEM(expected); i++) {
234 int rv = TEST_int_eq(expected[i], keydata[i]);
235
236 if (!rv)
237 TEST_info("i = %zu", i);
238 else
239 ret++;
240 }
Richard Levitte5a02d132019-10-17 00:26:44 +0200241
242 ret = (ret == OSSL_NELEM(expected));
243
244 err:
245 RSA_free(rsa);
246 BN_free(bn1);
247 BN_free(bn2);
248 BN_free(bn3);
249 EVP_PKEY_free(pk);
250 EVP_KEYMGMT_free(km1);
251 EVP_KEYMGMT_free(km2);
252
253 return ret;
254}
255
256static int (*tests[])(FIXTURE *) = {
257 test_pass_rsa
258};
259
260static int test_pass_key(int n)
261{
262 SETUP_TEST_FIXTURE(FIXTURE, set_up);
263 EXECUTE_TEST(tests[n], tear_down);
264 return result;
265}
266
267int setup_tests(void)
268{
269 ADD_ALL_TESTS(test_pass_key, 1);
270 return 1;
271}