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