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