xref: /freebsd/crypto/openssl/test/evp_pkey_provided_test.c (revision 44096ebd22ddd0081a357011714eff8963614b65)
1e0c4386eSCy Schubert /*
2e0c4386eSCy Schubert  * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
3e0c4386eSCy Schubert  *
4e0c4386eSCy Schubert  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e0c4386eSCy Schubert  * this file except in compliance with the License.  You can obtain a copy
6e0c4386eSCy Schubert  * in the file LICENSE in the source distribution or at
7e0c4386eSCy Schubert  * https://www.openssl.org/source/license.html
8e0c4386eSCy Schubert  */
9e0c4386eSCy Schubert 
10e0c4386eSCy Schubert #include <string.h> /* memset */
11e0c4386eSCy Schubert #include <openssl/evp.h>
12e0c4386eSCy Schubert #include <openssl/pem.h>
13e0c4386eSCy Schubert #include <openssl/encoder.h>
14e0c4386eSCy Schubert #include <openssl/provider.h>
15e0c4386eSCy Schubert #include <openssl/param_build.h>
16e0c4386eSCy Schubert #include <openssl/core_names.h>
17e0c4386eSCy Schubert #include <openssl/sha.h>
18e0c4386eSCy Schubert #include "crypto/ecx.h"
19e0c4386eSCy Schubert #include "crypto/evp.h"          /* For the internal API */
20e0c4386eSCy Schubert #include "crypto/bn_dh.h"        /* _bignum_ffdhe2048_p */
21e0c4386eSCy Schubert #include "internal/nelem.h"
22e0c4386eSCy Schubert #include "testutil.h"
23e0c4386eSCy Schubert 
24e0c4386eSCy Schubert static char *datadir = NULL;
25e0c4386eSCy Schubert 
26e0c4386eSCy Schubert /*
27e0c4386eSCy Schubert  * Do not change the order of the following defines unless you also
28e0c4386eSCy Schubert  * update the for loop bounds used inside test_print_key_using_encoder() and
29e0c4386eSCy Schubert  * test_print_key_using_encoder_public().
30e0c4386eSCy Schubert  */
31e0c4386eSCy Schubert #define PRIV_TEXT    0
32e0c4386eSCy Schubert #define PRIV_PEM     1
33e0c4386eSCy Schubert #define PRIV_DER     2
34e0c4386eSCy Schubert #define PUB_TEXT     3
35e0c4386eSCy Schubert #define PUB_PEM      4
36e0c4386eSCy Schubert #define PUB_DER      5
37e0c4386eSCy Schubert 
38e0c4386eSCy Schubert static void stripcr(char *buf, size_t *len)
39e0c4386eSCy Schubert {
40e0c4386eSCy Schubert     size_t i;
41e0c4386eSCy Schubert     char *curr, *writ;
42e0c4386eSCy Schubert 
43e0c4386eSCy Schubert     for (i = *len, curr = buf, writ = buf; i > 0; i--, curr++) {
44e0c4386eSCy Schubert         if (*curr == '\r') {
45e0c4386eSCy Schubert             (*len)--;
46e0c4386eSCy Schubert             continue;
47e0c4386eSCy Schubert         }
48e0c4386eSCy Schubert         if (curr != writ)
49e0c4386eSCy Schubert             *writ = *curr;
50e0c4386eSCy Schubert         writ++;
51e0c4386eSCy Schubert     }
52e0c4386eSCy Schubert }
53e0c4386eSCy Schubert 
54e0c4386eSCy Schubert static int compare_with_file(const char *alg, int type, BIO *membio)
55e0c4386eSCy Schubert {
56e0c4386eSCy Schubert     char filename[80];
57e0c4386eSCy Schubert     BIO *file = NULL;
58e0c4386eSCy Schubert     char buf[4096];
59e0c4386eSCy Schubert     char *memdata, *fullfile = NULL;
60e0c4386eSCy Schubert     const char *suffix;
61e0c4386eSCy Schubert     size_t readbytes;
62e0c4386eSCy Schubert     int ret = 0;
63e0c4386eSCy Schubert     int len;
64e0c4386eSCy Schubert     size_t slen;
65e0c4386eSCy Schubert 
66e0c4386eSCy Schubert     switch (type) {
67e0c4386eSCy Schubert     case PRIV_TEXT:
68e0c4386eSCy Schubert         suffix = "priv.txt";
69e0c4386eSCy Schubert         break;
70e0c4386eSCy Schubert 
71e0c4386eSCy Schubert     case PRIV_PEM:
72e0c4386eSCy Schubert         suffix = "priv.pem";
73e0c4386eSCy Schubert         break;
74e0c4386eSCy Schubert 
75e0c4386eSCy Schubert     case PRIV_DER:
76e0c4386eSCy Schubert         suffix = "priv.der";
77e0c4386eSCy Schubert         break;
78e0c4386eSCy Schubert 
79e0c4386eSCy Schubert     case PUB_TEXT:
80e0c4386eSCy Schubert         suffix = "pub.txt";
81e0c4386eSCy Schubert         break;
82e0c4386eSCy Schubert 
83e0c4386eSCy Schubert     case PUB_PEM:
84e0c4386eSCy Schubert         suffix = "pub.pem";
85e0c4386eSCy Schubert         break;
86e0c4386eSCy Schubert 
87e0c4386eSCy Schubert     case PUB_DER:
88e0c4386eSCy Schubert         suffix = "pub.der";
89e0c4386eSCy Schubert         break;
90e0c4386eSCy Schubert 
91e0c4386eSCy Schubert     default:
92e0c4386eSCy Schubert         TEST_error("Invalid file type");
93e0c4386eSCy Schubert         goto err;
94e0c4386eSCy Schubert     }
95e0c4386eSCy Schubert 
96e0c4386eSCy Schubert     BIO_snprintf(filename, sizeof(filename), "%s.%s", alg, suffix);
97e0c4386eSCy Schubert     fullfile = test_mk_file_path(datadir, filename);
98e0c4386eSCy Schubert     if (!TEST_ptr(fullfile))
99e0c4386eSCy Schubert         goto err;
100e0c4386eSCy Schubert 
101e0c4386eSCy Schubert     file = BIO_new_file(fullfile, "rb");
102e0c4386eSCy Schubert     if (!TEST_ptr(file))
103e0c4386eSCy Schubert         goto err;
104e0c4386eSCy Schubert 
105e0c4386eSCy Schubert     if (!TEST_true(BIO_read_ex(file, buf, sizeof(buf), &readbytes))
106e0c4386eSCy Schubert             || !TEST_true(BIO_eof(file))
107e0c4386eSCy Schubert             || !TEST_size_t_lt(readbytes, sizeof(buf)))
108e0c4386eSCy Schubert         goto err;
109e0c4386eSCy Schubert 
110e0c4386eSCy Schubert     len = BIO_get_mem_data(membio, &memdata);
111e0c4386eSCy Schubert     if (!TEST_int_gt(len, 0))
112e0c4386eSCy Schubert         goto err;
113e0c4386eSCy Schubert 
114e0c4386eSCy Schubert     slen = len;
115e0c4386eSCy Schubert     if (type != PRIV_DER && type != PUB_DER) {
116e0c4386eSCy Schubert         stripcr(memdata, &slen);
117e0c4386eSCy Schubert         stripcr(buf, &readbytes);
118e0c4386eSCy Schubert     }
119e0c4386eSCy Schubert 
120e0c4386eSCy Schubert     if (!TEST_mem_eq(memdata, slen, buf, readbytes))
121e0c4386eSCy Schubert         goto err;
122e0c4386eSCy Schubert 
123e0c4386eSCy Schubert     ret = 1;
124e0c4386eSCy Schubert  err:
125e0c4386eSCy Schubert     OPENSSL_free(fullfile);
126e0c4386eSCy Schubert     (void)BIO_reset(membio);
127e0c4386eSCy Schubert     BIO_free(file);
128e0c4386eSCy Schubert     return ret;
129e0c4386eSCy Schubert }
130e0c4386eSCy Schubert 
131e0c4386eSCy Schubert static int pass_cb(char *buf, int size, int rwflag, void *u)
132e0c4386eSCy Schubert {
133e0c4386eSCy Schubert     return 0;
134e0c4386eSCy Schubert }
135e0c4386eSCy Schubert 
136e0c4386eSCy Schubert static int pass_cb_error(char *buf, int size, int rwflag, void *u)
137e0c4386eSCy Schubert {
138e0c4386eSCy Schubert     return -1;
139e0c4386eSCy Schubert }
140e0c4386eSCy Schubert 
141e0c4386eSCy Schubert static int test_print_key_using_pem(const char *alg, const EVP_PKEY *pk)
142e0c4386eSCy Schubert {
143e0c4386eSCy Schubert     BIO *membio = BIO_new(BIO_s_mem());
144e0c4386eSCy Schubert     int ret = 0;
145e0c4386eSCy Schubert 
146e0c4386eSCy Schubert     if (!TEST_ptr(membio))
147e0c4386eSCy Schubert         goto err;
148e0c4386eSCy Schubert 
149e0c4386eSCy Schubert     if (/* Output Encrypted private key in PEM form */
150e0c4386eSCy Schubert         !TEST_true(PEM_write_bio_PrivateKey(bio_out, pk, EVP_aes_256_cbc(),
151e0c4386eSCy Schubert                                             (unsigned char *)"pass", 4,
152e0c4386eSCy Schubert                                             NULL, NULL))
153e0c4386eSCy Schubert         /* Output zero-length passphrase encrypted private key in PEM form */
154e0c4386eSCy Schubert         || !TEST_true(PEM_write_bio_PKCS8PrivateKey(bio_out, pk,
155e0c4386eSCy Schubert                                                     EVP_aes_256_cbc(),
156e0c4386eSCy Schubert                                                     (const char *)~0, 0,
157e0c4386eSCy Schubert                                                     NULL, NULL))
158e0c4386eSCy Schubert         || !TEST_true(PEM_write_bio_PKCS8PrivateKey(bio_out, pk,
159e0c4386eSCy Schubert                                                     EVP_aes_256_cbc(),
160e0c4386eSCy Schubert                                                     NULL, 0, NULL, ""))
161e0c4386eSCy Schubert         || !TEST_true(PEM_write_bio_PKCS8PrivateKey(bio_out, pk,
162e0c4386eSCy Schubert                                                     EVP_aes_256_cbc(),
163e0c4386eSCy Schubert                                                     NULL, 0, pass_cb, NULL))
164e0c4386eSCy Schubert         || !TEST_false(PEM_write_bio_PKCS8PrivateKey(bio_out, pk,
165e0c4386eSCy Schubert                                                      EVP_aes_256_cbc(),
166e0c4386eSCy Schubert                                                      NULL, 0, pass_cb_error,
167e0c4386eSCy Schubert                                                      NULL))
168e0c4386eSCy Schubert #ifndef OPENSSL_NO_DES
169e0c4386eSCy Schubert         || !TEST_true(PEM_write_bio_PKCS8PrivateKey_nid(
170e0c4386eSCy Schubert             bio_out, pk, NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
171e0c4386eSCy Schubert             (const char *)~0, 0, NULL, NULL))
172e0c4386eSCy Schubert         || !TEST_true(PEM_write_bio_PKCS8PrivateKey_nid(
173e0c4386eSCy Schubert             bio_out, pk, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, NULL, 0,
174e0c4386eSCy Schubert             NULL, ""))
175e0c4386eSCy Schubert         || !TEST_true(PEM_write_bio_PKCS8PrivateKey_nid(
176e0c4386eSCy Schubert             bio_out, pk, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, NULL, 0,
177e0c4386eSCy Schubert             pass_cb, NULL))
178e0c4386eSCy Schubert         || !TEST_false(PEM_write_bio_PKCS8PrivateKey_nid(
179e0c4386eSCy Schubert             bio_out, pk, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, NULL, 0,
180e0c4386eSCy Schubert             pass_cb_error, NULL))
181e0c4386eSCy Schubert #endif
182e0c4386eSCy Schubert         /* Private key in text form */
183e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_print_private(membio, pk, 0, NULL), 0)
184e0c4386eSCy Schubert         || !TEST_true(compare_with_file(alg, PRIV_TEXT, membio))
185e0c4386eSCy Schubert         /* Public key in PEM form */
186e0c4386eSCy Schubert         || !TEST_true(PEM_write_bio_PUBKEY(membio, pk))
187e0c4386eSCy Schubert         || !TEST_true(compare_with_file(alg, PUB_PEM, membio))
188e0c4386eSCy Schubert         /* Unencrypted private key in PEM form */
189e0c4386eSCy Schubert         || !TEST_true(PEM_write_bio_PrivateKey(membio, pk,
190e0c4386eSCy Schubert                                                NULL, NULL, 0, NULL, NULL))
191e0c4386eSCy Schubert         || !TEST_true(compare_with_file(alg, PRIV_PEM, membio))
192e0c4386eSCy Schubert         /* NULL key */
193e0c4386eSCy Schubert         || !TEST_false(PEM_write_bio_PrivateKey(membio, NULL,
194e0c4386eSCy Schubert                                                NULL, NULL, 0, NULL, NULL))
195e0c4386eSCy Schubert         || !TEST_false(PEM_write_bio_PrivateKey_traditional(membio, NULL,
196e0c4386eSCy Schubert                                                NULL, NULL, 0, NULL, NULL)))
197e0c4386eSCy Schubert         goto err;
198e0c4386eSCy Schubert 
199e0c4386eSCy Schubert     ret = 1;
200e0c4386eSCy Schubert  err:
201e0c4386eSCy Schubert     BIO_free(membio);
202e0c4386eSCy Schubert     return ret;
203e0c4386eSCy Schubert }
204e0c4386eSCy Schubert 
205e0c4386eSCy Schubert static int test_print_key_type_using_encoder(const char *alg, int type,
206e0c4386eSCy Schubert                                              const EVP_PKEY *pk)
207e0c4386eSCy Schubert {
208e0c4386eSCy Schubert     const char *output_type, *output_structure;
209e0c4386eSCy Schubert     int selection;
210e0c4386eSCy Schubert     OSSL_ENCODER_CTX *ctx = NULL;
211e0c4386eSCy Schubert     BIO *membio = BIO_new(BIO_s_mem());
212e0c4386eSCy Schubert     int ret = 0;
213e0c4386eSCy Schubert 
214e0c4386eSCy Schubert     switch (type) {
215e0c4386eSCy Schubert     case PRIV_TEXT:
216e0c4386eSCy Schubert         output_type = "TEXT";
217e0c4386eSCy Schubert         output_structure = NULL;
218e0c4386eSCy Schubert         selection = OSSL_KEYMGMT_SELECT_KEYPAIR
219e0c4386eSCy Schubert             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
220e0c4386eSCy Schubert         break;
221e0c4386eSCy Schubert 
222e0c4386eSCy Schubert     case PRIV_PEM:
223e0c4386eSCy Schubert         output_type = "PEM";
224e0c4386eSCy Schubert         output_structure = "PrivateKeyInfo";
225e0c4386eSCy Schubert         selection = OSSL_KEYMGMT_SELECT_KEYPAIR
226e0c4386eSCy Schubert             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
227e0c4386eSCy Schubert         break;
228e0c4386eSCy Schubert 
229e0c4386eSCy Schubert     case PRIV_DER:
230e0c4386eSCy Schubert         output_type = "DER";
231e0c4386eSCy Schubert         output_structure = "PrivateKeyInfo";
232e0c4386eSCy Schubert         selection = OSSL_KEYMGMT_SELECT_KEYPAIR
233e0c4386eSCy Schubert             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
234e0c4386eSCy Schubert         break;
235e0c4386eSCy Schubert 
236e0c4386eSCy Schubert     case PUB_TEXT:
237e0c4386eSCy Schubert         output_type = "TEXT";
238e0c4386eSCy Schubert         output_structure = NULL;
239e0c4386eSCy Schubert         selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY
240e0c4386eSCy Schubert             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
241e0c4386eSCy Schubert         break;
242e0c4386eSCy Schubert 
243e0c4386eSCy Schubert     case PUB_PEM:
244e0c4386eSCy Schubert         output_type = "PEM";
245e0c4386eSCy Schubert         output_structure = "SubjectPublicKeyInfo";
246e0c4386eSCy Schubert         selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY
247e0c4386eSCy Schubert             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
248e0c4386eSCy Schubert         break;
249e0c4386eSCy Schubert 
250e0c4386eSCy Schubert     case PUB_DER:
251e0c4386eSCy Schubert         output_type = "DER";
252e0c4386eSCy Schubert         output_structure = "SubjectPublicKeyInfo";
253e0c4386eSCy Schubert         selection = OSSL_KEYMGMT_SELECT_PUBLIC_KEY
254e0c4386eSCy Schubert             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS;
255e0c4386eSCy Schubert         break;
256e0c4386eSCy Schubert 
257e0c4386eSCy Schubert     default:
258e0c4386eSCy Schubert         TEST_error("Invalid encoding type");
259e0c4386eSCy Schubert         goto err;
260e0c4386eSCy Schubert     }
261e0c4386eSCy Schubert 
262e0c4386eSCy Schubert     if (!TEST_ptr(membio))
263e0c4386eSCy Schubert         goto err;
264e0c4386eSCy Schubert 
265e0c4386eSCy Schubert     /* Make a context, it's valid for several prints */
266e0c4386eSCy Schubert     TEST_note("Setting up a OSSL_ENCODER context with passphrase");
267e0c4386eSCy Schubert     if (!TEST_ptr(ctx = OSSL_ENCODER_CTX_new_for_pkey(pk, selection,
268e0c4386eSCy Schubert                                                       output_type,
269e0c4386eSCy Schubert                                                       output_structure,
270e0c4386eSCy Schubert                                                       NULL))
271e0c4386eSCy Schubert         /* Check that this operation is supported */
272e0c4386eSCy Schubert         || !TEST_int_ne(OSSL_ENCODER_CTX_get_num_encoders(ctx), 0))
273e0c4386eSCy Schubert         goto err;
274e0c4386eSCy Schubert 
275e0c4386eSCy Schubert     /* Use no cipher.  This should give us an unencrypted PEM */
276e0c4386eSCy Schubert     TEST_note("Testing with no encryption");
277e0c4386eSCy Schubert     if (!TEST_true(OSSL_ENCODER_to_bio(ctx, membio))
278e0c4386eSCy Schubert         || !TEST_true(compare_with_file(alg, type, membio)))
279e0c4386eSCy Schubert         goto err;
280e0c4386eSCy Schubert 
281e0c4386eSCy Schubert     if (type == PRIV_PEM) {
282e0c4386eSCy Schubert         /* Set a passphrase to be used later */
283e0c4386eSCy Schubert         if (!TEST_true(OSSL_ENCODER_CTX_set_passphrase(ctx,
284e0c4386eSCy Schubert                                                           (unsigned char *)"pass",
285e0c4386eSCy Schubert                                                           4)))
286e0c4386eSCy Schubert             goto err;
287e0c4386eSCy Schubert 
288e0c4386eSCy Schubert         /* Use a valid cipher name */
289e0c4386eSCy Schubert         TEST_note("Displaying PEM encrypted with AES-256-CBC");
290e0c4386eSCy Schubert         if (!TEST_true(OSSL_ENCODER_CTX_set_cipher(ctx, "AES-256-CBC", NULL))
291e0c4386eSCy Schubert             || !TEST_true(OSSL_ENCODER_to_bio(ctx, bio_out)))
292e0c4386eSCy Schubert             goto err;
293e0c4386eSCy Schubert 
294e0c4386eSCy Schubert         /* Use an invalid cipher name, which should generate no output */
295e0c4386eSCy Schubert         TEST_note("NOT Displaying PEM encrypted with (invalid) FOO");
296e0c4386eSCy Schubert         if (!TEST_false(OSSL_ENCODER_CTX_set_cipher(ctx, "FOO", NULL))
297e0c4386eSCy Schubert             || !TEST_false(OSSL_ENCODER_to_bio(ctx, bio_out)))
298e0c4386eSCy Schubert             goto err;
299e0c4386eSCy Schubert 
300e0c4386eSCy Schubert         /* Clear the cipher.  This should give us an unencrypted PEM again */
301e0c4386eSCy Schubert         TEST_note("Testing with encryption cleared (no encryption)");
302e0c4386eSCy Schubert         if (!TEST_true(OSSL_ENCODER_CTX_set_cipher(ctx, NULL, NULL))
303e0c4386eSCy Schubert             || !TEST_true(OSSL_ENCODER_to_bio(ctx, membio))
304e0c4386eSCy Schubert             || !TEST_true(compare_with_file(alg, type, membio)))
305e0c4386eSCy Schubert             goto err;
306e0c4386eSCy Schubert     }
307e0c4386eSCy Schubert     ret = 1;
308e0c4386eSCy Schubert err:
309e0c4386eSCy Schubert     BIO_free(membio);
310e0c4386eSCy Schubert     OSSL_ENCODER_CTX_free(ctx);
311e0c4386eSCy Schubert     return ret;
312e0c4386eSCy Schubert }
313e0c4386eSCy Schubert 
314e0c4386eSCy Schubert static int test_print_key_using_encoder(const char *alg, const EVP_PKEY *pk)
315e0c4386eSCy Schubert {
316e0c4386eSCy Schubert     int i;
317e0c4386eSCy Schubert     int ret = 1;
318e0c4386eSCy Schubert 
319e0c4386eSCy Schubert     for (i = PRIV_TEXT; i <= PUB_DER; i++)
320e0c4386eSCy Schubert         ret = ret && test_print_key_type_using_encoder(alg, i, pk);
321e0c4386eSCy Schubert 
322e0c4386eSCy Schubert     return ret;
323e0c4386eSCy Schubert }
324e0c4386eSCy Schubert 
325e0c4386eSCy Schubert #ifndef OPENSSL_NO_EC
326e0c4386eSCy Schubert static int test_print_key_using_encoder_public(const char *alg,
327e0c4386eSCy Schubert                                                const EVP_PKEY *pk)
328e0c4386eSCy Schubert {
329e0c4386eSCy Schubert     int i;
330e0c4386eSCy Schubert     int ret = 1;
331e0c4386eSCy Schubert 
332e0c4386eSCy Schubert     for (i = PUB_TEXT; i <= PUB_DER; i++)
333e0c4386eSCy Schubert         ret = ret && test_print_key_type_using_encoder(alg, i, pk);
334e0c4386eSCy Schubert 
335e0c4386eSCy Schubert     return ret;
336e0c4386eSCy Schubert }
337e0c4386eSCy Schubert #endif
338e0c4386eSCy Schubert 
339e0c4386eSCy Schubert /* Array indexes used in test_fromdata_rsa */
340e0c4386eSCy Schubert #define N       0
341e0c4386eSCy Schubert #define E       1
342e0c4386eSCy Schubert #define D       2
343e0c4386eSCy Schubert #define P       3
344e0c4386eSCy Schubert #define Q       4
345e0c4386eSCy Schubert #define DP      5
346e0c4386eSCy Schubert #define DQ      6
347e0c4386eSCy Schubert #define QINV    7
348e0c4386eSCy Schubert 
349e0c4386eSCy Schubert static int test_fromdata_rsa(void)
350e0c4386eSCy Schubert {
351e0c4386eSCy Schubert     int ret = 0, i;
352e0c4386eSCy Schubert     EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
353e0c4386eSCy Schubert     EVP_PKEY *pk = NULL, *copy_pk = NULL, *dup_pk = NULL;
354e0c4386eSCy Schubert     /*
355e0c4386eSCy Schubert      * 32-bit RSA key, extracted from this command,
356e0c4386eSCy Schubert      * executed with OpenSSL 1.0.2:
357e0c4386eSCy Schubert      *
358e0c4386eSCy Schubert      * openssl genrsa 32 | openssl rsa -text
359e0c4386eSCy Schubert      */
360e0c4386eSCy Schubert     static unsigned long key_numbers[] = {
361e0c4386eSCy Schubert         0xbc747fc5,              /* N */
362e0c4386eSCy Schubert         0x10001,                 /* E */
363e0c4386eSCy Schubert         0x7b133399,              /* D */
364e0c4386eSCy Schubert         0xe963,                  /* P */
365e0c4386eSCy Schubert         0xceb7,                  /* Q */
366e0c4386eSCy Schubert         0x8599,                  /* DP */
367e0c4386eSCy Schubert         0xbd87,                  /* DQ */
368e0c4386eSCy Schubert         0xcc3b,                  /* QINV */
369e0c4386eSCy Schubert     };
370e0c4386eSCy Schubert     OSSL_PARAM fromdata_params[] = {
371e0c4386eSCy Schubert         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_N, &key_numbers[N]),
372e0c4386eSCy Schubert         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_E, &key_numbers[E]),
373e0c4386eSCy Schubert         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_D, &key_numbers[D]),
374e0c4386eSCy Schubert         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR1, &key_numbers[P]),
375e0c4386eSCy Schubert         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR2, &key_numbers[Q]),
376e0c4386eSCy Schubert         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT1, &key_numbers[DP]),
377e0c4386eSCy Schubert         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT2, &key_numbers[DQ]),
378e0c4386eSCy Schubert         OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, &key_numbers[QINV]),
379e0c4386eSCy Schubert         OSSL_PARAM_END
380e0c4386eSCy Schubert     };
381e0c4386eSCy Schubert     BIGNUM *bn = BN_new();
382e0c4386eSCy Schubert     BIGNUM *bn_from = BN_new();
383e0c4386eSCy Schubert 
384e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL)))
385e0c4386eSCy Schubert         goto err;
386e0c4386eSCy Schubert 
387e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1)
388e0c4386eSCy Schubert         || !TEST_int_eq(EVP_PKEY_fromdata(ctx, &pk, EVP_PKEY_KEYPAIR,
389e0c4386eSCy Schubert                                           fromdata_params), 1))
390e0c4386eSCy Schubert         goto err;
391e0c4386eSCy Schubert 
392*44096ebdSEnji Cooper     for (;;) {
393e0c4386eSCy Schubert         ret = 0;
394e0c4386eSCy Schubert         if (!TEST_int_eq(EVP_PKEY_get_bits(pk), 32)
395e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_security_bits(pk), 8)
396e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_size(pk), 4)
397e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_missing_parameters(pk)))
398e0c4386eSCy Schubert             goto err;
399e0c4386eSCy Schubert 
400e0c4386eSCy Schubert         EVP_PKEY_CTX_free(key_ctx);
401e0c4386eSCy Schubert         if (!TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, "")))
402e0c4386eSCy Schubert             goto err;
403e0c4386eSCy Schubert 
404e0c4386eSCy Schubert         if (!TEST_int_gt(EVP_PKEY_check(key_ctx), 0)
405e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_public_check(key_ctx), 0)
406e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_private_check(key_ctx), 0)
407e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_pairwise_check(key_ctx), 0))
408e0c4386eSCy Schubert             goto err;
409e0c4386eSCy Schubert 
410e0c4386eSCy Schubert         /* EVP_PKEY_copy_parameters() should fail for RSA */
411e0c4386eSCy Schubert         if (!TEST_ptr(copy_pk = EVP_PKEY_new())
412e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_copy_parameters(copy_pk, pk)))
413e0c4386eSCy Schubert             goto err;
414e0c4386eSCy Schubert         EVP_PKEY_free(copy_pk);
415e0c4386eSCy Schubert         copy_pk = NULL;
416e0c4386eSCy Schubert 
417e0c4386eSCy Schubert         ret = test_print_key_using_pem("RSA", pk)
418e0c4386eSCy Schubert               && test_print_key_using_encoder("RSA", pk);
419e0c4386eSCy Schubert 
420*44096ebdSEnji Cooper         if (!ret || dup_pk != NULL)
421*44096ebdSEnji Cooper             break;
422*44096ebdSEnji Cooper 
423*44096ebdSEnji Cooper         if (!TEST_ptr(dup_pk = EVP_PKEY_dup(pk)))
424e0c4386eSCy Schubert             goto err;
425e0c4386eSCy Schubert         ret = ret && TEST_int_eq(EVP_PKEY_eq(pk, dup_pk), 1);
426e0c4386eSCy Schubert         EVP_PKEY_free(pk);
427e0c4386eSCy Schubert         pk = dup_pk;
428e0c4386eSCy Schubert         if (!ret)
429e0c4386eSCy Schubert             goto err;
430e0c4386eSCy Schubert     }
431e0c4386eSCy Schubert  err:
432e0c4386eSCy Schubert     /* for better diagnostics always compare key params */
433e0c4386eSCy Schubert     for (i = 0; fromdata_params[i].key != NULL; ++i) {
434e0c4386eSCy Schubert         if (!TEST_true(BN_set_word(bn_from, key_numbers[i]))
435e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, fromdata_params[i].key, &bn))
436e0c4386eSCy Schubert             || !TEST_BN_eq(bn, bn_from))
437e0c4386eSCy Schubert             ret = 0;
438e0c4386eSCy Schubert     }
439e0c4386eSCy Schubert     BN_free(bn_from);
440e0c4386eSCy Schubert     BN_free(bn);
441e0c4386eSCy Schubert     EVP_PKEY_free(pk);
442e0c4386eSCy Schubert     EVP_PKEY_free(copy_pk);
443e0c4386eSCy Schubert     EVP_PKEY_CTX_free(key_ctx);
444e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
445e0c4386eSCy Schubert 
446e0c4386eSCy Schubert     return ret;
447e0c4386eSCy Schubert }
448e0c4386eSCy Schubert 
449e0c4386eSCy Schubert static int test_evp_pkey_get_bn_param_large(void)
450e0c4386eSCy Schubert {
451e0c4386eSCy Schubert     int ret = 0;
452e0c4386eSCy Schubert     EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
453e0c4386eSCy Schubert     EVP_PKEY *pk = NULL;
454e0c4386eSCy Schubert     OSSL_PARAM_BLD *bld = NULL;
455e0c4386eSCy Schubert     OSSL_PARAM *fromdata_params = NULL;
456e0c4386eSCy Schubert     BIGNUM *n = NULL, *e = NULL, *d = NULL, *n_out = NULL;
457e0c4386eSCy Schubert     /*
458e0c4386eSCy Schubert      * The buffer size chosen here for n_data larger than the buffer used
459e0c4386eSCy Schubert      * internally in EVP_PKEY_get_bn_param.
460e0c4386eSCy Schubert      */
461e0c4386eSCy Schubert     static unsigned char n_data[2050];
462e0c4386eSCy Schubert     static const unsigned char e_data[] = {
463e0c4386eSCy Schubert         0x1, 0x00, 0x01
464e0c4386eSCy Schubert     };
465e0c4386eSCy Schubert     static const unsigned char d_data[]= {
466e0c4386eSCy Schubert        0x99, 0x33, 0x13, 0x7b
467e0c4386eSCy Schubert     };
468e0c4386eSCy Schubert 
469e0c4386eSCy Schubert     /* N is a large buffer */
470e0c4386eSCy Schubert     memset(n_data, 0xCE, sizeof(n_data));
471e0c4386eSCy Schubert 
472e0c4386eSCy Schubert     if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
473e0c4386eSCy Schubert         || !TEST_ptr(n = BN_bin2bn(n_data, sizeof(n_data), NULL))
474e0c4386eSCy Schubert         || !TEST_ptr(e = BN_bin2bn(e_data, sizeof(e_data), NULL))
475e0c4386eSCy Schubert         || !TEST_ptr(d = BN_bin2bn(d_data, sizeof(d_data), NULL))
476e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, n))
477e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, e))
478e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D, d))
479e0c4386eSCy Schubert         || !TEST_ptr(fromdata_params = OSSL_PARAM_BLD_to_param(bld))
480e0c4386eSCy Schubert         || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL))
481e0c4386eSCy Schubert         || !TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1)
482e0c4386eSCy Schubert         || !TEST_int_eq(EVP_PKEY_fromdata(ctx, &pk, EVP_PKEY_KEYPAIR,
483e0c4386eSCy Schubert                                           fromdata_params), 1)
484e0c4386eSCy Schubert         || !TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, ""))
485e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_RSA_N, &n_out))
486e0c4386eSCy Schubert         || !TEST_BN_eq(n, n_out))
487e0c4386eSCy Schubert         goto err;
488e0c4386eSCy Schubert     ret = 1;
489e0c4386eSCy Schubert  err:
490e0c4386eSCy Schubert     BN_free(n_out);
491e0c4386eSCy Schubert     BN_free(n);
492e0c4386eSCy Schubert     BN_free(e);
493e0c4386eSCy Schubert     BN_free(d);
494e0c4386eSCy Schubert     EVP_PKEY_free(pk);
495e0c4386eSCy Schubert     EVP_PKEY_CTX_free(key_ctx);
496e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
497e0c4386eSCy Schubert     OSSL_PARAM_free(fromdata_params);
498e0c4386eSCy Schubert     OSSL_PARAM_BLD_free(bld);
499e0c4386eSCy Schubert     return ret;
500e0c4386eSCy Schubert }
501e0c4386eSCy Schubert 
502e0c4386eSCy Schubert 
503e0c4386eSCy Schubert #ifndef OPENSSL_NO_DH
504e0c4386eSCy Schubert static int test_fromdata_dh_named_group(void)
505e0c4386eSCy Schubert {
506e0c4386eSCy Schubert     int ret = 0;
507e0c4386eSCy Schubert     int gindex = 0, pcounter = 0, hindex = 0;
508e0c4386eSCy Schubert     EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
509e0c4386eSCy Schubert     EVP_PKEY *pk = NULL, *copy_pk = NULL, *dup_pk = NULL;
510e0c4386eSCy Schubert     size_t len;
511e0c4386eSCy Schubert     BIGNUM *pub = NULL, *priv = NULL;
512e0c4386eSCy Schubert     BIGNUM *pub_out = NULL, *priv_out = NULL;
513e0c4386eSCy Schubert     BIGNUM *p = NULL, *q = NULL, *g = NULL, *j = NULL;
514e0c4386eSCy Schubert     OSSL_PARAM *fromdata_params = NULL;
515e0c4386eSCy Schubert     OSSL_PARAM_BLD *bld = NULL;
516e0c4386eSCy Schubert     char name_out[80];
517e0c4386eSCy Schubert     unsigned char seed_out[32];
518e0c4386eSCy Schubert 
519e0c4386eSCy Schubert     /*
520e0c4386eSCy Schubert      * DH key data was generated using the following:
521e0c4386eSCy Schubert      * openssl genpkey -algorithm DH -pkeyopt group:ffdhe2048
522e0c4386eSCy Schubert      *                 -pkeyopt priv_len:224 -text
523e0c4386eSCy Schubert      */
524e0c4386eSCy Schubert     static const unsigned char priv_data[] = {
525e0c4386eSCy Schubert         0x88, 0x85, 0xe7, 0x9f, 0xee, 0x6d, 0xc5, 0x7c, 0x78, 0xaf, 0x63, 0x5d,
526e0c4386eSCy Schubert         0x38, 0x2a, 0xd0, 0xed, 0x56, 0x4b, 0x47, 0x21, 0x2b, 0xfa, 0x55, 0xfa,
527e0c4386eSCy Schubert         0x87, 0xe8, 0xa9, 0x7b,
528e0c4386eSCy Schubert     };
529e0c4386eSCy Schubert     static const unsigned char pub_data[] = {
530e0c4386eSCy Schubert         0x00, 0xd6, 0x2d, 0x77, 0xe0, 0xd3, 0x7d, 0xf8, 0xeb, 0x98, 0x50, 0xa1,
531e0c4386eSCy Schubert         0x82, 0x22, 0x65, 0xd5, 0xd9, 0xfe, 0xc9, 0x3f, 0xbe, 0x16, 0x83, 0xbd,
532e0c4386eSCy Schubert         0x33, 0xe9, 0xc6, 0x93, 0xcf, 0x08, 0xaf, 0x83, 0xfa, 0x80, 0x8a, 0x6c,
533e0c4386eSCy Schubert         0x64, 0xdf, 0x70, 0x64, 0xd5, 0x0a, 0x7c, 0x5a, 0x72, 0xda, 0x66, 0xe6,
534e0c4386eSCy Schubert         0xf9, 0xf5, 0x31, 0x21, 0x92, 0xb0, 0x60, 0x1a, 0xb5, 0xd3, 0xf0, 0xa5,
535e0c4386eSCy Schubert         0xfa, 0x48, 0x95, 0x2e, 0x38, 0xd9, 0xc5, 0xe6, 0xda, 0xfb, 0x6c, 0x03,
536e0c4386eSCy Schubert         0x9d, 0x4b, 0x69, 0xb7, 0x95, 0xe4, 0x5c, 0xc0, 0x93, 0x4f, 0x48, 0xd9,
537e0c4386eSCy Schubert         0x7e, 0x06, 0x22, 0xb2, 0xde, 0xf3, 0x79, 0x24, 0xed, 0xe1, 0xd1, 0x4a,
538e0c4386eSCy Schubert         0x57, 0xf1, 0x40, 0x86, 0x70, 0x42, 0x25, 0xc5, 0x27, 0x68, 0xc9, 0xfa,
539e0c4386eSCy Schubert         0xe5, 0x8e, 0x62, 0x7e, 0xff, 0x49, 0x6c, 0x5b, 0xb5, 0xba, 0xf9, 0xef,
540e0c4386eSCy Schubert         0x9a, 0x1a, 0x10, 0xd4, 0x81, 0x53, 0xcf, 0x83, 0x04, 0x18, 0x1c, 0xe1,
541e0c4386eSCy Schubert         0xdb, 0xe1, 0x65, 0xa9, 0x7f, 0xe1, 0x33, 0xeb, 0xc3, 0x4f, 0xe3, 0xb7,
542e0c4386eSCy Schubert         0x22, 0xf7, 0x1c, 0x09, 0x4f, 0xed, 0xc6, 0x07, 0x8e, 0x78, 0x05, 0x8f,
543e0c4386eSCy Schubert         0x7c, 0x96, 0xd9, 0x12, 0xe0, 0x81, 0x74, 0x1a, 0xe9, 0x13, 0xc0, 0x20,
544e0c4386eSCy Schubert         0x82, 0x65, 0xbb, 0x42, 0x3b, 0xed, 0x08, 0x6a, 0x84, 0x4f, 0xea, 0x77,
545e0c4386eSCy Schubert         0x14, 0x32, 0xf9, 0xed, 0xc2, 0x12, 0xd6, 0xc5, 0xc6, 0xb3, 0xe5, 0xf2,
546e0c4386eSCy Schubert         0x6e, 0xf6, 0x16, 0x7f, 0x37, 0xde, 0xbc, 0x09, 0xc7, 0x06, 0x6b, 0x12,
547e0c4386eSCy Schubert         0xbc, 0xad, 0x2d, 0x49, 0x25, 0xd5, 0xdc, 0xf4, 0x18, 0x14, 0xd2, 0xf0,
548e0c4386eSCy Schubert         0xf1, 0x1d, 0x1f, 0x3a, 0xaa, 0x15, 0x55, 0xbb, 0x0d, 0x7f, 0xbe, 0x67,
549e0c4386eSCy Schubert         0xa1, 0xa7, 0xf0, 0xaa, 0xb3, 0xfb, 0x41, 0x82, 0x39, 0x49, 0x93, 0xbc,
550e0c4386eSCy Schubert         0xa8, 0xee, 0x72, 0x13, 0x45, 0x65, 0x15, 0x42, 0x17, 0xaa, 0xd8, 0xab,
551e0c4386eSCy Schubert         0xcf, 0x33, 0x42, 0x83, 0x42
552e0c4386eSCy Schubert     };
553e0c4386eSCy Schubert     static const char group_name[] = "ffdhe2048";
554e0c4386eSCy Schubert     static const long priv_len = 224;
555e0c4386eSCy Schubert 
556e0c4386eSCy Schubert     if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
557e0c4386eSCy Schubert         || !TEST_ptr(pub = BN_bin2bn(pub_data, sizeof(pub_data), NULL))
558e0c4386eSCy Schubert         || !TEST_ptr(priv = BN_bin2bn(priv_data, sizeof(priv_data), NULL))
559e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
560e0c4386eSCy Schubert                                                       OSSL_PKEY_PARAM_GROUP_NAME,
561e0c4386eSCy Schubert                                                       group_name, 0))
562e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_long(bld, OSSL_PKEY_PARAM_DH_PRIV_LEN,
563e0c4386eSCy Schubert                                                priv_len))
564e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub))
565e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, priv))
566e0c4386eSCy Schubert         || !TEST_ptr(fromdata_params = OSSL_PARAM_BLD_to_param(bld)))
567e0c4386eSCy Schubert         goto err;
568e0c4386eSCy Schubert 
569e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)))
570e0c4386eSCy Schubert         goto err;
571e0c4386eSCy Schubert 
572e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1)
573e0c4386eSCy Schubert         || !TEST_int_eq(EVP_PKEY_fromdata(ctx, &pk, EVP_PKEY_KEYPAIR,
574e0c4386eSCy Schubert                                           fromdata_params), 1))
575e0c4386eSCy Schubert         goto err;
576e0c4386eSCy Schubert 
577e0c4386eSCy Schubert     /*
578e0c4386eSCy Schubert      * A few extra checks of EVP_PKEY_get_utf8_string_param() to see that
579e0c4386eSCy Schubert      * it behaves as expected with regards to string length and terminating
580e0c4386eSCy Schubert      * NUL byte.
581e0c4386eSCy Schubert      */
582e0c4386eSCy Schubert     if (!TEST_true(EVP_PKEY_get_utf8_string_param(pk,
583e0c4386eSCy Schubert                                                   OSSL_PKEY_PARAM_GROUP_NAME,
584e0c4386eSCy Schubert                                                   NULL, sizeof(name_out),
585e0c4386eSCy Schubert                                                   &len))
586e0c4386eSCy Schubert         || !TEST_size_t_eq(len, sizeof(group_name) - 1)
587e0c4386eSCy Schubert         /* Just enough space to hold the group name and a terminating NUL */
588e0c4386eSCy Schubert         || !TEST_true(EVP_PKEY_get_utf8_string_param(pk,
589e0c4386eSCy Schubert                                                      OSSL_PKEY_PARAM_GROUP_NAME,
590e0c4386eSCy Schubert                                                      name_out,
591e0c4386eSCy Schubert                                                      sizeof(group_name),
592e0c4386eSCy Schubert                                                      &len))
593e0c4386eSCy Schubert         || !TEST_size_t_eq(len, sizeof(group_name) - 1)
594e0c4386eSCy Schubert         /* Too small buffer to hold the terminating NUL byte */
595e0c4386eSCy Schubert         || !TEST_false(EVP_PKEY_get_utf8_string_param(pk,
596e0c4386eSCy Schubert                                                       OSSL_PKEY_PARAM_GROUP_NAME,
597e0c4386eSCy Schubert                                                       name_out,
598e0c4386eSCy Schubert                                                       sizeof(group_name) - 1,
599e0c4386eSCy Schubert                                                       &len))
600e0c4386eSCy Schubert         /* Too small buffer to hold the whole group name, even! */
601e0c4386eSCy Schubert         || !TEST_false(EVP_PKEY_get_utf8_string_param(pk,
602e0c4386eSCy Schubert                                                       OSSL_PKEY_PARAM_GROUP_NAME,
603e0c4386eSCy Schubert                                                       name_out,
604e0c4386eSCy Schubert                                                       sizeof(group_name) - 2,
605e0c4386eSCy Schubert                                                       &len)))
606e0c4386eSCy Schubert         goto err;
607e0c4386eSCy Schubert 
608*44096ebdSEnji Cooper     for (;;) {
609e0c4386eSCy Schubert         ret = 0;
610e0c4386eSCy Schubert         if (!TEST_int_eq(EVP_PKEY_get_bits(pk), 2048)
611e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_security_bits(pk), 112)
612e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_size(pk), 256)
613e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_missing_parameters(pk)))
614e0c4386eSCy Schubert             goto err;
615e0c4386eSCy Schubert 
616e0c4386eSCy Schubert         if (!TEST_true(EVP_PKEY_get_utf8_string_param(pk,
617e0c4386eSCy Schubert                                                       OSSL_PKEY_PARAM_GROUP_NAME,
618e0c4386eSCy Schubert                                                       name_out,
619e0c4386eSCy Schubert                                                       sizeof(name_out),
620e0c4386eSCy Schubert                                                       &len))
621e0c4386eSCy Schubert             || !TEST_str_eq(name_out, group_name)
622e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PUB_KEY,
623e0c4386eSCy Schubert                                                 &pub_out))
624e0c4386eSCy Schubert 
625e0c4386eSCy Schubert             || !TEST_BN_eq(pub, pub_out)
626e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY,
627e0c4386eSCy Schubert                                                 &priv_out))
628e0c4386eSCy Schubert             || !TEST_BN_eq(priv, priv_out)
629e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_P, &p))
630e0c4386eSCy Schubert             || !TEST_BN_eq(&ossl_bignum_ffdhe2048_p, p)
631e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_Q, &q))
632e0c4386eSCy Schubert             || !TEST_ptr(q)
633e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_G, &g))
634e0c4386eSCy Schubert             || !TEST_BN_eq(&ossl_bignum_const_2, g)
635e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_get_bn_param(pk,
636e0c4386eSCy Schubert                                                  OSSL_PKEY_PARAM_FFC_COFACTOR,
637e0c4386eSCy Schubert                                                  &j))
638e0c4386eSCy Schubert             || !TEST_ptr_null(j)
639e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_get_octet_string_param(pk,
640e0c4386eSCy Schubert                                                            OSSL_PKEY_PARAM_FFC_SEED,
641e0c4386eSCy Schubert                                                            seed_out,
642e0c4386eSCy Schubert                                                            sizeof(seed_out),
643e0c4386eSCy Schubert                                                            &len))
644e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_int_param(pk, OSSL_PKEY_PARAM_FFC_GINDEX,
645e0c4386eSCy Schubert                                                  &gindex))
646e0c4386eSCy Schubert             || !TEST_int_eq(gindex, -1)
647e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_int_param(pk, OSSL_PKEY_PARAM_FFC_H,
648e0c4386eSCy Schubert                                                  &hindex))
649e0c4386eSCy Schubert             || !TEST_int_eq(hindex, 0)
650e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_int_param(pk,
651e0c4386eSCy Schubert                                                  OSSL_PKEY_PARAM_FFC_PCOUNTER,
652e0c4386eSCy Schubert                                                  &pcounter))
653e0c4386eSCy Schubert             || !TEST_int_eq(pcounter, -1))
654e0c4386eSCy Schubert             goto err;
655e0c4386eSCy Schubert         BN_free(p);
656e0c4386eSCy Schubert         p = NULL;
657e0c4386eSCy Schubert         BN_free(q);
658e0c4386eSCy Schubert         q = NULL;
659e0c4386eSCy Schubert         BN_free(g);
660e0c4386eSCy Schubert         g = NULL;
661e0c4386eSCy Schubert         BN_free(j);
662e0c4386eSCy Schubert         j = NULL;
663e0c4386eSCy Schubert         BN_free(pub_out);
664e0c4386eSCy Schubert         pub_out = NULL;
665e0c4386eSCy Schubert         BN_free(priv_out);
666e0c4386eSCy Schubert         priv_out = NULL;
667e0c4386eSCy Schubert 
668e0c4386eSCy Schubert         if (!TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, "")))
669e0c4386eSCy Schubert             goto err;
670e0c4386eSCy Schubert 
671e0c4386eSCy Schubert         if (!TEST_int_gt(EVP_PKEY_check(key_ctx), 0)
672e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_public_check(key_ctx), 0)
673e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_private_check(key_ctx), 0)
674e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_pairwise_check(key_ctx), 0))
675e0c4386eSCy Schubert             goto err;
676e0c4386eSCy Schubert         EVP_PKEY_CTX_free(key_ctx);
677e0c4386eSCy Schubert         key_ctx = NULL;
678e0c4386eSCy Schubert 
679e0c4386eSCy Schubert         if (!TEST_ptr(copy_pk = EVP_PKEY_new())
680e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
681e0c4386eSCy Schubert             goto err;
682e0c4386eSCy Schubert         EVP_PKEY_free(copy_pk);
683e0c4386eSCy Schubert         copy_pk = NULL;
684e0c4386eSCy Schubert 
685e0c4386eSCy Schubert         ret = test_print_key_using_pem("DH", pk)
686e0c4386eSCy Schubert               && test_print_key_using_encoder("DH", pk);
687e0c4386eSCy Schubert 
688*44096ebdSEnji Cooper         if (!ret || dup_pk != NULL)
689*44096ebdSEnji Cooper             break;
690*44096ebdSEnji Cooper 
691*44096ebdSEnji Cooper         if (!TEST_ptr(dup_pk = EVP_PKEY_dup(pk)))
692e0c4386eSCy Schubert             goto err;
693e0c4386eSCy Schubert         ret = ret && TEST_int_eq(EVP_PKEY_eq(pk, dup_pk), 1);
694e0c4386eSCy Schubert         EVP_PKEY_free(pk);
695e0c4386eSCy Schubert         pk = dup_pk;
696e0c4386eSCy Schubert         if (!ret)
697e0c4386eSCy Schubert             goto err;
698e0c4386eSCy Schubert     }
699e0c4386eSCy Schubert err:
700e0c4386eSCy Schubert     BN_free(p);
701e0c4386eSCy Schubert     BN_free(q);
702e0c4386eSCy Schubert     BN_free(g);
703e0c4386eSCy Schubert     BN_free(j);
704e0c4386eSCy Schubert     BN_free(pub);
705e0c4386eSCy Schubert     BN_free(priv);
706e0c4386eSCy Schubert     BN_free(pub_out);
707e0c4386eSCy Schubert     BN_free(priv_out);
708e0c4386eSCy Schubert     EVP_PKEY_free(copy_pk);
709e0c4386eSCy Schubert     EVP_PKEY_free(pk);
710e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
711e0c4386eSCy Schubert     EVP_PKEY_CTX_free(key_ctx);
712e0c4386eSCy Schubert     OSSL_PARAM_free(fromdata_params);
713e0c4386eSCy Schubert     OSSL_PARAM_BLD_free(bld);
714e0c4386eSCy Schubert 
715e0c4386eSCy Schubert     return ret;
716e0c4386eSCy Schubert }
717e0c4386eSCy Schubert 
718e0c4386eSCy Schubert static int test_fromdata_dh_fips186_4(void)
719e0c4386eSCy Schubert {
720e0c4386eSCy Schubert     int ret = 0;
721e0c4386eSCy Schubert     int gindex = 0, pcounter = 0, hindex = 0;
722e0c4386eSCy Schubert     EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
723e0c4386eSCy Schubert     EVP_PKEY *pk = NULL, *dup_pk = NULL;
724e0c4386eSCy Schubert     size_t len;
725e0c4386eSCy Schubert     BIGNUM *pub = NULL, *priv = NULL;
726e0c4386eSCy Schubert     BIGNUM *pub_out = NULL, *priv_out = NULL;
727e0c4386eSCy Schubert     BIGNUM *p = NULL, *q = NULL, *g = NULL, *j = NULL;
728e0c4386eSCy Schubert     OSSL_PARAM_BLD *bld = NULL;
729e0c4386eSCy Schubert     OSSL_PARAM *fromdata_params = NULL;
730e0c4386eSCy Schubert     char name_out[80];
731e0c4386eSCy Schubert     unsigned char seed_out[32];
732e0c4386eSCy Schubert 
733e0c4386eSCy Schubert     /*
734e0c4386eSCy Schubert      * DH key data was generated using the following:
735e0c4386eSCy Schubert      * openssl genpkey -algorithm DH
736e0c4386eSCy Schubert      *                 -pkeyopt group:ffdhe2048 -pkeyopt priv_len:224 -text
737e0c4386eSCy Schubert      */
738e0c4386eSCy Schubert     static const unsigned char priv_data[] = {
739e0c4386eSCy Schubert        0x88, 0x85, 0xe7, 0x9f, 0xee, 0x6d, 0xc5, 0x7c, 0x78, 0xaf, 0x63, 0x5d,
740e0c4386eSCy Schubert        0x38, 0x2a, 0xd0, 0xed, 0x56, 0x4b, 0x47, 0x21, 0x2b, 0xfa, 0x55, 0xfa,
741e0c4386eSCy Schubert        0x87, 0xe8, 0xa9, 0x7b,
742e0c4386eSCy Schubert     };
743e0c4386eSCy Schubert     static const unsigned char pub_data[] = {
744e0c4386eSCy Schubert        0xd6, 0x2d, 0x77, 0xe0, 0xd3, 0x7d, 0xf8, 0xeb, 0x98, 0x50, 0xa1, 0x82,
745e0c4386eSCy Schubert        0x22, 0x65, 0xd5, 0xd9, 0xfe, 0xc9, 0x3f, 0xbe, 0x16, 0x83, 0xbd, 0x33,
746e0c4386eSCy Schubert        0xe9, 0xc6, 0x93, 0xcf, 0x08, 0xaf, 0x83, 0xfa, 0x80, 0x8a, 0x6c, 0x64,
747e0c4386eSCy Schubert        0xdf, 0x70, 0x64, 0xd5, 0x0a, 0x7c, 0x5a, 0x72, 0xda, 0x66, 0xe6, 0xf9,
748e0c4386eSCy Schubert        0xf5, 0x31, 0x21, 0x92, 0xb0, 0x60, 0x1a, 0xb5, 0xd3, 0xf0, 0xa5, 0xfa,
749e0c4386eSCy Schubert        0x48, 0x95, 0x2e, 0x38, 0xd9, 0xc5, 0xe6, 0xda, 0xfb, 0x6c, 0x03, 0x9d,
750e0c4386eSCy Schubert        0x4b, 0x69, 0xb7, 0x95, 0xe4, 0x5c, 0xc0, 0x93, 0x4f, 0x48, 0xd9, 0x7e,
751e0c4386eSCy Schubert        0x06, 0x22, 0xb2, 0xde, 0xf3, 0x79, 0x24, 0xed, 0xe1, 0xd1, 0x4a, 0x57,
752e0c4386eSCy Schubert        0xf1, 0x40, 0x86, 0x70, 0x42, 0x25, 0xc5, 0x27, 0x68, 0xc9, 0xfa, 0xe5,
753e0c4386eSCy Schubert        0x8e, 0x62, 0x7e, 0xff, 0x49, 0x6c, 0x5b, 0xb5, 0xba, 0xf9, 0xef, 0x9a,
754e0c4386eSCy Schubert        0x1a, 0x10, 0xd4, 0x81, 0x53, 0xcf, 0x83, 0x04, 0x18, 0x1c, 0xe1, 0xdb,
755e0c4386eSCy Schubert        0xe1, 0x65, 0xa9, 0x7f, 0xe1, 0x33, 0xeb, 0xc3, 0x4f, 0xe3, 0xb7, 0x22,
756e0c4386eSCy Schubert        0xf7, 0x1c, 0x09, 0x4f, 0xed, 0xc6, 0x07, 0x8e, 0x78, 0x05, 0x8f, 0x7c,
757e0c4386eSCy Schubert        0x96, 0xd9, 0x12, 0xe0, 0x81, 0x74, 0x1a, 0xe9, 0x13, 0xc0, 0x20, 0x82,
758e0c4386eSCy Schubert        0x65, 0xbb, 0x42, 0x3b, 0xed, 0x08, 0x6a, 0x84, 0x4f, 0xea, 0x77, 0x14,
759e0c4386eSCy Schubert        0x32, 0xf9, 0xed, 0xc2, 0x12, 0xd6, 0xc5, 0xc6, 0xb3, 0xe5, 0xf2, 0x6e,
760e0c4386eSCy Schubert        0xf6, 0x16, 0x7f, 0x37, 0xde, 0xbc, 0x09, 0xc7, 0x06, 0x6b, 0x12, 0xbc,
761e0c4386eSCy Schubert        0xad, 0x2d, 0x49, 0x25, 0xd5, 0xdc, 0xf4, 0x18, 0x14, 0xd2, 0xf0, 0xf1,
762e0c4386eSCy Schubert        0x1d, 0x1f, 0x3a, 0xaa, 0x15, 0x55, 0xbb, 0x0d, 0x7f, 0xbe, 0x67, 0xa1,
763e0c4386eSCy Schubert        0xa7, 0xf0, 0xaa, 0xb3, 0xfb, 0x41, 0x82, 0x39, 0x49, 0x93, 0xbc, 0xa8,
764e0c4386eSCy Schubert        0xee, 0x72, 0x13, 0x45, 0x65, 0x15, 0x42, 0x17, 0xaa, 0xd8, 0xab, 0xcf,
765e0c4386eSCy Schubert        0x33, 0x42, 0x83, 0x42
766e0c4386eSCy Schubert     };
767e0c4386eSCy Schubert     static const char group_name[] = "ffdhe2048";
768e0c4386eSCy Schubert     static const long priv_len = 224;
769e0c4386eSCy Schubert 
770e0c4386eSCy Schubert 
771e0c4386eSCy Schubert     if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
772e0c4386eSCy Schubert         || !TEST_ptr(pub = BN_bin2bn(pub_data, sizeof(pub_data), NULL))
773e0c4386eSCy Schubert         || !TEST_ptr(priv = BN_bin2bn(priv_data, sizeof(priv_data), NULL))
774e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
775e0c4386eSCy Schubert                                                       OSSL_PKEY_PARAM_GROUP_NAME,
776e0c4386eSCy Schubert                                                       group_name, 0))
777e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_long(bld, OSSL_PKEY_PARAM_DH_PRIV_LEN,
778e0c4386eSCy Schubert                                                priv_len))
779e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY, pub))
780e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, priv))
781e0c4386eSCy Schubert         || !TEST_ptr(fromdata_params = OSSL_PARAM_BLD_to_param(bld)))
782e0c4386eSCy Schubert         goto err;
783e0c4386eSCy Schubert 
784e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)))
785e0c4386eSCy Schubert         goto err;
786e0c4386eSCy Schubert 
787e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1)
788e0c4386eSCy Schubert         || !TEST_int_eq(EVP_PKEY_fromdata(ctx, &pk, EVP_PKEY_KEYPAIR,
789e0c4386eSCy Schubert                                           fromdata_params), 1))
790e0c4386eSCy Schubert         goto err;
791e0c4386eSCy Schubert 
792*44096ebdSEnji Cooper     for (;;) {
793e0c4386eSCy Schubert         ret = 0;
794e0c4386eSCy Schubert         if (!TEST_int_eq(EVP_PKEY_get_bits(pk), 2048)
795e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_security_bits(pk), 112)
796e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_size(pk), 256)
797e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_missing_parameters(pk)))
798e0c4386eSCy Schubert             goto err;
799e0c4386eSCy Schubert 
800e0c4386eSCy Schubert         if (!TEST_true(EVP_PKEY_get_utf8_string_param(pk,
801e0c4386eSCy Schubert                                                       OSSL_PKEY_PARAM_GROUP_NAME,
802e0c4386eSCy Schubert                                                       name_out,
803e0c4386eSCy Schubert                                                       sizeof(name_out),
804e0c4386eSCy Schubert                                                       &len))
805e0c4386eSCy Schubert             || !TEST_str_eq(name_out, group_name)
806e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PUB_KEY,
807e0c4386eSCy Schubert                                                 &pub_out))
808e0c4386eSCy Schubert             || !TEST_BN_eq(pub, pub_out)
809e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY,
810e0c4386eSCy Schubert                                                 &priv_out))
811e0c4386eSCy Schubert             || !TEST_BN_eq(priv, priv_out)
812e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_P, &p))
813e0c4386eSCy Schubert             || !TEST_BN_eq(&ossl_bignum_ffdhe2048_p, p)
814e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_Q, &q))
815e0c4386eSCy Schubert             || !TEST_ptr(q)
816e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_G, &g))
817e0c4386eSCy Schubert             || !TEST_BN_eq(&ossl_bignum_const_2, g)
818e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_get_bn_param(pk,
819e0c4386eSCy Schubert                                                  OSSL_PKEY_PARAM_FFC_COFACTOR,
820e0c4386eSCy Schubert                                                  &j))
821e0c4386eSCy Schubert             || !TEST_ptr_null(j)
822e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_get_octet_string_param(pk,
823e0c4386eSCy Schubert                                                            OSSL_PKEY_PARAM_FFC_SEED,
824e0c4386eSCy Schubert                                                            seed_out,
825e0c4386eSCy Schubert                                                            sizeof(seed_out),
826e0c4386eSCy Schubert                                                            &len))
827e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_int_param(pk,
828e0c4386eSCy Schubert                                                  OSSL_PKEY_PARAM_FFC_GINDEX,
829e0c4386eSCy Schubert                                                  &gindex))
830e0c4386eSCy Schubert             || !TEST_int_eq(gindex, -1)
831e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_int_param(pk, OSSL_PKEY_PARAM_FFC_H,
832e0c4386eSCy Schubert                                                  &hindex))
833e0c4386eSCy Schubert             || !TEST_int_eq(hindex, 0)
834e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_int_param(pk,
835e0c4386eSCy Schubert                                                  OSSL_PKEY_PARAM_FFC_PCOUNTER,
836e0c4386eSCy Schubert                                                  &pcounter))
837e0c4386eSCy Schubert             || !TEST_int_eq(pcounter, -1))
838e0c4386eSCy Schubert             goto err;
839e0c4386eSCy Schubert         BN_free(p);
840e0c4386eSCy Schubert         p = NULL;
841e0c4386eSCy Schubert         BN_free(q);
842e0c4386eSCy Schubert         q = NULL;
843e0c4386eSCy Schubert         BN_free(g);
844e0c4386eSCy Schubert         g = NULL;
845e0c4386eSCy Schubert         BN_free(j);
846e0c4386eSCy Schubert         j = NULL;
847e0c4386eSCy Schubert         BN_free(pub_out);
848e0c4386eSCy Schubert         pub_out = NULL;
849e0c4386eSCy Schubert         BN_free(priv_out);
850e0c4386eSCy Schubert         priv_out = NULL;
851e0c4386eSCy Schubert 
852e0c4386eSCy Schubert         if (!TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, "")))
853e0c4386eSCy Schubert             goto err;
854e0c4386eSCy Schubert 
855e0c4386eSCy Schubert         if (!TEST_int_gt(EVP_PKEY_check(key_ctx), 0)
856e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_public_check(key_ctx), 0)
857e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_private_check(key_ctx), 0)
858e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_pairwise_check(key_ctx), 0))
859e0c4386eSCy Schubert             goto err;
860e0c4386eSCy Schubert         EVP_PKEY_CTX_free(key_ctx);
861e0c4386eSCy Schubert         key_ctx = NULL;
862e0c4386eSCy Schubert 
863e0c4386eSCy Schubert         ret = test_print_key_using_pem("DH", pk)
864e0c4386eSCy Schubert               && test_print_key_using_encoder("DH", pk);
865e0c4386eSCy Schubert 
866*44096ebdSEnji Cooper         if (!ret || dup_pk != NULL)
867*44096ebdSEnji Cooper             break;
868*44096ebdSEnji Cooper 
869*44096ebdSEnji Cooper         if (!TEST_ptr(dup_pk = EVP_PKEY_dup(pk)))
870e0c4386eSCy Schubert             goto err;
871e0c4386eSCy Schubert         ret = ret && TEST_int_eq(EVP_PKEY_eq(pk, dup_pk), 1);
872e0c4386eSCy Schubert         EVP_PKEY_free(pk);
873e0c4386eSCy Schubert         pk = dup_pk;
874e0c4386eSCy Schubert         if (!ret)
875e0c4386eSCy Schubert             goto err;
876e0c4386eSCy Schubert     }
877e0c4386eSCy Schubert err:
878e0c4386eSCy Schubert     BN_free(p);
879e0c4386eSCy Schubert     BN_free(q);
880e0c4386eSCy Schubert     BN_free(g);
881e0c4386eSCy Schubert     BN_free(j);
882e0c4386eSCy Schubert     BN_free(pub);
883e0c4386eSCy Schubert     BN_free(priv);
884e0c4386eSCy Schubert     BN_free(pub_out);
885e0c4386eSCy Schubert     BN_free(priv_out);
886e0c4386eSCy Schubert     EVP_PKEY_free(pk);
887e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
888e0c4386eSCy Schubert     EVP_PKEY_CTX_free(key_ctx);
889e0c4386eSCy Schubert     OSSL_PARAM_free(fromdata_params);
890e0c4386eSCy Schubert     OSSL_PARAM_BLD_free(bld);
891e0c4386eSCy Schubert 
892e0c4386eSCy Schubert     return ret;
893e0c4386eSCy Schubert }
894e0c4386eSCy Schubert 
895e0c4386eSCy Schubert #endif
896e0c4386eSCy Schubert 
897e0c4386eSCy Schubert 
898e0c4386eSCy Schubert 
899e0c4386eSCy Schubert #ifndef OPENSSL_NO_EC
900e0c4386eSCy Schubert /* Array indexes used in test_fromdata_ecx */
901e0c4386eSCy Schubert # define PRIV_KEY        0
902e0c4386eSCy Schubert # define PUB_KEY         1
903e0c4386eSCy Schubert 
904e0c4386eSCy Schubert # define X25519_IDX      0
905e0c4386eSCy Schubert # define X448_IDX        1
906e0c4386eSCy Schubert # define ED25519_IDX     2
907e0c4386eSCy Schubert # define ED448_IDX       3
908e0c4386eSCy Schubert 
909e0c4386eSCy Schubert /*
910e0c4386eSCy Schubert  * tst uses indexes 0 ... (3 * 4 - 1)
911e0c4386eSCy Schubert  * For the 4 ECX key types (X25519_IDX..ED448_IDX)
912e0c4386eSCy Schubert  * 0..3  = public + private key.
913e0c4386eSCy Schubert  * 4..7  = private key (This will generate the public key from the private key)
914e0c4386eSCy Schubert  * 8..11 = public key
915e0c4386eSCy Schubert  */
916e0c4386eSCy Schubert static int test_fromdata_ecx(int tst)
917e0c4386eSCy Schubert {
918e0c4386eSCy Schubert     int ret = 0;
919e0c4386eSCy Schubert     EVP_PKEY_CTX *ctx = NULL, *ctx2 = NULL;
920e0c4386eSCy Schubert     EVP_PKEY *pk = NULL, *copy_pk = NULL, *dup_pk = NULL;
921e0c4386eSCy Schubert     const char *alg = NULL;
922e0c4386eSCy Schubert     size_t len;
923e0c4386eSCy Schubert     unsigned char out_pub[ED448_KEYLEN];
924e0c4386eSCy Schubert     unsigned char out_priv[ED448_KEYLEN];
925e0c4386eSCy Schubert     OSSL_PARAM params[3] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
926e0c4386eSCy Schubert 
927e0c4386eSCy Schubert     /* ED448_KEYLEN > X448_KEYLEN > X25519_KEYLEN == ED25519_KEYLEN */
928e0c4386eSCy Schubert     static unsigned char key_numbers[4][2][ED448_KEYLEN] = {
929e0c4386eSCy Schubert         /* X25519: Keys from RFC 7748 6.1 */
930e0c4386eSCy Schubert         {
931e0c4386eSCy Schubert             /* Private Key */
932e0c4386eSCy Schubert             {
933e0c4386eSCy Schubert                 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16,
934e0c4386eSCy Schubert                 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87,
935e0c4386eSCy Schubert                 0xeb, 0xc0, 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9,
936e0c4386eSCy Schubert                 0x2c, 0x2a
937e0c4386eSCy Schubert             },
938e0c4386eSCy Schubert             /* Public Key */
939e0c4386eSCy Schubert             {
940e0c4386eSCy Schubert                 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b,
941e0c4386eSCy Schubert                 0x7d, 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d,
942e0c4386eSCy Schubert                 0x26, 0x38, 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b,
943e0c4386eSCy Schubert                 0x4e, 0x6a
944e0c4386eSCy Schubert             }
945e0c4386eSCy Schubert         },
946e0c4386eSCy Schubert         /* X448: Keys from RFC 7748 6.2 */
947e0c4386eSCy Schubert         {
948e0c4386eSCy Schubert             /* Private Key */
949e0c4386eSCy Schubert             {
950e0c4386eSCy Schubert                 0x9a, 0x8f, 0x49, 0x25, 0xd1, 0x51, 0x9f, 0x57, 0x75, 0xcf,
951e0c4386eSCy Schubert                 0x46, 0xb0, 0x4b, 0x58, 0x00, 0xd4, 0xee, 0x9e, 0xe8, 0xba,
952e0c4386eSCy Schubert                 0xe8, 0xbc, 0x55, 0x65, 0xd4, 0x98, 0xc2, 0x8d, 0xd9, 0xc9,
953e0c4386eSCy Schubert                 0xba, 0xf5, 0x74, 0xa9, 0x41, 0x97, 0x44, 0x89, 0x73, 0x91,
954e0c4386eSCy Schubert                 0x00, 0x63, 0x82, 0xa6, 0xf1, 0x27, 0xab, 0x1d, 0x9a, 0xc2,
955e0c4386eSCy Schubert                 0xd8, 0xc0, 0xa5, 0x98, 0x72, 0x6b
956e0c4386eSCy Schubert             },
957e0c4386eSCy Schubert             /* Public Key */
958e0c4386eSCy Schubert             {
959e0c4386eSCy Schubert                 0x9b, 0x08, 0xf7, 0xcc, 0x31, 0xb7, 0xe3, 0xe6, 0x7d, 0x22,
960e0c4386eSCy Schubert                 0xd5, 0xae, 0xa1, 0x21, 0x07, 0x4a, 0x27, 0x3b, 0xd2, 0xb8,
961e0c4386eSCy Schubert                 0x3d, 0xe0, 0x9c, 0x63, 0xfa, 0xa7, 0x3d, 0x2c, 0x22, 0xc5,
962e0c4386eSCy Schubert                 0xd9, 0xbb, 0xc8, 0x36, 0x64, 0x72, 0x41, 0xd9, 0x53, 0xd4,
963e0c4386eSCy Schubert                 0x0c, 0x5b, 0x12, 0xda, 0x88, 0x12, 0x0d, 0x53, 0x17, 0x7f,
964e0c4386eSCy Schubert                 0x80, 0xe5, 0x32, 0xc4, 0x1f, 0xa0
965e0c4386eSCy Schubert             }
966e0c4386eSCy Schubert         },
967e0c4386eSCy Schubert         /* ED25519: Keys from RFC 8032 */
968e0c4386eSCy Schubert         {
969e0c4386eSCy Schubert             /* Private Key */
970e0c4386eSCy Schubert             {
971e0c4386eSCy Schubert                 0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 0xba, 0x84,
972e0c4386eSCy Schubert                 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69,
973e0c4386eSCy Schubert                 0x7b, 0x32, 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae,
974e0c4386eSCy Schubert                 0x7f, 0x60
975e0c4386eSCy Schubert             },
976e0c4386eSCy Schubert             /* Public Key */
977e0c4386eSCy Schubert             {
978e0c4386eSCy Schubert                 0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b,
979e0c4386eSCy Schubert                 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3,
980e0c4386eSCy Schubert                 0xda, 0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07,
981e0c4386eSCy Schubert                 0x51, 0x1a
982e0c4386eSCy Schubert             }
983e0c4386eSCy Schubert         },
984e0c4386eSCy Schubert         /* ED448: Keys from RFC 8032 */
985e0c4386eSCy Schubert         {
986e0c4386eSCy Schubert             /* Private Key */
987e0c4386eSCy Schubert             {
988e0c4386eSCy Schubert                 0x6c, 0x82, 0xa5, 0x62, 0xcb, 0x80, 0x8d, 0x10, 0xd6, 0x32,
989e0c4386eSCy Schubert                 0xbe, 0x89, 0xc8, 0x51, 0x3e, 0xbf, 0x6c, 0x92, 0x9f, 0x34,
990e0c4386eSCy Schubert                 0xdd, 0xfa, 0x8c, 0x9f, 0x63, 0xc9, 0x96, 0x0e, 0xf6, 0xe3,
991e0c4386eSCy Schubert                 0x48, 0xa3, 0x52, 0x8c, 0x8a, 0x3f, 0xcc, 0x2f, 0x04, 0x4e,
992e0c4386eSCy Schubert                 0x39, 0xa3, 0xfc, 0x5b, 0x94, 0x49, 0x2f, 0x8f, 0x03, 0x2e,
993e0c4386eSCy Schubert                 0x75, 0x49, 0xa2, 0x00, 0x98, 0xf9, 0x5b
994e0c4386eSCy Schubert             },
995e0c4386eSCy Schubert             /* Public Key */
996e0c4386eSCy Schubert             {
997e0c4386eSCy Schubert                 0x5f, 0xd7, 0x44, 0x9b, 0x59, 0xb4, 0x61, 0xfd, 0x2c, 0xe7,
998e0c4386eSCy Schubert                 0x87, 0xec, 0x61, 0x6a, 0xd4, 0x6a, 0x1d, 0xa1, 0x34, 0x24,
999e0c4386eSCy Schubert                 0x85, 0xa7, 0x0e, 0x1f, 0x8a, 0x0e, 0xa7, 0x5d, 0x80, 0xe9,
1000e0c4386eSCy Schubert                 0x67, 0x78, 0xed, 0xf1, 0x24, 0x76, 0x9b, 0x46, 0xc7, 0x06,
1001e0c4386eSCy Schubert                 0x1b, 0xd6, 0x78, 0x3d, 0xf1, 0xe5, 0x0f, 0x6c, 0xd1, 0xfa,
1002e0c4386eSCy Schubert                 0x1a, 0xbe, 0xaf, 0xe8, 0x25, 0x61, 0x80
1003e0c4386eSCy Schubert             }
1004e0c4386eSCy Schubert         }
1005e0c4386eSCy Schubert     };
1006e0c4386eSCy Schubert     OSSL_PARAM x25519_fromdata_params[] = {
1007e0c4386eSCy Schubert         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
1008e0c4386eSCy Schubert                                 key_numbers[X25519_IDX][PRIV_KEY],
1009e0c4386eSCy Schubert                                 X25519_KEYLEN),
1010e0c4386eSCy Schubert         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
1011e0c4386eSCy Schubert                                 key_numbers[X25519_IDX][PUB_KEY],
1012e0c4386eSCy Schubert                                 X25519_KEYLEN),
1013e0c4386eSCy Schubert         OSSL_PARAM_END
1014e0c4386eSCy Schubert     };
1015e0c4386eSCy Schubert     OSSL_PARAM x448_fromdata_params[] = {
1016e0c4386eSCy Schubert         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
1017e0c4386eSCy Schubert                                 key_numbers[X448_IDX][PRIV_KEY],
1018e0c4386eSCy Schubert                                 X448_KEYLEN),
1019e0c4386eSCy Schubert         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
1020e0c4386eSCy Schubert                                 key_numbers[X448_IDX][PUB_KEY],
1021e0c4386eSCy Schubert                                 X448_KEYLEN),
1022e0c4386eSCy Schubert         OSSL_PARAM_END
1023e0c4386eSCy Schubert     };
1024e0c4386eSCy Schubert     OSSL_PARAM ed25519_fromdata_params[] = {
1025e0c4386eSCy Schubert         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
1026e0c4386eSCy Schubert                                 key_numbers[ED25519_IDX][PRIV_KEY],
1027e0c4386eSCy Schubert                                 ED25519_KEYLEN),
1028e0c4386eSCy Schubert         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
1029e0c4386eSCy Schubert                                 key_numbers[ED25519_IDX][PUB_KEY],
1030e0c4386eSCy Schubert                                 ED25519_KEYLEN),
1031e0c4386eSCy Schubert         OSSL_PARAM_END
1032e0c4386eSCy Schubert     };
1033e0c4386eSCy Schubert     OSSL_PARAM ed448_fromdata_params[] = {
1034e0c4386eSCy Schubert         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
1035e0c4386eSCy Schubert                                 key_numbers[ED448_IDX][PRIV_KEY],
1036e0c4386eSCy Schubert                                 ED448_KEYLEN),
1037e0c4386eSCy Schubert         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
1038e0c4386eSCy Schubert                                 key_numbers[ED448_IDX][PUB_KEY],
1039e0c4386eSCy Schubert                                 ED448_KEYLEN),
1040e0c4386eSCy Schubert         OSSL_PARAM_END
1041e0c4386eSCy Schubert     };
1042e0c4386eSCy Schubert     OSSL_PARAM *fromdata_params = NULL;
1043e0c4386eSCy Schubert     int bits = 0, security_bits = 0, size = 0;
1044e0c4386eSCy Schubert     OSSL_PARAM *orig_fromdata_params = NULL;
1045e0c4386eSCy Schubert 
1046e0c4386eSCy Schubert     switch (tst & 3) {
1047e0c4386eSCy Schubert     case X25519_IDX:
1048e0c4386eSCy Schubert         fromdata_params = x25519_fromdata_params;
1049e0c4386eSCy Schubert         bits = X25519_BITS;
1050e0c4386eSCy Schubert         security_bits = X25519_SECURITY_BITS;
1051e0c4386eSCy Schubert         size = X25519_KEYLEN;
1052e0c4386eSCy Schubert         alg = "X25519";
1053e0c4386eSCy Schubert         break;
1054e0c4386eSCy Schubert 
1055e0c4386eSCy Schubert     case X448_IDX:
1056e0c4386eSCy Schubert         fromdata_params = x448_fromdata_params;
1057e0c4386eSCy Schubert         bits = X448_BITS;
1058e0c4386eSCy Schubert         security_bits = X448_SECURITY_BITS;
1059e0c4386eSCy Schubert         size = X448_KEYLEN;
1060e0c4386eSCy Schubert         alg = "X448";
1061e0c4386eSCy Schubert         break;
1062e0c4386eSCy Schubert 
1063e0c4386eSCy Schubert     case ED25519_IDX:
1064e0c4386eSCy Schubert         fromdata_params = ed25519_fromdata_params;
1065e0c4386eSCy Schubert         bits = ED25519_BITS;
1066e0c4386eSCy Schubert         security_bits = ED25519_SECURITY_BITS;
1067e0c4386eSCy Schubert         size = ED25519_SIGSIZE;
1068e0c4386eSCy Schubert         alg = "ED25519";
1069e0c4386eSCy Schubert         break;
1070e0c4386eSCy Schubert 
1071e0c4386eSCy Schubert     case ED448_IDX:
1072e0c4386eSCy Schubert         fromdata_params = ed448_fromdata_params;
1073e0c4386eSCy Schubert         bits = ED448_BITS;
1074e0c4386eSCy Schubert         security_bits = ED448_SECURITY_BITS;
1075e0c4386eSCy Schubert         size = ED448_SIGSIZE;
1076e0c4386eSCy Schubert         alg = "ED448";
1077e0c4386eSCy Schubert         break;
1078e0c4386eSCy Schubert     default:
1079e0c4386eSCy Schubert         goto err;
1080e0c4386eSCy Schubert     }
1081e0c4386eSCy Schubert 
1082e0c4386eSCy Schubert     ctx = EVP_PKEY_CTX_new_from_name(NULL, alg, NULL);
1083e0c4386eSCy Schubert     if (!TEST_ptr(ctx))
1084e0c4386eSCy Schubert         goto err;
1085e0c4386eSCy Schubert 
1086e0c4386eSCy Schubert     orig_fromdata_params = fromdata_params;
1087e0c4386eSCy Schubert     if (tst > 7) {
1088e0c4386eSCy Schubert         /* public key only */
1089e0c4386eSCy Schubert         fromdata_params++;
1090e0c4386eSCy Schubert     } else if (tst > 3) {
1091e0c4386eSCy Schubert         /* private key only */
1092e0c4386eSCy Schubert         params[0] = fromdata_params[0];
1093e0c4386eSCy Schubert         params[1] = fromdata_params[2];
1094e0c4386eSCy Schubert         fromdata_params = params;
1095e0c4386eSCy Schubert     }
1096e0c4386eSCy Schubert 
1097e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1)
1098e0c4386eSCy Schubert         || !TEST_int_eq(EVP_PKEY_fromdata(ctx, &pk, EVP_PKEY_KEYPAIR,
1099e0c4386eSCy Schubert                                           fromdata_params), 1))
1100e0c4386eSCy Schubert         goto err;
1101e0c4386eSCy Schubert 
1102*44096ebdSEnji Cooper     for (;;) {
1103e0c4386eSCy Schubert         ret = 0;
1104e0c4386eSCy Schubert         if (!TEST_int_eq(EVP_PKEY_get_bits(pk), bits)
1105e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_security_bits(pk), security_bits)
1106e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_size(pk), size)
1107e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_missing_parameters(pk)))
1108e0c4386eSCy Schubert             goto err;
1109e0c4386eSCy Schubert 
1110e0c4386eSCy Schubert         if (!TEST_ptr(ctx2 = EVP_PKEY_CTX_new_from_pkey(NULL, pk, NULL)))
1111e0c4386eSCy Schubert             goto err;
1112e0c4386eSCy Schubert         if (tst <= 7) {
1113e0c4386eSCy Schubert             if (!TEST_int_gt(EVP_PKEY_check(ctx2), 0))
1114e0c4386eSCy Schubert                 goto err;
1115e0c4386eSCy Schubert             if (!TEST_true(EVP_PKEY_get_octet_string_param(
1116e0c4386eSCy Schubert                                pk, orig_fromdata_params[PRIV_KEY].key,
1117e0c4386eSCy Schubert                                out_priv, sizeof(out_priv), &len))
1118e0c4386eSCy Schubert                 || !TEST_mem_eq(out_priv, len,
1119e0c4386eSCy Schubert                                 orig_fromdata_params[PRIV_KEY].data,
1120e0c4386eSCy Schubert                                 orig_fromdata_params[PRIV_KEY].data_size)
1121e0c4386eSCy Schubert                 || !TEST_true(EVP_PKEY_get_octet_string_param(
1122e0c4386eSCy Schubert                                   pk, orig_fromdata_params[PUB_KEY].key,
1123e0c4386eSCy Schubert                                   out_pub, sizeof(out_pub), &len))
1124e0c4386eSCy Schubert                 || !TEST_mem_eq(out_pub, len,
1125e0c4386eSCy Schubert                                 orig_fromdata_params[PUB_KEY].data,
1126e0c4386eSCy Schubert                                 orig_fromdata_params[PUB_KEY].data_size))
1127e0c4386eSCy Schubert                 goto err;
1128e0c4386eSCy Schubert         } else {
1129e0c4386eSCy Schubert             /* The private key check should fail if there is only a public key */
1130e0c4386eSCy Schubert             if (!TEST_int_gt(EVP_PKEY_public_check(ctx2), 0)
1131e0c4386eSCy Schubert                 || !TEST_int_le(EVP_PKEY_private_check(ctx2), 0)
1132e0c4386eSCy Schubert                 || !TEST_int_le(EVP_PKEY_check(ctx2), 0))
1133e0c4386eSCy Schubert                 goto err;
1134e0c4386eSCy Schubert         }
1135e0c4386eSCy Schubert         EVP_PKEY_CTX_free(ctx2);
1136e0c4386eSCy Schubert         ctx2 = NULL;
1137e0c4386eSCy Schubert 
1138e0c4386eSCy Schubert         if (!TEST_ptr(copy_pk = EVP_PKEY_new())
1139e0c4386eSCy Schubert                /* This should succeed because there are no parameters to copy */
1140e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
1141e0c4386eSCy Schubert             goto err;
1142e0c4386eSCy Schubert         if (!TEST_ptr(ctx2 = EVP_PKEY_CTX_new_from_pkey(NULL, copy_pk, NULL))
1143e0c4386eSCy Schubert                /* This should fail because copy_pk has no pubkey */
1144e0c4386eSCy Schubert             || !TEST_int_le(EVP_PKEY_public_check(ctx2), 0))
1145e0c4386eSCy Schubert             goto err;
1146e0c4386eSCy Schubert         EVP_PKEY_CTX_free(ctx2);
1147e0c4386eSCy Schubert         ctx2 = NULL;
1148e0c4386eSCy Schubert         EVP_PKEY_free(copy_pk);
1149e0c4386eSCy Schubert         copy_pk = NULL;
1150e0c4386eSCy Schubert 
1151e0c4386eSCy Schubert         if (tst > 7)
1152e0c4386eSCy Schubert             ret = test_print_key_using_encoder_public(alg, pk);
1153e0c4386eSCy Schubert         else
1154e0c4386eSCy Schubert             ret = test_print_key_using_pem(alg, pk)
1155e0c4386eSCy Schubert                   && test_print_key_using_encoder(alg, pk);
1156e0c4386eSCy Schubert 
1157*44096ebdSEnji Cooper         if (!ret || dup_pk != NULL)
1158*44096ebdSEnji Cooper             break;
1159*44096ebdSEnji Cooper 
1160*44096ebdSEnji Cooper         if (!TEST_ptr(dup_pk = EVP_PKEY_dup(pk)))
1161e0c4386eSCy Schubert             goto err;
1162e0c4386eSCy Schubert         ret = ret && TEST_int_eq(EVP_PKEY_eq(pk, dup_pk), 1);
1163e0c4386eSCy Schubert         EVP_PKEY_free(pk);
1164e0c4386eSCy Schubert         pk = dup_pk;
1165e0c4386eSCy Schubert         if (!ret)
1166e0c4386eSCy Schubert             goto err;
1167e0c4386eSCy Schubert     }
1168e0c4386eSCy Schubert 
1169e0c4386eSCy Schubert err:
1170e0c4386eSCy Schubert     EVP_PKEY_free(pk);
1171e0c4386eSCy Schubert     EVP_PKEY_free(copy_pk);
1172e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
1173e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx2);
1174e0c4386eSCy Schubert 
1175e0c4386eSCy Schubert     return ret;
1176e0c4386eSCy Schubert }
1177e0c4386eSCy Schubert 
1178e0c4386eSCy Schubert static int test_fromdata_ec(void)
1179e0c4386eSCy Schubert {
1180e0c4386eSCy Schubert     int ret = 0;
1181e0c4386eSCy Schubert     EVP_PKEY_CTX *ctx = NULL;
1182e0c4386eSCy Schubert     EVP_PKEY *pk = NULL, *copy_pk = NULL, *dup_pk = NULL;
1183e0c4386eSCy Schubert     OSSL_PARAM_BLD *bld = NULL;
1184e0c4386eSCy Schubert     BIGNUM *ec_priv_bn = NULL;
1185e0c4386eSCy Schubert     BIGNUM *bn_priv = NULL;
1186e0c4386eSCy Schubert     OSSL_PARAM *fromdata_params = NULL;
1187e0c4386eSCy Schubert     const char *alg = "EC";
1188e0c4386eSCy Schubert     const char *curve = "prime256v1";
1189e0c4386eSCy Schubert     const char bad_curve[] = "nonexistent-curve";
1190e0c4386eSCy Schubert     OSSL_PARAM nokey_params[2] = {
1191e0c4386eSCy Schubert        OSSL_PARAM_END,
1192e0c4386eSCy Schubert        OSSL_PARAM_END
1193e0c4386eSCy Schubert     };
1194e0c4386eSCy Schubert     /* UNCOMPRESSED FORMAT */
1195e0c4386eSCy Schubert     static const unsigned char ec_pub_keydata[] = {
1196e0c4386eSCy Schubert        POINT_CONVERSION_UNCOMPRESSED,
1197e0c4386eSCy Schubert        0x1b, 0x93, 0x67, 0x55, 0x1c, 0x55, 0x9f, 0x63,
1198e0c4386eSCy Schubert        0xd1, 0x22, 0xa4, 0xd8, 0xd1, 0x0a, 0x60, 0x6d,
1199e0c4386eSCy Schubert        0x02, 0xa5, 0x77, 0x57, 0xc8, 0xa3, 0x47, 0x73,
1200e0c4386eSCy Schubert        0x3a, 0x6a, 0x08, 0x28, 0x39, 0xbd, 0xc9, 0xd2,
1201e0c4386eSCy Schubert        0x80, 0xec, 0xe9, 0xa7, 0x08, 0x29, 0x71, 0x2f,
1202e0c4386eSCy Schubert        0xc9, 0x56, 0x82, 0xee, 0x9a, 0x85, 0x0f, 0x6d,
1203e0c4386eSCy Schubert        0x7f, 0x59, 0x5f, 0x8c, 0xd1, 0x96, 0x0b, 0xdf,
1204e0c4386eSCy Schubert        0x29, 0x3e, 0x49, 0x07, 0x88, 0x3f, 0x9a, 0x29
1205e0c4386eSCy Schubert     };
1206e0c4386eSCy Schubert     /* SAME BUT COMPRESSED FORMAT */
1207e0c4386eSCy Schubert     static const unsigned char ec_pub_keydata_compressed[] = {
1208e0c4386eSCy Schubert        POINT_CONVERSION_COMPRESSED+1,
1209e0c4386eSCy Schubert        0x1b, 0x93, 0x67, 0x55, 0x1c, 0x55, 0x9f, 0x63,
1210e0c4386eSCy Schubert        0xd1, 0x22, 0xa4, 0xd8, 0xd1, 0x0a, 0x60, 0x6d,
1211e0c4386eSCy Schubert        0x02, 0xa5, 0x77, 0x57, 0xc8, 0xa3, 0x47, 0x73,
1212e0c4386eSCy Schubert        0x3a, 0x6a, 0x08, 0x28, 0x39, 0xbd, 0xc9, 0xd2
1213e0c4386eSCy Schubert     };
1214e0c4386eSCy Schubert     static const unsigned char ec_priv_keydata[] = {
1215e0c4386eSCy Schubert         0x33, 0xd0, 0x43, 0x83, 0xa9, 0x89, 0x56, 0x03,
1216e0c4386eSCy Schubert         0xd2, 0xd7, 0xfe, 0x6b, 0x01, 0x6f, 0xe4, 0x59,
1217e0c4386eSCy Schubert         0xcc, 0x0d, 0x9a, 0x24, 0x6c, 0x86, 0x1b, 0x2e,
1218e0c4386eSCy Schubert         0xdc, 0x4b, 0x4d, 0x35, 0x43, 0xe1, 0x1b, 0xad
1219e0c4386eSCy Schubert     };
1220e0c4386eSCy Schubert     unsigned char out_pub[sizeof(ec_pub_keydata)];
1221e0c4386eSCy Schubert     char out_curve_name[80];
1222e0c4386eSCy Schubert     const OSSL_PARAM *gettable = NULL;
1223e0c4386eSCy Schubert     size_t len;
1224e0c4386eSCy Schubert     EC_GROUP *group = NULL;
1225e0c4386eSCy Schubert     BIGNUM *group_a = NULL;
1226e0c4386eSCy Schubert     BIGNUM *group_b = NULL;
1227e0c4386eSCy Schubert     BIGNUM *group_p = NULL;
1228e0c4386eSCy Schubert     BIGNUM *a = NULL;
1229e0c4386eSCy Schubert     BIGNUM *b = NULL;
1230e0c4386eSCy Schubert     BIGNUM *p = NULL;
1231e0c4386eSCy Schubert 
1232e0c4386eSCy Schubert 
1233e0c4386eSCy Schubert     if (!TEST_ptr(bld = OSSL_PARAM_BLD_new()))
1234e0c4386eSCy Schubert         goto err;
1235e0c4386eSCy Schubert     if (!TEST_ptr(ec_priv_bn = BN_bin2bn(ec_priv_keydata,
1236e0c4386eSCy Schubert                                          sizeof(ec_priv_keydata), NULL)))
1237e0c4386eSCy Schubert         goto err;
1238e0c4386eSCy Schubert 
1239e0c4386eSCy Schubert     if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1240e0c4386eSCy Schubert                                         curve, 0) <= 0)
1241e0c4386eSCy Schubert         goto err;
1242e0c4386eSCy Schubert     /*
1243e0c4386eSCy Schubert      * We intentionally provide the input point in compressed format,
1244e0c4386eSCy Schubert      * and avoid setting `OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT`.
1245e0c4386eSCy Schubert      *
1246e0c4386eSCy Schubert      * Later on we check what format is used when exporting the
1247e0c4386eSCy Schubert      * `OSSL_PKEY_PARAM_PUB_KEY` and expect to default to uncompressed
1248e0c4386eSCy Schubert      * format.
1249e0c4386eSCy Schubert      */
1250e0c4386eSCy Schubert     if (OSSL_PARAM_BLD_push_octet_string(bld, OSSL_PKEY_PARAM_PUB_KEY,
1251e0c4386eSCy Schubert                                          ec_pub_keydata_compressed,
1252e0c4386eSCy Schubert                                          sizeof(ec_pub_keydata_compressed)) <= 0)
1253e0c4386eSCy Schubert         goto err;
1254e0c4386eSCy Schubert     if (OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY, ec_priv_bn) <= 0)
1255e0c4386eSCy Schubert         goto err;
1256e0c4386eSCy Schubert     if (!TEST_ptr(fromdata_params = OSSL_PARAM_BLD_to_param(bld)))
1257e0c4386eSCy Schubert         goto err;
1258e0c4386eSCy Schubert     ctx = EVP_PKEY_CTX_new_from_name(NULL, alg, NULL);
1259e0c4386eSCy Schubert     if (!TEST_ptr(ctx))
1260e0c4386eSCy Schubert         goto err;
1261e0c4386eSCy Schubert 
1262e0c4386eSCy Schubert     /* try importing parameters with bad curve first */
1263e0c4386eSCy Schubert     nokey_params[0] =
1264e0c4386eSCy Schubert         OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME,
1265e0c4386eSCy Schubert                                          (char *)bad_curve, sizeof(bad_curve));
1266e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1)
1267e0c4386eSCy Schubert         || !TEST_int_eq(EVP_PKEY_fromdata(ctx, &pk, EVP_PKEY_KEY_PARAMETERS,
1268e0c4386eSCy Schubert                                           nokey_params), 0)
1269e0c4386eSCy Schubert         || !TEST_ptr_null(pk))
1270e0c4386eSCy Schubert         goto err;
1271e0c4386eSCy Schubert 
1272e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1)
1273e0c4386eSCy Schubert         || !TEST_int_eq(EVP_PKEY_fromdata(ctx, &pk, EVP_PKEY_KEYPAIR,
1274e0c4386eSCy Schubert                                           fromdata_params), 1))
1275e0c4386eSCy Schubert         goto err;
1276e0c4386eSCy Schubert 
1277*44096ebdSEnji Cooper     for (;;) {
1278e0c4386eSCy Schubert         ret = 0;
1279e0c4386eSCy Schubert         if (!TEST_int_eq(EVP_PKEY_get_bits(pk), 256)
1280e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_security_bits(pk), 128)
1281e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_size(pk), 2 + 35 * 2)
1282e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_missing_parameters(pk)))
1283e0c4386eSCy Schubert             goto err;
1284e0c4386eSCy Schubert 
1285e0c4386eSCy Schubert         if (!TEST_ptr(copy_pk = EVP_PKEY_new())
1286e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
1287e0c4386eSCy Schubert             goto err;
1288e0c4386eSCy Schubert         EVP_PKEY_free(copy_pk);
1289e0c4386eSCy Schubert         copy_pk = NULL;
1290e0c4386eSCy Schubert 
1291e0c4386eSCy Schubert         if (!TEST_ptr(gettable = EVP_PKEY_gettable_params(pk))
1292e0c4386eSCy Schubert             || !TEST_ptr(OSSL_PARAM_locate_const(gettable,
1293e0c4386eSCy Schubert                                                  OSSL_PKEY_PARAM_GROUP_NAME))
1294e0c4386eSCy Schubert             || !TEST_ptr(OSSL_PARAM_locate_const(gettable,
1295e0c4386eSCy Schubert                                                  OSSL_PKEY_PARAM_PUB_KEY))
1296e0c4386eSCy Schubert             || !TEST_ptr(OSSL_PARAM_locate_const(gettable,
1297e0c4386eSCy Schubert                                                  OSSL_PKEY_PARAM_PRIV_KEY)))
1298e0c4386eSCy Schubert             goto err;
1299e0c4386eSCy Schubert 
1300e0c4386eSCy Schubert         if (!TEST_ptr(group = EC_GROUP_new_by_curve_name(OBJ_sn2nid(curve)))
1301e0c4386eSCy Schubert             || !TEST_ptr(group_p = BN_new())
1302e0c4386eSCy Schubert             || !TEST_ptr(group_a = BN_new())
1303e0c4386eSCy Schubert             || !TEST_ptr(group_b = BN_new())
1304e0c4386eSCy Schubert             || !TEST_true(EC_GROUP_get_curve(group, group_p, group_a, group_b, NULL)))
1305e0c4386eSCy Schubert             goto err;
1306e0c4386eSCy Schubert 
1307e0c4386eSCy Schubert         if (!TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_EC_A, &a))
1308e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_EC_B, &b))
1309e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_EC_P, &p)))
1310e0c4386eSCy Schubert             goto err;
1311e0c4386eSCy Schubert 
1312e0c4386eSCy Schubert         if (!TEST_BN_eq(group_p, p) || !TEST_BN_eq(group_a, a)
1313e0c4386eSCy Schubert             || !TEST_BN_eq(group_b, b))
1314e0c4386eSCy Schubert             goto err;
1315e0c4386eSCy Schubert 
1316*44096ebdSEnji Cooper         EC_GROUP_free(group);
1317*44096ebdSEnji Cooper         group = NULL;
1318*44096ebdSEnji Cooper         BN_free(group_p);
1319*44096ebdSEnji Cooper         group_p = NULL;
1320*44096ebdSEnji Cooper         BN_free(group_a);
1321*44096ebdSEnji Cooper         group_a = NULL;
1322*44096ebdSEnji Cooper         BN_free(group_b);
1323*44096ebdSEnji Cooper         group_b = NULL;
1324*44096ebdSEnji Cooper 
1325e0c4386eSCy Schubert         if (!EVP_PKEY_get_utf8_string_param(pk, OSSL_PKEY_PARAM_GROUP_NAME,
1326e0c4386eSCy Schubert                                             out_curve_name,
1327e0c4386eSCy Schubert                                             sizeof(out_curve_name),
1328e0c4386eSCy Schubert                                             &len)
1329e0c4386eSCy Schubert             || !TEST_str_eq(out_curve_name, curve)
1330e0c4386eSCy Schubert             || !EVP_PKEY_get_octet_string_param(pk, OSSL_PKEY_PARAM_PUB_KEY,
1331e0c4386eSCy Schubert                                             out_pub, sizeof(out_pub), &len)
1332e0c4386eSCy Schubert 
1333e0c4386eSCy Schubert             /*
1334e0c4386eSCy Schubert              * Our providers use uncompressed format by default if
1335e0c4386eSCy Schubert              * `OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT` was not
1336e0c4386eSCy Schubert              * explicitly set, irrespective of the format used for the
1337e0c4386eSCy Schubert              * input point given as a param to create this key.
1338e0c4386eSCy Schubert              */
1339e0c4386eSCy Schubert             || !TEST_true(out_pub[0] == POINT_CONVERSION_UNCOMPRESSED)
1340e0c4386eSCy Schubert             || !TEST_mem_eq(out_pub + 1, len - 1,
1341e0c4386eSCy Schubert                             ec_pub_keydata + 1, sizeof(ec_pub_keydata) - 1)
1342e0c4386eSCy Schubert 
1343e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY,
1344e0c4386eSCy Schubert                                                 &bn_priv))
1345e0c4386eSCy Schubert             || !TEST_BN_eq(ec_priv_bn, bn_priv))
1346e0c4386eSCy Schubert             goto err;
1347e0c4386eSCy Schubert         BN_free(bn_priv);
1348e0c4386eSCy Schubert         bn_priv = NULL;
1349e0c4386eSCy Schubert 
1350e0c4386eSCy Schubert         ret = test_print_key_using_pem(alg, pk)
1351e0c4386eSCy Schubert               && test_print_key_using_encoder(alg, pk);
1352e0c4386eSCy Schubert 
1353*44096ebdSEnji Cooper         if (!ret || dup_pk != NULL)
1354*44096ebdSEnji Cooper             break;
1355*44096ebdSEnji Cooper 
1356*44096ebdSEnji Cooper         if (!TEST_ptr(dup_pk = EVP_PKEY_dup(pk)))
1357e0c4386eSCy Schubert             goto err;
1358e0c4386eSCy Schubert         ret = ret && TEST_int_eq(EVP_PKEY_eq(pk, dup_pk), 1);
1359e0c4386eSCy Schubert         EVP_PKEY_free(pk);
1360e0c4386eSCy Schubert         pk = dup_pk;
1361e0c4386eSCy Schubert         if (!ret)
1362e0c4386eSCy Schubert             goto err;
1363e0c4386eSCy Schubert     }
1364e0c4386eSCy Schubert 
1365e0c4386eSCy Schubert err:
1366e0c4386eSCy Schubert     EC_GROUP_free(group);
1367e0c4386eSCy Schubert     BN_free(group_a);
1368e0c4386eSCy Schubert     BN_free(group_b);
1369e0c4386eSCy Schubert     BN_free(group_p);
1370e0c4386eSCy Schubert     BN_free(a);
1371e0c4386eSCy Schubert     BN_free(b);
1372e0c4386eSCy Schubert     BN_free(p);
1373e0c4386eSCy Schubert     BN_free(bn_priv);
1374e0c4386eSCy Schubert     BN_free(ec_priv_bn);
1375e0c4386eSCy Schubert     OSSL_PARAM_free(fromdata_params);
1376e0c4386eSCy Schubert     OSSL_PARAM_BLD_free(bld);
1377e0c4386eSCy Schubert     EVP_PKEY_free(pk);
1378e0c4386eSCy Schubert     EVP_PKEY_free(copy_pk);
1379e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
1380e0c4386eSCy Schubert     return ret;
1381e0c4386eSCy Schubert }
1382e0c4386eSCy Schubert 
1383e0c4386eSCy Schubert static int test_ec_dup_no_operation(void)
1384e0c4386eSCy Schubert {
1385e0c4386eSCy Schubert     int ret = 0;
1386e0c4386eSCy Schubert     EVP_PKEY_CTX *pctx = NULL, *ctx = NULL, *kctx = NULL;
1387e0c4386eSCy Schubert     EVP_PKEY *param = NULL, *pkey = NULL;
1388e0c4386eSCy Schubert 
1389e0c4386eSCy Schubert     if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))
1390e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_paramgen_init(pctx), 0)
1391e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1392e0c4386eSCy Schubert                         NID_X9_62_prime256v1), 0)
1393e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_paramgen(pctx, &param), 0)
1394e0c4386eSCy Schubert         || !TEST_ptr(param))
1395e0c4386eSCy Schubert         goto err;
1396e0c4386eSCy Schubert 
1397e0c4386eSCy Schubert     EVP_PKEY_CTX_free(pctx);
1398e0c4386eSCy Schubert     pctx = NULL;
1399e0c4386eSCy Schubert 
1400e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(NULL, param, NULL))
1401e0c4386eSCy Schubert         || !TEST_ptr(kctx = EVP_PKEY_CTX_dup(ctx))
1402e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_keygen_init(kctx), 0)
1403e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_keygen(kctx, &pkey), 0))
1404e0c4386eSCy Schubert         goto err;
1405e0c4386eSCy Schubert     ret = 1;
1406e0c4386eSCy Schubert err:
1407e0c4386eSCy Schubert     EVP_PKEY_free(pkey);
1408e0c4386eSCy Schubert     EVP_PKEY_free(param);
1409e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
1410e0c4386eSCy Schubert     EVP_PKEY_CTX_free(kctx);
1411e0c4386eSCy Schubert     EVP_PKEY_CTX_free(pctx);
1412e0c4386eSCy Schubert     return ret;
1413e0c4386eSCy Schubert }
1414e0c4386eSCy Schubert 
1415e0c4386eSCy Schubert /* Test that keygen doesn't support EVP_PKEY_CTX_dup */
1416e0c4386eSCy Schubert static int test_ec_dup_keygen_operation(void)
1417e0c4386eSCy Schubert {
1418e0c4386eSCy Schubert     int ret = 0;
1419e0c4386eSCy Schubert     EVP_PKEY_CTX *pctx = NULL, *ctx = NULL, *kctx = NULL;
1420e0c4386eSCy Schubert     EVP_PKEY *param = NULL, *pkey = NULL;
1421e0c4386eSCy Schubert 
1422e0c4386eSCy Schubert     if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))
1423e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_paramgen_init(pctx), 0)
1424e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx,
1425e0c4386eSCy Schubert                         NID_X9_62_prime256v1), 0)
1426e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_paramgen(pctx, &param), 0)
1427e0c4386eSCy Schubert         || !TEST_ptr(param))
1428e0c4386eSCy Schubert         goto err;
1429e0c4386eSCy Schubert 
1430e0c4386eSCy Schubert     EVP_PKEY_CTX_free(pctx);
1431e0c4386eSCy Schubert     pctx = NULL;
1432e0c4386eSCy Schubert 
1433e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(NULL, param, NULL))
1434e0c4386eSCy Schubert         || !TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)
1435e0c4386eSCy Schubert         || !TEST_ptr_null(kctx = EVP_PKEY_CTX_dup(ctx)))
1436e0c4386eSCy Schubert         goto err;
1437e0c4386eSCy Schubert     ret = 1;
1438e0c4386eSCy Schubert err:
1439e0c4386eSCy Schubert     EVP_PKEY_free(pkey);
1440e0c4386eSCy Schubert     EVP_PKEY_free(param);
1441e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
1442e0c4386eSCy Schubert     EVP_PKEY_CTX_free(kctx);
1443e0c4386eSCy Schubert     EVP_PKEY_CTX_free(pctx);
1444e0c4386eSCy Schubert     return ret;
1445e0c4386eSCy Schubert }
1446e0c4386eSCy Schubert 
1447e0c4386eSCy Schubert #endif /* OPENSSL_NO_EC */
1448e0c4386eSCy Schubert 
1449e0c4386eSCy Schubert #ifndef OPENSSL_NO_DSA
1450e0c4386eSCy Schubert static int test_fromdata_dsa_fips186_4(void)
1451e0c4386eSCy Schubert {
1452e0c4386eSCy Schubert     int ret = 0;
1453e0c4386eSCy Schubert     EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
1454e0c4386eSCy Schubert     EVP_PKEY *pk = NULL, *copy_pk = NULL, *dup_pk = NULL;
1455e0c4386eSCy Schubert     BIGNUM *pub = NULL, *priv = NULL;
1456e0c4386eSCy Schubert     BIGNUM *p = NULL, *q = NULL, *g = NULL;
1457e0c4386eSCy Schubert     BIGNUM *pub_out = NULL, *priv_out = NULL;
1458e0c4386eSCy Schubert     BIGNUM *p_out = NULL, *q_out = NULL, *g_out = NULL, *j_out = NULL;
1459e0c4386eSCy Schubert     int gindex_out = 0, pcounter_out = 0, hindex_out = 0;
1460e0c4386eSCy Schubert     char name_out[80];
1461e0c4386eSCy Schubert     unsigned char seed_out[32];
1462e0c4386eSCy Schubert     size_t len;
1463e0c4386eSCy Schubert     OSSL_PARAM_BLD *bld = NULL;
1464e0c4386eSCy Schubert     OSSL_PARAM *fromdata_params = NULL;
1465e0c4386eSCy Schubert 
1466e0c4386eSCy Schubert     /*
1467e0c4386eSCy Schubert      * DSA parameter data was generated using the following:
1468e0c4386eSCy Schubert      * openssl genpkey -genparam -algorithm DSA -pkeyopt pbits:2048 \
1469e0c4386eSCy Schubert      *                 -pkeyopt qbits:256 -pkeyopt type:0 \
1470e0c4386eSCy Schubert      *                 -pkeyopt gindex:1 -out dsa_params.pem -text
1471e0c4386eSCy Schubert      */
1472e0c4386eSCy Schubert     static const unsigned char p_data[] = {
1473e0c4386eSCy Schubert         0x00, 0xa0, 0xb7, 0x02, 0xc4, 0xac, 0xa6, 0x42, 0xab, 0xf2, 0x34, 0x0b,
1474e0c4386eSCy Schubert         0x22, 0x47, 0x1f, 0x33, 0xcf, 0xd5, 0x04, 0xe4, 0x3e, 0xec, 0xa1, 0x21,
1475e0c4386eSCy Schubert         0xc8, 0x41, 0x2b, 0xef, 0xb8, 0x1f, 0x0b, 0x5b, 0x88, 0x8b, 0x67, 0xf8,
1476e0c4386eSCy Schubert         0x68, 0x6d, 0x7c, 0x4d, 0x96, 0x5f, 0x3c, 0x66, 0xef, 0x58, 0x34, 0xd7,
1477e0c4386eSCy Schubert         0xf6, 0xa2, 0x1b, 0xad, 0xc8, 0x12, 0x52, 0xb8, 0xe8, 0x2a, 0x63, 0xcc,
1478e0c4386eSCy Schubert         0xea, 0xe7, 0x4e, 0xc8, 0x34, 0x4c, 0x58, 0x59, 0x0a, 0xc2, 0x4a, 0xe4,
1479e0c4386eSCy Schubert         0xb4, 0x64, 0x20, 0xf4, 0xf6, 0x0a, 0xcf, 0x86, 0x01, 0x6c, 0x7f, 0x23,
1480e0c4386eSCy Schubert         0x4a, 0x51, 0x07, 0x99, 0x42, 0x28, 0x7a, 0xff, 0x18, 0x67, 0x52, 0x64,
1481e0c4386eSCy Schubert         0xf2, 0x9a, 0x62, 0x30, 0xc3, 0x00, 0xde, 0x23, 0xe9, 0x11, 0x95, 0x7e,
1482e0c4386eSCy Schubert         0xd1, 0x3d, 0x8d, 0xb4, 0x0e, 0x9f, 0x9e, 0xb1, 0x30, 0x03, 0xf0, 0x73,
1483e0c4386eSCy Schubert         0xa8, 0x40, 0x48, 0x42, 0x7b, 0x60, 0xa0, 0xc4, 0xf2, 0x3b, 0x2d, 0x0a,
1484e0c4386eSCy Schubert         0x0c, 0xb8, 0x19, 0xfb, 0xb4, 0xf8, 0xe0, 0x2a, 0xc7, 0xf1, 0xc0, 0xc6,
1485e0c4386eSCy Schubert         0x86, 0x14, 0x60, 0x12, 0x0f, 0xc0, 0xde, 0x4a, 0x67, 0xec, 0xc7, 0xde,
1486e0c4386eSCy Schubert         0x76, 0x21, 0x1a, 0x55, 0x7f, 0x86, 0xc3, 0x97, 0x98, 0xce, 0xf5, 0xcd,
1487e0c4386eSCy Schubert         0xf0, 0xe7, 0x12, 0xd6, 0x93, 0xee, 0x1b, 0x9b, 0x61, 0xef, 0x05, 0x8c,
1488e0c4386eSCy Schubert         0x45, 0x46, 0xd9, 0x64, 0x6f, 0xbe, 0x27, 0xaa, 0x67, 0x01, 0xcc, 0x71,
1489e0c4386eSCy Schubert         0xb1, 0x60, 0xce, 0x21, 0xd8, 0x51, 0x17, 0x27, 0x0d, 0x90, 0x3d, 0x18,
1490e0c4386eSCy Schubert         0x7c, 0x87, 0x15, 0x8e, 0x48, 0x4c, 0x6c, 0xc5, 0x72, 0xeb, 0xb7, 0x56,
1491e0c4386eSCy Schubert         0xf5, 0x6b, 0x60, 0x8f, 0xc2, 0xfd, 0x3f, 0x46, 0x5c, 0x00, 0x91, 0x85,
1492e0c4386eSCy Schubert         0x79, 0x45, 0x5b, 0x1c, 0x82, 0xc4, 0x87, 0x50, 0x79, 0xba, 0xcc, 0x1c,
1493e0c4386eSCy Schubert         0x32, 0x7e, 0x2e, 0xb8, 0x2e, 0xc5, 0x4e, 0xd1, 0x9b, 0xdb, 0x66, 0x79,
1494e0c4386eSCy Schubert         0x7c, 0xfe, 0xaf, 0x6a, 0x05
1495e0c4386eSCy Schubert     };
1496e0c4386eSCy Schubert     static const unsigned char q_data[] = {
1497e0c4386eSCy Schubert         0xa8, 0xcd, 0xf4, 0x33, 0x7b, 0x13, 0x0a, 0x24, 0xc1, 0xde, 0x4a, 0x04,
1498e0c4386eSCy Schubert         0x7b, 0x4b, 0x71, 0x51, 0x32, 0xe9, 0x47, 0x74, 0xbd, 0x0c, 0x21, 0x40,
1499e0c4386eSCy Schubert         0x84, 0x12, 0x0a, 0x17, 0x73, 0xdb, 0x29, 0xc7
1500e0c4386eSCy Schubert     };
1501e0c4386eSCy Schubert     static const unsigned char g_data[] = {
1502e0c4386eSCy Schubert         0x6c, 0xc6, 0xa4, 0x3e, 0x61, 0x84, 0xc1, 0xff, 0x6f, 0x4a, 0x1a, 0x6b,
1503e0c4386eSCy Schubert         0xb0, 0x24, 0x4b, 0xd2, 0x92, 0x5b, 0x29, 0x5c, 0x61, 0xb8, 0xc9, 0x2b,
1504e0c4386eSCy Schubert         0xd6, 0xf7, 0x59, 0xfd, 0xd8, 0x70, 0x66, 0x77, 0xfc, 0xc1, 0xa4, 0xd4,
1505e0c4386eSCy Schubert         0xb0, 0x1e, 0xd5, 0xbf, 0x59, 0x98, 0xb3, 0x66, 0x8b, 0xf4, 0x2e, 0xe6,
1506e0c4386eSCy Schubert         0x12, 0x3e, 0xcc, 0xf8, 0x02, 0xb8, 0xc6, 0xc3, 0x47, 0xd2, 0xf5, 0xaa,
1507e0c4386eSCy Schubert         0x0c, 0x5f, 0x51, 0xf5, 0xd0, 0x4c, 0x55, 0x3d, 0x07, 0x73, 0xa6, 0x57,
1508e0c4386eSCy Schubert         0xce, 0x5a, 0xad, 0x42, 0x0c, 0x13, 0x0f, 0xe2, 0x31, 0x25, 0x8e, 0x72,
1509e0c4386eSCy Schubert         0x12, 0x73, 0x10, 0xdb, 0x7f, 0x79, 0xeb, 0x59, 0xfc, 0xfe, 0xf7, 0x0c,
1510e0c4386eSCy Schubert         0x1a, 0x81, 0x53, 0x96, 0x22, 0xb8, 0xe7, 0x58, 0xd8, 0x67, 0x80, 0x60,
1511e0c4386eSCy Schubert         0xad, 0x8b, 0x55, 0x1c, 0x91, 0xf0, 0x72, 0x9a, 0x7e, 0xad, 0x37, 0xf1,
1512e0c4386eSCy Schubert         0x77, 0x18, 0x96, 0x8a, 0x68, 0x70, 0xfc, 0x71, 0xa9, 0xa2, 0xe8, 0x35,
1513e0c4386eSCy Schubert         0x27, 0x78, 0xf2, 0xef, 0x59, 0x36, 0x6d, 0x7c, 0xb6, 0x98, 0xd8, 0x1e,
1514e0c4386eSCy Schubert         0xfa, 0x25, 0x73, 0x97, 0x45, 0x58, 0xe3, 0xae, 0xbd, 0x52, 0x54, 0x05,
1515e0c4386eSCy Schubert         0xd8, 0x26, 0x26, 0xba, 0xba, 0x05, 0xb5, 0xe9, 0xe5, 0x76, 0xae, 0x25,
1516e0c4386eSCy Schubert         0xdd, 0xfc, 0x10, 0x89, 0x5a, 0xa9, 0xee, 0x59, 0xc5, 0x79, 0x8b, 0xeb,
1517e0c4386eSCy Schubert         0x1e, 0x2c, 0x61, 0xab, 0x0d, 0xd1, 0x10, 0x04, 0x91, 0x32, 0x77, 0x4a,
1518e0c4386eSCy Schubert         0xa6, 0x64, 0x53, 0xda, 0x4c, 0xd7, 0x3a, 0x29, 0xd4, 0xf3, 0x82, 0x25,
1519e0c4386eSCy Schubert         0x1d, 0x6f, 0x4a, 0x7f, 0xd3, 0x08, 0x3b, 0x42, 0x30, 0x10, 0xd8, 0xd0,
1520e0c4386eSCy Schubert         0x97, 0x3a, 0xeb, 0x92, 0x63, 0xec, 0x93, 0x2b, 0x6f, 0x32, 0xd8, 0xcd,
1521e0c4386eSCy Schubert         0x80, 0xd3, 0xc0, 0x4c, 0x03, 0xd5, 0xca, 0xbc, 0x8f, 0xc7, 0x43, 0x53,
1522e0c4386eSCy Schubert         0x64, 0x66, 0x1c, 0x82, 0x2d, 0xfb, 0xff, 0x39, 0xba, 0xd6, 0x42, 0x62,
1523e0c4386eSCy Schubert         0x02, 0x6f, 0x96, 0x36
1524e0c4386eSCy Schubert     };
1525e0c4386eSCy Schubert     static const unsigned char seed_data[] = {
1526e0c4386eSCy Schubert         0x64, 0x46, 0x07, 0x32, 0x8d, 0x70, 0x9c, 0xb3, 0x8a, 0x35, 0xde, 0x62,
1527e0c4386eSCy Schubert         0x00, 0xf2, 0x6d, 0x52, 0x37, 0x4d, 0xb3, 0x84, 0xe1, 0x9d, 0x41, 0x04,
1528e0c4386eSCy Schubert         0xda, 0x7b, 0xdc, 0x0d, 0x8b, 0x5e, 0xe0, 0x84
1529e0c4386eSCy Schubert     };
1530e0c4386eSCy Schubert     const int gindex = 1;
1531e0c4386eSCy Schubert     const int pcounter = 53;
1532e0c4386eSCy Schubert     /*
1533e0c4386eSCy Schubert      * The keypair was generated using
1534e0c4386eSCy Schubert      * openssl genpkey -paramfile dsa_params.pem --pkeyopt pcounter:53 \
1535e0c4386eSCy Schubert      *                 -pkeyopt gindex:1 \
1536e0c4386eSCy Schubert      *                 -pkeyopt hexseed:644607328d709cb38a35de6200f26d -text
1537e0c4386eSCy Schubert      */
1538e0c4386eSCy Schubert     static const unsigned char priv_data[] = {
1539e0c4386eSCy Schubert         0x00, 0x8f, 0xc5, 0x9e, 0xd0, 0xf7, 0x2a, 0x0b, 0x66, 0xf1, 0x32, 0x73,
1540e0c4386eSCy Schubert         0xae, 0xf6, 0xd9, 0xd4, 0xdb, 0x2d, 0x96, 0x55, 0x89, 0xff, 0xef, 0xa8,
1541e0c4386eSCy Schubert         0x5f, 0x47, 0x8f, 0xca, 0x02, 0x8a, 0xe1, 0x35, 0x90
1542e0c4386eSCy Schubert     };
1543e0c4386eSCy Schubert     static const unsigned char pub_data[] = {
1544e0c4386eSCy Schubert         0x44, 0x19, 0xc9, 0x46, 0x45, 0x57, 0xc1, 0xa9, 0xd8, 0x30, 0x99, 0x29,
1545e0c4386eSCy Schubert         0x6a, 0x4b, 0x63, 0x71, 0x69, 0x96, 0x35, 0x17, 0xb2, 0x62, 0x9b, 0x80,
1546e0c4386eSCy Schubert         0x0a, 0x95, 0x9d, 0x6a, 0xc0, 0x32, 0x0d, 0x07, 0x5f, 0x19, 0x44, 0x02,
1547e0c4386eSCy Schubert         0xf1, 0xbd, 0xce, 0xdf, 0x10, 0xf8, 0x02, 0x5d, 0x7d, 0x98, 0x8a, 0x73,
1548e0c4386eSCy Schubert         0x89, 0x00, 0xb6, 0x24, 0xd6, 0x33, 0xe7, 0xcf, 0x8b, 0x49, 0x2a, 0xaf,
1549e0c4386eSCy Schubert         0x13, 0x1c, 0xb2, 0x52, 0x15, 0xfd, 0x9b, 0xd5, 0x40, 0x4a, 0x1a, 0xda,
1550e0c4386eSCy Schubert         0x29, 0x4c, 0x92, 0x7e, 0x66, 0x06, 0xdb, 0x61, 0x86, 0xac, 0xb5, 0xda,
1551e0c4386eSCy Schubert         0x3c, 0x7d, 0x73, 0x7e, 0x54, 0x32, 0x68, 0xa5, 0x02, 0xbc, 0x59, 0x47,
1552e0c4386eSCy Schubert         0x84, 0xd3, 0x87, 0x71, 0x5f, 0xeb, 0x43, 0x45, 0x24, 0xd3, 0xec, 0x08,
1553e0c4386eSCy Schubert         0x52, 0xc2, 0x89, 0x2d, 0x9c, 0x1a, 0xcc, 0x91, 0x65, 0x5d, 0xa3, 0xa1,
1554e0c4386eSCy Schubert         0x35, 0x31, 0x10, 0x1c, 0x3a, 0xa8, 0x4d, 0x18, 0xd5, 0x06, 0xaf, 0xb2,
1555e0c4386eSCy Schubert         0xec, 0x5c, 0x89, 0x9e, 0x90, 0x86, 0x10, 0x01, 0xeb, 0x51, 0xd5, 0x1b,
1556e0c4386eSCy Schubert         0x9c, 0xcb, 0x66, 0x07, 0x3f, 0xc4, 0x6e, 0x0a, 0x1b, 0x73, 0xa0, 0x4b,
1557e0c4386eSCy Schubert         0x5f, 0x4d, 0xab, 0x35, 0x28, 0xfa, 0xda, 0x3a, 0x0c, 0x08, 0xe8, 0xf3,
1558e0c4386eSCy Schubert         0xef, 0x42, 0x67, 0xbc, 0x21, 0xf2, 0xc2, 0xb8, 0xff, 0x1a, 0x81, 0x05,
1559e0c4386eSCy Schubert         0x68, 0x73, 0x62, 0xdf, 0xd7, 0xab, 0x0f, 0x22, 0x89, 0x57, 0x96, 0xd4,
1560e0c4386eSCy Schubert         0x93, 0xaf, 0xa1, 0x21, 0xa3, 0x48, 0xe9, 0xf0, 0x97, 0x47, 0xa0, 0x27,
1561e0c4386eSCy Schubert         0xba, 0x87, 0xb8, 0x15, 0x5f, 0xff, 0x2c, 0x50, 0x41, 0xf1, 0x7e, 0xc6,
1562e0c4386eSCy Schubert         0x81, 0xc4, 0x51, 0xf1, 0xfd, 0xd6, 0x86, 0xf7, 0x69, 0x97, 0xf1, 0x49,
1563e0c4386eSCy Schubert         0xc9, 0xf9, 0xf4, 0x9b, 0xf4, 0xe8, 0x85, 0xa7, 0xbd, 0x36, 0x55, 0x4a,
1564e0c4386eSCy Schubert         0x3d, 0xe8, 0x65, 0x09, 0x7b, 0xb7, 0x12, 0x64, 0xd2, 0x0a, 0x53, 0x60,
1565e0c4386eSCy Schubert         0x48, 0xd1, 0x8a, 0xbd
1566e0c4386eSCy Schubert     };
1567e0c4386eSCy Schubert 
1568e0c4386eSCy Schubert     if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
1569e0c4386eSCy Schubert         || !TEST_ptr(pub = BN_bin2bn(pub_data, sizeof(pub_data), NULL))
1570e0c4386eSCy Schubert         || !TEST_ptr(priv = BN_bin2bn(priv_data, sizeof(priv_data), NULL))
1571e0c4386eSCy Schubert         || !TEST_ptr(p = BN_bin2bn(p_data, sizeof(p_data), NULL))
1572e0c4386eSCy Schubert         || !TEST_ptr(q = BN_bin2bn(q_data, sizeof(q_data), NULL))
1573e0c4386eSCy Schubert         || !TEST_ptr(g = BN_bin2bn(g_data, sizeof(g_data), NULL))
1574e0c4386eSCy Schubert 
1575e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p))
1576e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_Q, q))
1577e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_G, g))
1578e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
1579e0c4386eSCy Schubert                                                        OSSL_PKEY_PARAM_FFC_SEED,
1580e0c4386eSCy Schubert                                                        seed_data,
1581e0c4386eSCy Schubert                                                        sizeof(seed_data)))
1582e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_int(bld, OSSL_PKEY_PARAM_FFC_GINDEX,
1583e0c4386eSCy Schubert                                               gindex))
1584e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_int(bld,
1585e0c4386eSCy Schubert                                               OSSL_PKEY_PARAM_FFC_PCOUNTER,
1586e0c4386eSCy Schubert                                               pcounter))
1587e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY,
1588e0c4386eSCy Schubert                                              pub))
1589e0c4386eSCy Schubert         || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY,
1590e0c4386eSCy Schubert                                              priv))
1591e0c4386eSCy Schubert         || !TEST_ptr(fromdata_params = OSSL_PARAM_BLD_to_param(bld)))
1592e0c4386eSCy Schubert         goto err;
1593e0c4386eSCy Schubert 
1594e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL)))
1595e0c4386eSCy Schubert         goto err;
1596e0c4386eSCy Schubert 
1597e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1)
1598e0c4386eSCy Schubert         || !TEST_int_eq(EVP_PKEY_fromdata(ctx, &pk, EVP_PKEY_KEYPAIR,
1599e0c4386eSCy Schubert                                           fromdata_params), 1))
1600e0c4386eSCy Schubert         goto err;
1601e0c4386eSCy Schubert 
1602*44096ebdSEnji Cooper     for (;;) {
1603e0c4386eSCy Schubert         ret = 0;
1604e0c4386eSCy Schubert         if (!TEST_int_eq(EVP_PKEY_get_bits(pk), 2048)
1605e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_security_bits(pk), 112)
1606e0c4386eSCy Schubert             || !TEST_int_eq(EVP_PKEY_get_size(pk), 2 + 2 * (3 + sizeof(q_data)))
1607e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_missing_parameters(pk)))
1608e0c4386eSCy Schubert             goto err;
1609e0c4386eSCy Schubert 
1610e0c4386eSCy Schubert         if (!TEST_false(EVP_PKEY_get_utf8_string_param(pk,
1611e0c4386eSCy Schubert                                                        OSSL_PKEY_PARAM_GROUP_NAME,
1612e0c4386eSCy Schubert                                                        name_out,
1613e0c4386eSCy Schubert                                                        sizeof(name_out),
1614e0c4386eSCy Schubert                                                        &len))
1615e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PUB_KEY,
1616e0c4386eSCy Schubert                                                 &pub_out))
1617e0c4386eSCy Schubert             || !TEST_BN_eq(pub, pub_out)
1618e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_PRIV_KEY,
1619e0c4386eSCy Schubert                                                 &priv_out))
1620e0c4386eSCy Schubert             || !TEST_BN_eq(priv, priv_out)
1621e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_P,
1622e0c4386eSCy Schubert                                                 &p_out))
1623e0c4386eSCy Schubert             || !TEST_BN_eq(p, p_out)
1624e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_Q,
1625e0c4386eSCy Schubert                                                 &q_out))
1626e0c4386eSCy Schubert             || !TEST_BN_eq(q, q_out)
1627e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_bn_param(pk, OSSL_PKEY_PARAM_FFC_G,
1628e0c4386eSCy Schubert                                                 &g_out))
1629e0c4386eSCy Schubert             || !TEST_BN_eq(g, g_out)
1630e0c4386eSCy Schubert             || !TEST_false(EVP_PKEY_get_bn_param(pk,
1631e0c4386eSCy Schubert                                                  OSSL_PKEY_PARAM_FFC_COFACTOR,
1632e0c4386eSCy Schubert                                                  &j_out))
1633e0c4386eSCy Schubert             || !TEST_ptr_null(j_out)
1634e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_octet_string_param(pk,
1635e0c4386eSCy Schubert                                                           OSSL_PKEY_PARAM_FFC_SEED,
1636e0c4386eSCy Schubert                                                           seed_out,
1637e0c4386eSCy Schubert                                                           sizeof(seed_out),
1638e0c4386eSCy Schubert                                                           &len))
1639e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_int_param(pk,
1640e0c4386eSCy Schubert                                                  OSSL_PKEY_PARAM_FFC_GINDEX,
1641e0c4386eSCy Schubert                                                  &gindex_out))
1642e0c4386eSCy Schubert             || !TEST_int_eq(gindex, gindex_out)
1643e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_int_param(pk, OSSL_PKEY_PARAM_FFC_H,
1644e0c4386eSCy Schubert                                                  &hindex_out))
1645e0c4386eSCy Schubert             || !TEST_int_eq(hindex_out, 0)
1646e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_get_int_param(pk,
1647e0c4386eSCy Schubert                                                  OSSL_PKEY_PARAM_FFC_PCOUNTER,
1648e0c4386eSCy Schubert                                                  &pcounter_out))
1649e0c4386eSCy Schubert             || !TEST_int_eq(pcounter, pcounter_out))
1650e0c4386eSCy Schubert             goto err;
1651*44096ebdSEnji Cooper         BN_free(p_out);
1652*44096ebdSEnji Cooper         p_out = NULL;
1653*44096ebdSEnji Cooper         BN_free(q_out);
1654*44096ebdSEnji Cooper         q_out = NULL;
1655*44096ebdSEnji Cooper         BN_free(g_out);
1656*44096ebdSEnji Cooper         g_out = NULL;
1657e0c4386eSCy Schubert         BN_free(j_out);
1658e0c4386eSCy Schubert         j_out = NULL;
1659e0c4386eSCy Schubert         BN_free(pub_out);
1660e0c4386eSCy Schubert         pub_out = NULL;
1661e0c4386eSCy Schubert         BN_free(priv_out);
1662e0c4386eSCy Schubert         priv_out = NULL;
1663e0c4386eSCy Schubert 
1664e0c4386eSCy Schubert         if (!TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pk, "")))
1665e0c4386eSCy Schubert             goto err;
1666e0c4386eSCy Schubert 
1667e0c4386eSCy Schubert         if (!TEST_int_gt(EVP_PKEY_check(key_ctx), 0)
1668e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_public_check(key_ctx), 0)
1669e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_private_check(key_ctx), 0)
1670e0c4386eSCy Schubert             || !TEST_int_gt(EVP_PKEY_pairwise_check(key_ctx), 0))
1671e0c4386eSCy Schubert             goto err;
1672e0c4386eSCy Schubert         EVP_PKEY_CTX_free(key_ctx);
1673e0c4386eSCy Schubert         key_ctx = NULL;
1674e0c4386eSCy Schubert 
1675e0c4386eSCy Schubert         if (!TEST_ptr(copy_pk = EVP_PKEY_new())
1676e0c4386eSCy Schubert             || !TEST_true(EVP_PKEY_copy_parameters(copy_pk, pk)))
1677e0c4386eSCy Schubert             goto err;
1678e0c4386eSCy Schubert         EVP_PKEY_free(copy_pk);
1679e0c4386eSCy Schubert         copy_pk = NULL;
1680e0c4386eSCy Schubert 
1681e0c4386eSCy Schubert         ret = test_print_key_using_pem("DSA", pk)
1682e0c4386eSCy Schubert               && test_print_key_using_encoder("DSA", pk);
1683e0c4386eSCy Schubert 
1684*44096ebdSEnji Cooper         if (!ret || dup_pk != NULL)
1685*44096ebdSEnji Cooper             break;
1686*44096ebdSEnji Cooper 
1687*44096ebdSEnji Cooper         if (!TEST_ptr(dup_pk = EVP_PKEY_dup(pk)))
1688e0c4386eSCy Schubert             goto err;
1689e0c4386eSCy Schubert         ret = ret && TEST_int_eq(EVP_PKEY_eq(pk, dup_pk), 1);
1690e0c4386eSCy Schubert         EVP_PKEY_free(pk);
1691e0c4386eSCy Schubert         pk = dup_pk;
1692e0c4386eSCy Schubert         if (!ret)
1693e0c4386eSCy Schubert             goto err;
1694e0c4386eSCy Schubert     }
1695e0c4386eSCy Schubert 
1696e0c4386eSCy Schubert  err:
1697e0c4386eSCy Schubert     OSSL_PARAM_free(fromdata_params);
1698e0c4386eSCy Schubert     OSSL_PARAM_BLD_free(bld);
1699e0c4386eSCy Schubert     BN_free(p);
1700e0c4386eSCy Schubert     BN_free(q);
1701e0c4386eSCy Schubert     BN_free(g);
1702e0c4386eSCy Schubert     BN_free(pub);
1703e0c4386eSCy Schubert     BN_free(priv);
1704e0c4386eSCy Schubert     BN_free(p_out);
1705e0c4386eSCy Schubert     BN_free(q_out);
1706e0c4386eSCy Schubert     BN_free(g_out);
1707e0c4386eSCy Schubert     BN_free(pub_out);
1708e0c4386eSCy Schubert     BN_free(priv_out);
1709e0c4386eSCy Schubert     BN_free(j_out);
1710e0c4386eSCy Schubert     EVP_PKEY_free(pk);
1711e0c4386eSCy Schubert     EVP_PKEY_free(copy_pk);
1712e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
1713e0c4386eSCy Schubert     EVP_PKEY_CTX_free(key_ctx);
1714e0c4386eSCy Schubert 
1715e0c4386eSCy Schubert     return ret;
1716e0c4386eSCy Schubert }
1717e0c4386eSCy Schubert 
1718e0c4386eSCy Schubert static int test_check_dsa(void)
1719e0c4386eSCy Schubert {
1720e0c4386eSCy Schubert     int ret = 0;
1721e0c4386eSCy Schubert     EVP_PKEY_CTX *ctx = NULL;
1722e0c4386eSCy Schubert 
1723e0c4386eSCy Schubert     if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL))
1724e0c4386eSCy Schubert         || !TEST_int_le(EVP_PKEY_check(ctx), 0)
1725e0c4386eSCy Schubert         || !TEST_int_le(EVP_PKEY_public_check(ctx), 0)
1726e0c4386eSCy Schubert         || !TEST_int_le(EVP_PKEY_private_check(ctx), 0)
1727e0c4386eSCy Schubert         || !TEST_int_le(EVP_PKEY_pairwise_check(ctx), 0))
1728e0c4386eSCy Schubert        goto err;
1729e0c4386eSCy Schubert 
1730e0c4386eSCy Schubert     ret = 1;
1731e0c4386eSCy Schubert  err:
1732e0c4386eSCy Schubert     EVP_PKEY_CTX_free(ctx);
1733e0c4386eSCy Schubert 
1734e0c4386eSCy Schubert     return ret;
1735e0c4386eSCy Schubert }
1736e0c4386eSCy Schubert #endif /* OPENSSL_NO_DSA */
1737e0c4386eSCy Schubert 
1738e0c4386eSCy Schubert 
1739e0c4386eSCy Schubert static OSSL_PARAM *do_construct_hkdf_params(char *digest, char *key,
1740e0c4386eSCy Schubert                                             size_t keylen, char *salt)
1741e0c4386eSCy Schubert {
1742e0c4386eSCy Schubert     OSSL_PARAM *params = OPENSSL_malloc(sizeof(OSSL_PARAM) * 5);
1743e0c4386eSCy Schubert     OSSL_PARAM *p = params;
1744e0c4386eSCy Schubert 
1745e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, digest, 0);
1746e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT,
1747e0c4386eSCy Schubert                                              salt, strlen(salt));
1748e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY,
1749e0c4386eSCy Schubert                                              (unsigned char *)key, keylen);
1750e0c4386eSCy Schubert     *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MODE,
1751e0c4386eSCy Schubert                                             "EXTRACT_ONLY", 0);
1752e0c4386eSCy Schubert     *p = OSSL_PARAM_construct_end();
1753e0c4386eSCy Schubert 
1754e0c4386eSCy Schubert     return params;
1755e0c4386eSCy Schubert }
1756e0c4386eSCy Schubert 
1757e0c4386eSCy Schubert /* Test that EVP_PKEY_CTX_dup() fails gracefully for a KDF */
1758e0c4386eSCy Schubert static int test_evp_pkey_ctx_dup_kdf_fail(void)
1759e0c4386eSCy Schubert {
1760e0c4386eSCy Schubert     int ret = 0;
1761e0c4386eSCy Schubert     size_t len = 0;
1762e0c4386eSCy Schubert     EVP_PKEY_CTX *pctx = NULL, *dctx = NULL;
1763e0c4386eSCy Schubert     OSSL_PARAM *params = NULL;
1764e0c4386eSCy Schubert 
1765e0c4386eSCy Schubert     if (!TEST_ptr(params = do_construct_hkdf_params("sha256", "secret", 6,
1766e0c4386eSCy Schubert                                                     "salt")))
1767e0c4386eSCy Schubert         goto err;
1768e0c4386eSCy Schubert     if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(NULL, "HKDF", NULL)))
1769e0c4386eSCy Schubert         goto err;
1770e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_PKEY_derive_init_ex(pctx, params), 1))
1771e0c4386eSCy Schubert         goto err;
1772e0c4386eSCy Schubert     if (!TEST_int_eq(EVP_PKEY_derive(pctx, NULL, &len), 1)
1773e0c4386eSCy Schubert         || !TEST_size_t_eq(len, SHA256_DIGEST_LENGTH))
1774e0c4386eSCy Schubert         goto err;
1775e0c4386eSCy Schubert     if (!TEST_ptr_null(dctx = EVP_PKEY_CTX_dup(pctx)))
1776e0c4386eSCy Schubert         goto err;
1777e0c4386eSCy Schubert     ret = 1;
1778e0c4386eSCy Schubert err:
1779e0c4386eSCy Schubert     OPENSSL_free(params);
1780e0c4386eSCy Schubert     EVP_PKEY_CTX_free(dctx);
1781e0c4386eSCy Schubert     EVP_PKEY_CTX_free(pctx);
1782e0c4386eSCy Schubert     return ret;
1783e0c4386eSCy Schubert }
1784e0c4386eSCy Schubert 
1785e0c4386eSCy Schubert int setup_tests(void)
1786e0c4386eSCy Schubert {
1787e0c4386eSCy Schubert     if (!test_skip_common_options()) {
1788e0c4386eSCy Schubert         TEST_error("Error parsing test options\n");
1789e0c4386eSCy Schubert         return 0;
1790e0c4386eSCy Schubert     }
1791e0c4386eSCy Schubert 
1792e0c4386eSCy Schubert     if (!TEST_ptr(datadir = test_get_argument(0)))
1793e0c4386eSCy Schubert         return 0;
1794e0c4386eSCy Schubert 
1795e0c4386eSCy Schubert     ADD_TEST(test_evp_pkey_ctx_dup_kdf_fail);
1796e0c4386eSCy Schubert     ADD_TEST(test_evp_pkey_get_bn_param_large);
1797e0c4386eSCy Schubert     ADD_TEST(test_fromdata_rsa);
1798e0c4386eSCy Schubert #ifndef OPENSSL_NO_DH
1799e0c4386eSCy Schubert     ADD_TEST(test_fromdata_dh_fips186_4);
1800e0c4386eSCy Schubert     ADD_TEST(test_fromdata_dh_named_group);
1801e0c4386eSCy Schubert #endif
1802e0c4386eSCy Schubert #ifndef OPENSSL_NO_DSA
1803e0c4386eSCy Schubert     ADD_TEST(test_check_dsa);
1804e0c4386eSCy Schubert     ADD_TEST(test_fromdata_dsa_fips186_4);
1805e0c4386eSCy Schubert #endif
1806e0c4386eSCy Schubert #ifndef OPENSSL_NO_EC
1807e0c4386eSCy Schubert     ADD_ALL_TESTS(test_fromdata_ecx, 4 * 3);
1808e0c4386eSCy Schubert     ADD_TEST(test_fromdata_ec);
1809e0c4386eSCy Schubert     ADD_TEST(test_ec_dup_no_operation);
1810e0c4386eSCy Schubert     ADD_TEST(test_ec_dup_keygen_operation);
1811e0c4386eSCy Schubert #endif
1812e0c4386eSCy Schubert     return 1;
1813e0c4386eSCy Schubert }
1814