2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
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
11 * DH low level APIs are deprecated for public use, but still ok for
14 #include "internal/deprecated.h"
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>
30 # include <openssl/dh.h>
31 # include "crypto/bn_dh.h"
32 # include "crypto/dh.h"
34 static int cb(int p, int n, BN_GENCB *arg);
36 static int dh_test(void)
39 BIGNUM *p = NULL, *q = NULL, *g = NULL;
40 const BIGNUM *p2, *q2, *g2;
41 BIGNUM *priv_key = NULL;
42 const BIGNUM *pub_key2, *priv_key2;
47 const BIGNUM *ap = NULL, *ag = NULL, *apub_key = NULL;
48 const BIGNUM *bpub_key = NULL, *bpriv_key = NULL;
49 BIGNUM *bp = NULL, *bg = NULL, *cpriv_key = NULL;
50 unsigned char *abuf = NULL;
51 unsigned char *bbuf = NULL;
52 unsigned char *cbuf = NULL;
53 int i, alen, blen, clen, aout, bout, cout;
56 if (!TEST_ptr(dh = DH_new())
57 || !TEST_ptr(p = BN_new())
58 || !TEST_ptr(q = BN_new())
59 || !TEST_ptr(g = BN_new())
60 || !TEST_ptr(priv_key = BN_new()))
67 /* using a small predefined Sophie Germain DH group with generator 3 */
68 if (!TEST_true(BN_set_word(p, 4079L))
69 || !TEST_true(BN_set_word(q, 2039L))
70 || !TEST_true(BN_set_word(g, 3L))
71 || !TEST_true(DH_set0_pqg(dh, p, q, g)))
74 /* check fails, because p is way too small */
75 if (!DH_check(dh, &i))
77 i ^= DH_MODULUS_TOO_SMALL;
78 if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
79 || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
80 || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
81 || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
82 || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
83 || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
84 || !TEST_false(i & DH_CHECK_INVALID_J_VALUE)
85 || !TEST_false(i & DH_MODULUS_TOO_SMALL)
86 || !TEST_false(i & DH_MODULUS_TOO_LARGE)
90 /* test the combined getter for p, q, and g */
91 DH_get0_pqg(dh, &p2, &q2, &g2);
92 if (!TEST_ptr_eq(p2, p)
93 || !TEST_ptr_eq(q2, q)
94 || !TEST_ptr_eq(g2, g))
97 /* test the simple getters for p, q, and g */
98 if (!TEST_ptr_eq(DH_get0_p(dh), p2)
99 || !TEST_ptr_eq(DH_get0_q(dh), q2)
100 || !TEST_ptr_eq(DH_get0_g(dh), g2))
103 /* set the private key only*/
104 if (!TEST_true(BN_set_word(priv_key, 1234L))
105 || !TEST_true(DH_set0_key(dh, NULL, priv_key)))
108 /* test the combined getter for pub_key and priv_key */
109 DH_get0_key(dh, &pub_key2, &priv_key2);
110 if (!TEST_ptr_eq(pub_key2, NULL)
111 || !TEST_ptr_eq(priv_key2, priv_key))
114 /* test the simple getters for pub_key and priv_key */
115 if (!TEST_ptr_eq(DH_get0_pub_key(dh), pub_key2)
116 || !TEST_ptr_eq(DH_get0_priv_key(dh), priv_key2))
119 /* now generate a key pair (expect failure since modulus is too small) */
120 if (!TEST_false(DH_generate_key(dh)))
123 /* We'll have a stale error on the queue from the above test so clear it */
130 /* generate a DH group ... */
131 if (!TEST_ptr(_cb = BN_GENCB_new()))
133 BN_GENCB_set(_cb, &cb, NULL);
134 if (!TEST_ptr(a = DH_new())
135 || !TEST_true(DH_generate_parameters_ex(a, 512,
136 DH_GENERATOR_5, _cb)))
139 /* ... and check whether it is valid */
140 if (!DH_check(a, &i))
142 if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
143 || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
144 || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
145 || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
146 || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
147 || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
148 || !TEST_false(i & DH_CHECK_INVALID_J_VALUE)
149 || !TEST_false(i & DH_MODULUS_TOO_SMALL)
150 || !TEST_false(i & DH_MODULUS_TOO_LARGE)
154 DH_get0_pqg(a, &ap, NULL, &ag);
156 /* now create another copy of the DH group for the peer */
157 if (!TEST_ptr(b = DH_new()))
160 if (!TEST_ptr(bp = BN_dup(ap))
161 || !TEST_ptr(bg = BN_dup(ag))
162 || !TEST_true(DH_set0_pqg(b, bp, NULL, bg)))
167 * III) simulate a key exchange
170 if (!DH_generate_key(a))
172 DH_get0_key(a, &apub_key, NULL);
174 if (!DH_generate_key(b))
176 DH_get0_key(b, &bpub_key, &bpriv_key);
178 /* Also test with a private-key-only copy of |b|. */
179 if (!TEST_ptr(c = DHparams_dup(b))
180 || !TEST_ptr(cpriv_key = BN_dup(bpriv_key))
181 || !TEST_true(DH_set0_key(c, NULL, cpriv_key)))
186 if (!TEST_ptr(abuf = OPENSSL_malloc(alen))
187 || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
191 if (!TEST_ptr(bbuf = OPENSSL_malloc(blen))
192 || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
196 if (!TEST_ptr(cbuf = OPENSSL_malloc(clen))
197 || !TEST_true((cout = DH_compute_key(cbuf, apub_key, c)) != -1))
200 if (!TEST_true(aout >= 20)
201 || !TEST_mem_eq(abuf, aout, bbuf, bout)
202 || !TEST_mem_eq(abuf, aout, cbuf, cout))
209 /* an error occurred before p,q,g were assigned to dh */
214 /* an error occurred before priv_key was assigned to dh */
233 static int cb(int p, int n, BN_GENCB *arg)
238 static int dh_computekey_range_test(void)
242 BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL;
243 unsigned char *buf = NULL;
245 if (!TEST_ptr(p = BN_dup(&ossl_bignum_ffdhe2048_p))
246 || !TEST_ptr(q = BN_dup(&ossl_bignum_ffdhe2048_q))
247 || !TEST_ptr(g = BN_dup(&ossl_bignum_const_2))
248 || !TEST_ptr(dh = DH_new())
249 || !TEST_true(DH_set0_pqg(dh, p, q, g)))
253 if (!TEST_int_gt(sz = DH_size(dh), 0)
254 || !TEST_ptr(buf = OPENSSL_malloc(sz))
255 || !TEST_ptr(pub = BN_new())
256 || !TEST_ptr(priv = BN_new()))
259 if (!TEST_true(BN_set_word(priv, 1))
260 || !TEST_true(DH_set0_key(dh, NULL, priv)))
263 if (!TEST_true(BN_set_word(pub, 1)))
266 /* Given z = pub ^ priv mod p */
268 /* Test that z == 1 fails */
269 if (!TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0))
271 /* Test that z == 0 fails */
272 if (!TEST_ptr(BN_copy(pub, DH_get0_p(dh)))
273 || !TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0))
275 /* Test that z == p - 1 fails */
276 if (!TEST_true(BN_sub_word(pub, 1))
277 || !TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0))
279 /* Test that z == p - 2 passes */
280 if (!TEST_true(BN_sub_word(pub, 1))
281 || !TEST_int_eq(ossl_dh_compute_key(buf, pub, dh), sz))
296 /* Test data from RFC 5114 */
298 static const unsigned char dhtest_1024_160_xA[] = {
299 0xB9, 0xA3, 0xB3, 0xAE, 0x8F, 0xEF, 0xC1, 0xA2, 0x93, 0x04, 0x96, 0x50,
300 0x70, 0x86, 0xF8, 0x45, 0x5D, 0x48, 0x94, 0x3E
303 static const unsigned char dhtest_1024_160_yA[] = {
304 0x2A, 0x85, 0x3B, 0x3D, 0x92, 0x19, 0x75, 0x01, 0xB9, 0x01, 0x5B, 0x2D,
305 0xEB, 0x3E, 0xD8, 0x4F, 0x5E, 0x02, 0x1D, 0xCC, 0x3E, 0x52, 0xF1, 0x09,
306 0xD3, 0x27, 0x3D, 0x2B, 0x75, 0x21, 0x28, 0x1C, 0xBA, 0xBE, 0x0E, 0x76,
307 0xFF, 0x57, 0x27, 0xFA, 0x8A, 0xCC, 0xE2, 0x69, 0x56, 0xBA, 0x9A, 0x1F,
308 0xCA, 0x26, 0xF2, 0x02, 0x28, 0xD8, 0x69, 0x3F, 0xEB, 0x10, 0x84, 0x1D,
309 0x84, 0xA7, 0x36, 0x00, 0x54, 0xEC, 0xE5, 0xA7, 0xF5, 0xB7, 0xA6, 0x1A,
310 0xD3, 0xDF, 0xB3, 0xC6, 0x0D, 0x2E, 0x43, 0x10, 0x6D, 0x87, 0x27, 0xDA,
311 0x37, 0xDF, 0x9C, 0xCE, 0x95, 0xB4, 0x78, 0x75, 0x5D, 0x06, 0xBC, 0xEA,
312 0x8F, 0x9D, 0x45, 0x96, 0x5F, 0x75, 0xA5, 0xF3, 0xD1, 0xDF, 0x37, 0x01,
313 0x16, 0x5F, 0xC9, 0xE5, 0x0C, 0x42, 0x79, 0xCE, 0xB0, 0x7F, 0x98, 0x95,
314 0x40, 0xAE, 0x96, 0xD5, 0xD8, 0x8E, 0xD7, 0x76
317 static const unsigned char dhtest_1024_160_xB[] = {
318 0x93, 0x92, 0xC9, 0xF9, 0xEB, 0x6A, 0x7A, 0x6A, 0x90, 0x22, 0xF7, 0xD8,
319 0x3E, 0x72, 0x23, 0xC6, 0x83, 0x5B, 0xBD, 0xDA
322 static const unsigned char dhtest_1024_160_yB[] = {
323 0x71, 0x7A, 0x6C, 0xB0, 0x53, 0x37, 0x1F, 0xF4, 0xA3, 0xB9, 0x32, 0x94,
324 0x1C, 0x1E, 0x56, 0x63, 0xF8, 0x61, 0xA1, 0xD6, 0xAD, 0x34, 0xAE, 0x66,
325 0x57, 0x6D, 0xFB, 0x98, 0xF6, 0xC6, 0xCB, 0xF9, 0xDD, 0xD5, 0xA5, 0x6C,
326 0x78, 0x33, 0xF6, 0xBC, 0xFD, 0xFF, 0x09, 0x55, 0x82, 0xAD, 0x86, 0x8E,
327 0x44, 0x0E, 0x8D, 0x09, 0xFD, 0x76, 0x9E, 0x3C, 0xEC, 0xCD, 0xC3, 0xD3,
328 0xB1, 0xE4, 0xCF, 0xA0, 0x57, 0x77, 0x6C, 0xAA, 0xF9, 0x73, 0x9B, 0x6A,
329 0x9F, 0xEE, 0x8E, 0x74, 0x11, 0xF8, 0xD6, 0xDA, 0xC0, 0x9D, 0x6A, 0x4E,
330 0xDB, 0x46, 0xCC, 0x2B, 0x5D, 0x52, 0x03, 0x09, 0x0E, 0xAE, 0x61, 0x26,
331 0x31, 0x1E, 0x53, 0xFD, 0x2C, 0x14, 0xB5, 0x74, 0xE6, 0xA3, 0x10, 0x9A,
332 0x3D, 0xA1, 0xBE, 0x41, 0xBD, 0xCE, 0xAA, 0x18, 0x6F, 0x5C, 0xE0, 0x67,
333 0x16, 0xA2, 0xB6, 0xA0, 0x7B, 0x3C, 0x33, 0xFE
336 static const unsigned char dhtest_1024_160_Z[] = {
337 0x5C, 0x80, 0x4F, 0x45, 0x4D, 0x30, 0xD9, 0xC4, 0xDF, 0x85, 0x27, 0x1F,
338 0x93, 0x52, 0x8C, 0x91, 0xDF, 0x6B, 0x48, 0xAB, 0x5F, 0x80, 0xB3, 0xB5,
339 0x9C, 0xAA, 0xC1, 0xB2, 0x8F, 0x8A, 0xCB, 0xA9, 0xCD, 0x3E, 0x39, 0xF3,
340 0xCB, 0x61, 0x45, 0x25, 0xD9, 0x52, 0x1D, 0x2E, 0x64, 0x4C, 0x53, 0xB8,
341 0x07, 0xB8, 0x10, 0xF3, 0x40, 0x06, 0x2F, 0x25, 0x7D, 0x7D, 0x6F, 0xBF,
342 0xE8, 0xD5, 0xE8, 0xF0, 0x72, 0xE9, 0xB6, 0xE9, 0xAF, 0xDA, 0x94, 0x13,
343 0xEA, 0xFB, 0x2E, 0x8B, 0x06, 0x99, 0xB1, 0xFB, 0x5A, 0x0C, 0xAC, 0xED,
344 0xDE, 0xAE, 0xAD, 0x7E, 0x9C, 0xFB, 0xB3, 0x6A, 0xE2, 0xB4, 0x20, 0x83,
345 0x5B, 0xD8, 0x3A, 0x19, 0xFB, 0x0B, 0x5E, 0x96, 0xBF, 0x8F, 0xA4, 0xD0,
346 0x9E, 0x34, 0x55, 0x25, 0x16, 0x7E, 0xCD, 0x91, 0x55, 0x41, 0x6F, 0x46,
347 0xF4, 0x08, 0xED, 0x31, 0xB6, 0x3C, 0x6E, 0x6D
350 static const unsigned char dhtest_2048_224_xA[] = {
351 0x22, 0xE6, 0x26, 0x01, 0xDB, 0xFF, 0xD0, 0x67, 0x08, 0xA6, 0x80, 0xF7,
352 0x47, 0xF3, 0x61, 0xF7, 0x6D, 0x8F, 0x4F, 0x72, 0x1A, 0x05, 0x48, 0xE4,
353 0x83, 0x29, 0x4B, 0x0C
356 static const unsigned char dhtest_2048_224_yA[] = {
357 0x1B, 0x3A, 0x63, 0x45, 0x1B, 0xD8, 0x86, 0xE6, 0x99, 0xE6, 0x7B, 0x49,
358 0x4E, 0x28, 0x8B, 0xD7, 0xF8, 0xE0, 0xD3, 0x70, 0xBA, 0xDD, 0xA7, 0xA0,
359 0xEF, 0xD2, 0xFD, 0xE7, 0xD8, 0xF6, 0x61, 0x45, 0xCC, 0x9F, 0x28, 0x04,
360 0x19, 0x97, 0x5E, 0xB8, 0x08, 0x87, 0x7C, 0x8A, 0x4C, 0x0C, 0x8E, 0x0B,
361 0xD4, 0x8D, 0x4A, 0x54, 0x01, 0xEB, 0x1E, 0x87, 0x76, 0xBF, 0xEE, 0xE1,
362 0x34, 0xC0, 0x38, 0x31, 0xAC, 0x27, 0x3C, 0xD9, 0xD6, 0x35, 0xAB, 0x0C,
363 0xE0, 0x06, 0xA4, 0x2A, 0x88, 0x7E, 0x3F, 0x52, 0xFB, 0x87, 0x66, 0xB6,
364 0x50, 0xF3, 0x80, 0x78, 0xBC, 0x8E, 0xE8, 0x58, 0x0C, 0xEF, 0xE2, 0x43,
365 0x96, 0x8C, 0xFC, 0x4F, 0x8D, 0xC3, 0xDB, 0x08, 0x45, 0x54, 0x17, 0x1D,
366 0x41, 0xBF, 0x2E, 0x86, 0x1B, 0x7B, 0xB4, 0xD6, 0x9D, 0xD0, 0xE0, 0x1E,
367 0xA3, 0x87, 0xCB, 0xAA, 0x5C, 0xA6, 0x72, 0xAF, 0xCB, 0xE8, 0xBD, 0xB9,
368 0xD6, 0x2D, 0x4C, 0xE1, 0x5F, 0x17, 0xDD, 0x36, 0xF9, 0x1E, 0xD1, 0xEE,
369 0xDD, 0x65, 0xCA, 0x4A, 0x06, 0x45, 0x5C, 0xB9, 0x4C, 0xD4, 0x0A, 0x52,
370 0xEC, 0x36, 0x0E, 0x84, 0xB3, 0xC9, 0x26, 0xE2, 0x2C, 0x43, 0x80, 0xA3,
371 0xBF, 0x30, 0x9D, 0x56, 0x84, 0x97, 0x68, 0xB7, 0xF5, 0x2C, 0xFD, 0xF6,
372 0x55, 0xFD, 0x05, 0x3A, 0x7E, 0xF7, 0x06, 0x97, 0x9E, 0x7E, 0x58, 0x06,
373 0xB1, 0x7D, 0xFA, 0xE5, 0x3A, 0xD2, 0xA5, 0xBC, 0x56, 0x8E, 0xBB, 0x52,
374 0x9A, 0x7A, 0x61, 0xD6, 0x8D, 0x25, 0x6F, 0x8F, 0xC9, 0x7C, 0x07, 0x4A,
375 0x86, 0x1D, 0x82, 0x7E, 0x2E, 0xBC, 0x8C, 0x61, 0x34, 0x55, 0x31, 0x15,
376 0xB7, 0x0E, 0x71, 0x03, 0x92, 0x0A, 0xA1, 0x6D, 0x85, 0xE5, 0x2B, 0xCB,
377 0xAB, 0x8D, 0x78, 0x6A, 0x68, 0x17, 0x8F, 0xA8, 0xFF, 0x7C, 0x2F, 0x5C,
378 0x71, 0x64, 0x8D, 0x6F
381 static const unsigned char dhtest_2048_224_xB[] = {
382 0x4F, 0xF3, 0xBC, 0x96, 0xC7, 0xFC, 0x6A, 0x6D, 0x71, 0xD3, 0xB3, 0x63,
383 0x80, 0x0A, 0x7C, 0xDF, 0xEF, 0x6F, 0xC4, 0x1B, 0x44, 0x17, 0xEA, 0x15,
384 0x35, 0x3B, 0x75, 0x90
387 static const unsigned char dhtest_2048_224_yB[] = {
388 0x4D, 0xCE, 0xE9, 0x92, 0xA9, 0x76, 0x2A, 0x13, 0xF2, 0xF8, 0x38, 0x44,
389 0xAD, 0x3D, 0x77, 0xEE, 0x0E, 0x31, 0xC9, 0x71, 0x8B, 0x3D, 0xB6, 0xC2,
390 0x03, 0x5D, 0x39, 0x61, 0x18, 0x2C, 0x3E, 0x0B, 0xA2, 0x47, 0xEC, 0x41,
391 0x82, 0xD7, 0x60, 0xCD, 0x48, 0xD9, 0x95, 0x99, 0x97, 0x06, 0x22, 0xA1,
392 0x88, 0x1B, 0xBA, 0x2D, 0xC8, 0x22, 0x93, 0x9C, 0x78, 0xC3, 0x91, 0x2C,
393 0x66, 0x61, 0xFA, 0x54, 0x38, 0xB2, 0x07, 0x66, 0x22, 0x2B, 0x75, 0xE2,
394 0x4C, 0x2E, 0x3A, 0xD0, 0xC7, 0x28, 0x72, 0x36, 0x12, 0x95, 0x25, 0xEE,
395 0x15, 0xB5, 0xDD, 0x79, 0x98, 0xAA, 0x04, 0xC4, 0xA9, 0x69, 0x6C, 0xAC,
396 0xD7, 0x17, 0x20, 0x83, 0xA9, 0x7A, 0x81, 0x66, 0x4E, 0xAD, 0x2C, 0x47,
397 0x9E, 0x44, 0x4E, 0x4C, 0x06, 0x54, 0xCC, 0x19, 0xE2, 0x8D, 0x77, 0x03,
398 0xCE, 0xE8, 0xDA, 0xCD, 0x61, 0x26, 0xF5, 0xD6, 0x65, 0xEC, 0x52, 0xC6,
399 0x72, 0x55, 0xDB, 0x92, 0x01, 0x4B, 0x03, 0x7E, 0xB6, 0x21, 0xA2, 0xAC,
400 0x8E, 0x36, 0x5D, 0xE0, 0x71, 0xFF, 0xC1, 0x40, 0x0A, 0xCF, 0x07, 0x7A,
401 0x12, 0x91, 0x3D, 0xD8, 0xDE, 0x89, 0x47, 0x34, 0x37, 0xAB, 0x7B, 0xA3,
402 0x46, 0x74, 0x3C, 0x1B, 0x21, 0x5D, 0xD9, 0xC1, 0x21, 0x64, 0xA7, 0xE4,
403 0x05, 0x31, 0x18, 0xD1, 0x99, 0xBE, 0xC8, 0xEF, 0x6F, 0xC5, 0x61, 0x17,
404 0x0C, 0x84, 0xC8, 0x7D, 0x10, 0xEE, 0x9A, 0x67, 0x4A, 0x1F, 0xA8, 0xFF,
405 0xE1, 0x3B, 0xDF, 0xBA, 0x1D, 0x44, 0xDE, 0x48, 0x94, 0x6D, 0x68, 0xDC,
406 0x0C, 0xDD, 0x77, 0x76, 0x35, 0xA7, 0xAB, 0x5B, 0xFB, 0x1E, 0x4B, 0xB7,
407 0xB8, 0x56, 0xF9, 0x68, 0x27, 0x73, 0x4C, 0x18, 0x41, 0x38, 0xE9, 0x15,
408 0xD9, 0xC3, 0x00, 0x2E, 0xBC, 0xE5, 0x31, 0x20, 0x54, 0x6A, 0x7E, 0x20,
409 0x02, 0x14, 0x2B, 0x6C
412 static const unsigned char dhtest_2048_224_Z[] = {
413 0x34, 0xD9, 0xBD, 0xDC, 0x1B, 0x42, 0x17, 0x6C, 0x31, 0x3F, 0xEA, 0x03,
414 0x4C, 0x21, 0x03, 0x4D, 0x07, 0x4A, 0x63, 0x13, 0xBB, 0x4E, 0xCD, 0xB3,
415 0x70, 0x3F, 0xFF, 0x42, 0x45, 0x67, 0xA4, 0x6B, 0xDF, 0x75, 0x53, 0x0E,
416 0xDE, 0x0A, 0x9D, 0xA5, 0x22, 0x9D, 0xE7, 0xD7, 0x67, 0x32, 0x28, 0x6C,
417 0xBC, 0x0F, 0x91, 0xDA, 0x4C, 0x3C, 0x85, 0x2F, 0xC0, 0x99, 0xC6, 0x79,
418 0x53, 0x1D, 0x94, 0xC7, 0x8A, 0xB0, 0x3D, 0x9D, 0xEC, 0xB0, 0xA4, 0xE4,
419 0xCA, 0x8B, 0x2B, 0xB4, 0x59, 0x1C, 0x40, 0x21, 0xCF, 0x8C, 0xE3, 0xA2,
420 0x0A, 0x54, 0x1D, 0x33, 0x99, 0x40, 0x17, 0xD0, 0x20, 0x0A, 0xE2, 0xC9,
421 0x51, 0x6E, 0x2F, 0xF5, 0x14, 0x57, 0x79, 0x26, 0x9E, 0x86, 0x2B, 0x0F,
422 0xB4, 0x74, 0xA2, 0xD5, 0x6D, 0xC3, 0x1E, 0xD5, 0x69, 0xA7, 0x70, 0x0B,
423 0x4C, 0x4A, 0xB1, 0x6B, 0x22, 0xA4, 0x55, 0x13, 0x53, 0x1E, 0xF5, 0x23,
424 0xD7, 0x12, 0x12, 0x07, 0x7B, 0x5A, 0x16, 0x9B, 0xDE, 0xFF, 0xAD, 0x7A,
425 0xD9, 0x60, 0x82, 0x84, 0xC7, 0x79, 0x5B, 0x6D, 0x5A, 0x51, 0x83, 0xB8,
426 0x70, 0x66, 0xDE, 0x17, 0xD8, 0xD6, 0x71, 0xC9, 0xEB, 0xD8, 0xEC, 0x89,
427 0x54, 0x4D, 0x45, 0xEC, 0x06, 0x15, 0x93, 0xD4, 0x42, 0xC6, 0x2A, 0xB9,
428 0xCE, 0x3B, 0x1C, 0xB9, 0x94, 0x3A, 0x1D, 0x23, 0xA5, 0xEA, 0x3B, 0xCF,
429 0x21, 0xA0, 0x14, 0x71, 0xE6, 0x7E, 0x00, 0x3E, 0x7F, 0x8A, 0x69, 0xC7,
430 0x28, 0xBE, 0x49, 0x0B, 0x2F, 0xC8, 0x8C, 0xFE, 0xB9, 0x2D, 0xB6, 0xA2,
431 0x15, 0xE5, 0xD0, 0x3C, 0x17, 0xC4, 0x64, 0xC9, 0xAC, 0x1A, 0x46, 0xE2,
432 0x03, 0xE1, 0x3F, 0x95, 0x29, 0x95, 0xFB, 0x03, 0xC6, 0x9D, 0x3C, 0xC4,
433 0x7F, 0xCB, 0x51, 0x0B, 0x69, 0x98, 0xFF, 0xD3, 0xAA, 0x6D, 0xE7, 0x3C,
434 0xF9, 0xF6, 0x38, 0x69
437 static const unsigned char dhtest_2048_256_xA[] = {
438 0x08, 0x81, 0x38, 0x2C, 0xDB, 0x87, 0x66, 0x0C, 0x6D, 0xC1, 0x3E, 0x61,
439 0x49, 0x38, 0xD5, 0xB9, 0xC8, 0xB2, 0xF2, 0x48, 0x58, 0x1C, 0xC5, 0xE3,
440 0x1B, 0x35, 0x45, 0x43, 0x97, 0xFC, 0xE5, 0x0E
443 static const unsigned char dhtest_2048_256_yA[] = {
444 0x2E, 0x93, 0x80, 0xC8, 0x32, 0x3A, 0xF9, 0x75, 0x45, 0xBC, 0x49, 0x41,
445 0xDE, 0xB0, 0xEC, 0x37, 0x42, 0xC6, 0x2F, 0xE0, 0xEC, 0xE8, 0x24, 0xA6,
446 0xAB, 0xDB, 0xE6, 0x6C, 0x59, 0xBE, 0xE0, 0x24, 0x29, 0x11, 0xBF, 0xB9,
447 0x67, 0x23, 0x5C, 0xEB, 0xA3, 0x5A, 0xE1, 0x3E, 0x4E, 0xC7, 0x52, 0xBE,
448 0x63, 0x0B, 0x92, 0xDC, 0x4B, 0xDE, 0x28, 0x47, 0xA9, 0xC6, 0x2C, 0xB8,
449 0x15, 0x27, 0x45, 0x42, 0x1F, 0xB7, 0xEB, 0x60, 0xA6, 0x3C, 0x0F, 0xE9,
450 0x15, 0x9F, 0xCC, 0xE7, 0x26, 0xCE, 0x7C, 0xD8, 0x52, 0x3D, 0x74, 0x50,
451 0x66, 0x7E, 0xF8, 0x40, 0xE4, 0x91, 0x91, 0x21, 0xEB, 0x5F, 0x01, 0xC8,
452 0xC9, 0xB0, 0xD3, 0xD6, 0x48, 0xA9, 0x3B, 0xFB, 0x75, 0x68, 0x9E, 0x82,
453 0x44, 0xAC, 0x13, 0x4A, 0xF5, 0x44, 0x71, 0x1C, 0xE7, 0x9A, 0x02, 0xDC,
454 0xC3, 0x42, 0x26, 0x68, 0x47, 0x80, 0xDD, 0xDC, 0xB4, 0x98, 0x59, 0x41,
455 0x06, 0xC3, 0x7F, 0x5B, 0xC7, 0x98, 0x56, 0x48, 0x7A, 0xF5, 0xAB, 0x02,
456 0x2A, 0x2E, 0x5E, 0x42, 0xF0, 0x98, 0x97, 0xC1, 0xA8, 0x5A, 0x11, 0xEA,
457 0x02, 0x12, 0xAF, 0x04, 0xD9, 0xB4, 0xCE, 0xBC, 0x93, 0x7C, 0x3C, 0x1A,
458 0x3E, 0x15, 0xA8, 0xA0, 0x34, 0x2E, 0x33, 0x76, 0x15, 0xC8, 0x4E, 0x7F,
459 0xE3, 0xB8, 0xB9, 0xB8, 0x7F, 0xB1, 0xE7, 0x3A, 0x15, 0xAF, 0x12, 0xA3,
460 0x0D, 0x74, 0x6E, 0x06, 0xDF, 0xC3, 0x4F, 0x29, 0x0D, 0x79, 0x7C, 0xE5,
461 0x1A, 0xA1, 0x3A, 0xA7, 0x85, 0xBF, 0x66, 0x58, 0xAF, 0xF5, 0xE4, 0xB0,
462 0x93, 0x00, 0x3C, 0xBE, 0xAF, 0x66, 0x5B, 0x3C, 0x2E, 0x11, 0x3A, 0x3A,
463 0x4E, 0x90, 0x52, 0x69, 0x34, 0x1D, 0xC0, 0x71, 0x14, 0x26, 0x68, 0x5F,
464 0x4E, 0xF3, 0x7E, 0x86, 0x8A, 0x81, 0x26, 0xFF, 0x3F, 0x22, 0x79, 0xB5,
465 0x7C, 0xA6, 0x7E, 0x29
468 static const unsigned char dhtest_2048_256_xB[] = {
469 0x7D, 0x62, 0xA7, 0xE3, 0xEF, 0x36, 0xDE, 0x61, 0x7B, 0x13, 0xD1, 0xAF,
470 0xB8, 0x2C, 0x78, 0x0D, 0x83, 0xA2, 0x3B, 0xD4, 0xEE, 0x67, 0x05, 0x64,
471 0x51, 0x21, 0xF3, 0x71, 0xF5, 0x46, 0xA5, 0x3D
474 static const unsigned char dhtest_2048_256_yB[] = {
475 0x57, 0x5F, 0x03, 0x51, 0xBD, 0x2B, 0x1B, 0x81, 0x74, 0x48, 0xBD, 0xF8,
476 0x7A, 0x6C, 0x36, 0x2C, 0x1E, 0x28, 0x9D, 0x39, 0x03, 0xA3, 0x0B, 0x98,
477 0x32, 0xC5, 0x74, 0x1F, 0xA2, 0x50, 0x36, 0x3E, 0x7A, 0xCB, 0xC7, 0xF7,
478 0x7F, 0x3D, 0xAC, 0xBC, 0x1F, 0x13, 0x1A, 0xDD, 0x8E, 0x03, 0x36, 0x7E,
479 0xFF, 0x8F, 0xBB, 0xB3, 0xE1, 0xC5, 0x78, 0x44, 0x24, 0x80, 0x9B, 0x25,
480 0xAF, 0xE4, 0xD2, 0x26, 0x2A, 0x1A, 0x6F, 0xD2, 0xFA, 0xB6, 0x41, 0x05,
481 0xCA, 0x30, 0xA6, 0x74, 0xE0, 0x7F, 0x78, 0x09, 0x85, 0x20, 0x88, 0x63,
482 0x2F, 0xC0, 0x49, 0x23, 0x37, 0x91, 0xAD, 0x4E, 0xDD, 0x08, 0x3A, 0x97,
483 0x8B, 0x88, 0x3E, 0xE6, 0x18, 0xBC, 0x5E, 0x0D, 0xD0, 0x47, 0x41, 0x5F,
484 0x2D, 0x95, 0xE6, 0x83, 0xCF, 0x14, 0x82, 0x6B, 0x5F, 0xBE, 0x10, 0xD3,
485 0xCE, 0x41, 0xC6, 0xC1, 0x20, 0xC7, 0x8A, 0xB2, 0x00, 0x08, 0xC6, 0x98,
486 0xBF, 0x7F, 0x0B, 0xCA, 0xB9, 0xD7, 0xF4, 0x07, 0xBE, 0xD0, 0xF4, 0x3A,
487 0xFB, 0x29, 0x70, 0xF5, 0x7F, 0x8D, 0x12, 0x04, 0x39, 0x63, 0xE6, 0x6D,
488 0xDD, 0x32, 0x0D, 0x59, 0x9A, 0xD9, 0x93, 0x6C, 0x8F, 0x44, 0x13, 0x7C,
489 0x08, 0xB1, 0x80, 0xEC, 0x5E, 0x98, 0x5C, 0xEB, 0xE1, 0x86, 0xF3, 0xD5,
490 0x49, 0x67, 0x7E, 0x80, 0x60, 0x73, 0x31, 0xEE, 0x17, 0xAF, 0x33, 0x80,
491 0xA7, 0x25, 0xB0, 0x78, 0x23, 0x17, 0xD7, 0xDD, 0x43, 0xF5, 0x9D, 0x7A,
492 0xF9, 0x56, 0x8A, 0x9B, 0xB6, 0x3A, 0x84, 0xD3, 0x65, 0xF9, 0x22, 0x44,
493 0xED, 0x12, 0x09, 0x88, 0x21, 0x93, 0x02, 0xF4, 0x29, 0x24, 0xC7, 0xCA,
494 0x90, 0xB8, 0x9D, 0x24, 0xF7, 0x1B, 0x0A, 0xB6, 0x97, 0x82, 0x3D, 0x7D,
495 0xEB, 0x1A, 0xFF, 0x5B, 0x0E, 0x8E, 0x4A, 0x45, 0xD4, 0x9F, 0x7F, 0x53,
496 0x75, 0x7E, 0x19, 0x13
499 static const unsigned char dhtest_2048_256_Z[] = {
500 0x86, 0xC7, 0x0B, 0xF8, 0xD0, 0xBB, 0x81, 0xBB, 0x01, 0x07, 0x8A, 0x17,
501 0x21, 0x9C, 0xB7, 0xD2, 0x72, 0x03, 0xDB, 0x2A, 0x19, 0xC8, 0x77, 0xF1,
502 0xD1, 0xF1, 0x9F, 0xD7, 0xD7, 0x7E, 0xF2, 0x25, 0x46, 0xA6, 0x8F, 0x00,
503 0x5A, 0xD5, 0x2D, 0xC8, 0x45, 0x53, 0xB7, 0x8F, 0xC6, 0x03, 0x30, 0xBE,
504 0x51, 0xEA, 0x7C, 0x06, 0x72, 0xCA, 0xC1, 0x51, 0x5E, 0x4B, 0x35, 0xC0,
505 0x47, 0xB9, 0xA5, 0x51, 0xB8, 0x8F, 0x39, 0xDC, 0x26, 0xDA, 0x14, 0xA0,
506 0x9E, 0xF7, 0x47, 0x74, 0xD4, 0x7C, 0x76, 0x2D, 0xD1, 0x77, 0xF9, 0xED,
507 0x5B, 0xC2, 0xF1, 0x1E, 0x52, 0xC8, 0x79, 0xBD, 0x95, 0x09, 0x85, 0x04,
508 0xCD, 0x9E, 0xEC, 0xD8, 0xA8, 0xF9, 0xB3, 0xEF, 0xBD, 0x1F, 0x00, 0x8A,
509 0xC5, 0x85, 0x30, 0x97, 0xD9, 0xD1, 0x83, 0x7F, 0x2B, 0x18, 0xF7, 0x7C,
510 0xD7, 0xBE, 0x01, 0xAF, 0x80, 0xA7, 0xC7, 0xB5, 0xEA, 0x3C, 0xA5, 0x4C,
511 0xC0, 0x2D, 0x0C, 0x11, 0x6F, 0xEE, 0x3F, 0x95, 0xBB, 0x87, 0x39, 0x93,
512 0x85, 0x87, 0x5D, 0x7E, 0x86, 0x74, 0x7E, 0x67, 0x6E, 0x72, 0x89, 0x38,
513 0xAC, 0xBF, 0xF7, 0x09, 0x8E, 0x05, 0xBE, 0x4D, 0xCF, 0xB2, 0x40, 0x52,
514 0xB8, 0x3A, 0xEF, 0xFB, 0x14, 0x78, 0x3F, 0x02, 0x9A, 0xDB, 0xDE, 0x7F,
515 0x53, 0xFA, 0xE9, 0x20, 0x84, 0x22, 0x40, 0x90, 0xE0, 0x07, 0xCE, 0xE9,
516 0x4D, 0x4B, 0xF2, 0xBA, 0xCE, 0x9F, 0xFD, 0x4B, 0x57, 0xD2, 0xAF, 0x7C,
517 0x72, 0x4D, 0x0C, 0xAA, 0x19, 0xBF, 0x05, 0x01, 0xF6, 0xF1, 0x7B, 0x4A,
518 0xA1, 0x0F, 0x42, 0x5E, 0x3E, 0xA7, 0x60, 0x80, 0xB4, 0xB9, 0xD6, 0xB3,
519 0xCE, 0xFE, 0xA1, 0x15, 0xB2, 0xCE, 0xB8, 0x78, 0x9B, 0xB8, 0xA3, 0xB0,
520 0xEA, 0x87, 0xFE, 0xBE, 0x63, 0xB6, 0xC8, 0xF8, 0x46, 0xEC, 0x6D, 0xB0,
521 0xC2, 0x6C, 0x5D, 0x7C
525 DH *(*get_param) (void);
526 const unsigned char *xA;
528 const unsigned char *yA;
530 const unsigned char *xB;
532 const unsigned char *yB;
534 const unsigned char *Z;
538 # define make_rfc5114_td(pre) { \
540 dhtest_##pre##_xA, sizeof(dhtest_##pre##_xA), \
541 dhtest_##pre##_yA, sizeof(dhtest_##pre##_yA), \
542 dhtest_##pre##_xB, sizeof(dhtest_##pre##_xB), \
543 dhtest_##pre##_yB, sizeof(dhtest_##pre##_yB), \
544 dhtest_##pre##_Z, sizeof(dhtest_##pre##_Z) \
547 static const rfc5114_td rfctd[] = {
548 make_rfc5114_td(1024_160),
549 make_rfc5114_td(2048_224),
550 make_rfc5114_td(2048_256)
553 static int rfc5114_test(void)
558 unsigned char *Z1 = NULL;
559 unsigned char *Z2 = NULL;
560 const rfc5114_td *td = NULL;
561 BIGNUM *priv_key = NULL, *pub_key = NULL;
562 const BIGNUM *pub_key_tmp;
564 for (i = 0; i < (int)OSSL_NELEM(rfctd); i++) {
566 /* Set up DH structures setting key components */
567 if (!TEST_ptr(dhA = td->get_param())
568 || !TEST_ptr(dhB = td->get_param()))
571 if (!TEST_ptr(priv_key = BN_bin2bn(td->xA, td->xA_len, NULL))
572 || !TEST_ptr(pub_key = BN_bin2bn(td->yA, td->yA_len, NULL))
573 || !TEST_true(DH_set0_key(dhA, pub_key, priv_key)))
576 if (!TEST_ptr(priv_key = BN_bin2bn(td->xB, td->xB_len, NULL))
577 || !TEST_ptr(pub_key = BN_bin2bn(td->yB, td->yB_len, NULL))
578 || !TEST_true( DH_set0_key(dhB, pub_key, priv_key)))
580 priv_key = pub_key = NULL;
582 if (!TEST_uint_eq(td->Z_len, (size_t)DH_size(dhA))
583 || !TEST_uint_eq(td->Z_len, (size_t)DH_size(dhB)))
586 if (!TEST_ptr(Z1 = OPENSSL_malloc(DH_size(dhA)))
587 || !TEST_ptr(Z2 = OPENSSL_malloc(DH_size(dhB))))
590 * Work out shared secrets using both sides and compare with expected
593 DH_get0_key(dhB, &pub_key_tmp, NULL);
594 if (!TEST_int_ne(DH_compute_key(Z1, pub_key_tmp, dhA), -1))
597 DH_get0_key(dhA, &pub_key_tmp, NULL);
598 if (!TEST_int_ne(DH_compute_key(Z2, pub_key_tmp, dhB), -1))
601 if (!TEST_mem_eq(Z1, td->Z_len, td->Z, td->Z_len)
602 || !TEST_mem_eq(Z2, td->Z_len, td->Z, td->Z_len))
623 TEST_error("Initialisation error RFC5114 set %d\n", i + 1);
631 TEST_error("Test failed RFC5114 set %d\n", i + 1);
635 static int rfc7919_test(void)
637 DH *a = NULL, *b = NULL;
638 const BIGNUM *apub_key = NULL, *bpub_key = NULL;
639 unsigned char *abuf = NULL;
640 unsigned char *bbuf = NULL;
641 int i, alen, blen, aout, bout;
644 if (!TEST_ptr(a = DH_new_by_nid(NID_ffdhe2048)))
647 if (!DH_check(a, &i))
649 if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
650 || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
651 || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
652 || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
656 if (!DH_generate_key(a))
658 DH_get0_key(a, &apub_key, NULL);
660 /* now create another copy of the DH group for the peer */
661 if (!TEST_ptr(b = DH_new_by_nid(NID_ffdhe2048)))
664 if (!DH_generate_key(b))
666 DH_get0_key(b, &bpub_key, NULL);
669 if (!TEST_int_gt(alen, 0) || !TEST_ptr(abuf = OPENSSL_malloc(alen))
670 || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
674 if (!TEST_int_gt(blen, 0) || !TEST_ptr(bbuf = OPENSSL_malloc(blen))
675 || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
678 if (!TEST_true(aout >= 20)
679 || !TEST_mem_eq(abuf, aout, bbuf, bout))
692 static int prime_groups[] = {
704 static int dh_test_prime_groups(int index)
708 const BIGNUM *p, *q, *g;
711 if (!TEST_ptr(dh = DH_new_by_nid(prime_groups[index])))
713 DH_get0_pqg(dh, &p, &q, &g);
714 if (!TEST_ptr(p) || !TEST_ptr(q) || !TEST_ptr(g))
717 if (!TEST_int_eq(DH_get_nid(dh), prime_groups[index]))
720 len = DH_get_length(dh);
721 if (!TEST_true(len > 0)
722 || !TEST_true(len <= BN_num_bits(q)))
731 static int dh_get_nid(void)
734 const BIGNUM *p, *q, *g;
735 BIGNUM *pcpy = NULL, *gcpy = NULL, *qcpy = NULL;
736 DH *dh1 = DH_new_by_nid(NID_ffdhe2048);
743 /* Set new DH parameters manually using a existing named group's p & g */
744 DH_get0_pqg(dh1, &p, &q, &g);
748 || !TEST_ptr(pcpy = BN_dup(p))
749 || !TEST_ptr(gcpy = BN_dup(g)))
752 if (!TEST_true(DH_set0_pqg(dh2, pcpy, NULL, gcpy)))
755 /* Test q is set if p and g are provided */
756 if (!TEST_ptr(DH_get0_q(dh2)))
759 /* Test that setting p & g manually returns that it is a named group */
760 if (!TEST_int_eq(DH_get_nid(dh2), NID_ffdhe2048))
763 /* Test that after changing g it is no longer a named group */
764 if (!TEST_ptr(gcpy = BN_dup(BN_value_one())))
766 if (!TEST_true(DH_set0_pqg(dh2, NULL, NULL, gcpy)))
769 if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
772 /* Test that setting an incorrect q results in this not being a named group */
773 if (!TEST_ptr(pcpy = BN_dup(p))
774 || !TEST_ptr(qcpy = BN_dup(q))
775 || !TEST_ptr(gcpy = BN_dup(g))
776 || !TEST_int_eq(BN_add_word(qcpy, 2), 1)
777 || !TEST_true(DH_set0_pqg(dh2, pcpy, qcpy, gcpy)))
779 pcpy = qcpy = gcpy = NULL;
780 if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
796 int setup_tests(void)
799 TEST_note("No DH support");
802 ADD_TEST(dh_computekey_range_test);
803 ADD_TEST(rfc5114_test);
804 ADD_TEST(rfc7919_test);
805 ADD_ALL_TESTS(dh_test_prime_groups, OSSL_NELEM(prime_groups));
806 ADD_TEST(dh_get_nid);