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