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