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