Fix no-dh and no-dsa
[openssl.git] / test / evp_libctx_test.c
1 /*
2  * Copyright 2020 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 /*
11
12  * These tests are setup to load null into the default library context.
13  * Any tests are expected to use the created 'libctx' to find algorithms.
14  * The framework runs the tests twice using the 'default' provider or
15  * 'fips' provider as inputs.
16  */
17
18 /*
19  * DSA/DH low level APIs are deprecated for public use, but still ok for
20  * internal use.
21  */
22 #include "internal/deprecated.h"
23 #include <openssl/evp.h>
24 #include <openssl/provider.h>
25 #include <openssl/dsa.h>
26 #include <openssl/dh.h>
27 #include <openssl/safestack.h>
28 #include "testutil.h"
29 #include "internal/nelem.h"
30 #include "crypto/bn_dh.h"   /* _bignum_ffdhe2048_p */
31 #include "../e_os.h"        /* strcasecmp */
32
33 DEFINE_STACK_OF_CSTRING()
34
35 static OPENSSL_CTX *libctx = NULL;
36 static OSSL_PROVIDER *nullprov = NULL;
37 static OSSL_PROVIDER *libprov = NULL;
38 static STACK_OF(OPENSSL_CSTRING) *cipher_names = NULL;
39
40 typedef enum OPTION_choice {
41     OPT_ERR = -1,
42     OPT_EOF = 0,
43     OPT_CONFIG_FILE,
44     OPT_PROVIDER_NAME,
45     OPT_TEST_ENUM
46 } OPTION_CHOICE;
47
48 const OPTIONS *test_get_options(void)
49 {
50     static const OPTIONS test_options[] = {
51         OPT_TEST_OPTIONS_DEFAULT_USAGE,
52         { "config", OPT_CONFIG_FILE, '<',
53           "The configuration file to use for the libctx" },
54         { "provider", OPT_PROVIDER_NAME, 's',
55           "The provider to load (The default value is 'default'" },
56         { NULL }
57     };
58     return test_options;
59 }
60
61 #ifndef OPENSSL_NO_DH
62 static const char *getname(int id)
63 {
64     const char *name[] = {"p", "q", "g" };
65
66     if (id >= 0 && id < 3)
67         return name[id];
68     return "?";
69 }
70 #endif
71
72 /*
73  * We're using some DH specific values in this test, so we skip compilation if
74  * we're in a no-dh build.
75  */
76 #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DH)
77
78 static int test_dsa_param_keygen(int tstid)
79 {
80     int ret = 0;
81     int expected;
82     EVP_PKEY_CTX *gen_ctx = NULL;
83     EVP_PKEY *pkey_parm = NULL;
84     EVP_PKEY *pkey = NULL;
85     DSA *dsa = NULL;
86     int pind, qind, gind;
87     BIGNUM *p = NULL, *q = NULL, *g = NULL;
88
89     /*
90      * Just grab some fixed dh p, q, g values for testing,
91      * these 'safe primes' should not be used normally for dsa *.
92      */
93     static const BIGNUM *bn[] = {
94         &_bignum_dh2048_256_p,  &_bignum_dh2048_256_q, &_bignum_dh2048_256_g
95     };
96
97     /*
98      * These tests are using bad values for p, q, g by reusing the values.
99      * A value of 0 uses p, 1 uses q and 2 uses g.
100      * There are 27 different combinations, with only the 1 valid combination.
101      */
102     pind = tstid / 9;
103     qind = (tstid / 3) % 3;
104     gind = tstid % 3;
105     expected  = (pind == 0 && qind == 1 && gind == 2);
106
107     TEST_note("Testing with (p, q, g) = (%s, %s, %s)\n", getname(pind),
108               getname(qind), getname(gind));
109
110     if (!TEST_ptr(pkey_parm = EVP_PKEY_new())
111         || !TEST_ptr(dsa = DSA_new())
112         || !TEST_ptr(p = BN_dup(bn[pind]))
113         || !TEST_ptr(q = BN_dup(bn[qind]))
114         || !TEST_ptr(g = BN_dup(bn[gind]))
115         || !TEST_true(DSA_set0_pqg(dsa, p, q, g)))
116         goto err;
117     p = q = g = NULL;
118
119     if (!TEST_true(EVP_PKEY_assign_DSA(pkey_parm, dsa)))
120         goto err;
121     dsa = NULL;
122
123     if (!TEST_ptr(gen_ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey_parm, NULL))
124         || !TEST_int_gt(EVP_PKEY_keygen_init(gen_ctx), 0)
125         || !TEST_int_eq(EVP_PKEY_keygen(gen_ctx, &pkey), expected))
126         goto err;
127     ret = 1;
128 err:
129     EVP_PKEY_free(pkey);
130     EVP_PKEY_CTX_free(gen_ctx);
131     EVP_PKEY_free(pkey_parm);
132     DSA_free(dsa);
133     BN_free(g);
134     BN_free(q);
135     BN_free(p);
136     return ret;
137 }
138 #endif /* OPENSSL_NO_DSA */
139
140 #ifndef OPENSSL_NO_DH
141 static int do_dh_param_keygen(int tstid, const BIGNUM **bn)
142 {
143     int ret = 0;
144     int expected;
145     EVP_PKEY_CTX *gen_ctx = NULL;
146     EVP_PKEY *pkey_parm = NULL;
147     EVP_PKEY *pkey = NULL;
148     DH *dh = NULL;
149     int pind, qind, gind;
150     BIGNUM *p = NULL, *q = NULL, *g = NULL;
151
152     /*
153      * These tests are using bad values for p, q, g by reusing the values.
154      * A value of 0 uses p, 1 uses q and 2 uses g.
155      * There are 27 different combinations, with only the 1 valid combination.
156      */
157     pind = tstid / 9;
158     qind = (tstid / 3) % 3;
159     gind = tstid % 3;
160     expected  = (pind == 0 && qind == 1 && gind == 2);
161
162     TEST_note("Testing with (p, q, g) = (%s, %s, %s)", getname(pind),
163               getname(qind), getname(gind));
164
165     if (!TEST_ptr(pkey_parm = EVP_PKEY_new())
166         || !TEST_ptr(dh = DH_new())
167         || !TEST_ptr(p = BN_dup(bn[pind]))
168         || !TEST_ptr(q = BN_dup(bn[qind]))
169         || !TEST_ptr(g = BN_dup(bn[gind]))
170         || !TEST_true(DH_set0_pqg(dh, p, q, g)))
171         goto err;
172     p = q = g = NULL;
173
174     if (!TEST_true(EVP_PKEY_assign_DH(pkey_parm, dh)))
175         goto err;
176     dh = NULL;
177
178     if (!TEST_ptr(gen_ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey_parm, NULL))
179         || !TEST_int_gt(EVP_PKEY_keygen_init(gen_ctx), 0)
180         || !TEST_int_eq(EVP_PKEY_keygen(gen_ctx, &pkey), expected))
181         goto err;
182     ret = 1;
183 err:
184     EVP_PKEY_free(pkey);
185     EVP_PKEY_CTX_free(gen_ctx);
186     EVP_PKEY_free(pkey_parm);
187     DH_free(dh);
188     BN_free(g);
189     BN_free(q);
190     BN_free(p);
191     return ret;
192 }
193
194 /*
195  * Note that we get the fips186-4 path being run for most of these cases since
196  * the internal code will detect that the p, q, g does not match a safe prime
197  * group (Except for when tstid = 5, which sets the correct p, q, g)
198  */
199 static int test_dh_safeprime_param_keygen(int tstid)
200 {
201     static const BIGNUM *bn[] = {
202         &_bignum_ffdhe2048_p,  &_bignum_ffdhe2048_q, &_bignum_const_2
203     };
204     return do_dh_param_keygen(tstid, bn);
205 }
206 #endif /* OPENSSL_NO_DH */
207
208 static int test_cipher_reinit(int test_id)
209 {
210     int ret = 0, out1_len = 0, out2_len = 0, diff, ccm;
211     EVP_CIPHER *cipher = NULL;
212     EVP_CIPHER_CTX *ctx = NULL;
213     unsigned char out1[256];
214     unsigned char out2[256];
215     unsigned char in[16] = {
216         0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
217         0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
218     };
219     unsigned char key[64] = {
220         0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
221         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
222         0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
223         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
224         0x02, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
225         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
226         0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
227         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
228     };
229     unsigned char iv[16] = {
230         0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
231         0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
232     };
233     const char *name = sk_OPENSSL_CSTRING_value(cipher_names, test_id);
234
235     if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()))
236         goto err;
237
238     TEST_note("Fetching %s\n", name);
239     if (!TEST_ptr(cipher = EVP_CIPHER_fetch(libctx, name, NULL)))
240         goto err;
241
242     /* ccm fails on the second update - this matches OpenSSL 1_1_1 behaviour */
243     ccm = (EVP_CIPHER_mode(cipher) == EVP_CIPH_CCM_MODE);
244
245     /* DES3-WRAP uses random every update - so it will give a different value */
246     diff = EVP_CIPHER_is_a(cipher, "DES3-WRAP");
247
248     if (!TEST_true(EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv))
249         || !TEST_true(EVP_EncryptUpdate(ctx, out1, &out1_len, in, sizeof(in)))
250         || !TEST_true(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
251         || !TEST_int_eq(EVP_EncryptUpdate(ctx, out2, &out2_len, in, sizeof(in)),
252                         ccm ? 0 : 1))
253         goto err;
254
255     if (ccm == 0) {
256         if (diff) {
257             if (!TEST_mem_ne(out1, out1_len, out2, out2_len))
258                 goto err;
259         } else {
260             if (!TEST_mem_eq(out1, out1_len, out2, out2_len))
261                 goto err;
262         }
263     }
264     ret = 1;
265 err:
266     EVP_CIPHER_free(cipher);
267     EVP_CIPHER_CTX_free(ctx);
268     return ret;
269 }
270
271 static int name_cmp(const char * const *a, const char * const *b)
272 {
273     return strcasecmp(*a, *b);
274 }
275
276 static void collect_cipher_names(EVP_CIPHER *cipher, void *cipher_names_list)
277 {
278     STACK_OF(OPENSSL_CSTRING) *names = cipher_names_list;
279
280     sk_OPENSSL_CSTRING_push(names, EVP_CIPHER_name(cipher));
281 }
282
283 int setup_tests(void)
284 {
285     const char *prov_name = "default";
286     char *config_file = NULL;
287     OPTION_CHOICE o;
288
289     while ((o = opt_next()) != OPT_EOF) {
290         switch (o) {
291         case OPT_PROVIDER_NAME:
292             prov_name = opt_arg();
293             break;
294         case OPT_CONFIG_FILE:
295             config_file = opt_arg();
296             break;
297         case OPT_TEST_CASES:
298            break;
299         default:
300         case OPT_ERR:
301             return 0;
302         }
303     }
304
305     nullprov = OSSL_PROVIDER_load(NULL, "null");
306     if (!TEST_ptr(nullprov))
307         return 0;
308
309     libctx = OPENSSL_CTX_new();
310
311     if (!TEST_ptr(libctx))
312         return 0;
313
314     if (config_file != NULL) {
315         if (!TEST_true(OPENSSL_CTX_load_config(libctx, config_file)))
316             return 0;
317     }
318
319     libprov = OSSL_PROVIDER_load(libctx, prov_name);
320     if (!TEST_ptr(libprov))
321         return 0;
322
323 #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DH)
324     ADD_ALL_TESTS(test_dsa_param_keygen, 3 * 3 * 3);
325 #endif
326 #ifndef OPENSSL_NO_DH
327     ADD_ALL_TESTS(test_dh_safeprime_param_keygen, 3 * 3 * 3);
328 #endif
329
330     if (!TEST_ptr(cipher_names = sk_OPENSSL_CSTRING_new(name_cmp)))
331         return 0;
332     EVP_CIPHER_do_all_provided(libctx, collect_cipher_names, cipher_names);
333
334     ADD_ALL_TESTS(test_cipher_reinit, sk_OPENSSL_CSTRING_num(cipher_names));
335     return 1;
336 }
337
338 void cleanup_tests(void)
339 {
340     sk_OPENSSL_CSTRING_free(cipher_names);
341     OSSL_PROVIDER_unload(libprov);
342     OPENSSL_CTX_free(libctx);
343     OSSL_PROVIDER_unload(nullprov);
344 }