589261a060beaa0cd8e472c39709c9979039531a
[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 "internal/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;
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     ossl_param_bld_init(&bld);
622
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(fromdata_params);
658     EVP_PKEY_free(pk);
659     EVP_PKEY_free(copy_pk);
660     EVP_PKEY_CTX_free(ctx);
661     return ret;
662 }
663
664 #endif /* OPENSSL_NO_EC */
665
666 int setup_tests(void)
667 {
668     if (!test_skip_common_options()) {
669         TEST_error("Error parsing test options\n");
670         return 0;
671     }
672
673     if (!TEST_ptr(datadir = test_get_argument(0)))
674         return 0;
675
676     ADD_TEST(test_fromdata_rsa);
677 #ifndef OPENSSL_NO_DH
678     ADD_TEST(test_fromdata_dh);
679 #endif
680 #ifndef OPENSSL_NO_EC
681     ADD_ALL_TESTS(test_fromdata_ecx, 4);
682     ADD_TEST(test_fromdata_ec);
683 #endif
684     return 1;
685 }