Raise an error on syscall failure in tls_retry_write_records
[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_rfc5114_fix_nid_test(void)
734 {
735     int ok = 0;
736     EVP_PKEY_CTX *paramgen_ctx;
737
738     /* Run the test. Success is any time the test does not cause a SIGSEGV interrupt */
739     paramgen_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DHX, 0);
740     if (!TEST_ptr(paramgen_ctx))
741         goto err;
742     if (!TEST_int_eq(EVP_PKEY_paramgen_init(paramgen_ctx), 1))
743         goto err;
744     /* Tested function is called here */
745     if (!TEST_int_eq(EVP_PKEY_CTX_set_dhx_rfc5114(paramgen_ctx, 3), 1))
746         goto err;
747     /* If we're still running then the test passed. */
748     ok = 1;
749 err:
750     EVP_PKEY_CTX_free(paramgen_ctx);
751     return ok;
752 }
753
754 static int dh_get_nid(void)
755 {
756     int ok = 0;
757     const BIGNUM *p, *q, *g;
758     BIGNUM *pcpy = NULL, *gcpy = NULL, *qcpy = NULL;
759     DH *dh1 = DH_new_by_nid(NID_ffdhe2048);
760     DH *dh2 = DH_new();
761
762     if (!TEST_ptr(dh1)
763         || !TEST_ptr(dh2))
764         goto err;
765
766     /* Set new DH parameters manually using a existing named group's p & g */
767     DH_get0_pqg(dh1, &p, &q, &g);
768     if (!TEST_ptr(p)
769         || !TEST_ptr(q)
770         || !TEST_ptr(g)
771         || !TEST_ptr(pcpy = BN_dup(p))
772         || !TEST_ptr(gcpy = BN_dup(g)))
773         goto err;
774
775     if (!TEST_true(DH_set0_pqg(dh2, pcpy, NULL, gcpy)))
776         goto err;
777     pcpy = gcpy = NULL;
778     /* Test q is set if p and g are provided */
779     if (!TEST_ptr(DH_get0_q(dh2)))
780         goto err;
781
782     /* Test that setting p & g manually returns that it is a named group */
783     if (!TEST_int_eq(DH_get_nid(dh2), NID_ffdhe2048))
784         goto err;
785
786     /* Test that after changing g it is no longer a named group */
787     if (!TEST_ptr(gcpy = BN_dup(BN_value_one())))
788        goto err;
789     if (!TEST_true(DH_set0_pqg(dh2, NULL, NULL, gcpy)))
790        goto err;
791     gcpy = NULL;
792     if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
793         goto err;
794
795     /* Test that setting an incorrect q results in this not being a named group */
796     if (!TEST_ptr(pcpy = BN_dup(p))
797         || !TEST_ptr(qcpy = BN_dup(q))
798         || !TEST_ptr(gcpy = BN_dup(g))
799         || !TEST_int_eq(BN_add_word(qcpy, 2), 1)
800         || !TEST_true(DH_set0_pqg(dh2, pcpy, qcpy, gcpy)))
801         goto err;
802     pcpy = qcpy = gcpy = NULL;
803     if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
804         goto err;
805
806     ok = 1;
807 err:
808     BN_free(pcpy);
809     BN_free(qcpy);
810     BN_free(gcpy);
811     DH_free(dh2);
812     DH_free(dh1);
813     return ok;
814 }
815
816 static const unsigned char dh_pub_der[] = {
817     0x30, 0x82, 0x02, 0x28, 0x30, 0x82, 0x01, 0x1b, 0x06, 0x09, 0x2a, 0x86,
818     0x48, 0x86, 0xf7, 0x0d, 0x01, 0x03, 0x01, 0x30, 0x82, 0x01, 0x0c, 0x02,
819     0x82, 0x01, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
820     0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b,
821     0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74,
822     0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79,
823     0x8e, 0x34, 0x04, 0xdd, 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b,
824     0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d,
825     0x6d, 0x51, 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
826     0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6,
827     0xf4, 0x06, 0xb7, 0xed, 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5,
828     0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51,
829     0xec, 0xe4, 0x5b, 0x3d, 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05,
830     0x98, 0xda, 0x48, 0x36, 0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8,
831     0xfd, 0x24, 0xcf, 0x5f, 0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96,
832     0x1c, 0x62, 0xf3, 0x56, 0x20, 0x85, 0x52, 0xbb, 0x9e, 0xd5, 0x29, 0x07,
833     0x70, 0x96, 0x96, 0x6d, 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04,
834     0xf1, 0x74, 0x6c, 0x08, 0xca, 0x18, 0x21, 0x7c, 0x32, 0x90, 0x5e, 0x46,
835     0x2e, 0x36, 0xce, 0x3b, 0xe3, 0x9e, 0x77, 0x2c, 0x18, 0x0e, 0x86, 0x03,
836     0x9b, 0x27, 0x83, 0xa2, 0xec, 0x07, 0xa2, 0x8f, 0xb5, 0xc5, 0x5d, 0xf0,
837     0x6f, 0x4c, 0x52, 0xc9, 0xde, 0x2b, 0xcb, 0xf6, 0x95, 0x58, 0x17, 0x18,
838     0x39, 0x95, 0x49, 0x7c, 0xea, 0x95, 0x6a, 0xe5, 0x15, 0xd2, 0x26, 0x18,
839     0x98, 0xfa, 0x05, 0x10, 0x15, 0x72, 0x8e, 0x5a, 0x8a, 0xac, 0xaa, 0x68,
840     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x02, 0x02,
841     0x02, 0x04, 0x00, 0x03, 0x82, 0x01, 0x05, 0x00, 0x02, 0x82, 0x01, 0x00,
842     0x08, 0x87, 0x8a, 0x5f, 0x4f, 0x3b, 0xef, 0xe1, 0x77, 0x13, 0x3b, 0xd7,
843     0x58, 0x76, 0xc9, 0xeb, 0x7e, 0x2d, 0xcc, 0x7e, 0xed, 0xc5, 0xee, 0xf9,
844     0x2d, 0x55, 0xb0, 0xe2, 0x37, 0x8c, 0x51, 0x87, 0x6a, 0x8e, 0x0d, 0xb2,
845     0x08, 0xed, 0x4f, 0x88, 0x9b, 0x63, 0x19, 0x7a, 0x67, 0xa1, 0x61, 0xd8,
846     0x17, 0xa0, 0x2c, 0xdb, 0xc2, 0xfa, 0xb3, 0x4f, 0xe7, 0xcb, 0x16, 0xf2,
847     0xe7, 0xd0, 0x2c, 0xf8, 0xcc, 0x97, 0xd3, 0xe7, 0xae, 0xc2, 0x71, 0xd8,
848     0x2b, 0x12, 0x83, 0xe9, 0x5a, 0x45, 0xfe, 0x66, 0x5c, 0xa2, 0xb6, 0xce,
849     0x2f, 0x04, 0x05, 0xe7, 0xa7, 0xbc, 0xe5, 0x63, 0x1a, 0x93, 0x3d, 0x4d,
850     0xf4, 0x77, 0xdd, 0x2a, 0xc9, 0x51, 0x7b, 0xf5, 0x54, 0xa2, 0xab, 0x26,
851     0xee, 0x16, 0xd3, 0x83, 0x92, 0x85, 0x40, 0x67, 0xa3, 0xa9, 0x31, 0x16,
852     0x64, 0x45, 0x5a, 0x2a, 0x9d, 0xa8, 0x1a, 0x84, 0x2f, 0x59, 0x57, 0x6b,
853     0xbb, 0x51, 0x28, 0xbd, 0x91, 0x60, 0xd9, 0x8f, 0x54, 0x6a, 0xa0, 0x6b,
854     0xb2, 0xf6, 0x78, 0x79, 0xd2, 0x3a, 0x8f, 0xa6, 0x24, 0x7e, 0xe9, 0x6e,
855     0x66, 0x30, 0xed, 0xbf, 0x55, 0x71, 0x9c, 0x89, 0x81, 0xf0, 0xa7, 0xe7,
856     0x05, 0x87, 0x51, 0xc1, 0xff, 0xe5, 0xcf, 0x1f, 0x19, 0xe4, 0xeb, 0x7c,
857     0x1c, 0x1a, 0x58, 0xd5, 0x22, 0x3d, 0x31, 0x22, 0xc7, 0x8b, 0x60, 0xf5,
858     0xe8, 0x95, 0x73, 0xe0, 0x20, 0xe2, 0x4f, 0x03, 0x9e, 0x89, 0x34, 0x91,
859     0x5e, 0xda, 0x4f, 0x60, 0xff, 0xc9, 0x4f, 0x5a, 0x37, 0x1e, 0xb0, 0xed,
860     0x26, 0x4c, 0xa4, 0xc6, 0x26, 0xc9, 0xcc, 0xab, 0xd2, 0x1a, 0x3a, 0x82,
861     0x68, 0x03, 0x49, 0x8f, 0xb0, 0xb9, 0xc8, 0x48, 0x9d, 0xc7, 0xdf, 0x8b,
862     0x1c, 0xbf, 0xda, 0x89, 0x78, 0x6f, 0xd3, 0x62, 0xad, 0x35, 0xb9, 0xd3,
863     0x9b, 0xd0, 0x25, 0x65
864 };
865
866 /*
867  * Load PKCS3 DH Parameters that contain an optional private value length.
868  * Loading a named group should not overwrite the private value length field.
869  */
870 static int dh_load_pkcs3_namedgroup_privlen_test(void)
871 {
872     int ret, privlen = 0;
873     EVP_PKEY *pkey = NULL;
874     const unsigned char *p = dh_pub_der;
875
876     ret = TEST_ptr(pkey = d2i_PUBKEY_ex(NULL, &p, sizeof(dh_pub_der),
877                                         NULL, NULL))
878           && TEST_true(EVP_PKEY_get_int_param(pkey, OSSL_PKEY_PARAM_DH_PRIV_LEN,
879                                               &privlen))
880           && TEST_int_eq(privlen, 1024);
881
882     EVP_PKEY_free(pkey);
883     return ret;
884 }
885
886 #endif
887
888 int setup_tests(void)
889 {
890 #ifdef OPENSSL_NO_DH
891     TEST_note("No DH support");
892 #else
893     ADD_TEST(dh_test);
894     ADD_TEST(dh_computekey_range_test);
895     ADD_TEST(rfc5114_test);
896     ADD_TEST(rfc7919_test);
897     ADD_ALL_TESTS(dh_test_prime_groups, OSSL_NELEM(prime_groups));
898     ADD_TEST(dh_get_nid);
899     ADD_TEST(dh_load_pkcs3_namedgroup_privlen_test);
900     ADD_TEST(dh_rfc5114_fix_nid_test);
901 #endif
902     return 1;
903 }