]> git.ipfire.org Git - thirdparty/openssl.git/blob - test/evp_pkey_provided_test.c
9f8d0086f7b587644fa927895a3b85b974de1e2f
[thirdparty/openssl.git] / test / evp_pkey_provided_test.c
1 /*
2 * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
3 *
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
10 #include <string.h> /* memset */
11 #include <openssl/evp.h>
12 #include <openssl/pem.h>
13 #include <openssl/serializer.h>
14 #include <openssl/provider.h>
15 #include <openssl/params.h>
16 #include <openssl/core_names.h>
17 #include "crypto/ecx.h"
18 #include "internal/nelem.h"
19 #include "openssl/param_build.h"
20 #include "crypto/evp.h" /* For the internal API */
21 #include "testutil.h"
22
23 static char *datadir = NULL;
24
25 #define PRIV_TEXT 0
26 #define PRIV_PEM 1
27 #define PRIV_DER 2
28 #define PUB_TEXT 3
29 #define PUB_PEM 4
30 #define PUB_DER 5
31
32 static void stripcr(char *buf, size_t *len)
33 {
34 size_t i;
35 char *curr, *writ;
36
37 for (i = *len, curr = buf, writ = buf; i > 0; i--, curr++) {
38 if (*curr == '\r') {
39 (*len)--;
40 continue;
41 }
42 if (curr != writ)
43 *writ = *curr;
44 writ++;
45 }
46 }
47
48 static int compare_with_file(const char *alg, int type, BIO *membio)
49 {
50 char filename[80];
51 BIO *file = NULL;
52 char buf[1024];
53 char *memdata, *fullfile = NULL;
54 const char *suffix;
55 size_t readbytes;
56 int ret = 0;
57 int len;
58 size_t slen;
59
60 switch (type) {
61 case PRIV_TEXT:
62 suffix = "priv.txt";
63 break;
64
65 case PRIV_PEM:
66 suffix = "priv.pem";
67 break;
68
69 case PRIV_DER:
70 suffix = "priv.der";
71 break;
72
73 case PUB_TEXT:
74 suffix = "pub.txt";
75 break;
76
77 case PUB_PEM:
78 suffix = "pub.pem";
79 break;
80
81 case PUB_DER:
82 suffix = "pub.der";
83 break;
84
85 default:
86 TEST_error("Invalid file type");
87 goto err;
88 }
89
90 BIO_snprintf(filename, sizeof(filename), "%s.%s", alg, suffix);
91 fullfile = test_mk_file_path(datadir, filename);
92 if (!TEST_ptr(fullfile))
93 goto err;
94
95 file = BIO_new_file(fullfile, "rb");
96 if (!TEST_ptr(file))
97 goto err;
98
99 if (!TEST_true(BIO_read_ex(file, buf, sizeof(buf), &readbytes))
100 || !TEST_true(BIO_eof(file))
101 || !TEST_size_t_lt(readbytes, sizeof(buf)))
102 goto err;
103
104 len = BIO_get_mem_data(membio, &memdata);
105 if (!TEST_int_gt(len, 0))
106 goto err;
107
108 slen = len;
109 if (type != PRIV_DER && type != PUB_DER) {
110 stripcr(memdata, &slen);
111 stripcr(buf, &readbytes);
112 }
113
114 if (!TEST_mem_eq(memdata, slen, buf, readbytes))
115 goto err;
116
117 ret = 1;
118 err:
119 OPENSSL_free(fullfile);
120 (void)BIO_reset(membio);
121 BIO_free(file);
122 return ret;
123 }
124
125 static int test_print_key_using_pem(const char *alg, const EVP_PKEY *pk)
126 {
127 BIO *membio = BIO_new(BIO_s_mem());
128 int ret = 0;
129
130 if (!TEST_ptr(membio))
131 goto err;
132
133 if (!TEST_true(EVP_PKEY_print_private(membio, pk, 0, NULL))
134 || !TEST_true(compare_with_file(alg, PRIV_TEXT, membio))
135 /* Public key in PEM form */
136 || !TEST_true(PEM_write_bio_PUBKEY(membio, pk))
137 || !TEST_true(compare_with_file(alg, PUB_PEM, membio))
138 /* Unencrypted private key in PEM form */
139 || !TEST_true(PEM_write_bio_PrivateKey(membio, pk,
140 NULL, NULL, 0, NULL, NULL))
141 || !TEST_true(compare_with_file(alg, PRIV_PEM, membio))
142 /* Encrypted private key in PEM form */
143 || !TEST_true(PEM_write_bio_PrivateKey(bio_out, pk, EVP_aes_256_cbc(),
144 (unsigned char *)"pass", 4,
145 NULL, NULL)))
146 goto err;
147
148 ret = 1;
149 err:
150 BIO_free(membio);
151 return ret;
152 }
153
154 static int test_print_key_type_using_serializer(const char *alg, int type,
155 const EVP_PKEY *pk)
156 {
157 const char *pq;
158 OSSL_SERIALIZER_CTX *ctx = NULL;
159 BIO *membio = BIO_new(BIO_s_mem());
160 int ret = 0;
161
162 switch (type) {
163 case PRIV_TEXT:
164 pq = OSSL_SERIALIZER_PrivateKey_TO_TEXT_PQ;
165 break;
166
167 case PRIV_PEM:
168 pq = OSSL_SERIALIZER_PrivateKey_TO_PEM_PQ;
169 break;
170
171 case PRIV_DER:
172 pq = OSSL_SERIALIZER_PrivateKey_TO_DER_PQ;
173 break;
174
175 case PUB_TEXT:
176 pq = OSSL_SERIALIZER_PUBKEY_TO_TEXT_PQ;
177 break;
178
179 case PUB_PEM:
180 pq = OSSL_SERIALIZER_PUBKEY_TO_PEM_PQ;
181 break;
182
183 case PUB_DER:
184 pq = OSSL_SERIALIZER_PUBKEY_TO_DER_PQ;
185 break;
186
187 default:
188 TEST_error("Invalid serialization type");
189 goto err;
190 }
191
192 if (!TEST_ptr(membio))
193 goto err;
194
195 /* Make a context, it's valid for several prints */
196 TEST_note("Setting up a OSSL_SERIALIZER context with passphrase");
197 if (!TEST_ptr(ctx = OSSL_SERIALIZER_CTX_new_by_EVP_PKEY(pk, pq))
198 /* Check that this operation is supported */
199 || !TEST_ptr(OSSL_SERIALIZER_CTX_get_serializer(ctx)))
200 goto err;
201
202 /* Use no cipher. This should give us an unencrypted PEM */
203 TEST_note("Testing with no encryption");
204 if (!TEST_true(OSSL_SERIALIZER_to_bio(ctx, membio))
205 || !TEST_true(compare_with_file(alg, type, membio)))
206 goto err;
207
208 if (type == PRIV_PEM) {
209 /* Set a passphrase to be used later */
210 if (!TEST_true(OSSL_SERIALIZER_CTX_set_passphrase(ctx,
211 (unsigned char *)"pass",
212 4)))
213 goto err;
214
215 /* Use a valid cipher name */
216 TEST_note("Displaying PEM encrypted with AES-256-CBC");
217 if (!TEST_true(OSSL_SERIALIZER_CTX_set_cipher(ctx, "AES-256-CBC", NULL))
218 || !TEST_true(OSSL_SERIALIZER_to_bio(ctx, bio_out)))
219 goto err;
220
221 /* Use an invalid cipher name, which should generate no output */
222 TEST_note("NOT Displaying PEM encrypted with (invalid) FOO");
223 if (!TEST_false(OSSL_SERIALIZER_CTX_set_cipher(ctx, "FOO", NULL))
224 || !TEST_false(OSSL_SERIALIZER_to_bio(ctx, bio_out)))
225 goto err;
226
227 /* Clear the cipher. This should give us an unencrypted PEM again */
228 TEST_note("Testing with encryption cleared (no encryption)");
229 if (!TEST_true(OSSL_SERIALIZER_CTX_set_cipher(ctx, NULL, NULL))
230 || !TEST_true(OSSL_SERIALIZER_to_bio(ctx, membio))
231 || !TEST_true(compare_with_file(alg, type, membio)))
232 goto err;
233 }
234 ret = 1;
235 err:
236 BIO_free(membio);
237 OSSL_SERIALIZER_CTX_free(ctx);
238 return ret;
239 }
240
241 static int test_print_key_using_serializer(const char *alg, const EVP_PKEY *pk)
242 {
243 int i;
244 int ret = 1;
245
246 for (i = 0; i < 6; i++)
247 ret = ret && test_print_key_type_using_serializer(alg, i, pk);
248
249 return ret;
250 }
251
252 /* Array indexes used in test_fromdata_rsa */
253 #define N 0
254 #define E 1
255 #define D 2
256 #define P 3
257 #define Q 4
258 #define DP 5
259 #define DQ 6
260 #define QINV 7
261
262 static int test_fromdata_rsa(void)
263 {
264 int ret = 0, i;
265 EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
266 EVP_PKEY *pk = NULL, *copy_pk = NULL;
267 /*
268 * 32-bit RSA key, extracted from this command,
269 * executed with OpenSSL 1.0.2:
270 *
271 * openssl genrsa 32 | openssl rsa -text
272 */
273 static unsigned long key_numbers[] = {
274 0xbc747fc5, /* N */
275 0x10001, /* E */
276 0x7b133399, /* D */
277 0xe963, /* P */
278 0xceb7, /* Q */
279 0x8599, /* DP */
280 0xbd87, /* DQ */
281 0xcc3b, /* QINV */
282 };
283 OSSL_PARAM fromdata_params[] = {
284 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_N, &key_numbers[N]),
285 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_E, &key_numbers[E]),
286 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_D, &key_numbers[D]),
287 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR1, &key_numbers[P]),
288 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR2, &key_numbers[Q]),
289 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT1, &key_numbers[DP]),
290 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT2, &key_numbers[DQ]),
291 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &key_numbers[QINV]),
292 OSSL_PARAM_END
293 };
294 BIGNUM *bn = BN_new();
295 BIGNUM *bn_from = BN_new();
296
297 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)))
298 goto err;
299
300 if (!TEST_true(EVP_PKEY_key_fromdata_init(ctx))
301 || !TEST_true(EVP_PKEY_fromdata(ctx, &pk, fromdata_params))
302 || !TEST_int_eq(EVP_PKEY_bits(pk), 32)
303 || !TEST_int_eq(EVP_PKEY_security_bits(pk), 8)
304 || !TEST_int_eq(EVP_PKEY_size(pk), 4))
305 goto err;
306
307 if (!TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, "")))
308 goto err;
309
310 if (!TEST_true(EVP_PKEY_check(key_ctx))
311 || !TEST_true(EVP_PKEY_public_check(key_ctx))
312 || !TEST_true(EVP_PKEY_private_check(key_ctx))
313 || !TEST_true(EVP_PKEY_pairwise_check(key_ctx)))
314 goto err;
315
316 /* EVP_PKEY_copy_parameters() should fail for RSA */
317 if (!TEST_ptr(copy_pk = EVP_PKEY_new())
318 || !TEST_false(EVP_PKEY_copy_parameters(copy_pk, pk)))
319 goto err;
320
321 for (i = 0; fromdata_params[i].key != NULL; ++i) {
322 if (!TEST_true(BN_set_word(bn_from, key_numbers[i]))
323 || !TEST_true(EVP_PKEY_get_bn_param(pk, fromdata_params[i].key, &bn))
324 || !TEST_BN_eq(bn, bn_from))
325 goto err;
326 }
327 ret = test_print_key_using_pem("RSA", pk)
328 && test_print_key_using_serializer("RSA", pk);
329 err:
330 BN_free(bn_from);
331 BN_free(bn);
332 EVP_PKEY_free(pk);
333 EVP_PKEY_free(copy_pk);
334 EVP_PKEY_CTX_free(key_ctx);
335 EVP_PKEY_CTX_free(ctx);
336
337 return ret;
338 }
339
340 static int test_evp_pkey_get_bn_param_large(void)
341 {
342 int ret = 0;
343 EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
344 EVP_PKEY *pk = NULL;
345 OSSL_PARAM_BLD *bld = NULL;
346 OSSL_PARAM *fromdata_params = NULL;
347 BIGNUM *n = NULL, *e = NULL, *d = NULL, *n_out = NULL;
348 /*
349 * The buffer size chosen here for n_data larger than the buffer used
350 * internally in EVP_PKEY_get_bn_param.
351 */
352 static unsigned char n_data[2050];
353 static const unsigned char e_data[] = {
354 0x1, 0x00, 0x01
355 };
356 static const unsigned char d_data[]= {
357 0x99, 0x33, 0x13, 0x7b
358 };
359
360 /* N is a large buffer */
361 memset(n_data, 0xCE, sizeof(n_data));
362
363 if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
364 || !TEST_ptr(n = BN_bin2bn(n_data, sizeof(n_data), NULL))
365 || !TEST_ptr(e = BN_bin2bn(e_data, sizeof(e_data), NULL))
366 || !TEST_ptr(d = BN_bin2bn(d_data, sizeof(d_data), NULL))
367 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, n))
368 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, e))
369 || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, d))
370 || !TEST_ptr(fromdata_params = OSSL_PARAM_BLD_to_param(bld))
371 || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL))
372 || !TEST_true(EVP_PKEY_key_fromdata_init(ctx))
373 || !TEST_true(EVP_PKEY_fromdata(ctx, &pk, fromdata_params))
374 || !TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, ""))
375 || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_N, &n_out))
376 || !TEST_BN_eq(n, n_out))
377 goto err;
378 ret = 1;
379 err:
380 BN_free(n_out);
381 BN_free(n);
382 BN_free(e);
383 BN_free(d);
384 EVP_PKEY_free(pk);
385 EVP_PKEY_CTX_free(key_ctx);
386 EVP_PKEY_CTX_free(ctx);
387 OSSL_PARAM_BLD_free_params(fromdata_params);
388 OSSL_PARAM_BLD_free(bld);
389 return ret;
390 }
391
392
393 #ifndef OPENSSL_NO_DH
394 /* Array indexes used in test_fromdata_dh */
395 #define PRIV_KEY 0
396 #define PUB_KEY 1
397 #define FFC_P 2
398 #define FFC_G 3
399
400 static int test_fromdata_dh(void)
401 {
402 int ret = 0;
403 EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
404 EVP_PKEY *pk = NULL, *copy_pk = NULL;
405 /*
406 * 32-bit DH key, extracted from this command,
407 * executed with OpenSSL 1.0.2:
408 *
409 * openssl dhparam -out dhp.pem 32
410 * openssl genpkey -paramfile dhp.pem | openssl pkey -text
411 */
412 static unsigned long key_numbers[] = {
413 0x666c2b06, /* priv-key */
414 0x6fa6de50, /* pub-key */
415 0x8bb45f53, /* P */
416 0x2, /* G */
417 };
418 OSSL_PARAM fromdata_params[] = {
419 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_PRIV_KEY, &key_numbers[PRIV_KEY]),
420 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_PUB_KEY, &key_numbers[PUB_KEY]),
421 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_FFC_P, &key_numbers[FFC_P]),
422 OSSL_PARAM_ulong(OSSL_PKEY_PARAM_FFC_G, &key_numbers[FFC_G]),
423 OSSL_PARAM_END
424 };
425
426 if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)))
427 goto err;
428
429 if (!TEST_true(EVP_PKEY_key_fromdata_init(ctx))
430 || !TEST_true(EVP_PKEY_fromdata(ctx, &pk, fromdata_params))
431 || !TEST_int_eq(EVP_PKEY_bits(pk), 32)
432 || !TEST_int_eq(EVP_PKEY_security_bits(pk), 0) /* Missing Q */
433 || !TEST_int_eq(EVP_PKEY_size(pk), 4))
434 goto err;
435
436 if (!TEST_ptr(copy_pk = EVP_PKEY_new())
437 || !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
438 goto err;
439
440 ret = test_print_key_using_pem("DH", pk)
441 && test_print_key_using_serializer("DH", pk);
442
443 if (!TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, "")))
444 goto err;
445
446 if (!TEST_false(EVP_PKEY_check(key_ctx))
447 || !TEST_true(EVP_PKEY_public_check(key_ctx))
448 || !TEST_false(EVP_PKEY_private_check(key_ctx)) /* Need a q */
449 || !TEST_true(EVP_PKEY_pairwise_check(key_ctx)))
450 goto err;
451
452 err:
453 EVP_PKEY_free(pk);
454 EVP_PKEY_free(copy_pk);
455 EVP_PKEY_CTX_free(ctx);
456 EVP_PKEY_CTX_free(key_ctx);
457
458 return ret;
459 }
460 #endif
461
462 #ifndef OPENSSL_NO_EC
463 /* Array indexes used in test_fromdata_ecx */
464 # define PRIV_KEY 0
465 # define PUB_KEY 1
466
467 # define X25519_IDX 0
468 # define X448_IDX 1
469 # define ED25519_IDX 2
470 # define ED448_IDX 3
471
472 static int test_fromdata_ecx(int tst)
473 {
474 int ret = 0;
475 EVP_PKEY_CTX *ctx = NULL;
476 EVP_PKEY *pk = NULL, *copy_pk = NULL;
477 const char *alg = NULL;
478 size_t len;
479 unsigned char out_pub[ED448_KEYLEN];
480 unsigned char out_priv[ED448_KEYLEN];
481
482 /* ED448_KEYLEN > X448_KEYLEN > X25519_KEYLEN == ED25519_KEYLEN */
483 static unsigned char key_numbers[4][2][ED448_KEYLEN] = {
484 /* X25519: Keys from RFC 7748 6.1 */
485 {
486 /* Private Key */
487 {
488 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16,
489 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87,
490 0xeb, 0xc0, 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9,
491 0x2c, 0x2a
492 },
493 /* Public Key */
494 {
495 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b,
496 0x7d, 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d,
497 0x26, 0x38, 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b,
498 0x4e, 0x6a
499 }
500 },
501 /* X448: Keys from RFC 7748 6.2 */
502 {
503 /* Private Key */
504 {
505 0x9a, 0x8f, 0x49, 0x25, 0xd1, 0x51, 0x9f, 0x57, 0x75, 0xcf,
506 0x46, 0xb0, 0x4b, 0x58, 0x00, 0xd4, 0xee, 0x9e, 0xe8, 0xba,
507 0xe8, 0xbc, 0x55, 0x65, 0xd4, 0x98, 0xc2, 0x8d, 0xd9, 0xc9,
508 0xba, 0xf5, 0x74, 0xa9, 0x41, 0x97, 0x44, 0x89, 0x73, 0x91,
509 0x00, 0x63, 0x82, 0xa6, 0xf1, 0x27, 0xab, 0x1d, 0x9a, 0xc2,
510 0xd8, 0xc0, 0xa5, 0x98, 0x72, 0x6b
511 },
512 /* Public Key */
513 {
514 0x9b, 0x08, 0xf7, 0xcc, 0x31, 0xb7, 0xe3, 0xe6, 0x7d, 0x22,
515 0xd5, 0xae, 0xa1, 0x21, 0x07, 0x4a, 0x27, 0x3b, 0xd2, 0xb8,
516 0x3d, 0xe0, 0x9c, 0x63, 0xfa, 0xa7, 0x3d, 0x2c, 0x22, 0xc5,
517 0xd9, 0xbb, 0xc8, 0x36, 0x64, 0x72, 0x41, 0xd9, 0x53, 0xd4,
518 0x0c, 0x5b, 0x12, 0xda, 0x88, 0x12, 0x0d, 0x53, 0x17, 0x7f,
519 0x80, 0xe5, 0x32, 0xc4, 0x1f, 0xa0
520 }
521 },
522 /* ED25519: Keys from RFC 8032 */
523 {
524 /* Private Key */
525 {
526 0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 0xba, 0x84,
527 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69,
528 0x7b, 0x32, 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae,
529 0x7f, 0x60
530 },
531 /* Public Key */
532 {
533 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b,
534 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3,
535 0xda, 0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07,
536 0x51, 0x1a
537 }
538 },
539 /* ED448: Keys from RFC 8032 */
540 {
541 /* Private Key */
542 {
543 0x6c, 0x82, 0xa5, 0x62, 0xcb, 0x80, 0x8d, 0x10, 0xd6, 0x32,
544 0xbe, 0x89, 0xc8, 0x51, 0x3e, 0xbf, 0x6c, 0x92, 0x9f, 0x34,
545 0xdd, 0xfa, 0x8c, 0x9f, 0x63, 0xc9, 0x96, 0x0e, 0xf6, 0xe3,
546 0x48, 0xa3, 0x52, 0x8c, 0x8a, 0x3f, 0xcc, 0x2f, 0x04, 0x4e,
547 0x39, 0xa3, 0xfc, 0x5b, 0x94, 0x49, 0x2f, 0x8f, 0x03, 0x2e,
548 0x75, 0x49, 0xa2, 0x00, 0x98, 0xf9, 0x5b
549 },
550 /* Public Key */
551 {
552 0x5f, 0xd7, 0x44, 0x9b, 0x59, 0xb4, 0x61, 0xfd, 0x2c, 0xe7,
553 0x87, 0xec, 0x61, 0x6a, 0xd4, 0x6a, 0x1d, 0xa1, 0x34, 0x24,
554 0x85, 0xa7, 0x0e, 0x1f, 0x8a, 0x0e, 0xa7, 0x5d, 0x80, 0xe9,
555 0x67, 0x78, 0xed, 0xf1, 0x24, 0x76, 0x9b, 0x46, 0xc7, 0x06,
556 0x1b, 0xd6, 0x78, 0x3d, 0xf1, 0xe5, 0x0f, 0x6c, 0xd1, 0xfa,
557 0x1a, 0xbe, 0xaf, 0xe8, 0x25, 0x61, 0x80
558 }
559 }
560 };
561 OSSL_PARAM x25519_fromdata_params[] = {
562 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
563 key_numbers[X25519_IDX][PRIV_KEY],
564 X25519_KEYLEN),
565 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
566 key_numbers[X25519_IDX][PUB_KEY],
567 X25519_KEYLEN),
568 OSSL_PARAM_END
569 };
570 OSSL_PARAM x448_fromdata_params[] = {
571 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
572 key_numbers[X448_IDX][PRIV_KEY],
573 X448_KEYLEN),
574 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
575 key_numbers[X448_IDX][PUB_KEY],
576 X448_KEYLEN),
577 OSSL_PARAM_END
578 };
579 OSSL_PARAM ed25519_fromdata_params[] = {
580 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
581 key_numbers[ED25519_IDX][PRIV_KEY],
582 ED25519_KEYLEN),
583 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
584 key_numbers[ED25519_IDX][PUB_KEY],
585 ED25519_KEYLEN),
586 OSSL_PARAM_END
587 };
588 OSSL_PARAM ed448_fromdata_params[] = {
589 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
590 key_numbers[ED448_IDX][PRIV_KEY],
591 ED448_KEYLEN),
592 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
593 key_numbers[ED448_IDX][PUB_KEY],
594 ED448_KEYLEN),
595 OSSL_PARAM_END
596 };
597 OSSL_PARAM *fromdata_params = NULL;
598 int bits = 0, security_bits = 0, size = 0;
599
600 switch (tst) {
601 case X25519_IDX:
602 fromdata_params = x25519_fromdata_params;
603 bits = X25519_BITS;
604 security_bits = X25519_SECURITY_BITS;
605 size = X25519_KEYLEN;
606 alg = "X25519";
607 break;
608
609 case X448_IDX:
610 fromdata_params = x448_fromdata_params;
611 bits = X448_BITS;
612 security_bits = X448_SECURITY_BITS;
613 size = X448_KEYLEN;
614 alg = "X448";
615 break;
616
617 case ED25519_IDX:
618 fromdata_params = ed25519_fromdata_params;
619 bits = ED25519_BITS;
620 security_bits = ED25519_SECURITY_BITS;
621 size = ED25519_KEYLEN;
622 alg = "ED25519";
623 break;
624
625 case ED448_IDX:
626 fromdata_params = ed448_fromdata_params;
627 bits = ED448_BITS;
628 security_bits = ED448_SECURITY_BITS;
629 size = ED448_KEYLEN;
630 alg = "ED448";
631 break;
632 }
633
634 ctx = EVP_PKEY_CTX_new_from_name(NULL, alg, NULL);
635 if (!TEST_ptr(ctx))
636 goto err;
637
638 if (!TEST_true(EVP_PKEY_key_fromdata_init(ctx))
639 || !TEST_true(EVP_PKEY_fromdata(ctx, &pk, fromdata_params))
640 || !TEST_int_eq(EVP_PKEY_bits(pk), bits)
641 || !TEST_int_eq(EVP_PKEY_security_bits(pk), security_bits)
642 || !TEST_int_eq(EVP_PKEY_size(pk), size))
643 goto err;
644
645 if (!TEST_ptr(copy_pk = EVP_PKEY_new())
646 || !TEST_false(EVP_PKEY_copy_parameters(copy_pk, pk)))
647 goto err;
648
649 if (!TEST_true(EVP_PKEY_get_octet_string_param(
650 pk, fromdata_params[PRIV_KEY].key,
651 out_priv, sizeof(out_priv), &len))
652 || !TEST_mem_eq(out_priv, len,
653 fromdata_params[PRIV_KEY].data,
654 fromdata_params[PRIV_KEY].data_size)
655 || !TEST_true(EVP_PKEY_get_octet_string_param(
656 pk, fromdata_params[PUB_KEY].key,
657 out_pub, sizeof(out_pub), &len))
658 || !TEST_mem_eq(out_pub, len,
659 fromdata_params[PUB_KEY].data,
660 fromdata_params[PUB_KEY].data_size))
661 goto err;
662
663 ret = test_print_key_using_pem(alg, pk)
664 && test_print_key_using_serializer(alg, pk);
665
666 err:
667 EVP_PKEY_free(pk);
668 EVP_PKEY_free(copy_pk);
669 EVP_PKEY_CTX_free(ctx);
670
671 return ret;
672 }
673
674 #define CURVE_NAME 2
675
676 static int test_fromdata_ec(void)
677 {
678 int ret = 0;
679 EVP_PKEY_CTX *ctx = NULL;
680 EVP_PKEY *pk = NULL, *copy_pk = NULL;
681 OSSL_PARAM_BLD *bld = OSSL_PARAM_BLD_new();
682 BIGNUM *ec_priv_bn = NULL;
683 BIGNUM *bn_priv = NULL;
684 OSSL_PARAM *fromdata_params = NULL;
685 const char *alg = "EC";
686 const char *curve = "prime256v1";
687 /* UNCOMPRESSED FORMAT */
688 static const unsigned char ec_pub_keydata[] = {
689 POINT_CONVERSION_UNCOMPRESSED,
690 0x1b, 0x93, 0x67, 0x55, 0x1c, 0x55, 0x9f, 0x63,
691 0xd1, 0x22, 0xa4, 0xd8, 0xd1, 0x0a, 0x60, 0x6d,
692 0x02, 0xa5, 0x77, 0x57, 0xc8, 0xa3, 0x47, 0x73,
693 0x3a, 0x6a, 0x08, 0x28, 0x39, 0xbd, 0xc9, 0xd2,
694 0x80, 0xec, 0xe9, 0xa7, 0x08, 0x29, 0x71, 0x2f,
695 0xc9, 0x56, 0x82, 0xee, 0x9a, 0x85, 0x0f, 0x6d,
696 0x7f, 0x59, 0x5f, 0x8c, 0xd1, 0x96, 0x0b, 0xdf,
697 0x29, 0x3e, 0x49, 0x07, 0x88, 0x3f, 0x9a, 0x29
698 };
699 static const unsigned char ec_priv_keydata[] = {
700 0x33, 0xd0, 0x43, 0x83, 0xa9, 0x89, 0x56, 0x03,
701 0xd2, 0xd7, 0xfe, 0x6b, 0x01, 0x6f, 0xe4, 0x59,
702 0xcc, 0x0d, 0x9a, 0x24, 0x6c, 0x86, 0x1b, 0x2e,
703 0xdc, 0x4b, 0x4d, 0x35, 0x43, 0xe1, 0x1b, 0xad
704 };
705 const int compressed_sz = 1 + (sizeof(ec_pub_keydata) - 1) / 2;
706 unsigned char out_pub[sizeof(ec_pub_keydata)];
707 char out_curve_name[80];
708 const OSSL_PARAM *gettable = NULL;
709 size_t len;
710
711
712 if (!TEST_ptr(bld))
713 goto err;
714 if (!TEST_ptr(ec_priv_bn = BN_bin2bn(ec_priv_keydata,
715 sizeof(ec_priv_keydata), NULL)))
716 goto err;
717
718 if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_EC_NAME,
719 curve, 0) <= 0)
720 goto err;
721 if (OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY,
722 ec_pub_keydata,
723 sizeof(ec_pub_keydata)) <= 0)
724 goto err;
725 if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, ec_priv_bn) <= 0)
726 goto err;
727 if (!TEST_ptr(fromdata_params = OSSL_PARAM_BLD_to_param(bld)))
728 goto err;
729 ctx = EVP_PKEY_CTX_new_from_name(NULL, alg, NULL);
730 if (!TEST_ptr(ctx))
731 goto err;
732
733 if (!TEST_true(EVP_PKEY_key_fromdata_init(ctx))
734 || !TEST_true(EVP_PKEY_fromdata(ctx, &pk, fromdata_params))
735 || !TEST_int_eq(EVP_PKEY_bits(pk), 256)
736 || !TEST_int_eq(EVP_PKEY_security_bits(pk), 128)
737 || !TEST_int_eq(EVP_PKEY_size(pk), 2 + 35 * 2))
738 goto err;
739
740 if (!TEST_ptr(copy_pk = EVP_PKEY_new())
741 || !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
742 goto err;
743
744 if (!TEST_ptr(gettable = EVP_PKEY_gettable_params(pk))
745 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_EC_NAME))
746 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_PUB_KEY))
747 || !TEST_ptr(OSSL_PARAM_locate_const(gettable, OSSL_PKEY_PARAM_PRIV_KEY)))
748 goto err;
749
750 if (!EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_EC_NAME,
751 out_curve_name, sizeof(out_curve_name),
752 &len)
753 || !TEST_str_eq(out_curve_name, curve)
754 || !EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_PUB_KEY,
755 out_pub, sizeof(out_pub), &len)
756 || !TEST_true(out_pub[0] == (POINT_CONVERSION_COMPRESSED + 1))
757 || !TEST_mem_eq(out_pub + 1, len - 1,
758 ec_pub_keydata + 1, compressed_sz - 1)
759 || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY,
760 &bn_priv))
761 || !TEST_BN_eq(ec_priv_bn, bn_priv))
762 goto err;
763
764 ret = test_print_key_using_pem(alg, pk)
765 && test_print_key_using_serializer(alg, pk);
766 err:
767 BN_free(bn_priv);
768 BN_free(ec_priv_bn);
769 OSSL_PARAM_BLD_free_params(fromdata_params);
770 OSSL_PARAM_BLD_free(bld);
771 EVP_PKEY_free(pk);
772 EVP_PKEY_free(copy_pk);
773 EVP_PKEY_CTX_free(ctx);
774 return ret;
775 }
776
777 #endif /* OPENSSL_NO_EC */
778
779 int setup_tests(void)
780 {
781 if (!test_skip_common_options()) {
782 TEST_error("Error parsing test options\n");
783 return 0;
784 }
785
786 if (!TEST_ptr(datadir = test_get_argument(0)))
787 return 0;
788
789 ADD_TEST(test_evp_pkey_get_bn_param_large);
790 ADD_TEST(test_fromdata_rsa);
791 #ifndef OPENSSL_NO_DH
792 ADD_TEST(test_fromdata_dh);
793 #endif
794 #ifndef OPENSSL_NO_EC
795 ADD_ALL_TESTS(test_fromdata_ecx, 4);
796 ADD_TEST(test_fromdata_ec);
797 #endif
798 return 1;
799 }