Configure: untabify indentation
[openssl.git] / test / dhtest.c
1 /*
2  * Copyright 1995-2018 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 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "internal/nelem.h"
15 #include <openssl/crypto.h>
16 #include <openssl/bio.h>
17 #include <openssl/bn.h>
18 #include <openssl/rand.h>
19 #include <openssl/err.h>
20 #include "testutil.h"
21
22 #ifndef OPENSSL_NO_DH
23 # include <openssl/dh.h>
24
25 static int cb(int p, int n, BN_GENCB *arg);
26
27 static int dh_test(void)
28 {
29     DH *dh = NULL;
30     BIGNUM *p = NULL, *q = NULL, *g = NULL;
31     const BIGNUM *p2, *q2, *g2;
32     BIGNUM *priv_key = NULL;
33     const BIGNUM *pub_key2, *priv_key2;
34     BN_GENCB *_cb = NULL;
35     DH *a = NULL;
36     DH *b = NULL;
37     DH *c = NULL;
38     const BIGNUM *ap = NULL, *ag = NULL, *apub_key = NULL;
39     const BIGNUM *bpub_key = NULL, *bpriv_key = NULL;
40     BIGNUM *bp = NULL, *bg = NULL, *cpriv_key = NULL;
41     unsigned char *abuf = NULL;
42     unsigned char *bbuf = NULL;
43     unsigned char *cbuf = NULL;
44     int i, alen, blen, clen, aout, bout, cout;
45     int ret = 0;
46
47     if (!TEST_ptr(dh = DH_new())
48         || !TEST_ptr(p = BN_new())
49         || !TEST_ptr(q = BN_new())
50         || !TEST_ptr(g = BN_new())
51         || !TEST_ptr(priv_key = BN_new()))
52         goto err1;
53
54     /*
55      * I) basic tests
56      */
57
58     /* using a small predefined Sophie Germain DH group with generator 3 */
59     if (!TEST_true(BN_set_word(p, 4079L))
60         || !TEST_true(BN_set_word(q, 2039L))
61         || !TEST_true(BN_set_word(g, 3L))
62         || !TEST_true(DH_set0_pqg(dh, p, q, g)))
63         goto err1;
64
65     /* test the combined getter for p, q, and g */
66     DH_get0_pqg(dh, &p2, &q2, &g2);
67     if (!TEST_ptr_eq(p2, p)
68         || !TEST_ptr_eq(q2, q)
69         || !TEST_ptr_eq(g2, g))
70         goto err2;
71
72     /* test the simple getters for p, q, and g */
73     if (!TEST_ptr_eq(DH_get0_p(dh), p2)
74         || !TEST_ptr_eq(DH_get0_q(dh), q2)
75         || !TEST_ptr_eq(DH_get0_g(dh), g2))
76         goto err2;
77
78     /* set the private key only*/
79     if (!TEST_true(BN_set_word(priv_key, 1234L))
80         || !TEST_true(DH_set0_key(dh, NULL, priv_key)))
81         goto err2;
82
83     /* test the combined getter for pub_key and priv_key */
84     DH_get0_key(dh, &pub_key2, &priv_key2);
85     if (!TEST_ptr_eq(pub_key2, NULL)
86         || !TEST_ptr_eq(priv_key2, priv_key))
87         goto err3;
88
89     /* test the simple getters for pub_key and priv_key */
90     if (!TEST_ptr_eq(DH_get0_pub_key(dh), pub_key2)
91         || !TEST_ptr_eq(DH_get0_priv_key(dh), priv_key2))
92         goto err3;
93
94     /* now generate a key pair ... */
95     if (!DH_generate_key(dh))
96         goto err3;
97
98     /* ... and check whether the private key was reused: */
99
100     /* test it with the combined getter for pub_key and priv_key */
101     DH_get0_key(dh, &pub_key2, &priv_key2);
102     if (!TEST_ptr(pub_key2)
103         || !TEST_ptr_eq(priv_key2, priv_key))
104         goto err3;
105
106     /* test it the simple getters for pub_key and priv_key */
107     if (!TEST_ptr_eq(DH_get0_pub_key(dh), pub_key2)
108         || !TEST_ptr_eq(DH_get0_priv_key(dh), priv_key2))
109         goto err3;
110
111     /* check whether the public key was calculated correctly */
112     TEST_uint_eq(BN_get_word(pub_key2), 3331L);
113
114     /*
115      * II) key generation
116      */
117
118     /* generate a DH group ... */
119     if (!TEST_ptr(_cb = BN_GENCB_new()))
120         goto err3;
121     BN_GENCB_set(_cb, &cb, NULL);
122     if (!TEST_ptr(a = DH_new())
123             || !TEST_true(DH_generate_parameters_ex(a, 64,
124                                                     DH_GENERATOR_5, _cb)))
125         goto err3;
126
127     /* ... and check whether it is valid */
128     if (!DH_check(a, &i))
129         goto err3;
130     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
131             || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
132             || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
133             || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR))
134         goto err3;
135
136     DH_get0_pqg(a, &ap, NULL, &ag);
137
138     /* now create another copy of the DH group for the peer */
139     if (!TEST_ptr(b = DH_new()))
140         goto err3;
141
142     if (!TEST_ptr(bp = BN_dup(ap))
143             || !TEST_ptr(bg = BN_dup(ag))
144             || !TEST_true(DH_set0_pqg(b, bp, NULL, bg)))
145         goto err3;
146     bp = bg = NULL;
147
148     /*
149      * III) simulate a key exchange
150      */
151
152     if (!DH_generate_key(a))
153         goto err3;
154     DH_get0_key(a, &apub_key, NULL);
155
156     if (!DH_generate_key(b))
157         goto err3;
158     DH_get0_key(b, &bpub_key, &bpriv_key);
159
160     /* Also test with a private-key-only copy of |b|. */
161     if (!TEST_ptr(c = DHparams_dup(b))
162             || !TEST_ptr(cpriv_key = BN_dup(bpriv_key))
163             || !TEST_true(DH_set0_key(c, NULL, cpriv_key)))
164         goto err3;
165     cpriv_key = NULL;
166
167     alen = DH_size(a);
168     if (!TEST_ptr(abuf = OPENSSL_malloc(alen))
169             || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
170         goto err3;
171
172     blen = DH_size(b);
173     if (!TEST_ptr(bbuf = OPENSSL_malloc(blen))
174             || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
175         goto err3;
176
177     clen = DH_size(c);
178     if (!TEST_ptr(cbuf = OPENSSL_malloc(clen))
179             || !TEST_true((cout = DH_compute_key(cbuf, apub_key, c)) != -1))
180         goto err3;
181
182     if (!TEST_true(aout >= 4)
183             || !TEST_mem_eq(abuf, aout, bbuf, bout)
184             || !TEST_mem_eq(abuf, aout, cbuf, cout))
185         goto err3;
186
187     ret = 1;
188     goto success;
189
190  err1:
191     /* an error occurred before p,q,g were assigned to dh */
192     BN_free(p);
193     BN_free(q);
194     BN_free(g);
195  err2:
196     /* an error occured before priv_key was assigned to dh */
197     BN_free(priv_key);
198  err3:
199  success:
200     OPENSSL_free(abuf);
201     OPENSSL_free(bbuf);
202     OPENSSL_free(cbuf);
203     DH_free(b);
204     DH_free(a);
205     DH_free(c);
206     BN_free(bp);
207     BN_free(bg);
208     BN_free(cpriv_key);
209     BN_GENCB_free(_cb);
210     DH_free(dh);
211
212     return ret;
213 }
214
215 static int cb(int p, int n, BN_GENCB *arg)
216 {
217     return 1;
218 }
219
220 /* Test data from RFC 5114 */
221
222 static const unsigned char dhtest_1024_160_xA[] = {
223     0xB9, 0xA3, 0xB3, 0xAE, 0x8F, 0xEF, 0xC1, 0xA2, 0x93, 0x04, 0x96, 0x50,
224     0x70, 0x86, 0xF8, 0x45, 0x5D, 0x48, 0x94, 0x3E
225 };
226
227 static const unsigned char dhtest_1024_160_yA[] = {
228     0x2A, 0x85, 0x3B, 0x3D, 0x92, 0x19, 0x75, 0x01, 0xB9, 0x01, 0x5B, 0x2D,
229     0xEB, 0x3E, 0xD8, 0x4F, 0x5E, 0x02, 0x1D, 0xCC, 0x3E, 0x52, 0xF1, 0x09,
230     0xD3, 0x27, 0x3D, 0x2B, 0x75, 0x21, 0x28, 0x1C, 0xBA, 0xBE, 0x0E, 0x76,
231     0xFF, 0x57, 0x27, 0xFA, 0x8A, 0xCC, 0xE2, 0x69, 0x56, 0xBA, 0x9A, 0x1F,
232     0xCA, 0x26, 0xF2, 0x02, 0x28, 0xD8, 0x69, 0x3F, 0xEB, 0x10, 0x84, 0x1D,
233     0x84, 0xA7, 0x36, 0x00, 0x54, 0xEC, 0xE5, 0xA7, 0xF5, 0xB7, 0xA6, 0x1A,
234     0xD3, 0xDF, 0xB3, 0xC6, 0x0D, 0x2E, 0x43, 0x10, 0x6D, 0x87, 0x27, 0xDA,
235     0x37, 0xDF, 0x9C, 0xCE, 0x95, 0xB4, 0x78, 0x75, 0x5D, 0x06, 0xBC, 0xEA,
236     0x8F, 0x9D, 0x45, 0x96, 0x5F, 0x75, 0xA5, 0xF3, 0xD1, 0xDF, 0x37, 0x01,
237     0x16, 0x5F, 0xC9, 0xE5, 0x0C, 0x42, 0x79, 0xCE, 0xB0, 0x7F, 0x98, 0x95,
238     0x40, 0xAE, 0x96, 0xD5, 0xD8, 0x8E, 0xD7, 0x76
239 };
240
241 static const unsigned char dhtest_1024_160_xB[] = {
242     0x93, 0x92, 0xC9, 0xF9, 0xEB, 0x6A, 0x7A, 0x6A, 0x90, 0x22, 0xF7, 0xD8,
243     0x3E, 0x72, 0x23, 0xC6, 0x83, 0x5B, 0xBD, 0xDA
244 };
245
246 static const unsigned char dhtest_1024_160_yB[] = {
247     0x71, 0x7A, 0x6C, 0xB0, 0x53, 0x37, 0x1F, 0xF4, 0xA3, 0xB9, 0x32, 0x94,
248     0x1C, 0x1E, 0x56, 0x63, 0xF8, 0x61, 0xA1, 0xD6, 0xAD, 0x34, 0xAE, 0x66,
249     0x57, 0x6D, 0xFB, 0x98, 0xF6, 0xC6, 0xCB, 0xF9, 0xDD, 0xD5, 0xA5, 0x6C,
250     0x78, 0x33, 0xF6, 0xBC, 0xFD, 0xFF, 0x09, 0x55, 0x82, 0xAD, 0x86, 0x8E,
251     0x44, 0x0E, 0x8D, 0x09, 0xFD, 0x76, 0x9E, 0x3C, 0xEC, 0xCD, 0xC3, 0xD3,
252     0xB1, 0xE4, 0xCF, 0xA0, 0x57, 0x77, 0x6C, 0xAA, 0xF9, 0x73, 0x9B, 0x6A,
253     0x9F, 0xEE, 0x8E, 0x74, 0x11, 0xF8, 0xD6, 0xDA, 0xC0, 0x9D, 0x6A, 0x4E,
254     0xDB, 0x46, 0xCC, 0x2B, 0x5D, 0x52, 0x03, 0x09, 0x0E, 0xAE, 0x61, 0x26,
255     0x31, 0x1E, 0x53, 0xFD, 0x2C, 0x14, 0xB5, 0x74, 0xE6, 0xA3, 0x10, 0x9A,
256     0x3D, 0xA1, 0xBE, 0x41, 0xBD, 0xCE, 0xAA, 0x18, 0x6F, 0x5C, 0xE0, 0x67,
257     0x16, 0xA2, 0xB6, 0xA0, 0x7B, 0x3C, 0x33, 0xFE
258 };
259
260 static const unsigned char dhtest_1024_160_Z[] = {
261     0x5C, 0x80, 0x4F, 0x45, 0x4D, 0x30, 0xD9, 0xC4, 0xDF, 0x85, 0x27, 0x1F,
262     0x93, 0x52, 0x8C, 0x91, 0xDF, 0x6B, 0x48, 0xAB, 0x5F, 0x80, 0xB3, 0xB5,
263     0x9C, 0xAA, 0xC1, 0xB2, 0x8F, 0x8A, 0xCB, 0xA9, 0xCD, 0x3E, 0x39, 0xF3,
264     0xCB, 0x61, 0x45, 0x25, 0xD9, 0x52, 0x1D, 0x2E, 0x64, 0x4C, 0x53, 0xB8,
265     0x07, 0xB8, 0x10, 0xF3, 0x40, 0x06, 0x2F, 0x25, 0x7D, 0x7D, 0x6F, 0xBF,
266     0xE8, 0xD5, 0xE8, 0xF0, 0x72, 0xE9, 0xB6, 0xE9, 0xAF, 0xDA, 0x94, 0x13,
267     0xEA, 0xFB, 0x2E, 0x8B, 0x06, 0x99, 0xB1, 0xFB, 0x5A, 0x0C, 0xAC, 0xED,
268     0xDE, 0xAE, 0xAD, 0x7E, 0x9C, 0xFB, 0xB3, 0x6A, 0xE2, 0xB4, 0x20, 0x83,
269     0x5B, 0xD8, 0x3A, 0x19, 0xFB, 0x0B, 0x5E, 0x96, 0xBF, 0x8F, 0xA4, 0xD0,
270     0x9E, 0x34, 0x55, 0x25, 0x16, 0x7E, 0xCD, 0x91, 0x55, 0x41, 0x6F, 0x46,
271     0xF4, 0x08, 0xED, 0x31, 0xB6, 0x3C, 0x6E, 0x6D
272 };
273
274 static const unsigned char dhtest_2048_224_xA[] = {
275     0x22, 0xE6, 0x26, 0x01, 0xDB, 0xFF, 0xD0, 0x67, 0x08, 0xA6, 0x80, 0xF7,
276     0x47, 0xF3, 0x61, 0xF7, 0x6D, 0x8F, 0x4F, 0x72, 0x1A, 0x05, 0x48, 0xE4,
277     0x83, 0x29, 0x4B, 0x0C
278 };
279
280 static const unsigned char dhtest_2048_224_yA[] = {
281     0x1B, 0x3A, 0x63, 0x45, 0x1B, 0xD8, 0x86, 0xE6, 0x99, 0xE6, 0x7B, 0x49,
282     0x4E, 0x28, 0x8B, 0xD7, 0xF8, 0xE0, 0xD3, 0x70, 0xBA, 0xDD, 0xA7, 0xA0,
283     0xEF, 0xD2, 0xFD, 0xE7, 0xD8, 0xF6, 0x61, 0x45, 0xCC, 0x9F, 0x28, 0x04,
284     0x19, 0x97, 0x5E, 0xB8, 0x08, 0x87, 0x7C, 0x8A, 0x4C, 0x0C, 0x8E, 0x0B,
285     0xD4, 0x8D, 0x4A, 0x54, 0x01, 0xEB, 0x1E, 0x87, 0x76, 0xBF, 0xEE, 0xE1,
286     0x34, 0xC0, 0x38, 0x31, 0xAC, 0x27, 0x3C, 0xD9, 0xD6, 0x35, 0xAB, 0x0C,
287     0xE0, 0x06, 0xA4, 0x2A, 0x88, 0x7E, 0x3F, 0x52, 0xFB, 0x87, 0x66, 0xB6,
288     0x50, 0xF3, 0x80, 0x78, 0xBC, 0x8E, 0xE8, 0x58, 0x0C, 0xEF, 0xE2, 0x43,
289     0x96, 0x8C, 0xFC, 0x4F, 0x8D, 0xC3, 0xDB, 0x08, 0x45, 0x54, 0x17, 0x1D,
290     0x41, 0xBF, 0x2E, 0x86, 0x1B, 0x7B, 0xB4, 0xD6, 0x9D, 0xD0, 0xE0, 0x1E,
291     0xA3, 0x87, 0xCB, 0xAA, 0x5C, 0xA6, 0x72, 0xAF, 0xCB, 0xE8, 0xBD, 0xB9,
292     0xD6, 0x2D, 0x4C, 0xE1, 0x5F, 0x17, 0xDD, 0x36, 0xF9, 0x1E, 0xD1, 0xEE,
293     0xDD, 0x65, 0xCA, 0x4A, 0x06, 0x45, 0x5C, 0xB9, 0x4C, 0xD4, 0x0A, 0x52,
294     0xEC, 0x36, 0x0E, 0x84, 0xB3, 0xC9, 0x26, 0xE2, 0x2C, 0x43, 0x80, 0xA3,
295     0xBF, 0x30, 0x9D, 0x56, 0x84, 0x97, 0x68, 0xB7, 0xF5, 0x2C, 0xFD, 0xF6,
296     0x55, 0xFD, 0x05, 0x3A, 0x7E, 0xF7, 0x06, 0x97, 0x9E, 0x7E, 0x58, 0x06,
297     0xB1, 0x7D, 0xFA, 0xE5, 0x3A, 0xD2, 0xA5, 0xBC, 0x56, 0x8E, 0xBB, 0x52,
298     0x9A, 0x7A, 0x61, 0xD6, 0x8D, 0x25, 0x6F, 0x8F, 0xC9, 0x7C, 0x07, 0x4A,
299     0x86, 0x1D, 0x82, 0x7E, 0x2E, 0xBC, 0x8C, 0x61, 0x34, 0x55, 0x31, 0x15,
300     0xB7, 0x0E, 0x71, 0x03, 0x92, 0x0A, 0xA1, 0x6D, 0x85, 0xE5, 0x2B, 0xCB,
301     0xAB, 0x8D, 0x78, 0x6A, 0x68, 0x17, 0x8F, 0xA8, 0xFF, 0x7C, 0x2F, 0x5C,
302     0x71, 0x64, 0x8D, 0x6F
303 };
304
305 static const unsigned char dhtest_2048_224_xB[] = {
306     0x4F, 0xF3, 0xBC, 0x96, 0xC7, 0xFC, 0x6A, 0x6D, 0x71, 0xD3, 0xB3, 0x63,
307     0x80, 0x0A, 0x7C, 0xDF, 0xEF, 0x6F, 0xC4, 0x1B, 0x44, 0x17, 0xEA, 0x15,
308     0x35, 0x3B, 0x75, 0x90
309 };
310
311 static const unsigned char dhtest_2048_224_yB[] = {
312     0x4D, 0xCE, 0xE9, 0x92, 0xA9, 0x76, 0x2A, 0x13, 0xF2, 0xF8, 0x38, 0x44,
313     0xAD, 0x3D, 0x77, 0xEE, 0x0E, 0x31, 0xC9, 0x71, 0x8B, 0x3D, 0xB6, 0xC2,
314     0x03, 0x5D, 0x39, 0x61, 0x18, 0x2C, 0x3E, 0x0B, 0xA2, 0x47, 0xEC, 0x41,
315     0x82, 0xD7, 0x60, 0xCD, 0x48, 0xD9, 0x95, 0x99, 0x97, 0x06, 0x22, 0xA1,
316     0x88, 0x1B, 0xBA, 0x2D, 0xC8, 0x22, 0x93, 0x9C, 0x78, 0xC3, 0x91, 0x2C,
317     0x66, 0x61, 0xFA, 0x54, 0x38, 0xB2, 0x07, 0x66, 0x22, 0x2B, 0x75, 0xE2,
318     0x4C, 0x2E, 0x3A, 0xD0, 0xC7, 0x28, 0x72, 0x36, 0x12, 0x95, 0x25, 0xEE,
319     0x15, 0xB5, 0xDD, 0x79, 0x98, 0xAA, 0x04, 0xC4, 0xA9, 0x69, 0x6C, 0xAC,
320     0xD7, 0x17, 0x20, 0x83, 0xA9, 0x7A, 0x81, 0x66, 0x4E, 0xAD, 0x2C, 0x47,
321     0x9E, 0x44, 0x4E, 0x4C, 0x06, 0x54, 0xCC, 0x19, 0xE2, 0x8D, 0x77, 0x03,
322     0xCE, 0xE8, 0xDA, 0xCD, 0x61, 0x26, 0xF5, 0xD6, 0x65, 0xEC, 0x52, 0xC6,
323     0x72, 0x55, 0xDB, 0x92, 0x01, 0x4B, 0x03, 0x7E, 0xB6, 0x21, 0xA2, 0xAC,
324     0x8E, 0x36, 0x5D, 0xE0, 0x71, 0xFF, 0xC1, 0x40, 0x0A, 0xCF, 0x07, 0x7A,
325     0x12, 0x91, 0x3D, 0xD8, 0xDE, 0x89, 0x47, 0x34, 0x37, 0xAB, 0x7B, 0xA3,
326     0x46, 0x74, 0x3C, 0x1B, 0x21, 0x5D, 0xD9, 0xC1, 0x21, 0x64, 0xA7, 0xE4,
327     0x05, 0x31, 0x18, 0xD1, 0x99, 0xBE, 0xC8, 0xEF, 0x6F, 0xC5, 0x61, 0x17,
328     0x0C, 0x84, 0xC8, 0x7D, 0x10, 0xEE, 0x9A, 0x67, 0x4A, 0x1F, 0xA8, 0xFF,
329     0xE1, 0x3B, 0xDF, 0xBA, 0x1D, 0x44, 0xDE, 0x48, 0x94, 0x6D, 0x68, 0xDC,
330     0x0C, 0xDD, 0x77, 0x76, 0x35, 0xA7, 0xAB, 0x5B, 0xFB, 0x1E, 0x4B, 0xB7,
331     0xB8, 0x56, 0xF9, 0x68, 0x27, 0x73, 0x4C, 0x18, 0x41, 0x38, 0xE9, 0x15,
332     0xD9, 0xC3, 0x00, 0x2E, 0xBC, 0xE5, 0x31, 0x20, 0x54, 0x6A, 0x7E, 0x20,
333     0x02, 0x14, 0x2B, 0x6C
334 };
335
336 static const unsigned char dhtest_2048_224_Z[] = {
337     0x34, 0xD9, 0xBD, 0xDC, 0x1B, 0x42, 0x17, 0x6C, 0x31, 0x3F, 0xEA, 0x03,
338     0x4C, 0x21, 0x03, 0x4D, 0x07, 0x4A, 0x63, 0x13, 0xBB, 0x4E, 0xCD, 0xB3,
339     0x70, 0x3F, 0xFF, 0x42, 0x45, 0x67, 0xA4, 0x6B, 0xDF, 0x75, 0x53, 0x0E,
340     0xDE, 0x0A, 0x9D, 0xA5, 0x22, 0x9D, 0xE7, 0xD7, 0x67, 0x32, 0x28, 0x6C,
341     0xBC, 0x0F, 0x91, 0xDA, 0x4C, 0x3C, 0x85, 0x2F, 0xC0, 0x99, 0xC6, 0x79,
342     0x53, 0x1D, 0x94, 0xC7, 0x8A, 0xB0, 0x3D, 0x9D, 0xEC, 0xB0, 0xA4, 0xE4,
343     0xCA, 0x8B, 0x2B, 0xB4, 0x59, 0x1C, 0x40, 0x21, 0xCF, 0x8C, 0xE3, 0xA2,
344     0x0A, 0x54, 0x1D, 0x33, 0x99, 0x40, 0x17, 0xD0, 0x20, 0x0A, 0xE2, 0xC9,
345     0x51, 0x6E, 0x2F, 0xF5, 0x14, 0x57, 0x79, 0x26, 0x9E, 0x86, 0x2B, 0x0F,
346     0xB4, 0x74, 0xA2, 0xD5, 0x6D, 0xC3, 0x1E, 0xD5, 0x69, 0xA7, 0x70, 0x0B,
347     0x4C, 0x4A, 0xB1, 0x6B, 0x22, 0xA4, 0x55, 0x13, 0x53, 0x1E, 0xF5, 0x23,
348     0xD7, 0x12, 0x12, 0x07, 0x7B, 0x5A, 0x16, 0x9B, 0xDE, 0xFF, 0xAD, 0x7A,
349     0xD9, 0x60, 0x82, 0x84, 0xC7, 0x79, 0x5B, 0x6D, 0x5A, 0x51, 0x83, 0xB8,
350     0x70, 0x66, 0xDE, 0x17, 0xD8, 0xD6, 0x71, 0xC9, 0xEB, 0xD8, 0xEC, 0x89,
351     0x54, 0x4D, 0x45, 0xEC, 0x06, 0x15, 0x93, 0xD4, 0x42, 0xC6, 0x2A, 0xB9,
352     0xCE, 0x3B, 0x1C, 0xB9, 0x94, 0x3A, 0x1D, 0x23, 0xA5, 0xEA, 0x3B, 0xCF,
353     0x21, 0xA0, 0x14, 0x71, 0xE6, 0x7E, 0x00, 0x3E, 0x7F, 0x8A, 0x69, 0xC7,
354     0x28, 0xBE, 0x49, 0x0B, 0x2F, 0xC8, 0x8C, 0xFE, 0xB9, 0x2D, 0xB6, 0xA2,
355     0x15, 0xE5, 0xD0, 0x3C, 0x17, 0xC4, 0x64, 0xC9, 0xAC, 0x1A, 0x46, 0xE2,
356     0x03, 0xE1, 0x3F, 0x95, 0x29, 0x95, 0xFB, 0x03, 0xC6, 0x9D, 0x3C, 0xC4,
357     0x7F, 0xCB, 0x51, 0x0B, 0x69, 0x98, 0xFF, 0xD3, 0xAA, 0x6D, 0xE7, 0x3C,
358     0xF9, 0xF6, 0x38, 0x69
359 };
360
361 static const unsigned char dhtest_2048_256_xA[] = {
362     0x08, 0x81, 0x38, 0x2C, 0xDB, 0x87, 0x66, 0x0C, 0x6D, 0xC1, 0x3E, 0x61,
363     0x49, 0x38, 0xD5, 0xB9, 0xC8, 0xB2, 0xF2, 0x48, 0x58, 0x1C, 0xC5, 0xE3,
364     0x1B, 0x35, 0x45, 0x43, 0x97, 0xFC, 0xE5, 0x0E
365 };
366
367 static const unsigned char dhtest_2048_256_yA[] = {
368     0x2E, 0x93, 0x80, 0xC8, 0x32, 0x3A, 0xF9, 0x75, 0x45, 0xBC, 0x49, 0x41,
369     0xDE, 0xB0, 0xEC, 0x37, 0x42, 0xC6, 0x2F, 0xE0, 0xEC, 0xE8, 0x24, 0xA6,
370     0xAB, 0xDB, 0xE6, 0x6C, 0x59, 0xBE, 0xE0, 0x24, 0x29, 0x11, 0xBF, 0xB9,
371     0x67, 0x23, 0x5C, 0xEB, 0xA3, 0x5A, 0xE1, 0x3E, 0x4E, 0xC7, 0x52, 0xBE,
372     0x63, 0x0B, 0x92, 0xDC, 0x4B, 0xDE, 0x28, 0x47, 0xA9, 0xC6, 0x2C, 0xB8,
373     0x15, 0x27, 0x45, 0x42, 0x1F, 0xB7, 0xEB, 0x60, 0xA6, 0x3C, 0x0F, 0xE9,
374     0x15, 0x9F, 0xCC, 0xE7, 0x26, 0xCE, 0x7C, 0xD8, 0x52, 0x3D, 0x74, 0x50,
375     0x66, 0x7E, 0xF8, 0x40, 0xE4, 0x91, 0x91, 0x21, 0xEB, 0x5F, 0x01, 0xC8,
376     0xC9, 0xB0, 0xD3, 0xD6, 0x48, 0xA9, 0x3B, 0xFB, 0x75, 0x68, 0x9E, 0x82,
377     0x44, 0xAC, 0x13, 0x4A, 0xF5, 0x44, 0x71, 0x1C, 0xE7, 0x9A, 0x02, 0xDC,
378     0xC3, 0x42, 0x26, 0x68, 0x47, 0x80, 0xDD, 0xDC, 0xB4, 0x98, 0x59, 0x41,
379     0x06, 0xC3, 0x7F, 0x5B, 0xC7, 0x98, 0x56, 0x48, 0x7A, 0xF5, 0xAB, 0x02,
380     0x2A, 0x2E, 0x5E, 0x42, 0xF0, 0x98, 0x97, 0xC1, 0xA8, 0x5A, 0x11, 0xEA,
381     0x02, 0x12, 0xAF, 0x04, 0xD9, 0xB4, 0xCE, 0xBC, 0x93, 0x7C, 0x3C, 0x1A,
382     0x3E, 0x15, 0xA8, 0xA0, 0x34, 0x2E, 0x33, 0x76, 0x15, 0xC8, 0x4E, 0x7F,
383     0xE3, 0xB8, 0xB9, 0xB8, 0x7F, 0xB1, 0xE7, 0x3A, 0x15, 0xAF, 0x12, 0xA3,
384     0x0D, 0x74, 0x6E, 0x06, 0xDF, 0xC3, 0x4F, 0x29, 0x0D, 0x79, 0x7C, 0xE5,
385     0x1A, 0xA1, 0x3A, 0xA7, 0x85, 0xBF, 0x66, 0x58, 0xAF, 0xF5, 0xE4, 0xB0,
386     0x93, 0x00, 0x3C, 0xBE, 0xAF, 0x66, 0x5B, 0x3C, 0x2E, 0x11, 0x3A, 0x3A,
387     0x4E, 0x90, 0x52, 0x69, 0x34, 0x1D, 0xC0, 0x71, 0x14, 0x26, 0x68, 0x5F,
388     0x4E, 0xF3, 0x7E, 0x86, 0x8A, 0x81, 0x26, 0xFF, 0x3F, 0x22, 0x79, 0xB5,
389     0x7C, 0xA6, 0x7E, 0x29
390 };
391
392 static const unsigned char dhtest_2048_256_xB[] = {
393     0x7D, 0x62, 0xA7, 0xE3, 0xEF, 0x36, 0xDE, 0x61, 0x7B, 0x13, 0xD1, 0xAF,
394     0xB8, 0x2C, 0x78, 0x0D, 0x83, 0xA2, 0x3B, 0xD4, 0xEE, 0x67, 0x05, 0x64,
395     0x51, 0x21, 0xF3, 0x71, 0xF5, 0x46, 0xA5, 0x3D
396 };
397
398 static const unsigned char dhtest_2048_256_yB[] = {
399     0x57, 0x5F, 0x03, 0x51, 0xBD, 0x2B, 0x1B, 0x81, 0x74, 0x48, 0xBD, 0xF8,
400     0x7A, 0x6C, 0x36, 0x2C, 0x1E, 0x28, 0x9D, 0x39, 0x03, 0xA3, 0x0B, 0x98,
401     0x32, 0xC5, 0x74, 0x1F, 0xA2, 0x50, 0x36, 0x3E, 0x7A, 0xCB, 0xC7, 0xF7,
402     0x7F, 0x3D, 0xAC, 0xBC, 0x1F, 0x13, 0x1A, 0xDD, 0x8E, 0x03, 0x36, 0x7E,
403     0xFF, 0x8F, 0xBB, 0xB3, 0xE1, 0xC5, 0x78, 0x44, 0x24, 0x80, 0x9B, 0x25,
404     0xAF, 0xE4, 0xD2, 0x26, 0x2A, 0x1A, 0x6F, 0xD2, 0xFA, 0xB6, 0x41, 0x05,
405     0xCA, 0x30, 0xA6, 0x74, 0xE0, 0x7F, 0x78, 0x09, 0x85, 0x20, 0x88, 0x63,
406     0x2F, 0xC0, 0x49, 0x23, 0x37, 0x91, 0xAD, 0x4E, 0xDD, 0x08, 0x3A, 0x97,
407     0x8B, 0x88, 0x3E, 0xE6, 0x18, 0xBC, 0x5E, 0x0D, 0xD0, 0x47, 0x41, 0x5F,
408     0x2D, 0x95, 0xE6, 0x83, 0xCF, 0x14, 0x82, 0x6B, 0x5F, 0xBE, 0x10, 0xD3,
409     0xCE, 0x41, 0xC6, 0xC1, 0x20, 0xC7, 0x8A, 0xB2, 0x00, 0x08, 0xC6, 0x98,
410     0xBF, 0x7F, 0x0B, 0xCA, 0xB9, 0xD7, 0xF4, 0x07, 0xBE, 0xD0, 0xF4, 0x3A,
411     0xFB, 0x29, 0x70, 0xF5, 0x7F, 0x8D, 0x12, 0x04, 0x39, 0x63, 0xE6, 0x6D,
412     0xDD, 0x32, 0x0D, 0x59, 0x9A, 0xD9, 0x93, 0x6C, 0x8F, 0x44, 0x13, 0x7C,
413     0x08, 0xB1, 0x80, 0xEC, 0x5E, 0x98, 0x5C, 0xEB, 0xE1, 0x86, 0xF3, 0xD5,
414     0x49, 0x67, 0x7E, 0x80, 0x60, 0x73, 0x31, 0xEE, 0x17, 0xAF, 0x33, 0x80,
415     0xA7, 0x25, 0xB0, 0x78, 0x23, 0x17, 0xD7, 0xDD, 0x43, 0xF5, 0x9D, 0x7A,
416     0xF9, 0x56, 0x8A, 0x9B, 0xB6, 0x3A, 0x84, 0xD3, 0x65, 0xF9, 0x22, 0x44,
417     0xED, 0x12, 0x09, 0x88, 0x21, 0x93, 0x02, 0xF4, 0x29, 0x24, 0xC7, 0xCA,
418     0x90, 0xB8, 0x9D, 0x24, 0xF7, 0x1B, 0x0A, 0xB6, 0x97, 0x82, 0x3D, 0x7D,
419     0xEB, 0x1A, 0xFF, 0x5B, 0x0E, 0x8E, 0x4A, 0x45, 0xD4, 0x9F, 0x7F, 0x53,
420     0x75, 0x7E, 0x19, 0x13
421 };
422
423 static const unsigned char dhtest_2048_256_Z[] = {
424     0x86, 0xC7, 0x0B, 0xF8, 0xD0, 0xBB, 0x81, 0xBB, 0x01, 0x07, 0x8A, 0x17,
425     0x21, 0x9C, 0xB7, 0xD2, 0x72, 0x03, 0xDB, 0x2A, 0x19, 0xC8, 0x77, 0xF1,
426     0xD1, 0xF1, 0x9F, 0xD7, 0xD7, 0x7E, 0xF2, 0x25, 0x46, 0xA6, 0x8F, 0x00,
427     0x5A, 0xD5, 0x2D, 0xC8, 0x45, 0x53, 0xB7, 0x8F, 0xC6, 0x03, 0x30, 0xBE,
428     0x51, 0xEA, 0x7C, 0x06, 0x72, 0xCA, 0xC1, 0x51, 0x5E, 0x4B, 0x35, 0xC0,
429     0x47, 0xB9, 0xA5, 0x51, 0xB8, 0x8F, 0x39, 0xDC, 0x26, 0xDA, 0x14, 0xA0,
430     0x9E, 0xF7, 0x47, 0x74, 0xD4, 0x7C, 0x76, 0x2D, 0xD1, 0x77, 0xF9, 0xED,
431     0x5B, 0xC2, 0xF1, 0x1E, 0x52, 0xC8, 0x79, 0xBD, 0x95, 0x09, 0x85, 0x04,
432     0xCD, 0x9E, 0xEC, 0xD8, 0xA8, 0xF9, 0xB3, 0xEF, 0xBD, 0x1F, 0x00, 0x8A,
433     0xC5, 0x85, 0x30, 0x97, 0xD9, 0xD1, 0x83, 0x7F, 0x2B, 0x18, 0xF7, 0x7C,
434     0xD7, 0xBE, 0x01, 0xAF, 0x80, 0xA7, 0xC7, 0xB5, 0xEA, 0x3C, 0xA5, 0x4C,
435     0xC0, 0x2D, 0x0C, 0x11, 0x6F, 0xEE, 0x3F, 0x95, 0xBB, 0x87, 0x39, 0x93,
436     0x85, 0x87, 0x5D, 0x7E, 0x86, 0x74, 0x7E, 0x67, 0x6E, 0x72, 0x89, 0x38,
437     0xAC, 0xBF, 0xF7, 0x09, 0x8E, 0x05, 0xBE, 0x4D, 0xCF, 0xB2, 0x40, 0x52,
438     0xB8, 0x3A, 0xEF, 0xFB, 0x14, 0x78, 0x3F, 0x02, 0x9A, 0xDB, 0xDE, 0x7F,
439     0x53, 0xFA, 0xE9, 0x20, 0x84, 0x22, 0x40, 0x90, 0xE0, 0x07, 0xCE, 0xE9,
440     0x4D, 0x4B, 0xF2, 0xBA, 0xCE, 0x9F, 0xFD, 0x4B, 0x57, 0xD2, 0xAF, 0x7C,
441     0x72, 0x4D, 0x0C, 0xAA, 0x19, 0xBF, 0x05, 0x01, 0xF6, 0xF1, 0x7B, 0x4A,
442     0xA1, 0x0F, 0x42, 0x5E, 0x3E, 0xA7, 0x60, 0x80, 0xB4, 0xB9, 0xD6, 0xB3,
443     0xCE, 0xFE, 0xA1, 0x15, 0xB2, 0xCE, 0xB8, 0x78, 0x9B, 0xB8, 0xA3, 0xB0,
444     0xEA, 0x87, 0xFE, 0xBE, 0x63, 0xB6, 0xC8, 0xF8, 0x46, 0xEC, 0x6D, 0xB0,
445     0xC2, 0x6C, 0x5D, 0x7C
446 };
447
448 static const unsigned char dhtest_rfc5114_2048_224_bad_y[] = {
449     0x45, 0x32, 0x5F, 0x51, 0x07, 0xE5, 0xDF, 0x1C, 0xD6, 0x02, 0x82, 0xB3,
450     0x32, 0x8F, 0xA4, 0x0F, 0x87, 0xB8, 0x41, 0xFE, 0xB9, 0x35, 0xDE, 0xAD,
451     0xC6, 0x26, 0x85, 0xB4, 0xFF, 0x94, 0x8C, 0x12, 0x4C, 0xBF, 0x5B, 0x20,
452     0xC4, 0x46, 0xA3, 0x26, 0xEB, 0xA4, 0x25, 0xB7, 0x68, 0x8E, 0xCC, 0x67,
453     0xBA, 0xEA, 0x58, 0xD0, 0xF2, 0xE9, 0xD2, 0x24, 0x72, 0x60, 0xDA, 0x88,
454     0x18, 0x9C, 0xE0, 0x31, 0x6A, 0xAD, 0x50, 0x6D, 0x94, 0x35, 0x8B, 0x83,
455     0x4A, 0x6E, 0xFA, 0x48, 0x73, 0x0F, 0x83, 0x87, 0xFF, 0x6B, 0x66, 0x1F,
456     0xA8, 0x82, 0xC6, 0x01, 0xE5, 0x80, 0xB5, 0xB0, 0x52, 0xD0, 0xE9, 0xD8,
457     0x72, 0xF9, 0x7D, 0x5B, 0x8B, 0xA5, 0x4C, 0xA5, 0x25, 0x95, 0x74, 0xE2,
458     0x7A, 0x61, 0x4E, 0xA7, 0x8F, 0x12, 0xE2, 0xD2, 0x9D, 0x8C, 0x02, 0x70,
459     0x34, 0x44, 0x32, 0xC7, 0xB2, 0xF3, 0xB9, 0xFE, 0x17, 0x2B, 0xD6, 0x1F,
460     0x8B, 0x7E, 0x4A, 0xFA, 0xA3, 0xB5, 0x3E, 0x7A, 0x81, 0x9A, 0x33, 0x66,
461     0x62, 0xA4, 0x50, 0x18, 0x3E, 0xA2, 0x5F, 0x00, 0x07, 0xD8, 0x9B, 0x22,
462     0xE4, 0xEC, 0x84, 0xD5, 0xEB, 0x5A, 0xF3, 0x2A, 0x31, 0x23, 0xD8, 0x44,
463     0x22, 0x2A, 0x8B, 0x37, 0x44, 0xCC, 0xC6, 0x87, 0x4B, 0xBE, 0x50, 0x9D,
464     0x4A, 0xC4, 0x8E, 0x45, 0xCF, 0x72, 0x4D, 0xC0, 0x89, 0xB3, 0x72, 0xED,
465     0x33, 0x2C, 0xBC, 0x7F, 0x16, 0x39, 0x3B, 0xEB, 0xD2, 0xDD, 0xA8, 0x01,
466     0x73, 0x84, 0x62, 0xB9, 0x29, 0xD2, 0xC9, 0x51, 0x32, 0x9E, 0x7A, 0x6A,
467     0xCF, 0xC1, 0x0A, 0xDB, 0x0E, 0xE0, 0x62, 0x77, 0x6F, 0x59, 0x62, 0x72,
468     0x5A, 0x69, 0xA6, 0x5B, 0x70, 0xCA, 0x65, 0xC4, 0x95, 0x6F, 0x9A, 0xC2,
469     0xDF, 0x72, 0x6D, 0xB1, 0x1E, 0x54, 0x7B, 0x51, 0xB4, 0xEF, 0x7F, 0x89,
470     0x93, 0x74, 0x89, 0x59
471 };
472
473 typedef struct {
474     DH *(*get_param) (void);
475     const unsigned char *xA;
476     size_t xA_len;
477     const unsigned char *yA;
478     size_t yA_len;
479     const unsigned char *xB;
480     size_t xB_len;
481     const unsigned char *yB;
482     size_t yB_len;
483     const unsigned char *Z;
484     size_t Z_len;
485 } rfc5114_td;
486
487 # define make_rfc5114_td(pre) { \
488         DH_get_##pre, \
489         dhtest_##pre##_xA, sizeof(dhtest_##pre##_xA), \
490         dhtest_##pre##_yA, sizeof(dhtest_##pre##_yA), \
491         dhtest_##pre##_xB, sizeof(dhtest_##pre##_xB), \
492         dhtest_##pre##_yB, sizeof(dhtest_##pre##_yB), \
493         dhtest_##pre##_Z, sizeof(dhtest_##pre##_Z) \
494         }
495
496 static const rfc5114_td rfctd[] = {
497         make_rfc5114_td(1024_160),
498         make_rfc5114_td(2048_224),
499         make_rfc5114_td(2048_256)
500 };
501
502 static int rfc5114_test(void)
503 {
504     int i;
505     DH *dhA = NULL;
506     DH *dhB = NULL;
507     unsigned char *Z1 = NULL;
508     unsigned char *Z2 = NULL;
509     const rfc5114_td *td = NULL;
510     BIGNUM *bady = NULL, *priv_key = NULL, *pub_key = NULL;
511     const BIGNUM *pub_key_tmp;
512
513     for (i = 0; i < (int)OSSL_NELEM(rfctd); i++) {
514         td = rfctd + i;
515         /* Set up DH structures setting key components */
516         if (!TEST_ptr(dhA = td->get_param())
517                 || !TEST_ptr(dhB = td->get_param()))
518             goto bad_err;
519
520         if (!TEST_ptr(priv_key = BN_bin2bn(td->xA, td->xA_len, NULL))
521                 || !TEST_ptr(pub_key = BN_bin2bn(td->yA, td->yA_len, NULL))
522                 || !TEST_true(DH_set0_key(dhA, pub_key, priv_key)))
523             goto bad_err;
524
525         if (!TEST_ptr(priv_key = BN_bin2bn(td->xB, td->xB_len, NULL))
526                 || !TEST_ptr(pub_key = BN_bin2bn(td->yB, td->yB_len, NULL))
527                 || !TEST_true( DH_set0_key(dhB, pub_key, priv_key)))
528             goto bad_err;
529         priv_key = pub_key = NULL;
530
531         if (!TEST_uint_eq(td->Z_len, (size_t)DH_size(dhA))
532             || !TEST_uint_eq(td->Z_len, (size_t)DH_size(dhB)))
533             goto err;
534
535         if (!TEST_ptr(Z1 = OPENSSL_malloc(DH_size(dhA)))
536                 || !TEST_ptr(Z2 = OPENSSL_malloc(DH_size(dhB))))
537             goto bad_err;
538         /*
539          * Work out shared secrets using both sides and compare with expected
540          * values.
541          */
542         DH_get0_key(dhB, &pub_key_tmp, NULL);
543         if (!TEST_int_ne(DH_compute_key(Z1, pub_key_tmp, dhA), -1))
544             goto bad_err;
545
546         DH_get0_key(dhA, &pub_key_tmp, NULL);
547         if (!TEST_int_ne(DH_compute_key(Z2, pub_key_tmp, dhB), -1))
548             goto bad_err;
549
550         if (!TEST_mem_eq(Z1, td->Z_len, td->Z, td->Z_len)
551                 || !TEST_mem_eq(Z2, td->Z_len, td->Z, td->Z_len))
552             goto err;
553
554         DH_free(dhA);
555         dhA = NULL;
556         DH_free(dhB);
557         dhB = NULL;
558         OPENSSL_free(Z1);
559         Z1 = NULL;
560         OPENSSL_free(Z2);
561         Z2 = NULL;
562     }
563
564     /* Now i == OSSL_NELEM(rfctd) */
565     /* RFC5114 uses unsafe primes, so now test an invalid y value */
566     if (!TEST_ptr(dhA = DH_get_2048_224())
567             || !TEST_ptr(Z1 = OPENSSL_malloc(DH_size(dhA))))
568         goto bad_err;
569
570     if (!TEST_ptr(bady = BN_bin2bn(dhtest_rfc5114_2048_224_bad_y,
571                                    sizeof(dhtest_rfc5114_2048_224_bad_y),
572                                    NULL)))
573         goto bad_err;
574
575     if (!DH_generate_key(dhA))
576         goto bad_err;
577
578     if (DH_compute_key(Z1, bady, dhA) != -1) {
579         /*
580          * DH_compute_key should fail with -1. If we get here we unexpectedly
581          * allowed an invalid y value
582          */
583         goto err;
584     }
585     /* We'll have a stale error on the queue from the above test so clear it */
586     ERR_clear_error();
587     BN_free(bady);
588     DH_free(dhA);
589     OPENSSL_free(Z1);
590     return 1;
591
592  bad_err:
593     BN_free(bady);
594     DH_free(dhA);
595     DH_free(dhB);
596     BN_free(pub_key);
597     BN_free(priv_key);
598     OPENSSL_free(Z1);
599     OPENSSL_free(Z2);
600     TEST_error("Initialisation error RFC5114 set %d\n", i + 1);
601     return 0;
602
603  err:
604     BN_free(bady);
605     DH_free(dhA);
606     DH_free(dhB);
607     OPENSSL_free(Z1);
608     OPENSSL_free(Z2);
609     TEST_error("Test failed RFC5114 set %d\n", i + 1);
610     return 0;
611 }
612 #endif
613
614
615 int setup_tests(void)
616 {
617 #ifdef OPENSSL_NO_DH
618     TEST_note("No DH support");
619 #else
620     ADD_TEST(dh_test);
621     ADD_TEST(rfc5114_test);
622 #endif
623     return 1;
624 }