Fix up path generation to use OPENSSL_MODULES
[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     int szA, szB;
562     const rfc5114_td *td = NULL;
563     BIGNUM *priv_key = NULL, *pub_key = NULL;
564     const BIGNUM *pub_key_tmp;
565
566     for (i = 0; i < (int)OSSL_NELEM(rfctd); i++) {
567         td = rfctd + i;
568         /* Set up DH structures setting key components */
569         if (!TEST_ptr(dhA = td->get_param())
570                 || !TEST_ptr(dhB = td->get_param()))
571             goto bad_err;
572
573         if (!TEST_ptr(priv_key = BN_bin2bn(td->xA, td->xA_len, NULL))
574                 || !TEST_ptr(pub_key = BN_bin2bn(td->yA, td->yA_len, NULL))
575                 || !TEST_true(DH_set0_key(dhA, pub_key, priv_key)))
576             goto bad_err;
577
578         if (!TEST_ptr(priv_key = BN_bin2bn(td->xB, td->xB_len, NULL))
579                 || !TEST_ptr(pub_key = BN_bin2bn(td->yB, td->yB_len, NULL))
580                 || !TEST_true( DH_set0_key(dhB, pub_key, priv_key)))
581             goto bad_err;
582         priv_key = pub_key = NULL;
583
584         if (!TEST_int_gt(szA = DH_size(dhA), 0)
585                 || !TEST_int_gt(szB = DH_size(dhB), 0)
586                 || !TEST_size_t_eq(td->Z_len, (size_t)szA)
587                 || !TEST_size_t_eq(td->Z_len, (size_t)szB))
588             goto err;
589
590         if (!TEST_ptr(Z1 = OPENSSL_malloc((size_t)szA))
591                 || !TEST_ptr(Z2 = OPENSSL_malloc((size_t)szB)))
592             goto bad_err;
593         /*
594          * Work out shared secrets using both sides and compare with expected
595          * values.
596          */
597         DH_get0_key(dhB, &pub_key_tmp, NULL);
598         if (!TEST_int_ne(DH_compute_key(Z1, pub_key_tmp, dhA), -1))
599             goto bad_err;
600
601         DH_get0_key(dhA, &pub_key_tmp, NULL);
602         if (!TEST_int_ne(DH_compute_key(Z2, pub_key_tmp, dhB), -1))
603             goto bad_err;
604
605         if (!TEST_mem_eq(Z1, td->Z_len, td->Z, td->Z_len)
606                 || !TEST_mem_eq(Z2, td->Z_len, td->Z, td->Z_len))
607             goto err;
608
609         DH_free(dhA);
610         dhA = NULL;
611         DH_free(dhB);
612         dhB = NULL;
613         OPENSSL_free(Z1);
614         Z1 = NULL;
615         OPENSSL_free(Z2);
616         Z2 = NULL;
617     }
618     return 1;
619
620  bad_err:
621     DH_free(dhA);
622     DH_free(dhB);
623     BN_free(pub_key);
624     BN_free(priv_key);
625     OPENSSL_free(Z1);
626     OPENSSL_free(Z2);
627     TEST_error("Initialisation error RFC5114 set %d\n", i + 1);
628     return 0;
629
630  err:
631     DH_free(dhA);
632     DH_free(dhB);
633     OPENSSL_free(Z1);
634     OPENSSL_free(Z2);
635     TEST_error("Test failed RFC5114 set %d\n", i + 1);
636     return 0;
637 }
638
639 static int rfc7919_test(void)
640 {
641     DH *a = NULL, *b = NULL;
642     const BIGNUM *apub_key = NULL, *bpub_key = NULL;
643     unsigned char *abuf = NULL;
644     unsigned char *bbuf = NULL;
645     int i, alen, blen, aout, bout;
646     int ret = 0;
647
648     if (!TEST_ptr(a = DH_new_by_nid(NID_ffdhe2048)))
649          goto err;
650
651     if (!DH_check(a, &i))
652         goto err;
653     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
654             || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
655             || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
656             || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
657             || !TEST_false(i))
658         goto err;
659
660     if (!DH_generate_key(a))
661         goto err;
662     DH_get0_key(a, &apub_key, NULL);
663
664     /* now create another copy of the DH group for the peer */
665     if (!TEST_ptr(b = DH_new_by_nid(NID_ffdhe2048)))
666         goto err;
667
668     if (!DH_generate_key(b))
669         goto err;
670     DH_get0_key(b, &bpub_key, NULL);
671
672     alen = DH_size(a);
673     if (!TEST_int_gt(alen, 0) || !TEST_ptr(abuf = OPENSSL_malloc(alen))
674             || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
675         goto err;
676
677     blen = DH_size(b);
678     if (!TEST_int_gt(blen, 0) || !TEST_ptr(bbuf = OPENSSL_malloc(blen))
679             || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
680         goto err;
681
682     if (!TEST_true(aout >= 20)
683             || !TEST_mem_eq(abuf, aout, bbuf, bout))
684         goto err;
685
686     ret = 1;
687
688  err:
689     OPENSSL_free(abuf);
690     OPENSSL_free(bbuf);
691     DH_free(a);
692     DH_free(b);
693     return ret;
694 }
695
696 static int prime_groups[] = {
697     NID_ffdhe2048,
698     NID_ffdhe3072,
699     NID_ffdhe4096,
700     NID_ffdhe6144,
701     NID_ffdhe8192,
702     NID_modp_2048,
703     NID_modp_3072,
704     NID_modp_4096,
705     NID_modp_6144,
706 };
707
708 static int dh_test_prime_groups(int index)
709 {
710     int ok = 0;
711     DH *dh = NULL;
712     const BIGNUM *p, *q, *g;
713
714     if (!TEST_ptr(dh = DH_new_by_nid(prime_groups[index])))
715         goto err;
716     DH_get0_pqg(dh, &p, &q, &g);
717     if (!TEST_ptr(p) || !TEST_ptr(q) || !TEST_ptr(g))
718         goto err;
719
720     if (!TEST_int_eq(DH_get_nid(dh), prime_groups[index]))
721         goto err;
722
723     /* Since q is set there is no need for the private length to be set */
724     if (!TEST_int_eq((int)DH_get_length(dh), 0))
725         goto err;
726
727     ok = 1;
728 err:
729     DH_free(dh);
730     return ok;
731 }
732
733 static int dh_get_nid(void)
734 {
735     int ok = 0;
736     const BIGNUM *p, *q, *g;
737     BIGNUM *pcpy = NULL, *gcpy = NULL, *qcpy = NULL;
738     DH *dh1 = DH_new_by_nid(NID_ffdhe2048);
739     DH *dh2 = DH_new();
740
741     if (!TEST_ptr(dh1)
742         || !TEST_ptr(dh2))
743         goto err;
744
745     /* Set new DH parameters manually using a existing named group's p & g */
746     DH_get0_pqg(dh1, &p, &q, &g);
747     if (!TEST_ptr(p)
748         || !TEST_ptr(q)
749         || !TEST_ptr(g)
750         || !TEST_ptr(pcpy = BN_dup(p))
751         || !TEST_ptr(gcpy = BN_dup(g)))
752         goto err;
753
754     if (!TEST_true(DH_set0_pqg(dh2, pcpy, NULL, gcpy)))
755         goto err;
756     pcpy = gcpy = NULL;
757     /* Test q is set if p and g are provided */
758     if (!TEST_ptr(DH_get0_q(dh2)))
759         goto err;
760
761     /* Test that setting p & g manually returns that it is a named group */
762     if (!TEST_int_eq(DH_get_nid(dh2), NID_ffdhe2048))
763         goto err;
764
765     /* Test that after changing g it is no longer a named group */
766     if (!TEST_ptr(gcpy = BN_dup(BN_value_one())))
767        goto err;
768     if (!TEST_true(DH_set0_pqg(dh2, NULL, NULL, gcpy)))
769        goto err;
770     gcpy = NULL;
771     if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
772         goto err;
773
774     /* Test that setting an incorrect q results in this not being a named group */
775     if (!TEST_ptr(pcpy = BN_dup(p))
776         || !TEST_ptr(qcpy = BN_dup(q))
777         || !TEST_ptr(gcpy = BN_dup(g))
778         || !TEST_int_eq(BN_add_word(qcpy, 2), 1)
779         || !TEST_true(DH_set0_pqg(dh2, pcpy, qcpy, gcpy)))
780         goto err;
781     pcpy = qcpy = gcpy = NULL;
782     if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
783         goto err;
784
785     ok = 1;
786 err:
787     BN_free(pcpy);
788     BN_free(qcpy);
789     BN_free(gcpy);
790     DH_free(dh2);
791     DH_free(dh1);
792     return ok;
793 }
794
795 static const unsigned char dh_pub_der[] = {
796     0x30, 0x82, 0x02, 0x28, 0x30, 0x82, 0x01, 0x1b, 0x06, 0x09, 0x2a, 0x86,
797     0x48, 0x86, 0xf7, 0x0d, 0x01, 0x03, 0x01, 0x30, 0x82, 0x01, 0x0c, 0x02,
798     0x82, 0x01, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
799     0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b,
800     0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74,
801     0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79,
802     0x8e, 0x34, 0x04, 0xdd, 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b,
803     0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d,
804     0x6d, 0x51, 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
805     0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6,
806     0xf4, 0x06, 0xb7, 0xed, 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5,
807     0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51,
808     0xec, 0xe4, 0x5b, 0x3d, 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05,
809     0x98, 0xda, 0x48, 0x36, 0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8,
810     0xfd, 0x24, 0xcf, 0x5f, 0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96,
811     0x1c, 0x62, 0xf3, 0x56, 0x20, 0x85, 0x52, 0xbb, 0x9e, 0xd5, 0x29, 0x07,
812     0x70, 0x96, 0x96, 0x6d, 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04,
813     0xf1, 0x74, 0x6c, 0x08, 0xca, 0x18, 0x21, 0x7c, 0x32, 0x90, 0x5e, 0x46,
814     0x2e, 0x36, 0xce, 0x3b, 0xe3, 0x9e, 0x77, 0x2c, 0x18, 0x0e, 0x86, 0x03,
815     0x9b, 0x27, 0x83, 0xa2, 0xec, 0x07, 0xa2, 0x8f, 0xb5, 0xc5, 0x5d, 0xf0,
816     0x6f, 0x4c, 0x52, 0xc9, 0xde, 0x2b, 0xcb, 0xf6, 0x95, 0x58, 0x17, 0x18,
817     0x39, 0x95, 0x49, 0x7c, 0xea, 0x95, 0x6a, 0xe5, 0x15, 0xd2, 0x26, 0x18,
818     0x98, 0xfa, 0x05, 0x10, 0x15, 0x72, 0x8e, 0x5a, 0x8a, 0xac, 0xaa, 0x68,
819     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x02, 0x02,
820     0x02, 0x04, 0x00, 0x03, 0x82, 0x01, 0x05, 0x00, 0x02, 0x82, 0x01, 0x00,
821     0x08, 0x87, 0x8a, 0x5f, 0x4f, 0x3b, 0xef, 0xe1, 0x77, 0x13, 0x3b, 0xd7,
822     0x58, 0x76, 0xc9, 0xeb, 0x7e, 0x2d, 0xcc, 0x7e, 0xed, 0xc5, 0xee, 0xf9,
823     0x2d, 0x55, 0xb0, 0xe2, 0x37, 0x8c, 0x51, 0x87, 0x6a, 0x8e, 0x0d, 0xb2,
824     0x08, 0xed, 0x4f, 0x88, 0x9b, 0x63, 0x19, 0x7a, 0x67, 0xa1, 0x61, 0xd8,
825     0x17, 0xa0, 0x2c, 0xdb, 0xc2, 0xfa, 0xb3, 0x4f, 0xe7, 0xcb, 0x16, 0xf2,
826     0xe7, 0xd0, 0x2c, 0xf8, 0xcc, 0x97, 0xd3, 0xe7, 0xae, 0xc2, 0x71, 0xd8,
827     0x2b, 0x12, 0x83, 0xe9, 0x5a, 0x45, 0xfe, 0x66, 0x5c, 0xa2, 0xb6, 0xce,
828     0x2f, 0x04, 0x05, 0xe7, 0xa7, 0xbc, 0xe5, 0x63, 0x1a, 0x93, 0x3d, 0x4d,
829     0xf4, 0x77, 0xdd, 0x2a, 0xc9, 0x51, 0x7b, 0xf5, 0x54, 0xa2, 0xab, 0x26,
830     0xee, 0x16, 0xd3, 0x83, 0x92, 0x85, 0x40, 0x67, 0xa3, 0xa9, 0x31, 0x16,
831     0x64, 0x45, 0x5a, 0x2a, 0x9d, 0xa8, 0x1a, 0x84, 0x2f, 0x59, 0x57, 0x6b,
832     0xbb, 0x51, 0x28, 0xbd, 0x91, 0x60, 0xd9, 0x8f, 0x54, 0x6a, 0xa0, 0x6b,
833     0xb2, 0xf6, 0x78, 0x79, 0xd2, 0x3a, 0x8f, 0xa6, 0x24, 0x7e, 0xe9, 0x6e,
834     0x66, 0x30, 0xed, 0xbf, 0x55, 0x71, 0x9c, 0x89, 0x81, 0xf0, 0xa7, 0xe7,
835     0x05, 0x87, 0x51, 0xc1, 0xff, 0xe5, 0xcf, 0x1f, 0x19, 0xe4, 0xeb, 0x7c,
836     0x1c, 0x1a, 0x58, 0xd5, 0x22, 0x3d, 0x31, 0x22, 0xc7, 0x8b, 0x60, 0xf5,
837     0xe8, 0x95, 0x73, 0xe0, 0x20, 0xe2, 0x4f, 0x03, 0x9e, 0x89, 0x34, 0x91,
838     0x5e, 0xda, 0x4f, 0x60, 0xff, 0xc9, 0x4f, 0x5a, 0x37, 0x1e, 0xb0, 0xed,
839     0x26, 0x4c, 0xa4, 0xc6, 0x26, 0xc9, 0xcc, 0xab, 0xd2, 0x1a, 0x3a, 0x82,
840     0x68, 0x03, 0x49, 0x8f, 0xb0, 0xb9, 0xc8, 0x48, 0x9d, 0xc7, 0xdf, 0x8b,
841     0x1c, 0xbf, 0xda, 0x89, 0x78, 0x6f, 0xd3, 0x62, 0xad, 0x35, 0xb9, 0xd3,
842     0x9b, 0xd0, 0x25, 0x65
843 };
844
845 /*
846  * Load PKCS3 DH Parameters that contain an optional private value length.
847  * Loading a named group should not overwrite the private value length field.
848  */
849 static int dh_load_pkcs3_namedgroup_privlen_test(void)
850 {
851     int ret, privlen = 0;
852     EVP_PKEY *pkey = NULL;
853     const unsigned char *p = dh_pub_der;
854
855     ret = TEST_ptr(pkey = d2i_PUBKEY_ex(NULL, &p, sizeof(dh_pub_der),
856                                         NULL, NULL))
857           && TEST_true(EVP_PKEY_get_int_param(pkey, OSSL_PKEY_PARAM_DH_PRIV_LEN,
858                                               &privlen))
859           && TEST_int_eq(privlen, 1024);
860
861     EVP_PKEY_free(pkey);
862     return ret;
863 }
864
865 #endif
866
867 int setup_tests(void)
868 {
869 #ifdef OPENSSL_NO_DH
870     TEST_note("No DH support");
871 #else
872     ADD_TEST(dh_test);
873     ADD_TEST(dh_computekey_range_test);
874     ADD_TEST(rfc5114_test);
875     ADD_TEST(rfc7919_test);
876     ADD_ALL_TESTS(dh_test_prime_groups, OSSL_NELEM(prime_groups));
877     ADD_TEST(dh_get_nid);
878     ADD_TEST(dh_load_pkcs3_namedgroup_privlen_test);
879 #endif
880     return 1;
881 }