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