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