xref: /freebsd/crypto/openssl/test/endecode_test.c (revision 78e936b2d0b5e6554425009199be31e76bc67c10)
1 /*
2  * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <string.h>
11 #include <openssl/core_dispatch.h>
12 #include <openssl/evp.h>
13 #include <openssl/pem.h>
14 #include <openssl/rsa.h>
15 #include <openssl/x509.h>
16 #include <openssl/core_names.h>
17 #include <openssl/params.h>
18 #include <openssl/param_build.h>
19 #include <openssl/encoder.h>
20 #include <openssl/decoder.h>
21 
22 #include "internal/cryptlib.h" /* ossl_assert */
23 #include "crypto/pem.h" /* For PVK and "blob" PEM headers */
24 #include "crypto/evp.h" /* For evp_pkey_is_provided() */
25 
26 #include "helpers/predefined_dhparams.h"
27 #include "testutil.h"
28 
29 #ifdef STATIC_LEGACY
30 OSSL_provider_init_fn ossl_legacy_provider_init;
31 #endif
32 
33 /* Extended test macros to allow passing file & line number */
34 #define TEST_FL_ptr(a) test_ptr(file, line, #a, a)
35 #define TEST_FL_mem_eq(a, m, b, n) test_mem_eq(file, line, #a, #b, a, m, b, n)
36 #define TEST_FL_strn_eq(a, b, n) test_strn_eq(file, line, #a, #b, a, n, b, n)
37 #define TEST_FL_strn2_eq(a, m, b, n) test_strn_eq(file, line, #a, #b, a, m, b, n)
38 #define TEST_FL_int_eq(a, b) test_int_eq(file, line, #a, #b, a, b)
39 #define TEST_FL_int_ge(a, b) test_int_ge(file, line, #a, #b, a, b)
40 #define TEST_FL_int_gt(a, b) test_int_gt(file, line, #a, #b, a, b)
41 #define TEST_FL_long_gt(a, b) test_long_gt(file, line, #a, #b, a, b)
42 #define TEST_FL_true(a) test_true(file, line, #a, (a) != 0)
43 
44 #if defined(OPENSSL_NO_DH) && defined(OPENSSL_NO_DSA) && defined(OPENSSL_NO_EC)
45 #define OPENSSL_NO_KEYPARAMS
46 #endif
47 
48 static int default_libctx = 1;
49 static int is_fips = 0;
50 static int is_fips_3_0_0 = 0;
51 static int is_fips_lt_3_5 = 0;
52 
53 static OSSL_LIB_CTX *testctx = NULL;
54 static OSSL_LIB_CTX *keyctx = NULL;
55 static char *testpropq = NULL;
56 
57 static OSSL_PROVIDER *nullprov = NULL;
58 static OSSL_PROVIDER *deflprov = NULL;
59 static OSSL_PROVIDER *keyprov = NULL;
60 
61 #ifndef OPENSSL_NO_EC
62 static BN_CTX *bnctx = NULL;
63 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
64 static OSSL_PARAM_BLD *bld_prime_nc = NULL;
65 static OSSL_PARAM_BLD *bld_prime = NULL;
66 static OSSL_PARAM *ec_explicit_prime_params_nc = NULL;
67 static OSSL_PARAM *ec_explicit_prime_params_explicit = NULL;
68 
69 #ifndef OPENSSL_NO_EC2M
70 static OSSL_PARAM_BLD *bld_tri_nc = NULL;
71 static OSSL_PARAM_BLD *bld_tri = NULL;
72 static OSSL_PARAM *ec_explicit_tri_params_nc = NULL;
73 static OSSL_PARAM *ec_explicit_tri_params_explicit = NULL;
74 #endif
75 #endif
76 #endif
77 
78 #ifndef OPENSSL_NO_KEYPARAMS
make_template(const char * type,OSSL_PARAM * genparams)79 static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams)
80 {
81     EVP_PKEY *pkey = NULL;
82     EVP_PKEY_CTX *ctx = NULL;
83 
84 #ifndef OPENSSL_NO_DH
85     /*
86      * Use 512-bit DH(X) keys with predetermined parameters for efficiency,
87      * for testing only. Use a minimum key size of 2048 for security purposes.
88      */
89     if (strcmp(type, "DH") == 0)
90         return get_dh512(keyctx);
91 
92     if (strcmp(type, "X9.42 DH") == 0)
93         return get_dhx512(keyctx);
94 #endif
95 
96     /*
97      * No real need to check the errors other than for the cascade
98      * effect.  |pkey| will simply remain NULL if something goes wrong.
99      */
100     (void)((ctx = EVP_PKEY_CTX_new_from_name(keyctx, type, testpropq)) != NULL
101         && EVP_PKEY_paramgen_init(ctx) > 0
102         && (genparams == NULL
103             || EVP_PKEY_CTX_set_params(ctx, genparams) > 0)
104         && EVP_PKEY_generate(ctx, &pkey) > 0);
105     EVP_PKEY_CTX_free(ctx);
106 
107     return pkey;
108 }
109 #endif
110 
111 #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_ML_DSA) || !defined(OPENSSL_NO_ML_KEM) || !defined(OPENSSL_NO_SLH_DSA)
make_key(const char * type,EVP_PKEY * template,OSSL_PARAM * genparams)112 static EVP_PKEY *make_key(const char *type, EVP_PKEY *template,
113     OSSL_PARAM *genparams)
114 {
115     EVP_PKEY *pkey = NULL;
116     EVP_PKEY_CTX *ctx = template != NULL
117         ? EVP_PKEY_CTX_new_from_pkey(keyctx, template, testpropq)
118         : EVP_PKEY_CTX_new_from_name(keyctx, type, testpropq);
119 
120     /*
121      * No real need to check the errors other than for the cascade
122      * effect.  |pkey| will simply remain NULL if something goes wrong.
123      */
124     (void)(ctx != NULL
125         && EVP_PKEY_keygen_init(ctx) > 0
126         && (genparams == NULL
127             || EVP_PKEY_CTX_set_params(ctx, genparams) > 0)
128         && EVP_PKEY_keygen(ctx, &pkey) > 0);
129     EVP_PKEY_CTX_free(ctx);
130     return pkey;
131 }
132 #endif
133 
134 /* Main test driver */
135 
136 typedef int(encoder)(const char *file, const int line,
137     void **encoded, long *encoded_len,
138     void *object, int selection,
139     const char *output_type, const char *output_structure,
140     const char *pass, const char *pcipher);
141 typedef int(decoder)(const char *file, const int line,
142     void **object, void *encoded, long encoded_len,
143     const char *input_type, const char *structure_type,
144     const char *keytype, int selection, const char *pass);
145 typedef int(tester)(const char *file, const int line,
146     const void *data1, size_t data1_len,
147     const void *data2, size_t data2_len);
148 typedef int(checker)(const char *file, const int line,
149     const char *type, const void *data, size_t data_len);
150 typedef void(dumper)(const char *label, const void *data, size_t data_len);
151 
152 #define FLAG_DECODE_WITH_TYPE 0x0001
153 #define FLAG_FAIL_IF_FIPS 0x0002
154 
test_encode_decode(const char * file,const int line,const char * type,EVP_PKEY * pkey,int selection,const char * output_type,const char * output_structure,const char * pass,const char * pcipher,encoder * encode_cb,decoder * decode_cb,tester * test_cb,checker * check_cb,dumper * dump_cb,int flags)155 static int test_encode_decode(const char *file, const int line,
156     const char *type, EVP_PKEY *pkey,
157     int selection, const char *output_type,
158     const char *output_structure,
159     const char *pass, const char *pcipher,
160     encoder *encode_cb, decoder *decode_cb,
161     tester *test_cb, checker *check_cb,
162     dumper *dump_cb, int flags)
163 {
164     void *encoded = NULL;
165     long encoded_len = 0;
166     EVP_PKEY *pkey2 = NULL;
167     EVP_PKEY *pkey3 = NULL;
168     void *encoded2 = NULL;
169     long encoded2_len = 0;
170     int ok = 0;
171 
172     /*
173      * Encode |pkey|, decode the result into |pkey2|, and finish off by
174      * encoding |pkey2| as well.  That last encoding is for checking and
175      * dumping purposes.
176      */
177     if (!TEST_true(encode_cb(file, line, &encoded, &encoded_len, pkey, selection,
178             output_type, output_structure, pass, pcipher)))
179         goto end;
180 
181     if ((flags & FLAG_FAIL_IF_FIPS) != 0 && is_fips && !is_fips_3_0_0) {
182         if (TEST_false(decode_cb(file, line, (void **)&pkey2, encoded,
183                 encoded_len, output_type, output_structure,
184                 (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
185                 selection, pass)))
186             ok = 1;
187         goto end;
188     }
189 
190     if (!TEST_true(check_cb(file, line, type, encoded, encoded_len))
191         || !TEST_true(decode_cb(file, line, (void **)&pkey2, encoded, encoded_len,
192             output_type, output_structure,
193             (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
194             selection, pass))
195         || ((output_structure == NULL
196                 || strcmp(output_structure, "type-specific") != 0)
197             && !TEST_true(decode_cb(file, line, (void **)&pkey3, encoded, encoded_len,
198                 output_type, output_structure,
199                 (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
200                 0, pass)))
201         || !TEST_true(encode_cb(file, line, &encoded2, &encoded2_len, pkey2, selection,
202             output_type, output_structure, pass, pcipher)))
203         goto end;
204 
205     if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
206         if (!TEST_int_eq(EVP_PKEY_parameters_eq(pkey, pkey2), 1)
207             || (pkey3 != NULL
208                 && !TEST_int_eq(EVP_PKEY_parameters_eq(pkey, pkey3), 1)))
209             goto end;
210     } else {
211         if (!TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1)
212             || (pkey3 != NULL
213                 && !TEST_int_eq(EVP_PKEY_eq(pkey, pkey3), 1)))
214             goto end;
215     }
216 
217     /*
218      * Double check the encoding, but only for unprotected keys,
219      * as protected keys have a random component, which makes the output
220      * differ.
221      */
222     if ((pass == NULL && pcipher == NULL)
223         && !test_cb(file, line, encoded, encoded_len, encoded2, encoded2_len))
224         goto end;
225 
226     ok = 1;
227 end:
228     if (!ok) {
229         if (encoded != NULL && encoded_len != 0)
230             dump_cb("|pkey| encoded", encoded, encoded_len);
231         if (encoded2 != NULL && encoded2_len != 0)
232             dump_cb("|pkey2| encoded", encoded2, encoded2_len);
233     }
234 
235     OPENSSL_free(encoded);
236     OPENSSL_free(encoded2);
237     EVP_PKEY_free(pkey2);
238     EVP_PKEY_free(pkey3);
239     return ok;
240 }
241 
242 /* Encoding and decoding methods */
243 
encode_EVP_PKEY_prov(const char * file,const int line,void ** encoded,long * encoded_len,void * object,int selection,const char * output_type,const char * output_structure,const char * pass,const char * pcipher)244 static int encode_EVP_PKEY_prov(const char *file, const int line,
245     void **encoded, long *encoded_len,
246     void *object, int selection,
247     const char *output_type,
248     const char *output_structure,
249     const char *pass, const char *pcipher)
250 {
251     EVP_PKEY *pkey = object;
252     OSSL_ENCODER_CTX *ectx = NULL;
253     BIO *mem_ser = NULL;
254     BUF_MEM *mem_buf = NULL;
255     const unsigned char *upass = (const unsigned char *)pass;
256     int ok = 0;
257 
258     if (!TEST_FL_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection,
259                          output_type,
260                          output_structure,
261                          testpropq))
262         || !TEST_FL_int_gt(OSSL_ENCODER_CTX_get_num_encoders(ectx), 0)
263         || (pass != NULL
264             && !TEST_FL_true(OSSL_ENCODER_CTX_set_passphrase(ectx, upass,
265                 strlen(pass))))
266         || (pcipher != NULL
267             && !TEST_FL_true(OSSL_ENCODER_CTX_set_cipher(ectx, pcipher, NULL)))
268         || !TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
269         || !TEST_FL_true(OSSL_ENCODER_to_bio(ectx, mem_ser))
270         || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
271         || !TEST_FL_ptr(*encoded = mem_buf->data)
272         || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
273         goto end;
274 
275     /* Detach the encoded output */
276     mem_buf->data = NULL;
277     mem_buf->length = 0;
278     ok = 1;
279 end:
280     BIO_free(mem_ser);
281     OSSL_ENCODER_CTX_free(ectx);
282     return ok;
283 }
284 
decode_EVP_PKEY_prov(const char * file,const int line,void ** object,void * encoded,long encoded_len,const char * input_type,const char * structure_type,const char * keytype,int selection,const char * pass)285 static int decode_EVP_PKEY_prov(const char *file, const int line,
286     void **object, void *encoded, long encoded_len,
287     const char *input_type,
288     const char *structure_type,
289     const char *keytype, int selection,
290     const char *pass)
291 {
292     EVP_PKEY *pkey = NULL, *testpkey = NULL;
293     OSSL_DECODER_CTX *dctx = NULL;
294     BIO *encoded_bio = NULL;
295     const unsigned char *upass = (const unsigned char *)pass;
296     int ok = 0;
297     int i;
298     const char *badtype;
299 
300     if (strcmp(input_type, "DER") == 0)
301         badtype = "PEM";
302     else
303         badtype = "DER";
304 
305     if (!TEST_FL_ptr(encoded_bio = BIO_new_mem_buf(encoded, encoded_len)))
306         goto end;
307 
308     /*
309      * We attempt the decode 3 times. The first time we provide the expected
310      * starting input type. The second time we provide NULL for the starting
311      * type. The third time we provide a bad starting input type.
312      * The bad starting input type should fail. The other two should succeed
313      * and produce the same result.
314      */
315     for (i = 0; i < 3; i++) {
316         const char *testtype = (i == 0) ? input_type
317                                         : ((i == 1) ? NULL : badtype);
318 
319         if (!TEST_FL_ptr(dctx = OSSL_DECODER_CTX_new_for_pkey(&testpkey,
320                              testtype,
321                              structure_type,
322                              keytype,
323                              selection,
324                              testctx, testpropq))
325             || (pass != NULL
326                 && !OSSL_DECODER_CTX_set_passphrase(dctx, upass, strlen(pass)))
327             || !TEST_FL_int_gt(BIO_reset(encoded_bio), 0)
328             /* We expect to fail when using a bad input type */
329             || !TEST_FL_int_eq(OSSL_DECODER_from_bio(dctx, encoded_bio),
330                 (i == 2) ? 0 : 1))
331             goto end;
332         OSSL_DECODER_CTX_free(dctx);
333         dctx = NULL;
334 
335         if (i == 0) {
336             pkey = testpkey;
337             testpkey = NULL;
338         } else if (i == 1) {
339             if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
340                 if (!TEST_FL_int_eq(EVP_PKEY_parameters_eq(pkey, testpkey), 1))
341                     goto end;
342             } else {
343                 if (!TEST_FL_int_eq(EVP_PKEY_eq(pkey, testpkey), 1))
344                     goto end;
345             }
346         }
347     }
348     ok = 1;
349     *object = pkey;
350     pkey = NULL;
351 
352 end:
353     EVP_PKEY_free(pkey);
354     EVP_PKEY_free(testpkey);
355     BIO_free(encoded_bio);
356     OSSL_DECODER_CTX_free(dctx);
357     return ok;
358 }
359 
encode_EVP_PKEY_legacy_PEM(const char * file,const int line,void ** encoded,long * encoded_len,void * object,ossl_unused int selection,ossl_unused const char * output_type,ossl_unused const char * output_structure,const char * pass,const char * pcipher)360 static int encode_EVP_PKEY_legacy_PEM(const char *file, const int line,
361     void **encoded, long *encoded_len,
362     void *object, ossl_unused int selection,
363     ossl_unused const char *output_type,
364     ossl_unused const char *output_structure,
365     const char *pass, const char *pcipher)
366 {
367     EVP_PKEY *pkey = object;
368     EVP_CIPHER *cipher = NULL;
369     BIO *mem_ser = NULL;
370     BUF_MEM *mem_buf = NULL;
371     const unsigned char *upass = (const unsigned char *)pass;
372     size_t passlen = 0;
373     int ok = 0;
374 
375     if (pcipher != NULL && pass != NULL) {
376         passlen = strlen(pass);
377         if (!TEST_FL_ptr(cipher = EVP_CIPHER_fetch(testctx, pcipher, testpropq)))
378             goto end;
379     }
380     if (!TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
381         || !TEST_FL_true(PEM_write_bio_PrivateKey_traditional(mem_ser, pkey,
382             cipher,
383             upass, passlen,
384             NULL, NULL))
385         || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
386         || !TEST_FL_ptr(*encoded = mem_buf->data)
387         || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
388         goto end;
389 
390     /* Detach the encoded output */
391     mem_buf->data = NULL;
392     mem_buf->length = 0;
393     ok = 1;
394 end:
395     BIO_free(mem_ser);
396     EVP_CIPHER_free(cipher);
397     return ok;
398 }
399 
encode_EVP_PKEY_MSBLOB(const char * file,const int line,void ** encoded,long * encoded_len,void * object,int selection,ossl_unused const char * output_type,ossl_unused const char * output_structure,ossl_unused const char * pass,ossl_unused const char * pcipher)400 static int encode_EVP_PKEY_MSBLOB(const char *file, const int line,
401     void **encoded, long *encoded_len,
402     void *object, int selection,
403     ossl_unused const char *output_type,
404     ossl_unused const char *output_structure,
405     ossl_unused const char *pass,
406     ossl_unused const char *pcipher)
407 {
408     EVP_PKEY *pkey = object;
409     BIO *mem_ser = NULL;
410     BUF_MEM *mem_buf = NULL;
411     int ok = 0;
412 
413     if (!TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem())))
414         goto end;
415 
416     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
417         if (!TEST_FL_int_ge(i2b_PrivateKey_bio(mem_ser, pkey), 0))
418             goto end;
419     } else {
420         if (!TEST_FL_int_ge(i2b_PublicKey_bio(mem_ser, pkey), 0))
421             goto end;
422     }
423 
424     if (!TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
425         || !TEST_FL_ptr(*encoded = mem_buf->data)
426         || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
427         goto end;
428 
429     /* Detach the encoded output */
430     mem_buf->data = NULL;
431     mem_buf->length = 0;
432     ok = 1;
433 end:
434     BIO_free(mem_ser);
435     return ok;
436 }
437 
438 static pem_password_cb pass_pw;
pass_pw(char * buf,int size,int rwflag,void * userdata)439 static int pass_pw(char *buf, int size, int rwflag, void *userdata)
440 {
441     OPENSSL_strlcpy(buf, userdata, size);
442     return strlen(userdata);
443 }
444 
encode_EVP_PKEY_PVK(const char * file,const int line,void ** encoded,long * encoded_len,void * object,int selection,ossl_unused const char * output_type,ossl_unused const char * output_structure,const char * pass,ossl_unused const char * pcipher)445 static int encode_EVP_PKEY_PVK(const char *file, const int line,
446     void **encoded, long *encoded_len,
447     void *object, int selection,
448     ossl_unused const char *output_type,
449     ossl_unused const char *output_structure,
450     const char *pass,
451     ossl_unused const char *pcipher)
452 {
453     EVP_PKEY *pkey = object;
454     BIO *mem_ser = NULL;
455     BUF_MEM *mem_buf = NULL;
456     int enc = (pass != NULL);
457     int ok = 0;
458 
459     if (!TEST_FL_true(ossl_assert((selection
460                                       & OSSL_KEYMGMT_SELECT_PRIVATE_KEY)
461             != 0))
462         || !TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
463         || !TEST_FL_int_ge(i2b_PVK_bio_ex(mem_ser, pkey, enc,
464                                pass_pw, (void *)pass, testctx, testpropq),
465             0)
466         || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
467         || !TEST_FL_ptr(*encoded = mem_buf->data)
468         || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
469         goto end;
470 
471     /* Detach the encoded output */
472     mem_buf->data = NULL;
473     mem_buf->length = 0;
474     ok = 1;
475 end:
476     BIO_free(mem_ser);
477     return ok;
478 }
479 
test_text(const char * file,const int line,const void * data1,size_t data1_len,const void * data2,size_t data2_len)480 static int test_text(const char *file, const int line,
481     const void *data1, size_t data1_len,
482     const void *data2, size_t data2_len)
483 {
484     return TEST_FL_strn2_eq(data1, data1_len, data2, data2_len);
485 }
486 
test_mem(const char * file,const int line,const void * data1,size_t data1_len,const void * data2,size_t data2_len)487 static int test_mem(const char *file, const int line,
488     const void *data1, size_t data1_len,
489     const void *data2, size_t data2_len)
490 {
491     return TEST_FL_mem_eq(data1, data1_len, data2, data2_len);
492 }
493 
494 /* Test cases and their dumpers / checkers */
495 
collect_name(const char * name,void * arg)496 static void collect_name(const char *name, void *arg)
497 {
498     char **namelist = arg;
499     char *new_namelist;
500     size_t space;
501 
502     space = strlen(name);
503     if (*namelist != NULL)
504         space += strlen(*namelist) + 2 /* for comma and space */;
505     space++; /* for terminating null byte */
506 
507     new_namelist = OPENSSL_realloc(*namelist, space);
508     if (new_namelist == NULL)
509         return;
510     if (*namelist != NULL) {
511         strcat(new_namelist, ", ");
512         strcat(new_namelist, name);
513     } else {
514         strcpy(new_namelist, name);
515     }
516     *namelist = new_namelist;
517 }
518 
dump_der(const char * label,const void * data,size_t data_len)519 static void dump_der(const char *label, const void *data, size_t data_len)
520 {
521     test_output_memory(label, data, data_len);
522 }
523 
dump_pem(const char * label,const void * data,size_t data_len)524 static void dump_pem(const char *label, const void *data, size_t data_len)
525 {
526     test_output_string(label, data, data_len - 1);
527 }
528 
check_unprotected_PKCS8_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)529 static int check_unprotected_PKCS8_DER(const char *file, const int line,
530     const char *type,
531     const void *data, size_t data_len)
532 {
533     const unsigned char *datap = data;
534     PKCS8_PRIV_KEY_INFO *p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &datap, data_len);
535     int ok = 0;
536 
537     if (TEST_FL_ptr(p8inf)) {
538         EVP_PKEY *pkey = EVP_PKCS82PKEY_ex(p8inf, testctx, testpropq);
539         char *namelist = NULL;
540 
541         if (TEST_FL_ptr(pkey)) {
542             if (!(ok = TEST_FL_true(EVP_PKEY_is_a(pkey, type)))) {
543                 EVP_PKEY_type_names_do_all(pkey, collect_name, &namelist);
544                 if (namelist != NULL)
545                     TEST_note("%s isn't any of %s", type, namelist);
546                 OPENSSL_free(namelist);
547             }
548             ok = ok && TEST_FL_true(evp_pkey_is_provided(pkey));
549             EVP_PKEY_free(pkey);
550         }
551     }
552     PKCS8_PRIV_KEY_INFO_free(p8inf);
553     return ok;
554 }
555 
test_unprotected_via_DER(const char * type,EVP_PKEY * key,int fips)556 static int test_unprotected_via_DER(const char *type, EVP_PKEY *key, int fips)
557 {
558     return test_encode_decode(__FILE__, __LINE__, type, key,
559         OSSL_KEYMGMT_SELECT_KEYPAIR
560             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
561         "DER", "PrivateKeyInfo", NULL, NULL,
562         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
563         test_mem, check_unprotected_PKCS8_DER,
564         dump_der, fips ? 0 : FLAG_FAIL_IF_FIPS);
565 }
566 
check_unprotected_PKCS8_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)567 static int check_unprotected_PKCS8_PEM(const char *file, const int line,
568     const char *type,
569     const void *data, size_t data_len)
570 {
571     static const char expected_pem_header[] = "-----BEGIN " PEM_STRING_PKCS8INF "-----";
572 
573     return TEST_FL_strn_eq(data, expected_pem_header,
574         sizeof(expected_pem_header) - 1);
575 }
576 
test_unprotected_via_PEM(const char * type,EVP_PKEY * key,int fips)577 static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key, int fips)
578 {
579     return test_encode_decode(__FILE__, __LINE__, type, key,
580         OSSL_KEYMGMT_SELECT_KEYPAIR
581             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
582         "PEM", "PrivateKeyInfo", NULL, NULL,
583         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
584         test_text, check_unprotected_PKCS8_PEM,
585         dump_pem, fips ? 0 : FLAG_FAIL_IF_FIPS);
586 }
587 
588 #ifndef OPENSSL_NO_KEYPARAMS
check_params_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)589 static int check_params_DER(const char *file, const int line,
590     const char *type, const void *data, size_t data_len)
591 {
592     const unsigned char *datap = data;
593     int ok = 0;
594     int itype = NID_undef;
595     EVP_PKEY *pkey = NULL;
596 
597     if (strcmp(type, "DH") == 0)
598         itype = EVP_PKEY_DH;
599     else if (strcmp(type, "X9.42 DH") == 0)
600         itype = EVP_PKEY_DHX;
601     else if (strcmp(type, "DSA") == 0)
602         itype = EVP_PKEY_DSA;
603     else if (strcmp(type, "EC") == 0)
604         itype = EVP_PKEY_EC;
605 
606     if (itype != NID_undef) {
607         pkey = d2i_KeyParams(itype, NULL, &datap, data_len);
608         ok = (pkey != NULL);
609         EVP_PKEY_free(pkey);
610     }
611 
612     return ok;
613 }
614 
check_params_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)615 static int check_params_PEM(const char *file, const int line,
616     const char *type,
617     const void *data, size_t data_len)
618 {
619     static char expected_pem_header[80];
620 
621     return TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
622                               sizeof(expected_pem_header),
623                               "-----BEGIN %s PARAMETERS-----", type),
624                0)
625         && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header));
626 }
627 
test_params_via_DER(const char * type,EVP_PKEY * key)628 static int test_params_via_DER(const char *type, EVP_PKEY *key)
629 {
630     return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
631         "DER", "type-specific", NULL, NULL,
632         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
633         test_mem, check_params_DER,
634         dump_der, FLAG_DECODE_WITH_TYPE);
635 }
636 
test_params_via_PEM(const char * type,EVP_PKEY * key)637 static int test_params_via_PEM(const char *type, EVP_PKEY *key)
638 {
639     return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
640         "PEM", "type-specific", NULL, NULL,
641         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
642         test_text, check_params_PEM,
643         dump_pem, 0);
644 }
645 #endif /* !OPENSSL_NO_KEYPARAMS */
646 
check_unprotected_legacy_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)647 static int check_unprotected_legacy_PEM(const char *file, const int line,
648     const char *type,
649     const void *data, size_t data_len)
650 {
651     static char expected_pem_header[80];
652 
653     return TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
654                               sizeof(expected_pem_header),
655                               "-----BEGIN %s PRIVATE KEY-----", type),
656                0)
657         && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header));
658 }
659 
test_unprotected_via_legacy_PEM(const char * type,EVP_PKEY * key)660 static int test_unprotected_via_legacy_PEM(const char *type, EVP_PKEY *key)
661 {
662     if (!default_libctx || is_fips)
663         return TEST_skip("Test not available if using a non-default library context or FIPS provider");
664 
665     return test_encode_decode(__FILE__, __LINE__, type, key,
666         OSSL_KEYMGMT_SELECT_KEYPAIR
667             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
668         "PEM", "type-specific", NULL, NULL,
669         encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
670         test_text, check_unprotected_legacy_PEM,
671         dump_pem, 0);
672 }
673 
check_MSBLOB(const char * file,const int line,const char * type,const void * data,size_t data_len)674 static int check_MSBLOB(const char *file, const int line,
675     const char *type, const void *data, size_t data_len)
676 {
677     const unsigned char *datap = data;
678     EVP_PKEY *pkey = b2i_PrivateKey(&datap, data_len);
679     int ok = TEST_FL_ptr(pkey);
680 
681     EVP_PKEY_free(pkey);
682     return ok;
683 }
684 
test_unprotected_via_MSBLOB(const char * type,EVP_PKEY * key)685 static int test_unprotected_via_MSBLOB(const char *type, EVP_PKEY *key)
686 {
687     return test_encode_decode(__FILE__, __LINE__, type, key,
688         OSSL_KEYMGMT_SELECT_KEYPAIR
689             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
690         "MSBLOB", NULL, NULL, NULL,
691         encode_EVP_PKEY_MSBLOB, decode_EVP_PKEY_prov,
692         test_mem, check_MSBLOB,
693         dump_der, 0);
694 }
695 
check_PVK(const char * file,const int line,const char * type,const void * data,size_t data_len)696 static int check_PVK(const char *file, const int line,
697     const char *type, const void *data, size_t data_len)
698 {
699     const unsigned char *in = data;
700     unsigned int saltlen = 0, keylen = 0;
701     int isdss = -1;
702 
703     return ossl_do_PVK_header(&in, data_len, 0, &isdss, &saltlen, &keylen);
704 }
705 
test_unprotected_via_PVK(const char * type,EVP_PKEY * key)706 static int test_unprotected_via_PVK(const char *type, EVP_PKEY *key)
707 {
708     return test_encode_decode(__FILE__, __LINE__, type, key,
709         OSSL_KEYMGMT_SELECT_KEYPAIR
710             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
711         "PVK", NULL, NULL, NULL,
712         encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
713         test_mem, check_PVK,
714         dump_der, 0);
715 }
716 
717 static const char *pass_cipher = "AES-256-CBC";
718 static const char *pass = "the holy handgrenade of antioch";
719 
check_protected_PKCS8_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)720 static int check_protected_PKCS8_DER(const char *file, const int line,
721     const char *type,
722     const void *data, size_t data_len)
723 {
724     const unsigned char *datap = data;
725     X509_SIG *p8 = d2i_X509_SIG(NULL, &datap, data_len);
726     int ok = TEST_FL_ptr(p8);
727 
728     X509_SIG_free(p8);
729     return ok;
730 }
731 
test_protected_via_DER(const char * type,EVP_PKEY * key,int fips)732 static int test_protected_via_DER(const char *type, EVP_PKEY *key, int fips)
733 {
734     return test_encode_decode(__FILE__, __LINE__, type, key,
735         OSSL_KEYMGMT_SELECT_KEYPAIR
736             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
737         "DER", "EncryptedPrivateKeyInfo",
738         pass, pass_cipher,
739         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
740         test_mem, check_protected_PKCS8_DER,
741         dump_der, fips ? 0 : FLAG_FAIL_IF_FIPS);
742 }
743 
check_protected_PKCS8_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)744 static int check_protected_PKCS8_PEM(const char *file, const int line,
745     const char *type,
746     const void *data, size_t data_len)
747 {
748     static const char expected_pem_header[] = "-----BEGIN " PEM_STRING_PKCS8 "-----";
749 
750     return TEST_FL_strn_eq(data, expected_pem_header,
751         sizeof(expected_pem_header) - 1);
752 }
753 
test_protected_via_PEM(const char * type,EVP_PKEY * key,int fips)754 static int test_protected_via_PEM(const char *type, EVP_PKEY *key, int fips)
755 {
756     return test_encode_decode(__FILE__, __LINE__, type, key,
757         OSSL_KEYMGMT_SELECT_KEYPAIR
758             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
759         "PEM", "EncryptedPrivateKeyInfo",
760         pass, pass_cipher,
761         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
762         test_text, check_protected_PKCS8_PEM,
763         dump_pem, fips ? 0 : FLAG_FAIL_IF_FIPS);
764 }
765 
check_protected_legacy_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)766 static int check_protected_legacy_PEM(const char *file, const int line,
767     const char *type,
768     const void *data, size_t data_len)
769 {
770     static char expected_pem_header[80];
771 
772     return TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
773                               sizeof(expected_pem_header),
774                               "-----BEGIN %s PRIVATE KEY-----", type),
775                0)
776         && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header))
777         && TEST_FL_ptr(strstr(data, "\nDEK-Info: "));
778 }
779 
test_protected_via_legacy_PEM(const char * type,EVP_PKEY * key)780 static int test_protected_via_legacy_PEM(const char *type, EVP_PKEY *key)
781 {
782     if (!default_libctx || is_fips)
783         return TEST_skip("Test not available if using a non-default library context or FIPS provider");
784 
785     return test_encode_decode(__FILE__, __LINE__, type, key,
786         OSSL_KEYMGMT_SELECT_KEYPAIR
787             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
788         "PEM", "type-specific", pass, pass_cipher,
789         encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
790         test_text, check_protected_legacy_PEM,
791         dump_pem, 0);
792 }
793 
794 #ifndef OPENSSL_NO_RC4
test_protected_via_PVK(const char * type,EVP_PKEY * key)795 static int test_protected_via_PVK(const char *type, EVP_PKEY *key)
796 {
797     int ret = 0;
798     OSSL_PROVIDER *lgcyprov = OSSL_PROVIDER_load(testctx, "legacy");
799     if (lgcyprov == NULL)
800         return TEST_skip("Legacy provider not available");
801 
802     ret = test_encode_decode(__FILE__, __LINE__, type, key,
803         OSSL_KEYMGMT_SELECT_KEYPAIR
804             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
805         "PVK", NULL, pass, NULL,
806         encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
807         test_mem, check_PVK, dump_der, 0);
808     OSSL_PROVIDER_unload(lgcyprov);
809     return ret;
810 }
811 #endif
812 
check_public_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)813 static int check_public_DER(const char *file, const int line,
814     const char *type, const void *data, size_t data_len)
815 {
816     const unsigned char *datap = data;
817     EVP_PKEY *pkey = d2i_PUBKEY_ex(NULL, &datap, data_len, testctx, testpropq);
818     int ok = (TEST_FL_ptr(pkey) && TEST_FL_true(EVP_PKEY_is_a(pkey, type)));
819 
820     EVP_PKEY_free(pkey);
821     return ok;
822 }
823 
test_public_via_DER(const char * type,EVP_PKEY * key,int fips)824 static int test_public_via_DER(const char *type, EVP_PKEY *key, int fips)
825 {
826     return test_encode_decode(__FILE__, __LINE__, type, key,
827         OSSL_KEYMGMT_SELECT_PUBLIC_KEY
828             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
829         "DER", "SubjectPublicKeyInfo", NULL, NULL,
830         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
831         test_mem, check_public_DER, dump_der,
832         fips ? 0 : FLAG_FAIL_IF_FIPS);
833 }
834 
check_public_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)835 static int check_public_PEM(const char *file, const int line,
836     const char *type, const void *data, size_t data_len)
837 {
838     static const char expected_pem_header[] = "-----BEGIN " PEM_STRING_PUBLIC "-----";
839 
840     return TEST_FL_strn_eq(data, expected_pem_header,
841         sizeof(expected_pem_header) - 1);
842 }
843 
test_public_via_PEM(const char * type,EVP_PKEY * key,int fips)844 static int test_public_via_PEM(const char *type, EVP_PKEY *key, int fips)
845 {
846     return test_encode_decode(__FILE__, __LINE__, type, key,
847         OSSL_KEYMGMT_SELECT_PUBLIC_KEY
848             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
849         "PEM", "SubjectPublicKeyInfo", NULL, NULL,
850         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
851         test_text, check_public_PEM, dump_pem,
852         fips ? 0 : FLAG_FAIL_IF_FIPS);
853 }
854 
check_public_MSBLOB(const char * file,const int line,const char * type,const void * data,size_t data_len)855 static int check_public_MSBLOB(const char *file, const int line,
856     const char *type,
857     const void *data, size_t data_len)
858 {
859     const unsigned char *datap = data;
860     EVP_PKEY *pkey = b2i_PublicKey(&datap, data_len);
861     int ok = TEST_FL_ptr(pkey);
862 
863     EVP_PKEY_free(pkey);
864     return ok;
865 }
866 
test_public_via_MSBLOB(const char * type,EVP_PKEY * key)867 static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
868 {
869     return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
870         "MSBLOB", NULL, NULL, NULL,
871         encode_EVP_PKEY_MSBLOB, decode_EVP_PKEY_prov,
872         test_mem, check_public_MSBLOB, dump_der, 0);
873 }
874 
875 /*
876  * Build a public-only EVP_PKEY of the same algorithm as |src| by
877  * round-tripping the public component through OSSL_PARAMs.
878  */
make_public_only_copy(EVP_PKEY * src)879 static EVP_PKEY *make_public_only_copy(EVP_PKEY *src)
880 {
881     OSSL_PARAM *params = NULL;
882     EVP_PKEY_CTX *cctx = NULL;
883     EVP_PKEY *pub = NULL;
884 
885     if (!EVP_PKEY_todata(src, EVP_PKEY_PUBLIC_KEY, &params))
886         goto end;
887     if ((cctx = EVP_PKEY_CTX_new_from_pkey(NULL, src, NULL)) == NULL
888         || EVP_PKEY_fromdata_init(cctx) <= 0
889         || EVP_PKEY_fromdata(cctx, &pub, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
890         EVP_PKEY_free(pub);
891         pub = NULL;
892     }
893 end:
894     OSSL_PARAM_free(params);
895     EVP_PKEY_CTX_free(cctx);
896     return pub;
897 }
898 
899 /*
900  * Build an "embryonic" EVP_PKEY of the same algorithm as |src|: just
901  * the keymgmt-bound type and (where applicable) domain parameters,
902  * with no key material.  Mirrors the idiom used in
903  * test/ml_kem_evp_extra_test.c.
904  */
make_embryonic_copy(EVP_PKEY * src)905 static EVP_PKEY *make_embryonic_copy(EVP_PKEY *src)
906 {
907     EVP_PKEY *embryo = EVP_PKEY_new();
908 
909     if (embryo == NULL)
910         return NULL;
911     if (EVP_PKEY_copy_parameters(embryo, src) <= 0) {
912         EVP_PKEY_free(embryo);
913         return NULL;
914     }
915     return embryo;
916 }
917 
918 /*
919  * Check that EVP_PKEY_dup() works for every supported provider-backed
920  * key type, and that the duplicate compares equal to the original.
921  *
922  * Exercised in three shapes:
923  *   1. The full keypair |key| (typically pub + priv).
924  *   2. A public-only key derived from |key|.
925  *   3. An "embryonic" key (algorithm + domain parameters only, no key
926  *      material) produced with EVP_PKEY_copy_parameters().  Not every
927  *      keymgmt allows building such a key (RSA's dup refuses any
928  *      selection without keypair bits); when EVP_PKEY_copy_parameters
929  *      fails we skip this arm with a TEST_info().
930  */
test_dup(const char * type,EVP_PKEY * key)931 static int test_dup(const char *type, EVP_PKEY *key)
932 {
933     EVP_PKEY *dup = NULL;
934     EVP_PKEY *pub_only = NULL;
935     EVP_PKEY *embryo = NULL;
936     int ok = 0;
937 
938     if (!TEST_ptr(key)) {
939         TEST_info("%s: no source key", type);
940         return 0;
941     }
942 
943     /* 1. Dup the full keypair. */
944     if (!TEST_ptr(dup = EVP_PKEY_dup(key))) {
945         TEST_info("%s: EVP_PKEY_dup of keypair returned NULL", type);
946         goto end;
947     }
948     if (!TEST_int_eq(EVP_PKEY_eq(key, dup), 1)) {
949         TEST_info("%s: keypair dup does not compare equal to original", type);
950         goto end;
951     }
952     EVP_PKEY_free(dup);
953     dup = NULL;
954 
955     /* 2. Dup a public-only copy of the same key. */
956     if (!TEST_ptr(pub_only = make_public_only_copy(key))) {
957         TEST_info("%s: could not derive a public-only key", type);
958         goto end;
959     }
960     if (!TEST_ptr(dup = EVP_PKEY_dup(pub_only))) {
961         TEST_info("%s: EVP_PKEY_dup of public-only key returned NULL", type);
962         goto end;
963     }
964     if (!TEST_int_eq(EVP_PKEY_eq(pub_only, dup), 1)) {
965         TEST_info("%s: public-only dup does not compare equal to original",
966             type);
967         goto end;
968     }
969     EVP_PKEY_free(dup);
970     dup = NULL;
971 
972     /*
973      * 3. Dup an embryonic key.  EVP_PKEY_parameters_eq() answers 1 for
974      * algorithms with real domain parameters and may answer -2 ("nothing
975      * to compare") for those without.  We only reject 0 (definitively
976      * unequal) and -1 (different keymgmts).
977      */
978     embryo = make_embryonic_copy(key);
979     if (embryo != NULL) {
980         if (!TEST_ptr(dup = EVP_PKEY_dup(embryo))) {
981             TEST_info("%s: EVP_PKEY_dup of embryonic key returned NULL",
982                 type);
983             goto end;
984         }
985         {
986             int eq = EVP_PKEY_parameters_eq(embryo, dup);
987 
988             if (!TEST_true(eq == 1 || eq == -2)) {
989                 TEST_info("%s: embryonic dup parameters_eq %d (want 1 or -2)",
990                     type, eq);
991                 goto end;
992             }
993         }
994     } else {
995         TEST_info("%s: skipping embryonic dup (no params-only key shape)",
996             type);
997     }
998 
999     ok = 1;
1000 end:
1001     EVP_PKEY_free(dup);
1002     EVP_PKEY_free(pub_only);
1003     EVP_PKEY_free(embryo);
1004     return ok;
1005 }
1006 
1007 /*
1008  * Drive EVP_PKEY_fromdata with the supplied OSSL_PARAM[] (NULL =
1009  * empty array) for the given selection.  Either outcome is accepted:
1010  * fromdata may reject the input, or it may succeed and yield a key
1011  * with at most algorithm-bound parameters.  In the success case a
1012  * battery of common consumer ops must not crash on the resulting
1013  * key; their return values are not asserted.
1014  */
run_empty_fromdata_probe(const char * type,EVP_PKEY_CTX * cctx,int selection,OSSL_PARAM * params,const char * selname)1015 static int run_empty_fromdata_probe(const char *type, EVP_PKEY_CTX *cctx,
1016     int selection, OSSL_PARAM *params, const char *selname)
1017 {
1018     EVP_PKEY *pkey = NULL;
1019     OSSL_PARAM empty[1];
1020     int r;
1021     int ok = 0;
1022 
1023     if (params == NULL) {
1024         empty[0] = OSSL_PARAM_construct_end();
1025         params = empty;
1026     }
1027 
1028     if (!TEST_int_gt(EVP_PKEY_fromdata_init(cctx), 0)) {
1029         TEST_info("%s: fromdata_init failed (%s)", type, selname);
1030         goto end;
1031     }
1032     r = EVP_PKEY_fromdata(cctx, &pkey, selection, params);
1033     if (r <= 0) {
1034         /* Rejection is fine, but the out-pointer must remain NULL. */
1035         if (!TEST_ptr_null(pkey)) {
1036             TEST_info("%s: fromdata returned %d but pkey != NULL (%s)",
1037                 type, r, selname);
1038             goto end;
1039         }
1040         ok = 1;
1041         goto end;
1042     }
1043     if (!TEST_ptr(pkey)) {
1044         TEST_info("%s: fromdata returned %d but pkey == NULL (%s)",
1045             type, r, selname);
1046         goto end;
1047     }
1048     /*
1049      * Walk a battery of common consumer ops on the resulting key.
1050      * Their return values are not asserted - a contentless key may
1051      * fail every op - only crashing is forbidden.
1052      */
1053     (void)EVP_PKEY_get_bits(pkey);
1054     (void)EVP_PKEY_get_security_bits(pkey);
1055     (void)EVP_PKEY_get_size(pkey);
1056     (void)EVP_PKEY_eq(pkey, pkey);
1057     (void)EVP_PKEY_parameters_eq(pkey, pkey);
1058     {
1059         OSSL_PARAM *out = NULL;
1060 
1061         if (EVP_PKEY_todata(pkey, selection, &out) > 0)
1062             OSSL_PARAM_free(out);
1063     }
1064     {
1065         EVP_PKEY *clone = EVP_PKEY_dup(pkey);
1066 
1067         EVP_PKEY_free(clone);
1068     }
1069     {
1070         BIO *bio = BIO_new(BIO_s_null());
1071 
1072         if (bio != NULL) {
1073             (void)EVP_PKEY_print_public(bio, pkey, 0, NULL);
1074             (void)EVP_PKEY_print_private(bio, pkey, 0, NULL);
1075             (void)EVP_PKEY_print_params(bio, pkey, 0, NULL);
1076             BIO_free(bio);
1077         }
1078     }
1079     {
1080         /* The param/public/private/pairwise check family. */
1081         EVP_PKEY_CTX *vctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
1082 
1083         if (vctx != NULL) {
1084             (void)EVP_PKEY_param_check(vctx);
1085             (void)EVP_PKEY_param_check_quick(vctx);
1086             (void)EVP_PKEY_public_check(vctx);
1087             (void)EVP_PKEY_public_check_quick(vctx);
1088             (void)EVP_PKEY_private_check(vctx);
1089             (void)EVP_PKEY_pairwise_check(vctx);
1090             EVP_PKEY_CTX_free(vctx);
1091         }
1092     }
1093     ok = 1;
1094 end:
1095     EVP_PKEY_free(pkey);
1096     return ok;
1097 }
1098 
probe_empty_fromdata(const char * type,EVP_PKEY * prototype,int selection,const char * selname)1099 static int probe_empty_fromdata(const char *type, EVP_PKEY *prototype,
1100     int selection, const char *selname)
1101 {
1102     EVP_PKEY_CTX *cctx = NULL;
1103     int ok = 0;
1104 
1105     if (!TEST_ptr(cctx = EVP_PKEY_CTX_new_from_pkey(NULL, prototype, NULL))) {
1106         TEST_info("%s: CTX alloc failed for empty fromdata (%s)",
1107             type, selname);
1108         goto end;
1109     }
1110     ok = run_empty_fromdata_probe(type, cctx, selection, NULL, selname);
1111 end:
1112     EVP_PKEY_CTX_free(cctx);
1113     return ok;
1114 }
1115 
1116 /*
1117  * Drive EVP_PKEY_fromdata with an empty OSSL_PARAM[] for both
1118  * EVP_PKEY_PUBLIC_KEY and EVP_PKEY_KEYPAIR selections.  Either
1119  * outcome is acceptable: fromdata rejects, or it succeeds and the
1120  * resulting key survives the consumer-op battery without crashing.
1121  */
test_fromdata(const char * type,EVP_PKEY * prototype)1122 static int test_fromdata(const char *type, EVP_PKEY *prototype)
1123 {
1124     if (!TEST_ptr(prototype)) {
1125         TEST_info("%s: no prototype key", type);
1126         return 0;
1127     }
1128     if (!probe_empty_fromdata(type, prototype, EVP_PKEY_PUBLIC_KEY,
1129             "EVP_PKEY_PUBLIC_KEY"))
1130         return 0;
1131     if (!probe_empty_fromdata(type, prototype, EVP_PKEY_KEYPAIR,
1132             "EVP_PKEY_KEYPAIR"))
1133         return 0;
1134     return 1;
1135 }
1136 
1137 /*
1138  * Named-group-only partial-shape variants for prototype-matrix
1139  * algorithms, plus any keymgmts without a keygen path.  Each entry
1140  * is one (name, selection, params-builder) shape; a NULL builder
1141  * means "use an empty OSSL_PARAM[]".  Algorithms not loadable under
1142  * the active provider set are silently skipped.
1143  */
1144 typedef int (*fromdata_shape_build_fn)(OSSL_PARAM_BLD *bld);
1145 
1146 struct fromdata_shape {
1147     const char *name; /* keymgmt algorithm name */
1148     int selection; /* EVP_PKEY_PUBLIC_KEY / KEYPAIR / etc. */
1149     fromdata_shape_build_fn build; /* NULL -> empty OSSL_PARAM[] */
1150     const char *label; /* diagnostic label */
1151 };
1152 
1153 #ifndef OPENSSL_NO_DH
build_dh_named_group(OSSL_PARAM_BLD * bld)1154 static int build_dh_named_group(OSSL_PARAM_BLD *bld)
1155 {
1156     return OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1157         "ffdhe2048", 0);
1158 }
1159 #endif
1160 
1161 #ifndef OPENSSL_NO_EC
build_ec_named_group(OSSL_PARAM_BLD * bld)1162 static int build_ec_named_group(OSSL_PARAM_BLD *bld)
1163 {
1164     return OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1165         "P-256", 0);
1166 }
1167 #ifndef OPENSSL_NO_SM2
build_sm2_named_group(OSSL_PARAM_BLD * bld)1168 static int build_sm2_named_group(OSSL_PARAM_BLD *bld)
1169 {
1170     return OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1171         "SM2", 0);
1172 }
1173 #endif
1174 #endif
1175 
1176 #if defined(OPENSSL_NO_DH) && defined(OPENSSL_NO_EC) && defined(OPENSSL_NO_SM2)
1177 #undef TEST_FROMDATA_NO_KEYGEN
1178 #else
1179 #define TEST_FROMDATA_NO_KEYGEN
1180 
1181 static const struct fromdata_shape no_keygen_shapes[] = {
1182 /* Named-group-only partial shapes. */
1183 #ifndef OPENSSL_NO_DH
1184     { "DH", EVP_PKEY_KEYPAIR, build_dh_named_group,
1185         "DH / named group only / KEYPAIR" },
1186     { "DH", EVP_PKEY_PUBLIC_KEY, build_dh_named_group,
1187         "DH / named group only / PUBLIC_KEY" },
1188 #endif
1189 #ifndef OPENSSL_NO_EC
1190     { "EC", EVP_PKEY_KEYPAIR, build_ec_named_group,
1191         "EC / group only / KEYPAIR" },
1192     { "EC", EVP_PKEY_PUBLIC_KEY, build_ec_named_group,
1193         "EC / group only / PUBLIC_KEY" },
1194 #ifndef OPENSSL_NO_SM2
1195     { "SM2", EVP_PKEY_KEYPAIR, build_sm2_named_group,
1196         "SM2 / group only / KEYPAIR" },
1197 #endif
1198 #endif
1199 };
1200 
1201 /*
1202  * Probe an algorithm by name rather than a prototype key, for keymgmts without
1203  * a keygen path.  Algorithms not loadable under the active provider set are
1204  * silently skipped.  |params| may be NULL (= empty OSSL_PARAM[]) or a
1205  * caller-built partial array.
1206  */
probe_fromdata_by_name(const char * name,int selection,OSSL_PARAM * params,const char * selname)1207 static int probe_fromdata_by_name(const char *name, int selection,
1208     OSSL_PARAM *params, const char *selname)
1209 {
1210     EVP_PKEY_CTX *cctx = NULL;
1211     int ok = 1;
1212 
1213     cctx = EVP_PKEY_CTX_new_from_name(NULL, name, NULL);
1214     if (cctx == NULL)
1215         return 1;
1216     ok = run_empty_fromdata_probe(name, cctx, selection, params, selname);
1217     EVP_PKEY_CTX_free(cctx);
1218     return ok;
1219 }
1220 
test_fromdata_no_keygen(void)1221 static int test_fromdata_no_keygen(void)
1222 {
1223     size_t i;
1224 
1225     for (i = 0; i < OSSL_NELEM(no_keygen_shapes); i++) {
1226         const struct fromdata_shape *s = &no_keygen_shapes[i];
1227         OSSL_PARAM_BLD *bld = NULL;
1228         OSSL_PARAM *params = NULL;
1229         int ok;
1230 
1231         if (s->build != NULL) {
1232             if (!TEST_ptr(bld = OSSL_PARAM_BLD_new()))
1233                 return 0;
1234             if (!s->build(bld)) {
1235                 TEST_info("%s: builder failed", s->label);
1236                 OSSL_PARAM_BLD_free(bld);
1237                 return 0;
1238             }
1239             params = OSSL_PARAM_BLD_to_param(bld);
1240             if (!TEST_ptr(params)) {
1241                 OSSL_PARAM_BLD_free(bld);
1242                 return 0;
1243             }
1244         }
1245         ok = probe_fromdata_by_name(s->name, s->selection, params, s->label);
1246         OSSL_PARAM_free(params);
1247         OSSL_PARAM_BLD_free(bld);
1248         if (!ok)
1249             return 0;
1250     }
1251     return 1;
1252 }
1253 #endif
1254 
1255 #define KEYS(KEYTYPE) \
1256     static EVP_PKEY *key_##KEYTYPE = NULL
1257 #define MAKE_KEYS(KEYTYPE, KEYTYPEstr, params) \
1258     ok &= TEST_ptr(key_##KEYTYPE = make_key(KEYTYPEstr, NULL, params))
1259 #define FREE_KEYS(KEYTYPE) \
1260     EVP_PKEY_free(key_##KEYTYPE);
1261 
1262 #define DOMAIN_KEYS(KEYTYPE)                    \
1263     static EVP_PKEY *template_##KEYTYPE = NULL; \
1264     static EVP_PKEY *key_##KEYTYPE = NULL
1265 #define MAKE_DOMAIN_KEYS(KEYTYPE, KEYTYPEstr, params)                 \
1266     do {                                                              \
1267         ok &= TEST_ptr(template_##KEYTYPE = make_template(KEYTYPEstr, \
1268                            params));                                  \
1269         ok &= TEST_ptr(key_##KEYTYPE = make_key(KEYTYPEstr,           \
1270                            template_##KEYTYPE, NULL));                \
1271     } while (0)
1272 #define FREE_DOMAIN_KEYS(KEYTYPE)      \
1273     EVP_PKEY_free(template_##KEYTYPE); \
1274     EVP_PKEY_free(key_##KEYTYPE)
1275 
1276 #define IMPLEMENT_TEST_SUITE(KEYTYPE, KEYTYPEstr, fips)                   \
1277     static int test_unprotected_##KEYTYPE##_via_DER(void)                 \
1278     {                                                                     \
1279         return test_unprotected_via_DER(KEYTYPEstr, key_##KEYTYPE, fips); \
1280     }                                                                     \
1281     static int test_unprotected_##KEYTYPE##_via_PEM(void)                 \
1282     {                                                                     \
1283         return test_unprotected_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips); \
1284     }                                                                     \
1285     static int test_protected_##KEYTYPE##_via_DER(void)                   \
1286     {                                                                     \
1287         return test_protected_via_DER(KEYTYPEstr, key_##KEYTYPE, fips);   \
1288     }                                                                     \
1289     static int test_protected_##KEYTYPE##_via_PEM(void)                   \
1290     {                                                                     \
1291         return test_protected_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips);   \
1292     }                                                                     \
1293     static int test_public_##KEYTYPE##_via_DER(void)                      \
1294     {                                                                     \
1295         return test_public_via_DER(KEYTYPEstr, key_##KEYTYPE, fips);      \
1296     }                                                                     \
1297     static int test_public_##KEYTYPE##_via_PEM(void)                      \
1298     {                                                                     \
1299         return test_public_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips);      \
1300     }                                                                     \
1301     static int test_dup_##KEYTYPE(void)                                   \
1302     {                                                                     \
1303         return test_dup(KEYTYPEstr, key_##KEYTYPE);                       \
1304     }                                                                     \
1305     static int test_fromdata_##KEYTYPE(void)                              \
1306     {                                                                     \
1307         return test_fromdata(KEYTYPEstr, key_##KEYTYPE);                  \
1308     }
1309 
1310 #define ADD_TEST_SUITE(KEYTYPE)                             \
1311     do {                                                    \
1312         if (key_##KEYTYPE != NULL) {                        \
1313             ADD_TEST(test_unprotected_##KEYTYPE##_via_DER); \
1314             ADD_TEST(test_unprotected_##KEYTYPE##_via_PEM); \
1315             ADD_TEST(test_protected_##KEYTYPE##_via_DER);   \
1316             ADD_TEST(test_protected_##KEYTYPE##_via_PEM);   \
1317             ADD_TEST(test_public_##KEYTYPE##_via_DER);      \
1318             ADD_TEST(test_public_##KEYTYPE##_via_PEM);      \
1319             ADD_TEST(test_dup_##KEYTYPE);                   \
1320             ADD_TEST(test_fromdata_##KEYTYPE);              \
1321         }                                                   \
1322     } while (0)
1323 
1324 #define IMPLEMENT_TEST_SUITE_PARAMS(KEYTYPE, KEYTYPEstr)       \
1325     static int test_params_##KEYTYPE##_via_DER(void)           \
1326     {                                                          \
1327         return test_params_via_DER(KEYTYPEstr, key_##KEYTYPE); \
1328     }                                                          \
1329     static int test_params_##KEYTYPE##_via_PEM(void)           \
1330     {                                                          \
1331         return test_params_via_PEM(KEYTYPEstr, key_##KEYTYPE); \
1332     }
1333 
1334 #define ADD_TEST_SUITE_PARAMS(KEYTYPE)                 \
1335     do {                                               \
1336         if (key_##KEYTYPE != NULL) {                   \
1337             ADD_TEST(test_params_##KEYTYPE##_via_DER); \
1338             ADD_TEST(test_params_##KEYTYPE##_via_PEM); \
1339         }                                              \
1340     } while (0)
1341 
1342 #define IMPLEMENT_TEST_SUITE_LEGACY(KEYTYPE, KEYTYPEstr)                   \
1343     static int test_unprotected_##KEYTYPE##_via_legacy_PEM(void)           \
1344     {                                                                      \
1345         return test_unprotected_via_legacy_PEM(KEYTYPEstr, key_##KEYTYPE); \
1346     }                                                                      \
1347     static int test_protected_##KEYTYPE##_via_legacy_PEM(void)             \
1348     {                                                                      \
1349         return test_protected_via_legacy_PEM(KEYTYPEstr, key_##KEYTYPE);   \
1350     }
1351 
1352 #define ADD_TEST_SUITE_LEGACY(KEYTYPE)                             \
1353     do {                                                           \
1354         if (key_##KEYTYPE != NULL) {                               \
1355             ADD_TEST(test_unprotected_##KEYTYPE##_via_legacy_PEM); \
1356             ADD_TEST(test_protected_##KEYTYPE##_via_legacy_PEM);   \
1357         }                                                          \
1358     } while (0)
1359 
1360 #define IMPLEMENT_TEST_SUITE_MSBLOB(KEYTYPE, KEYTYPEstr)               \
1361     static int test_unprotected_##KEYTYPE##_via_MSBLOB(void)           \
1362     {                                                                  \
1363         return test_unprotected_via_MSBLOB(KEYTYPEstr, key_##KEYTYPE); \
1364     }                                                                  \
1365     static int test_public_##KEYTYPE##_via_MSBLOB(void)                \
1366     {                                                                  \
1367         return test_public_via_MSBLOB(KEYTYPEstr, key_##KEYTYPE);      \
1368     }
1369 
1370 #define ADD_TEST_SUITE_MSBLOB(KEYTYPE)                         \
1371     do {                                                       \
1372         if (key_##KEYTYPE != NULL) {                           \
1373             ADD_TEST(test_unprotected_##KEYTYPE##_via_MSBLOB); \
1374             ADD_TEST(test_public_##KEYTYPE##_via_MSBLOB);      \
1375         }                                                      \
1376     } while (0)
1377 
1378 #define IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(KEYTYPE, KEYTYPEstr)   \
1379     static int test_unprotected_##KEYTYPE##_via_PVK(void)           \
1380     {                                                               \
1381         return test_unprotected_via_PVK(KEYTYPEstr, key_##KEYTYPE); \
1382     }
1383 #define ADD_TEST_SUITE_UNPROTECTED_PVK(KEYTYPE)             \
1384     do {                                                    \
1385         if (key_##KEYTYPE != NULL)                          \
1386             ADD_TEST(test_unprotected_##KEYTYPE##_via_PVK); \
1387     } while (0)
1388 #ifndef OPENSSL_NO_RC4
1389 #define IMPLEMENT_TEST_SUITE_PROTECTED_PVK(KEYTYPE, KEYTYPEstr)   \
1390     static int test_protected_##KEYTYPE##_via_PVK(void)           \
1391     {                                                             \
1392         return test_protected_via_PVK(KEYTYPEstr, key_##KEYTYPE); \
1393     }
1394 #define ADD_TEST_SUITE_PROTECTED_PVK(KEYTYPE)             \
1395     do {                                                  \
1396         if (key_##KEYTYPE != NULL)                        \
1397             ADD_TEST(test_protected_##KEYTYPE##_via_PVK); \
1398     } while (0)
1399 #endif
1400 
1401 #ifndef OPENSSL_NO_DH
1402 DOMAIN_KEYS(DH);
1403 IMPLEMENT_TEST_SUITE(DH, "DH", 1)
1404 IMPLEMENT_TEST_SUITE_PARAMS(DH, "DH")
1405 DOMAIN_KEYS(DHX);
1406 IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH", 1)
1407 IMPLEMENT_TEST_SUITE_PARAMS(DHX, "X9.42 DH")
1408 /*
1409  * DH has no support for PEM_write_bio_PrivateKey_traditional(),
1410  * so no legacy tests.
1411  */
1412 #endif
1413 #ifndef OPENSSL_NO_DSA
1414 DOMAIN_KEYS(DSA);
1415 IMPLEMENT_TEST_SUITE(DSA, "DSA", 1)
1416 IMPLEMENT_TEST_SUITE_PARAMS(DSA, "DSA")
1417 IMPLEMENT_TEST_SUITE_LEGACY(DSA, "DSA")
1418 IMPLEMENT_TEST_SUITE_MSBLOB(DSA, "DSA")
1419 IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(DSA, "DSA")
1420 #ifndef OPENSSL_NO_RC4
1421 IMPLEMENT_TEST_SUITE_PROTECTED_PVK(DSA, "DSA")
1422 #endif
1423 #endif
1424 #ifndef OPENSSL_NO_EC
1425 DOMAIN_KEYS(EC);
1426 IMPLEMENT_TEST_SUITE(EC, "EC", 1)
1427 IMPLEMENT_TEST_SUITE_PARAMS(EC, "EC")
1428 IMPLEMENT_TEST_SUITE_LEGACY(EC, "EC")
1429 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
1430 DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
1431 IMPLEMENT_TEST_SUITE(ECExplicitPrimeNamedCurve, "EC", 1)
1432 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve, "EC")
1433 DOMAIN_KEYS(ECExplicitPrime2G);
1434 IMPLEMENT_TEST_SUITE(ECExplicitPrime2G, "EC", 0)
1435 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrime2G, "EC")
1436 #ifndef OPENSSL_NO_EC2M
1437 DOMAIN_KEYS(ECExplicitTriNamedCurve);
1438 IMPLEMENT_TEST_SUITE(ECExplicitTriNamedCurve, "EC", 1)
1439 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitTriNamedCurve, "EC")
1440 DOMAIN_KEYS(ECExplicitTri2G);
1441 IMPLEMENT_TEST_SUITE(ECExplicitTri2G, "EC", 0)
1442 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitTri2G, "EC")
1443 #endif
1444 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
1445 #ifndef OPENSSL_NO_SM2
1446 KEYS(SM2);
1447 IMPLEMENT_TEST_SUITE(SM2, "SM2", 0)
1448 #endif
1449 #endif
1450 #ifndef OPENSSL_NO_ECX
1451 /*
1452  * ED25519, ED448, X25519 and X448 have no support for
1453  * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
1454  */
1455 KEYS(ED25519);
1456 IMPLEMENT_TEST_SUITE(ED25519, "ED25519", 1)
1457 KEYS(ED448);
1458 IMPLEMENT_TEST_SUITE(ED448, "ED448", 1)
1459 KEYS(X25519);
1460 IMPLEMENT_TEST_SUITE(X25519, "X25519", 1)
1461 KEYS(X448);
1462 IMPLEMENT_TEST_SUITE(X448, "X448", 1)
1463 #endif
1464 #ifndef OPENSSL_NO_ML_KEM
1465 /*
1466  * ML-KEM has no support for PEM_write_bio_PrivateKey_traditional(), so no
1467  * legacy tests.
1468  */
1469 KEYS(ML_KEM_512);
1470 IMPLEMENT_TEST_SUITE(ML_KEM_512, "ML-KEM-512", 1)
1471 KEYS(ML_KEM_768);
1472 IMPLEMENT_TEST_SUITE(ML_KEM_768, "ML-KEM-768", 1)
1473 KEYS(ML_KEM_1024);
1474 IMPLEMENT_TEST_SUITE(ML_KEM_1024, "ML-KEM-1024", 1)
1475 #endif
1476 #ifndef OPENSSL_NO_SLH_DSA
1477 KEYS(SLH_DSA_SHA2_128s);
1478 KEYS(SLH_DSA_SHA2_128f);
1479 KEYS(SLH_DSA_SHA2_192s);
1480 KEYS(SLH_DSA_SHA2_192f);
1481 KEYS(SLH_DSA_SHA2_256s);
1482 KEYS(SLH_DSA_SHA2_256f);
1483 KEYS(SLH_DSA_SHAKE_128s);
1484 KEYS(SLH_DSA_SHAKE_128f);
1485 KEYS(SLH_DSA_SHAKE_192s);
1486 KEYS(SLH_DSA_SHAKE_192f);
1487 KEYS(SLH_DSA_SHAKE_256s);
1488 KEYS(SLH_DSA_SHAKE_256f);
1489 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_128s, "SLH-DSA-SHA2-128s", 1)
1490 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_128f, "SLH-DSA-SHA2-128f", 1)
1491 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_192s, "SLH-DSA-SHA2-192s", 1)
1492 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_192f, "SLH-DSA-SHA2-192f", 1)
1493 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_256s, "SLH-DSA-SHA2-256s", 1)
1494 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_256f, "SLH-DSA-SHA2-256f", 1)
1495 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_128s, "SLH-DSA-SHAKE-128s", 1)
1496 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_128f, "SLH-DSA-SHAKE-128f", 1)
1497 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_192s, "SLH-DSA-SHAKE-192s", 1)
1498 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_192f, "SLH-DSA-SHAKE-192f", 1)
1499 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_256s, "SLH-DSA-SHAKE-256s", 1)
1500 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_256f, "SLH-DSA-SHAKE-256f", 1)
1501 #endif /* OPENSSL_NO_SLH_DSA */
1502 KEYS(RSA);
1503 IMPLEMENT_TEST_SUITE(RSA, "RSA", 1)
1504 IMPLEMENT_TEST_SUITE_LEGACY(RSA, "RSA")
1505 KEYS(RSA_PSS);
1506 IMPLEMENT_TEST_SUITE(RSA_PSS, "RSA-PSS", 1)
1507 /*
1508  * RSA-PSS has no support for PEM_write_bio_PrivateKey_traditional(),
1509  * so no legacy tests.
1510  */
1511 IMPLEMENT_TEST_SUITE_MSBLOB(RSA, "RSA")
1512 IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(RSA, "RSA")
1513 #ifndef OPENSSL_NO_RC4
1514 IMPLEMENT_TEST_SUITE_PROTECTED_PVK(RSA, "RSA")
1515 #endif
1516 
1517 #ifndef OPENSSL_NO_ML_DSA
1518 KEYS(ML_DSA_44);
1519 KEYS(ML_DSA_65);
1520 KEYS(ML_DSA_87);
1521 IMPLEMENT_TEST_SUITE(ML_DSA_44, "ML-DSA-44", 1)
1522 IMPLEMENT_TEST_SUITE(ML_DSA_65, "ML-DSA-65", 1)
1523 IMPLEMENT_TEST_SUITE(ML_DSA_87, "ML-DSA-87", 1)
1524 #endif /*  OPENSSL_NO_ML_DSA */
1525 
1526 #ifndef OPENSSL_NO_EC
1527 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
1528 /* Explicit parameters that match a named curve */
do_create_ec_explicit_prime_params(OSSL_PARAM_BLD * bld,const unsigned char * gen,size_t gen_len)1529 static int do_create_ec_explicit_prime_params(OSSL_PARAM_BLD *bld,
1530     const unsigned char *gen,
1531     size_t gen_len)
1532 {
1533     BIGNUM *a, *b, *prime, *order;
1534 
1535     /* Curve prime256v1 */
1536     static const unsigned char prime_data[] = {
1537         0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
1538         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1539         0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
1540         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1541         0xff
1542     };
1543     static const unsigned char a_data[] = {
1544         0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
1545         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1546         0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
1547         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1548         0xfc
1549     };
1550     static const unsigned char b_data[] = {
1551         0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
1552         0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
1553         0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
1554         0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b
1555     };
1556     static const unsigned char seed[] = {
1557         0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93,
1558         0x6a, 0x66, 0x78, 0xe1, 0x13, 0x9d, 0x26, 0xb7,
1559         0x81, 0x9f, 0x7e, 0x90
1560     };
1561     static const unsigned char order_data[] = {
1562         0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
1563         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1564         0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e,
1565         0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51
1566     };
1567     return TEST_ptr(a = BN_CTX_get(bnctx))
1568         && TEST_ptr(b = BN_CTX_get(bnctx))
1569         && TEST_ptr(prime = BN_CTX_get(bnctx))
1570         && TEST_ptr(order = BN_CTX_get(bnctx))
1571         && TEST_ptr(BN_bin2bn(prime_data, sizeof(prime_data), prime))
1572         && TEST_ptr(BN_bin2bn(a_data, sizeof(a_data), a))
1573         && TEST_ptr(BN_bin2bn(b_data, sizeof(b_data), b))
1574         && TEST_ptr(BN_bin2bn(order_data, sizeof(order_data), order))
1575         && TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
1576             OSSL_PKEY_PARAM_EC_FIELD_TYPE, SN_X9_62_prime_field,
1577             0))
1578         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, prime))
1579         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
1580         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b))
1581         && TEST_true(OSSL_PARAM_BLD_push_BN(bld,
1582             OSSL_PKEY_PARAM_EC_ORDER, order))
1583         && TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
1584             OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_len))
1585         && TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
1586             OSSL_PKEY_PARAM_EC_SEED, seed, sizeof(seed)))
1587         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
1588             BN_value_one()));
1589 }
1590 
create_ec_explicit_prime_params_namedcurve(OSSL_PARAM_BLD * bld)1591 static int create_ec_explicit_prime_params_namedcurve(OSSL_PARAM_BLD *bld)
1592 {
1593     static const unsigned char prime256v1_gen[] = {
1594         0x04,
1595         0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
1596         0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
1597         0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
1598         0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
1599         0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,
1600         0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
1601         0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
1602         0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5
1603     };
1604     return do_create_ec_explicit_prime_params(bld, prime256v1_gen,
1605         sizeof(prime256v1_gen));
1606 }
1607 
create_ec_explicit_prime_params(OSSL_PARAM_BLD * bld)1608 static int create_ec_explicit_prime_params(OSSL_PARAM_BLD *bld)
1609 {
1610     /* 2G */
1611     static const unsigned char prime256v1_gen2[] = {
1612         0x04,
1613         0xe4, 0x97, 0x08, 0xbe, 0x7d, 0xfa, 0xa2, 0x9a,
1614         0xa3, 0x12, 0x6f, 0xe4, 0xe7, 0xd0, 0x25, 0xe3,
1615         0x4a, 0xc1, 0x03, 0x15, 0x8c, 0xd9, 0x33, 0xc6,
1616         0x97, 0x42, 0xf5, 0xdc, 0x97, 0xb9, 0xd7, 0x31,
1617         0xe9, 0x7d, 0x74, 0x3d, 0x67, 0x6a, 0x3b, 0x21,
1618         0x08, 0x9c, 0x31, 0x73, 0xf8, 0xc1, 0x27, 0xc9,
1619         0xd2, 0xa0, 0xa0, 0x83, 0x66, 0xe0, 0xc9, 0xda,
1620         0xa8, 0xc6, 0x56, 0x2b, 0x94, 0xb1, 0xae, 0x55
1621     };
1622     return do_create_ec_explicit_prime_params(bld, prime256v1_gen2,
1623         sizeof(prime256v1_gen2));
1624 }
1625 
1626 #ifndef OPENSSL_NO_EC2M
do_create_ec_explicit_trinomial_params(OSSL_PARAM_BLD * bld,const unsigned char * gen,size_t gen_len)1627 static int do_create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld,
1628     const unsigned char *gen,
1629     size_t gen_len)
1630 {
1631     BIGNUM *a, *b, *poly, *order, *cofactor;
1632     /* sect233k1 characteristic-two-field tpBasis */
1633     static const unsigned char poly_data[] = {
1634         0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1635         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1636         0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
1637     };
1638     static const unsigned char a_data[] = {
1639         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1640         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1641         0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1642     };
1643     static const unsigned char b_data[] = {
1644         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1645         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1646         0x00, 0x00, 0x00, 0x00, 0x00, 0x01
1647     };
1648     static const unsigned char order_data[] = {
1649         0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1650         0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15, 0xBC, 0xD4, 0x6E, 0xFB,
1651         0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF
1652     };
1653     static const unsigned char cofactor_data[] = {
1654         0x4
1655     };
1656     return TEST_ptr(a = BN_CTX_get(bnctx))
1657         && TEST_ptr(b = BN_CTX_get(bnctx))
1658         && TEST_ptr(poly = BN_CTX_get(bnctx))
1659         && TEST_ptr(order = BN_CTX_get(bnctx))
1660         && TEST_ptr(cofactor = BN_CTX_get(bnctx))
1661         && TEST_ptr(BN_bin2bn(poly_data, sizeof(poly_data), poly))
1662         && TEST_ptr(BN_bin2bn(a_data, sizeof(a_data), a))
1663         && TEST_ptr(BN_bin2bn(b_data, sizeof(b_data), b))
1664         && TEST_ptr(BN_bin2bn(order_data, sizeof(order_data), order))
1665         && TEST_ptr(BN_bin2bn(cofactor_data, sizeof(cofactor_data), cofactor))
1666         && TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
1667             OSSL_PKEY_PARAM_EC_FIELD_TYPE,
1668             SN_X9_62_characteristic_two_field, 0))
1669         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, poly))
1670         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
1671         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b))
1672         && TEST_true(OSSL_PARAM_BLD_push_BN(bld,
1673             OSSL_PKEY_PARAM_EC_ORDER, order))
1674         && TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
1675             OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_len))
1676         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
1677             cofactor));
1678 }
1679 
create_ec_explicit_trinomial_params_namedcurve(OSSL_PARAM_BLD * bld)1680 static int create_ec_explicit_trinomial_params_namedcurve(OSSL_PARAM_BLD *bld)
1681 {
1682     static const unsigned char gen[] = {
1683         0x04,
1684         0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, 0x29, 0xF2,
1685         0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2, 0x6B, 0xF5, 0x0A, 0x4C,
1686         0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26,
1687         0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, 0x55, 0x5A,
1688         0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A, 0xEB, 0x9B, 0x56, 0xE0,
1689         0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3
1690     };
1691     return do_create_ec_explicit_trinomial_params(bld, gen, sizeof(gen));
1692 }
1693 
create_ec_explicit_trinomial_params(OSSL_PARAM_BLD * bld)1694 static int create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld)
1695 {
1696     static const unsigned char gen2[] = {
1697         0x04,
1698         0x00, 0xd7, 0xba, 0xd0, 0x26, 0x6c, 0x31, 0x6a, 0x78, 0x76, 0x01, 0xd1,
1699         0x32, 0x4b, 0x8f, 0x30, 0x29, 0x2d, 0x78, 0x30, 0xca, 0x43, 0xaa, 0xf0,
1700         0xa2, 0x5a, 0xd4, 0x0f, 0xb3, 0xf4,
1701         0x00, 0x85, 0x4b, 0x1b, 0x8d, 0x50, 0x10, 0xa5, 0x1c, 0x80, 0xf7, 0x86,
1702         0x40, 0x62, 0x4c, 0x87, 0xd1, 0x26, 0x7a, 0x9c, 0x5c, 0xe9, 0x82, 0x29,
1703         0xd1, 0x67, 0x70, 0x41, 0xea, 0xcb
1704     };
1705     return do_create_ec_explicit_trinomial_params(bld, gen2, sizeof(gen2));
1706 }
1707 #endif /* OPENSSL_NO_EC2M */
1708 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
1709 
1710 /*
1711  * Test that multiple calls to OSSL_ENCODER_to_data() do not cause side effects
1712  */
ec_encode_to_data_multi(void)1713 static int ec_encode_to_data_multi(void)
1714 {
1715     int ret;
1716     OSSL_ENCODER_CTX *ectx = NULL;
1717     EVP_PKEY *key = NULL;
1718     uint8_t *enc = NULL;
1719     size_t enc_len = 0;
1720 
1721     ret = TEST_ptr(key = EVP_PKEY_Q_keygen(testctx, "", "EC", "P-256"))
1722         && TEST_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(key, EVP_PKEY_KEYPAIR,
1723                         "DER", NULL, NULL))
1724         && TEST_int_eq(OSSL_ENCODER_to_data(ectx, NULL, &enc_len), 1)
1725         && TEST_int_eq(OSSL_ENCODER_to_data(ectx, &enc, &enc_len), 1);
1726     OPENSSL_free(enc);
1727     EVP_PKEY_free(key);
1728     OSSL_ENCODER_CTX_free(ectx);
1729     return ret;
1730 }
1731 #endif /* OPENSSL_NO_EC */
1732 
1733 typedef enum OPTION_choice {
1734     OPT_ERR = -1,
1735     OPT_EOF = 0,
1736     OPT_CONTEXT,
1737     OPT_RSA_FILE,
1738     OPT_RSA_PSS_FILE,
1739     OPT_CONFIG_FILE,
1740     OPT_PROVIDER_NAME,
1741     OPT_TEST_ENUM
1742 } OPTION_CHOICE;
1743 
test_get_options(void)1744 const OPTIONS *test_get_options(void)
1745 {
1746     static const OPTIONS options[] = {
1747         OPT_TEST_OPTIONS_DEFAULT_USAGE,
1748         { "context", OPT_CONTEXT, '-',
1749             "Explicitly use a non-default library context" },
1750         { "rsa", OPT_RSA_FILE, '<',
1751             "PEM format RSA key file to encode/decode" },
1752         { "pss", OPT_RSA_PSS_FILE, '<',
1753             "PEM format RSA-PSS key file to encode/decode" },
1754         { "config", OPT_CONFIG_FILE, '<',
1755             "The configuration file to use for the library context" },
1756         { "provider", OPT_PROVIDER_NAME, 's',
1757             "The provider to load (The default value is 'default')" },
1758         { NULL }
1759     };
1760     return options;
1761 }
1762 
setup_tests(void)1763 int setup_tests(void)
1764 {
1765     const char *rsa_file = NULL;
1766     const char *rsa_pss_file = NULL;
1767     const char *prov_name = "default";
1768     char *config_file = NULL;
1769     int ok = 1;
1770 
1771 #ifndef OPENSSL_NO_DSA
1772     static size_t qbits = 160; /* PVK only tolerates 160 Q bits */
1773     static size_t pbits = 1024; /* With 160 Q bits, we MUST use 1024 P bits */
1774     OSSL_PARAM DSA_params[] = {
1775         OSSL_PARAM_size_t("pbits", &pbits),
1776         OSSL_PARAM_size_t("qbits", &qbits),
1777         OSSL_PARAM_END
1778     };
1779 #endif
1780 
1781 #ifndef OPENSSL_NO_EC
1782     static char groupname[] = "prime256v1";
1783     OSSL_PARAM EC_params[] = {
1784         OSSL_PARAM_utf8_string("group", groupname, sizeof(groupname) - 1),
1785         OSSL_PARAM_END
1786     };
1787 #endif
1788 
1789     OPTION_CHOICE o;
1790 
1791     while ((o = opt_next()) != OPT_EOF) {
1792         switch (o) {
1793         case OPT_CONTEXT:
1794             default_libctx = 0;
1795             break;
1796         case OPT_PROVIDER_NAME:
1797             prov_name = opt_arg();
1798             break;
1799         case OPT_CONFIG_FILE:
1800             config_file = opt_arg();
1801             break;
1802         case OPT_RSA_FILE:
1803             rsa_file = opt_arg();
1804             break;
1805         case OPT_RSA_PSS_FILE:
1806             rsa_pss_file = opt_arg();
1807             break;
1808         case OPT_TEST_CASES:
1809             break;
1810         default:
1811             return 0;
1812         }
1813     }
1814 
1815     if (strcmp(prov_name, "fips") == 0)
1816         is_fips = 1;
1817 
1818     if (default_libctx) {
1819         if (!test_get_libctx(NULL, NULL, config_file, &deflprov, prov_name))
1820             return 0;
1821     } else {
1822         if (!test_get_libctx(&testctx, &nullprov, config_file, &deflprov, prov_name))
1823             return 0;
1824     }
1825 
1826     /* FIPS(3.0.0): provider imports explicit params but they won't work #17998 */
1827     is_fips_3_0_0 = is_fips && fips_provider_version_eq(testctx, 3, 0, 0);
1828     /* FIPS(3.5.0) is the first to support ML-DSA, ML-KEM and SLH-DSA */
1829     is_fips_lt_3_5 = is_fips && fips_provider_version_lt(testctx, 3, 5, 0);
1830 
1831 #ifdef STATIC_LEGACY
1832     /*
1833      * This test is always statically linked against libcrypto. We must not
1834      * attempt to load legacy.so that might be dynamically linked against
1835      * libcrypto. Instead we use a built-in version of the legacy provider.
1836      */
1837     if (!OSSL_PROVIDER_add_builtin(testctx, "legacy", ossl_legacy_provider_init))
1838         return 0;
1839 #endif
1840 
1841     /* Separate provider/ctx for generating the test data */
1842     if (!TEST_ptr(keyctx = OSSL_LIB_CTX_new()))
1843         return 0;
1844     if (!TEST_ptr(keyprov = OSSL_PROVIDER_load(keyctx, "default")))
1845         return 0;
1846 
1847 #ifndef OPENSSL_NO_EC
1848     if (!TEST_ptr(bnctx = BN_CTX_new_ex(testctx)))
1849         return 0;
1850 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
1851     if (!TEST_ptr(bld_prime_nc = OSSL_PARAM_BLD_new())
1852         || !TEST_ptr(bld_prime = OSSL_PARAM_BLD_new())
1853         || !create_ec_explicit_prime_params_namedcurve(bld_prime_nc)
1854         || !create_ec_explicit_prime_params(bld_prime)
1855         || !TEST_ptr(ec_explicit_prime_params_nc = OSSL_PARAM_BLD_to_param(bld_prime_nc))
1856         || !TEST_ptr(ec_explicit_prime_params_explicit = OSSL_PARAM_BLD_to_param(bld_prime))
1857 #ifndef OPENSSL_NO_EC2M
1858         || !TEST_ptr(bld_tri_nc = OSSL_PARAM_BLD_new())
1859         || !TEST_ptr(bld_tri = OSSL_PARAM_BLD_new())
1860         || !create_ec_explicit_trinomial_params_namedcurve(bld_tri_nc)
1861         || !create_ec_explicit_trinomial_params(bld_tri)
1862         || !TEST_ptr(ec_explicit_tri_params_nc = OSSL_PARAM_BLD_to_param(bld_tri_nc))
1863         || !TEST_ptr(ec_explicit_tri_params_explicit = OSSL_PARAM_BLD_to_param(bld_tri))
1864 #endif
1865     )
1866         return 0;
1867 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
1868 #endif
1869 
1870     TEST_info("Generating keys...");
1871 
1872 #ifndef OPENSSL_NO_DH
1873     TEST_info("Generating DH keys...");
1874     MAKE_DOMAIN_KEYS(DH, "DH", NULL);
1875     MAKE_DOMAIN_KEYS(DHX, "X9.42 DH", NULL);
1876 #endif
1877 #ifndef OPENSSL_NO_DSA
1878     TEST_info("Generating DSA keys...");
1879     MAKE_DOMAIN_KEYS(DSA, "DSA", DSA_params);
1880 #endif
1881 #ifndef OPENSSL_NO_EC
1882     TEST_info("Generating EC keys...");
1883     MAKE_DOMAIN_KEYS(EC, "EC", EC_params);
1884 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
1885     MAKE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve, "EC", ec_explicit_prime_params_nc);
1886     MAKE_DOMAIN_KEYS(ECExplicitPrime2G, "EC", ec_explicit_prime_params_explicit);
1887 #ifndef OPENSSL_NO_EC2M
1888     MAKE_DOMAIN_KEYS(ECExplicitTriNamedCurve, "EC", ec_explicit_tri_params_nc);
1889     MAKE_DOMAIN_KEYS(ECExplicitTri2G, "EC", ec_explicit_tri_params_explicit);
1890 #endif
1891 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
1892 #ifndef OPENSSL_NO_SM2
1893     MAKE_KEYS(SM2, "SM2", NULL);
1894 #endif
1895 #endif
1896 #ifndef OPENSSL_NO_ECX
1897     MAKE_KEYS(ED25519, "ED25519", NULL);
1898     MAKE_KEYS(ED448, "ED448", NULL);
1899     MAKE_KEYS(X25519, "X25519", NULL);
1900     MAKE_KEYS(X448, "X448", NULL);
1901 #endif
1902 #ifndef OPENSSL_NO_ML_DSA
1903     if (!is_fips_lt_3_5) {
1904         MAKE_KEYS(ML_DSA_44, "ML-DSA-44", NULL);
1905         MAKE_KEYS(ML_DSA_65, "ML-DSA-65", NULL);
1906         MAKE_KEYS(ML_DSA_87, "ML-DSA-87", NULL);
1907     }
1908 #endif /* OPENSSL_NO_ML_DSA */
1909 #ifndef OPENSSL_NO_ML_KEM
1910     if (!is_fips_lt_3_5) {
1911         MAKE_KEYS(ML_KEM_512, "ML-KEM-512", NULL);
1912         MAKE_KEYS(ML_KEM_768, "ML-KEM-768", NULL);
1913         MAKE_KEYS(ML_KEM_1024, "ML-KEM-1024", NULL);
1914     }
1915 #endif
1916 #ifndef OPENSSL_NO_SLH_DSA
1917     if (!is_fips_lt_3_5) {
1918         MAKE_KEYS(SLH_DSA_SHA2_128s, "SLH-DSA-SHA2-128s", NULL);
1919         MAKE_KEYS(SLH_DSA_SHA2_128f, "SLH-DSA-SHA2-128f", NULL);
1920         MAKE_KEYS(SLH_DSA_SHA2_192s, "SLH-DSA-SHA2-192s", NULL);
1921         MAKE_KEYS(SLH_DSA_SHA2_192f, "SLH-DSA-SHA2-192f", NULL);
1922         MAKE_KEYS(SLH_DSA_SHA2_256s, "SLH-DSA-SHA2-256s", NULL);
1923         MAKE_KEYS(SLH_DSA_SHA2_256f, "SLH-DSA-SHA2-256f", NULL);
1924         MAKE_KEYS(SLH_DSA_SHAKE_128s, "SLH-DSA-SHAKE-128s", NULL);
1925         MAKE_KEYS(SLH_DSA_SHAKE_128f, "SLH-DSA-SHAKE-128f", NULL);
1926         MAKE_KEYS(SLH_DSA_SHAKE_192s, "SLH-DSA-SHAKE-192s", NULL);
1927         MAKE_KEYS(SLH_DSA_SHAKE_192f, "SLH-DSA-SHAKE-192f", NULL);
1928         MAKE_KEYS(SLH_DSA_SHAKE_256s, "SLH-DSA-SHAKE-256s", NULL);
1929         MAKE_KEYS(SLH_DSA_SHAKE_256f, "SLH-DSA-SHAKE-256f", NULL);
1930     }
1931 #endif /* OPENSSL_NO_SLH_DSA */
1932 
1933     TEST_info("Loading RSA key...");
1934     ok &= TEST_ptr(key_RSA = load_pkey_pem(rsa_file, keyctx));
1935     TEST_info("Loading RSA_PSS key...");
1936     ok &= TEST_ptr(key_RSA_PSS = load_pkey_pem(rsa_pss_file, keyctx));
1937     TEST_info("Generating keys done");
1938 
1939     /*
1940      * Register every test whose key was successfully generated.  The
1941      * per-algorithm key_##KEYTYPE != NULL guard inside each
1942      * ADD_TEST_SUITE* macro keeps us from referencing missing keys.
1943      */
1944     {
1945 #ifndef OPENSSL_NO_DH
1946         ADD_TEST_SUITE(DH);
1947         ADD_TEST_SUITE_PARAMS(DH);
1948         ADD_TEST_SUITE(DHX);
1949         ADD_TEST_SUITE_PARAMS(DHX);
1950         /*
1951          * DH has no support for PEM_write_bio_PrivateKey_traditional(),
1952          * so no legacy tests.
1953          */
1954 #endif
1955 #ifndef OPENSSL_NO_DSA
1956         ADD_TEST_SUITE(DSA);
1957         ADD_TEST_SUITE_PARAMS(DSA);
1958         ADD_TEST_SUITE_LEGACY(DSA);
1959         ADD_TEST_SUITE_MSBLOB(DSA);
1960         ADD_TEST_SUITE_UNPROTECTED_PVK(DSA);
1961 #ifndef OPENSSL_NO_RC4
1962         ADD_TEST_SUITE_PROTECTED_PVK(DSA);
1963 #endif
1964 #endif
1965 #ifndef OPENSSL_NO_EC
1966         ADD_TEST(ec_encode_to_data_multi);
1967         ADD_TEST_SUITE(EC);
1968         ADD_TEST_SUITE_PARAMS(EC);
1969         ADD_TEST_SUITE_LEGACY(EC);
1970 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
1971         ADD_TEST_SUITE(ECExplicitPrimeNamedCurve);
1972         ADD_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve);
1973         ADD_TEST_SUITE(ECExplicitPrime2G);
1974         ADD_TEST_SUITE_LEGACY(ECExplicitPrime2G);
1975 #ifndef OPENSSL_NO_EC2M
1976         ADD_TEST_SUITE(ECExplicitTriNamedCurve);
1977         ADD_TEST_SUITE_LEGACY(ECExplicitTriNamedCurve);
1978         ADD_TEST_SUITE(ECExplicitTri2G);
1979         ADD_TEST_SUITE_LEGACY(ECExplicitTri2G);
1980 #endif
1981 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
1982 #ifndef OPENSSL_NO_SM2
1983         if (!is_fips_3_0_0) {
1984             /* 3.0.0 FIPS provider imports explicit EC params and then fails. */
1985             ADD_TEST_SUITE(SM2);
1986         }
1987 #endif
1988 #endif
1989 #ifndef OPENSSL_NO_ECX
1990         ADD_TEST_SUITE(ED25519);
1991         ADD_TEST_SUITE(ED448);
1992         ADD_TEST_SUITE(X25519);
1993         ADD_TEST_SUITE(X448);
1994         /*
1995          * ED25519, ED448, X25519 and X448 have no support for
1996          * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
1997          */
1998 #endif
1999 #ifndef OPENSSL_NO_ML_KEM
2000         if (!is_fips_lt_3_5) {
2001             ADD_TEST_SUITE(ML_KEM_512);
2002             ADD_TEST_SUITE(ML_KEM_768);
2003             ADD_TEST_SUITE(ML_KEM_1024);
2004         }
2005 #endif
2006         ADD_TEST_SUITE(RSA);
2007         ADD_TEST_SUITE_LEGACY(RSA);
2008         ADD_TEST_SUITE(RSA_PSS);
2009         /*
2010          * RSA-PSS has no support for PEM_write_bio_PrivateKey_traditional(),
2011          * so no legacy tests.
2012          */
2013         ADD_TEST_SUITE_MSBLOB(RSA);
2014         ADD_TEST_SUITE_UNPROTECTED_PVK(RSA);
2015 #ifndef OPENSSL_NO_RC4
2016         ADD_TEST_SUITE_PROTECTED_PVK(RSA);
2017 #endif
2018 
2019 #ifndef OPENSSL_NO_ML_DSA
2020         if (!is_fips_lt_3_5) {
2021             ADD_TEST_SUITE(ML_DSA_44);
2022             ADD_TEST_SUITE(ML_DSA_65);
2023             ADD_TEST_SUITE(ML_DSA_87);
2024         }
2025 #endif /* OPENSSL_NO_ML_DSA */
2026 
2027 #ifndef OPENSSL_NO_SLH_DSA
2028         if (!is_fips_lt_3_5) {
2029             ADD_TEST_SUITE(SLH_DSA_SHA2_128s);
2030             ADD_TEST_SUITE(SLH_DSA_SHA2_128f);
2031             ADD_TEST_SUITE(SLH_DSA_SHA2_192s);
2032             ADD_TEST_SUITE(SLH_DSA_SHA2_192f);
2033             ADD_TEST_SUITE(SLH_DSA_SHA2_256s);
2034             ADD_TEST_SUITE(SLH_DSA_SHA2_256f);
2035             ADD_TEST_SUITE(SLH_DSA_SHAKE_128s);
2036             ADD_TEST_SUITE(SLH_DSA_SHAKE_128f);
2037             ADD_TEST_SUITE(SLH_DSA_SHAKE_192s);
2038             ADD_TEST_SUITE(SLH_DSA_SHAKE_192f);
2039             ADD_TEST_SUITE(SLH_DSA_SHAKE_256s);
2040             ADD_TEST_SUITE(SLH_DSA_SHAKE_256f);
2041         }
2042 #endif /* OPENSSL_NO_SLH_DSA */
2043 
2044         /*
2045          * Named-group-only partial shapes for DH and EC/SM2.  Each
2046          * shape is silently skipped if the algorithm is not loadable.
2047          */
2048 #ifdef TEST_FROMDATA_NO_KEYGEN
2049         ADD_TEST(test_fromdata_no_keygen);
2050 #endif
2051     }
2052 
2053     return ok;
2054 }
2055 
cleanup_tests(void)2056 void cleanup_tests(void)
2057 {
2058 #ifndef OPENSSL_NO_EC
2059 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
2060     OSSL_PARAM_free(ec_explicit_prime_params_nc);
2061     OSSL_PARAM_free(ec_explicit_prime_params_explicit);
2062     OSSL_PARAM_BLD_free(bld_prime_nc);
2063     OSSL_PARAM_BLD_free(bld_prime);
2064 #ifndef OPENSSL_NO_EC2M
2065     OSSL_PARAM_free(ec_explicit_tri_params_nc);
2066     OSSL_PARAM_free(ec_explicit_tri_params_explicit);
2067     OSSL_PARAM_BLD_free(bld_tri_nc);
2068     OSSL_PARAM_BLD_free(bld_tri);
2069 #endif
2070 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
2071     BN_CTX_free(bnctx);
2072 #endif /* OPENSSL_NO_EC */
2073 
2074 #ifndef OPENSSL_NO_DH
2075     FREE_DOMAIN_KEYS(DH);
2076     FREE_DOMAIN_KEYS(DHX);
2077 #endif
2078 #ifndef OPENSSL_NO_DSA
2079     FREE_DOMAIN_KEYS(DSA);
2080 #endif
2081 #ifndef OPENSSL_NO_EC
2082     FREE_DOMAIN_KEYS(EC);
2083 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
2084     FREE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
2085     FREE_DOMAIN_KEYS(ECExplicitPrime2G);
2086 #ifndef OPENSSL_NO_EC2M
2087     FREE_DOMAIN_KEYS(ECExplicitTriNamedCurve);
2088     FREE_DOMAIN_KEYS(ECExplicitTri2G);
2089 #endif
2090 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
2091 #ifndef OPENSSL_NO_SM2
2092     FREE_KEYS(SM2);
2093 #endif
2094 #endif
2095 #ifndef OPENSSL_NO_ECX
2096     FREE_KEYS(ED25519);
2097     FREE_KEYS(ED448);
2098     FREE_KEYS(X25519);
2099     FREE_KEYS(X448);
2100 #endif
2101 #ifndef OPENSSL_NO_ML_KEM
2102     if (!is_fips_lt_3_5) {
2103         FREE_KEYS(ML_KEM_512);
2104         FREE_KEYS(ML_KEM_768);
2105         FREE_KEYS(ML_KEM_1024);
2106     }
2107 #endif
2108     FREE_KEYS(RSA);
2109     FREE_KEYS(RSA_PSS);
2110 
2111 #ifndef OPENSSL_NO_ML_DSA
2112     if (!is_fips_lt_3_5) {
2113         FREE_KEYS(ML_DSA_44);
2114         FREE_KEYS(ML_DSA_65);
2115         FREE_KEYS(ML_DSA_87);
2116     }
2117 #endif /* OPENSSL_NO_ML_DSA */
2118 
2119 #ifndef OPENSSL_NO_SLH_DSA
2120     if (!is_fips_lt_3_5) {
2121         FREE_KEYS(SLH_DSA_SHA2_128s);
2122         FREE_KEYS(SLH_DSA_SHA2_128f);
2123         FREE_KEYS(SLH_DSA_SHA2_192s);
2124         FREE_KEYS(SLH_DSA_SHA2_192f);
2125         FREE_KEYS(SLH_DSA_SHA2_256s);
2126         FREE_KEYS(SLH_DSA_SHA2_256f);
2127         FREE_KEYS(SLH_DSA_SHAKE_128s);
2128         FREE_KEYS(SLH_DSA_SHAKE_128f);
2129         FREE_KEYS(SLH_DSA_SHAKE_192s);
2130         FREE_KEYS(SLH_DSA_SHAKE_192f);
2131         FREE_KEYS(SLH_DSA_SHAKE_256s);
2132         FREE_KEYS(SLH_DSA_SHAKE_256f);
2133     }
2134 #endif /* OPENSSL_NO_SLH_DSA */
2135 
2136     OSSL_PROVIDER_unload(nullprov);
2137     OSSL_PROVIDER_unload(deflprov);
2138     OSSL_PROVIDER_unload(keyprov);
2139     OSSL_LIB_CTX_free(testctx);
2140     OSSL_LIB_CTX_free(keyctx);
2141 }
2142