Fix PEM certificate loading that sometimes fails
[openssl.git] / test / dhtest.c
1 /*
2  * Copyright 1995-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  * DH low level APIs are deprecated for public use, but still ok for
12  * internal use.
13  */
14 #include "internal/deprecated.h"
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include "internal/nelem.h"
21 #include <openssl/crypto.h>
22 #include <openssl/bio.h>
23 #include <openssl/bn.h>
24 #include <openssl/rand.h>
25 #include <openssl/err.h>
26 #include <openssl/obj_mac.h>
27 #include "testutil.h"
28
29 #ifndef OPENSSL_NO_DH
30 # include <openssl/dh.h>
31
32 static int cb(int p, int n, BN_GENCB *arg);
33
34 static int dh_test(void)
35 {
36     DH *dh = NULL;
37     BIGNUM *p = NULL, *q = NULL, *g = NULL;
38     const BIGNUM *p2, *q2, *g2;
39     BIGNUM *priv_key = NULL;
40     const BIGNUM *pub_key2, *priv_key2;
41     BN_GENCB *_cb = NULL;
42     DH *a = NULL;
43     DH *b = NULL;
44     DH *c = NULL;
45     const BIGNUM *ap = NULL, *ag = NULL, *apub_key = NULL;
46     const BIGNUM *bpub_key = NULL, *bpriv_key = NULL;
47     BIGNUM *bp = NULL, *bg = NULL, *cpriv_key = NULL;
48     unsigned char *abuf = NULL;
49     unsigned char *bbuf = NULL;
50     unsigned char *cbuf = NULL;
51     int i, alen, blen, clen, aout, bout, cout;
52     int ret = 0;
53
54     if (!TEST_ptr(dh = DH_new())
55         || !TEST_ptr(p = BN_new())
56         || !TEST_ptr(q = BN_new())
57         || !TEST_ptr(g = BN_new())
58         || !TEST_ptr(priv_key = BN_new()))
59         goto err1;
60
61     /*
62      * I) basic tests
63      */
64
65     /* using a small predefined Sophie Germain DH group with generator 3 */
66     if (!TEST_true(BN_set_word(p, 4079L))
67         || !TEST_true(BN_set_word(q, 2039L))
68         || !TEST_true(BN_set_word(g, 3L))
69         || !TEST_true(DH_set0_pqg(dh, p, q, g)))
70         goto err1;
71
72     /* check fails, because p is way too small */
73     if (!DH_check(dh, &i))
74         goto err2;
75     i ^= DH_MODULUS_TOO_SMALL;
76     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
77             || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
78             || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
79             || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
80             || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
81             || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
82             || !TEST_false(i & DH_CHECK_INVALID_J_VALUE)
83             || !TEST_false(i & DH_MODULUS_TOO_SMALL)
84             || !TEST_false(i & DH_MODULUS_TOO_LARGE)
85             || !TEST_false(i))
86         goto err2;
87
88     /* test the combined getter for p, q, and g */
89     DH_get0_pqg(dh, &p2, &q2, &g2);
90     if (!TEST_ptr_eq(p2, p)
91         || !TEST_ptr_eq(q2, q)
92         || !TEST_ptr_eq(g2, g))
93         goto err2;
94
95     /* test the simple getters for p, q, and g */
96     if (!TEST_ptr_eq(DH_get0_p(dh), p2)
97         || !TEST_ptr_eq(DH_get0_q(dh), q2)
98         || !TEST_ptr_eq(DH_get0_g(dh), g2))
99         goto err2;
100
101     /* set the private key only*/
102     if (!TEST_true(BN_set_word(priv_key, 1234L))
103         || !TEST_true(DH_set0_key(dh, NULL, priv_key)))
104         goto err2;
105
106     /* test the combined getter for pub_key and priv_key */
107     DH_get0_key(dh, &pub_key2, &priv_key2);
108     if (!TEST_ptr_eq(pub_key2, NULL)
109         || !TEST_ptr_eq(priv_key2, priv_key))
110         goto err3;
111
112     /* test the simple getters for pub_key and priv_key */
113     if (!TEST_ptr_eq(DH_get0_pub_key(dh), pub_key2)
114         || !TEST_ptr_eq(DH_get0_priv_key(dh), priv_key2))
115         goto err3;
116
117     /* now generate a key pair (expect failure since modulus is too small) */
118     if (!TEST_false(DH_generate_key(dh)))
119         goto err3;
120
121     /* We'll have a stale error on the queue from the above test so clear it */
122     ERR_clear_error();
123
124     /*
125      * II) key generation
126      */
127
128     /* generate a DH group ... */
129     if (!TEST_ptr(_cb = BN_GENCB_new()))
130         goto err3;
131     BN_GENCB_set(_cb, &cb, NULL);
132     if (!TEST_ptr(a = DH_new())
133             || !TEST_true(DH_generate_parameters_ex(a, 512,
134                                                     DH_GENERATOR_5, _cb)))
135         goto err3;
136
137     /* ... and check whether it is valid */
138     if (!DH_check(a, &i))
139         goto err3;
140     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
141             || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
142             || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
143             || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
144             || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
145             || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
146             || !TEST_false(i & DH_CHECK_INVALID_J_VALUE)
147             || !TEST_false(i & DH_MODULUS_TOO_SMALL)
148             || !TEST_false(i & DH_MODULUS_TOO_LARGE)
149             || !TEST_false(i))
150         goto err3;
151
152     DH_get0_pqg(a, &ap, NULL, &ag);
153
154     /* now create another copy of the DH group for the peer */
155     if (!TEST_ptr(b = DH_new()))
156         goto err3;
157
158     if (!TEST_ptr(bp = BN_dup(ap))
159             || !TEST_ptr(bg = BN_dup(ag))
160             || !TEST_true(DH_set0_pqg(b, bp, NULL, bg)))
161         goto err3;
162     bp = bg = NULL;
163
164     /*
165      * III) simulate a key exchange
166      */
167
168     if (!DH_generate_key(a))
169         goto err3;
170     DH_get0_key(a, &apub_key, NULL);
171
172     if (!DH_generate_key(b))
173         goto err3;
174     DH_get0_key(b, &bpub_key, &bpriv_key);
175
176     /* Also test with a private-key-only copy of |b|. */
177     if (!TEST_ptr(c = DHparams_dup(b))
178             || !TEST_ptr(cpriv_key = BN_dup(bpriv_key))
179             || !TEST_true(DH_set0_key(c, NULL, cpriv_key)))
180         goto err3;
181     cpriv_key = NULL;
182
183     alen = DH_size(a);
184     if (!TEST_ptr(abuf = OPENSSL_malloc(alen))
185             || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
186         goto err3;
187
188     blen = DH_size(b);
189     if (!TEST_ptr(bbuf = OPENSSL_malloc(blen))
190             || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
191         goto err3;
192
193     clen = DH_size(c);
194     if (!TEST_ptr(cbuf = OPENSSL_malloc(clen))
195             || !TEST_true((cout = DH_compute_key(cbuf, apub_key, c)) != -1))
196         goto err3;
197
198     if (!TEST_true(aout >= 20)
199             || !TEST_mem_eq(abuf, aout, bbuf, bout)
200             || !TEST_mem_eq(abuf, aout, cbuf, cout))
201         goto err3;
202
203     ret = 1;
204     goto success;
205
206  err1:
207     /* an error occurred before p,q,g were assigned to dh */
208     BN_free(p);
209     BN_free(q);
210     BN_free(g);
211  err2:
212     /* an error occurred before priv_key was assigned to dh */
213     BN_free(priv_key);
214  err3:
215  success:
216     OPENSSL_free(abuf);
217     OPENSSL_free(bbuf);
218     OPENSSL_free(cbuf);
219     DH_free(b);
220     DH_free(a);
221     DH_free(c);
222     BN_free(bp);
223     BN_free(bg);
224     BN_free(cpriv_key);
225     BN_GENCB_free(_cb);
226     DH_free(dh);
227
228     return ret;
229 }
230
231 static int cb(int p, int n, BN_GENCB *arg)
232 {
233     return 1;
234 }
235
236 /* Test data from RFC 5114 */
237
238 static const unsigned char dhtest_1024_160_xA[] = {
239     0xB9, 0xA3, 0xB3, 0xAE, 0x8F, 0xEF, 0xC1, 0xA2, 0x93, 0x04, 0x96, 0x50,
240     0x70, 0x86, 0xF8, 0x45, 0x5D, 0x48, 0x94, 0x3E
241 };
242
243 static const unsigned char dhtest_1024_160_yA[] = {
244     0x2A, 0x85, 0x3B, 0x3D, 0x92, 0x19, 0x75, 0x01, 0xB9, 0x01, 0x5B, 0x2D,
245     0xEB, 0x3E, 0xD8, 0x4F, 0x5E, 0x02, 0x1D, 0xCC, 0x3E, 0x52, 0xF1, 0x09,
246     0xD3, 0x27, 0x3D, 0x2B, 0x75, 0x21, 0x28, 0x1C, 0xBA, 0xBE, 0x0E, 0x76,
247     0xFF, 0x57, 0x27, 0xFA, 0x8A, 0xCC, 0xE2, 0x69, 0x56, 0xBA, 0x9A, 0x1F,
248     0xCA, 0x26, 0xF2, 0x02, 0x28, 0xD8, 0x69, 0x3F, 0xEB, 0x10, 0x84, 0x1D,
249     0x84, 0xA7, 0x36, 0x00, 0x54, 0xEC, 0xE5, 0xA7, 0xF5, 0xB7, 0xA6, 0x1A,
250     0xD3, 0xDF, 0xB3, 0xC6, 0x0D, 0x2E, 0x43, 0x10, 0x6D, 0x87, 0x27, 0xDA,
251     0x37, 0xDF, 0x9C, 0xCE, 0x95, 0xB4, 0x78, 0x75, 0x5D, 0x06, 0xBC, 0xEA,
252     0x8F, 0x9D, 0x45, 0x96, 0x5F, 0x75, 0xA5, 0xF3, 0xD1, 0xDF, 0x37, 0x01,
253     0x16, 0x5F, 0xC9, 0xE5, 0x0C, 0x42, 0x79, 0xCE, 0xB0, 0x7F, 0x98, 0x95,
254     0x40, 0xAE, 0x96, 0xD5, 0xD8, 0x8E, 0xD7, 0x76
255 };
256
257 static const unsigned char dhtest_1024_160_xB[] = {
258     0x93, 0x92, 0xC9, 0xF9, 0xEB, 0x6A, 0x7A, 0x6A, 0x90, 0x22, 0xF7, 0xD8,
259     0x3E, 0x72, 0x23, 0xC6, 0x83, 0x5B, 0xBD, 0xDA
260 };
261
262 static const unsigned char dhtest_1024_160_yB[] = {
263     0x71, 0x7A, 0x6C, 0xB0, 0x53, 0x37, 0x1F, 0xF4, 0xA3, 0xB9, 0x32, 0x94,
264     0x1C, 0x1E, 0x56, 0x63, 0xF8, 0x61, 0xA1, 0xD6, 0xAD, 0x34, 0xAE, 0x66,
265     0x57, 0x6D, 0xFB, 0x98, 0xF6, 0xC6, 0xCB, 0xF9, 0xDD, 0xD5, 0xA5, 0x6C,
266     0x78, 0x33, 0xF6, 0xBC, 0xFD, 0xFF, 0x09, 0x55, 0x82, 0xAD, 0x86, 0x8E,
267     0x44, 0x0E, 0x8D, 0x09, 0xFD, 0x76, 0x9E, 0x3C, 0xEC, 0xCD, 0xC3, 0xD3,
268     0xB1, 0xE4, 0xCF, 0xA0, 0x57, 0x77, 0x6C, 0xAA, 0xF9, 0x73, 0x9B, 0x6A,
269     0x9F, 0xEE, 0x8E, 0x74, 0x11, 0xF8, 0xD6, 0xDA, 0xC0, 0x9D, 0x6A, 0x4E,
270     0xDB, 0x46, 0xCC, 0x2B, 0x5D, 0x52, 0x03, 0x09, 0x0E, 0xAE, 0x61, 0x26,
271     0x31, 0x1E, 0x53, 0xFD, 0x2C, 0x14, 0xB5, 0x74, 0xE6, 0xA3, 0x10, 0x9A,
272     0x3D, 0xA1, 0xBE, 0x41, 0xBD, 0xCE, 0xAA, 0x18, 0x6F, 0x5C, 0xE0, 0x67,
273     0x16, 0xA2, 0xB6, 0xA0, 0x7B, 0x3C, 0x33, 0xFE
274 };
275
276 static const unsigned char dhtest_1024_160_Z[] = {
277     0x5C, 0x80, 0x4F, 0x45, 0x4D, 0x30, 0xD9, 0xC4, 0xDF, 0x85, 0x27, 0x1F,
278     0x93, 0x52, 0x8C, 0x91, 0xDF, 0x6B, 0x48, 0xAB, 0x5F, 0x80, 0xB3, 0xB5,
279     0x9C, 0xAA, 0xC1, 0xB2, 0x8F, 0x8A, 0xCB, 0xA9, 0xCD, 0x3E, 0x39, 0xF3,
280     0xCB, 0x61, 0x45, 0x25, 0xD9, 0x52, 0x1D, 0x2E, 0x64, 0x4C, 0x53, 0xB8,
281     0x07, 0xB8, 0x10, 0xF3, 0x40, 0x06, 0x2F, 0x25, 0x7D, 0x7D, 0x6F, 0xBF,
282     0xE8, 0xD5, 0xE8, 0xF0, 0x72, 0xE9, 0xB6, 0xE9, 0xAF, 0xDA, 0x94, 0x13,
283     0xEA, 0xFB, 0x2E, 0x8B, 0x06, 0x99, 0xB1, 0xFB, 0x5A, 0x0C, 0xAC, 0xED,
284     0xDE, 0xAE, 0xAD, 0x7E, 0x9C, 0xFB, 0xB3, 0x6A, 0xE2, 0xB4, 0x20, 0x83,
285     0x5B, 0xD8, 0x3A, 0x19, 0xFB, 0x0B, 0x5E, 0x96, 0xBF, 0x8F, 0xA4, 0xD0,
286     0x9E, 0x34, 0x55, 0x25, 0x16, 0x7E, 0xCD, 0x91, 0x55, 0x41, 0x6F, 0x46,
287     0xF4, 0x08, 0xED, 0x31, 0xB6, 0x3C, 0x6E, 0x6D
288 };
289
290 static const unsigned char dhtest_2048_224_xA[] = {
291     0x22, 0xE6, 0x26, 0x01, 0xDB, 0xFF, 0xD0, 0x67, 0x08, 0xA6, 0x80, 0xF7,
292     0x47, 0xF3, 0x61, 0xF7, 0x6D, 0x8F, 0x4F, 0x72, 0x1A, 0x05, 0x48, 0xE4,
293     0x83, 0x29, 0x4B, 0x0C
294 };
295
296 static const unsigned char dhtest_2048_224_yA[] = {
297     0x1B, 0x3A, 0x63, 0x45, 0x1B, 0xD8, 0x86, 0xE6, 0x99, 0xE6, 0x7B, 0x49,
298     0x4E, 0x28, 0x8B, 0xD7, 0xF8, 0xE0, 0xD3, 0x70, 0xBA, 0xDD, 0xA7, 0xA0,
299     0xEF, 0xD2, 0xFD, 0xE7, 0xD8, 0xF6, 0x61, 0x45, 0xCC, 0x9F, 0x28, 0x04,
300     0x19, 0x97, 0x5E, 0xB8, 0x08, 0x87, 0x7C, 0x8A, 0x4C, 0x0C, 0x8E, 0x0B,
301     0xD4, 0x8D, 0x4A, 0x54, 0x01, 0xEB, 0x1E, 0x87, 0x76, 0xBF, 0xEE, 0xE1,
302     0x34, 0xC0, 0x38, 0x31, 0xAC, 0x27, 0x3C, 0xD9, 0xD6, 0x35, 0xAB, 0x0C,
303     0xE0, 0x06, 0xA4, 0x2A, 0x88, 0x7E, 0x3F, 0x52, 0xFB, 0x87, 0x66, 0xB6,
304     0x50, 0xF3, 0x80, 0x78, 0xBC, 0x8E, 0xE8, 0x58, 0x0C, 0xEF, 0xE2, 0x43,
305     0x96, 0x8C, 0xFC, 0x4F, 0x8D, 0xC3, 0xDB, 0x08, 0x45, 0x54, 0x17, 0x1D,
306     0x41, 0xBF, 0x2E, 0x86, 0x1B, 0x7B, 0xB4, 0xD6, 0x9D, 0xD0, 0xE0, 0x1E,
307     0xA3, 0x87, 0xCB, 0xAA, 0x5C, 0xA6, 0x72, 0xAF, 0xCB, 0xE8, 0xBD, 0xB9,
308     0xD6, 0x2D, 0x4C, 0xE1, 0x5F, 0x17, 0xDD, 0x36, 0xF9, 0x1E, 0xD1, 0xEE,
309     0xDD, 0x65, 0xCA, 0x4A, 0x06, 0x45, 0x5C, 0xB9, 0x4C, 0xD4, 0x0A, 0x52,
310     0xEC, 0x36, 0x0E, 0x84, 0xB3, 0xC9, 0x26, 0xE2, 0x2C, 0x43, 0x80, 0xA3,
311     0xBF, 0x30, 0x9D, 0x56, 0x84, 0x97, 0x68, 0xB7, 0xF5, 0x2C, 0xFD, 0xF6,
312     0x55, 0xFD, 0x05, 0x3A, 0x7E, 0xF7, 0x06, 0x97, 0x9E, 0x7E, 0x58, 0x06,
313     0xB1, 0x7D, 0xFA, 0xE5, 0x3A, 0xD2, 0xA5, 0xBC, 0x56, 0x8E, 0xBB, 0x52,
314     0x9A, 0x7A, 0x61, 0xD6, 0x8D, 0x25, 0x6F, 0x8F, 0xC9, 0x7C, 0x07, 0x4A,
315     0x86, 0x1D, 0x82, 0x7E, 0x2E, 0xBC, 0x8C, 0x61, 0x34, 0x55, 0x31, 0x15,
316     0xB7, 0x0E, 0x71, 0x03, 0x92, 0x0A, 0xA1, 0x6D, 0x85, 0xE5, 0x2B, 0xCB,
317     0xAB, 0x8D, 0x78, 0x6A, 0x68, 0x17, 0x8F, 0xA8, 0xFF, 0x7C, 0x2F, 0x5C,
318     0x71, 0x64, 0x8D, 0x6F
319 };
320
321 static const unsigned char dhtest_2048_224_xB[] = {
322     0x4F, 0xF3, 0xBC, 0x96, 0xC7, 0xFC, 0x6A, 0x6D, 0x71, 0xD3, 0xB3, 0x63,
323     0x80, 0x0A, 0x7C, 0xDF, 0xEF, 0x6F, 0xC4, 0x1B, 0x44, 0x17, 0xEA, 0x15,
324     0x35, 0x3B, 0x75, 0x90
325 };
326
327 static const unsigned char dhtest_2048_224_yB[] = {
328     0x4D, 0xCE, 0xE9, 0x92, 0xA9, 0x76, 0x2A, 0x13, 0xF2, 0xF8, 0x38, 0x44,
329     0xAD, 0x3D, 0x77, 0xEE, 0x0E, 0x31, 0xC9, 0x71, 0x8B, 0x3D, 0xB6, 0xC2,
330     0x03, 0x5D, 0x39, 0x61, 0x18, 0x2C, 0x3E, 0x0B, 0xA2, 0x47, 0xEC, 0x41,
331     0x82, 0xD7, 0x60, 0xCD, 0x48, 0xD9, 0x95, 0x99, 0x97, 0x06, 0x22, 0xA1,
332     0x88, 0x1B, 0xBA, 0x2D, 0xC8, 0x22, 0x93, 0x9C, 0x78, 0xC3, 0x91, 0x2C,
333     0x66, 0x61, 0xFA, 0x54, 0x38, 0xB2, 0x07, 0x66, 0x22, 0x2B, 0x75, 0xE2,
334     0x4C, 0x2E, 0x3A, 0xD0, 0xC7, 0x28, 0x72, 0x36, 0x12, 0x95, 0x25, 0xEE,
335     0x15, 0xB5, 0xDD, 0x79, 0x98, 0xAA, 0x04, 0xC4, 0xA9, 0x69, 0x6C, 0xAC,
336     0xD7, 0x17, 0x20, 0x83, 0xA9, 0x7A, 0x81, 0x66, 0x4E, 0xAD, 0x2C, 0x47,
337     0x9E, 0x44, 0x4E, 0x4C, 0x06, 0x54, 0xCC, 0x19, 0xE2, 0x8D, 0x77, 0x03,
338     0xCE, 0xE8, 0xDA, 0xCD, 0x61, 0x26, 0xF5, 0xD6, 0x65, 0xEC, 0x52, 0xC6,
339     0x72, 0x55, 0xDB, 0x92, 0x01, 0x4B, 0x03, 0x7E, 0xB6, 0x21, 0xA2, 0xAC,
340     0x8E, 0x36, 0x5D, 0xE0, 0x71, 0xFF, 0xC1, 0x40, 0x0A, 0xCF, 0x07, 0x7A,
341     0x12, 0x91, 0x3D, 0xD8, 0xDE, 0x89, 0x47, 0x34, 0x37, 0xAB, 0x7B, 0xA3,
342     0x46, 0x74, 0x3C, 0x1B, 0x21, 0x5D, 0xD9, 0xC1, 0x21, 0x64, 0xA7, 0xE4,
343     0x05, 0x31, 0x18, 0xD1, 0x99, 0xBE, 0xC8, 0xEF, 0x6F, 0xC5, 0x61, 0x17,
344     0x0C, 0x84, 0xC8, 0x7D, 0x10, 0xEE, 0x9A, 0x67, 0x4A, 0x1F, 0xA8, 0xFF,
345     0xE1, 0x3B, 0xDF, 0xBA, 0x1D, 0x44, 0xDE, 0x48, 0x94, 0x6D, 0x68, 0xDC,
346     0x0C, 0xDD, 0x77, 0x76, 0x35, 0xA7, 0xAB, 0x5B, 0xFB, 0x1E, 0x4B, 0xB7,
347     0xB8, 0x56, 0xF9, 0x68, 0x27, 0x73, 0x4C, 0x18, 0x41, 0x38, 0xE9, 0x15,
348     0xD9, 0xC3, 0x00, 0x2E, 0xBC, 0xE5, 0x31, 0x20, 0x54, 0x6A, 0x7E, 0x20,
349     0x02, 0x14, 0x2B, 0x6C
350 };
351
352 static const unsigned char dhtest_2048_224_Z[] = {
353     0x34, 0xD9, 0xBD, 0xDC, 0x1B, 0x42, 0x17, 0x6C, 0x31, 0x3F, 0xEA, 0x03,
354     0x4C, 0x21, 0x03, 0x4D, 0x07, 0x4A, 0x63, 0x13, 0xBB, 0x4E, 0xCD, 0xB3,
355     0x70, 0x3F, 0xFF, 0x42, 0x45, 0x67, 0xA4, 0x6B, 0xDF, 0x75, 0x53, 0x0E,
356     0xDE, 0x0A, 0x9D, 0xA5, 0x22, 0x9D, 0xE7, 0xD7, 0x67, 0x32, 0x28, 0x6C,
357     0xBC, 0x0F, 0x91, 0xDA, 0x4C, 0x3C, 0x85, 0x2F, 0xC0, 0x99, 0xC6, 0x79,
358     0x53, 0x1D, 0x94, 0xC7, 0x8A, 0xB0, 0x3D, 0x9D, 0xEC, 0xB0, 0xA4, 0xE4,
359     0xCA, 0x8B, 0x2B, 0xB4, 0x59, 0x1C, 0x40, 0x21, 0xCF, 0x8C, 0xE3, 0xA2,
360     0x0A, 0x54, 0x1D, 0x33, 0x99, 0x40, 0x17, 0xD0, 0x20, 0x0A, 0xE2, 0xC9,
361     0x51, 0x6E, 0x2F, 0xF5, 0x14, 0x57, 0x79, 0x26, 0x9E, 0x86, 0x2B, 0x0F,
362     0xB4, 0x74, 0xA2, 0xD5, 0x6D, 0xC3, 0x1E, 0xD5, 0x69, 0xA7, 0x70, 0x0B,
363     0x4C, 0x4A, 0xB1, 0x6B, 0x22, 0xA4, 0x55, 0x13, 0x53, 0x1E, 0xF5, 0x23,
364     0xD7, 0x12, 0x12, 0x07, 0x7B, 0x5A, 0x16, 0x9B, 0xDE, 0xFF, 0xAD, 0x7A,
365     0xD9, 0x60, 0x82, 0x84, 0xC7, 0x79, 0x5B, 0x6D, 0x5A, 0x51, 0x83, 0xB8,
366     0x70, 0x66, 0xDE, 0x17, 0xD8, 0xD6, 0x71, 0xC9, 0xEB, 0xD8, 0xEC, 0x89,
367     0x54, 0x4D, 0x45, 0xEC, 0x06, 0x15, 0x93, 0xD4, 0x42, 0xC6, 0x2A, 0xB9,
368     0xCE, 0x3B, 0x1C, 0xB9, 0x94, 0x3A, 0x1D, 0x23, 0xA5, 0xEA, 0x3B, 0xCF,
369     0x21, 0xA0, 0x14, 0x71, 0xE6, 0x7E, 0x00, 0x3E, 0x7F, 0x8A, 0x69, 0xC7,
370     0x28, 0xBE, 0x49, 0x0B, 0x2F, 0xC8, 0x8C, 0xFE, 0xB9, 0x2D, 0xB6, 0xA2,
371     0x15, 0xE5, 0xD0, 0x3C, 0x17, 0xC4, 0x64, 0xC9, 0xAC, 0x1A, 0x46, 0xE2,
372     0x03, 0xE1, 0x3F, 0x95, 0x29, 0x95, 0xFB, 0x03, 0xC6, 0x9D, 0x3C, 0xC4,
373     0x7F, 0xCB, 0x51, 0x0B, 0x69, 0x98, 0xFF, 0xD3, 0xAA, 0x6D, 0xE7, 0x3C,
374     0xF9, 0xF6, 0x38, 0x69
375 };
376
377 static const unsigned char dhtest_2048_256_xA[] = {
378     0x08, 0x81, 0x38, 0x2C, 0xDB, 0x87, 0x66, 0x0C, 0x6D, 0xC1, 0x3E, 0x61,
379     0x49, 0x38, 0xD5, 0xB9, 0xC8, 0xB2, 0xF2, 0x48, 0x58, 0x1C, 0xC5, 0xE3,
380     0x1B, 0x35, 0x45, 0x43, 0x97, 0xFC, 0xE5, 0x0E
381 };
382
383 static const unsigned char dhtest_2048_256_yA[] = {
384     0x2E, 0x93, 0x80, 0xC8, 0x32, 0x3A, 0xF9, 0x75, 0x45, 0xBC, 0x49, 0x41,
385     0xDE, 0xB0, 0xEC, 0x37, 0x42, 0xC6, 0x2F, 0xE0, 0xEC, 0xE8, 0x24, 0xA6,
386     0xAB, 0xDB, 0xE6, 0x6C, 0x59, 0xBE, 0xE0, 0x24, 0x29, 0x11, 0xBF, 0xB9,
387     0x67, 0x23, 0x5C, 0xEB, 0xA3, 0x5A, 0xE1, 0x3E, 0x4E, 0xC7, 0x52, 0xBE,
388     0x63, 0x0B, 0x92, 0xDC, 0x4B, 0xDE, 0x28, 0x47, 0xA9, 0xC6, 0x2C, 0xB8,
389     0x15, 0x27, 0x45, 0x42, 0x1F, 0xB7, 0xEB, 0x60, 0xA6, 0x3C, 0x0F, 0xE9,
390     0x15, 0x9F, 0xCC, 0xE7, 0x26, 0xCE, 0x7C, 0xD8, 0x52, 0x3D, 0x74, 0x50,
391     0x66, 0x7E, 0xF8, 0x40, 0xE4, 0x91, 0x91, 0x21, 0xEB, 0x5F, 0x01, 0xC8,
392     0xC9, 0xB0, 0xD3, 0xD6, 0x48, 0xA9, 0x3B, 0xFB, 0x75, 0x68, 0x9E, 0x82,
393     0x44, 0xAC, 0x13, 0x4A, 0xF5, 0x44, 0x71, 0x1C, 0xE7, 0x9A, 0x02, 0xDC,
394     0xC3, 0x42, 0x26, 0x68, 0x47, 0x80, 0xDD, 0xDC, 0xB4, 0x98, 0x59, 0x41,
395     0x06, 0xC3, 0x7F, 0x5B, 0xC7, 0x98, 0x56, 0x48, 0x7A, 0xF5, 0xAB, 0x02,
396     0x2A, 0x2E, 0x5E, 0x42, 0xF0, 0x98, 0x97, 0xC1, 0xA8, 0x5A, 0x11, 0xEA,
397     0x02, 0x12, 0xAF, 0x04, 0xD9, 0xB4, 0xCE, 0xBC, 0x93, 0x7C, 0x3C, 0x1A,
398     0x3E, 0x15, 0xA8, 0xA0, 0x34, 0x2E, 0x33, 0x76, 0x15, 0xC8, 0x4E, 0x7F,
399     0xE3, 0xB8, 0xB9, 0xB8, 0x7F, 0xB1, 0xE7, 0x3A, 0x15, 0xAF, 0x12, 0xA3,
400     0x0D, 0x74, 0x6E, 0x06, 0xDF, 0xC3, 0x4F, 0x29, 0x0D, 0x79, 0x7C, 0xE5,
401     0x1A, 0xA1, 0x3A, 0xA7, 0x85, 0xBF, 0x66, 0x58, 0xAF, 0xF5, 0xE4, 0xB0,
402     0x93, 0x00, 0x3C, 0xBE, 0xAF, 0x66, 0x5B, 0x3C, 0x2E, 0x11, 0x3A, 0x3A,
403     0x4E, 0x90, 0x52, 0x69, 0x34, 0x1D, 0xC0, 0x71, 0x14, 0x26, 0x68, 0x5F,
404     0x4E, 0xF3, 0x7E, 0x86, 0x8A, 0x81, 0x26, 0xFF, 0x3F, 0x22, 0x79, 0xB5,
405     0x7C, 0xA6, 0x7E, 0x29
406 };
407
408 static const unsigned char dhtest_2048_256_xB[] = {
409     0x7D, 0x62, 0xA7, 0xE3, 0xEF, 0x36, 0xDE, 0x61, 0x7B, 0x13, 0xD1, 0xAF,
410     0xB8, 0x2C, 0x78, 0x0D, 0x83, 0xA2, 0x3B, 0xD4, 0xEE, 0x67, 0x05, 0x64,
411     0x51, 0x21, 0xF3, 0x71, 0xF5, 0x46, 0xA5, 0x3D
412 };
413
414 static const unsigned char dhtest_2048_256_yB[] = {
415     0x57, 0x5F, 0x03, 0x51, 0xBD, 0x2B, 0x1B, 0x81, 0x74, 0x48, 0xBD, 0xF8,
416     0x7A, 0x6C, 0x36, 0x2C, 0x1E, 0x28, 0x9D, 0x39, 0x03, 0xA3, 0x0B, 0x98,
417     0x32, 0xC5, 0x74, 0x1F, 0xA2, 0x50, 0x36, 0x3E, 0x7A, 0xCB, 0xC7, 0xF7,
418     0x7F, 0x3D, 0xAC, 0xBC, 0x1F, 0x13, 0x1A, 0xDD, 0x8E, 0x03, 0x36, 0x7E,
419     0xFF, 0x8F, 0xBB, 0xB3, 0xE1, 0xC5, 0x78, 0x44, 0x24, 0x80, 0x9B, 0x25,
420     0xAF, 0xE4, 0xD2, 0x26, 0x2A, 0x1A, 0x6F, 0xD2, 0xFA, 0xB6, 0x41, 0x05,
421     0xCA, 0x30, 0xA6, 0x74, 0xE0, 0x7F, 0x78, 0x09, 0x85, 0x20, 0x88, 0x63,
422     0x2F, 0xC0, 0x49, 0x23, 0x37, 0x91, 0xAD, 0x4E, 0xDD, 0x08, 0x3A, 0x97,
423     0x8B, 0x88, 0x3E, 0xE6, 0x18, 0xBC, 0x5E, 0x0D, 0xD0, 0x47, 0x41, 0x5F,
424     0x2D, 0x95, 0xE6, 0x83, 0xCF, 0x14, 0x82, 0x6B, 0x5F, 0xBE, 0x10, 0xD3,
425     0xCE, 0x41, 0xC6, 0xC1, 0x20, 0xC7, 0x8A, 0xB2, 0x00, 0x08, 0xC6, 0x98,
426     0xBF, 0x7F, 0x0B, 0xCA, 0xB9, 0xD7, 0xF4, 0x07, 0xBE, 0xD0, 0xF4, 0x3A,
427     0xFB, 0x29, 0x70, 0xF5, 0x7F, 0x8D, 0x12, 0x04, 0x39, 0x63, 0xE6, 0x6D,
428     0xDD, 0x32, 0x0D, 0x59, 0x9A, 0xD9, 0x93, 0x6C, 0x8F, 0x44, 0x13, 0x7C,
429     0x08, 0xB1, 0x80, 0xEC, 0x5E, 0x98, 0x5C, 0xEB, 0xE1, 0x86, 0xF3, 0xD5,
430     0x49, 0x67, 0x7E, 0x80, 0x60, 0x73, 0x31, 0xEE, 0x17, 0xAF, 0x33, 0x80,
431     0xA7, 0x25, 0xB0, 0x78, 0x23, 0x17, 0xD7, 0xDD, 0x43, 0xF5, 0x9D, 0x7A,
432     0xF9, 0x56, 0x8A, 0x9B, 0xB6, 0x3A, 0x84, 0xD3, 0x65, 0xF9, 0x22, 0x44,
433     0xED, 0x12, 0x09, 0x88, 0x21, 0x93, 0x02, 0xF4, 0x29, 0x24, 0xC7, 0xCA,
434     0x90, 0xB8, 0x9D, 0x24, 0xF7, 0x1B, 0x0A, 0xB6, 0x97, 0x82, 0x3D, 0x7D,
435     0xEB, 0x1A, 0xFF, 0x5B, 0x0E, 0x8E, 0x4A, 0x45, 0xD4, 0x9F, 0x7F, 0x53,
436     0x75, 0x7E, 0x19, 0x13
437 };
438
439 static const unsigned char dhtest_2048_256_Z[] = {
440     0x86, 0xC7, 0x0B, 0xF8, 0xD0, 0xBB, 0x81, 0xBB, 0x01, 0x07, 0x8A, 0x17,
441     0x21, 0x9C, 0xB7, 0xD2, 0x72, 0x03, 0xDB, 0x2A, 0x19, 0xC8, 0x77, 0xF1,
442     0xD1, 0xF1, 0x9F, 0xD7, 0xD7, 0x7E, 0xF2, 0x25, 0x46, 0xA6, 0x8F, 0x00,
443     0x5A, 0xD5, 0x2D, 0xC8, 0x45, 0x53, 0xB7, 0x8F, 0xC6, 0x03, 0x30, 0xBE,
444     0x51, 0xEA, 0x7C, 0x06, 0x72, 0xCA, 0xC1, 0x51, 0x5E, 0x4B, 0x35, 0xC0,
445     0x47, 0xB9, 0xA5, 0x51, 0xB8, 0x8F, 0x39, 0xDC, 0x26, 0xDA, 0x14, 0xA0,
446     0x9E, 0xF7, 0x47, 0x74, 0xD4, 0x7C, 0x76, 0x2D, 0xD1, 0x77, 0xF9, 0xED,
447     0x5B, 0xC2, 0xF1, 0x1E, 0x52, 0xC8, 0x79, 0xBD, 0x95, 0x09, 0x85, 0x04,
448     0xCD, 0x9E, 0xEC, 0xD8, 0xA8, 0xF9, 0xB3, 0xEF, 0xBD, 0x1F, 0x00, 0x8A,
449     0xC5, 0x85, 0x30, 0x97, 0xD9, 0xD1, 0x83, 0x7F, 0x2B, 0x18, 0xF7, 0x7C,
450     0xD7, 0xBE, 0x01, 0xAF, 0x80, 0xA7, 0xC7, 0xB5, 0xEA, 0x3C, 0xA5, 0x4C,
451     0xC0, 0x2D, 0x0C, 0x11, 0x6F, 0xEE, 0x3F, 0x95, 0xBB, 0x87, 0x39, 0x93,
452     0x85, 0x87, 0x5D, 0x7E, 0x86, 0x74, 0x7E, 0x67, 0x6E, 0x72, 0x89, 0x38,
453     0xAC, 0xBF, 0xF7, 0x09, 0x8E, 0x05, 0xBE, 0x4D, 0xCF, 0xB2, 0x40, 0x52,
454     0xB8, 0x3A, 0xEF, 0xFB, 0x14, 0x78, 0x3F, 0x02, 0x9A, 0xDB, 0xDE, 0x7F,
455     0x53, 0xFA, 0xE9, 0x20, 0x84, 0x22, 0x40, 0x90, 0xE0, 0x07, 0xCE, 0xE9,
456     0x4D, 0x4B, 0xF2, 0xBA, 0xCE, 0x9F, 0xFD, 0x4B, 0x57, 0xD2, 0xAF, 0x7C,
457     0x72, 0x4D, 0x0C, 0xAA, 0x19, 0xBF, 0x05, 0x01, 0xF6, 0xF1, 0x7B, 0x4A,
458     0xA1, 0x0F, 0x42, 0x5E, 0x3E, 0xA7, 0x60, 0x80, 0xB4, 0xB9, 0xD6, 0xB3,
459     0xCE, 0xFE, 0xA1, 0x15, 0xB2, 0xCE, 0xB8, 0x78, 0x9B, 0xB8, 0xA3, 0xB0,
460     0xEA, 0x87, 0xFE, 0xBE, 0x63, 0xB6, 0xC8, 0xF8, 0x46, 0xEC, 0x6D, 0xB0,
461     0xC2, 0x6C, 0x5D, 0x7C
462 };
463
464 static const unsigned char dhtest_rfc5114_2048_224_bad_y[] = {
465     0x45, 0x32, 0x5F, 0x51, 0x07, 0xE5, 0xDF, 0x1C, 0xD6, 0x02, 0x82, 0xB3,
466     0x32, 0x8F, 0xA4, 0x0F, 0x87, 0xB8, 0x41, 0xFE, 0xB9, 0x35, 0xDE, 0xAD,
467     0xC6, 0x26, 0x85, 0xB4, 0xFF, 0x94, 0x8C, 0x12, 0x4C, 0xBF, 0x5B, 0x20,
468     0xC4, 0x46, 0xA3, 0x26, 0xEB, 0xA4, 0x25, 0xB7, 0x68, 0x8E, 0xCC, 0x67,
469     0xBA, 0xEA, 0x58, 0xD0, 0xF2, 0xE9, 0xD2, 0x24, 0x72, 0x60, 0xDA, 0x88,
470     0x18, 0x9C, 0xE0, 0x31, 0x6A, 0xAD, 0x50, 0x6D, 0x94, 0x35, 0x8B, 0x83,
471     0x4A, 0x6E, 0xFA, 0x48, 0x73, 0x0F, 0x83, 0x87, 0xFF, 0x6B, 0x66, 0x1F,
472     0xA8, 0x82, 0xC6, 0x01, 0xE5, 0x80, 0xB5, 0xB0, 0x52, 0xD0, 0xE9, 0xD8,
473     0x72, 0xF9, 0x7D, 0x5B, 0x8B, 0xA5, 0x4C, 0xA5, 0x25, 0x95, 0x74, 0xE2,
474     0x7A, 0x61, 0x4E, 0xA7, 0x8F, 0x12, 0xE2, 0xD2, 0x9D, 0x8C, 0x02, 0x70,
475     0x34, 0x44, 0x32, 0xC7, 0xB2, 0xF3, 0xB9, 0xFE, 0x17, 0x2B, 0xD6, 0x1F,
476     0x8B, 0x7E, 0x4A, 0xFA, 0xA3, 0xB5, 0x3E, 0x7A, 0x81, 0x9A, 0x33, 0x66,
477     0x62, 0xA4, 0x50, 0x18, 0x3E, 0xA2, 0x5F, 0x00, 0x07, 0xD8, 0x9B, 0x22,
478     0xE4, 0xEC, 0x84, 0xD5, 0xEB, 0x5A, 0xF3, 0x2A, 0x31, 0x23, 0xD8, 0x44,
479     0x22, 0x2A, 0x8B, 0x37, 0x44, 0xCC, 0xC6, 0x87, 0x4B, 0xBE, 0x50, 0x9D,
480     0x4A, 0xC4, 0x8E, 0x45, 0xCF, 0x72, 0x4D, 0xC0, 0x89, 0xB3, 0x72, 0xED,
481     0x33, 0x2C, 0xBC, 0x7F, 0x16, 0x39, 0x3B, 0xEB, 0xD2, 0xDD, 0xA8, 0x01,
482     0x73, 0x84, 0x62, 0xB9, 0x29, 0xD2, 0xC9, 0x51, 0x32, 0x9E, 0x7A, 0x6A,
483     0xCF, 0xC1, 0x0A, 0xDB, 0x0E, 0xE0, 0x62, 0x77, 0x6F, 0x59, 0x62, 0x72,
484     0x5A, 0x69, 0xA6, 0x5B, 0x70, 0xCA, 0x65, 0xC4, 0x95, 0x6F, 0x9A, 0xC2,
485     0xDF, 0x72, 0x6D, 0xB1, 0x1E, 0x54, 0x7B, 0x51, 0xB4, 0xEF, 0x7F, 0x89,
486     0x93, 0x74, 0x89, 0x59
487 };
488
489 typedef struct {
490     DH *(*get_param) (void);
491     const unsigned char *xA;
492     size_t xA_len;
493     const unsigned char *yA;
494     size_t yA_len;
495     const unsigned char *xB;
496     size_t xB_len;
497     const unsigned char *yB;
498     size_t yB_len;
499     const unsigned char *Z;
500     size_t Z_len;
501 } rfc5114_td;
502
503 # define make_rfc5114_td(pre) { \
504         DH_get_##pre, \
505         dhtest_##pre##_xA, sizeof(dhtest_##pre##_xA), \
506         dhtest_##pre##_yA, sizeof(dhtest_##pre##_yA), \
507         dhtest_##pre##_xB, sizeof(dhtest_##pre##_xB), \
508         dhtest_##pre##_yB, sizeof(dhtest_##pre##_yB), \
509         dhtest_##pre##_Z, sizeof(dhtest_##pre##_Z) \
510         }
511
512 static const rfc5114_td rfctd[] = {
513         make_rfc5114_td(1024_160),
514         make_rfc5114_td(2048_224),
515         make_rfc5114_td(2048_256)
516 };
517
518 static int rfc5114_test(void)
519 {
520     int i;
521     DH *dhA = NULL;
522     DH *dhB = NULL;
523     unsigned char *Z1 = NULL;
524     unsigned char *Z2 = NULL;
525     const rfc5114_td *td = NULL;
526     BIGNUM *bady = NULL, *priv_key = NULL, *pub_key = NULL;
527     const BIGNUM *pub_key_tmp;
528
529     for (i = 0; i < (int)OSSL_NELEM(rfctd); i++) {
530         td = rfctd + i;
531         /* Set up DH structures setting key components */
532         if (!TEST_ptr(dhA = td->get_param())
533                 || !TEST_ptr(dhB = td->get_param()))
534             goto bad_err;
535
536         if (!TEST_ptr(priv_key = BN_bin2bn(td->xA, td->xA_len, NULL))
537                 || !TEST_ptr(pub_key = BN_bin2bn(td->yA, td->yA_len, NULL))
538                 || !TEST_true(DH_set0_key(dhA, pub_key, priv_key)))
539             goto bad_err;
540
541         if (!TEST_ptr(priv_key = BN_bin2bn(td->xB, td->xB_len, NULL))
542                 || !TEST_ptr(pub_key = BN_bin2bn(td->yB, td->yB_len, NULL))
543                 || !TEST_true( DH_set0_key(dhB, pub_key, priv_key)))
544             goto bad_err;
545         priv_key = pub_key = NULL;
546
547         if (!TEST_uint_eq(td->Z_len, (size_t)DH_size(dhA))
548             || !TEST_uint_eq(td->Z_len, (size_t)DH_size(dhB)))
549             goto err;
550
551         if (!TEST_ptr(Z1 = OPENSSL_malloc(DH_size(dhA)))
552                 || !TEST_ptr(Z2 = OPENSSL_malloc(DH_size(dhB))))
553             goto bad_err;
554         /*
555          * Work out shared secrets using both sides and compare with expected
556          * values.
557          */
558         DH_get0_key(dhB, &pub_key_tmp, NULL);
559         if (!TEST_int_ne(DH_compute_key(Z1, pub_key_tmp, dhA), -1))
560             goto bad_err;
561
562         DH_get0_key(dhA, &pub_key_tmp, NULL);
563         if (!TEST_int_ne(DH_compute_key(Z2, pub_key_tmp, dhB), -1))
564             goto bad_err;
565
566         if (!TEST_mem_eq(Z1, td->Z_len, td->Z, td->Z_len)
567                 || !TEST_mem_eq(Z2, td->Z_len, td->Z, td->Z_len))
568             goto err;
569
570         DH_free(dhA);
571         dhA = NULL;
572         DH_free(dhB);
573         dhB = NULL;
574         OPENSSL_free(Z1);
575         Z1 = NULL;
576         OPENSSL_free(Z2);
577         Z2 = NULL;
578     }
579
580     /* Now i == OSSL_NELEM(rfctd) */
581     /* RFC5114 uses unsafe primes, so now test an invalid y value */
582     if (!TEST_ptr(dhA = DH_get_2048_224())
583             || !TEST_ptr(Z1 = OPENSSL_malloc(DH_size(dhA))))
584         goto bad_err;
585
586     if (!TEST_ptr(bady = BN_bin2bn(dhtest_rfc5114_2048_224_bad_y,
587                                    sizeof(dhtest_rfc5114_2048_224_bad_y),
588                                    NULL)))
589         goto bad_err;
590
591     if (!DH_generate_key(dhA))
592         goto bad_err;
593
594     if (DH_compute_key(Z1, bady, dhA) != -1) {
595         /*
596          * DH_compute_key should fail with -1. If we get here we unexpectedly
597          * allowed an invalid y value
598          */
599         goto err;
600     }
601     /* We'll have a stale error on the queue from the above test so clear it */
602     ERR_clear_error();
603     BN_free(bady);
604     DH_free(dhA);
605     OPENSSL_free(Z1);
606     return 1;
607
608  bad_err:
609     BN_free(bady);
610     DH_free(dhA);
611     DH_free(dhB);
612     BN_free(pub_key);
613     BN_free(priv_key);
614     OPENSSL_free(Z1);
615     OPENSSL_free(Z2);
616     TEST_error("Initialisation error RFC5114 set %d\n", i + 1);
617     return 0;
618
619  err:
620     BN_free(bady);
621     DH_free(dhA);
622     DH_free(dhB);
623     OPENSSL_free(Z1);
624     OPENSSL_free(Z2);
625     TEST_error("Test failed RFC5114 set %d\n", i + 1);
626     return 0;
627 }
628
629 static int rfc7919_test(void)
630 {
631     DH *a = NULL, *b = NULL;
632     const BIGNUM *apub_key = NULL, *bpub_key = NULL;
633     unsigned char *abuf = NULL;
634     unsigned char *bbuf = NULL;
635     int i, alen, blen, aout, bout;
636     int ret = 0;
637
638     if (!TEST_ptr(a = DH_new_by_nid(NID_ffdhe2048)))
639          goto err;
640
641     if (!DH_check(a, &i))
642         goto err;
643     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
644             || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
645             || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
646             || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
647             || !TEST_false(i))
648         goto err;
649
650     if (!DH_generate_key(a))
651         goto err;
652     DH_get0_key(a, &apub_key, NULL);
653
654     /* now create another copy of the DH group for the peer */
655     if (!TEST_ptr(b = DH_new_by_nid(NID_ffdhe2048)))
656         goto err;
657
658     if (!DH_generate_key(b))
659         goto err;
660     DH_get0_key(b, &bpub_key, NULL);
661
662     alen = DH_size(a);
663     if (!TEST_ptr(abuf = OPENSSL_malloc(alen))
664             || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
665         goto err;
666
667     blen = DH_size(b);
668     if (!TEST_ptr(bbuf = OPENSSL_malloc(blen))
669             || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
670         goto err;
671
672     if (!TEST_true(aout >= 20)
673             || !TEST_mem_eq(abuf, aout, bbuf, bout))
674         goto err;
675
676     ret = 1;
677
678  err:
679     OPENSSL_free(abuf);
680     OPENSSL_free(bbuf);
681     DH_free(a);
682     DH_free(b);
683     return ret;
684 }
685
686 static int prime_groups[] = {
687     NID_ffdhe2048,
688     NID_ffdhe3072,
689     NID_ffdhe4096,
690     NID_ffdhe6144,
691     NID_ffdhe8192,
692     NID_modp_2048,
693     NID_modp_3072,
694     NID_modp_4096,
695     NID_modp_6144,
696 };
697
698 static int dh_test_prime_groups(int index)
699 {
700     int ok = 0;
701     DH *dh = NULL;
702     const BIGNUM *p, *q, *g;
703     long len;
704
705     if (!TEST_ptr(dh = DH_new_by_nid(prime_groups[index])))
706         goto err;
707     DH_get0_pqg(dh, &p, &q, &g);
708     if (!TEST_ptr(p) || !TEST_ptr(q) || !TEST_ptr(g))
709         goto err;
710
711     if (!TEST_int_eq(DH_get_nid(dh), prime_groups[index]))
712         goto err;
713
714     len = DH_get_length(dh);
715     if (!TEST_true(len > 0)
716         || !TEST_true(len <= BN_num_bits(q)))
717         goto err;
718
719     ok = 1;
720 err:
721     DH_free(dh);
722     return ok;
723 }
724
725 static int dh_get_nid(void)
726 {
727     int ok = 0;
728     const BIGNUM *p, *q, *g;
729     BIGNUM *pcpy = NULL, *gcpy = NULL, *qcpy = NULL;
730     DH *dh1 = DH_new_by_nid(NID_ffdhe2048);
731     DH *dh2 = DH_new();
732
733     if (!TEST_ptr(dh1)
734         || !TEST_ptr(dh2))
735         goto err;
736
737     /* Set new DH parameters manually using a existing named group's p & g */
738     DH_get0_pqg(dh1, &p, &q, &g);
739     if (!TEST_ptr(p)
740         || !TEST_ptr(q)
741         || !TEST_ptr(g)
742         || !TEST_ptr(pcpy = BN_dup(p))
743         || !TEST_ptr(gcpy = BN_dup(g)))
744         goto err;
745
746     if (!TEST_true(DH_set0_pqg(dh2, pcpy, NULL, gcpy)))
747         goto err;
748     pcpy = gcpy = NULL;
749     /* Test q is set if p and g are provided */
750     if (!TEST_ptr(DH_get0_q(dh2)))
751         goto err;
752
753     /* Test that setting p & g manually returns that it is a named group */
754     if (!TEST_int_eq(DH_get_nid(dh2), NID_ffdhe2048))
755         goto err;
756
757     /* Test that after changing g it is no longer a named group */
758     if (!TEST_ptr(gcpy = BN_dup(BN_value_one())))
759        goto err;
760     if (!TEST_true(DH_set0_pqg(dh2, NULL, NULL, gcpy)))
761        goto err;
762     gcpy = NULL;
763     if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
764         goto err;
765
766     /* Test that setting an incorrect q results in this not being a named group */
767     if (!TEST_ptr(pcpy = BN_dup(p))
768         || !TEST_ptr(qcpy = BN_dup(q))
769         || !TEST_ptr(gcpy = BN_dup(g))
770         || !TEST_int_eq(BN_add_word(qcpy, 2), 1)
771         || !TEST_true(DH_set0_pqg(dh2, pcpy, qcpy, gcpy)))
772         goto err;
773     pcpy = qcpy = gcpy = NULL;
774     if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
775         goto err;
776
777     ok = 1;
778 err:
779     BN_free(pcpy);
780     BN_free(qcpy);
781     BN_free(gcpy);
782     DH_free(dh2);
783     DH_free(dh1);
784     return ok;
785 }
786
787 #endif
788
789
790 int setup_tests(void)
791 {
792 #ifdef OPENSSL_NO_DH
793     TEST_note("No DH support");
794 #else
795     ADD_TEST(dh_test);
796     ADD_TEST(rfc5114_test);
797     ADD_TEST(rfc7919_test);
798     ADD_ALL_TESTS(dh_test_prime_groups, OSSL_NELEM(prime_groups));
799     ADD_TEST(dh_get_nid);
800 #endif
801     return 1;
802 }