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 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
64 static OSSL_PARAM_BLD *bld_prime_nc = NULL;
65 static OSSL_PARAM_BLD *bld_prime = NULL;
66 static OSSL_PARAM *ec_explicit_prime_params_nc = NULL;
67 static OSSL_PARAM *ec_explicit_prime_params_explicit = NULL;
68
69 #ifndef OPENSSL_NO_EC2M
70 static OSSL_PARAM_BLD *bld_tri_nc = NULL;
71 static OSSL_PARAM_BLD *bld_tri = NULL;
72 static OSSL_PARAM *ec_explicit_tri_params_nc = NULL;
73 static OSSL_PARAM *ec_explicit_tri_params_explicit = NULL;
74 #endif
75 #endif
76 #endif
77
78 #ifndef OPENSSL_NO_KEYPARAMS
make_template(const char * type,OSSL_PARAM * genparams)79 static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams)
80 {
81 EVP_PKEY *pkey = NULL;
82 EVP_PKEY_CTX *ctx = NULL;
83
84 #ifndef OPENSSL_NO_DH
85 /*
86 * Use 512-bit DH(X) keys with predetermined parameters for efficiency,
87 * for testing only. Use a minimum key size of 2048 for security purposes.
88 */
89 if (strcmp(type, "DH") == 0)
90 return get_dh512(keyctx);
91
92 if (strcmp(type, "X9.42 DH") == 0)
93 return get_dhx512(keyctx);
94 #endif
95
96 /*
97 * No real need to check the errors other than for the cascade
98 * effect. |pkey| will simply remain NULL if something goes wrong.
99 */
100 (void)((ctx = EVP_PKEY_CTX_new_from_name(keyctx, type, testpropq)) != NULL
101 && EVP_PKEY_paramgen_init(ctx) > 0
102 && (genparams == NULL
103 || EVP_PKEY_CTX_set_params(ctx, genparams) > 0)
104 && EVP_PKEY_generate(ctx, &pkey) > 0);
105 EVP_PKEY_CTX_free(ctx);
106
107 return pkey;
108 }
109 #endif
110
111 #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)112 static EVP_PKEY *make_key(const char *type, EVP_PKEY *template,
113 OSSL_PARAM *genparams)
114 {
115 EVP_PKEY *pkey = NULL;
116 EVP_PKEY_CTX *ctx = template != NULL
117 ? EVP_PKEY_CTX_new_from_pkey(keyctx, template, testpropq)
118 : EVP_PKEY_CTX_new_from_name(keyctx, type, testpropq);
119
120 /*
121 * No real need to check the errors other than for the cascade
122 * effect. |pkey| will simply remain NULL if something goes wrong.
123 */
124 (void)(ctx != NULL
125 && EVP_PKEY_keygen_init(ctx) > 0
126 && (genparams == NULL
127 || EVP_PKEY_CTX_set_params(ctx, genparams) > 0)
128 && EVP_PKEY_keygen(ctx, &pkey) > 0);
129 EVP_PKEY_CTX_free(ctx);
130 return pkey;
131 }
132 #endif
133
134 /* Main test driver */
135
136 typedef int(encoder)(const char *file, const int line,
137 void **encoded, long *encoded_len,
138 void *object, int selection,
139 const char *output_type, const char *output_structure,
140 const char *pass, const char *pcipher);
141 typedef int(decoder)(const char *file, const int line,
142 void **object, void *encoded, long encoded_len,
143 const char *input_type, const char *structure_type,
144 const char *keytype, int selection, const char *pass);
145 typedef int(tester)(const char *file, const int line,
146 const void *data1, size_t data1_len,
147 const void *data2, size_t data2_len);
148 typedef int(checker)(const char *file, const int line,
149 const char *type, const void *data, size_t data_len);
150 typedef void(dumper)(const char *label, const void *data, size_t data_len);
151
152 #define FLAG_DECODE_WITH_TYPE 0x0001
153 #define FLAG_FAIL_IF_FIPS 0x0002
154
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)155 static int test_encode_decode(const char *file, const int line,
156 const char *type, EVP_PKEY *pkey,
157 int selection, const char *output_type,
158 const char *output_structure,
159 const char *pass, const char *pcipher,
160 encoder *encode_cb, decoder *decode_cb,
161 tester *test_cb, checker *check_cb,
162 dumper *dump_cb, int flags)
163 {
164 void *encoded = NULL;
165 long encoded_len = 0;
166 EVP_PKEY *pkey2 = NULL;
167 EVP_PKEY *pkey3 = NULL;
168 void *encoded2 = NULL;
169 long encoded2_len = 0;
170 int ok = 0;
171
172 /*
173 * Encode |pkey|, decode the result into |pkey2|, and finish off by
174 * encoding |pkey2| as well. That last encoding is for checking and
175 * dumping purposes.
176 */
177 if (!TEST_true(encode_cb(file, line, &encoded, &encoded_len, pkey, selection,
178 output_type, output_structure, pass, pcipher)))
179 goto end;
180
181 if ((flags & FLAG_FAIL_IF_FIPS) != 0 && is_fips && !is_fips_3_0_0) {
182 if (TEST_false(decode_cb(file, line, (void **)&pkey2, encoded,
183 encoded_len, output_type, output_structure,
184 (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
185 selection, pass)))
186 ok = 1;
187 goto end;
188 }
189
190 if (!TEST_true(check_cb(file, line, type, encoded, encoded_len))
191 || !TEST_true(decode_cb(file, line, (void **)&pkey2, encoded, encoded_len,
192 output_type, output_structure,
193 (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
194 selection, pass))
195 || ((output_structure == NULL
196 || strcmp(output_structure, "type-specific") != 0)
197 && !TEST_true(decode_cb(file, line, (void **)&pkey3, encoded, encoded_len,
198 output_type, output_structure,
199 (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
200 0, pass)))
201 || !TEST_true(encode_cb(file, line, &encoded2, &encoded2_len, pkey2, selection,
202 output_type, output_structure, pass, pcipher)))
203 goto end;
204
205 if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
206 if (!TEST_int_eq(EVP_PKEY_parameters_eq(pkey, pkey2), 1)
207 || (pkey3 != NULL
208 && !TEST_int_eq(EVP_PKEY_parameters_eq(pkey, pkey3), 1)))
209 goto end;
210 } else {
211 if (!TEST_int_eq(EVP_PKEY_eq(pkey, pkey2), 1)
212 || (pkey3 != NULL
213 && !TEST_int_eq(EVP_PKEY_eq(pkey, pkey3), 1)))
214 goto end;
215 }
216
217 /*
218 * Double check the encoding, but only for unprotected keys,
219 * as protected keys have a random component, which makes the output
220 * differ.
221 */
222 if ((pass == NULL && pcipher == NULL)
223 && !test_cb(file, line, encoded, encoded_len, encoded2, encoded2_len))
224 goto end;
225
226 ok = 1;
227 end:
228 if (!ok) {
229 if (encoded != NULL && encoded_len != 0)
230 dump_cb("|pkey| encoded", encoded, encoded_len);
231 if (encoded2 != NULL && encoded2_len != 0)
232 dump_cb("|pkey2| encoded", encoded2, encoded2_len);
233 }
234
235 OPENSSL_free(encoded);
236 OPENSSL_free(encoded2);
237 EVP_PKEY_free(pkey2);
238 EVP_PKEY_free(pkey3);
239 return ok;
240 }
241
242 /* Encoding and decoding methods */
243
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)244 static int encode_EVP_PKEY_prov(const char *file, const int line,
245 void **encoded, long *encoded_len,
246 void *object, int selection,
247 const char *output_type,
248 const char *output_structure,
249 const char *pass, const char *pcipher)
250 {
251 EVP_PKEY *pkey = object;
252 OSSL_ENCODER_CTX *ectx = NULL;
253 BIO *mem_ser = NULL;
254 BUF_MEM *mem_buf = NULL;
255 const unsigned char *upass = (const unsigned char *)pass;
256 int ok = 0;
257
258 if (!TEST_FL_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection,
259 output_type,
260 output_structure,
261 testpropq))
262 || !TEST_FL_int_gt(OSSL_ENCODER_CTX_get_num_encoders(ectx), 0)
263 || (pass != NULL
264 && !TEST_FL_true(OSSL_ENCODER_CTX_set_passphrase(ectx, upass,
265 strlen(pass))))
266 || (pcipher != NULL
267 && !TEST_FL_true(OSSL_ENCODER_CTX_set_cipher(ectx, pcipher, NULL)))
268 || !TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
269 || !TEST_FL_true(OSSL_ENCODER_to_bio(ectx, mem_ser))
270 || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
271 || !TEST_FL_ptr(*encoded = mem_buf->data)
272 || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
273 goto end;
274
275 /* Detach the encoded output */
276 mem_buf->data = NULL;
277 mem_buf->length = 0;
278 ok = 1;
279 end:
280 BIO_free(mem_ser);
281 OSSL_ENCODER_CTX_free(ectx);
282 return ok;
283 }
284
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)285 static int decode_EVP_PKEY_prov(const char *file, const int line,
286 void **object, void *encoded, long encoded_len,
287 const char *input_type,
288 const char *structure_type,
289 const char *keytype, int selection,
290 const char *pass)
291 {
292 EVP_PKEY *pkey = NULL, *testpkey = NULL;
293 OSSL_DECODER_CTX *dctx = NULL;
294 BIO *encoded_bio = NULL;
295 const unsigned char *upass = (const unsigned char *)pass;
296 int ok = 0;
297 int i;
298 const char *badtype;
299
300 if (strcmp(input_type, "DER") == 0)
301 badtype = "PEM";
302 else
303 badtype = "DER";
304
305 if (!TEST_FL_ptr(encoded_bio = BIO_new_mem_buf(encoded, encoded_len)))
306 goto end;
307
308 /*
309 * We attempt the decode 3 times. The first time we provide the expected
310 * starting input type. The second time we provide NULL for the starting
311 * type. The third time we provide a bad starting input type.
312 * The bad starting input type should fail. The other two should succeed
313 * and produce the same result.
314 */
315 for (i = 0; i < 3; i++) {
316 const char *testtype = (i == 0) ? input_type
317 : ((i == 1) ? NULL : badtype);
318
319 if (!TEST_FL_ptr(dctx = OSSL_DECODER_CTX_new_for_pkey(&testpkey,
320 testtype,
321 structure_type,
322 keytype,
323 selection,
324 testctx, testpropq))
325 || (pass != NULL
326 && !OSSL_DECODER_CTX_set_passphrase(dctx, upass, strlen(pass)))
327 || !TEST_FL_int_gt(BIO_reset(encoded_bio), 0)
328 /* We expect to fail when using a bad input type */
329 || !TEST_FL_int_eq(OSSL_DECODER_from_bio(dctx, encoded_bio),
330 (i == 2) ? 0 : 1))
331 goto end;
332 OSSL_DECODER_CTX_free(dctx);
333 dctx = NULL;
334
335 if (i == 0) {
336 pkey = testpkey;
337 testpkey = NULL;
338 } else if (i == 1) {
339 if (selection == OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) {
340 if (!TEST_FL_int_eq(EVP_PKEY_parameters_eq(pkey, testpkey), 1))
341 goto end;
342 } else {
343 if (!TEST_FL_int_eq(EVP_PKEY_eq(pkey, testpkey), 1))
344 goto end;
345 }
346 }
347 }
348 ok = 1;
349 *object = pkey;
350 pkey = NULL;
351
352 end:
353 EVP_PKEY_free(pkey);
354 EVP_PKEY_free(testpkey);
355 BIO_free(encoded_bio);
356 OSSL_DECODER_CTX_free(dctx);
357 return ok;
358 }
359
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)360 static int encode_EVP_PKEY_legacy_PEM(const char *file, const int line,
361 void **encoded, long *encoded_len,
362 void *object, ossl_unused int selection,
363 ossl_unused const char *output_type,
364 ossl_unused const char *output_structure,
365 const char *pass, const char *pcipher)
366 {
367 EVP_PKEY *pkey = object;
368 EVP_CIPHER *cipher = NULL;
369 BIO *mem_ser = NULL;
370 BUF_MEM *mem_buf = NULL;
371 const unsigned char *upass = (const unsigned char *)pass;
372 size_t passlen = 0;
373 int ok = 0;
374
375 if (pcipher != NULL && pass != NULL) {
376 passlen = strlen(pass);
377 if (!TEST_FL_ptr(cipher = EVP_CIPHER_fetch(testctx, pcipher, testpropq)))
378 goto end;
379 }
380 if (!TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
381 || !TEST_FL_true(PEM_write_bio_PrivateKey_traditional(mem_ser, pkey,
382 cipher,
383 upass, passlen,
384 NULL, NULL))
385 || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
386 || !TEST_FL_ptr(*encoded = mem_buf->data)
387 || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
388 goto end;
389
390 /* Detach the encoded output */
391 mem_buf->data = NULL;
392 mem_buf->length = 0;
393 ok = 1;
394 end:
395 BIO_free(mem_ser);
396 EVP_CIPHER_free(cipher);
397 return ok;
398 }
399
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)400 static int encode_EVP_PKEY_MSBLOB(const char *file, const int line,
401 void **encoded, long *encoded_len,
402 void *object, int selection,
403 ossl_unused const char *output_type,
404 ossl_unused const char *output_structure,
405 ossl_unused const char *pass,
406 ossl_unused const char *pcipher)
407 {
408 EVP_PKEY *pkey = object;
409 BIO *mem_ser = NULL;
410 BUF_MEM *mem_buf = NULL;
411 int ok = 0;
412
413 if (!TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem())))
414 goto end;
415
416 if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
417 if (!TEST_FL_int_ge(i2b_PrivateKey_bio(mem_ser, pkey), 0))
418 goto end;
419 } else {
420 if (!TEST_FL_int_ge(i2b_PublicKey_bio(mem_ser, pkey), 0))
421 goto end;
422 }
423
424 if (!TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
425 || !TEST_FL_ptr(*encoded = mem_buf->data)
426 || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
427 goto end;
428
429 /* Detach the encoded output */
430 mem_buf->data = NULL;
431 mem_buf->length = 0;
432 ok = 1;
433 end:
434 BIO_free(mem_ser);
435 return ok;
436 }
437
438 static pem_password_cb pass_pw;
pass_pw(char * buf,int size,int rwflag,void * userdata)439 static int pass_pw(char *buf, int size, int rwflag, void *userdata)
440 {
441 OPENSSL_strlcpy(buf, userdata, size);
442 return strlen(userdata);
443 }
444
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)445 static int encode_EVP_PKEY_PVK(const char *file, const int line,
446 void **encoded, long *encoded_len,
447 void *object, int selection,
448 ossl_unused const char *output_type,
449 ossl_unused const char *output_structure,
450 const char *pass,
451 ossl_unused const char *pcipher)
452 {
453 EVP_PKEY *pkey = object;
454 BIO *mem_ser = NULL;
455 BUF_MEM *mem_buf = NULL;
456 int enc = (pass != NULL);
457 int ok = 0;
458
459 if (!TEST_FL_true(ossl_assert((selection
460 & OSSL_KEYMGMT_SELECT_PRIVATE_KEY)
461 != 0))
462 || !TEST_FL_ptr(mem_ser = BIO_new(BIO_s_mem()))
463 || !TEST_FL_int_ge(i2b_PVK_bio_ex(mem_ser, pkey, enc,
464 pass_pw, (void *)pass, testctx, testpropq),
465 0)
466 || !TEST_FL_true(BIO_get_mem_ptr(mem_ser, &mem_buf) > 0)
467 || !TEST_FL_ptr(*encoded = mem_buf->data)
468 || !TEST_FL_long_gt(*encoded_len = mem_buf->length, 0))
469 goto end;
470
471 /* Detach the encoded output */
472 mem_buf->data = NULL;
473 mem_buf->length = 0;
474 ok = 1;
475 end:
476 BIO_free(mem_ser);
477 return ok;
478 }
479
test_text(const char * file,const int line,const void * data1,size_t data1_len,const void * data2,size_t data2_len)480 static int test_text(const char *file, const int line,
481 const void *data1, size_t data1_len,
482 const void *data2, size_t data2_len)
483 {
484 return TEST_FL_strn2_eq(data1, data1_len, data2, data2_len);
485 }
486
test_mem(const char * file,const int line,const void * data1,size_t data1_len,const void * data2,size_t data2_len)487 static int test_mem(const char *file, const int line,
488 const void *data1, size_t data1_len,
489 const void *data2, size_t data2_len)
490 {
491 return TEST_FL_mem_eq(data1, data1_len, data2, data2_len);
492 }
493
494 /* Test cases and their dumpers / checkers */
495
collect_name(const char * name,void * arg)496 static void collect_name(const char *name, void *arg)
497 {
498 char **namelist = arg;
499 char *new_namelist;
500 size_t space;
501
502 space = strlen(name);
503 if (*namelist != NULL)
504 space += strlen(*namelist) + 2 /* for comma and space */;
505 space++; /* for terminating null byte */
506
507 new_namelist = OPENSSL_realloc(*namelist, space);
508 if (new_namelist == NULL)
509 return;
510 if (*namelist != NULL) {
511 strcat(new_namelist, ", ");
512 strcat(new_namelist, name);
513 } else {
514 strcpy(new_namelist, name);
515 }
516 *namelist = new_namelist;
517 }
518
dump_der(const char * label,const void * data,size_t data_len)519 static void dump_der(const char *label, const void *data, size_t data_len)
520 {
521 test_output_memory(label, data, data_len);
522 }
523
dump_pem(const char * label,const void * data,size_t data_len)524 static void dump_pem(const char *label, const void *data, size_t data_len)
525 {
526 test_output_string(label, data, data_len - 1);
527 }
528
check_unprotected_PKCS8_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)529 static int check_unprotected_PKCS8_DER(const char *file, const int line,
530 const char *type,
531 const void *data, size_t data_len)
532 {
533 const unsigned char *datap = data;
534 PKCS8_PRIV_KEY_INFO *p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &datap, data_len);
535 int ok = 0;
536
537 if (TEST_FL_ptr(p8inf)) {
538 EVP_PKEY *pkey = EVP_PKCS82PKEY_ex(p8inf, testctx, testpropq);
539 char *namelist = NULL;
540
541 if (TEST_FL_ptr(pkey)) {
542 if (!(ok = TEST_FL_true(EVP_PKEY_is_a(pkey, type)))) {
543 EVP_PKEY_type_names_do_all(pkey, collect_name, &namelist);
544 if (namelist != NULL)
545 TEST_note("%s isn't any of %s", type, namelist);
546 OPENSSL_free(namelist);
547 }
548 ok = ok && TEST_FL_true(evp_pkey_is_provided(pkey));
549 EVP_PKEY_free(pkey);
550 }
551 }
552 PKCS8_PRIV_KEY_INFO_free(p8inf);
553 return ok;
554 }
555
test_unprotected_via_DER(const char * type,EVP_PKEY * key,int fips)556 static int test_unprotected_via_DER(const char *type, EVP_PKEY *key, int fips)
557 {
558 return test_encode_decode(__FILE__, __LINE__, type, key,
559 OSSL_KEYMGMT_SELECT_KEYPAIR
560 | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
561 "DER", "PrivateKeyInfo", NULL, NULL,
562 encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
563 test_mem, check_unprotected_PKCS8_DER,
564 dump_der, fips ? 0 : FLAG_FAIL_IF_FIPS);
565 }
566
check_unprotected_PKCS8_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)567 static int check_unprotected_PKCS8_PEM(const char *file, const int line,
568 const char *type,
569 const void *data, size_t data_len)
570 {
571 static const char expected_pem_header[] = "-----BEGIN " PEM_STRING_PKCS8INF "-----";
572
573 return TEST_FL_strn_eq(data, expected_pem_header,
574 sizeof(expected_pem_header) - 1);
575 }
576
test_unprotected_via_PEM(const char * type,EVP_PKEY * key,int fips)577 static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key, int fips)
578 {
579 return test_encode_decode(__FILE__, __LINE__, type, key,
580 OSSL_KEYMGMT_SELECT_KEYPAIR
581 | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
582 "PEM", "PrivateKeyInfo", NULL, NULL,
583 encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
584 test_text, check_unprotected_PKCS8_PEM,
585 dump_pem, fips ? 0 : FLAG_FAIL_IF_FIPS);
586 }
587
588 #ifndef OPENSSL_NO_KEYPARAMS
check_params_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)589 static int check_params_DER(const char *file, const int line,
590 const char *type, const void *data, size_t data_len)
591 {
592 const unsigned char *datap = data;
593 int ok = 0;
594 int itype = NID_undef;
595 EVP_PKEY *pkey = NULL;
596
597 if (strcmp(type, "DH") == 0)
598 itype = EVP_PKEY_DH;
599 else if (strcmp(type, "X9.42 DH") == 0)
600 itype = EVP_PKEY_DHX;
601 else if (strcmp(type, "DSA") == 0)
602 itype = EVP_PKEY_DSA;
603 else if (strcmp(type, "EC") == 0)
604 itype = EVP_PKEY_EC;
605
606 if (itype != NID_undef) {
607 pkey = d2i_KeyParams(itype, NULL, &datap, data_len);
608 ok = (pkey != NULL);
609 EVP_PKEY_free(pkey);
610 }
611
612 return ok;
613 }
614
check_params_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)615 static int check_params_PEM(const char *file, const int line,
616 const char *type,
617 const void *data, size_t data_len)
618 {
619 static char expected_pem_header[80];
620
621 return TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
622 sizeof(expected_pem_header),
623 "-----BEGIN %s PARAMETERS-----", type),
624 0)
625 && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header));
626 }
627
test_params_via_DER(const char * type,EVP_PKEY * key)628 static int test_params_via_DER(const char *type, EVP_PKEY *key)
629 {
630 return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
631 "DER", "type-specific", NULL, NULL,
632 encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
633 test_mem, check_params_DER,
634 dump_der, FLAG_DECODE_WITH_TYPE);
635 }
636
test_params_via_PEM(const char * type,EVP_PKEY * key)637 static int test_params_via_PEM(const char *type, EVP_PKEY *key)
638 {
639 return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
640 "PEM", "type-specific", NULL, NULL,
641 encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
642 test_text, check_params_PEM,
643 dump_pem, 0);
644 }
645 #endif /* !OPENSSL_NO_KEYPARAMS */
646
check_unprotected_legacy_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)647 static int check_unprotected_legacy_PEM(const char *file, const int line,
648 const char *type,
649 const void *data, size_t data_len)
650 {
651 static char expected_pem_header[80];
652
653 return TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
654 sizeof(expected_pem_header),
655 "-----BEGIN %s PRIVATE KEY-----", type),
656 0)
657 && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header));
658 }
659
test_unprotected_via_legacy_PEM(const char * type,EVP_PKEY * key)660 static int test_unprotected_via_legacy_PEM(const char *type, EVP_PKEY *key)
661 {
662 if (!default_libctx || is_fips)
663 return TEST_skip("Test not available if using a non-default library context or FIPS provider");
664
665 return test_encode_decode(__FILE__, __LINE__, type, key,
666 OSSL_KEYMGMT_SELECT_KEYPAIR
667 | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
668 "PEM", "type-specific", NULL, NULL,
669 encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
670 test_text, check_unprotected_legacy_PEM,
671 dump_pem, 0);
672 }
673
check_MSBLOB(const char * file,const int line,const char * type,const void * data,size_t data_len)674 static int check_MSBLOB(const char *file, const int line,
675 const char *type, const void *data, size_t data_len)
676 {
677 const unsigned char *datap = data;
678 EVP_PKEY *pkey = b2i_PrivateKey(&datap, data_len);
679 int ok = TEST_FL_ptr(pkey);
680
681 EVP_PKEY_free(pkey);
682 return ok;
683 }
684
test_unprotected_via_MSBLOB(const char * type,EVP_PKEY * key)685 static int test_unprotected_via_MSBLOB(const char *type, EVP_PKEY *key)
686 {
687 return test_encode_decode(__FILE__, __LINE__, type, key,
688 OSSL_KEYMGMT_SELECT_KEYPAIR
689 | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
690 "MSBLOB", NULL, NULL, NULL,
691 encode_EVP_PKEY_MSBLOB, decode_EVP_PKEY_prov,
692 test_mem, check_MSBLOB,
693 dump_der, 0);
694 }
695
check_PVK(const char * file,const int line,const char * type,const void * data,size_t data_len)696 static int check_PVK(const char *file, const int line,
697 const char *type, const void *data, size_t data_len)
698 {
699 const unsigned char *in = data;
700 unsigned int saltlen = 0, keylen = 0;
701 int isdss = -1;
702
703 return ossl_do_PVK_header(&in, data_len, 0, &isdss, &saltlen, &keylen);
704 }
705
test_unprotected_via_PVK(const char * type,EVP_PKEY * key)706 static int test_unprotected_via_PVK(const char *type, EVP_PKEY *key)
707 {
708 return test_encode_decode(__FILE__, __LINE__, type, key,
709 OSSL_KEYMGMT_SELECT_KEYPAIR
710 | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
711 "PVK", NULL, NULL, NULL,
712 encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
713 test_mem, check_PVK,
714 dump_der, 0);
715 }
716
717 static const char *pass_cipher = "AES-256-CBC";
718 static const char *pass = "the holy handgrenade of antioch";
719
check_protected_PKCS8_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)720 static int check_protected_PKCS8_DER(const char *file, const int line,
721 const char *type,
722 const void *data, size_t data_len)
723 {
724 const unsigned char *datap = data;
725 X509_SIG *p8 = d2i_X509_SIG(NULL, &datap, data_len);
726 int ok = TEST_FL_ptr(p8);
727
728 X509_SIG_free(p8);
729 return ok;
730 }
731
test_protected_via_DER(const char * type,EVP_PKEY * key,int fips)732 static int test_protected_via_DER(const char *type, EVP_PKEY *key, int fips)
733 {
734 return test_encode_decode(__FILE__, __LINE__, type, key,
735 OSSL_KEYMGMT_SELECT_KEYPAIR
736 | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
737 "DER", "EncryptedPrivateKeyInfo",
738 pass, pass_cipher,
739 encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
740 test_mem, check_protected_PKCS8_DER,
741 dump_der, fips ? 0 : FLAG_FAIL_IF_FIPS);
742 }
743
check_protected_PKCS8_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)744 static int check_protected_PKCS8_PEM(const char *file, const int line,
745 const char *type,
746 const void *data, size_t data_len)
747 {
748 static const char expected_pem_header[] = "-----BEGIN " PEM_STRING_PKCS8 "-----";
749
750 return TEST_FL_strn_eq(data, expected_pem_header,
751 sizeof(expected_pem_header) - 1);
752 }
753
test_protected_via_PEM(const char * type,EVP_PKEY * key,int fips)754 static int test_protected_via_PEM(const char *type, EVP_PKEY *key, int fips)
755 {
756 return test_encode_decode(__FILE__, __LINE__, type, key,
757 OSSL_KEYMGMT_SELECT_KEYPAIR
758 | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
759 "PEM", "EncryptedPrivateKeyInfo",
760 pass, pass_cipher,
761 encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
762 test_text, check_protected_PKCS8_PEM,
763 dump_pem, fips ? 0 : FLAG_FAIL_IF_FIPS);
764 }
765
check_protected_legacy_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)766 static int check_protected_legacy_PEM(const char *file, const int line,
767 const char *type,
768 const void *data, size_t data_len)
769 {
770 static char expected_pem_header[80];
771
772 return TEST_FL_int_gt(BIO_snprintf(expected_pem_header,
773 sizeof(expected_pem_header),
774 "-----BEGIN %s PRIVATE KEY-----", type),
775 0)
776 && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header))
777 && TEST_FL_ptr(strstr(data, "\nDEK-Info: "));
778 }
779
test_protected_via_legacy_PEM(const char * type,EVP_PKEY * key)780 static int test_protected_via_legacy_PEM(const char *type, EVP_PKEY *key)
781 {
782 if (!default_libctx || is_fips)
783 return TEST_skip("Test not available if using a non-default library context or FIPS provider");
784
785 return test_encode_decode(__FILE__, __LINE__, type, key,
786 OSSL_KEYMGMT_SELECT_KEYPAIR
787 | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
788 "PEM", "type-specific", pass, pass_cipher,
789 encode_EVP_PKEY_legacy_PEM, decode_EVP_PKEY_prov,
790 test_text, check_protected_legacy_PEM,
791 dump_pem, 0);
792 }
793
794 #ifndef OPENSSL_NO_RC4
test_protected_via_PVK(const char * type,EVP_PKEY * key)795 static int test_protected_via_PVK(const char *type, EVP_PKEY *key)
796 {
797 int ret = 0;
798 OSSL_PROVIDER *lgcyprov = OSSL_PROVIDER_load(testctx, "legacy");
799 if (lgcyprov == NULL)
800 return TEST_skip("Legacy provider not available");
801
802 ret = test_encode_decode(__FILE__, __LINE__, type, key,
803 OSSL_KEYMGMT_SELECT_KEYPAIR
804 | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
805 "PVK", NULL, pass, NULL,
806 encode_EVP_PKEY_PVK, decode_EVP_PKEY_prov,
807 test_mem, check_PVK, dump_der, 0);
808 OSSL_PROVIDER_unload(lgcyprov);
809 return ret;
810 }
811 #endif
812
check_public_DER(const char * file,const int line,const char * type,const void * data,size_t data_len)813 static int check_public_DER(const char *file, const int line,
814 const char *type, const void *data, size_t data_len)
815 {
816 const unsigned char *datap = data;
817 EVP_PKEY *pkey = d2i_PUBKEY_ex(NULL, &datap, data_len, testctx, testpropq);
818 int ok = (TEST_FL_ptr(pkey) && TEST_FL_true(EVP_PKEY_is_a(pkey, type)));
819
820 EVP_PKEY_free(pkey);
821 return ok;
822 }
823
test_public_via_DER(const char * type,EVP_PKEY * key,int fips)824 static int test_public_via_DER(const char *type, EVP_PKEY *key, int fips)
825 {
826 return test_encode_decode(__FILE__, __LINE__, type, key,
827 OSSL_KEYMGMT_SELECT_PUBLIC_KEY
828 | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
829 "DER", "SubjectPublicKeyInfo", NULL, NULL,
830 encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
831 test_mem, check_public_DER, dump_der,
832 fips ? 0 : FLAG_FAIL_IF_FIPS);
833 }
834
check_public_PEM(const char * file,const int line,const char * type,const void * data,size_t data_len)835 static int check_public_PEM(const char *file, const int line,
836 const char *type, const void *data, size_t data_len)
837 {
838 static const char expected_pem_header[] = "-----BEGIN " PEM_STRING_PUBLIC "-----";
839
840 return TEST_FL_strn_eq(data, expected_pem_header,
841 sizeof(expected_pem_header) - 1);
842 }
843
test_public_via_PEM(const char * type,EVP_PKEY * key,int fips)844 static int test_public_via_PEM(const char *type, EVP_PKEY *key, int fips)
845 {
846 return test_encode_decode(__FILE__, __LINE__, type, key,
847 OSSL_KEYMGMT_SELECT_PUBLIC_KEY
848 | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
849 "PEM", "SubjectPublicKeyInfo", NULL, NULL,
850 encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
851 test_text, check_public_PEM, dump_pem,
852 fips ? 0 : FLAG_FAIL_IF_FIPS);
853 }
854
check_public_MSBLOB(const char * file,const int line,const char * type,const void * data,size_t data_len)855 static int check_public_MSBLOB(const char *file, const int line,
856 const char *type,
857 const void *data, size_t data_len)
858 {
859 const unsigned char *datap = data;
860 EVP_PKEY *pkey = b2i_PublicKey(&datap, data_len);
861 int ok = TEST_FL_ptr(pkey);
862
863 EVP_PKEY_free(pkey);
864 return ok;
865 }
866
test_public_via_MSBLOB(const char * type,EVP_PKEY * key)867 static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
868 {
869 return test_encode_decode(__FILE__, __LINE__, type, key, OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS,
870 "MSBLOB", NULL, NULL, NULL,
871 encode_EVP_PKEY_MSBLOB, decode_EVP_PKEY_prov,
872 test_mem, check_public_MSBLOB, dump_der, 0);
873 }
874
875 /*
876 * Build a public-only EVP_PKEY of the same algorithm as |src| by
877 * round-tripping the public component through OSSL_PARAMs.
878 */
make_public_only_copy(EVP_PKEY * src)879 static EVP_PKEY *make_public_only_copy(EVP_PKEY *src)
880 {
881 OSSL_PARAM *params = NULL;
882 EVP_PKEY_CTX *cctx = NULL;
883 EVP_PKEY *pub = NULL;
884
885 if (!EVP_PKEY_todata(src, EVP_PKEY_PUBLIC_KEY, ¶ms))
886 goto end;
887 if ((cctx = EVP_PKEY_CTX_new_from_pkey(NULL, src, NULL)) == NULL
888 || EVP_PKEY_fromdata_init(cctx) <= 0
889 || EVP_PKEY_fromdata(cctx, &pub, EVP_PKEY_PUBLIC_KEY, params) <= 0) {
890 EVP_PKEY_free(pub);
891 pub = NULL;
892 }
893 end:
894 OSSL_PARAM_free(params);
895 EVP_PKEY_CTX_free(cctx);
896 return pub;
897 }
898
899 /*
900 * Build an "embryonic" EVP_PKEY of the same algorithm as |src|: just
901 * the keymgmt-bound type and (where applicable) domain parameters,
902 * with no key material. Mirrors the idiom used in
903 * test/ml_kem_evp_extra_test.c.
904 */
make_embryonic_copy(EVP_PKEY * src)905 static EVP_PKEY *make_embryonic_copy(EVP_PKEY *src)
906 {
907 EVP_PKEY *embryo = EVP_PKEY_new();
908
909 if (embryo == NULL)
910 return NULL;
911 if (EVP_PKEY_copy_parameters(embryo, src) <= 0) {
912 EVP_PKEY_free(embryo);
913 return NULL;
914 }
915 return embryo;
916 }
917
918 /*
919 * Check that EVP_PKEY_dup() works for every supported provider-backed
920 * key type, and that the duplicate compares equal to the original.
921 *
922 * Exercised in three shapes:
923 * 1. The full keypair |key| (typically pub + priv).
924 * 2. A public-only key derived from |key|.
925 * 3. An "embryonic" key (algorithm + domain parameters only, no key
926 * material) produced with EVP_PKEY_copy_parameters(). Not every
927 * keymgmt allows building such a key (RSA's dup refuses any
928 * selection without keypair bits); when EVP_PKEY_copy_parameters
929 * fails we skip this arm with a TEST_info().
930 */
test_dup(const char * type,EVP_PKEY * key)931 static int test_dup(const char *type, EVP_PKEY *key)
932 {
933 EVP_PKEY *dup = NULL;
934 EVP_PKEY *pub_only = NULL;
935 EVP_PKEY *embryo = NULL;
936 int ok = 0;
937
938 if (!TEST_ptr(key)) {
939 TEST_info("%s: no source key", type);
940 return 0;
941 }
942
943 /* 1. Dup the full keypair. */
944 if (!TEST_ptr(dup = EVP_PKEY_dup(key))) {
945 TEST_info("%s: EVP_PKEY_dup of keypair returned NULL", type);
946 goto end;
947 }
948 if (!TEST_int_eq(EVP_PKEY_eq(key, dup), 1)) {
949 TEST_info("%s: keypair dup does not compare equal to original", type);
950 goto end;
951 }
952 EVP_PKEY_free(dup);
953 dup = NULL;
954
955 /* 2. Dup a public-only copy of the same key. */
956 if (!TEST_ptr(pub_only = make_public_only_copy(key))) {
957 TEST_info("%s: could not derive a public-only key", type);
958 goto end;
959 }
960 if (!TEST_ptr(dup = EVP_PKEY_dup(pub_only))) {
961 TEST_info("%s: EVP_PKEY_dup of public-only key returned NULL", type);
962 goto end;
963 }
964 if (!TEST_int_eq(EVP_PKEY_eq(pub_only, dup), 1)) {
965 TEST_info("%s: public-only dup does not compare equal to original",
966 type);
967 goto end;
968 }
969 EVP_PKEY_free(dup);
970 dup = NULL;
971
972 /*
973 * 3. Dup an embryonic key. EVP_PKEY_parameters_eq() answers 1 for
974 * algorithms with real domain parameters and may answer -2 ("nothing
975 * to compare") for those without. We only reject 0 (definitively
976 * unequal) and -1 (different keymgmts).
977 */
978 embryo = make_embryonic_copy(key);
979 if (embryo != NULL) {
980 if (!TEST_ptr(dup = EVP_PKEY_dup(embryo))) {
981 TEST_info("%s: EVP_PKEY_dup of embryonic key returned NULL",
982 type);
983 goto end;
984 }
985 {
986 int eq = EVP_PKEY_parameters_eq(embryo, dup);
987
988 if (!TEST_true(eq == 1 || eq == -2)) {
989 TEST_info("%s: embryonic dup parameters_eq %d (want 1 or -2)",
990 type, eq);
991 goto end;
992 }
993 }
994 } else {
995 TEST_info("%s: skipping embryonic dup (no params-only key shape)",
996 type);
997 }
998
999 ok = 1;
1000 end:
1001 EVP_PKEY_free(dup);
1002 EVP_PKEY_free(pub_only);
1003 EVP_PKEY_free(embryo);
1004 return ok;
1005 }
1006
1007 /*
1008 * Drive EVP_PKEY_fromdata with the supplied OSSL_PARAM[] (NULL =
1009 * empty array) for the given selection. Either outcome is accepted:
1010 * fromdata may reject the input, or it may succeed and yield a key
1011 * with at most algorithm-bound parameters. In the success case a
1012 * battery of common consumer ops must not crash on the resulting
1013 * key; their return values are not asserted.
1014 */
run_empty_fromdata_probe(const char * type,EVP_PKEY_CTX * cctx,int selection,OSSL_PARAM * params,const char * selname)1015 static int run_empty_fromdata_probe(const char *type, EVP_PKEY_CTX *cctx,
1016 int selection, OSSL_PARAM *params, const char *selname)
1017 {
1018 EVP_PKEY *pkey = NULL;
1019 OSSL_PARAM empty[1];
1020 int r;
1021 int ok = 0;
1022
1023 if (params == NULL) {
1024 empty[0] = OSSL_PARAM_construct_end();
1025 params = empty;
1026 }
1027
1028 if (!TEST_int_gt(EVP_PKEY_fromdata_init(cctx), 0)) {
1029 TEST_info("%s: fromdata_init failed (%s)", type, selname);
1030 goto end;
1031 }
1032 r = EVP_PKEY_fromdata(cctx, &pkey, selection, params);
1033 if (r <= 0) {
1034 /* Rejection is fine, but the out-pointer must remain NULL. */
1035 if (!TEST_ptr_null(pkey)) {
1036 TEST_info("%s: fromdata returned %d but pkey != NULL (%s)",
1037 type, r, selname);
1038 goto end;
1039 }
1040 ok = 1;
1041 goto end;
1042 }
1043 if (!TEST_ptr(pkey)) {
1044 TEST_info("%s: fromdata returned %d but pkey == NULL (%s)",
1045 type, r, selname);
1046 goto end;
1047 }
1048 /*
1049 * Walk a battery of common consumer ops on the resulting key.
1050 * Their return values are not asserted - a contentless key may
1051 * fail every op - only crashing is forbidden.
1052 */
1053 (void)EVP_PKEY_get_bits(pkey);
1054 (void)EVP_PKEY_get_security_bits(pkey);
1055 (void)EVP_PKEY_get_size(pkey);
1056 (void)EVP_PKEY_eq(pkey, pkey);
1057 (void)EVP_PKEY_parameters_eq(pkey, pkey);
1058 {
1059 OSSL_PARAM *out = NULL;
1060
1061 if (EVP_PKEY_todata(pkey, selection, &out) > 0)
1062 OSSL_PARAM_free(out);
1063 }
1064 {
1065 EVP_PKEY *clone = EVP_PKEY_dup(pkey);
1066
1067 EVP_PKEY_free(clone);
1068 }
1069 {
1070 BIO *bio = BIO_new(BIO_s_null());
1071
1072 if (bio != NULL) {
1073 (void)EVP_PKEY_print_public(bio, pkey, 0, NULL);
1074 (void)EVP_PKEY_print_private(bio, pkey, 0, NULL);
1075 (void)EVP_PKEY_print_params(bio, pkey, 0, NULL);
1076 BIO_free(bio);
1077 }
1078 }
1079 {
1080 /* The param/public/private/pairwise check family. */
1081 EVP_PKEY_CTX *vctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
1082
1083 if (vctx != NULL) {
1084 (void)EVP_PKEY_param_check(vctx);
1085 (void)EVP_PKEY_param_check_quick(vctx);
1086 (void)EVP_PKEY_public_check(vctx);
1087 (void)EVP_PKEY_public_check_quick(vctx);
1088 (void)EVP_PKEY_private_check(vctx);
1089 (void)EVP_PKEY_pairwise_check(vctx);
1090 EVP_PKEY_CTX_free(vctx);
1091 }
1092 }
1093 ok = 1;
1094 end:
1095 EVP_PKEY_free(pkey);
1096 return ok;
1097 }
1098
probe_empty_fromdata(const char * type,EVP_PKEY * prototype,int selection,const char * selname)1099 static int probe_empty_fromdata(const char *type, EVP_PKEY *prototype,
1100 int selection, const char *selname)
1101 {
1102 EVP_PKEY_CTX *cctx = NULL;
1103 int ok = 0;
1104
1105 if (!TEST_ptr(cctx = EVP_PKEY_CTX_new_from_pkey(NULL, prototype, NULL))) {
1106 TEST_info("%s: CTX alloc failed for empty fromdata (%s)",
1107 type, selname);
1108 goto end;
1109 }
1110 ok = run_empty_fromdata_probe(type, cctx, selection, NULL, selname);
1111 end:
1112 EVP_PKEY_CTX_free(cctx);
1113 return ok;
1114 }
1115
1116 /*
1117 * Drive EVP_PKEY_fromdata with an empty OSSL_PARAM[] for both
1118 * EVP_PKEY_PUBLIC_KEY and EVP_PKEY_KEYPAIR selections. Either
1119 * outcome is acceptable: fromdata rejects, or it succeeds and the
1120 * resulting key survives the consumer-op battery without crashing.
1121 */
test_fromdata(const char * type,EVP_PKEY * prototype)1122 static int test_fromdata(const char *type, EVP_PKEY *prototype)
1123 {
1124 if (!TEST_ptr(prototype)) {
1125 TEST_info("%s: no prototype key", type);
1126 return 0;
1127 }
1128 if (!probe_empty_fromdata(type, prototype, EVP_PKEY_PUBLIC_KEY,
1129 "EVP_PKEY_PUBLIC_KEY"))
1130 return 0;
1131 if (!probe_empty_fromdata(type, prototype, EVP_PKEY_KEYPAIR,
1132 "EVP_PKEY_KEYPAIR"))
1133 return 0;
1134 return 1;
1135 }
1136
1137 /*
1138 * Named-group-only partial-shape variants for prototype-matrix
1139 * algorithms, plus any keymgmts without a keygen path. Each entry
1140 * is one (name, selection, params-builder) shape; a NULL builder
1141 * means "use an empty OSSL_PARAM[]". Algorithms not loadable under
1142 * the active provider set are silently skipped.
1143 */
1144 typedef int (*fromdata_shape_build_fn)(OSSL_PARAM_BLD *bld);
1145
1146 struct fromdata_shape {
1147 const char *name; /* keymgmt algorithm name */
1148 int selection; /* EVP_PKEY_PUBLIC_KEY / KEYPAIR / etc. */
1149 fromdata_shape_build_fn build; /* NULL -> empty OSSL_PARAM[] */
1150 const char *label; /* diagnostic label */
1151 };
1152
1153 #ifndef OPENSSL_NO_DH
build_dh_named_group(OSSL_PARAM_BLD * bld)1154 static int build_dh_named_group(OSSL_PARAM_BLD *bld)
1155 {
1156 return OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1157 "ffdhe2048", 0);
1158 }
1159 #endif
1160
1161 #ifndef OPENSSL_NO_EC
build_ec_named_group(OSSL_PARAM_BLD * bld)1162 static int build_ec_named_group(OSSL_PARAM_BLD *bld)
1163 {
1164 return OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1165 "P-256", 0);
1166 }
1167 #ifndef OPENSSL_NO_SM2
build_sm2_named_group(OSSL_PARAM_BLD * bld)1168 static int build_sm2_named_group(OSSL_PARAM_BLD *bld)
1169 {
1170 return OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_PKEY_PARAM_GROUP_NAME,
1171 "SM2", 0);
1172 }
1173 #endif
1174 #endif
1175
1176 #if defined(OPENSSL_NO_DH) && defined(OPENSSL_NO_EC) && defined(OPENSSL_NO_SM2)
1177 #undef TEST_FROMDATA_NO_KEYGEN
1178 #else
1179 #define TEST_FROMDATA_NO_KEYGEN
1180
1181 static const struct fromdata_shape no_keygen_shapes[] = {
1182 /* Named-group-only partial shapes. */
1183 #ifndef OPENSSL_NO_DH
1184 { "DH", EVP_PKEY_KEYPAIR, build_dh_named_group,
1185 "DH / named group only / KEYPAIR" },
1186 { "DH", EVP_PKEY_PUBLIC_KEY, build_dh_named_group,
1187 "DH / named group only / PUBLIC_KEY" },
1188 #endif
1189 #ifndef OPENSSL_NO_EC
1190 { "EC", EVP_PKEY_KEYPAIR, build_ec_named_group,
1191 "EC / group only / KEYPAIR" },
1192 { "EC", EVP_PKEY_PUBLIC_KEY, build_ec_named_group,
1193 "EC / group only / PUBLIC_KEY" },
1194 #ifndef OPENSSL_NO_SM2
1195 { "SM2", EVP_PKEY_KEYPAIR, build_sm2_named_group,
1196 "SM2 / group only / KEYPAIR" },
1197 #endif
1198 #endif
1199 };
1200
1201 /*
1202 * Probe an algorithm by name rather than a prototype key, for keymgmts without
1203 * a keygen path. Algorithms not loadable under the active provider set are
1204 * silently skipped. |params| may be NULL (= empty OSSL_PARAM[]) or a
1205 * caller-built partial array.
1206 */
probe_fromdata_by_name(const char * name,int selection,OSSL_PARAM * params,const char * selname)1207 static int probe_fromdata_by_name(const char *name, int selection,
1208 OSSL_PARAM *params, const char *selname)
1209 {
1210 EVP_PKEY_CTX *cctx = NULL;
1211 int ok = 1;
1212
1213 cctx = EVP_PKEY_CTX_new_from_name(NULL, name, NULL);
1214 if (cctx == NULL)
1215 return 1;
1216 ok = run_empty_fromdata_probe(name, cctx, selection, params, selname);
1217 EVP_PKEY_CTX_free(cctx);
1218 return ok;
1219 }
1220
test_fromdata_no_keygen(void)1221 static int test_fromdata_no_keygen(void)
1222 {
1223 size_t i;
1224
1225 for (i = 0; i < OSSL_NELEM(no_keygen_shapes); i++) {
1226 const struct fromdata_shape *s = &no_keygen_shapes[i];
1227 OSSL_PARAM_BLD *bld = NULL;
1228 OSSL_PARAM *params = NULL;
1229 int ok;
1230
1231 if (s->build != NULL) {
1232 if (!TEST_ptr(bld = OSSL_PARAM_BLD_new()))
1233 return 0;
1234 if (!s->build(bld)) {
1235 TEST_info("%s: builder failed", s->label);
1236 OSSL_PARAM_BLD_free(bld);
1237 return 0;
1238 }
1239 params = OSSL_PARAM_BLD_to_param(bld);
1240 if (!TEST_ptr(params)) {
1241 OSSL_PARAM_BLD_free(bld);
1242 return 0;
1243 }
1244 }
1245 ok = probe_fromdata_by_name(s->name, s->selection, params, s->label);
1246 OSSL_PARAM_free(params);
1247 OSSL_PARAM_BLD_free(bld);
1248 if (!ok)
1249 return 0;
1250 }
1251 return 1;
1252 }
1253 #endif
1254
1255 #define KEYS(KEYTYPE) \
1256 static EVP_PKEY *key_##KEYTYPE = NULL
1257 #define MAKE_KEYS(KEYTYPE, KEYTYPEstr, params) \
1258 ok &= TEST_ptr(key_##KEYTYPE = make_key(KEYTYPEstr, NULL, params))
1259 #define FREE_KEYS(KEYTYPE) \
1260 EVP_PKEY_free(key_##KEYTYPE);
1261
1262 #define DOMAIN_KEYS(KEYTYPE) \
1263 static EVP_PKEY *template_##KEYTYPE = NULL; \
1264 static EVP_PKEY *key_##KEYTYPE = NULL
1265 #define MAKE_DOMAIN_KEYS(KEYTYPE, KEYTYPEstr, params) \
1266 do { \
1267 ok &= TEST_ptr(template_##KEYTYPE = make_template(KEYTYPEstr, \
1268 params)); \
1269 ok &= TEST_ptr(key_##KEYTYPE = make_key(KEYTYPEstr, \
1270 template_##KEYTYPE, NULL)); \
1271 } while (0)
1272 #define FREE_DOMAIN_KEYS(KEYTYPE) \
1273 EVP_PKEY_free(template_##KEYTYPE); \
1274 EVP_PKEY_free(key_##KEYTYPE)
1275
1276 #define IMPLEMENT_TEST_SUITE(KEYTYPE, KEYTYPEstr, fips) \
1277 static int test_unprotected_##KEYTYPE##_via_DER(void) \
1278 { \
1279 return test_unprotected_via_DER(KEYTYPEstr, key_##KEYTYPE, fips); \
1280 } \
1281 static int test_unprotected_##KEYTYPE##_via_PEM(void) \
1282 { \
1283 return test_unprotected_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips); \
1284 } \
1285 static int test_protected_##KEYTYPE##_via_DER(void) \
1286 { \
1287 return test_protected_via_DER(KEYTYPEstr, key_##KEYTYPE, fips); \
1288 } \
1289 static int test_protected_##KEYTYPE##_via_PEM(void) \
1290 { \
1291 return test_protected_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips); \
1292 } \
1293 static int test_public_##KEYTYPE##_via_DER(void) \
1294 { \
1295 return test_public_via_DER(KEYTYPEstr, key_##KEYTYPE, fips); \
1296 } \
1297 static int test_public_##KEYTYPE##_via_PEM(void) \
1298 { \
1299 return test_public_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips); \
1300 } \
1301 static int test_dup_##KEYTYPE(void) \
1302 { \
1303 return test_dup(KEYTYPEstr, key_##KEYTYPE); \
1304 } \
1305 static int test_fromdata_##KEYTYPE(void) \
1306 { \
1307 return test_fromdata(KEYTYPEstr, key_##KEYTYPE); \
1308 }
1309
1310 #define ADD_TEST_SUITE(KEYTYPE) \
1311 do { \
1312 if (key_##KEYTYPE != NULL) { \
1313 ADD_TEST(test_unprotected_##KEYTYPE##_via_DER); \
1314 ADD_TEST(test_unprotected_##KEYTYPE##_via_PEM); \
1315 ADD_TEST(test_protected_##KEYTYPE##_via_DER); \
1316 ADD_TEST(test_protected_##KEYTYPE##_via_PEM); \
1317 ADD_TEST(test_public_##KEYTYPE##_via_DER); \
1318 ADD_TEST(test_public_##KEYTYPE##_via_PEM); \
1319 ADD_TEST(test_dup_##KEYTYPE); \
1320 ADD_TEST(test_fromdata_##KEYTYPE); \
1321 } \
1322 } while (0)
1323
1324 #define IMPLEMENT_TEST_SUITE_PARAMS(KEYTYPE, KEYTYPEstr) \
1325 static int test_params_##KEYTYPE##_via_DER(void) \
1326 { \
1327 return test_params_via_DER(KEYTYPEstr, key_##KEYTYPE); \
1328 } \
1329 static int test_params_##KEYTYPE##_via_PEM(void) \
1330 { \
1331 return test_params_via_PEM(KEYTYPEstr, key_##KEYTYPE); \
1332 }
1333
1334 #define ADD_TEST_SUITE_PARAMS(KEYTYPE) \
1335 do { \
1336 if (key_##KEYTYPE != NULL) { \
1337 ADD_TEST(test_params_##KEYTYPE##_via_DER); \
1338 ADD_TEST(test_params_##KEYTYPE##_via_PEM); \
1339 } \
1340 } while (0)
1341
1342 #define IMPLEMENT_TEST_SUITE_LEGACY(KEYTYPE, KEYTYPEstr) \
1343 static int test_unprotected_##KEYTYPE##_via_legacy_PEM(void) \
1344 { \
1345 return test_unprotected_via_legacy_PEM(KEYTYPEstr, key_##KEYTYPE); \
1346 } \
1347 static int test_protected_##KEYTYPE##_via_legacy_PEM(void) \
1348 { \
1349 return test_protected_via_legacy_PEM(KEYTYPEstr, key_##KEYTYPE); \
1350 }
1351
1352 #define ADD_TEST_SUITE_LEGACY(KEYTYPE) \
1353 do { \
1354 if (key_##KEYTYPE != NULL) { \
1355 ADD_TEST(test_unprotected_##KEYTYPE##_via_legacy_PEM); \
1356 ADD_TEST(test_protected_##KEYTYPE##_via_legacy_PEM); \
1357 } \
1358 } while (0)
1359
1360 #define IMPLEMENT_TEST_SUITE_MSBLOB(KEYTYPE, KEYTYPEstr) \
1361 static int test_unprotected_##KEYTYPE##_via_MSBLOB(void) \
1362 { \
1363 return test_unprotected_via_MSBLOB(KEYTYPEstr, key_##KEYTYPE); \
1364 } \
1365 static int test_public_##KEYTYPE##_via_MSBLOB(void) \
1366 { \
1367 return test_public_via_MSBLOB(KEYTYPEstr, key_##KEYTYPE); \
1368 }
1369
1370 #define ADD_TEST_SUITE_MSBLOB(KEYTYPE) \
1371 do { \
1372 if (key_##KEYTYPE != NULL) { \
1373 ADD_TEST(test_unprotected_##KEYTYPE##_via_MSBLOB); \
1374 ADD_TEST(test_public_##KEYTYPE##_via_MSBLOB); \
1375 } \
1376 } while (0)
1377
1378 #define IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(KEYTYPE, KEYTYPEstr) \
1379 static int test_unprotected_##KEYTYPE##_via_PVK(void) \
1380 { \
1381 return test_unprotected_via_PVK(KEYTYPEstr, key_##KEYTYPE); \
1382 }
1383 #define ADD_TEST_SUITE_UNPROTECTED_PVK(KEYTYPE) \
1384 do { \
1385 if (key_##KEYTYPE != NULL) \
1386 ADD_TEST(test_unprotected_##KEYTYPE##_via_PVK); \
1387 } while (0)
1388 #ifndef OPENSSL_NO_RC4
1389 #define IMPLEMENT_TEST_SUITE_PROTECTED_PVK(KEYTYPE, KEYTYPEstr) \
1390 static int test_protected_##KEYTYPE##_via_PVK(void) \
1391 { \
1392 return test_protected_via_PVK(KEYTYPEstr, key_##KEYTYPE); \
1393 }
1394 #define ADD_TEST_SUITE_PROTECTED_PVK(KEYTYPE) \
1395 do { \
1396 if (key_##KEYTYPE != NULL) \
1397 ADD_TEST(test_protected_##KEYTYPE##_via_PVK); \
1398 } while (0)
1399 #endif
1400
1401 #ifndef OPENSSL_NO_DH
1402 DOMAIN_KEYS(DH);
1403 IMPLEMENT_TEST_SUITE(DH, "DH", 1)
1404 IMPLEMENT_TEST_SUITE_PARAMS(DH, "DH")
1405 DOMAIN_KEYS(DHX);
1406 IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH", 1)
1407 IMPLEMENT_TEST_SUITE_PARAMS(DHX, "X9.42 DH")
1408 /*
1409 * DH has no support for PEM_write_bio_PrivateKey_traditional(),
1410 * so no legacy tests.
1411 */
1412 #endif
1413 #ifndef OPENSSL_NO_DSA
1414 DOMAIN_KEYS(DSA);
1415 IMPLEMENT_TEST_SUITE(DSA, "DSA", 1)
1416 IMPLEMENT_TEST_SUITE_PARAMS(DSA, "DSA")
1417 IMPLEMENT_TEST_SUITE_LEGACY(DSA, "DSA")
1418 IMPLEMENT_TEST_SUITE_MSBLOB(DSA, "DSA")
1419 IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(DSA, "DSA")
1420 #ifndef OPENSSL_NO_RC4
1421 IMPLEMENT_TEST_SUITE_PROTECTED_PVK(DSA, "DSA")
1422 #endif
1423 #endif
1424 #ifndef OPENSSL_NO_EC
1425 DOMAIN_KEYS(EC);
1426 IMPLEMENT_TEST_SUITE(EC, "EC", 1)
1427 IMPLEMENT_TEST_SUITE_PARAMS(EC, "EC")
1428 IMPLEMENT_TEST_SUITE_LEGACY(EC, "EC")
1429 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
1430 DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
1431 IMPLEMENT_TEST_SUITE(ECExplicitPrimeNamedCurve, "EC", 1)
1432 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve, "EC")
1433 DOMAIN_KEYS(ECExplicitPrime2G);
1434 IMPLEMENT_TEST_SUITE(ECExplicitPrime2G, "EC", 0)
1435 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrime2G, "EC")
1436 #ifndef OPENSSL_NO_EC2M
1437 DOMAIN_KEYS(ECExplicitTriNamedCurve);
1438 IMPLEMENT_TEST_SUITE(ECExplicitTriNamedCurve, "EC", 1)
1439 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitTriNamedCurve, "EC")
1440 DOMAIN_KEYS(ECExplicitTri2G);
1441 IMPLEMENT_TEST_SUITE(ECExplicitTri2G, "EC", 0)
1442 IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitTri2G, "EC")
1443 #endif
1444 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
1445 #ifndef OPENSSL_NO_SM2
1446 KEYS(SM2);
1447 IMPLEMENT_TEST_SUITE(SM2, "SM2", 0)
1448 #endif
1449 #endif
1450 #ifndef OPENSSL_NO_ECX
1451 /*
1452 * ED25519, ED448, X25519 and X448 have no support for
1453 * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
1454 */
1455 KEYS(ED25519);
1456 IMPLEMENT_TEST_SUITE(ED25519, "ED25519", 1)
1457 KEYS(ED448);
1458 IMPLEMENT_TEST_SUITE(ED448, "ED448", 1)
1459 KEYS(X25519);
1460 IMPLEMENT_TEST_SUITE(X25519, "X25519", 1)
1461 KEYS(X448);
1462 IMPLEMENT_TEST_SUITE(X448, "X448", 1)
1463 #endif
1464 #ifndef OPENSSL_NO_ML_KEM
1465 /*
1466 * ML-KEM has no support for PEM_write_bio_PrivateKey_traditional(), so no
1467 * legacy tests.
1468 */
1469 KEYS(ML_KEM_512);
1470 IMPLEMENT_TEST_SUITE(ML_KEM_512, "ML-KEM-512", 1)
1471 KEYS(ML_KEM_768);
1472 IMPLEMENT_TEST_SUITE(ML_KEM_768, "ML-KEM-768", 1)
1473 KEYS(ML_KEM_1024);
1474 IMPLEMENT_TEST_SUITE(ML_KEM_1024, "ML-KEM-1024", 1)
1475 #endif
1476 #ifndef OPENSSL_NO_SLH_DSA
1477 KEYS(SLH_DSA_SHA2_128s);
1478 KEYS(SLH_DSA_SHA2_128f);
1479 KEYS(SLH_DSA_SHA2_192s);
1480 KEYS(SLH_DSA_SHA2_192f);
1481 KEYS(SLH_DSA_SHA2_256s);
1482 KEYS(SLH_DSA_SHA2_256f);
1483 KEYS(SLH_DSA_SHAKE_128s);
1484 KEYS(SLH_DSA_SHAKE_128f);
1485 KEYS(SLH_DSA_SHAKE_192s);
1486 KEYS(SLH_DSA_SHAKE_192f);
1487 KEYS(SLH_DSA_SHAKE_256s);
1488 KEYS(SLH_DSA_SHAKE_256f);
1489 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_128s, "SLH-DSA-SHA2-128s", 1)
1490 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_128f, "SLH-DSA-SHA2-128f", 1)
1491 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_192s, "SLH-DSA-SHA2-192s", 1)
1492 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_192f, "SLH-DSA-SHA2-192f", 1)
1493 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_256s, "SLH-DSA-SHA2-256s", 1)
1494 IMPLEMENT_TEST_SUITE(SLH_DSA_SHA2_256f, "SLH-DSA-SHA2-256f", 1)
1495 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_128s, "SLH-DSA-SHAKE-128s", 1)
1496 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_128f, "SLH-DSA-SHAKE-128f", 1)
1497 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_192s, "SLH-DSA-SHAKE-192s", 1)
1498 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_192f, "SLH-DSA-SHAKE-192f", 1)
1499 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_256s, "SLH-DSA-SHAKE-256s", 1)
1500 IMPLEMENT_TEST_SUITE(SLH_DSA_SHAKE_256f, "SLH-DSA-SHAKE-256f", 1)
1501 #endif /* OPENSSL_NO_SLH_DSA */
1502 KEYS(RSA);
1503 IMPLEMENT_TEST_SUITE(RSA, "RSA", 1)
1504 IMPLEMENT_TEST_SUITE_LEGACY(RSA, "RSA")
1505 KEYS(RSA_PSS);
1506 IMPLEMENT_TEST_SUITE(RSA_PSS, "RSA-PSS", 1)
1507 /*
1508 * RSA-PSS has no support for PEM_write_bio_PrivateKey_traditional(),
1509 * so no legacy tests.
1510 */
1511 IMPLEMENT_TEST_SUITE_MSBLOB(RSA, "RSA")
1512 IMPLEMENT_TEST_SUITE_UNPROTECTED_PVK(RSA, "RSA")
1513 #ifndef OPENSSL_NO_RC4
1514 IMPLEMENT_TEST_SUITE_PROTECTED_PVK(RSA, "RSA")
1515 #endif
1516
1517 #ifndef OPENSSL_NO_ML_DSA
1518 KEYS(ML_DSA_44);
1519 KEYS(ML_DSA_65);
1520 KEYS(ML_DSA_87);
1521 IMPLEMENT_TEST_SUITE(ML_DSA_44, "ML-DSA-44", 1)
1522 IMPLEMENT_TEST_SUITE(ML_DSA_65, "ML-DSA-65", 1)
1523 IMPLEMENT_TEST_SUITE(ML_DSA_87, "ML-DSA-87", 1)
1524 #endif /* OPENSSL_NO_ML_DSA */
1525
1526 #ifndef OPENSSL_NO_EC
1527 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
1528 /* 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)1529 static int do_create_ec_explicit_prime_params(OSSL_PARAM_BLD *bld,
1530 const unsigned char *gen,
1531 size_t gen_len)
1532 {
1533 BIGNUM *a, *b, *prime, *order;
1534
1535 /* Curve prime256v1 */
1536 static const unsigned char prime_data[] = {
1537 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
1538 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1539 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
1540 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1541 0xff
1542 };
1543 static const unsigned char a_data[] = {
1544 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
1545 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1546 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
1547 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1548 0xfc
1549 };
1550 static const unsigned char b_data[] = {
1551 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7,
1552 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc,
1553 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6,
1554 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b
1555 };
1556 static const unsigned char seed[] = {
1557 0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93,
1558 0x6a, 0x66, 0x78, 0xe1, 0x13, 0x9d, 0x26, 0xb7,
1559 0x81, 0x9f, 0x7e, 0x90
1560 };
1561 static const unsigned char order_data[] = {
1562 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
1563 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1564 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e,
1565 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51
1566 };
1567 return TEST_ptr(a = BN_CTX_get(bnctx))
1568 && TEST_ptr(b = BN_CTX_get(bnctx))
1569 && TEST_ptr(prime = BN_CTX_get(bnctx))
1570 && TEST_ptr(order = BN_CTX_get(bnctx))
1571 && TEST_ptr(BN_bin2bn(prime_data, sizeof(prime_data), prime))
1572 && TEST_ptr(BN_bin2bn(a_data, sizeof(a_data), a))
1573 && TEST_ptr(BN_bin2bn(b_data, sizeof(b_data), b))
1574 && TEST_ptr(BN_bin2bn(order_data, sizeof(order_data), order))
1575 && TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
1576 OSSL_PKEY_PARAM_EC_FIELD_TYPE, SN_X9_62_prime_field,
1577 0))
1578 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, prime))
1579 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
1580 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b))
1581 && TEST_true(OSSL_PARAM_BLD_push_BN(bld,
1582 OSSL_PKEY_PARAM_EC_ORDER, order))
1583 && TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
1584 OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_len))
1585 && TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
1586 OSSL_PKEY_PARAM_EC_SEED, seed, sizeof(seed)))
1587 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
1588 BN_value_one()));
1589 }
1590
create_ec_explicit_prime_params_namedcurve(OSSL_PARAM_BLD * bld)1591 static int create_ec_explicit_prime_params_namedcurve(OSSL_PARAM_BLD *bld)
1592 {
1593 static const unsigned char prime256v1_gen[] = {
1594 0x04,
1595 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
1596 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2,
1597 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
1598 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
1599 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b,
1600 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
1601 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
1602 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5
1603 };
1604 return do_create_ec_explicit_prime_params(bld, prime256v1_gen,
1605 sizeof(prime256v1_gen));
1606 }
1607
create_ec_explicit_prime_params(OSSL_PARAM_BLD * bld)1608 static int create_ec_explicit_prime_params(OSSL_PARAM_BLD *bld)
1609 {
1610 /* 2G */
1611 static const unsigned char prime256v1_gen2[] = {
1612 0x04,
1613 0xe4, 0x97, 0x08, 0xbe, 0x7d, 0xfa, 0xa2, 0x9a,
1614 0xa3, 0x12, 0x6f, 0xe4, 0xe7, 0xd0, 0x25, 0xe3,
1615 0x4a, 0xc1, 0x03, 0x15, 0x8c, 0xd9, 0x33, 0xc6,
1616 0x97, 0x42, 0xf5, 0xdc, 0x97, 0xb9, 0xd7, 0x31,
1617 0xe9, 0x7d, 0x74, 0x3d, 0x67, 0x6a, 0x3b, 0x21,
1618 0x08, 0x9c, 0x31, 0x73, 0xf8, 0xc1, 0x27, 0xc9,
1619 0xd2, 0xa0, 0xa0, 0x83, 0x66, 0xe0, 0xc9, 0xda,
1620 0xa8, 0xc6, 0x56, 0x2b, 0x94, 0xb1, 0xae, 0x55
1621 };
1622 return do_create_ec_explicit_prime_params(bld, prime256v1_gen2,
1623 sizeof(prime256v1_gen2));
1624 }
1625
1626 #ifndef OPENSSL_NO_EC2M
do_create_ec_explicit_trinomial_params(OSSL_PARAM_BLD * bld,const unsigned char * gen,size_t gen_len)1627 static int do_create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld,
1628 const unsigned char *gen,
1629 size_t gen_len)
1630 {
1631 BIGNUM *a, *b, *poly, *order, *cofactor;
1632 /* sect233k1 characteristic-two-field tpBasis */
1633 static const unsigned char poly_data[] = {
1634 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1636 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
1637 };
1638 static const unsigned char a_data[] = {
1639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1642 };
1643 static const unsigned char b_data[] = {
1644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1646 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
1647 };
1648 static const unsigned char order_data[] = {
1649 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1650 0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15, 0xBC, 0xD4, 0x6E, 0xFB,
1651 0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF
1652 };
1653 static const unsigned char cofactor_data[] = {
1654 0x4
1655 };
1656 return TEST_ptr(a = BN_CTX_get(bnctx))
1657 && TEST_ptr(b = BN_CTX_get(bnctx))
1658 && TEST_ptr(poly = BN_CTX_get(bnctx))
1659 && TEST_ptr(order = BN_CTX_get(bnctx))
1660 && TEST_ptr(cofactor = BN_CTX_get(bnctx))
1661 && TEST_ptr(BN_bin2bn(poly_data, sizeof(poly_data), poly))
1662 && TEST_ptr(BN_bin2bn(a_data, sizeof(a_data), a))
1663 && TEST_ptr(BN_bin2bn(b_data, sizeof(b_data), b))
1664 && TEST_ptr(BN_bin2bn(order_data, sizeof(order_data), order))
1665 && TEST_ptr(BN_bin2bn(cofactor_data, sizeof(cofactor_data), cofactor))
1666 && TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
1667 OSSL_PKEY_PARAM_EC_FIELD_TYPE,
1668 SN_X9_62_characteristic_two_field, 0))
1669 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_P, poly))
1670 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_A, a))
1671 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_B, b))
1672 && TEST_true(OSSL_PARAM_BLD_push_BN(bld,
1673 OSSL_PKEY_PARAM_EC_ORDER, order))
1674 && TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
1675 OSSL_PKEY_PARAM_EC_GENERATOR, gen, gen_len))
1676 && TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_EC_COFACTOR,
1677 cofactor));
1678 }
1679
create_ec_explicit_trinomial_params_namedcurve(OSSL_PARAM_BLD * bld)1680 static int create_ec_explicit_trinomial_params_namedcurve(OSSL_PARAM_BLD *bld)
1681 {
1682 static const unsigned char gen[] = {
1683 0x04,
1684 0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, 0x29, 0xF2,
1685 0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2, 0x6B, 0xF5, 0x0A, 0x4C,
1686 0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26,
1687 0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, 0x55, 0x5A,
1688 0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A, 0xEB, 0x9B, 0x56, 0xE0,
1689 0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3
1690 };
1691 return do_create_ec_explicit_trinomial_params(bld, gen, sizeof(gen));
1692 }
1693
create_ec_explicit_trinomial_params(OSSL_PARAM_BLD * bld)1694 static int create_ec_explicit_trinomial_params(OSSL_PARAM_BLD *bld)
1695 {
1696 static const unsigned char gen2[] = {
1697 0x04,
1698 0x00, 0xd7, 0xba, 0xd0, 0x26, 0x6c, 0x31, 0x6a, 0x78, 0x76, 0x01, 0xd1,
1699 0x32, 0x4b, 0x8f, 0x30, 0x29, 0x2d, 0x78, 0x30, 0xca, 0x43, 0xaa, 0xf0,
1700 0xa2, 0x5a, 0xd4, 0x0f, 0xb3, 0xf4,
1701 0x00, 0x85, 0x4b, 0x1b, 0x8d, 0x50, 0x10, 0xa5, 0x1c, 0x80, 0xf7, 0x86,
1702 0x40, 0x62, 0x4c, 0x87, 0xd1, 0x26, 0x7a, 0x9c, 0x5c, 0xe9, 0x82, 0x29,
1703 0xd1, 0x67, 0x70, 0x41, 0xea, 0xcb
1704 };
1705 return do_create_ec_explicit_trinomial_params(bld, gen2, sizeof(gen2));
1706 }
1707 #endif /* OPENSSL_NO_EC2M */
1708 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
1709
1710 /*
1711 * Test that multiple calls to OSSL_ENCODER_to_data() do not cause side effects
1712 */
ec_encode_to_data_multi(void)1713 static int ec_encode_to_data_multi(void)
1714 {
1715 int ret;
1716 OSSL_ENCODER_CTX *ectx = NULL;
1717 EVP_PKEY *key = NULL;
1718 uint8_t *enc = NULL;
1719 size_t enc_len = 0;
1720
1721 ret = TEST_ptr(key = EVP_PKEY_Q_keygen(testctx, "", "EC", "P-256"))
1722 && TEST_ptr(ectx = OSSL_ENCODER_CTX_new_for_pkey(key, EVP_PKEY_KEYPAIR,
1723 "DER", NULL, NULL))
1724 && TEST_int_eq(OSSL_ENCODER_to_data(ectx, NULL, &enc_len), 1)
1725 && TEST_int_eq(OSSL_ENCODER_to_data(ectx, &enc, &enc_len), 1);
1726 OPENSSL_free(enc);
1727 EVP_PKEY_free(key);
1728 OSSL_ENCODER_CTX_free(ectx);
1729 return ret;
1730 }
1731 #endif /* OPENSSL_NO_EC */
1732
1733 typedef enum OPTION_choice {
1734 OPT_ERR = -1,
1735 OPT_EOF = 0,
1736 OPT_CONTEXT,
1737 OPT_RSA_FILE,
1738 OPT_RSA_PSS_FILE,
1739 OPT_CONFIG_FILE,
1740 OPT_PROVIDER_NAME,
1741 OPT_TEST_ENUM
1742 } OPTION_CHOICE;
1743
test_get_options(void)1744 const OPTIONS *test_get_options(void)
1745 {
1746 static const OPTIONS options[] = {
1747 OPT_TEST_OPTIONS_DEFAULT_USAGE,
1748 { "context", OPT_CONTEXT, '-',
1749 "Explicitly use a non-default library context" },
1750 { "rsa", OPT_RSA_FILE, '<',
1751 "PEM format RSA key file to encode/decode" },
1752 { "pss", OPT_RSA_PSS_FILE, '<',
1753 "PEM format RSA-PSS key file to encode/decode" },
1754 { "config", OPT_CONFIG_FILE, '<',
1755 "The configuration file to use for the library context" },
1756 { "provider", OPT_PROVIDER_NAME, 's',
1757 "The provider to load (The default value is 'default')" },
1758 { NULL }
1759 };
1760 return options;
1761 }
1762
setup_tests(void)1763 int setup_tests(void)
1764 {
1765 const char *rsa_file = NULL;
1766 const char *rsa_pss_file = NULL;
1767 const char *prov_name = "default";
1768 char *config_file = NULL;
1769 int ok = 1;
1770
1771 #ifndef OPENSSL_NO_DSA
1772 static size_t qbits = 160; /* PVK only tolerates 160 Q bits */
1773 static size_t pbits = 1024; /* With 160 Q bits, we MUST use 1024 P bits */
1774 OSSL_PARAM DSA_params[] = {
1775 OSSL_PARAM_size_t("pbits", &pbits),
1776 OSSL_PARAM_size_t("qbits", &qbits),
1777 OSSL_PARAM_END
1778 };
1779 #endif
1780
1781 #ifndef OPENSSL_NO_EC
1782 static char groupname[] = "prime256v1";
1783 OSSL_PARAM EC_params[] = {
1784 OSSL_PARAM_utf8_string("group", groupname, sizeof(groupname) - 1),
1785 OSSL_PARAM_END
1786 };
1787 #endif
1788
1789 OPTION_CHOICE o;
1790
1791 while ((o = opt_next()) != OPT_EOF) {
1792 switch (o) {
1793 case OPT_CONTEXT:
1794 default_libctx = 0;
1795 break;
1796 case OPT_PROVIDER_NAME:
1797 prov_name = opt_arg();
1798 break;
1799 case OPT_CONFIG_FILE:
1800 config_file = opt_arg();
1801 break;
1802 case OPT_RSA_FILE:
1803 rsa_file = opt_arg();
1804 break;
1805 case OPT_RSA_PSS_FILE:
1806 rsa_pss_file = opt_arg();
1807 break;
1808 case OPT_TEST_CASES:
1809 break;
1810 default:
1811 return 0;
1812 }
1813 }
1814
1815 if (strcmp(prov_name, "fips") == 0)
1816 is_fips = 1;
1817
1818 if (default_libctx) {
1819 if (!test_get_libctx(NULL, NULL, config_file, &deflprov, prov_name))
1820 return 0;
1821 } else {
1822 if (!test_get_libctx(&testctx, &nullprov, config_file, &deflprov, prov_name))
1823 return 0;
1824 }
1825
1826 /* FIPS(3.0.0): provider imports explicit params but they won't work #17998 */
1827 is_fips_3_0_0 = is_fips && fips_provider_version_eq(testctx, 3, 0, 0);
1828 /* FIPS(3.5.0) is the first to support ML-DSA, ML-KEM and SLH-DSA */
1829 is_fips_lt_3_5 = is_fips && fips_provider_version_lt(testctx, 3, 5, 0);
1830
1831 #ifdef STATIC_LEGACY
1832 /*
1833 * This test is always statically linked against libcrypto. We must not
1834 * attempt to load legacy.so that might be dynamically linked against
1835 * libcrypto. Instead we use a built-in version of the legacy provider.
1836 */
1837 if (!OSSL_PROVIDER_add_builtin(testctx, "legacy", ossl_legacy_provider_init))
1838 return 0;
1839 #endif
1840
1841 /* Separate provider/ctx for generating the test data */
1842 if (!TEST_ptr(keyctx = OSSL_LIB_CTX_new()))
1843 return 0;
1844 if (!TEST_ptr(keyprov = OSSL_PROVIDER_load(keyctx, "default")))
1845 return 0;
1846
1847 #ifndef OPENSSL_NO_EC
1848 if (!TEST_ptr(bnctx = BN_CTX_new_ex(testctx)))
1849 return 0;
1850 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
1851 if (!TEST_ptr(bld_prime_nc = OSSL_PARAM_BLD_new())
1852 || !TEST_ptr(bld_prime = OSSL_PARAM_BLD_new())
1853 || !create_ec_explicit_prime_params_namedcurve(bld_prime_nc)
1854 || !create_ec_explicit_prime_params(bld_prime)
1855 || !TEST_ptr(ec_explicit_prime_params_nc = OSSL_PARAM_BLD_to_param(bld_prime_nc))
1856 || !TEST_ptr(ec_explicit_prime_params_explicit = OSSL_PARAM_BLD_to_param(bld_prime))
1857 #ifndef OPENSSL_NO_EC2M
1858 || !TEST_ptr(bld_tri_nc = OSSL_PARAM_BLD_new())
1859 || !TEST_ptr(bld_tri = OSSL_PARAM_BLD_new())
1860 || !create_ec_explicit_trinomial_params_namedcurve(bld_tri_nc)
1861 || !create_ec_explicit_trinomial_params(bld_tri)
1862 || !TEST_ptr(ec_explicit_tri_params_nc = OSSL_PARAM_BLD_to_param(bld_tri_nc))
1863 || !TEST_ptr(ec_explicit_tri_params_explicit = OSSL_PARAM_BLD_to_param(bld_tri))
1864 #endif
1865 )
1866 return 0;
1867 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
1868 #endif
1869
1870 TEST_info("Generating keys...");
1871
1872 #ifndef OPENSSL_NO_DH
1873 TEST_info("Generating DH keys...");
1874 MAKE_DOMAIN_KEYS(DH, "DH", NULL);
1875 MAKE_DOMAIN_KEYS(DHX, "X9.42 DH", NULL);
1876 #endif
1877 #ifndef OPENSSL_NO_DSA
1878 TEST_info("Generating DSA keys...");
1879 MAKE_DOMAIN_KEYS(DSA, "DSA", DSA_params);
1880 #endif
1881 #ifndef OPENSSL_NO_EC
1882 TEST_info("Generating EC keys...");
1883 MAKE_DOMAIN_KEYS(EC, "EC", EC_params);
1884 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
1885 MAKE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve, "EC", ec_explicit_prime_params_nc);
1886 MAKE_DOMAIN_KEYS(ECExplicitPrime2G, "EC", ec_explicit_prime_params_explicit);
1887 #ifndef OPENSSL_NO_EC2M
1888 MAKE_DOMAIN_KEYS(ECExplicitTriNamedCurve, "EC", ec_explicit_tri_params_nc);
1889 MAKE_DOMAIN_KEYS(ECExplicitTri2G, "EC", ec_explicit_tri_params_explicit);
1890 #endif
1891 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
1892 #ifndef OPENSSL_NO_SM2
1893 MAKE_KEYS(SM2, "SM2", NULL);
1894 #endif
1895 #endif
1896 #ifndef OPENSSL_NO_ECX
1897 MAKE_KEYS(ED25519, "ED25519", NULL);
1898 MAKE_KEYS(ED448, "ED448", NULL);
1899 MAKE_KEYS(X25519, "X25519", NULL);
1900 MAKE_KEYS(X448, "X448", NULL);
1901 #endif
1902 #ifndef OPENSSL_NO_ML_DSA
1903 if (!is_fips_lt_3_5) {
1904 MAKE_KEYS(ML_DSA_44, "ML-DSA-44", NULL);
1905 MAKE_KEYS(ML_DSA_65, "ML-DSA-65", NULL);
1906 MAKE_KEYS(ML_DSA_87, "ML-DSA-87", NULL);
1907 }
1908 #endif /* OPENSSL_NO_ML_DSA */
1909 #ifndef OPENSSL_NO_ML_KEM
1910 if (!is_fips_lt_3_5) {
1911 MAKE_KEYS(ML_KEM_512, "ML-KEM-512", NULL);
1912 MAKE_KEYS(ML_KEM_768, "ML-KEM-768", NULL);
1913 MAKE_KEYS(ML_KEM_1024, "ML-KEM-1024", NULL);
1914 }
1915 #endif
1916 #ifndef OPENSSL_NO_SLH_DSA
1917 if (!is_fips_lt_3_5) {
1918 MAKE_KEYS(SLH_DSA_SHA2_128s, "SLH-DSA-SHA2-128s", NULL);
1919 MAKE_KEYS(SLH_DSA_SHA2_128f, "SLH-DSA-SHA2-128f", NULL);
1920 MAKE_KEYS(SLH_DSA_SHA2_192s, "SLH-DSA-SHA2-192s", NULL);
1921 MAKE_KEYS(SLH_DSA_SHA2_192f, "SLH-DSA-SHA2-192f", NULL);
1922 MAKE_KEYS(SLH_DSA_SHA2_256s, "SLH-DSA-SHA2-256s", NULL);
1923 MAKE_KEYS(SLH_DSA_SHA2_256f, "SLH-DSA-SHA2-256f", NULL);
1924 MAKE_KEYS(SLH_DSA_SHAKE_128s, "SLH-DSA-SHAKE-128s", NULL);
1925 MAKE_KEYS(SLH_DSA_SHAKE_128f, "SLH-DSA-SHAKE-128f", NULL);
1926 MAKE_KEYS(SLH_DSA_SHAKE_192s, "SLH-DSA-SHAKE-192s", NULL);
1927 MAKE_KEYS(SLH_DSA_SHAKE_192f, "SLH-DSA-SHAKE-192f", NULL);
1928 MAKE_KEYS(SLH_DSA_SHAKE_256s, "SLH-DSA-SHAKE-256s", NULL);
1929 MAKE_KEYS(SLH_DSA_SHAKE_256f, "SLH-DSA-SHAKE-256f", NULL);
1930 }
1931 #endif /* OPENSSL_NO_SLH_DSA */
1932
1933 TEST_info("Loading RSA key...");
1934 ok &= TEST_ptr(key_RSA = load_pkey_pem(rsa_file, keyctx));
1935 TEST_info("Loading RSA_PSS key...");
1936 ok &= TEST_ptr(key_RSA_PSS = load_pkey_pem(rsa_pss_file, keyctx));
1937 TEST_info("Generating keys done");
1938
1939 /*
1940 * Register every test whose key was successfully generated. The
1941 * per-algorithm key_##KEYTYPE != NULL guard inside each
1942 * ADD_TEST_SUITE* macro keeps us from referencing missing keys.
1943 */
1944 {
1945 #ifndef OPENSSL_NO_DH
1946 ADD_TEST_SUITE(DH);
1947 ADD_TEST_SUITE_PARAMS(DH);
1948 ADD_TEST_SUITE(DHX);
1949 ADD_TEST_SUITE_PARAMS(DHX);
1950 /*
1951 * DH has no support for PEM_write_bio_PrivateKey_traditional(),
1952 * so no legacy tests.
1953 */
1954 #endif
1955 #ifndef OPENSSL_NO_DSA
1956 ADD_TEST_SUITE(DSA);
1957 ADD_TEST_SUITE_PARAMS(DSA);
1958 ADD_TEST_SUITE_LEGACY(DSA);
1959 ADD_TEST_SUITE_MSBLOB(DSA);
1960 ADD_TEST_SUITE_UNPROTECTED_PVK(DSA);
1961 #ifndef OPENSSL_NO_RC4
1962 ADD_TEST_SUITE_PROTECTED_PVK(DSA);
1963 #endif
1964 #endif
1965 #ifndef OPENSSL_NO_EC
1966 ADD_TEST(ec_encode_to_data_multi);
1967 ADD_TEST_SUITE(EC);
1968 ADD_TEST_SUITE_PARAMS(EC);
1969 ADD_TEST_SUITE_LEGACY(EC);
1970 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
1971 ADD_TEST_SUITE(ECExplicitPrimeNamedCurve);
1972 ADD_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve);
1973 ADD_TEST_SUITE(ECExplicitPrime2G);
1974 ADD_TEST_SUITE_LEGACY(ECExplicitPrime2G);
1975 #ifndef OPENSSL_NO_EC2M
1976 ADD_TEST_SUITE(ECExplicitTriNamedCurve);
1977 ADD_TEST_SUITE_LEGACY(ECExplicitTriNamedCurve);
1978 ADD_TEST_SUITE(ECExplicitTri2G);
1979 ADD_TEST_SUITE_LEGACY(ECExplicitTri2G);
1980 #endif
1981 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
1982 #ifndef OPENSSL_NO_SM2
1983 if (!is_fips_3_0_0) {
1984 /* 3.0.0 FIPS provider imports explicit EC params and then fails. */
1985 ADD_TEST_SUITE(SM2);
1986 }
1987 #endif
1988 #endif
1989 #ifndef OPENSSL_NO_ECX
1990 ADD_TEST_SUITE(ED25519);
1991 ADD_TEST_SUITE(ED448);
1992 ADD_TEST_SUITE(X25519);
1993 ADD_TEST_SUITE(X448);
1994 /*
1995 * ED25519, ED448, X25519 and X448 have no support for
1996 * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
1997 */
1998 #endif
1999 #ifndef OPENSSL_NO_ML_KEM
2000 if (!is_fips_lt_3_5) {
2001 ADD_TEST_SUITE(ML_KEM_512);
2002 ADD_TEST_SUITE(ML_KEM_768);
2003 ADD_TEST_SUITE(ML_KEM_1024);
2004 }
2005 #endif
2006 ADD_TEST_SUITE(RSA);
2007 ADD_TEST_SUITE_LEGACY(RSA);
2008 ADD_TEST_SUITE(RSA_PSS);
2009 /*
2010 * RSA-PSS has no support for PEM_write_bio_PrivateKey_traditional(),
2011 * so no legacy tests.
2012 */
2013 ADD_TEST_SUITE_MSBLOB(RSA);
2014 ADD_TEST_SUITE_UNPROTECTED_PVK(RSA);
2015 #ifndef OPENSSL_NO_RC4
2016 ADD_TEST_SUITE_PROTECTED_PVK(RSA);
2017 #endif
2018
2019 #ifndef OPENSSL_NO_ML_DSA
2020 if (!is_fips_lt_3_5) {
2021 ADD_TEST_SUITE(ML_DSA_44);
2022 ADD_TEST_SUITE(ML_DSA_65);
2023 ADD_TEST_SUITE(ML_DSA_87);
2024 }
2025 #endif /* OPENSSL_NO_ML_DSA */
2026
2027 #ifndef OPENSSL_NO_SLH_DSA
2028 if (!is_fips_lt_3_5) {
2029 ADD_TEST_SUITE(SLH_DSA_SHA2_128s);
2030 ADD_TEST_SUITE(SLH_DSA_SHA2_128f);
2031 ADD_TEST_SUITE(SLH_DSA_SHA2_192s);
2032 ADD_TEST_SUITE(SLH_DSA_SHA2_192f);
2033 ADD_TEST_SUITE(SLH_DSA_SHA2_256s);
2034 ADD_TEST_SUITE(SLH_DSA_SHA2_256f);
2035 ADD_TEST_SUITE(SLH_DSA_SHAKE_128s);
2036 ADD_TEST_SUITE(SLH_DSA_SHAKE_128f);
2037 ADD_TEST_SUITE(SLH_DSA_SHAKE_192s);
2038 ADD_TEST_SUITE(SLH_DSA_SHAKE_192f);
2039 ADD_TEST_SUITE(SLH_DSA_SHAKE_256s);
2040 ADD_TEST_SUITE(SLH_DSA_SHAKE_256f);
2041 }
2042 #endif /* OPENSSL_NO_SLH_DSA */
2043
2044 /*
2045 * Named-group-only partial shapes for DH and EC/SM2. Each
2046 * shape is silently skipped if the algorithm is not loadable.
2047 */
2048 #ifdef TEST_FROMDATA_NO_KEYGEN
2049 ADD_TEST(test_fromdata_no_keygen);
2050 #endif
2051 }
2052
2053 return ok;
2054 }
2055
cleanup_tests(void)2056 void cleanup_tests(void)
2057 {
2058 #ifndef OPENSSL_NO_EC
2059 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
2060 OSSL_PARAM_free(ec_explicit_prime_params_nc);
2061 OSSL_PARAM_free(ec_explicit_prime_params_explicit);
2062 OSSL_PARAM_BLD_free(bld_prime_nc);
2063 OSSL_PARAM_BLD_free(bld_prime);
2064 #ifndef OPENSSL_NO_EC2M
2065 OSSL_PARAM_free(ec_explicit_tri_params_nc);
2066 OSSL_PARAM_free(ec_explicit_tri_params_explicit);
2067 OSSL_PARAM_BLD_free(bld_tri_nc);
2068 OSSL_PARAM_BLD_free(bld_tri);
2069 #endif
2070 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
2071 BN_CTX_free(bnctx);
2072 #endif /* OPENSSL_NO_EC */
2073
2074 #ifndef OPENSSL_NO_DH
2075 FREE_DOMAIN_KEYS(DH);
2076 FREE_DOMAIN_KEYS(DHX);
2077 #endif
2078 #ifndef OPENSSL_NO_DSA
2079 FREE_DOMAIN_KEYS(DSA);
2080 #endif
2081 #ifndef OPENSSL_NO_EC
2082 FREE_DOMAIN_KEYS(EC);
2083 #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES
2084 FREE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
2085 FREE_DOMAIN_KEYS(ECExplicitPrime2G);
2086 #ifndef OPENSSL_NO_EC2M
2087 FREE_DOMAIN_KEYS(ECExplicitTriNamedCurve);
2088 FREE_DOMAIN_KEYS(ECExplicitTri2G);
2089 #endif
2090 #endif /* OPENSSL_NO_EC_EXPLICIT_CURVES */
2091 #ifndef OPENSSL_NO_SM2
2092 FREE_KEYS(SM2);
2093 #endif
2094 #endif
2095 #ifndef OPENSSL_NO_ECX
2096 FREE_KEYS(ED25519);
2097 FREE_KEYS(ED448);
2098 FREE_KEYS(X25519);
2099 FREE_KEYS(X448);
2100 #endif
2101 #ifndef OPENSSL_NO_ML_KEM
2102 if (!is_fips_lt_3_5) {
2103 FREE_KEYS(ML_KEM_512);
2104 FREE_KEYS(ML_KEM_768);
2105 FREE_KEYS(ML_KEM_1024);
2106 }
2107 #endif
2108 FREE_KEYS(RSA);
2109 FREE_KEYS(RSA_PSS);
2110
2111 #ifndef OPENSSL_NO_ML_DSA
2112 if (!is_fips_lt_3_5) {
2113 FREE_KEYS(ML_DSA_44);
2114 FREE_KEYS(ML_DSA_65);
2115 FREE_KEYS(ML_DSA_87);
2116 }
2117 #endif /* OPENSSL_NO_ML_DSA */
2118
2119 #ifndef OPENSSL_NO_SLH_DSA
2120 if (!is_fips_lt_3_5) {
2121 FREE_KEYS(SLH_DSA_SHA2_128s);
2122 FREE_KEYS(SLH_DSA_SHA2_128f);
2123 FREE_KEYS(SLH_DSA_SHA2_192s);
2124 FREE_KEYS(SLH_DSA_SHA2_192f);
2125 FREE_KEYS(SLH_DSA_SHA2_256s);
2126 FREE_KEYS(SLH_DSA_SHA2_256f);
2127 FREE_KEYS(SLH_DSA_SHAKE_128s);
2128 FREE_KEYS(SLH_DSA_SHAKE_128f);
2129 FREE_KEYS(SLH_DSA_SHAKE_192s);
2130 FREE_KEYS(SLH_DSA_SHAKE_192f);
2131 FREE_KEYS(SLH_DSA_SHAKE_256s);
2132 FREE_KEYS(SLH_DSA_SHAKE_256f);
2133 }
2134 #endif /* OPENSSL_NO_SLH_DSA */
2135
2136 OSSL_PROVIDER_unload(nullprov);
2137 OSSL_PROVIDER_unload(deflprov);
2138 OSSL_PROVIDER_unload(keyprov);
2139 OSSL_LIB_CTX_free(testctx);
2140 OSSL_LIB_CTX_free(keyctx);
2141 }
2142