]> git.ipfire.org Git - thirdparty/openssl.git/blob - test/dhtest.c
Fix BIO_get_new_index() to return an error when it is exhausted.
[thirdparty/openssl.git] / test / dhtest.c
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
35 static int cb(int p, int n, BN_GENCB *arg);
36
37 static int dh_test(void)
38 {
39 DH *dh = NULL;
40 BIGNUM *p = NULL, *q = NULL, *g = NULL;
41 const BIGNUM *p2, *q2, *g2;
42 BIGNUM *priv_key = NULL;
43 const BIGNUM *pub_key2, *priv_key2;
44 BN_GENCB *_cb = NULL;
45 DH *a = NULL;
46 DH *b = NULL;
47 DH *c = NULL;
48 const BIGNUM *ap = NULL, *ag = NULL, *apub_key = NULL;
49 const BIGNUM *bpub_key = NULL, *bpriv_key = NULL;
50 BIGNUM *bp = NULL, *bg = NULL, *cpriv_key = NULL;
51 unsigned char *abuf = NULL;
52 unsigned char *bbuf = NULL;
53 unsigned char *cbuf = NULL;
54 int i, alen, blen, clen, aout, bout, cout;
55 int ret = 0;
56
57 if (!TEST_ptr(dh = DH_new())
58 || !TEST_ptr(p = BN_new())
59 || !TEST_ptr(q = BN_new())
60 || !TEST_ptr(g = BN_new())
61 || !TEST_ptr(priv_key = BN_new()))
62 goto err1;
63
64 /*
65 * I) basic tests
66 */
67
68 /* using a small predefined Sophie Germain DH group with generator 3 */
69 if (!TEST_true(BN_set_word(p, 4079L))
70 || !TEST_true(BN_set_word(q, 2039L))
71 || !TEST_true(BN_set_word(g, 3L))
72 || !TEST_true(DH_set0_pqg(dh, p, q, g)))
73 goto err1;
74
75 /* check fails, because p is way too small */
76 if (!TEST_true(DH_check(dh, &i)))
77 goto err2;
78 i ^= DH_MODULUS_TOO_SMALL;
79 if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
80 || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
81 || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
82 || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
83 || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
84 || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
85 || !TEST_false(i & DH_CHECK_INVALID_J_VALUE)
86 || !TEST_false(i & DH_MODULUS_TOO_SMALL)
87 || !TEST_false(i & DH_MODULUS_TOO_LARGE)
88 || !TEST_false(i))
89 goto err2;
90
91 /* test the combined getter for p, q, and g */
92 DH_get0_pqg(dh, &p2, &q2, &g2);
93 if (!TEST_ptr_eq(p2, p)
94 || !TEST_ptr_eq(q2, q)
95 || !TEST_ptr_eq(g2, g))
96 goto err2;
97
98 /* test the simple getters for p, q, and g */
99 if (!TEST_ptr_eq(DH_get0_p(dh), p2)
100 || !TEST_ptr_eq(DH_get0_q(dh), q2)
101 || !TEST_ptr_eq(DH_get0_g(dh), g2))
102 goto err2;
103
104 /* set the private key only*/
105 if (!TEST_true(BN_set_word(priv_key, 1234L))
106 || !TEST_true(DH_set0_key(dh, NULL, priv_key)))
107 goto err2;
108
109 /* test the combined getter for pub_key and priv_key */
110 DH_get0_key(dh, &pub_key2, &priv_key2);
111 if (!TEST_ptr_eq(pub_key2, NULL)
112 || !TEST_ptr_eq(priv_key2, priv_key))
113 goto err3;
114
115 /* test the simple getters for pub_key and priv_key */
116 if (!TEST_ptr_eq(DH_get0_pub_key(dh), pub_key2)
117 || !TEST_ptr_eq(DH_get0_priv_key(dh), priv_key2))
118 goto err3;
119
120 /* now generate a key pair (expect failure since modulus is too small) */
121 if (!TEST_false(DH_generate_key(dh)))
122 goto err3;
123
124 /* We'll have a stale error on the queue from the above test so clear it */
125 ERR_clear_error();
126
127 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
257 static int cb(int p, int n, BN_GENCB *arg)
258 {
259 return 1;
260 }
261
262 static 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;
309 err:
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
322 static 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
327 static 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
341 static 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
346 static 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
360 static 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
374 static 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
380 static 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
405 static 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
411 static 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
436 static 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
461 static 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
467 static 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
492 static 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
498 static 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
523 static 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
548 typedef 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
571 static const rfc5114_td rfctd[] = {
572 make_rfc5114_td(1024_160),
573 make_rfc5114_td(2048_224),
574 make_rfc5114_td(2048_256)
575 };
576
577 static 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
662 static 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
719 static 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
731 static 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;
751 err:
752 DH_free(dh);
753 return ok;
754 }
755
756 static 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;
775 err:
776 EVP_PKEY_CTX_free(paramgen_ctx);
777 return ok;
778 }
779
780 static 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;
799 err:
800 EVP_PKEY_CTX_free(paramgen_ctx);
801 return ok;
802 }
803
804 static 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;
857 err:
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
866 static 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 */
920 static 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
938 int 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 }