xref: /freebsd/crypto/openssl/test/dhtest.c (revision f126890ac5386406dadf7c4cfa9566cbb56537c5)
1 /*
2  * Copyright 1995-2023 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 <openssl/core_names.h>
28 #include "testutil.h"
29 
30 #ifndef OPENSSL_NO_DH
31 # include <openssl/dh.h>
32 # include "crypto/bn_dh.h"
33 # include "crypto/dh.h"
34 
35 static int cb(int p, int n, BN_GENCB *arg);
36 
37 static int dh_test(void)
38 {
39     DH *dh = NULL;
40     BIGNUM *p = NULL, *q = NULL, *g = NULL;
41     const BIGNUM *p2, *q2, *g2;
42     BIGNUM *priv_key = NULL;
43     const BIGNUM *pub_key2, *priv_key2;
44     BN_GENCB *_cb = NULL;
45     DH *a = NULL;
46     DH *b = NULL;
47     DH *c = NULL;
48     const BIGNUM *ap = NULL, *ag = NULL, *apub_key = NULL;
49     const BIGNUM *bpub_key = NULL, *bpriv_key = NULL;
50     BIGNUM *bp = NULL, *bg = NULL, *cpriv_key = NULL;
51     unsigned char *abuf = NULL;
52     unsigned char *bbuf = NULL;
53     unsigned char *cbuf = NULL;
54     int i, alen, blen, clen, aout, bout, cout;
55     int ret = 0;
56 
57     if (!TEST_ptr(dh = DH_new())
58         || !TEST_ptr(p = BN_new())
59         || !TEST_ptr(q = BN_new())
60         || !TEST_ptr(g = BN_new())
61         || !TEST_ptr(priv_key = BN_new()))
62         goto err1;
63 
64     /*
65      * I) basic tests
66      */
67 
68     /* using a small predefined Sophie Germain DH group with generator 3 */
69     if (!TEST_true(BN_set_word(p, 4079L))
70         || !TEST_true(BN_set_word(q, 2039L))
71         || !TEST_true(BN_set_word(g, 3L))
72         || !TEST_true(DH_set0_pqg(dh, p, q, g)))
73         goto err1;
74 
75     /* check fails, because p is way too small */
76     if (!TEST_true(DH_check(dh, &i)))
77         goto err2;
78     i ^= DH_MODULUS_TOO_SMALL;
79     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
80             || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
81             || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
82             || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
83             || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
84             || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
85             || !TEST_false(i & DH_CHECK_INVALID_J_VALUE)
86             || !TEST_false(i & DH_MODULUS_TOO_SMALL)
87             || !TEST_false(i & DH_MODULUS_TOO_LARGE)
88             || !TEST_false(i))
89         goto err2;
90 
91     /* test the combined getter for p, q, and g */
92     DH_get0_pqg(dh, &p2, &q2, &g2);
93     if (!TEST_ptr_eq(p2, p)
94         || !TEST_ptr_eq(q2, q)
95         || !TEST_ptr_eq(g2, g))
96         goto err2;
97 
98     /* test the simple getters for p, q, and g */
99     if (!TEST_ptr_eq(DH_get0_p(dh), p2)
100         || !TEST_ptr_eq(DH_get0_q(dh), q2)
101         || !TEST_ptr_eq(DH_get0_g(dh), g2))
102         goto err2;
103 
104     /* set the private key only*/
105     if (!TEST_true(BN_set_word(priv_key, 1234L))
106         || !TEST_true(DH_set0_key(dh, NULL, priv_key)))
107         goto err2;
108 
109     /* test the combined getter for pub_key and priv_key */
110     DH_get0_key(dh, &pub_key2, &priv_key2);
111     if (!TEST_ptr_eq(pub_key2, NULL)
112         || !TEST_ptr_eq(priv_key2, priv_key))
113         goto err3;
114 
115     /* test the simple getters for pub_key and priv_key */
116     if (!TEST_ptr_eq(DH_get0_pub_key(dh), pub_key2)
117         || !TEST_ptr_eq(DH_get0_priv_key(dh), priv_key2))
118         goto err3;
119 
120     /* now generate a key pair (expect failure since modulus is too small) */
121     if (!TEST_false(DH_generate_key(dh)))
122         goto err3;
123 
124     /* We'll have a stale error on the queue from the above test so clear it */
125     ERR_clear_error();
126 
127     if (!TEST_ptr(BN_copy(q, p)) || !TEST_true(BN_add(q, q, BN_value_one())))
128         goto err3;
129 
130     if (!TEST_true(DH_check(dh, &i)))
131         goto err3;
132     if (!TEST_true(i & DH_CHECK_INVALID_Q_VALUE)
133         || !TEST_false(i & DH_CHECK_Q_NOT_PRIME))
134         goto err3;
135 
136     /* Modulus of size: dh check max modulus bits + 1 */
137     if (!TEST_true(BN_set_word(p, 1))
138             || !TEST_true(BN_lshift(p, p, OPENSSL_DH_CHECK_MAX_MODULUS_BITS)))
139         goto err3;
140 
141     /*
142      * We expect no checks at all for an excessively large modulus
143      */
144     if (!TEST_false(DH_check(dh, &i)))
145         goto err3;
146 
147     /* We'll have a stale error on the queue from the above test so clear it */
148     ERR_clear_error();
149 
150     /*
151      * II) key generation
152      */
153 
154     /* generate a DH group ... */
155     if (!TEST_ptr(_cb = BN_GENCB_new()))
156         goto err3;
157     BN_GENCB_set(_cb, &cb, NULL);
158     if (!TEST_ptr(a = DH_new())
159             || !TEST_true(DH_generate_parameters_ex(a, 512,
160                                                     DH_GENERATOR_5, _cb)))
161         goto err3;
162 
163     /* ... and check whether it is valid */
164     if (!TEST_true(DH_check(a, &i)))
165         goto err3;
166     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
167             || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
168             || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
169             || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
170             || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
171             || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
172             || !TEST_false(i & DH_CHECK_INVALID_J_VALUE)
173             || !TEST_false(i & DH_MODULUS_TOO_SMALL)
174             || !TEST_false(i & DH_MODULUS_TOO_LARGE)
175             || !TEST_false(i))
176         goto err3;
177 
178     DH_get0_pqg(a, &ap, NULL, &ag);
179 
180     /* now create another copy of the DH group for the peer */
181     if (!TEST_ptr(b = DH_new()))
182         goto err3;
183 
184     if (!TEST_ptr(bp = BN_dup(ap))
185             || !TEST_ptr(bg = BN_dup(ag))
186             || !TEST_true(DH_set0_pqg(b, bp, NULL, bg)))
187         goto err3;
188     bp = bg = NULL;
189 
190     /*
191      * III) simulate a key exchange
192      */
193 
194     if (!DH_generate_key(a))
195         goto err3;
196     DH_get0_key(a, &apub_key, NULL);
197 
198     if (!DH_generate_key(b))
199         goto err3;
200     DH_get0_key(b, &bpub_key, &bpriv_key);
201 
202     /* Also test with a private-key-only copy of |b|. */
203     if (!TEST_ptr(c = DHparams_dup(b))
204             || !TEST_ptr(cpriv_key = BN_dup(bpriv_key))
205             || !TEST_true(DH_set0_key(c, NULL, cpriv_key)))
206         goto err3;
207     cpriv_key = NULL;
208 
209     alen = DH_size(a);
210     if (!TEST_ptr(abuf = OPENSSL_malloc(alen))
211             || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
212         goto err3;
213 
214     blen = DH_size(b);
215     if (!TEST_ptr(bbuf = OPENSSL_malloc(blen))
216             || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
217         goto err3;
218 
219     clen = DH_size(c);
220     if (!TEST_ptr(cbuf = OPENSSL_malloc(clen))
221             || !TEST_true((cout = DH_compute_key(cbuf, apub_key, c)) != -1))
222         goto err3;
223 
224     if (!TEST_true(aout >= 20)
225             || !TEST_mem_eq(abuf, aout, bbuf, bout)
226             || !TEST_mem_eq(abuf, aout, cbuf, cout))
227         goto err3;
228 
229     ret = 1;
230     goto success;
231 
232  err1:
233     /* an error occurred before p,q,g were assigned to dh */
234     BN_free(p);
235     BN_free(q);
236     BN_free(g);
237  err2:
238     /* an error occurred before priv_key was assigned to dh */
239     BN_free(priv_key);
240  err3:
241  success:
242     OPENSSL_free(abuf);
243     OPENSSL_free(bbuf);
244     OPENSSL_free(cbuf);
245     DH_free(b);
246     DH_free(a);
247     DH_free(c);
248     BN_free(bp);
249     BN_free(bg);
250     BN_free(cpriv_key);
251     BN_GENCB_free(_cb);
252     DH_free(dh);
253 
254     return ret;
255 }
256 
257 static int cb(int p, int n, BN_GENCB *arg)
258 {
259     return 1;
260 }
261 
262 static int dh_computekey_range_test(void)
263 {
264     int ret = 0, sz;
265     DH *dh = NULL;
266     BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL;
267     unsigned char *buf = NULL;
268 
269     if (!TEST_ptr(p = BN_dup(&ossl_bignum_ffdhe2048_p))
270         || !TEST_ptr(q = BN_dup(&ossl_bignum_ffdhe2048_q))
271         || !TEST_ptr(g = BN_dup(&ossl_bignum_const_2))
272         || !TEST_ptr(dh = DH_new())
273         || !TEST_true(DH_set0_pqg(dh, p, q, g)))
274         goto err;
275     p = q = g = NULL;
276 
277     if (!TEST_int_gt(sz = DH_size(dh), 0)
278         || !TEST_ptr(buf = OPENSSL_malloc(sz))
279         || !TEST_ptr(pub = BN_new())
280         || !TEST_ptr(priv = BN_new()))
281         goto err;
282 
283     if (!TEST_true(BN_set_word(priv, 1))
284         || !TEST_true(DH_set0_key(dh, NULL, priv)))
285         goto err;
286     priv = NULL;
287     if (!TEST_true(BN_set_word(pub, 1)))
288         goto err;
289 
290     /* Given z = pub ^ priv mod p */
291 
292     /* Test that z == 1 fails */
293     if (!TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0))
294         goto err;
295     /* Test that z == 0 fails */
296     if (!TEST_ptr(BN_copy(pub, DH_get0_p(dh)))
297         || !TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0))
298         goto err;
299     /* Test that z == p - 1 fails */
300     if (!TEST_true(BN_sub_word(pub, 1))
301         || !TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0))
302         goto err;
303     /* Test that z == p - 2 passes */
304     if (!TEST_true(BN_sub_word(pub, 1))
305         || !TEST_int_eq(ossl_dh_compute_key(buf, pub, dh), sz))
306         goto err;
307 
308     ret = 1;
309 err:
310     OPENSSL_free(buf);
311     BN_free(priv);
312     BN_free(pub);
313     BN_free(g);
314     BN_free(q);
315     BN_free(p);
316     DH_free(dh);
317     return ret;
318 }
319 
320 /* Test data from RFC 5114 */
321 
322 static const unsigned char dhtest_1024_160_xA[] = {
323     0xB9, 0xA3, 0xB3, 0xAE, 0x8F, 0xEF, 0xC1, 0xA2, 0x93, 0x04, 0x96, 0x50,
324     0x70, 0x86, 0xF8, 0x45, 0x5D, 0x48, 0x94, 0x3E
325 };
326 
327 static const unsigned char dhtest_1024_160_yA[] = {
328     0x2A, 0x85, 0x3B, 0x3D, 0x92, 0x19, 0x75, 0x01, 0xB9, 0x01, 0x5B, 0x2D,
329     0xEB, 0x3E, 0xD8, 0x4F, 0x5E, 0x02, 0x1D, 0xCC, 0x3E, 0x52, 0xF1, 0x09,
330     0xD3, 0x27, 0x3D, 0x2B, 0x75, 0x21, 0x28, 0x1C, 0xBA, 0xBE, 0x0E, 0x76,
331     0xFF, 0x57, 0x27, 0xFA, 0x8A, 0xCC, 0xE2, 0x69, 0x56, 0xBA, 0x9A, 0x1F,
332     0xCA, 0x26, 0xF2, 0x02, 0x28, 0xD8, 0x69, 0x3F, 0xEB, 0x10, 0x84, 0x1D,
333     0x84, 0xA7, 0x36, 0x00, 0x54, 0xEC, 0xE5, 0xA7, 0xF5, 0xB7, 0xA6, 0x1A,
334     0xD3, 0xDF, 0xB3, 0xC6, 0x0D, 0x2E, 0x43, 0x10, 0x6D, 0x87, 0x27, 0xDA,
335     0x37, 0xDF, 0x9C, 0xCE, 0x95, 0xB4, 0x78, 0x75, 0x5D, 0x06, 0xBC, 0xEA,
336     0x8F, 0x9D, 0x45, 0x96, 0x5F, 0x75, 0xA5, 0xF3, 0xD1, 0xDF, 0x37, 0x01,
337     0x16, 0x5F, 0xC9, 0xE5, 0x0C, 0x42, 0x79, 0xCE, 0xB0, 0x7F, 0x98, 0x95,
338     0x40, 0xAE, 0x96, 0xD5, 0xD8, 0x8E, 0xD7, 0x76
339 };
340 
341 static const unsigned char dhtest_1024_160_xB[] = {
342     0x93, 0x92, 0xC9, 0xF9, 0xEB, 0x6A, 0x7A, 0x6A, 0x90, 0x22, 0xF7, 0xD8,
343     0x3E, 0x72, 0x23, 0xC6, 0x83, 0x5B, 0xBD, 0xDA
344 };
345 
346 static const unsigned char dhtest_1024_160_yB[] = {
347     0x71, 0x7A, 0x6C, 0xB0, 0x53, 0x37, 0x1F, 0xF4, 0xA3, 0xB9, 0x32, 0x94,
348     0x1C, 0x1E, 0x56, 0x63, 0xF8, 0x61, 0xA1, 0xD6, 0xAD, 0x34, 0xAE, 0x66,
349     0x57, 0x6D, 0xFB, 0x98, 0xF6, 0xC6, 0xCB, 0xF9, 0xDD, 0xD5, 0xA5, 0x6C,
350     0x78, 0x33, 0xF6, 0xBC, 0xFD, 0xFF, 0x09, 0x55, 0x82, 0xAD, 0x86, 0x8E,
351     0x44, 0x0E, 0x8D, 0x09, 0xFD, 0x76, 0x9E, 0x3C, 0xEC, 0xCD, 0xC3, 0xD3,
352     0xB1, 0xE4, 0xCF, 0xA0, 0x57, 0x77, 0x6C, 0xAA, 0xF9, 0x73, 0x9B, 0x6A,
353     0x9F, 0xEE, 0x8E, 0x74, 0x11, 0xF8, 0xD6, 0xDA, 0xC0, 0x9D, 0x6A, 0x4E,
354     0xDB, 0x46, 0xCC, 0x2B, 0x5D, 0x52, 0x03, 0x09, 0x0E, 0xAE, 0x61, 0x26,
355     0x31, 0x1E, 0x53, 0xFD, 0x2C, 0x14, 0xB5, 0x74, 0xE6, 0xA3, 0x10, 0x9A,
356     0x3D, 0xA1, 0xBE, 0x41, 0xBD, 0xCE, 0xAA, 0x18, 0x6F, 0x5C, 0xE0, 0x67,
357     0x16, 0xA2, 0xB6, 0xA0, 0x7B, 0x3C, 0x33, 0xFE
358 };
359 
360 static const unsigned char dhtest_1024_160_Z[] = {
361     0x5C, 0x80, 0x4F, 0x45, 0x4D, 0x30, 0xD9, 0xC4, 0xDF, 0x85, 0x27, 0x1F,
362     0x93, 0x52, 0x8C, 0x91, 0xDF, 0x6B, 0x48, 0xAB, 0x5F, 0x80, 0xB3, 0xB5,
363     0x9C, 0xAA, 0xC1, 0xB2, 0x8F, 0x8A, 0xCB, 0xA9, 0xCD, 0x3E, 0x39, 0xF3,
364     0xCB, 0x61, 0x45, 0x25, 0xD9, 0x52, 0x1D, 0x2E, 0x64, 0x4C, 0x53, 0xB8,
365     0x07, 0xB8, 0x10, 0xF3, 0x40, 0x06, 0x2F, 0x25, 0x7D, 0x7D, 0x6F, 0xBF,
366     0xE8, 0xD5, 0xE8, 0xF0, 0x72, 0xE9, 0xB6, 0xE9, 0xAF, 0xDA, 0x94, 0x13,
367     0xEA, 0xFB, 0x2E, 0x8B, 0x06, 0x99, 0xB1, 0xFB, 0x5A, 0x0C, 0xAC, 0xED,
368     0xDE, 0xAE, 0xAD, 0x7E, 0x9C, 0xFB, 0xB3, 0x6A, 0xE2, 0xB4, 0x20, 0x83,
369     0x5B, 0xD8, 0x3A, 0x19, 0xFB, 0x0B, 0x5E, 0x96, 0xBF, 0x8F, 0xA4, 0xD0,
370     0x9E, 0x34, 0x55, 0x25, 0x16, 0x7E, 0xCD, 0x91, 0x55, 0x41, 0x6F, 0x46,
371     0xF4, 0x08, 0xED, 0x31, 0xB6, 0x3C, 0x6E, 0x6D
372 };
373 
374 static const unsigned char dhtest_2048_224_xA[] = {
375     0x22, 0xE6, 0x26, 0x01, 0xDB, 0xFF, 0xD0, 0x67, 0x08, 0xA6, 0x80, 0xF7,
376     0x47, 0xF3, 0x61, 0xF7, 0x6D, 0x8F, 0x4F, 0x72, 0x1A, 0x05, 0x48, 0xE4,
377     0x83, 0x29, 0x4B, 0x0C
378 };
379 
380 static const unsigned char dhtest_2048_224_yA[] = {
381     0x1B, 0x3A, 0x63, 0x45, 0x1B, 0xD8, 0x86, 0xE6, 0x99, 0xE6, 0x7B, 0x49,
382     0x4E, 0x28, 0x8B, 0xD7, 0xF8, 0xE0, 0xD3, 0x70, 0xBA, 0xDD, 0xA7, 0xA0,
383     0xEF, 0xD2, 0xFD, 0xE7, 0xD8, 0xF6, 0x61, 0x45, 0xCC, 0x9F, 0x28, 0x04,
384     0x19, 0x97, 0x5E, 0xB8, 0x08, 0x87, 0x7C, 0x8A, 0x4C, 0x0C, 0x8E, 0x0B,
385     0xD4, 0x8D, 0x4A, 0x54, 0x01, 0xEB, 0x1E, 0x87, 0x76, 0xBF, 0xEE, 0xE1,
386     0x34, 0xC0, 0x38, 0x31, 0xAC, 0x27, 0x3C, 0xD9, 0xD6, 0x35, 0xAB, 0x0C,
387     0xE0, 0x06, 0xA4, 0x2A, 0x88, 0x7E, 0x3F, 0x52, 0xFB, 0x87, 0x66, 0xB6,
388     0x50, 0xF3, 0x80, 0x78, 0xBC, 0x8E, 0xE8, 0x58, 0x0C, 0xEF, 0xE2, 0x43,
389     0x96, 0x8C, 0xFC, 0x4F, 0x8D, 0xC3, 0xDB, 0x08, 0x45, 0x54, 0x17, 0x1D,
390     0x41, 0xBF, 0x2E, 0x86, 0x1B, 0x7B, 0xB4, 0xD6, 0x9D, 0xD0, 0xE0, 0x1E,
391     0xA3, 0x87, 0xCB, 0xAA, 0x5C, 0xA6, 0x72, 0xAF, 0xCB, 0xE8, 0xBD, 0xB9,
392     0xD6, 0x2D, 0x4C, 0xE1, 0x5F, 0x17, 0xDD, 0x36, 0xF9, 0x1E, 0xD1, 0xEE,
393     0xDD, 0x65, 0xCA, 0x4A, 0x06, 0x45, 0x5C, 0xB9, 0x4C, 0xD4, 0x0A, 0x52,
394     0xEC, 0x36, 0x0E, 0x84, 0xB3, 0xC9, 0x26, 0xE2, 0x2C, 0x43, 0x80, 0xA3,
395     0xBF, 0x30, 0x9D, 0x56, 0x84, 0x97, 0x68, 0xB7, 0xF5, 0x2C, 0xFD, 0xF6,
396     0x55, 0xFD, 0x05, 0x3A, 0x7E, 0xF7, 0x06, 0x97, 0x9E, 0x7E, 0x58, 0x06,
397     0xB1, 0x7D, 0xFA, 0xE5, 0x3A, 0xD2, 0xA5, 0xBC, 0x56, 0x8E, 0xBB, 0x52,
398     0x9A, 0x7A, 0x61, 0xD6, 0x8D, 0x25, 0x6F, 0x8F, 0xC9, 0x7C, 0x07, 0x4A,
399     0x86, 0x1D, 0x82, 0x7E, 0x2E, 0xBC, 0x8C, 0x61, 0x34, 0x55, 0x31, 0x15,
400     0xB7, 0x0E, 0x71, 0x03, 0x92, 0x0A, 0xA1, 0x6D, 0x85, 0xE5, 0x2B, 0xCB,
401     0xAB, 0x8D, 0x78, 0x6A, 0x68, 0x17, 0x8F, 0xA8, 0xFF, 0x7C, 0x2F, 0x5C,
402     0x71, 0x64, 0x8D, 0x6F
403 };
404 
405 static const unsigned char dhtest_2048_224_xB[] = {
406     0x4F, 0xF3, 0xBC, 0x96, 0xC7, 0xFC, 0x6A, 0x6D, 0x71, 0xD3, 0xB3, 0x63,
407     0x80, 0x0A, 0x7C, 0xDF, 0xEF, 0x6F, 0xC4, 0x1B, 0x44, 0x17, 0xEA, 0x15,
408     0x35, 0x3B, 0x75, 0x90
409 };
410 
411 static const unsigned char dhtest_2048_224_yB[] = {
412     0x4D, 0xCE, 0xE9, 0x92, 0xA9, 0x76, 0x2A, 0x13, 0xF2, 0xF8, 0x38, 0x44,
413     0xAD, 0x3D, 0x77, 0xEE, 0x0E, 0x31, 0xC9, 0x71, 0x8B, 0x3D, 0xB6, 0xC2,
414     0x03, 0x5D, 0x39, 0x61, 0x18, 0x2C, 0x3E, 0x0B, 0xA2, 0x47, 0xEC, 0x41,
415     0x82, 0xD7, 0x60, 0xCD, 0x48, 0xD9, 0x95, 0x99, 0x97, 0x06, 0x22, 0xA1,
416     0x88, 0x1B, 0xBA, 0x2D, 0xC8, 0x22, 0x93, 0x9C, 0x78, 0xC3, 0x91, 0x2C,
417     0x66, 0x61, 0xFA, 0x54, 0x38, 0xB2, 0x07, 0x66, 0x22, 0x2B, 0x75, 0xE2,
418     0x4C, 0x2E, 0x3A, 0xD0, 0xC7, 0x28, 0x72, 0x36, 0x12, 0x95, 0x25, 0xEE,
419     0x15, 0xB5, 0xDD, 0x79, 0x98, 0xAA, 0x04, 0xC4, 0xA9, 0x69, 0x6C, 0xAC,
420     0xD7, 0x17, 0x20, 0x83, 0xA9, 0x7A, 0x81, 0x66, 0x4E, 0xAD, 0x2C, 0x47,
421     0x9E, 0x44, 0x4E, 0x4C, 0x06, 0x54, 0xCC, 0x19, 0xE2, 0x8D, 0x77, 0x03,
422     0xCE, 0xE8, 0xDA, 0xCD, 0x61, 0x26, 0xF5, 0xD6, 0x65, 0xEC, 0x52, 0xC6,
423     0x72, 0x55, 0xDB, 0x92, 0x01, 0x4B, 0x03, 0x7E, 0xB6, 0x21, 0xA2, 0xAC,
424     0x8E, 0x36, 0x5D, 0xE0, 0x71, 0xFF, 0xC1, 0x40, 0x0A, 0xCF, 0x07, 0x7A,
425     0x12, 0x91, 0x3D, 0xD8, 0xDE, 0x89, 0x47, 0x34, 0x37, 0xAB, 0x7B, 0xA3,
426     0x46, 0x74, 0x3C, 0x1B, 0x21, 0x5D, 0xD9, 0xC1, 0x21, 0x64, 0xA7, 0xE4,
427     0x05, 0x31, 0x18, 0xD1, 0x99, 0xBE, 0xC8, 0xEF, 0x6F, 0xC5, 0x61, 0x17,
428     0x0C, 0x84, 0xC8, 0x7D, 0x10, 0xEE, 0x9A, 0x67, 0x4A, 0x1F, 0xA8, 0xFF,
429     0xE1, 0x3B, 0xDF, 0xBA, 0x1D, 0x44, 0xDE, 0x48, 0x94, 0x6D, 0x68, 0xDC,
430     0x0C, 0xDD, 0x77, 0x76, 0x35, 0xA7, 0xAB, 0x5B, 0xFB, 0x1E, 0x4B, 0xB7,
431     0xB8, 0x56, 0xF9, 0x68, 0x27, 0x73, 0x4C, 0x18, 0x41, 0x38, 0xE9, 0x15,
432     0xD9, 0xC3, 0x00, 0x2E, 0xBC, 0xE5, 0x31, 0x20, 0x54, 0x6A, 0x7E, 0x20,
433     0x02, 0x14, 0x2B, 0x6C
434 };
435 
436 static const unsigned char dhtest_2048_224_Z[] = {
437     0x34, 0xD9, 0xBD, 0xDC, 0x1B, 0x42, 0x17, 0x6C, 0x31, 0x3F, 0xEA, 0x03,
438     0x4C, 0x21, 0x03, 0x4D, 0x07, 0x4A, 0x63, 0x13, 0xBB, 0x4E, 0xCD, 0xB3,
439     0x70, 0x3F, 0xFF, 0x42, 0x45, 0x67, 0xA4, 0x6B, 0xDF, 0x75, 0x53, 0x0E,
440     0xDE, 0x0A, 0x9D, 0xA5, 0x22, 0x9D, 0xE7, 0xD7, 0x67, 0x32, 0x28, 0x6C,
441     0xBC, 0x0F, 0x91, 0xDA, 0x4C, 0x3C, 0x85, 0x2F, 0xC0, 0x99, 0xC6, 0x79,
442     0x53, 0x1D, 0x94, 0xC7, 0x8A, 0xB0, 0x3D, 0x9D, 0xEC, 0xB0, 0xA4, 0xE4,
443     0xCA, 0x8B, 0x2B, 0xB4, 0x59, 0x1C, 0x40, 0x21, 0xCF, 0x8C, 0xE3, 0xA2,
444     0x0A, 0x54, 0x1D, 0x33, 0x99, 0x40, 0x17, 0xD0, 0x20, 0x0A, 0xE2, 0xC9,
445     0x51, 0x6E, 0x2F, 0xF5, 0x14, 0x57, 0x79, 0x26, 0x9E, 0x86, 0x2B, 0x0F,
446     0xB4, 0x74, 0xA2, 0xD5, 0x6D, 0xC3, 0x1E, 0xD5, 0x69, 0xA7, 0x70, 0x0B,
447     0x4C, 0x4A, 0xB1, 0x6B, 0x22, 0xA4, 0x55, 0x13, 0x53, 0x1E, 0xF5, 0x23,
448     0xD7, 0x12, 0x12, 0x07, 0x7B, 0x5A, 0x16, 0x9B, 0xDE, 0xFF, 0xAD, 0x7A,
449     0xD9, 0x60, 0x82, 0x84, 0xC7, 0x79, 0x5B, 0x6D, 0x5A, 0x51, 0x83, 0xB8,
450     0x70, 0x66, 0xDE, 0x17, 0xD8, 0xD6, 0x71, 0xC9, 0xEB, 0xD8, 0xEC, 0x89,
451     0x54, 0x4D, 0x45, 0xEC, 0x06, 0x15, 0x93, 0xD4, 0x42, 0xC6, 0x2A, 0xB9,
452     0xCE, 0x3B, 0x1C, 0xB9, 0x94, 0x3A, 0x1D, 0x23, 0xA5, 0xEA, 0x3B, 0xCF,
453     0x21, 0xA0, 0x14, 0x71, 0xE6, 0x7E, 0x00, 0x3E, 0x7F, 0x8A, 0x69, 0xC7,
454     0x28, 0xBE, 0x49, 0x0B, 0x2F, 0xC8, 0x8C, 0xFE, 0xB9, 0x2D, 0xB6, 0xA2,
455     0x15, 0xE5, 0xD0, 0x3C, 0x17, 0xC4, 0x64, 0xC9, 0xAC, 0x1A, 0x46, 0xE2,
456     0x03, 0xE1, 0x3F, 0x95, 0x29, 0x95, 0xFB, 0x03, 0xC6, 0x9D, 0x3C, 0xC4,
457     0x7F, 0xCB, 0x51, 0x0B, 0x69, 0x98, 0xFF, 0xD3, 0xAA, 0x6D, 0xE7, 0x3C,
458     0xF9, 0xF6, 0x38, 0x69
459 };
460 
461 static const unsigned char dhtest_2048_256_xA[] = {
462     0x08, 0x81, 0x38, 0x2C, 0xDB, 0x87, 0x66, 0x0C, 0x6D, 0xC1, 0x3E, 0x61,
463     0x49, 0x38, 0xD5, 0xB9, 0xC8, 0xB2, 0xF2, 0x48, 0x58, 0x1C, 0xC5, 0xE3,
464     0x1B, 0x35, 0x45, 0x43, 0x97, 0xFC, 0xE5, 0x0E
465 };
466 
467 static const unsigned char dhtest_2048_256_yA[] = {
468     0x2E, 0x93, 0x80, 0xC8, 0x32, 0x3A, 0xF9, 0x75, 0x45, 0xBC, 0x49, 0x41,
469     0xDE, 0xB0, 0xEC, 0x37, 0x42, 0xC6, 0x2F, 0xE0, 0xEC, 0xE8, 0x24, 0xA6,
470     0xAB, 0xDB, 0xE6, 0x6C, 0x59, 0xBE, 0xE0, 0x24, 0x29, 0x11, 0xBF, 0xB9,
471     0x67, 0x23, 0x5C, 0xEB, 0xA3, 0x5A, 0xE1, 0x3E, 0x4E, 0xC7, 0x52, 0xBE,
472     0x63, 0x0B, 0x92, 0xDC, 0x4B, 0xDE, 0x28, 0x47, 0xA9, 0xC6, 0x2C, 0xB8,
473     0x15, 0x27, 0x45, 0x42, 0x1F, 0xB7, 0xEB, 0x60, 0xA6, 0x3C, 0x0F, 0xE9,
474     0x15, 0x9F, 0xCC, 0xE7, 0x26, 0xCE, 0x7C, 0xD8, 0x52, 0x3D, 0x74, 0x50,
475     0x66, 0x7E, 0xF8, 0x40, 0xE4, 0x91, 0x91, 0x21, 0xEB, 0x5F, 0x01, 0xC8,
476     0xC9, 0xB0, 0xD3, 0xD6, 0x48, 0xA9, 0x3B, 0xFB, 0x75, 0x68, 0x9E, 0x82,
477     0x44, 0xAC, 0x13, 0x4A, 0xF5, 0x44, 0x71, 0x1C, 0xE7, 0x9A, 0x02, 0xDC,
478     0xC3, 0x42, 0x26, 0x68, 0x47, 0x80, 0xDD, 0xDC, 0xB4, 0x98, 0x59, 0x41,
479     0x06, 0xC3, 0x7F, 0x5B, 0xC7, 0x98, 0x56, 0x48, 0x7A, 0xF5, 0xAB, 0x02,
480     0x2A, 0x2E, 0x5E, 0x42, 0xF0, 0x98, 0x97, 0xC1, 0xA8, 0x5A, 0x11, 0xEA,
481     0x02, 0x12, 0xAF, 0x04, 0xD9, 0xB4, 0xCE, 0xBC, 0x93, 0x7C, 0x3C, 0x1A,
482     0x3E, 0x15, 0xA8, 0xA0, 0x34, 0x2E, 0x33, 0x76, 0x15, 0xC8, 0x4E, 0x7F,
483     0xE3, 0xB8, 0xB9, 0xB8, 0x7F, 0xB1, 0xE7, 0x3A, 0x15, 0xAF, 0x12, 0xA3,
484     0x0D, 0x74, 0x6E, 0x06, 0xDF, 0xC3, 0x4F, 0x29, 0x0D, 0x79, 0x7C, 0xE5,
485     0x1A, 0xA1, 0x3A, 0xA7, 0x85, 0xBF, 0x66, 0x58, 0xAF, 0xF5, 0xE4, 0xB0,
486     0x93, 0x00, 0x3C, 0xBE, 0xAF, 0x66, 0x5B, 0x3C, 0x2E, 0x11, 0x3A, 0x3A,
487     0x4E, 0x90, 0x52, 0x69, 0x34, 0x1D, 0xC0, 0x71, 0x14, 0x26, 0x68, 0x5F,
488     0x4E, 0xF3, 0x7E, 0x86, 0x8A, 0x81, 0x26, 0xFF, 0x3F, 0x22, 0x79, 0xB5,
489     0x7C, 0xA6, 0x7E, 0x29
490 };
491 
492 static const unsigned char dhtest_2048_256_xB[] = {
493     0x7D, 0x62, 0xA7, 0xE3, 0xEF, 0x36, 0xDE, 0x61, 0x7B, 0x13, 0xD1, 0xAF,
494     0xB8, 0x2C, 0x78, 0x0D, 0x83, 0xA2, 0x3B, 0xD4, 0xEE, 0x67, 0x05, 0x64,
495     0x51, 0x21, 0xF3, 0x71, 0xF5, 0x46, 0xA5, 0x3D
496 };
497 
498 static const unsigned char dhtest_2048_256_yB[] = {
499     0x57, 0x5F, 0x03, 0x51, 0xBD, 0x2B, 0x1B, 0x81, 0x74, 0x48, 0xBD, 0xF8,
500     0x7A, 0x6C, 0x36, 0x2C, 0x1E, 0x28, 0x9D, 0x39, 0x03, 0xA3, 0x0B, 0x98,
501     0x32, 0xC5, 0x74, 0x1F, 0xA2, 0x50, 0x36, 0x3E, 0x7A, 0xCB, 0xC7, 0xF7,
502     0x7F, 0x3D, 0xAC, 0xBC, 0x1F, 0x13, 0x1A, 0xDD, 0x8E, 0x03, 0x36, 0x7E,
503     0xFF, 0x8F, 0xBB, 0xB3, 0xE1, 0xC5, 0x78, 0x44, 0x24, 0x80, 0x9B, 0x25,
504     0xAF, 0xE4, 0xD2, 0x26, 0x2A, 0x1A, 0x6F, 0xD2, 0xFA, 0xB6, 0x41, 0x05,
505     0xCA, 0x30, 0xA6, 0x74, 0xE0, 0x7F, 0x78, 0x09, 0x85, 0x20, 0x88, 0x63,
506     0x2F, 0xC0, 0x49, 0x23, 0x37, 0x91, 0xAD, 0x4E, 0xDD, 0x08, 0x3A, 0x97,
507     0x8B, 0x88, 0x3E, 0xE6, 0x18, 0xBC, 0x5E, 0x0D, 0xD0, 0x47, 0x41, 0x5F,
508     0x2D, 0x95, 0xE6, 0x83, 0xCF, 0x14, 0x82, 0x6B, 0x5F, 0xBE, 0x10, 0xD3,
509     0xCE, 0x41, 0xC6, 0xC1, 0x20, 0xC7, 0x8A, 0xB2, 0x00, 0x08, 0xC6, 0x98,
510     0xBF, 0x7F, 0x0B, 0xCA, 0xB9, 0xD7, 0xF4, 0x07, 0xBE, 0xD0, 0xF4, 0x3A,
511     0xFB, 0x29, 0x70, 0xF5, 0x7F, 0x8D, 0x12, 0x04, 0x39, 0x63, 0xE6, 0x6D,
512     0xDD, 0x32, 0x0D, 0x59, 0x9A, 0xD9, 0x93, 0x6C, 0x8F, 0x44, 0x13, 0x7C,
513     0x08, 0xB1, 0x80, 0xEC, 0x5E, 0x98, 0x5C, 0xEB, 0xE1, 0x86, 0xF3, 0xD5,
514     0x49, 0x67, 0x7E, 0x80, 0x60, 0x73, 0x31, 0xEE, 0x17, 0xAF, 0x33, 0x80,
515     0xA7, 0x25, 0xB0, 0x78, 0x23, 0x17, 0xD7, 0xDD, 0x43, 0xF5, 0x9D, 0x7A,
516     0xF9, 0x56, 0x8A, 0x9B, 0xB6, 0x3A, 0x84, 0xD3, 0x65, 0xF9, 0x22, 0x44,
517     0xED, 0x12, 0x09, 0x88, 0x21, 0x93, 0x02, 0xF4, 0x29, 0x24, 0xC7, 0xCA,
518     0x90, 0xB8, 0x9D, 0x24, 0xF7, 0x1B, 0x0A, 0xB6, 0x97, 0x82, 0x3D, 0x7D,
519     0xEB, 0x1A, 0xFF, 0x5B, 0x0E, 0x8E, 0x4A, 0x45, 0xD4, 0x9F, 0x7F, 0x53,
520     0x75, 0x7E, 0x19, 0x13
521 };
522 
523 static const unsigned char dhtest_2048_256_Z[] = {
524     0x86, 0xC7, 0x0B, 0xF8, 0xD0, 0xBB, 0x81, 0xBB, 0x01, 0x07, 0x8A, 0x17,
525     0x21, 0x9C, 0xB7, 0xD2, 0x72, 0x03, 0xDB, 0x2A, 0x19, 0xC8, 0x77, 0xF1,
526     0xD1, 0xF1, 0x9F, 0xD7, 0xD7, 0x7E, 0xF2, 0x25, 0x46, 0xA6, 0x8F, 0x00,
527     0x5A, 0xD5, 0x2D, 0xC8, 0x45, 0x53, 0xB7, 0x8F, 0xC6, 0x03, 0x30, 0xBE,
528     0x51, 0xEA, 0x7C, 0x06, 0x72, 0xCA, 0xC1, 0x51, 0x5E, 0x4B, 0x35, 0xC0,
529     0x47, 0xB9, 0xA5, 0x51, 0xB8, 0x8F, 0x39, 0xDC, 0x26, 0xDA, 0x14, 0xA0,
530     0x9E, 0xF7, 0x47, 0x74, 0xD4, 0x7C, 0x76, 0x2D, 0xD1, 0x77, 0xF9, 0xED,
531     0x5B, 0xC2, 0xF1, 0x1E, 0x52, 0xC8, 0x79, 0xBD, 0x95, 0x09, 0x85, 0x04,
532     0xCD, 0x9E, 0xEC, 0xD8, 0xA8, 0xF9, 0xB3, 0xEF, 0xBD, 0x1F, 0x00, 0x8A,
533     0xC5, 0x85, 0x30, 0x97, 0xD9, 0xD1, 0x83, 0x7F, 0x2B, 0x18, 0xF7, 0x7C,
534     0xD7, 0xBE, 0x01, 0xAF, 0x80, 0xA7, 0xC7, 0xB5, 0xEA, 0x3C, 0xA5, 0x4C,
535     0xC0, 0x2D, 0x0C, 0x11, 0x6F, 0xEE, 0x3F, 0x95, 0xBB, 0x87, 0x39, 0x93,
536     0x85, 0x87, 0x5D, 0x7E, 0x86, 0x74, 0x7E, 0x67, 0x6E, 0x72, 0x89, 0x38,
537     0xAC, 0xBF, 0xF7, 0x09, 0x8E, 0x05, 0xBE, 0x4D, 0xCF, 0xB2, 0x40, 0x52,
538     0xB8, 0x3A, 0xEF, 0xFB, 0x14, 0x78, 0x3F, 0x02, 0x9A, 0xDB, 0xDE, 0x7F,
539     0x53, 0xFA, 0xE9, 0x20, 0x84, 0x22, 0x40, 0x90, 0xE0, 0x07, 0xCE, 0xE9,
540     0x4D, 0x4B, 0xF2, 0xBA, 0xCE, 0x9F, 0xFD, 0x4B, 0x57, 0xD2, 0xAF, 0x7C,
541     0x72, 0x4D, 0x0C, 0xAA, 0x19, 0xBF, 0x05, 0x01, 0xF6, 0xF1, 0x7B, 0x4A,
542     0xA1, 0x0F, 0x42, 0x5E, 0x3E, 0xA7, 0x60, 0x80, 0xB4, 0xB9, 0xD6, 0xB3,
543     0xCE, 0xFE, 0xA1, 0x15, 0xB2, 0xCE, 0xB8, 0x78, 0x9B, 0xB8, 0xA3, 0xB0,
544     0xEA, 0x87, 0xFE, 0xBE, 0x63, 0xB6, 0xC8, 0xF8, 0x46, 0xEC, 0x6D, 0xB0,
545     0xC2, 0x6C, 0x5D, 0x7C
546 };
547 
548 typedef struct {
549     DH *(*get_param) (void);
550     const unsigned char *xA;
551     size_t xA_len;
552     const unsigned char *yA;
553     size_t yA_len;
554     const unsigned char *xB;
555     size_t xB_len;
556     const unsigned char *yB;
557     size_t yB_len;
558     const unsigned char *Z;
559     size_t Z_len;
560 } rfc5114_td;
561 
562 # define make_rfc5114_td(pre) { \
563         DH_get_##pre, \
564         dhtest_##pre##_xA, sizeof(dhtest_##pre##_xA), \
565         dhtest_##pre##_yA, sizeof(dhtest_##pre##_yA), \
566         dhtest_##pre##_xB, sizeof(dhtest_##pre##_xB), \
567         dhtest_##pre##_yB, sizeof(dhtest_##pre##_yB), \
568         dhtest_##pre##_Z, sizeof(dhtest_##pre##_Z) \
569         }
570 
571 static const rfc5114_td rfctd[] = {
572         make_rfc5114_td(1024_160),
573         make_rfc5114_td(2048_224),
574         make_rfc5114_td(2048_256)
575 };
576 
577 static int rfc5114_test(void)
578 {
579     int i;
580     DH *dhA = NULL;
581     DH *dhB = NULL;
582     unsigned char *Z1 = NULL;
583     unsigned char *Z2 = NULL;
584     int szA, szB;
585     const rfc5114_td *td = NULL;
586     BIGNUM *priv_key = NULL, *pub_key = NULL;
587     const BIGNUM *pub_key_tmp;
588 
589     for (i = 0; i < (int)OSSL_NELEM(rfctd); i++) {
590         td = rfctd + i;
591         /* Set up DH structures setting key components */
592         if (!TEST_ptr(dhA = td->get_param())
593                 || !TEST_ptr(dhB = td->get_param()))
594             goto bad_err;
595 
596         if (!TEST_ptr(priv_key = BN_bin2bn(td->xA, td->xA_len, NULL))
597                 || !TEST_ptr(pub_key = BN_bin2bn(td->yA, td->yA_len, NULL))
598                 || !TEST_true(DH_set0_key(dhA, pub_key, priv_key)))
599             goto bad_err;
600 
601         if (!TEST_ptr(priv_key = BN_bin2bn(td->xB, td->xB_len, NULL))
602                 || !TEST_ptr(pub_key = BN_bin2bn(td->yB, td->yB_len, NULL))
603                 || !TEST_true( DH_set0_key(dhB, pub_key, priv_key)))
604             goto bad_err;
605         priv_key = pub_key = NULL;
606 
607         if (!TEST_int_gt(szA = DH_size(dhA), 0)
608                 || !TEST_int_gt(szB = DH_size(dhB), 0)
609                 || !TEST_size_t_eq(td->Z_len, (size_t)szA)
610                 || !TEST_size_t_eq(td->Z_len, (size_t)szB))
611             goto err;
612 
613         if (!TEST_ptr(Z1 = OPENSSL_malloc((size_t)szA))
614                 || !TEST_ptr(Z2 = OPENSSL_malloc((size_t)szB)))
615             goto bad_err;
616         /*
617          * Work out shared secrets using both sides and compare with expected
618          * values.
619          */
620         DH_get0_key(dhB, &pub_key_tmp, NULL);
621         if (!TEST_int_ne(DH_compute_key(Z1, pub_key_tmp, dhA), -1))
622             goto bad_err;
623 
624         DH_get0_key(dhA, &pub_key_tmp, NULL);
625         if (!TEST_int_ne(DH_compute_key(Z2, pub_key_tmp, dhB), -1))
626             goto bad_err;
627 
628         if (!TEST_mem_eq(Z1, td->Z_len, td->Z, td->Z_len)
629                 || !TEST_mem_eq(Z2, td->Z_len, td->Z, td->Z_len))
630             goto err;
631 
632         DH_free(dhA);
633         dhA = NULL;
634         DH_free(dhB);
635         dhB = NULL;
636         OPENSSL_free(Z1);
637         Z1 = NULL;
638         OPENSSL_free(Z2);
639         Z2 = NULL;
640     }
641     return 1;
642 
643  bad_err:
644     DH_free(dhA);
645     DH_free(dhB);
646     BN_free(pub_key);
647     BN_free(priv_key);
648     OPENSSL_free(Z1);
649     OPENSSL_free(Z2);
650     TEST_error("Initialisation error RFC5114 set %d\n", i + 1);
651     return 0;
652 
653  err:
654     DH_free(dhA);
655     DH_free(dhB);
656     OPENSSL_free(Z1);
657     OPENSSL_free(Z2);
658     TEST_error("Test failed RFC5114 set %d\n", i + 1);
659     return 0;
660 }
661 
662 static int rfc7919_test(void)
663 {
664     DH *a = NULL, *b = NULL;
665     const BIGNUM *apub_key = NULL, *bpub_key = NULL;
666     unsigned char *abuf = NULL;
667     unsigned char *bbuf = NULL;
668     int i, alen, blen, aout, bout;
669     int ret = 0;
670 
671     if (!TEST_ptr(a = DH_new_by_nid(NID_ffdhe2048)))
672          goto err;
673 
674     if (!DH_check(a, &i))
675         goto err;
676     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
677             || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
678             || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
679             || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
680             || !TEST_false(i))
681         goto err;
682 
683     if (!DH_generate_key(a))
684         goto err;
685     DH_get0_key(a, &apub_key, NULL);
686 
687     /* now create another copy of the DH group for the peer */
688     if (!TEST_ptr(b = DH_new_by_nid(NID_ffdhe2048)))
689         goto err;
690 
691     if (!DH_generate_key(b))
692         goto err;
693     DH_get0_key(b, &bpub_key, NULL);
694 
695     alen = DH_size(a);
696     if (!TEST_int_gt(alen, 0) || !TEST_ptr(abuf = OPENSSL_malloc(alen))
697             || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
698         goto err;
699 
700     blen = DH_size(b);
701     if (!TEST_int_gt(blen, 0) || !TEST_ptr(bbuf = OPENSSL_malloc(blen))
702             || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
703         goto err;
704 
705     if (!TEST_true(aout >= 20)
706             || !TEST_mem_eq(abuf, aout, bbuf, bout))
707         goto err;
708 
709     ret = 1;
710 
711  err:
712     OPENSSL_free(abuf);
713     OPENSSL_free(bbuf);
714     DH_free(a);
715     DH_free(b);
716     return ret;
717 }
718 
719 static int prime_groups[] = {
720     NID_ffdhe2048,
721     NID_ffdhe3072,
722     NID_ffdhe4096,
723     NID_ffdhe6144,
724     NID_ffdhe8192,
725     NID_modp_2048,
726     NID_modp_3072,
727     NID_modp_4096,
728     NID_modp_6144,
729 };
730 
731 static int dh_test_prime_groups(int index)
732 {
733     int ok = 0;
734     DH *dh = NULL;
735     const BIGNUM *p, *q, *g;
736 
737     if (!TEST_ptr(dh = DH_new_by_nid(prime_groups[index])))
738         goto err;
739     DH_get0_pqg(dh, &p, &q, &g);
740     if (!TEST_ptr(p) || !TEST_ptr(q) || !TEST_ptr(g))
741         goto err;
742 
743     if (!TEST_int_eq(DH_get_nid(dh), prime_groups[index]))
744         goto err;
745 
746     /* Since q is set there is no need for the private length to be set */
747     if (!TEST_int_eq((int)DH_get_length(dh), 0))
748         goto err;
749 
750     ok = 1;
751 err:
752     DH_free(dh);
753     return ok;
754 }
755 
756 static int dh_rfc5114_fix_nid_test(void)
757 {
758     int ok = 0;
759     EVP_PKEY_CTX *paramgen_ctx;
760 
761     /* Run the test. Success is any time the test does not cause a SIGSEGV interrupt */
762     paramgen_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DHX, 0);
763     if (!TEST_ptr(paramgen_ctx))
764         goto err;
765     if (!TEST_int_eq(EVP_PKEY_paramgen_init(paramgen_ctx), 1))
766         goto err;
767     /* Tested function is called here */
768     if (!TEST_int_eq(EVP_PKEY_CTX_set_dhx_rfc5114(paramgen_ctx, 3), 1))
769         goto err;
770     /* Negative test */
771     if (!TEST_int_eq(EVP_PKEY_CTX_set_dhx_rfc5114(paramgen_ctx, 99), 0))
772         goto err;
773     /* If we're still running then the test passed. */
774     ok = 1;
775 err:
776     EVP_PKEY_CTX_free(paramgen_ctx);
777     return ok;
778 }
779 
780 static int dh_set_dh_nid_test(void)
781 {
782     int ok = 0;
783     EVP_PKEY_CTX *paramgen_ctx;
784 
785     /* Run the test. Success is any time the test does not cause a SIGSEGV interrupt */
786     paramgen_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
787     if (!TEST_ptr(paramgen_ctx))
788         goto err;
789     if (!TEST_int_eq(EVP_PKEY_paramgen_init(paramgen_ctx), 1))
790         goto err;
791     /* Tested function is called here */
792     if (!TEST_int_eq(EVP_PKEY_CTX_set_dh_nid(paramgen_ctx, NID_ffdhe2048), 1))
793         goto err;
794     /* Negative test */
795     if (!TEST_int_eq(EVP_PKEY_CTX_set_dh_nid(paramgen_ctx, NID_secp521r1), 0))
796         goto err;
797     /* If we're still running then the test passed. */
798     ok = 1;
799 err:
800     EVP_PKEY_CTX_free(paramgen_ctx);
801     return ok;
802 }
803 
804 static int dh_get_nid(void)
805 {
806     int ok = 0;
807     const BIGNUM *p, *q, *g;
808     BIGNUM *pcpy = NULL, *gcpy = NULL, *qcpy = NULL;
809     DH *dh1 = DH_new_by_nid(NID_ffdhe2048);
810     DH *dh2 = DH_new();
811 
812     if (!TEST_ptr(dh1)
813         || !TEST_ptr(dh2))
814         goto err;
815 
816     /* Set new DH parameters manually using a existing named group's p & g */
817     DH_get0_pqg(dh1, &p, &q, &g);
818     if (!TEST_ptr(p)
819         || !TEST_ptr(q)
820         || !TEST_ptr(g)
821         || !TEST_ptr(pcpy = BN_dup(p))
822         || !TEST_ptr(gcpy = BN_dup(g)))
823         goto err;
824 
825     if (!TEST_true(DH_set0_pqg(dh2, pcpy, NULL, gcpy)))
826         goto err;
827     pcpy = gcpy = NULL;
828     /* Test q is set if p and g are provided */
829     if (!TEST_ptr(DH_get0_q(dh2)))
830         goto err;
831 
832     /* Test that setting p & g manually returns that it is a named group */
833     if (!TEST_int_eq(DH_get_nid(dh2), NID_ffdhe2048))
834         goto err;
835 
836     /* Test that after changing g it is no longer a named group */
837     if (!TEST_ptr(gcpy = BN_dup(BN_value_one())))
838        goto err;
839     if (!TEST_true(DH_set0_pqg(dh2, NULL, NULL, gcpy)))
840        goto err;
841     gcpy = NULL;
842     if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
843         goto err;
844 
845     /* Test that setting an incorrect q results in this not being a named group */
846     if (!TEST_ptr(pcpy = BN_dup(p))
847         || !TEST_ptr(qcpy = BN_dup(q))
848         || !TEST_ptr(gcpy = BN_dup(g))
849         || !TEST_int_eq(BN_add_word(qcpy, 2), 1)
850         || !TEST_true(DH_set0_pqg(dh2, pcpy, qcpy, gcpy)))
851         goto err;
852     pcpy = qcpy = gcpy = NULL;
853     if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
854         goto err;
855 
856     ok = 1;
857 err:
858     BN_free(pcpy);
859     BN_free(qcpy);
860     BN_free(gcpy);
861     DH_free(dh2);
862     DH_free(dh1);
863     return ok;
864 }
865 
866 static const unsigned char dh_pub_der[] = {
867     0x30, 0x82, 0x02, 0x28, 0x30, 0x82, 0x01, 0x1b, 0x06, 0x09, 0x2a, 0x86,
868     0x48, 0x86, 0xf7, 0x0d, 0x01, 0x03, 0x01, 0x30, 0x82, 0x01, 0x0c, 0x02,
869     0x82, 0x01, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
870     0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b,
871     0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74,
872     0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79,
873     0x8e, 0x34, 0x04, 0xdd, 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b,
874     0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d,
875     0x6d, 0x51, 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
876     0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6,
877     0xf4, 0x06, 0xb7, 0xed, 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5,
878     0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51,
879     0xec, 0xe4, 0x5b, 0x3d, 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05,
880     0x98, 0xda, 0x48, 0x36, 0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8,
881     0xfd, 0x24, 0xcf, 0x5f, 0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96,
882     0x1c, 0x62, 0xf3, 0x56, 0x20, 0x85, 0x52, 0xbb, 0x9e, 0xd5, 0x29, 0x07,
883     0x70, 0x96, 0x96, 0x6d, 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04,
884     0xf1, 0x74, 0x6c, 0x08, 0xca, 0x18, 0x21, 0x7c, 0x32, 0x90, 0x5e, 0x46,
885     0x2e, 0x36, 0xce, 0x3b, 0xe3, 0x9e, 0x77, 0x2c, 0x18, 0x0e, 0x86, 0x03,
886     0x9b, 0x27, 0x83, 0xa2, 0xec, 0x07, 0xa2, 0x8f, 0xb5, 0xc5, 0x5d, 0xf0,
887     0x6f, 0x4c, 0x52, 0xc9, 0xde, 0x2b, 0xcb, 0xf6, 0x95, 0x58, 0x17, 0x18,
888     0x39, 0x95, 0x49, 0x7c, 0xea, 0x95, 0x6a, 0xe5, 0x15, 0xd2, 0x26, 0x18,
889     0x98, 0xfa, 0x05, 0x10, 0x15, 0x72, 0x8e, 0x5a, 0x8a, 0xac, 0xaa, 0x68,
890     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x02, 0x02,
891     0x02, 0x04, 0x00, 0x03, 0x82, 0x01, 0x05, 0x00, 0x02, 0x82, 0x01, 0x00,
892     0x08, 0x87, 0x8a, 0x5f, 0x4f, 0x3b, 0xef, 0xe1, 0x77, 0x13, 0x3b, 0xd7,
893     0x58, 0x76, 0xc9, 0xeb, 0x7e, 0x2d, 0xcc, 0x7e, 0xed, 0xc5, 0xee, 0xf9,
894     0x2d, 0x55, 0xb0, 0xe2, 0x37, 0x8c, 0x51, 0x87, 0x6a, 0x8e, 0x0d, 0xb2,
895     0x08, 0xed, 0x4f, 0x88, 0x9b, 0x63, 0x19, 0x7a, 0x67, 0xa1, 0x61, 0xd8,
896     0x17, 0xa0, 0x2c, 0xdb, 0xc2, 0xfa, 0xb3, 0x4f, 0xe7, 0xcb, 0x16, 0xf2,
897     0xe7, 0xd0, 0x2c, 0xf8, 0xcc, 0x97, 0xd3, 0xe7, 0xae, 0xc2, 0x71, 0xd8,
898     0x2b, 0x12, 0x83, 0xe9, 0x5a, 0x45, 0xfe, 0x66, 0x5c, 0xa2, 0xb6, 0xce,
899     0x2f, 0x04, 0x05, 0xe7, 0xa7, 0xbc, 0xe5, 0x63, 0x1a, 0x93, 0x3d, 0x4d,
900     0xf4, 0x77, 0xdd, 0x2a, 0xc9, 0x51, 0x7b, 0xf5, 0x54, 0xa2, 0xab, 0x26,
901     0xee, 0x16, 0xd3, 0x83, 0x92, 0x85, 0x40, 0x67, 0xa3, 0xa9, 0x31, 0x16,
902     0x64, 0x45, 0x5a, 0x2a, 0x9d, 0xa8, 0x1a, 0x84, 0x2f, 0x59, 0x57, 0x6b,
903     0xbb, 0x51, 0x28, 0xbd, 0x91, 0x60, 0xd9, 0x8f, 0x54, 0x6a, 0xa0, 0x6b,
904     0xb2, 0xf6, 0x78, 0x79, 0xd2, 0x3a, 0x8f, 0xa6, 0x24, 0x7e, 0xe9, 0x6e,
905     0x66, 0x30, 0xed, 0xbf, 0x55, 0x71, 0x9c, 0x89, 0x81, 0xf0, 0xa7, 0xe7,
906     0x05, 0x87, 0x51, 0xc1, 0xff, 0xe5, 0xcf, 0x1f, 0x19, 0xe4, 0xeb, 0x7c,
907     0x1c, 0x1a, 0x58, 0xd5, 0x22, 0x3d, 0x31, 0x22, 0xc7, 0x8b, 0x60, 0xf5,
908     0xe8, 0x95, 0x73, 0xe0, 0x20, 0xe2, 0x4f, 0x03, 0x9e, 0x89, 0x34, 0x91,
909     0x5e, 0xda, 0x4f, 0x60, 0xff, 0xc9, 0x4f, 0x5a, 0x37, 0x1e, 0xb0, 0xed,
910     0x26, 0x4c, 0xa4, 0xc6, 0x26, 0xc9, 0xcc, 0xab, 0xd2, 0x1a, 0x3a, 0x82,
911     0x68, 0x03, 0x49, 0x8f, 0xb0, 0xb9, 0xc8, 0x48, 0x9d, 0xc7, 0xdf, 0x8b,
912     0x1c, 0xbf, 0xda, 0x89, 0x78, 0x6f, 0xd3, 0x62, 0xad, 0x35, 0xb9, 0xd3,
913     0x9b, 0xd0, 0x25, 0x65
914 };
915 
916 /*
917  * Load PKCS3 DH Parameters that contain an optional private value length.
918  * Loading a named group should not overwrite the private value length field.
919  */
920 static int dh_load_pkcs3_namedgroup_privlen_test(void)
921 {
922     int ret, privlen = 0;
923     EVP_PKEY *pkey = NULL;
924     const unsigned char *p = dh_pub_der;
925 
926     ret = TEST_ptr(pkey = d2i_PUBKEY_ex(NULL, &p, sizeof(dh_pub_der),
927                                         NULL, NULL))
928           && TEST_true(EVP_PKEY_get_int_param(pkey, OSSL_PKEY_PARAM_DH_PRIV_LEN,
929                                               &privlen))
930           && TEST_int_eq(privlen, 1024);
931 
932     EVP_PKEY_free(pkey);
933     return ret;
934 }
935 
936 #endif
937 
938 int setup_tests(void)
939 {
940 #ifdef OPENSSL_NO_DH
941     TEST_note("No DH support");
942 #else
943     ADD_TEST(dh_test);
944     ADD_TEST(dh_computekey_range_test);
945     ADD_TEST(rfc5114_test);
946     ADD_TEST(rfc7919_test);
947     ADD_ALL_TESTS(dh_test_prime_groups, OSSL_NELEM(prime_groups));
948     ADD_TEST(dh_get_nid);
949     ADD_TEST(dh_load_pkcs3_namedgroup_privlen_test);
950     ADD_TEST(dh_rfc5114_fix_nid_test);
951     ADD_TEST(dh_set_dh_nid_test);
952 #endif
953     return 1;
954 }
955