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) || !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,
1216 0x00,
1217 0x00,
1218 0x00,
1219 0x00,
1220 0x00,
1221 0x00,
1222 0x00,
1223 0x00,
1224 0x00,
1225 0x00,
1226 0x00,
1227 0x00,
1228 0x00,
1229 0x00,
1230 0x00,
1231 0x00,
1232 0x00,
1233 0x00,
1234 0x00,
1235 0x04,
1236 0x00,
1237 0x00,
1238 0x00,
1239 0x00,
1240 0x00,
1241 0x00,
1242 0x00,
1243 0x00,
1244 0x01,
1245 };
1246 static const unsigned char a_data[] = {
1247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1250 };
1251 static const unsigned char b_data[] = {
1252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1254 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
1255 };
1256 static const unsigned char order_data[] = {
1257 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1258 0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15, 0xBC, 0xD4, 0x6E, 0xFB,
1259 0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF
1260 };
1261 static const unsigned char cofactor_data[] = {
1262 0x4
1263 };
1264 return TEST_ptr(a = BN_CTX_get(bnctx))
1265 && TEST_ptr(b = BN_CTX_get(bnctx))
1266 && TEST_ptr(poly = BN_CTX_get(bnctx))
1267 && TEST_ptr(order = BN_CTX_get(bnctx))
1268 && TEST_ptr(cofactor = BN_CTX_get(bnctx))
1269 && TEST_ptr(BN_bin2bn(poly_data, sizeof(poly_data), poly))
1270 && TEST_ptr(BN_bin2bn(a_data, sizeof(a_data), a))
1271 && TEST_ptr(BN_bin2bn(b_data, sizeof(b_data), b))
1272 && TEST_ptr(BN_bin2bn(order_data, sizeof(order_data), order))
1273 && TEST_ptr(BN_bin2bn(cofactor_data, sizeof(cofactor_data), cofactor))
1274 && TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
1275 OSSL_PKEY_PARAM_EC_FIELD_TYPE,
1276 SN_X9_62_characteristic_two_field, 0))
1277 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, poly))
1278 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
1279 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b))
1280 && TEST_true(OSSL_PARAM_BLD_push_BN(bld,
1281 OSSL_PKEY_PARAM_EC_ORDER, order))
1282 && TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
1283 OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_len))
1284 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
1285 cofactor));
1286 }
1287
create_ec_explicit_trinomial_params_namedcurve(OSSL_PARAM_BLD * bld)1288 static int create_ec_explicit_trinomial_params_namedcurve(OSSL_PARAM_BLD *bld)
1289 {
1290 static const unsigned char gen[] = {
1291 0x04,
1292 0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, 0x29, 0xF2,
1293 0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2, 0x6B, 0xF5, 0x0A, 0x4C,
1294 0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26,
1295 0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, 0x55, 0x5A,
1296 0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A, 0xEB, 0x9B, 0x56, 0xE0,
1297 0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3
1298 };
1299 return do_create_ec_explicit_trinomial_params(bld, gen, sizeof(gen));
1300 }
1301
create_ec_explicit_trinomial_params(OSSL_PARAM_BLD * bld)1302 static int create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld)
1303 {
1304 static const unsigned char gen2[] = {
1305 0x04,
1306 0x00, 0xd7, 0xba, 0xd0, 0x26, 0x6c, 0x31, 0x6a, 0x78, 0x76, 0x01, 0xd1,
1307 0x32, 0x4b, 0x8f, 0x30, 0x29, 0x2d, 0x78, 0x30, 0xca, 0x43, 0xaa, 0xf0,
1308 0xa2, 0x5a, 0xd4, 0x0f, 0xb3, 0xf4,
1309 0x00, 0x85, 0x4b, 0x1b, 0x8d, 0x50, 0x10, 0xa5, 0x1c, 0x80, 0xf7, 0x86,
1310 0x40, 0x62, 0x4c, 0x87, 0xd1, 0x26, 0x7a, 0x9c, 0x5c, 0xe9, 0x82, 0x29,
1311 0xd1, 0x67, 0x70, 0x41, 0xea, 0xcb
1312 };
1313 return do_create_ec_explicit_trinomial_params(bld, gen2, sizeof(gen2));
1314 }
1315 #endif /* OPENSSL_NO_EC2M */
1316
1317 /*
1318 * Test that multiple calls to OSSL_ENCODER_to_data() do not cause side effects
1319 */
ec_encode_to_data_multi(void)1320 static int ec_encode_to_data_multi(void)
1321 {
1322 int ret;
1323 OSSL_ENCODER_CTX *ectx = NULL;
1324 EVP_PKEY *key = NULL;
1325 uint8_t *enc = NULL;
1326 size_t enc_len = 0;
1327
1328 ret = TEST_ptr(key = EVP_PKEY_Q_keygen(testctx, "", "EC", "P-256"))
1329 && TEST_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(key, EVP_PKEY_KEYPAIR,
1330 "DER", NULL, NULL))
1331 && TEST_int_eq(OSSL_ENCODER_to_data(ectx, NULL, &enc_len), 1)
1332 && TEST_int_eq(OSSL_ENCODER_to_data(ectx, &enc, &enc_len), 1);
1333 OPENSSL_free(enc);
1334 EVP_PKEY_free(key);
1335 OSSL_ENCODER_CTX_free(ectx);
1336 return ret;
1337 }
1338 #endif /* OPENSSL_NO_EC */
1339
1340 typedef enum OPTION_choice {
1341 OPT_ERR = -1,
1342 OPT_EOF = 0,
1343 OPT_CONTEXT,
1344 OPT_RSA_FILE,
1345 OPT_RSA_PSS_FILE,
1346 OPT_CONFIG_FILE,
1347 OPT_PROVIDER_NAME,
1348 OPT_TEST_ENUM
1349 } OPTION_CHOICE;
1350
test_get_options(void)1351 const OPTIONS *test_get_options(void)
1352 {
1353 static const OPTIONS options[] = {
1354 OPT_TEST_OPTIONS_DEFAULT_USAGE,
1355 { "context", OPT_CONTEXT, '-',
1356 "Explicitly use a non-default library context" },
1357 { "rsa", OPT_RSA_FILE, '<',
1358 "PEM format RSA key file to encode/decode" },
1359 { "pss", OPT_RSA_PSS_FILE, '<',
1360 "PEM format RSA-PSS key file to encode/decode" },
1361 { "config", OPT_CONFIG_FILE, '<',
1362 "The configuration file to use for the library context" },
1363 { "provider", OPT_PROVIDER_NAME, 's',
1364 "The provider to load (The default value is 'default')" },
1365 { NULL }
1366 };
1367 return options;
1368 }
1369
setup_tests(void)1370 int setup_tests(void)
1371 {
1372 const char *rsa_file = NULL;
1373 const char *rsa_pss_file = NULL;
1374 const char *prov_name = "default";
1375 char *config_file = NULL;
1376 int ok = 1;
1377
1378 #ifndef OPENSSL_NO_DSA
1379 static size_t qbits = 160; /* PVK only tolerates 160 Q bits */
1380 static size_t pbits = 1024; /* With 160 Q bits, we MUST use 1024 P bits */
1381 OSSL_PARAM DSA_params[] = {
1382 OSSL_PARAM_size_t("pbits", &pbits),
1383 OSSL_PARAM_size_t("qbits", &qbits),
1384 OSSL_PARAM_END
1385 };
1386 #endif
1387
1388 #ifndef OPENSSL_NO_EC
1389 static char groupname[] = "prime256v1";
1390 OSSL_PARAM EC_params[] = {
1391 OSSL_PARAM_utf8_string("group", groupname, sizeof(groupname) - 1),
1392 OSSL_PARAM_END
1393 };
1394 #endif
1395
1396 OPTION_CHOICE o;
1397
1398 while ((o = opt_next()) != OPT_EOF) {
1399 switch (o) {
1400 case OPT_CONTEXT:
1401 default_libctx = 0;
1402 break;
1403 case OPT_PROVIDER_NAME:
1404 prov_name = opt_arg();
1405 break;
1406 case OPT_CONFIG_FILE:
1407 config_file = opt_arg();
1408 break;
1409 case OPT_RSA_FILE:
1410 rsa_file = opt_arg();
1411 break;
1412 case OPT_RSA_PSS_FILE:
1413 rsa_pss_file = opt_arg();
1414 break;
1415 case OPT_TEST_CASES:
1416 break;
1417 default:
1418 return 0;
1419 }
1420 }
1421
1422 if (strcmp(prov_name, "fips") == 0)
1423 is_fips = 1;
1424
1425 if (default_libctx) {
1426 if (!test_get_libctx(NULL, NULL, config_file, &deflprov, prov_name))
1427 return 0;
1428 } else {
1429 if (!test_get_libctx(&testctx, &nullprov, config_file, &deflprov, prov_name))
1430 return 0;
1431 }
1432
1433 /* FIPS(3.0.0): provider imports explicit params but they won't work #17998 */
1434 is_fips_3_0_0 = is_fips && fips_provider_version_eq(testctx, 3, 0, 0);
1435 /* FIPS(3.5.0) is the first to support ML-DSA, ML-KEM and SLH-DSA */
1436 is_fips_lt_3_5 = is_fips && fips_provider_version_lt(testctx, 3, 5, 0);
1437
1438 #ifdef STATIC_LEGACY
1439 /*
1440 * This test is always statically linked against libcrypto. We must not
1441 * attempt to load legacy.so that might be dynamically linked against
1442 * libcrypto. Instead we use a built-in version of the legacy provider.
1443 */
1444 if (!OSSL_PROVIDER_add_builtin(testctx, "legacy", ossl_legacy_provider_init))
1445 return 0;
1446 #endif
1447
1448 /* Separate provider/ctx for generating the test data */
1449 if (!TEST_ptr(keyctx = OSSL_LIB_CTX_new()))
1450 return 0;
1451 if (!TEST_ptr(keyprov = OSSL_PROVIDER_load(keyctx, "default")))
1452 return 0;
1453
1454 #ifndef OPENSSL_NO_EC
1455 if (!TEST_ptr(bnctx = BN_CTX_new_ex(testctx))
1456 || !TEST_ptr(bld_prime_nc = OSSL_PARAM_BLD_new())
1457 || !TEST_ptr(bld_prime = OSSL_PARAM_BLD_new())
1458 || !create_ec_explicit_prime_params_namedcurve(bld_prime_nc)
1459 || !create_ec_explicit_prime_params(bld_prime)
1460 || !TEST_ptr(ec_explicit_prime_params_nc = OSSL_PARAM_BLD_to_param(bld_prime_nc))
1461 || !TEST_ptr(ec_explicit_prime_params_explicit = OSSL_PARAM_BLD_to_param(bld_prime))
1462 #ifndef OPENSSL_NO_EC2M
1463 || !TEST_ptr(bld_tri_nc = OSSL_PARAM_BLD_new())
1464 || !TEST_ptr(bld_tri = OSSL_PARAM_BLD_new())
1465 || !create_ec_explicit_trinomial_params_namedcurve(bld_tri_nc)
1466 || !create_ec_explicit_trinomial_params(bld_tri)
1467 || !TEST_ptr(ec_explicit_tri_params_nc = OSSL_PARAM_BLD_to_param(bld_tri_nc))
1468 || !TEST_ptr(ec_explicit_tri_params_explicit = OSSL_PARAM_BLD_to_param(bld_tri))
1469 #endif
1470 )
1471 return 0;
1472 #endif
1473
1474 TEST_info("Generating keys...");
1475
1476 #ifndef OPENSSL_NO_DH
1477 TEST_info("Generating DH keys...");
1478 MAKE_DOMAIN_KEYS(DH, "DH", NULL);
1479 MAKE_DOMAIN_KEYS(DHX, "X9.42 DH", NULL);
1480 #endif
1481 #ifndef OPENSSL_NO_DSA
1482 TEST_info("Generating DSA keys...");
1483 MAKE_DOMAIN_KEYS(DSA, "DSA", DSA_params);
1484 #endif
1485 #ifndef OPENSSL_NO_EC
1486 TEST_info("Generating EC keys...");
1487 MAKE_DOMAIN_KEYS(EC, "EC", EC_params);
1488 MAKE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve, "EC", ec_explicit_prime_params_nc);
1489 MAKE_DOMAIN_KEYS(ECExplicitPrime2G, "EC", ec_explicit_prime_params_explicit);
1490 #ifndef OPENSSL_NO_EC2M
1491 MAKE_DOMAIN_KEYS(ECExplicitTriNamedCurve, "EC", ec_explicit_tri_params_nc);
1492 MAKE_DOMAIN_KEYS(ECExplicitTri2G, "EC", ec_explicit_tri_params_explicit);
1493 #endif
1494 #ifndef OPENSSL_NO_SM2
1495 MAKE_KEYS(SM2, "SM2", NULL);
1496 #endif
1497 #endif
1498 #ifndef OPENSSL_NO_ECX
1499 MAKE_KEYS(ED25519, "ED25519", NULL);
1500 MAKE_KEYS(ED448, "ED448", NULL);
1501 MAKE_KEYS(X25519, "X25519", NULL);
1502 MAKE_KEYS(X448, "X448", NULL);
1503 #endif
1504 #ifndef OPENSSL_NO_ML_DSA
1505 if (!is_fips_lt_3_5) {
1506 MAKE_KEYS(ML_DSA_44, "ML-DSA-44", NULL);
1507 MAKE_KEYS(ML_DSA_65, "ML-DSA-65", NULL);
1508 MAKE_KEYS(ML_DSA_87, "ML-DSA-87", NULL);
1509 }
1510 #endif /* OPENSSL_NO_ML_DSA */
1511 #ifndef OPENSSL_NO_ML_KEM
1512 if (!is_fips_lt_3_5) {
1513 MAKE_KEYS(ML_KEM_512, "ML-KEM-512", NULL);
1514 MAKE_KEYS(ML_KEM_768, "ML-KEM-768", NULL);
1515 MAKE_KEYS(ML_KEM_1024, "ML-KEM-1024", NULL);
1516 }
1517 #endif
1518 #ifndef OPENSSL_NO_SLH_DSA
1519 if (!is_fips_lt_3_5) {
1520 MAKE_KEYS(SLH_DSA_SHA2_128s, "SLH-DSA-SHA2-128s", NULL);
1521 MAKE_KEYS(SLH_DSA_SHA2_128f, "SLH-DSA-SHA2-128f", NULL);
1522 MAKE_KEYS(SLH_DSA_SHA2_192s, "SLH-DSA-SHA2-192s", NULL);
1523 MAKE_KEYS(SLH_DSA_SHA2_192f, "SLH-DSA-SHA2-192f", NULL);
1524 MAKE_KEYS(SLH_DSA_SHA2_256s, "SLH-DSA-SHA2-256s", NULL);
1525 MAKE_KEYS(SLH_DSA_SHA2_256f, "SLH-DSA-SHA2-256f", NULL);
1526 MAKE_KEYS(SLH_DSA_SHAKE_128s, "SLH-DSA-SHAKE-128s", NULL);
1527 MAKE_KEYS(SLH_DSA_SHAKE_128f, "SLH-DSA-SHAKE-128f", NULL);
1528 MAKE_KEYS(SLH_DSA_SHAKE_192s, "SLH-DSA-SHAKE-192s", NULL);
1529 MAKE_KEYS(SLH_DSA_SHAKE_192f, "SLH-DSA-SHAKE-192f", NULL);
1530 MAKE_KEYS(SLH_DSA_SHAKE_256s, "SLH-DSA-SHAKE-256s", NULL);
1531 MAKE_KEYS(SLH_DSA_SHAKE_256f, "SLH-DSA-SHAKE-256f", NULL);
1532 }
1533 #endif /* OPENSSL_NO_SLH_DSA */
1534
1535 TEST_info("Loading RSA key...");
1536 ok = ok && TEST_ptr(key_RSA = load_pkey_pem(rsa_file, keyctx));
1537 TEST_info("Loading RSA_PSS key...");
1538 ok = ok && TEST_ptr(key_RSA_PSS = load_pkey_pem(rsa_pss_file, keyctx));
1539 TEST_info("Generating keys done");
1540
1541 if (ok) {
1542 #ifndef OPENSSL_NO_DH
1543 ADD_TEST_SUITE(DH);
1544 ADD_TEST_SUITE_PARAMS(DH);
1545 ADD_TEST_SUITE(DHX);
1546 ADD_TEST_SUITE_PARAMS(DHX);
1547 /*
1548 * DH has no support for PEM_write_bio_PrivateKey_traditional(),
1549 * so no legacy tests.
1550 */
1551 #endif
1552 #ifndef OPENSSL_NO_DSA
1553 ADD_TEST_SUITE(DSA);
1554 ADD_TEST_SUITE_PARAMS(DSA);
1555 ADD_TEST_SUITE_LEGACY(DSA);
1556 ADD_TEST_SUITE_MSBLOB(DSA);
1557 ADD_TEST_SUITE_UNPROTECTED_PVK(DSA);
1558 #ifndef OPENSSL_NO_RC4
1559 ADD_TEST_SUITE_PROTECTED_PVK(DSA);
1560 #endif
1561 #endif
1562 #ifndef OPENSSL_NO_EC
1563 ADD_TEST(ec_encode_to_data_multi);
1564 ADD_TEST_SUITE(EC);
1565 ADD_TEST_SUITE_PARAMS(EC);
1566 ADD_TEST_SUITE_LEGACY(EC);
1567 ADD_TEST_SUITE(ECExplicitPrimeNamedCurve);
1568 ADD_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve);
1569 ADD_TEST_SUITE(ECExplicitPrime2G);
1570 ADD_TEST_SUITE_LEGACY(ECExplicitPrime2G);
1571 #ifndef OPENSSL_NO_EC2M
1572 ADD_TEST_SUITE(ECExplicitTriNamedCurve);
1573 ADD_TEST_SUITE_LEGACY(ECExplicitTriNamedCurve);
1574 ADD_TEST_SUITE(ECExplicitTri2G);
1575 ADD_TEST_SUITE_LEGACY(ECExplicitTri2G);
1576 #endif
1577 #ifndef OPENSSL_NO_SM2
1578 if (!is_fips_3_0_0) {
1579 /* 3.0.0 FIPS provider imports explicit EC params and then fails. */
1580 ADD_TEST_SUITE(SM2);
1581 }
1582 #endif
1583 #endif
1584 #ifndef OPENSSL_NO_ECX
1585 ADD_TEST_SUITE(ED25519);
1586 ADD_TEST_SUITE(ED448);
1587 ADD_TEST_SUITE(X25519);
1588 ADD_TEST_SUITE(X448);
1589 /*
1590 * ED25519, ED448, X25519 and X448 have no support for
1591 * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
1592 */
1593 #endif
1594 #ifndef OPENSSL_NO_ML_KEM
1595 if (!is_fips_lt_3_5) {
1596 ADD_TEST_SUITE(ML_KEM_512);
1597 ADD_TEST_SUITE(ML_KEM_768);
1598 ADD_TEST_SUITE(ML_KEM_1024);
1599 }
1600 #endif
1601 ADD_TEST_SUITE(RSA);
1602 ADD_TEST_SUITE_LEGACY(RSA);
1603 ADD_TEST_SUITE(RSA_PSS);
1604 /*
1605 * RSA-PSS has no support for PEM_write_bio_PrivateKey_traditional(),
1606 * so no legacy tests.
1607 */
1608 ADD_TEST_SUITE_MSBLOB(RSA);
1609 ADD_TEST_SUITE_UNPROTECTED_PVK(RSA);
1610 #ifndef OPENSSL_NO_RC4
1611 ADD_TEST_SUITE_PROTECTED_PVK(RSA);
1612 #endif
1613
1614 #ifndef OPENSSL_NO_ML_DSA
1615 if (!is_fips_lt_3_5) {
1616 ADD_TEST_SUITE(ML_DSA_44);
1617 ADD_TEST_SUITE(ML_DSA_65);
1618 ADD_TEST_SUITE(ML_DSA_87);
1619 }
1620 #endif /* OPENSSL_NO_ML_DSA */
1621
1622 #ifndef OPENSSL_NO_SLH_DSA
1623 if (!is_fips_lt_3_5) {
1624 ADD_TEST_SUITE(SLH_DSA_SHA2_128s);
1625 ADD_TEST_SUITE(SLH_DSA_SHA2_128f);
1626 ADD_TEST_SUITE(SLH_DSA_SHA2_192s);
1627 ADD_TEST_SUITE(SLH_DSA_SHA2_192f);
1628 ADD_TEST_SUITE(SLH_DSA_SHA2_256s);
1629 ADD_TEST_SUITE(SLH_DSA_SHA2_256f);
1630 ADD_TEST_SUITE(SLH_DSA_SHAKE_128s);
1631 ADD_TEST_SUITE(SLH_DSA_SHAKE_128f);
1632 ADD_TEST_SUITE(SLH_DSA_SHAKE_192s);
1633 ADD_TEST_SUITE(SLH_DSA_SHAKE_192f);
1634 ADD_TEST_SUITE(SLH_DSA_SHAKE_256s);
1635 ADD_TEST_SUITE(SLH_DSA_SHAKE_256f);
1636 }
1637 #endif /* OPENSSL_NO_SLH_DSA */
1638 }
1639
1640 return 1;
1641 }
1642
cleanup_tests(void)1643 void cleanup_tests(void)
1644 {
1645 #ifndef OPENSSL_NO_EC
1646 OSSL_PARAM_free(ec_explicit_prime_params_nc);
1647 OSSL_PARAM_free(ec_explicit_prime_params_explicit);
1648 OSSL_PARAM_BLD_free(bld_prime_nc);
1649 OSSL_PARAM_BLD_free(bld_prime);
1650 #ifndef OPENSSL_NO_EC2M
1651 OSSL_PARAM_free(ec_explicit_tri_params_nc);
1652 OSSL_PARAM_free(ec_explicit_tri_params_explicit);
1653 OSSL_PARAM_BLD_free(bld_tri_nc);
1654 OSSL_PARAM_BLD_free(bld_tri);
1655 #endif
1656 BN_CTX_free(bnctx);
1657 #endif /* OPENSSL_NO_EC */
1658
1659 #ifndef OPENSSL_NO_DH
1660 FREE_DOMAIN_KEYS(DH);
1661 FREE_DOMAIN_KEYS(DHX);
1662 #endif
1663 #ifndef OPENSSL_NO_DSA
1664 FREE_DOMAIN_KEYS(DSA);
1665 #endif
1666 #ifndef OPENSSL_NO_EC
1667 FREE_DOMAIN_KEYS(EC);
1668 FREE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
1669 FREE_DOMAIN_KEYS(ECExplicitPrime2G);
1670 #ifndef OPENSSL_NO_EC2M
1671 FREE_DOMAIN_KEYS(ECExplicitTriNamedCurve);
1672 FREE_DOMAIN_KEYS(ECExplicitTri2G);
1673 #endif
1674 #ifndef OPENSSL_NO_SM2
1675 FREE_KEYS(SM2);
1676 #endif
1677 #endif
1678 #ifndef OPENSSL_NO_ECX
1679 FREE_KEYS(ED25519);
1680 FREE_KEYS(ED448);
1681 FREE_KEYS(X25519);
1682 FREE_KEYS(X448);
1683 #endif
1684 #ifndef OPENSSL_NO_ML_KEM
1685 if (!is_fips_lt_3_5) {
1686 FREE_KEYS(ML_KEM_512);
1687 FREE_KEYS(ML_KEM_768);
1688 FREE_KEYS(ML_KEM_1024);
1689 }
1690 #endif
1691 FREE_KEYS(RSA);
1692 FREE_KEYS(RSA_PSS);
1693
1694 #ifndef OPENSSL_NO_ML_DSA
1695 if (!is_fips_lt_3_5) {
1696 FREE_KEYS(ML_DSA_44);
1697 FREE_KEYS(ML_DSA_65);
1698 FREE_KEYS(ML_DSA_87);
1699 }
1700 #endif /* OPENSSL_NO_ML_DSA */
1701
1702 #ifndef OPENSSL_NO_SLH_DSA
1703 if (!is_fips_lt_3_5) {
1704 FREE_KEYS(SLH_DSA_SHA2_128s);
1705 FREE_KEYS(SLH_DSA_SHA2_128f);
1706 FREE_KEYS(SLH_DSA_SHA2_192s);
1707 FREE_KEYS(SLH_DSA_SHA2_192f);
1708 FREE_KEYS(SLH_DSA_SHA2_256s);
1709 FREE_KEYS(SLH_DSA_SHA2_256f);
1710 FREE_KEYS(SLH_DSA_SHAKE_128s);
1711 FREE_KEYS(SLH_DSA_SHAKE_128f);
1712 FREE_KEYS(SLH_DSA_SHAKE_192s);
1713 FREE_KEYS(SLH_DSA_SHAKE_192f);
1714 FREE_KEYS(SLH_DSA_SHAKE_256s);
1715 FREE_KEYS(SLH_DSA_SHAKE_256f);
1716 }
1717 #endif /* OPENSSL_NO_SLH_DSA */
1718
1719 OSSL_PROVIDER_unload(nullprov);
1720 OSSL_PROVIDER_unload(deflprov);
1721 OSSL_PROVIDER_unload(keyprov);
1722 OSSL_LIB_CTX_free(testctx);
1723 OSSL_LIB_CTX_free(keyctx);
1724 }
1725