Make sure we always send an alert in libssl if we hit a fatal error
[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 }