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