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