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