xref: /freebsd/crypto/openssl/test/endecode_test.c (revision 1523ccfd9c8c254f7928143d31c305384b05fd11)
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 static OSSL_PARAM_BLD *bld_prime_nc = NULL;
64 static OSSL_PARAM_BLD *bld_prime = NULL;
65 static OSSL_PARAM *ec_explicit_prime_params_nc = NULL;
66 static OSSL_PARAM *ec_explicit_prime_params_explicit = NULL;
67 
68 #ifndef OPENSSL_NO_EC2M
69 static OSSL_PARAM_BLD *bld_tri_nc = NULL;
70 static OSSL_PARAM_BLD *bld_tri = NULL;
71 static OSSL_PARAM *ec_explicit_tri_params_nc = NULL;
72 static OSSL_PARAM *ec_explicit_tri_params_explicit = NULL;
73 #endif
74 #endif
75 
76 #ifndef OPENSSL_NO_KEYPARAMS
make_template(const char * type,OSSL_PARAM * genparams)77 static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams)
78 {
79     EVP_PKEY *pkey = NULL;
80     EVP_PKEY_CTX *ctx = NULL;
81 
82 #ifndef OPENSSL_NO_DH
83     /*
84      * Use 512-bit DH(X) keys with predetermined parameters for efficiency,
85      * for testing only. Use a minimum key size of 2048 for security purposes.
86      */
87     if (strcmp(type, "DH") == 0)
88         return get_dh512(keyctx);
89 
90     if (strcmp(type, "X9.42 DH") == 0)
91         return get_dhx512(keyctx);
92 #endif
93 
94     /*
95      * No real need to check the errors other than for the cascade
96      * effect.  |pkey| will simply remain NULL if something goes wrong.
97      */
98     (void)((ctx = EVP_PKEY_CTX_new_from_name(keyctx, type, testpropq)) != NULL
99         && EVP_PKEY_paramgen_init(ctx) > 0
100         && (genparams == NULL
101             || EVP_PKEY_CTX_set_params(ctx, genparams) > 0)
102         && EVP_PKEY_generate(ctx, &pkey) > 0);
103     EVP_PKEY_CTX_free(ctx);
104 
105     return pkey;
106 }
107 #endif
108 
109 #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)110 static EVP_PKEY *make_key(const char *type, EVP_PKEY *template,
111     OSSL_PARAM *genparams)
112 {
113     EVP_PKEY *pkey = NULL;
114     EVP_PKEY_CTX *ctx = template != NULL
115         ? EVP_PKEY_CTX_new_from_pkey(keyctx, template, testpropq)
116         : EVP_PKEY_CTX_new_from_name(keyctx, type, testpropq);
117 
118     /*
119      * No real need to check the errors other than for the cascade
120      * effect.  |pkey| will simply remain NULL if something goes wrong.
121      */
122     (void)(ctx != NULL
123         && EVP_PKEY_keygen_init(ctx) > 0
124         && (genparams == NULL
125             || EVP_PKEY_CTX_set_params(ctx, genparams) > 0)
126         && EVP_PKEY_keygen(ctx, &pkey) > 0);
127     EVP_PKEY_CTX_free(ctx);
128     return pkey;
129 }
130 #endif
131 
132 /* Main test driver */
133 
134 typedef int(encoder)(const char *file, const int line,
135     void **encoded, long *encoded_len,
136     void *object, int selection,
137     const char *output_type, const char *output_structure,
138     const char *pass, const char *pcipher);
139 typedef int(decoder)(const char *file, const int line,
140     void **object, void *encoded, long encoded_len,
141     const char *input_type, const char *structure_type,
142     const char *keytype, int selection, const char *pass);
143 typedef int(tester)(const char *file, const int line,
144     const void *data1, size_t data1_len,
145     const void *data2, size_t data2_len);
146 typedef int(checker)(const char *file, const int line,
147     const char *type, const void *data, size_t data_len);
148 typedef void(dumper)(const char *label, const void *data, size_t data_len);
149 
150 #define FLAG_DECODE_WITH_TYPE 0x0001
151 #define FLAG_FAIL_IF_FIPS 0x0002
152 
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)153 static int test_encode_decode(const char *file, const int line,
154     const char *type, EVP_PKEY *pkey,
155     int selection, const char *output_type,
156     const char *output_structure,
157     const char *pass, const char *pcipher,
158     encoder *encode_cb, decoder *decode_cb,
159     tester *test_cb, checker *check_cb,
160     dumper *dump_cb, int flags)
161 {
162     void *encoded = NULL;
163     long encoded_len = 0;
164     EVP_PKEY *pkey2 = NULL;
165     EVP_PKEY *pkey3 = NULL;
166     void *encoded2 = NULL;
167     long encoded2_len = 0;
168     int ok = 0;
169 
170     /*
171      * Encode |pkey|, decode the result into |pkey2|, and finish off by
172      * encoding |pkey2| as well.  That last encoding is for checking and
173      * dumping purposes.
174      */
175     if (!TEST_true(encode_cb(file, line, &encoded, &encoded_len, pkey, selection,
176             output_type, output_structure, pass, pcipher)))
177         goto end;
178 
179     if ((flags & FLAG_FAIL_IF_FIPS) != 0 && is_fips && !is_fips_3_0_0) {
180         if (TEST_false(decode_cb(file, line, (void **)&pkey2, encoded,
181                 encoded_len, output_type, output_structure,
182                 (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
183                 selection, pass)))
184             ok = 1;
185         goto end;
186     }
187 
188     if (!TEST_true(check_cb(file, line, type, encoded, encoded_len))
189         || !TEST_true(decode_cb(file, line, (void **)&pkey2, encoded, encoded_len,
190             output_type, output_structure,
191             (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
192             selection, pass))
193         || ((output_structure == NULL
194                 || strcmp(output_structure, "type-specific") != 0)
195             && !TEST_true(decode_cb(file, line, (void **)&pkey3, encoded, encoded_len,
196                 output_type, output_structure,
197                 (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
198                 0, pass)))
199         || !TEST_true(encode_cb(file, line, &encoded2, &encoded2_len, pkey2, selection,
200             output_type, output_structure, pass, pcipher)))
201         goto end;
202 
203     if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
204         if (!TEST_int_eq(EVP_PKEY_parameters_eq(pkey, pkey2), 1)
205             || (pkey3 != NULL
206                 && !TEST_int_eq(EVP_PKEY_parameters_eq(pkey, pkey3), 1)))
207             goto end;
208     } else {
209         if (!TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1)
210             || (pkey3 != NULL
211                 && !TEST_int_eq(EVP_PKEY_eq(pkey, pkey3), 1)))
212             goto end;
213     }
214 
215     /*
216      * Double check the encoding, but only for unprotected keys,
217      * as protected keys have a random component, which makes the output
218      * differ.
219      */
220     if ((pass == NULL && pcipher == NULL)
221         && !test_cb(file, line, encoded, encoded_len, encoded2, encoded2_len))
222         goto end;
223 
224     ok = 1;
225 end:
226     if (!ok) {
227         if (encoded != NULL && encoded_len != 0)
228             dump_cb("|pkey| encoded", encoded, encoded_len);
229         if (encoded2 != NULL && encoded2_len != 0)
230             dump_cb("|pkey2| encoded", encoded2, encoded2_len);
231     }
232 
233     OPENSSL_free(encoded);
234     OPENSSL_free(encoded2);
235     EVP_PKEY_free(pkey2);
236     EVP_PKEY_free(pkey3);
237     return ok;
238 }
239 
240 /* Encoding and decoding methods */
241 
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)242 static int encode_EVP_PKEY_prov(const char *file, const int line,
243     void **encoded, long *encoded_len,
244     void *object, int selection,
245     const char *output_type,
246     const char *output_structure,
247     const char *pass, const char *pcipher)
248 {
249     EVP_PKEY *pkey = object;
250     OSSL_ENCODER_CTX *ectx = NULL;
251     BIO *mem_ser = NULL;
252     BUF_MEM *mem_buf = NULL;
253     const unsigned char *upass = (const unsigned char *)pass;
254     int ok = 0;
255 
256     if (!TEST_FL_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection,
257                          output_type,
258                          output_structure,
259                          testpropq))
260         || !TEST_FL_int_gt(OSSL_ENCODER_CTX_get_num_encoders(ectx), 0)
261         || (pass != NULL
262             && !TEST_FL_true(OSSL_ENCODER_CTX_set_passphrase(ectx, upass,
263                 strlen(pass))))
264         || (pcipher != NULL
265             && !TEST_FL_true(OSSL_ENCODER_CTX_set_cipher(ectx, pcipher, NULL)))
266         || !TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
267         || !TEST_FL_true(OSSL_ENCODER_to_bio(ectx, mem_ser))
268         || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
269         || !TEST_FL_ptr(*encoded = mem_buf->data)
270         || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
271         goto end;
272 
273     /* Detach the encoded output */
274     mem_buf->data = NULL;
275     mem_buf->length = 0;
276     ok = 1;
277 end:
278     BIO_free(mem_ser);
279     OSSL_ENCODER_CTX_free(ectx);
280     return ok;
281 }
282 
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)283 static int decode_EVP_PKEY_prov(const char *file, const int line,
284     void **object, void *encoded, long encoded_len,
285     const char *input_type,
286     const char *structure_type,
287     const char *keytype, int selection,
288     const char *pass)
289 {
290     EVP_PKEY *pkey = NULL, *testpkey = NULL;
291     OSSL_DECODER_CTX *dctx = NULL;
292     BIO *encoded_bio = NULL;
293     const unsigned char *upass = (const unsigned char *)pass;
294     int ok = 0;
295     int i;
296     const char *badtype;
297 
298     if (strcmp(input_type, "DER") == 0)
299         badtype = "PEM";
300     else
301         badtype = "DER";
302 
303     if (!TEST_FL_ptr(encoded_bio = BIO_new_mem_buf(encoded, encoded_len)))
304         goto end;
305 
306     /*
307      * We attempt the decode 3 times. The first time we provide the expected
308      * starting input type. The second time we provide NULL for the starting
309      * type. The third time we provide a bad starting input type.
310      * The bad starting input type should fail. The other two should succeed
311      * and produce the same result.
312      */
313     for (i = 0; i < 3; i++) {
314         const char *testtype = (i == 0) ? input_type
315                                         : ((i == 1) ? NULL : badtype);
316 
317         if (!TEST_FL_ptr(dctx = OSSL_DECODER_CTX_new_for_pkey(&testpkey,
318                              testtype,
319                              structure_type,
320                              keytype,
321                              selection,
322                              testctx, testpropq))
323             || (pass != NULL
324                 && !OSSL_DECODER_CTX_set_passphrase(dctx, upass, strlen(pass)))
325             || !TEST_FL_int_gt(BIO_reset(encoded_bio), 0)
326             /* We expect to fail when using a bad input type */
327             || !TEST_FL_int_eq(OSSL_DECODER_from_bio(dctx, encoded_bio),
328                 (i == 2) ? 0 : 1))
329             goto end;
330         OSSL_DECODER_CTX_free(dctx);
331         dctx = NULL;
332 
333         if (i == 0) {
334             pkey = testpkey;
335             testpkey = NULL;
336         } else if (i == 1) {
337             if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
338                 if (!TEST_FL_int_eq(EVP_PKEY_parameters_eq(pkey, testpkey), 1))
339                     goto end;
340             } else {
341                 if (!TEST_FL_int_eq(EVP_PKEY_eq(pkey, testpkey), 1))
342                     goto end;
343             }
344         }
345     }
346     ok = 1;
347     *object = pkey;
348     pkey = NULL;
349 
350 end:
351     EVP_PKEY_free(pkey);
352     EVP_PKEY_free(testpkey);
353     BIO_free(encoded_bio);
354     OSSL_DECODER_CTX_free(dctx);
355     return ok;
356 }
357 
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)358 static int encode_EVP_PKEY_legacy_PEM(const char *file, const int line,
359     void **encoded, long *encoded_len,
360     void *object, ossl_unused int selection,
361     ossl_unused const char *output_type,
362     ossl_unused const char *output_structure,
363     const char *pass, const char *pcipher)
364 {
365     EVP_PKEY *pkey = object;
366     EVP_CIPHER *cipher = NULL;
367     BIO *mem_ser = NULL;
368     BUF_MEM *mem_buf = NULL;
369     const unsigned char *upass = (const unsigned char *)pass;
370     size_t passlen = 0;
371     int ok = 0;
372 
373     if (pcipher != NULL && pass != NULL) {
374         passlen = strlen(pass);
375         if (!TEST_FL_ptr(cipher = EVP_CIPHER_fetch(testctx, pcipher, testpropq)))
376             goto end;
377     }
378     if (!TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
379         || !TEST_FL_true(PEM_write_bio_PrivateKey_traditional(mem_ser, pkey,
380             cipher,
381             upass, passlen,
382             NULL, NULL))
383         || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
384         || !TEST_FL_ptr(*encoded = mem_buf->data)
385         || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
386         goto end;
387 
388     /* Detach the encoded output */
389     mem_buf->data = NULL;
390     mem_buf->length = 0;
391     ok = 1;
392 end:
393     BIO_free(mem_ser);
394     EVP_CIPHER_free(cipher);
395     return ok;
396 }
397 
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)398 static int encode_EVP_PKEY_MSBLOB(const char *file, const int line,
399     void **encoded, long *encoded_len,
400     void *object, int selection,
401     ossl_unused const char *output_type,
402     ossl_unused const char *output_structure,
403     ossl_unused const char *pass,
404     ossl_unused const char *pcipher)
405 {
406     EVP_PKEY *pkey = object;
407     BIO *mem_ser = NULL;
408     BUF_MEM *mem_buf = NULL;
409     int ok = 0;
410 
411     if (!TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem())))
412         goto end;
413 
414     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
415         if (!TEST_FL_int_ge(i2b_PrivateKey_bio(mem_ser, pkey), 0))
416             goto end;
417     } else {
418         if (!TEST_FL_int_ge(i2b_PublicKey_bio(mem_ser, pkey), 0))
419             goto end;
420     }
421 
422     if (!TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
423         || !TEST_FL_ptr(*encoded = mem_buf->data)
424         || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
425         goto end;
426 
427     /* Detach the encoded output */
428     mem_buf->data = NULL;
429     mem_buf->length = 0;
430     ok = 1;
431 end:
432     BIO_free(mem_ser);
433     return ok;
434 }
435 
436 static pem_password_cb pass_pw;
pass_pw(char * buf,int size,int rwflag,void * userdata)437 static int pass_pw(char *buf, int size, int rwflag, void *userdata)
438 {
439     OPENSSL_strlcpy(buf, userdata, size);
440     return strlen(userdata);
441 }
442 
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)443 static int encode_EVP_PKEY_PVK(const char *file, const int line,
444     void **encoded, long *encoded_len,
445     void *object, int selection,
446     ossl_unused const char *output_type,
447     ossl_unused const char *output_structure,
448     const char *pass,
449     ossl_unused const char *pcipher)
450 {
451     EVP_PKEY *pkey = object;
452     BIO *mem_ser = NULL;
453     BUF_MEM *mem_buf = NULL;
454     int enc = (pass != NULL);
455     int ok = 0;
456 
457     if (!TEST_FL_true(ossl_assert((selection
458                                       & OSSL_KEYMGMT_SELECT_PRIVATE_KEY)
459             != 0))
460         || !TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
461         || !TEST_FL_int_ge(i2b_PVK_bio_ex(mem_ser, pkey, enc,
462                                pass_pw, (void *)pass, testctx, testpropq),
463             0)
464         || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
465         || !TEST_FL_ptr(*encoded = mem_buf->data)
466         || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
467         goto end;
468 
469     /* Detach the encoded output */
470     mem_buf->data = NULL;
471     mem_buf->length = 0;
472     ok = 1;
473 end:
474     BIO_free(mem_ser);
475     return ok;
476 }
477 
test_text(const char * file,const int line,const void * data1,size_t data1_len,const void * data2,size_t data2_len)478 static int test_text(const char *file, const int line,
479     const void *data1, size_t data1_len,
480     const void *data2, size_t data2_len)
481 {
482     return TEST_FL_strn2_eq(data1, data1_len, data2, data2_len);
483 }
484 
test_mem(const char * file,const int line,const void * data1,size_t data1_len,const void * data2,size_t data2_len)485 static int test_mem(const char *file, const int line,
486     const void *data1, size_t data1_len,
487     const void *data2, size_t data2_len)
488 {
489     return TEST_FL_mem_eq(data1, data1_len, data2, data2_len);
490 }
491 
492 /* Test cases and their dumpers / checkers */
493 
collect_name(const char * name,void * arg)494 static void collect_name(const char *name, void *arg)
495 {
496     char **namelist = arg;
497     char *new_namelist;
498     size_t space;
499 
500     space = strlen(name);
501     if (*namelist != NULL)
502         space += strlen(*namelist) + 2 /* for comma and space */;
503     space++; /* for terminating null byte */
504 
505     new_namelist = OPENSSL_realloc(*namelist, space);
506     if (new_namelist == NULL)
507         return;
508     if (*namelist != NULL) {
509         strcat(new_namelist, ", ");
510         strcat(new_namelist, name);
511     } else {
512         strcpy(new_namelist, name);
513     }
514     *namelist = new_namelist;
515 }
516 
dump_der(const char * label,const void * data,size_t data_len)517 static void dump_der(const char *label, const void *data, size_t data_len)
518 {
519     test_output_memory(label, data, data_len);
520 }
521 
dump_pem(const char * label,const void * data,size_t data_len)522 static void dump_pem(const char *label, const void *data, size_t data_len)
523 {
524     test_output_string(label, data, data_len - 1);
525 }
526 
check_unprotected_PKCS8_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)527 static int check_unprotected_PKCS8_DER(const char *file, const int line,
528     const char *type,
529     const void *data, size_t data_len)
530 {
531     const unsigned char *datap = data;
532     PKCS8_PRIV_KEY_INFO *p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &datap, data_len);
533     int ok = 0;
534 
535     if (TEST_FL_ptr(p8inf)) {
536         EVP_PKEY *pkey = EVP_PKCS82PKEY_ex(p8inf, testctx, testpropq);
537         char *namelist = NULL;
538 
539         if (TEST_FL_ptr(pkey)) {
540             if (!(ok = TEST_FL_true(EVP_PKEY_is_a(pkey, type)))) {
541                 EVP_PKEY_type_names_do_all(pkey, collect_name, &namelist);
542                 if (namelist != NULL)
543                     TEST_note("%s isn't any of %s", type, namelist);
544                 OPENSSL_free(namelist);
545             }
546             ok = ok && TEST_FL_true(evp_pkey_is_provided(pkey));
547             EVP_PKEY_free(pkey);
548         }
549     }
550     PKCS8_PRIV_KEY_INFO_free(p8inf);
551     return ok;
552 }
553 
test_unprotected_via_DER(const char * type,EVP_PKEY * key,int fips)554 static int test_unprotected_via_DER(const char *type, EVP_PKEY *key, int fips)
555 {
556     return test_encode_decode(__FILE__, __LINE__, type, key,
557         OSSL_KEYMGMT_SELECT_KEYPAIR
558             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
559         "DER", "PrivateKeyInfo", NULL, NULL,
560         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
561         test_mem, check_unprotected_PKCS8_DER,
562         dump_der, fips ? 0 : FLAG_FAIL_IF_FIPS);
563 }
564 
check_unprotected_PKCS8_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)565 static int check_unprotected_PKCS8_PEM(const char *file, const int line,
566     const char *type,
567     const void *data, size_t data_len)
568 {
569     static const char expected_pem_header[] = "-----BEGIN " PEM_STRING_PKCS8INF "-----";
570 
571     return TEST_FL_strn_eq(data, expected_pem_header,
572         sizeof(expected_pem_header) - 1);
573 }
574 
test_unprotected_via_PEM(const char * type,EVP_PKEY * key,int fips)575 static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key, int fips)
576 {
577     return test_encode_decode(__FILE__, __LINE__, type, key,
578         OSSL_KEYMGMT_SELECT_KEYPAIR
579             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
580         "PEM", "PrivateKeyInfo", NULL, NULL,
581         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
582         test_text, check_unprotected_PKCS8_PEM,
583         dump_pem, fips ? 0 : FLAG_FAIL_IF_FIPS);
584 }
585 
586 #ifndef OPENSSL_NO_KEYPARAMS
check_params_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)587 static int check_params_DER(const char *file, const int line,
588     const char *type, const void *data, size_t data_len)
589 {
590     const unsigned char *datap = data;
591     int ok = 0;
592     int itype = NID_undef;
593     EVP_PKEY *pkey = NULL;
594 
595     if (strcmp(type, "DH") == 0)
596         itype = EVP_PKEY_DH;
597     else if (strcmp(type, "X9.42 DH") == 0)
598         itype = EVP_PKEY_DHX;
599     else if (strcmp(type, "DSA") == 0)
600         itype = EVP_PKEY_DSA;
601     else if (strcmp(type, "EC") == 0)
602         itype = EVP_PKEY_EC;
603 
604     if (itype != NID_undef) {
605         pkey = d2i_KeyParams(itype, NULL, &datap, data_len);
606         ok = (pkey != NULL);
607         EVP_PKEY_free(pkey);
608     }
609 
610     return ok;
611 }
612 
check_params_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)613 static int check_params_PEM(const char *file, const int line,
614     const char *type,
615     const void *data, size_t data_len)
616 {
617     static char expected_pem_header[80];
618 
619     return TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
620                               sizeof(expected_pem_header),
621                               "-----BEGIN %s PARAMETERS-----", type),
622                0)
623         && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header));
624 }
625 
test_params_via_DER(const char * type,EVP_PKEY * key)626 static int test_params_via_DER(const char *type, EVP_PKEY *key)
627 {
628     return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
629         "DER", "type-specific", NULL, NULL,
630         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
631         test_mem, check_params_DER,
632         dump_der, FLAG_DECODE_WITH_TYPE);
633 }
634 
test_params_via_PEM(const char * type,EVP_PKEY * key)635 static int test_params_via_PEM(const char *type, EVP_PKEY *key)
636 {
637     return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
638         "PEM", "type-specific", NULL, NULL,
639         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
640         test_text, check_params_PEM,
641         dump_pem, 0);
642 }
643 #endif /* !OPENSSL_NO_KEYPARAMS */
644 
check_unprotected_legacy_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)645 static int check_unprotected_legacy_PEM(const char *file, const int line,
646     const char *type,
647     const void *data, size_t data_len)
648 {
649     static char expected_pem_header[80];
650 
651     return TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
652                               sizeof(expected_pem_header),
653                               "-----BEGIN %s PRIVATE KEY-----", type),
654                0)
655         && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header));
656 }
657 
test_unprotected_via_legacy_PEM(const char * type,EVP_PKEY * key)658 static int test_unprotected_via_legacy_PEM(const char *type, EVP_PKEY *key)
659 {
660     if (!default_libctx || is_fips)
661         return TEST_skip("Test not available if using a non-default library context or FIPS provider");
662 
663     return test_encode_decode(__FILE__, __LINE__, type, key,
664         OSSL_KEYMGMT_SELECT_KEYPAIR
665             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
666         "PEM", "type-specific", NULL, NULL,
667         encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
668         test_text, check_unprotected_legacy_PEM,
669         dump_pem, 0);
670 }
671 
check_MSBLOB(const char * file,const int line,const char * type,const void * data,size_t data_len)672 static int check_MSBLOB(const char *file, const int line,
673     const char *type, const void *data, size_t data_len)
674 {
675     const unsigned char *datap = data;
676     EVP_PKEY *pkey = b2i_PrivateKey(&datap, data_len);
677     int ok = TEST_FL_ptr(pkey);
678 
679     EVP_PKEY_free(pkey);
680     return ok;
681 }
682 
test_unprotected_via_MSBLOB(const char * type,EVP_PKEY * key)683 static int test_unprotected_via_MSBLOB(const char *type, EVP_PKEY *key)
684 {
685     return test_encode_decode(__FILE__, __LINE__, type, key,
686         OSSL_KEYMGMT_SELECT_KEYPAIR
687             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
688         "MSBLOB", NULL, NULL, NULL,
689         encode_EVP_PKEY_MSBLOB, decode_EVP_PKEY_prov,
690         test_mem, check_MSBLOB,
691         dump_der, 0);
692 }
693 
check_PVK(const char * file,const int line,const char * type,const void * data,size_t data_len)694 static int check_PVK(const char *file, const int line,
695     const char *type, const void *data, size_t data_len)
696 {
697     const unsigned char *in = data;
698     unsigned int saltlen = 0, keylen = 0;
699     int isdss = -1;
700 
701     return ossl_do_PVK_header(&in, data_len, 0, &isdss, &saltlen, &keylen);
702 }
703 
test_unprotected_via_PVK(const char * type,EVP_PKEY * key)704 static int test_unprotected_via_PVK(const char *type, EVP_PKEY *key)
705 {
706     return test_encode_decode(__FILE__, __LINE__, type, key,
707         OSSL_KEYMGMT_SELECT_KEYPAIR
708             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
709         "PVK", NULL, NULL, NULL,
710         encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
711         test_mem, check_PVK,
712         dump_der, 0);
713 }
714 
715 static const char *pass_cipher = "AES-256-CBC";
716 static const char *pass = "the holy handgrenade of antioch";
717 
check_protected_PKCS8_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)718 static int check_protected_PKCS8_DER(const char *file, const int line,
719     const char *type,
720     const void *data, size_t data_len)
721 {
722     const unsigned char *datap = data;
723     X509_SIG *p8 = d2i_X509_SIG(NULL, &datap, data_len);
724     int ok = TEST_FL_ptr(p8);
725 
726     X509_SIG_free(p8);
727     return ok;
728 }
729 
test_protected_via_DER(const char * type,EVP_PKEY * key,int fips)730 static int test_protected_via_DER(const char *type, EVP_PKEY *key, int fips)
731 {
732     return test_encode_decode(__FILE__, __LINE__, type, key,
733         OSSL_KEYMGMT_SELECT_KEYPAIR
734             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
735         "DER", "EncryptedPrivateKeyInfo",
736         pass, pass_cipher,
737         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
738         test_mem, check_protected_PKCS8_DER,
739         dump_der, fips ? 0 : FLAG_FAIL_IF_FIPS);
740 }
741 
check_protected_PKCS8_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)742 static int check_protected_PKCS8_PEM(const char *file, const int line,
743     const char *type,
744     const void *data, size_t data_len)
745 {
746     static const char expected_pem_header[] = "-----BEGIN " PEM_STRING_PKCS8 "-----";
747 
748     return TEST_FL_strn_eq(data, expected_pem_header,
749         sizeof(expected_pem_header) - 1);
750 }
751 
test_protected_via_PEM(const char * type,EVP_PKEY * key,int fips)752 static int test_protected_via_PEM(const char *type, EVP_PKEY *key, int fips)
753 {
754     return test_encode_decode(__FILE__, __LINE__, type, key,
755         OSSL_KEYMGMT_SELECT_KEYPAIR
756             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
757         "PEM", "EncryptedPrivateKeyInfo",
758         pass, pass_cipher,
759         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
760         test_text, check_protected_PKCS8_PEM,
761         dump_pem, fips ? 0 : FLAG_FAIL_IF_FIPS);
762 }
763 
check_protected_legacy_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)764 static int check_protected_legacy_PEM(const char *file, const int line,
765     const char *type,
766     const void *data, size_t data_len)
767 {
768     static char expected_pem_header[80];
769 
770     return TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
771                               sizeof(expected_pem_header),
772                               "-----BEGIN %s PRIVATE KEY-----", type),
773                0)
774         && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header))
775         && TEST_FL_ptr(strstr(data, "\nDEK-Info: "));
776 }
777 
test_protected_via_legacy_PEM(const char * type,EVP_PKEY * key)778 static int test_protected_via_legacy_PEM(const char *type, EVP_PKEY *key)
779 {
780     if (!default_libctx || is_fips)
781         return TEST_skip("Test not available if using a non-default library context or FIPS provider");
782 
783     return test_encode_decode(__FILE__, __LINE__, type, key,
784         OSSL_KEYMGMT_SELECT_KEYPAIR
785             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
786         "PEM", "type-specific", pass, pass_cipher,
787         encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
788         test_text, check_protected_legacy_PEM,
789         dump_pem, 0);
790 }
791 
792 #ifndef OPENSSL_NO_RC4
test_protected_via_PVK(const char * type,EVP_PKEY * key)793 static int test_protected_via_PVK(const char *type, EVP_PKEY *key)
794 {
795     int ret = 0;
796     OSSL_PROVIDER *lgcyprov = OSSL_PROVIDER_load(testctx, "legacy");
797     if (lgcyprov == NULL)
798         return TEST_skip("Legacy provider not available");
799 
800     ret = test_encode_decode(__FILE__, __LINE__, type, key,
801         OSSL_KEYMGMT_SELECT_KEYPAIR
802             | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
803         "PVK", NULL, pass, NULL,
804         encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
805         test_mem, check_PVK, dump_der, 0);
806     OSSL_PROVIDER_unload(lgcyprov);
807     return ret;
808 }
809 #endif
810 
check_public_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)811 static int check_public_DER(const char *file, const int line,
812     const char *type, const void *data, size_t data_len)
813 {
814     const unsigned char *datap = data;
815     EVP_PKEY *pkey = d2i_PUBKEY_ex(NULL, &datap, data_len, testctx, testpropq);
816     int ok = (TEST_FL_ptr(pkey) && TEST_FL_true(EVP_PKEY_is_a(pkey, type)));
817 
818     EVP_PKEY_free(pkey);
819     return ok;
820 }
821 
test_public_via_DER(const char * type,EVP_PKEY * key,int fips)822 static int test_public_via_DER(const char *type, EVP_PKEY *key, int fips)
823 {
824     return test_encode_decode(__FILE__, __LINE__, type, key,
825         OSSL_KEYMGMT_SELECT_PUBLIC_KEY
826             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
827         "DER", "SubjectPublicKeyInfo", NULL, NULL,
828         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
829         test_mem, check_public_DER, dump_der,
830         fips ? 0 : FLAG_FAIL_IF_FIPS);
831 }
832 
check_public_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)833 static int check_public_PEM(const char *file, const int line,
834     const char *type, const void *data, size_t data_len)
835 {
836     static const char expected_pem_header[] = "-----BEGIN " PEM_STRING_PUBLIC "-----";
837 
838     return TEST_FL_strn_eq(data, expected_pem_header,
839         sizeof(expected_pem_header) - 1);
840 }
841 
test_public_via_PEM(const char * type,EVP_PKEY * key,int fips)842 static int test_public_via_PEM(const char *type, EVP_PKEY *key, int fips)
843 {
844     return test_encode_decode(__FILE__, __LINE__, type, key,
845         OSSL_KEYMGMT_SELECT_PUBLIC_KEY
846             | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
847         "PEM", "SubjectPublicKeyInfo", NULL, NULL,
848         encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
849         test_text, check_public_PEM, dump_pem,
850         fips ? 0 : FLAG_FAIL_IF_FIPS);
851 }
852 
check_public_MSBLOB(const char * file,const int line,const char * type,const void * data,size_t data_len)853 static int check_public_MSBLOB(const char *file, const int line,
854     const char *type,
855     const void *data, size_t data_len)
856 {
857     const unsigned char *datap = data;
858     EVP_PKEY *pkey = b2i_PublicKey(&datap, data_len);
859     int ok = TEST_FL_ptr(pkey);
860 
861     EVP_PKEY_free(pkey);
862     return ok;
863 }
864 
test_public_via_MSBLOB(const char * type,EVP_PKEY * key)865 static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
866 {
867     return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
868         "MSBLOB", NULL, NULL, NULL,
869         encode_EVP_PKEY_MSBLOB, decode_EVP_PKEY_prov,
870         test_mem, check_public_MSBLOB, dump_der, 0);
871 }
872 
873 #define KEYS(KEYTYPE) \
874     static EVP_PKEY *key_##KEYTYPE = NULL
875 #define MAKE_KEYS(KEYTYPE, KEYTYPEstr, params) \
876     ok = ok                                    \
877         && TEST_ptr(key_##KEYTYPE = make_key(KEYTYPEstr, NULL, params))
878 #define FREE_KEYS(KEYTYPE) \
879     EVP_PKEY_free(key_##KEYTYPE);
880 
881 #define DOMAIN_KEYS(KEYTYPE)                    \
882     static EVP_PKEY *template_##KEYTYPE = NULL; \
883     static EVP_PKEY *key_##KEYTYPE = NULL
884 #define MAKE_DOMAIN_KEYS(KEYTYPE, KEYTYPEstr, params)                       \
885     ok = ok                                                                 \
886         && TEST_ptr(template_##KEYTYPE = make_template(KEYTYPEstr, params)) \
887         && TEST_ptr(key_##KEYTYPE = make_key(KEYTYPEstr, template_##KEYTYPE, NULL))
888 #define FREE_DOMAIN_KEYS(KEYTYPE)      \
889     EVP_PKEY_free(template_##KEYTYPE); \
890     EVP_PKEY_free(key_##KEYTYPE)
891 
892 #define IMPLEMENT_TEST_SUITE(KEYTYPE, KEYTYPEstr, fips)                   \
893     static int test_unprotected_##KEYTYPE##_via_DER(void)                 \
894     {                                                                     \
895         return test_unprotected_via_DER(KEYTYPEstr, key_##KEYTYPE, fips); \
896     }                                                                     \
897     static int test_unprotected_##KEYTYPE##_via_PEM(void)                 \
898     {                                                                     \
899         return test_unprotected_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips); \
900     }                                                                     \
901     static int test_protected_##KEYTYPE##_via_DER(void)                   \
902     {                                                                     \
903         return test_protected_via_DER(KEYTYPEstr, key_##KEYTYPE, fips);   \
904     }                                                                     \
905     static int test_protected_##KEYTYPE##_via_PEM(void)                   \
906     {                                                                     \
907         return test_protected_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips);   \
908     }                                                                     \
909     static int test_public_##KEYTYPE##_via_DER(void)                      \
910     {                                                                     \
911         return test_public_via_DER(KEYTYPEstr, key_##KEYTYPE, fips);      \
912     }                                                                     \
913     static int test_public_##KEYTYPE##_via_PEM(void)                      \
914     {                                                                     \
915         return test_public_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips);      \
916     }
917 
918 #define ADD_TEST_SUITE(KEYTYPE)                     \
919     ADD_TEST(test_unprotected_##KEYTYPE##_via_DER); \
920     ADD_TEST(test_unprotected_##KEYTYPE##_via_PEM); \
921     ADD_TEST(test_protected_##KEYTYPE##_via_DER);   \
922     ADD_TEST(test_protected_##KEYTYPE##_via_PEM);   \
923     ADD_TEST(test_public_##KEYTYPE##_via_DER);      \
924     ADD_TEST(test_public_##KEYTYPE##_via_PEM)
925 
926 #define IMPLEMENT_TEST_SUITE_PARAMS(KEYTYPE, KEYTYPEstr)       \
927     static int test_params_##KEYTYPE##_via_DER(void)           \
928     {                                                          \
929         return test_params_via_DER(KEYTYPEstr, key_##KEYTYPE); \
930     }                                                          \
931     static int test_params_##KEYTYPE##_via_PEM(void)           \
932     {                                                          \
933         return test_params_via_PEM(KEYTYPEstr, key_##KEYTYPE); \
934     }
935 
936 #define ADD_TEST_SUITE_PARAMS(KEYTYPE)         \
937     ADD_TEST(test_params_##KEYTYPE##_via_DER); \
938     ADD_TEST(test_params_##KEYTYPE##_via_PEM)
939 
940 #define IMPLEMENT_TEST_SUITE_LEGACY(KEYTYPE, KEYTYPEstr)                   \
941     static int test_unprotected_##KEYTYPE##_via_legacy_PEM(void)           \
942     {                                                                      \
943         return test_unprotected_via_legacy_PEM(KEYTYPEstr, key_##KEYTYPE); \
944     }                                                                      \
945     static int test_protected_##KEYTYPE##_via_legacy_PEM(void)             \
946     {                                                                      \
947         return test_protected_via_legacy_PEM(KEYTYPEstr, key_##KEYTYPE);   \
948     }
949 
950 #define ADD_TEST_SUITE_LEGACY(KEYTYPE)                     \
951     ADD_TEST(test_unprotected_##KEYTYPE##_via_legacy_PEM); \
952     ADD_TEST(test_protected_##KEYTYPE##_via_legacy_PEM)
953 
954 #define IMPLEMENT_TEST_SUITE_MSBLOB(KEYTYPE, KEYTYPEstr)               \
955     static int test_unprotected_##KEYTYPE##_via_MSBLOB(void)           \
956     {                                                                  \
957         return test_unprotected_via_MSBLOB(KEYTYPEstr, key_##KEYTYPE); \
958     }                                                                  \
959     static int test_public_##KEYTYPE##_via_MSBLOB(void)                \
960     {                                                                  \
961         return test_public_via_MSBLOB(KEYTYPEstr, key_##KEYTYPE);      \
962     }
963 
964 #define ADD_TEST_SUITE_MSBLOB(KEYTYPE)                 \
965     ADD_TEST(test_unprotected_##KEYTYPE##_via_MSBLOB); \
966     ADD_TEST(test_public_##KEYTYPE##_via_MSBLOB)
967 
968 #define IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(KEYTYPE, KEYTYPEstr)   \
969     static int test_unprotected_##KEYTYPE##_via_PVK(void)           \
970     {                                                               \
971         return test_unprotected_via_PVK(KEYTYPEstr, key_##KEYTYPE); \
972     }
973 #define ADD_TEST_SUITE_UNPROTECTED_PVK(KEYTYPE) \
974     ADD_TEST(test_unprotected_##KEYTYPE##_via_PVK)
975 #ifndef OPENSSL_NO_RC4
976 #define IMPLEMENT_TEST_SUITE_PROTECTED_PVK(KEYTYPE, KEYTYPEstr)   \
977     static int test_protected_##KEYTYPE##_via_PVK(void)           \
978     {                                                             \
979         return test_protected_via_PVK(KEYTYPEstr, key_##KEYTYPE); \
980     }
981 #define ADD_TEST_SUITE_PROTECTED_PVK(KEYTYPE) \
982     ADD_TEST(test_protected_##KEYTYPE##_via_PVK)
983 #endif
984 
985 #ifndef OPENSSL_NO_DH
986 DOMAIN_KEYS(DH);
987 IMPLEMENT_TEST_SUITE(DH, "DH", 1)
988 IMPLEMENT_TEST_SUITE_PARAMS(DH, "DH")
989 DOMAIN_KEYS(DHX);
990 IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH", 1)
991 IMPLEMENT_TEST_SUITE_PARAMS(DHX, "X9.42 DH")
992 /*
993  * DH has no support for PEM_write_bio_PrivateKey_traditional(),
994  * so no legacy tests.
995  */
996 #endif
997 #ifndef OPENSSL_NO_DSA
998 DOMAIN_KEYS(DSA);
999 IMPLEMENT_TEST_SUITE(DSA, "DSA", 1)
1000 IMPLEMENT_TEST_SUITE_PARAMS(DSA, "DSA")
1001 IMPLEMENT_TEST_SUITE_LEGACY(DSA, "DSA")
1002 IMPLEMENT_TEST_SUITE_MSBLOB(DSA, "DSA")
1003 IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(DSA, "DSA")
1004 #ifndef OPENSSL_NO_RC4
1005 IMPLEMENT_TEST_SUITE_PROTECTED_PVK(DSA, "DSA")
1006 #endif
1007 #endif
1008 #ifndef OPENSSL_NO_EC
1009 DOMAIN_KEYS(EC);
1010 IMPLEMENT_TEST_SUITE(EC, "EC", 1)
1011 IMPLEMENT_TEST_SUITE_PARAMS(EC, "EC")
1012 IMPLEMENT_TEST_SUITE_LEGACY(EC, "EC")
1013 DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
1014 IMPLEMENT_TEST_SUITE(ECExplicitPrimeNamedCurve, "EC", 1)
1015 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve, "EC")
1016 DOMAIN_KEYS(ECExplicitPrime2G);
1017 IMPLEMENT_TEST_SUITE(ECExplicitPrime2G, "EC", 0)
1018 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrime2G, "EC")
1019 #ifndef OPENSSL_NO_EC2M
1020 DOMAIN_KEYS(ECExplicitTriNamedCurve);
1021 IMPLEMENT_TEST_SUITE(ECExplicitTriNamedCurve, "EC", 1)
1022 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitTriNamedCurve, "EC")
1023 DOMAIN_KEYS(ECExplicitTri2G);
1024 IMPLEMENT_TEST_SUITE(ECExplicitTri2G, "EC", 0)
1025 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitTri2G, "EC")
1026 #endif
1027 #ifndef OPENSSL_NO_SM2
1028 KEYS(SM2);
1029 IMPLEMENT_TEST_SUITE(SM2, "SM2", 0)
1030 #endif
1031 #endif
1032 #ifndef OPENSSL_NO_ECX
1033 /*
1034  * ED25519, ED448, X25519 and X448 have no support for
1035  * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
1036  */
1037 KEYS(ED25519);
1038 IMPLEMENT_TEST_SUITE(ED25519, "ED25519", 1)
1039 KEYS(ED448);
1040 IMPLEMENT_TEST_SUITE(ED448, "ED448", 1)
1041 KEYS(X25519);
1042 IMPLEMENT_TEST_SUITE(X25519, "X25519", 1)
1043 KEYS(X448);
1044 IMPLEMENT_TEST_SUITE(X448, "X448", 1)
1045 #endif
1046 #ifndef OPENSSL_NO_ML_KEM
1047 /*
1048  * ML-KEM has no support for PEM_write_bio_PrivateKey_traditional(), so no
1049  * legacy tests.
1050  */
1051 KEYS(ML_KEM_512);
1052 IMPLEMENT_TEST_SUITE(ML_KEM_512, "ML-KEM-512", 1)
1053 KEYS(ML_KEM_768);
1054 IMPLEMENT_TEST_SUITE(ML_KEM_768, "ML-KEM-768", 1)
1055 KEYS(ML_KEM_1024);
1056 IMPLEMENT_TEST_SUITE(ML_KEM_1024, "ML-KEM-1024", 1)
1057 #endif
1058 #ifndef OPENSSL_NO_SLH_DSA
1059 KEYS(SLH_DSA_SHA2_128s);
1060 KEYS(SLH_DSA_SHA2_128f);
1061 KEYS(SLH_DSA_SHA2_192s);
1062 KEYS(SLH_DSA_SHA2_192f);
1063 KEYS(SLH_DSA_SHA2_256s);
1064 KEYS(SLH_DSA_SHA2_256f);
1065 KEYS(SLH_DSA_SHAKE_128s);
1066 KEYS(SLH_DSA_SHAKE_128f);
1067 KEYS(SLH_DSA_SHAKE_192s);
1068 KEYS(SLH_DSA_SHAKE_192f);
1069 KEYS(SLH_DSA_SHAKE_256s);
1070 KEYS(SLH_DSA_SHAKE_256f);
1071 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_128s, "SLH-DSA-SHA2-128s", 1)
1072 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_128f, "SLH-DSA-SHA2-128f", 1)
1073 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_192s, "SLH-DSA-SHA2-192s", 1)
1074 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_192f, "SLH-DSA-SHA2-192f", 1)
1075 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_256s, "SLH-DSA-SHA2-256s", 1)
1076 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_256f, "SLH-DSA-SHA2-256f", 1)
1077 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_128s, "SLH-DSA-SHAKE-128s", 1)
1078 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_128f, "SLH-DSA-SHAKE-128f", 1)
1079 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_192s, "SLH-DSA-SHAKE-192s", 1)
1080 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_192f, "SLH-DSA-SHAKE-192f", 1)
1081 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_256s, "SLH-DSA-SHAKE-256s", 1)
1082 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_256f, "SLH-DSA-SHAKE-256f", 1)
1083 #endif /* OPENSSL_NO_SLH_DSA */
1084 KEYS(RSA);
1085 IMPLEMENT_TEST_SUITE(RSA, "RSA", 1)
1086 IMPLEMENT_TEST_SUITE_LEGACY(RSA, "RSA")
1087 KEYS(RSA_PSS);
1088 IMPLEMENT_TEST_SUITE(RSA_PSS, "RSA-PSS", 1)
1089 /*
1090  * RSA-PSS has no support for PEM_write_bio_PrivateKey_traditional(),
1091  * so no legacy tests.
1092  */
1093 IMPLEMENT_TEST_SUITE_MSBLOB(RSA, "RSA")
1094 IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(RSA, "RSA")
1095 #ifndef OPENSSL_NO_RC4
1096 IMPLEMENT_TEST_SUITE_PROTECTED_PVK(RSA, "RSA")
1097 #endif
1098 
1099 #ifndef OPENSSL_NO_ML_DSA
1100 KEYS(ML_DSA_44);
1101 KEYS(ML_DSA_65);
1102 KEYS(ML_DSA_87);
1103 IMPLEMENT_TEST_SUITE(ML_DSA_44, "ML-DSA-44", 1)
1104 IMPLEMENT_TEST_SUITE(ML_DSA_65, "ML-DSA-65", 1)
1105 IMPLEMENT_TEST_SUITE(ML_DSA_87, "ML-DSA-87", 1)
1106 #endif /*  OPENSSL_NO_ML_DSA */
1107 
1108 #ifndef OPENSSL_NO_EC
1109 /* 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)1110 static int do_create_ec_explicit_prime_params(OSSL_PARAM_BLD *bld,
1111     const unsigned char *gen,
1112     size_t gen_len)
1113 {
1114     BIGNUM *a, *b, *prime, *order;
1115 
1116     /* Curve prime256v1 */
1117     static const unsigned char prime_data[] = {
1118         0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
1119         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1120         0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
1121         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1122         0xff
1123     };
1124     static const unsigned char a_data[] = {
1125         0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
1126         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1127         0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
1128         0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1129         0xfc
1130     };
1131     static const unsigned char b_data[] = {
1132         0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
1133         0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
1134         0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
1135         0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b
1136     };
1137     static const unsigned char seed[] = {
1138         0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93,
1139         0x6a, 0x66, 0x78, 0xe1, 0x13, 0x9d, 0x26, 0xb7,
1140         0x81, 0x9f, 0x7e, 0x90
1141     };
1142     static const unsigned char order_data[] = {
1143         0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
1144         0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1145         0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e,
1146         0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51
1147     };
1148     return TEST_ptr(a = BN_CTX_get(bnctx))
1149         && TEST_ptr(b = BN_CTX_get(bnctx))
1150         && TEST_ptr(prime = BN_CTX_get(bnctx))
1151         && TEST_ptr(order = BN_CTX_get(bnctx))
1152         && TEST_ptr(BN_bin2bn(prime_data, sizeof(prime_data), prime))
1153         && TEST_ptr(BN_bin2bn(a_data, sizeof(a_data), a))
1154         && TEST_ptr(BN_bin2bn(b_data, sizeof(b_data), b))
1155         && TEST_ptr(BN_bin2bn(order_data, sizeof(order_data), order))
1156         && TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
1157             OSSL_PKEY_PARAM_EC_FIELD_TYPE, SN_X9_62_prime_field,
1158             0))
1159         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, prime))
1160         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
1161         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b))
1162         && TEST_true(OSSL_PARAM_BLD_push_BN(bld,
1163             OSSL_PKEY_PARAM_EC_ORDER, order))
1164         && TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
1165             OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_len))
1166         && TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
1167             OSSL_PKEY_PARAM_EC_SEED, seed, sizeof(seed)))
1168         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
1169             BN_value_one()));
1170 }
1171 
create_ec_explicit_prime_params_namedcurve(OSSL_PARAM_BLD * bld)1172 static int create_ec_explicit_prime_params_namedcurve(OSSL_PARAM_BLD *bld)
1173 {
1174     static const unsigned char prime256v1_gen[] = {
1175         0x04,
1176         0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
1177         0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
1178         0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
1179         0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
1180         0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,
1181         0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
1182         0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
1183         0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5
1184     };
1185     return do_create_ec_explicit_prime_params(bld, prime256v1_gen,
1186         sizeof(prime256v1_gen));
1187 }
1188 
create_ec_explicit_prime_params(OSSL_PARAM_BLD * bld)1189 static int create_ec_explicit_prime_params(OSSL_PARAM_BLD *bld)
1190 {
1191     /* 2G */
1192     static const unsigned char prime256v1_gen2[] = {
1193         0x04,
1194         0xe4, 0x97, 0x08, 0xbe, 0x7d, 0xfa, 0xa2, 0x9a,
1195         0xa3, 0x12, 0x6f, 0xe4, 0xe7, 0xd0, 0x25, 0xe3,
1196         0x4a, 0xc1, 0x03, 0x15, 0x8c, 0xd9, 0x33, 0xc6,
1197         0x97, 0x42, 0xf5, 0xdc, 0x97, 0xb9, 0xd7, 0x31,
1198         0xe9, 0x7d, 0x74, 0x3d, 0x67, 0x6a, 0x3b, 0x21,
1199         0x08, 0x9c, 0x31, 0x73, 0xf8, 0xc1, 0x27, 0xc9,
1200         0xd2, 0xa0, 0xa0, 0x83, 0x66, 0xe0, 0xc9, 0xda,
1201         0xa8, 0xc6, 0x56, 0x2b, 0x94, 0xb1, 0xae, 0x55
1202     };
1203     return do_create_ec_explicit_prime_params(bld, prime256v1_gen2,
1204         sizeof(prime256v1_gen2));
1205 }
1206 
1207 #ifndef OPENSSL_NO_EC2M
do_create_ec_explicit_trinomial_params(OSSL_PARAM_BLD * bld,const unsigned char * gen,size_t gen_len)1208 static int do_create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld,
1209     const unsigned char *gen,
1210     size_t gen_len)
1211 {
1212     BIGNUM *a, *b, *poly, *order, *cofactor;
1213     /* sect233k1 characteristic-two-field tpBasis */
1214     static const unsigned char poly_data[] = {
1215         0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1216         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1217         0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
1218     };
1219     static const unsigned char a_data[] = {
1220         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1221         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1222         0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1223     };
1224     static const unsigned char b_data[] = {
1225         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1226         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1227         0x00, 0x00, 0x00, 0x00, 0x00, 0x01
1228     };
1229     static const unsigned char order_data[] = {
1230         0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1231         0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15, 0xBC, 0xD4, 0x6E, 0xFB,
1232         0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF
1233     };
1234     static const unsigned char cofactor_data[] = {
1235         0x4
1236     };
1237     return TEST_ptr(a = BN_CTX_get(bnctx))
1238         && TEST_ptr(b = BN_CTX_get(bnctx))
1239         && TEST_ptr(poly = BN_CTX_get(bnctx))
1240         && TEST_ptr(order = BN_CTX_get(bnctx))
1241         && TEST_ptr(cofactor = BN_CTX_get(bnctx))
1242         && TEST_ptr(BN_bin2bn(poly_data, sizeof(poly_data), poly))
1243         && TEST_ptr(BN_bin2bn(a_data, sizeof(a_data), a))
1244         && TEST_ptr(BN_bin2bn(b_data, sizeof(b_data), b))
1245         && TEST_ptr(BN_bin2bn(order_data, sizeof(order_data), order))
1246         && TEST_ptr(BN_bin2bn(cofactor_data, sizeof(cofactor_data), cofactor))
1247         && TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
1248             OSSL_PKEY_PARAM_EC_FIELD_TYPE,
1249             SN_X9_62_characteristic_two_field, 0))
1250         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, poly))
1251         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
1252         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b))
1253         && TEST_true(OSSL_PARAM_BLD_push_BN(bld,
1254             OSSL_PKEY_PARAM_EC_ORDER, order))
1255         && TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
1256             OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_len))
1257         && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
1258             cofactor));
1259 }
1260 
create_ec_explicit_trinomial_params_namedcurve(OSSL_PARAM_BLD * bld)1261 static int create_ec_explicit_trinomial_params_namedcurve(OSSL_PARAM_BLD *bld)
1262 {
1263     static const unsigned char gen[] = {
1264         0x04,
1265         0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, 0x29, 0xF2,
1266         0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2, 0x6B, 0xF5, 0x0A, 0x4C,
1267         0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26,
1268         0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, 0x55, 0x5A,
1269         0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A, 0xEB, 0x9B, 0x56, 0xE0,
1270         0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3
1271     };
1272     return do_create_ec_explicit_trinomial_params(bld, gen, sizeof(gen));
1273 }
1274 
create_ec_explicit_trinomial_params(OSSL_PARAM_BLD * bld)1275 static int create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld)
1276 {
1277     static const unsigned char gen2[] = {
1278         0x04,
1279         0x00, 0xd7, 0xba, 0xd0, 0x26, 0x6c, 0x31, 0x6a, 0x78, 0x76, 0x01, 0xd1,
1280         0x32, 0x4b, 0x8f, 0x30, 0x29, 0x2d, 0x78, 0x30, 0xca, 0x43, 0xaa, 0xf0,
1281         0xa2, 0x5a, 0xd4, 0x0f, 0xb3, 0xf4,
1282         0x00, 0x85, 0x4b, 0x1b, 0x8d, 0x50, 0x10, 0xa5, 0x1c, 0x80, 0xf7, 0x86,
1283         0x40, 0x62, 0x4c, 0x87, 0xd1, 0x26, 0x7a, 0x9c, 0x5c, 0xe9, 0x82, 0x29,
1284         0xd1, 0x67, 0x70, 0x41, 0xea, 0xcb
1285     };
1286     return do_create_ec_explicit_trinomial_params(bld, gen2, sizeof(gen2));
1287 }
1288 #endif /* OPENSSL_NO_EC2M */
1289 
1290 /*
1291  * Test that multiple calls to OSSL_ENCODER_to_data() do not cause side effects
1292  */
ec_encode_to_data_multi(void)1293 static int ec_encode_to_data_multi(void)
1294 {
1295     int ret;
1296     OSSL_ENCODER_CTX *ectx = NULL;
1297     EVP_PKEY *key = NULL;
1298     uint8_t *enc = NULL;
1299     size_t enc_len = 0;
1300 
1301     ret = TEST_ptr(key = EVP_PKEY_Q_keygen(testctx, "", "EC", "P-256"))
1302         && TEST_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(key, EVP_PKEY_KEYPAIR,
1303                         "DER", NULL, NULL))
1304         && TEST_int_eq(OSSL_ENCODER_to_data(ectx, NULL, &enc_len), 1)
1305         && TEST_int_eq(OSSL_ENCODER_to_data(ectx, &enc, &enc_len), 1);
1306     OPENSSL_free(enc);
1307     EVP_PKEY_free(key);
1308     OSSL_ENCODER_CTX_free(ectx);
1309     return ret;
1310 }
1311 #endif /* OPENSSL_NO_EC */
1312 
1313 typedef enum OPTION_choice {
1314     OPT_ERR = -1,
1315     OPT_EOF = 0,
1316     OPT_CONTEXT,
1317     OPT_RSA_FILE,
1318     OPT_RSA_PSS_FILE,
1319     OPT_CONFIG_FILE,
1320     OPT_PROVIDER_NAME,
1321     OPT_TEST_ENUM
1322 } OPTION_CHOICE;
1323 
test_get_options(void)1324 const OPTIONS *test_get_options(void)
1325 {
1326     static const OPTIONS options[] = {
1327         OPT_TEST_OPTIONS_DEFAULT_USAGE,
1328         { "context", OPT_CONTEXT, '-',
1329             "Explicitly use a non-default library context" },
1330         { "rsa", OPT_RSA_FILE, '<',
1331             "PEM format RSA key file to encode/decode" },
1332         { "pss", OPT_RSA_PSS_FILE, '<',
1333             "PEM format RSA-PSS key file to encode/decode" },
1334         { "config", OPT_CONFIG_FILE, '<',
1335             "The configuration file to use for the library context" },
1336         { "provider", OPT_PROVIDER_NAME, 's',
1337             "The provider to load (The default value is 'default')" },
1338         { NULL }
1339     };
1340     return options;
1341 }
1342 
setup_tests(void)1343 int setup_tests(void)
1344 {
1345     const char *rsa_file = NULL;
1346     const char *rsa_pss_file = NULL;
1347     const char *prov_name = "default";
1348     char *config_file = NULL;
1349     int ok = 1;
1350 
1351 #ifndef OPENSSL_NO_DSA
1352     static size_t qbits = 160; /* PVK only tolerates 160 Q bits */
1353     static size_t pbits = 1024; /* With 160 Q bits, we MUST use 1024 P bits */
1354     OSSL_PARAM DSA_params[] = {
1355         OSSL_PARAM_size_t("pbits", &pbits),
1356         OSSL_PARAM_size_t("qbits", &qbits),
1357         OSSL_PARAM_END
1358     };
1359 #endif
1360 
1361 #ifndef OPENSSL_NO_EC
1362     static char groupname[] = "prime256v1";
1363     OSSL_PARAM EC_params[] = {
1364         OSSL_PARAM_utf8_string("group", groupname, sizeof(groupname) - 1),
1365         OSSL_PARAM_END
1366     };
1367 #endif
1368 
1369     OPTION_CHOICE o;
1370 
1371     while ((o = opt_next()) != OPT_EOF) {
1372         switch (o) {
1373         case OPT_CONTEXT:
1374             default_libctx = 0;
1375             break;
1376         case OPT_PROVIDER_NAME:
1377             prov_name = opt_arg();
1378             break;
1379         case OPT_CONFIG_FILE:
1380             config_file = opt_arg();
1381             break;
1382         case OPT_RSA_FILE:
1383             rsa_file = opt_arg();
1384             break;
1385         case OPT_RSA_PSS_FILE:
1386             rsa_pss_file = opt_arg();
1387             break;
1388         case OPT_TEST_CASES:
1389             break;
1390         default:
1391             return 0;
1392         }
1393     }
1394 
1395     if (strcmp(prov_name, "fips") == 0)
1396         is_fips = 1;
1397 
1398     if (default_libctx) {
1399         if (!test_get_libctx(NULL, NULL, config_file, &deflprov, prov_name))
1400             return 0;
1401     } else {
1402         if (!test_get_libctx(&testctx, &nullprov, config_file, &deflprov, prov_name))
1403             return 0;
1404     }
1405 
1406     /* FIPS(3.0.0): provider imports explicit params but they won't work #17998 */
1407     is_fips_3_0_0 = is_fips && fips_provider_version_eq(testctx, 3, 0, 0);
1408     /* FIPS(3.5.0) is the first to support ML-DSA, ML-KEM and SLH-DSA */
1409     is_fips_lt_3_5 = is_fips && fips_provider_version_lt(testctx, 3, 5, 0);
1410 
1411 #ifdef STATIC_LEGACY
1412     /*
1413      * This test is always statically linked against libcrypto. We must not
1414      * attempt to load legacy.so that might be dynamically linked against
1415      * libcrypto. Instead we use a built-in version of the legacy provider.
1416      */
1417     if (!OSSL_PROVIDER_add_builtin(testctx, "legacy", ossl_legacy_provider_init))
1418         return 0;
1419 #endif
1420 
1421     /* Separate provider/ctx for generating the test data */
1422     if (!TEST_ptr(keyctx = OSSL_LIB_CTX_new()))
1423         return 0;
1424     if (!TEST_ptr(keyprov = OSSL_PROVIDER_load(keyctx, "default")))
1425         return 0;
1426 
1427 #ifndef OPENSSL_NO_EC
1428     if (!TEST_ptr(bnctx = BN_CTX_new_ex(testctx))
1429         || !TEST_ptr(bld_prime_nc = OSSL_PARAM_BLD_new())
1430         || !TEST_ptr(bld_prime = OSSL_PARAM_BLD_new())
1431         || !create_ec_explicit_prime_params_namedcurve(bld_prime_nc)
1432         || !create_ec_explicit_prime_params(bld_prime)
1433         || !TEST_ptr(ec_explicit_prime_params_nc = OSSL_PARAM_BLD_to_param(bld_prime_nc))
1434         || !TEST_ptr(ec_explicit_prime_params_explicit = OSSL_PARAM_BLD_to_param(bld_prime))
1435 #ifndef OPENSSL_NO_EC2M
1436         || !TEST_ptr(bld_tri_nc = OSSL_PARAM_BLD_new())
1437         || !TEST_ptr(bld_tri = OSSL_PARAM_BLD_new())
1438         || !create_ec_explicit_trinomial_params_namedcurve(bld_tri_nc)
1439         || !create_ec_explicit_trinomial_params(bld_tri)
1440         || !TEST_ptr(ec_explicit_tri_params_nc = OSSL_PARAM_BLD_to_param(bld_tri_nc))
1441         || !TEST_ptr(ec_explicit_tri_params_explicit = OSSL_PARAM_BLD_to_param(bld_tri))
1442 #endif
1443     )
1444         return 0;
1445 #endif
1446 
1447     TEST_info("Generating keys...");
1448 
1449 #ifndef OPENSSL_NO_DH
1450     TEST_info("Generating DH keys...");
1451     MAKE_DOMAIN_KEYS(DH, "DH", NULL);
1452     MAKE_DOMAIN_KEYS(DHX, "X9.42 DH", NULL);
1453 #endif
1454 #ifndef OPENSSL_NO_DSA
1455     TEST_info("Generating DSA keys...");
1456     MAKE_DOMAIN_KEYS(DSA, "DSA", DSA_params);
1457 #endif
1458 #ifndef OPENSSL_NO_EC
1459     TEST_info("Generating EC keys...");
1460     MAKE_DOMAIN_KEYS(EC, "EC", EC_params);
1461     MAKE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve, "EC", ec_explicit_prime_params_nc);
1462     MAKE_DOMAIN_KEYS(ECExplicitPrime2G, "EC", ec_explicit_prime_params_explicit);
1463 #ifndef OPENSSL_NO_EC2M
1464     MAKE_DOMAIN_KEYS(ECExplicitTriNamedCurve, "EC", ec_explicit_tri_params_nc);
1465     MAKE_DOMAIN_KEYS(ECExplicitTri2G, "EC", ec_explicit_tri_params_explicit);
1466 #endif
1467 #ifndef OPENSSL_NO_SM2
1468     MAKE_KEYS(SM2, "SM2", NULL);
1469 #endif
1470 #endif
1471 #ifndef OPENSSL_NO_ECX
1472     MAKE_KEYS(ED25519, "ED25519", NULL);
1473     MAKE_KEYS(ED448, "ED448", NULL);
1474     MAKE_KEYS(X25519, "X25519", NULL);
1475     MAKE_KEYS(X448, "X448", NULL);
1476 #endif
1477 #ifndef OPENSSL_NO_ML_DSA
1478     if (!is_fips_lt_3_5) {
1479         MAKE_KEYS(ML_DSA_44, "ML-DSA-44", NULL);
1480         MAKE_KEYS(ML_DSA_65, "ML-DSA-65", NULL);
1481         MAKE_KEYS(ML_DSA_87, "ML-DSA-87", NULL);
1482     }
1483 #endif /* OPENSSL_NO_ML_DSA */
1484 #ifndef OPENSSL_NO_ML_KEM
1485     if (!is_fips_lt_3_5) {
1486         MAKE_KEYS(ML_KEM_512, "ML-KEM-512", NULL);
1487         MAKE_KEYS(ML_KEM_768, "ML-KEM-768", NULL);
1488         MAKE_KEYS(ML_KEM_1024, "ML-KEM-1024", NULL);
1489     }
1490 #endif
1491 #ifndef OPENSSL_NO_SLH_DSA
1492     if (!is_fips_lt_3_5) {
1493         MAKE_KEYS(SLH_DSA_SHA2_128s, "SLH-DSA-SHA2-128s", NULL);
1494         MAKE_KEYS(SLH_DSA_SHA2_128f, "SLH-DSA-SHA2-128f", NULL);
1495         MAKE_KEYS(SLH_DSA_SHA2_192s, "SLH-DSA-SHA2-192s", NULL);
1496         MAKE_KEYS(SLH_DSA_SHA2_192f, "SLH-DSA-SHA2-192f", NULL);
1497         MAKE_KEYS(SLH_DSA_SHA2_256s, "SLH-DSA-SHA2-256s", NULL);
1498         MAKE_KEYS(SLH_DSA_SHA2_256f, "SLH-DSA-SHA2-256f", NULL);
1499         MAKE_KEYS(SLH_DSA_SHAKE_128s, "SLH-DSA-SHAKE-128s", NULL);
1500         MAKE_KEYS(SLH_DSA_SHAKE_128f, "SLH-DSA-SHAKE-128f", NULL);
1501         MAKE_KEYS(SLH_DSA_SHAKE_192s, "SLH-DSA-SHAKE-192s", NULL);
1502         MAKE_KEYS(SLH_DSA_SHAKE_192f, "SLH-DSA-SHAKE-192f", NULL);
1503         MAKE_KEYS(SLH_DSA_SHAKE_256s, "SLH-DSA-SHAKE-256s", NULL);
1504         MAKE_KEYS(SLH_DSA_SHAKE_256f, "SLH-DSA-SHAKE-256f", NULL);
1505     }
1506 #endif /* OPENSSL_NO_SLH_DSA */
1507 
1508     TEST_info("Loading RSA key...");
1509     ok = ok && TEST_ptr(key_RSA = load_pkey_pem(rsa_file, keyctx));
1510     TEST_info("Loading RSA_PSS key...");
1511     ok = ok && TEST_ptr(key_RSA_PSS = load_pkey_pem(rsa_pss_file, keyctx));
1512     TEST_info("Generating keys done");
1513 
1514     if (ok) {
1515 #ifndef OPENSSL_NO_DH
1516         ADD_TEST_SUITE(DH);
1517         ADD_TEST_SUITE_PARAMS(DH);
1518         ADD_TEST_SUITE(DHX);
1519         ADD_TEST_SUITE_PARAMS(DHX);
1520         /*
1521          * DH has no support for PEM_write_bio_PrivateKey_traditional(),
1522          * so no legacy tests.
1523          */
1524 #endif
1525 #ifndef OPENSSL_NO_DSA
1526         ADD_TEST_SUITE(DSA);
1527         ADD_TEST_SUITE_PARAMS(DSA);
1528         ADD_TEST_SUITE_LEGACY(DSA);
1529         ADD_TEST_SUITE_MSBLOB(DSA);
1530         ADD_TEST_SUITE_UNPROTECTED_PVK(DSA);
1531 #ifndef OPENSSL_NO_RC4
1532         ADD_TEST_SUITE_PROTECTED_PVK(DSA);
1533 #endif
1534 #endif
1535 #ifndef OPENSSL_NO_EC
1536         ADD_TEST(ec_encode_to_data_multi);
1537         ADD_TEST_SUITE(EC);
1538         ADD_TEST_SUITE_PARAMS(EC);
1539         ADD_TEST_SUITE_LEGACY(EC);
1540         ADD_TEST_SUITE(ECExplicitPrimeNamedCurve);
1541         ADD_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve);
1542         ADD_TEST_SUITE(ECExplicitPrime2G);
1543         ADD_TEST_SUITE_LEGACY(ECExplicitPrime2G);
1544 #ifndef OPENSSL_NO_EC2M
1545         ADD_TEST_SUITE(ECExplicitTriNamedCurve);
1546         ADD_TEST_SUITE_LEGACY(ECExplicitTriNamedCurve);
1547         ADD_TEST_SUITE(ECExplicitTri2G);
1548         ADD_TEST_SUITE_LEGACY(ECExplicitTri2G);
1549 #endif
1550 #ifndef OPENSSL_NO_SM2
1551         if (!is_fips_3_0_0) {
1552             /* 3.0.0 FIPS provider imports explicit EC params and then fails. */
1553             ADD_TEST_SUITE(SM2);
1554         }
1555 #endif
1556 #endif
1557 #ifndef OPENSSL_NO_ECX
1558         ADD_TEST_SUITE(ED25519);
1559         ADD_TEST_SUITE(ED448);
1560         ADD_TEST_SUITE(X25519);
1561         ADD_TEST_SUITE(X448);
1562         /*
1563          * ED25519, ED448, X25519 and X448 have no support for
1564          * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
1565          */
1566 #endif
1567 #ifndef OPENSSL_NO_ML_KEM
1568         if (!is_fips_lt_3_5) {
1569             ADD_TEST_SUITE(ML_KEM_512);
1570             ADD_TEST_SUITE(ML_KEM_768);
1571             ADD_TEST_SUITE(ML_KEM_1024);
1572         }
1573 #endif
1574         ADD_TEST_SUITE(RSA);
1575         ADD_TEST_SUITE_LEGACY(RSA);
1576         ADD_TEST_SUITE(RSA_PSS);
1577         /*
1578          * RSA-PSS has no support for PEM_write_bio_PrivateKey_traditional(),
1579          * so no legacy tests.
1580          */
1581         ADD_TEST_SUITE_MSBLOB(RSA);
1582         ADD_TEST_SUITE_UNPROTECTED_PVK(RSA);
1583 #ifndef OPENSSL_NO_RC4
1584         ADD_TEST_SUITE_PROTECTED_PVK(RSA);
1585 #endif
1586 
1587 #ifndef OPENSSL_NO_ML_DSA
1588         if (!is_fips_lt_3_5) {
1589             ADD_TEST_SUITE(ML_DSA_44);
1590             ADD_TEST_SUITE(ML_DSA_65);
1591             ADD_TEST_SUITE(ML_DSA_87);
1592         }
1593 #endif /* OPENSSL_NO_ML_DSA */
1594 
1595 #ifndef OPENSSL_NO_SLH_DSA
1596         if (!is_fips_lt_3_5) {
1597             ADD_TEST_SUITE(SLH_DSA_SHA2_128s);
1598             ADD_TEST_SUITE(SLH_DSA_SHA2_128f);
1599             ADD_TEST_SUITE(SLH_DSA_SHA2_192s);
1600             ADD_TEST_SUITE(SLH_DSA_SHA2_192f);
1601             ADD_TEST_SUITE(SLH_DSA_SHA2_256s);
1602             ADD_TEST_SUITE(SLH_DSA_SHA2_256f);
1603             ADD_TEST_SUITE(SLH_DSA_SHAKE_128s);
1604             ADD_TEST_SUITE(SLH_DSA_SHAKE_128f);
1605             ADD_TEST_SUITE(SLH_DSA_SHAKE_192s);
1606             ADD_TEST_SUITE(SLH_DSA_SHAKE_192f);
1607             ADD_TEST_SUITE(SLH_DSA_SHAKE_256s);
1608             ADD_TEST_SUITE(SLH_DSA_SHAKE_256f);
1609         }
1610 #endif /* OPENSSL_NO_SLH_DSA */
1611     }
1612 
1613     return 1;
1614 }
1615 
cleanup_tests(void)1616 void cleanup_tests(void)
1617 {
1618 #ifndef OPENSSL_NO_EC
1619     OSSL_PARAM_free(ec_explicit_prime_params_nc);
1620     OSSL_PARAM_free(ec_explicit_prime_params_explicit);
1621     OSSL_PARAM_BLD_free(bld_prime_nc);
1622     OSSL_PARAM_BLD_free(bld_prime);
1623 #ifndef OPENSSL_NO_EC2M
1624     OSSL_PARAM_free(ec_explicit_tri_params_nc);
1625     OSSL_PARAM_free(ec_explicit_tri_params_explicit);
1626     OSSL_PARAM_BLD_free(bld_tri_nc);
1627     OSSL_PARAM_BLD_free(bld_tri);
1628 #endif
1629     BN_CTX_free(bnctx);
1630 #endif /* OPENSSL_NO_EC */
1631 
1632 #ifndef OPENSSL_NO_DH
1633     FREE_DOMAIN_KEYS(DH);
1634     FREE_DOMAIN_KEYS(DHX);
1635 #endif
1636 #ifndef OPENSSL_NO_DSA
1637     FREE_DOMAIN_KEYS(DSA);
1638 #endif
1639 #ifndef OPENSSL_NO_EC
1640     FREE_DOMAIN_KEYS(EC);
1641     FREE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
1642     FREE_DOMAIN_KEYS(ECExplicitPrime2G);
1643 #ifndef OPENSSL_NO_EC2M
1644     FREE_DOMAIN_KEYS(ECExplicitTriNamedCurve);
1645     FREE_DOMAIN_KEYS(ECExplicitTri2G);
1646 #endif
1647 #ifndef OPENSSL_NO_SM2
1648     FREE_KEYS(SM2);
1649 #endif
1650 #endif
1651 #ifndef OPENSSL_NO_ECX
1652     FREE_KEYS(ED25519);
1653     FREE_KEYS(ED448);
1654     FREE_KEYS(X25519);
1655     FREE_KEYS(X448);
1656 #endif
1657 #ifndef OPENSSL_NO_ML_KEM
1658     if (!is_fips_lt_3_5) {
1659         FREE_KEYS(ML_KEM_512);
1660         FREE_KEYS(ML_KEM_768);
1661         FREE_KEYS(ML_KEM_1024);
1662     }
1663 #endif
1664     FREE_KEYS(RSA);
1665     FREE_KEYS(RSA_PSS);
1666 
1667 #ifndef OPENSSL_NO_ML_DSA
1668     if (!is_fips_lt_3_5) {
1669         FREE_KEYS(ML_DSA_44);
1670         FREE_KEYS(ML_DSA_65);
1671         FREE_KEYS(ML_DSA_87);
1672     }
1673 #endif /* OPENSSL_NO_ML_DSA */
1674 
1675 #ifndef OPENSSL_NO_SLH_DSA
1676     if (!is_fips_lt_3_5) {
1677         FREE_KEYS(SLH_DSA_SHA2_128s);
1678         FREE_KEYS(SLH_DSA_SHA2_128f);
1679         FREE_KEYS(SLH_DSA_SHA2_192s);
1680         FREE_KEYS(SLH_DSA_SHA2_192f);
1681         FREE_KEYS(SLH_DSA_SHA2_256s);
1682         FREE_KEYS(SLH_DSA_SHA2_256f);
1683         FREE_KEYS(SLH_DSA_SHAKE_128s);
1684         FREE_KEYS(SLH_DSA_SHAKE_128f);
1685         FREE_KEYS(SLH_DSA_SHAKE_192s);
1686         FREE_KEYS(SLH_DSA_SHAKE_192f);
1687         FREE_KEYS(SLH_DSA_SHAKE_256s);
1688         FREE_KEYS(SLH_DSA_SHAKE_256f);
1689     }
1690 #endif /* OPENSSL_NO_SLH_DSA */
1691 
1692     OSSL_PROVIDER_unload(nullprov);
1693     OSSL_PROVIDER_unload(deflprov);
1694     OSSL_PROVIDER_unload(keyprov);
1695     OSSL_LIB_CTX_free(testctx);
1696     OSSL_LIB_CTX_free(keyctx);
1697 }
1698