add 'unsupported cipher mode' diagnostics to evp_lib.c and genpkey.c
[openssl.git] / test / dhtest.c
1 /*
2  * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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;
30     BIGNUM *p, *q, *g;
31     const BIGNUM *p2, *q2, *g2;
32     BIGNUM *priv_key;
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 err;
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 err;
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 err;
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 err;
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 err;
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 err;
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 err;
93
94     /* now generate a key pair ... */
95     if (!DH_generate_key(dh))
96         goto err;
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 err;
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 err;
110
111     /* check whether the public key was calculated correclty */
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 err;
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 err;
126
127     /* ... and check whether it is valid */
128     if (!DH_check(a, &i))
129         goto err;
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 err;
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 err;
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 err;
146     bp = bg = NULL;
147
148     /*
149      * III) simulate a key exchange
150      */
151
152     if (!DH_generate_key(a))
153         goto err;
154     DH_get0_key(a, &apub_key, NULL);
155
156     if (!DH_generate_key(b))
157         goto err;
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 err;
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 err;
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 err;
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 err;
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 err;
186
187     ret = 1;
188
189  err:
190     OPENSSL_free(abuf);
191     OPENSSL_free(bbuf);
192     OPENSSL_free(cbuf);
193     DH_free(b);
194     DH_free(a);
195     DH_free(c);
196     BN_free(bp);
197     BN_free(bg);
198     BN_free(cpriv_key);
199     BN_GENCB_free(_cb);
200     DH_free(dh);
201
202     return ret;
203 }
204
205 static int cb(int p, int n, BN_GENCB *arg)
206 {
207     return 1;
208 }
209
210 /* Test data from RFC 5114 */
211
212 static const unsigned char dhtest_1024_160_xA[] = {
213     0xB9, 0xA3, 0xB3, 0xAE, 0x8F, 0xEF, 0xC1, 0xA2, 0x93, 0x04, 0x96, 0x50,
214     0x70, 0x86, 0xF8, 0x45, 0x5D, 0x48, 0x94, 0x3E
215 };
216
217 static const unsigned char dhtest_1024_160_yA[] = {
218     0x2A, 0x85, 0x3B, 0x3D, 0x92, 0x19, 0x75, 0x01, 0xB9, 0x01, 0x5B, 0x2D,
219     0xEB, 0x3E, 0xD8, 0x4F, 0x5E, 0x02, 0x1D, 0xCC, 0x3E, 0x52, 0xF1, 0x09,
220     0xD3, 0x27, 0x3D, 0x2B, 0x75, 0x21, 0x28, 0x1C, 0xBA, 0xBE, 0x0E, 0x76,
221     0xFF, 0x57, 0x27, 0xFA, 0x8A, 0xCC, 0xE2, 0x69, 0x56, 0xBA, 0x9A, 0x1F,
222     0xCA, 0x26, 0xF2, 0x02, 0x28, 0xD8, 0x69, 0x3F, 0xEB, 0x10, 0x84, 0x1D,
223     0x84, 0xA7, 0x36, 0x00, 0x54, 0xEC, 0xE5, 0xA7, 0xF5, 0xB7, 0xA6, 0x1A,
224     0xD3, 0xDF, 0xB3, 0xC6, 0x0D, 0x2E, 0x43, 0x10, 0x6D, 0x87, 0x27, 0xDA,
225     0x37, 0xDF, 0x9C, 0xCE, 0x95, 0xB4, 0x78, 0x75, 0x5D, 0x06, 0xBC, 0xEA,
226     0x8F, 0x9D, 0x45, 0x96, 0x5F, 0x75, 0xA5, 0xF3, 0xD1, 0xDF, 0x37, 0x01,
227     0x16, 0x5F, 0xC9, 0xE5, 0x0C, 0x42, 0x79, 0xCE, 0xB0, 0x7F, 0x98, 0x95,
228     0x40, 0xAE, 0x96, 0xD5, 0xD8, 0x8E, 0xD7, 0x76
229 };
230
231 static const unsigned char dhtest_1024_160_xB[] = {
232     0x93, 0x92, 0xC9, 0xF9, 0xEB, 0x6A, 0x7A, 0x6A, 0x90, 0x22, 0xF7, 0xD8,
233     0x3E, 0x72, 0x23, 0xC6, 0x83, 0x5B, 0xBD, 0xDA
234 };
235
236 static const unsigned char dhtest_1024_160_yB[] = {
237     0x71, 0x7A, 0x6C, 0xB0, 0x53, 0x37, 0x1F, 0xF4, 0xA3, 0xB9, 0x32, 0x94,
238     0x1C, 0x1E, 0x56, 0x63, 0xF8, 0x61, 0xA1, 0xD6, 0xAD, 0x34, 0xAE, 0x66,
239     0x57, 0x6D, 0xFB, 0x98, 0xF6, 0xC6, 0xCB, 0xF9, 0xDD, 0xD5, 0xA5, 0x6C,
240     0x78, 0x33, 0xF6, 0xBC, 0xFD, 0xFF, 0x09, 0x55, 0x82, 0xAD, 0x86, 0x8E,
241     0x44, 0x0E, 0x8D, 0x09, 0xFD, 0x76, 0x9E, 0x3C, 0xEC, 0xCD, 0xC3, 0xD3,
242     0xB1, 0xE4, 0xCF, 0xA0, 0x57, 0x77, 0x6C, 0xAA, 0xF9, 0x73, 0x9B, 0x6A,
243     0x9F, 0xEE, 0x8E, 0x74, 0x11, 0xF8, 0xD6, 0xDA, 0xC0, 0x9D, 0x6A, 0x4E,
244     0xDB, 0x46, 0xCC, 0x2B, 0x5D, 0x52, 0x03, 0x09, 0x0E, 0xAE, 0x61, 0x26,
245     0x31, 0x1E, 0x53, 0xFD, 0x2C, 0x14, 0xB5, 0x74, 0xE6, 0xA3, 0x10, 0x9A,
246     0x3D, 0xA1, 0xBE, 0x41, 0xBD, 0xCE, 0xAA, 0x18, 0x6F, 0x5C, 0xE0, 0x67,
247     0x16, 0xA2, 0xB6, 0xA0, 0x7B, 0x3C, 0x33, 0xFE
248 };
249
250 static const unsigned char dhtest_1024_160_Z[] = {
251     0x5C, 0x80, 0x4F, 0x45, 0x4D, 0x30, 0xD9, 0xC4, 0xDF, 0x85, 0x27, 0x1F,
252     0x93, 0x52, 0x8C, 0x91, 0xDF, 0x6B, 0x48, 0xAB, 0x5F, 0x80, 0xB3, 0xB5,
253     0x9C, 0xAA, 0xC1, 0xB2, 0x8F, 0x8A, 0xCB, 0xA9, 0xCD, 0x3E, 0x39, 0xF3,
254     0xCB, 0x61, 0x45, 0x25, 0xD9, 0x52, 0x1D, 0x2E, 0x64, 0x4C, 0x53, 0xB8,
255     0x07, 0xB8, 0x10, 0xF3, 0x40, 0x06, 0x2F, 0x25, 0x7D, 0x7D, 0x6F, 0xBF,
256     0xE8, 0xD5, 0xE8, 0xF0, 0x72, 0xE9, 0xB6, 0xE9, 0xAF, 0xDA, 0x94, 0x13,
257     0xEA, 0xFB, 0x2E, 0x8B, 0x06, 0x99, 0xB1, 0xFB, 0x5A, 0x0C, 0xAC, 0xED,
258     0xDE, 0xAE, 0xAD, 0x7E, 0x9C, 0xFB, 0xB3, 0x6A, 0xE2, 0xB4, 0x20, 0x83,
259     0x5B, 0xD8, 0x3A, 0x19, 0xFB, 0x0B, 0x5E, 0x96, 0xBF, 0x8F, 0xA4, 0xD0,
260     0x9E, 0x34, 0x55, 0x25, 0x16, 0x7E, 0xCD, 0x91, 0x55, 0x41, 0x6F, 0x46,
261     0xF4, 0x08, 0xED, 0x31, 0xB6, 0x3C, 0x6E, 0x6D
262 };
263
264 static const unsigned char dhtest_2048_224_xA[] = {
265     0x22, 0xE6, 0x26, 0x01, 0xDB, 0xFF, 0xD0, 0x67, 0x08, 0xA6, 0x80, 0xF7,
266     0x47, 0xF3, 0x61, 0xF7, 0x6D, 0x8F, 0x4F, 0x72, 0x1A, 0x05, 0x48, 0xE4,
267     0x83, 0x29, 0x4B, 0x0C
268 };
269
270 static const unsigned char dhtest_2048_224_yA[] = {
271     0x1B, 0x3A, 0x63, 0x45, 0x1B, 0xD8, 0x86, 0xE6, 0x99, 0xE6, 0x7B, 0x49,
272     0x4E, 0x28, 0x8B, 0xD7, 0xF8, 0xE0, 0xD3, 0x70, 0xBA, 0xDD, 0xA7, 0xA0,
273     0xEF, 0xD2, 0xFD, 0xE7, 0xD8, 0xF6, 0x61, 0x45, 0xCC, 0x9F, 0x28, 0x04,
274     0x19, 0x97, 0x5E, 0xB8, 0x08, 0x87, 0x7C, 0x8A, 0x4C, 0x0C, 0x8E, 0x0B,
275     0xD4, 0x8D, 0x4A, 0x54, 0x01, 0xEB, 0x1E, 0x87, 0x76, 0xBF, 0xEE, 0xE1,
276     0x34, 0xC0, 0x38, 0x31, 0xAC, 0x27, 0x3C, 0xD9, 0xD6, 0x35, 0xAB, 0x0C,
277     0xE0, 0x06, 0xA4, 0x2A, 0x88, 0x7E, 0x3F, 0x52, 0xFB, 0x87, 0x66, 0xB6,
278     0x50, 0xF3, 0x80, 0x78, 0xBC, 0x8E, 0xE8, 0x58, 0x0C, 0xEF, 0xE2, 0x43,
279     0x96, 0x8C, 0xFC, 0x4F, 0x8D, 0xC3, 0xDB, 0x08, 0x45, 0x54, 0x17, 0x1D,
280     0x41, 0xBF, 0x2E, 0x86, 0x1B, 0x7B, 0xB4, 0xD6, 0x9D, 0xD0, 0xE0, 0x1E,
281     0xA3, 0x87, 0xCB, 0xAA, 0x5C, 0xA6, 0x72, 0xAF, 0xCB, 0xE8, 0xBD, 0xB9,
282     0xD6, 0x2D, 0x4C, 0xE1, 0x5F, 0x17, 0xDD, 0x36, 0xF9, 0x1E, 0xD1, 0xEE,
283     0xDD, 0x65, 0xCA, 0x4A, 0x06, 0x45, 0x5C, 0xB9, 0x4C, 0xD4, 0x0A, 0x52,
284     0xEC, 0x36, 0x0E, 0x84, 0xB3, 0xC9, 0x26, 0xE2, 0x2C, 0x43, 0x80, 0xA3,
285     0xBF, 0x30, 0x9D, 0x56, 0x84, 0x97, 0x68, 0xB7, 0xF5, 0x2C, 0xFD, 0xF6,
286     0x55, 0xFD, 0x05, 0x3A, 0x7E, 0xF7, 0x06, 0x97, 0x9E, 0x7E, 0x58, 0x06,
287     0xB1, 0x7D, 0xFA, 0xE5, 0x3A, 0xD2, 0xA5, 0xBC, 0x56, 0x8E, 0xBB, 0x52,
288     0x9A, 0x7A, 0x61, 0xD6, 0x8D, 0x25, 0x6F, 0x8F, 0xC9, 0x7C, 0x07, 0x4A,
289     0x86, 0x1D, 0x82, 0x7E, 0x2E, 0xBC, 0x8C, 0x61, 0x34, 0x55, 0x31, 0x15,
290     0xB7, 0x0E, 0x71, 0x03, 0x92, 0x0A, 0xA1, 0x6D, 0x85, 0xE5, 0x2B, 0xCB,
291     0xAB, 0x8D, 0x78, 0x6A, 0x68, 0x17, 0x8F, 0xA8, 0xFF, 0x7C, 0x2F, 0x5C,
292     0x71, 0x64, 0x8D, 0x6F
293 };
294
295 static const unsigned char dhtest_2048_224_xB[] = {
296     0x4F, 0xF3, 0xBC, 0x96, 0xC7, 0xFC, 0x6A, 0x6D, 0x71, 0xD3, 0xB3, 0x63,
297     0x80, 0x0A, 0x7C, 0xDF, 0xEF, 0x6F, 0xC4, 0x1B, 0x44, 0x17, 0xEA, 0x15,
298     0x35, 0x3B, 0x75, 0x90
299 };
300
301 static const unsigned char dhtest_2048_224_yB[] = {
302     0x4D, 0xCE, 0xE9, 0x92, 0xA9, 0x76, 0x2A, 0x13, 0xF2, 0xF8, 0x38, 0x44,
303     0xAD, 0x3D, 0x77, 0xEE, 0x0E, 0x31, 0xC9, 0x71, 0x8B, 0x3D, 0xB6, 0xC2,
304     0x03, 0x5D, 0x39, 0x61, 0x18, 0x2C, 0x3E, 0x0B, 0xA2, 0x47, 0xEC, 0x41,
305     0x82, 0xD7, 0x60, 0xCD, 0x48, 0xD9, 0x95, 0x99, 0x97, 0x06, 0x22, 0xA1,
306     0x88, 0x1B, 0xBA, 0x2D, 0xC8, 0x22, 0x93, 0x9C, 0x78, 0xC3, 0x91, 0x2C,
307     0x66, 0x61, 0xFA, 0x54, 0x38, 0xB2, 0x07, 0x66, 0x22, 0x2B, 0x75, 0xE2,
308     0x4C, 0x2E, 0x3A, 0xD0, 0xC7, 0x28, 0x72, 0x36, 0x12, 0x95, 0x25, 0xEE,
309     0x15, 0xB5, 0xDD, 0x79, 0x98, 0xAA, 0x04, 0xC4, 0xA9, 0x69, 0x6C, 0xAC,
310     0xD7, 0x17, 0x20, 0x83, 0xA9, 0x7A, 0x81, 0x66, 0x4E, 0xAD, 0x2C, 0x47,
311     0x9E, 0x44, 0x4E, 0x4C, 0x06, 0x54, 0xCC, 0x19, 0xE2, 0x8D, 0x77, 0x03,
312     0xCE, 0xE8, 0xDA, 0xCD, 0x61, 0x26, 0xF5, 0xD6, 0x65, 0xEC, 0x52, 0xC6,
313     0x72, 0x55, 0xDB, 0x92, 0x01, 0x4B, 0x03, 0x7E, 0xB6, 0x21, 0xA2, 0xAC,
314     0x8E, 0x36, 0x5D, 0xE0, 0x71, 0xFF, 0xC1, 0x40, 0x0A, 0xCF, 0x07, 0x7A,
315     0x12, 0x91, 0x3D, 0xD8, 0xDE, 0x89, 0x47, 0x34, 0x37, 0xAB, 0x7B, 0xA3,
316     0x46, 0x74, 0x3C, 0x1B, 0x21, 0x5D, 0xD9, 0xC1, 0x21, 0x64, 0xA7, 0xE4,
317     0x05, 0x31, 0x18, 0xD1, 0x99, 0xBE, 0xC8, 0xEF, 0x6F, 0xC5, 0x61, 0x17,
318     0x0C, 0x84, 0xC8, 0x7D, 0x10, 0xEE, 0x9A, 0x67, 0x4A, 0x1F, 0xA8, 0xFF,
319     0xE1, 0x3B, 0xDF, 0xBA, 0x1D, 0x44, 0xDE, 0x48, 0x94, 0x6D, 0x68, 0xDC,
320     0x0C, 0xDD, 0x77, 0x76, 0x35, 0xA7, 0xAB, 0x5B, 0xFB, 0x1E, 0x4B, 0xB7,
321     0xB8, 0x56, 0xF9, 0x68, 0x27, 0x73, 0x4C, 0x18, 0x41, 0x38, 0xE9, 0x15,
322     0xD9, 0xC3, 0x00, 0x2E, 0xBC, 0xE5, 0x31, 0x20, 0x54, 0x6A, 0x7E, 0x20,
323     0x02, 0x14, 0x2B, 0x6C
324 };
325
326 static const unsigned char dhtest_2048_224_Z[] = {
327     0x34, 0xD9, 0xBD, 0xDC, 0x1B, 0x42, 0x17, 0x6C, 0x31, 0x3F, 0xEA, 0x03,
328     0x4C, 0x21, 0x03, 0x4D, 0x07, 0x4A, 0x63, 0x13, 0xBB, 0x4E, 0xCD, 0xB3,
329     0x70, 0x3F, 0xFF, 0x42, 0x45, 0x67, 0xA4, 0x6B, 0xDF, 0x75, 0x53, 0x0E,
330     0xDE, 0x0A, 0x9D, 0xA5, 0x22, 0x9D, 0xE7, 0xD7, 0x67, 0x32, 0x28, 0x6C,
331     0xBC, 0x0F, 0x91, 0xDA, 0x4C, 0x3C, 0x85, 0x2F, 0xC0, 0x99, 0xC6, 0x79,
332     0x53, 0x1D, 0x94, 0xC7, 0x8A, 0xB0, 0x3D, 0x9D, 0xEC, 0xB0, 0xA4, 0xE4,
333     0xCA, 0x8B, 0x2B, 0xB4, 0x59, 0x1C, 0x40, 0x21, 0xCF, 0x8C, 0xE3, 0xA2,
334     0x0A, 0x54, 0x1D, 0x33, 0x99, 0x40, 0x17, 0xD0, 0x20, 0x0A, 0xE2, 0xC9,
335     0x51, 0x6E, 0x2F, 0xF5, 0x14, 0x57, 0x79, 0x26, 0x9E, 0x86, 0x2B, 0x0F,
336     0xB4, 0x74, 0xA2, 0xD5, 0x6D, 0xC3, 0x1E, 0xD5, 0x69, 0xA7, 0x70, 0x0B,
337     0x4C, 0x4A, 0xB1, 0x6B, 0x22, 0xA4, 0x55, 0x13, 0x53, 0x1E, 0xF5, 0x23,
338     0xD7, 0x12, 0x12, 0x07, 0x7B, 0x5A, 0x16, 0x9B, 0xDE, 0xFF, 0xAD, 0x7A,
339     0xD9, 0x60, 0x82, 0x84, 0xC7, 0x79, 0x5B, 0x6D, 0x5A, 0x51, 0x83, 0xB8,
340     0x70, 0x66, 0xDE, 0x17, 0xD8, 0xD6, 0x71, 0xC9, 0xEB, 0xD8, 0xEC, 0x89,
341     0x54, 0x4D, 0x45, 0xEC, 0x06, 0x15, 0x93, 0xD4, 0x42, 0xC6, 0x2A, 0xB9,
342     0xCE, 0x3B, 0x1C, 0xB9, 0x94, 0x3A, 0x1D, 0x23, 0xA5, 0xEA, 0x3B, 0xCF,
343     0x21, 0xA0, 0x14, 0x71, 0xE6, 0x7E, 0x00, 0x3E, 0x7F, 0x8A, 0x69, 0xC7,
344     0x28, 0xBE, 0x49, 0x0B, 0x2F, 0xC8, 0x8C, 0xFE, 0xB9, 0x2D, 0xB6, 0xA2,
345     0x15, 0xE5, 0xD0, 0x3C, 0x17, 0xC4, 0x64, 0xC9, 0xAC, 0x1A, 0x46, 0xE2,
346     0x03, 0xE1, 0x3F, 0x95, 0x29, 0x95, 0xFB, 0x03, 0xC6, 0x9D, 0x3C, 0xC4,
347     0x7F, 0xCB, 0x51, 0x0B, 0x69, 0x98, 0xFF, 0xD3, 0xAA, 0x6D, 0xE7, 0x3C,
348     0xF9, 0xF6, 0x38, 0x69
349 };
350
351 static const unsigned char dhtest_2048_256_xA[] = {
352     0x08, 0x81, 0x38, 0x2C, 0xDB, 0x87, 0x66, 0x0C, 0x6D, 0xC1, 0x3E, 0x61,
353     0x49, 0x38, 0xD5, 0xB9, 0xC8, 0xB2, 0xF2, 0x48, 0x58, 0x1C, 0xC5, 0xE3,
354     0x1B, 0x35, 0x45, 0x43, 0x97, 0xFC, 0xE5, 0x0E
355 };
356
357 static const unsigned char dhtest_2048_256_yA[] = {
358     0x2E, 0x93, 0x80, 0xC8, 0x32, 0x3A, 0xF9, 0x75, 0x45, 0xBC, 0x49, 0x41,
359     0xDE, 0xB0, 0xEC, 0x37, 0x42, 0xC6, 0x2F, 0xE0, 0xEC, 0xE8, 0x24, 0xA6,
360     0xAB, 0xDB, 0xE6, 0x6C, 0x59, 0xBE, 0xE0, 0x24, 0x29, 0x11, 0xBF, 0xB9,
361     0x67, 0x23, 0x5C, 0xEB, 0xA3, 0x5A, 0xE1, 0x3E, 0x4E, 0xC7, 0x52, 0xBE,
362     0x63, 0x0B, 0x92, 0xDC, 0x4B, 0xDE, 0x28, 0x47, 0xA9, 0xC6, 0x2C, 0xB8,
363     0x15, 0x27, 0x45, 0x42, 0x1F, 0xB7, 0xEB, 0x60, 0xA6, 0x3C, 0x0F, 0xE9,
364     0x15, 0x9F, 0xCC, 0xE7, 0x26, 0xCE, 0x7C, 0xD8, 0x52, 0x3D, 0x74, 0x50,
365     0x66, 0x7E, 0xF8, 0x40, 0xE4, 0x91, 0x91, 0x21, 0xEB, 0x5F, 0x01, 0xC8,
366     0xC9, 0xB0, 0xD3, 0xD6, 0x48, 0xA9, 0x3B, 0xFB, 0x75, 0x68, 0x9E, 0x82,
367     0x44, 0xAC, 0x13, 0x4A, 0xF5, 0x44, 0x71, 0x1C, 0xE7, 0x9A, 0x02, 0xDC,
368     0xC3, 0x42, 0x26, 0x68, 0x47, 0x80, 0xDD, 0xDC, 0xB4, 0x98, 0x59, 0x41,
369     0x06, 0xC3, 0x7F, 0x5B, 0xC7, 0x98, 0x56, 0x48, 0x7A, 0xF5, 0xAB, 0x02,
370     0x2A, 0x2E, 0x5E, 0x42, 0xF0, 0x98, 0x97, 0xC1, 0xA8, 0x5A, 0x11, 0xEA,
371     0x02, 0x12, 0xAF, 0x04, 0xD9, 0xB4, 0xCE, 0xBC, 0x93, 0x7C, 0x3C, 0x1A,
372     0x3E, 0x15, 0xA8, 0xA0, 0x34, 0x2E, 0x33, 0x76, 0x15, 0xC8, 0x4E, 0x7F,
373     0xE3, 0xB8, 0xB9, 0xB8, 0x7F, 0xB1, 0xE7, 0x3A, 0x15, 0xAF, 0x12, 0xA3,
374     0x0D, 0x74, 0x6E, 0x06, 0xDF, 0xC3, 0x4F, 0x29, 0x0D, 0x79, 0x7C, 0xE5,
375     0x1A, 0xA1, 0x3A, 0xA7, 0x85, 0xBF, 0x66, 0x58, 0xAF, 0xF5, 0xE4, 0xB0,
376     0x93, 0x00, 0x3C, 0xBE, 0xAF, 0x66, 0x5B, 0x3C, 0x2E, 0x11, 0x3A, 0x3A,
377     0x4E, 0x90, 0x52, 0x69, 0x34, 0x1D, 0xC0, 0x71, 0x14, 0x26, 0x68, 0x5F,
378     0x4E, 0xF3, 0x7E, 0x86, 0x8A, 0x81, 0x26, 0xFF, 0x3F, 0x22, 0x79, 0xB5,
379     0x7C, 0xA6, 0x7E, 0x29
380 };
381
382 static const unsigned char dhtest_2048_256_xB[] = {
383     0x7D, 0x62, 0xA7, 0xE3, 0xEF, 0x36, 0xDE, 0x61, 0x7B, 0x13, 0xD1, 0xAF,
384     0xB8, 0x2C, 0x78, 0x0D, 0x83, 0xA2, 0x3B, 0xD4, 0xEE, 0x67, 0x05, 0x64,
385     0x51, 0x21, 0xF3, 0x71, 0xF5, 0x46, 0xA5, 0x3D
386 };
387
388 static const unsigned char dhtest_2048_256_yB[] = {
389     0x57, 0x5F, 0x03, 0x51, 0xBD, 0x2B, 0x1B, 0x81, 0x74, 0x48, 0xBD, 0xF8,
390     0x7A, 0x6C, 0x36, 0x2C, 0x1E, 0x28, 0x9D, 0x39, 0x03, 0xA3, 0x0B, 0x98,
391     0x32, 0xC5, 0x74, 0x1F, 0xA2, 0x50, 0x36, 0x3E, 0x7A, 0xCB, 0xC7, 0xF7,
392     0x7F, 0x3D, 0xAC, 0xBC, 0x1F, 0x13, 0x1A, 0xDD, 0x8E, 0x03, 0x36, 0x7E,
393     0xFF, 0x8F, 0xBB, 0xB3, 0xE1, 0xC5, 0x78, 0x44, 0x24, 0x80, 0x9B, 0x25,
394     0xAF, 0xE4, 0xD2, 0x26, 0x2A, 0x1A, 0x6F, 0xD2, 0xFA, 0xB6, 0x41, 0x05,
395     0xCA, 0x30, 0xA6, 0x74, 0xE0, 0x7F, 0x78, 0x09, 0x85, 0x20, 0x88, 0x63,
396     0x2F, 0xC0, 0x49, 0x23, 0x37, 0x91, 0xAD, 0x4E, 0xDD, 0x08, 0x3A, 0x97,
397     0x8B, 0x88, 0x3E, 0xE6, 0x18, 0xBC, 0x5E, 0x0D, 0xD0, 0x47, 0x41, 0x5F,
398     0x2D, 0x95, 0xE6, 0x83, 0xCF, 0x14, 0x82, 0x6B, 0x5F, 0xBE, 0x10, 0xD3,
399     0xCE, 0x41, 0xC6, 0xC1, 0x20, 0xC7, 0x8A, 0xB2, 0x00, 0x08, 0xC6, 0x98,
400     0xBF, 0x7F, 0x0B, 0xCA, 0xB9, 0xD7, 0xF4, 0x07, 0xBE, 0xD0, 0xF4, 0x3A,
401     0xFB, 0x29, 0x70, 0xF5, 0x7F, 0x8D, 0x12, 0x04, 0x39, 0x63, 0xE6, 0x6D,
402     0xDD, 0x32, 0x0D, 0x59, 0x9A, 0xD9, 0x93, 0x6C, 0x8F, 0x44, 0x13, 0x7C,
403     0x08, 0xB1, 0x80, 0xEC, 0x5E, 0x98, 0x5C, 0xEB, 0xE1, 0x86, 0xF3, 0xD5,
404     0x49, 0x67, 0x7E, 0x80, 0x60, 0x73, 0x31, 0xEE, 0x17, 0xAF, 0x33, 0x80,
405     0xA7, 0x25, 0xB0, 0x78, 0x23, 0x17, 0xD7, 0xDD, 0x43, 0xF5, 0x9D, 0x7A,
406     0xF9, 0x56, 0x8A, 0x9B, 0xB6, 0x3A, 0x84, 0xD3, 0x65, 0xF9, 0x22, 0x44,
407     0xED, 0x12, 0x09, 0x88, 0x21, 0x93, 0x02, 0xF4, 0x29, 0x24, 0xC7, 0xCA,
408     0x90, 0xB8, 0x9D, 0x24, 0xF7, 0x1B, 0x0A, 0xB6, 0x97, 0x82, 0x3D, 0x7D,
409     0xEB, 0x1A, 0xFF, 0x5B, 0x0E, 0x8E, 0x4A, 0x45, 0xD4, 0x9F, 0x7F, 0x53,
410     0x75, 0x7E, 0x19, 0x13
411 };
412
413 static const unsigned char dhtest_2048_256_Z[] = {
414     0x86, 0xC7, 0x0B, 0xF8, 0xD0, 0xBB, 0x81, 0xBB, 0x01, 0x07, 0x8A, 0x17,
415     0x21, 0x9C, 0xB7, 0xD2, 0x72, 0x03, 0xDB, 0x2A, 0x19, 0xC8, 0x77, 0xF1,
416     0xD1, 0xF1, 0x9F, 0xD7, 0xD7, 0x7E, 0xF2, 0x25, 0x46, 0xA6, 0x8F, 0x00,
417     0x5A, 0xD5, 0x2D, 0xC8, 0x45, 0x53, 0xB7, 0x8F, 0xC6, 0x03, 0x30, 0xBE,
418     0x51, 0xEA, 0x7C, 0x06, 0x72, 0xCA, 0xC1, 0x51, 0x5E, 0x4B, 0x35, 0xC0,
419     0x47, 0xB9, 0xA5, 0x51, 0xB8, 0x8F, 0x39, 0xDC, 0x26, 0xDA, 0x14, 0xA0,
420     0x9E, 0xF7, 0x47, 0x74, 0xD4, 0x7C, 0x76, 0x2D, 0xD1, 0x77, 0xF9, 0xED,
421     0x5B, 0xC2, 0xF1, 0x1E, 0x52, 0xC8, 0x79, 0xBD, 0x95, 0x09, 0x85, 0x04,
422     0xCD, 0x9E, 0xEC, 0xD8, 0xA8, 0xF9, 0xB3, 0xEF, 0xBD, 0x1F, 0x00, 0x8A,
423     0xC5, 0x85, 0x30, 0x97, 0xD9, 0xD1, 0x83, 0x7F, 0x2B, 0x18, 0xF7, 0x7C,
424     0xD7, 0xBE, 0x01, 0xAF, 0x80, 0xA7, 0xC7, 0xB5, 0xEA, 0x3C, 0xA5, 0x4C,
425     0xC0, 0x2D, 0x0C, 0x11, 0x6F, 0xEE, 0x3F, 0x95, 0xBB, 0x87, 0x39, 0x93,
426     0x85, 0x87, 0x5D, 0x7E, 0x86, 0x74, 0x7E, 0x67, 0x6E, 0x72, 0x89, 0x38,
427     0xAC, 0xBF, 0xF7, 0x09, 0x8E, 0x05, 0xBE, 0x4D, 0xCF, 0xB2, 0x40, 0x52,
428     0xB8, 0x3A, 0xEF, 0xFB, 0x14, 0x78, 0x3F, 0x02, 0x9A, 0xDB, 0xDE, 0x7F,
429     0x53, 0xFA, 0xE9, 0x20, 0x84, 0x22, 0x40, 0x90, 0xE0, 0x07, 0xCE, 0xE9,
430     0x4D, 0x4B, 0xF2, 0xBA, 0xCE, 0x9F, 0xFD, 0x4B, 0x57, 0xD2, 0xAF, 0x7C,
431     0x72, 0x4D, 0x0C, 0xAA, 0x19, 0xBF, 0x05, 0x01, 0xF6, 0xF1, 0x7B, 0x4A,
432     0xA1, 0x0F, 0x42, 0x5E, 0x3E, 0xA7, 0x60, 0x80, 0xB4, 0xB9, 0xD6, 0xB3,
433     0xCE, 0xFE, 0xA1, 0x15, 0xB2, 0xCE, 0xB8, 0x78, 0x9B, 0xB8, 0xA3, 0xB0,
434     0xEA, 0x87, 0xFE, 0xBE, 0x63, 0xB6, 0xC8, 0xF8, 0x46, 0xEC, 0x6D, 0xB0,
435     0xC2, 0x6C, 0x5D, 0x7C
436 };
437
438 static const unsigned char dhtest_rfc5114_2048_224_bad_y[] = {
439     0x45, 0x32, 0x5F, 0x51, 0x07, 0xE5, 0xDF, 0x1C, 0xD6, 0x02, 0x82, 0xB3,
440     0x32, 0x8F, 0xA4, 0x0F, 0x87, 0xB8, 0x41, 0xFE, 0xB9, 0x35, 0xDE, 0xAD,
441     0xC6, 0x26, 0x85, 0xB4, 0xFF, 0x94, 0x8C, 0x12, 0x4C, 0xBF, 0x5B, 0x20,
442     0xC4, 0x46, 0xA3, 0x26, 0xEB, 0xA4, 0x25, 0xB7, 0x68, 0x8E, 0xCC, 0x67,
443     0xBA, 0xEA, 0x58, 0xD0, 0xF2, 0xE9, 0xD2, 0x24, 0x72, 0x60, 0xDA, 0x88,
444     0x18, 0x9C, 0xE0, 0x31, 0x6A, 0xAD, 0x50, 0x6D, 0x94, 0x35, 0x8B, 0x83,
445     0x4A, 0x6E, 0xFA, 0x48, 0x73, 0x0F, 0x83, 0x87, 0xFF, 0x6B, 0x66, 0x1F,
446     0xA8, 0x82, 0xC6, 0x01, 0xE5, 0x80, 0xB5, 0xB0, 0x52, 0xD0, 0xE9, 0xD8,
447     0x72, 0xF9, 0x7D, 0x5B, 0x8B, 0xA5, 0x4C, 0xA5, 0x25, 0x95, 0x74, 0xE2,
448     0x7A, 0x61, 0x4E, 0xA7, 0x8F, 0x12, 0xE2, 0xD2, 0x9D, 0x8C, 0x02, 0x70,
449     0x34, 0x44, 0x32, 0xC7, 0xB2, 0xF3, 0xB9, 0xFE, 0x17, 0x2B, 0xD6, 0x1F,
450     0x8B, 0x7E, 0x4A, 0xFA, 0xA3, 0xB5, 0x3E, 0x7A, 0x81, 0x9A, 0x33, 0x66,
451     0x62, 0xA4, 0x50, 0x18, 0x3E, 0xA2, 0x5F, 0x00, 0x07, 0xD8, 0x9B, 0x22,
452     0xE4, 0xEC, 0x84, 0xD5, 0xEB, 0x5A, 0xF3, 0x2A, 0x31, 0x23, 0xD8, 0x44,
453     0x22, 0x2A, 0x8B, 0x37, 0x44, 0xCC, 0xC6, 0x87, 0x4B, 0xBE, 0x50, 0x9D,
454     0x4A, 0xC4, 0x8E, 0x45, 0xCF, 0x72, 0x4D, 0xC0, 0x89, 0xB3, 0x72, 0xED,
455     0x33, 0x2C, 0xBC, 0x7F, 0x16, 0x39, 0x3B, 0xEB, 0xD2, 0xDD, 0xA8, 0x01,
456     0x73, 0x84, 0x62, 0xB9, 0x29, 0xD2, 0xC9, 0x51, 0x32, 0x9E, 0x7A, 0x6A,
457     0xCF, 0xC1, 0x0A, 0xDB, 0x0E, 0xE0, 0x62, 0x77, 0x6F, 0x59, 0x62, 0x72,
458     0x5A, 0x69, 0xA6, 0x5B, 0x70, 0xCA, 0x65, 0xC4, 0x95, 0x6F, 0x9A, 0xC2,
459     0xDF, 0x72, 0x6D, 0xB1, 0x1E, 0x54, 0x7B, 0x51, 0xB4, 0xEF, 0x7F, 0x89,
460     0x93, 0x74, 0x89, 0x59
461 };
462
463 typedef struct {
464     DH *(*get_param) (void);
465     const unsigned char *xA;
466     size_t xA_len;
467     const unsigned char *yA;
468     size_t yA_len;
469     const unsigned char *xB;
470     size_t xB_len;
471     const unsigned char *yB;
472     size_t yB_len;
473     const unsigned char *Z;
474     size_t Z_len;
475 } rfc5114_td;
476
477 # define make_rfc5114_td(pre) { \
478         DH_get_##pre, \
479         dhtest_##pre##_xA, sizeof(dhtest_##pre##_xA), \
480         dhtest_##pre##_yA, sizeof(dhtest_##pre##_yA), \
481         dhtest_##pre##_xB, sizeof(dhtest_##pre##_xB), \
482         dhtest_##pre##_yB, sizeof(dhtest_##pre##_yB), \
483         dhtest_##pre##_Z, sizeof(dhtest_##pre##_Z) \
484         }
485
486 static const rfc5114_td rfctd[] = {
487         make_rfc5114_td(1024_160),
488         make_rfc5114_td(2048_224),
489         make_rfc5114_td(2048_256)
490 };
491
492 static int rfc5114_test(void)
493 {
494     int i;
495     DH *dhA = NULL;
496     DH *dhB = NULL;
497     unsigned char *Z1 = NULL;
498     unsigned char *Z2 = NULL;
499     const rfc5114_td *td = NULL;
500     BIGNUM *bady = NULL, *priv_key = NULL, *pub_key = NULL;
501     const BIGNUM *pub_key_tmp;
502
503     for (i = 0; i < (int)OSSL_NELEM(rfctd); i++) {
504         td = rfctd + i;
505         /* Set up DH structures setting key components */
506         if (!TEST_ptr(dhA = td->get_param())
507                 || !TEST_ptr(dhB = td->get_param()))
508             goto bad_err;
509
510         if (!TEST_ptr(priv_key = BN_bin2bn(td->xA, td->xA_len, NULL))
511                 || !TEST_ptr(pub_key = BN_bin2bn(td->yA, td->yA_len, NULL))
512                 || !TEST_true(DH_set0_key(dhA, pub_key, priv_key)))
513             goto bad_err;
514
515         if (!TEST_ptr(priv_key = BN_bin2bn(td->xB, td->xB_len, NULL))
516                 || !TEST_ptr(pub_key = BN_bin2bn(td->yB, td->yB_len, NULL))
517                 || !TEST_true( DH_set0_key(dhB, pub_key, priv_key)))
518             goto bad_err;
519         priv_key = pub_key = NULL;
520
521         if (!TEST_uint_eq(td->Z_len, (size_t)DH_size(dhA))
522             || !TEST_uint_eq(td->Z_len, (size_t)DH_size(dhB)))
523             goto err;
524
525         if (!TEST_ptr(Z1 = OPENSSL_malloc(DH_size(dhA)))
526                 || !TEST_ptr(Z2 = OPENSSL_malloc(DH_size(dhB))))
527             goto bad_err;
528         /*
529          * Work out shared secrets using both sides and compare with expected
530          * values.
531          */
532         DH_get0_key(dhB, &pub_key_tmp, NULL);
533         if (!TEST_int_ne(DH_compute_key(Z1, pub_key_tmp, dhA), -1))
534             goto bad_err;
535
536         DH_get0_key(dhA, &pub_key_tmp, NULL);
537         if (!TEST_int_ne(DH_compute_key(Z2, pub_key_tmp, dhB), -1))
538             goto bad_err;
539
540         if (!TEST_mem_eq(Z1, td->Z_len, td->Z, td->Z_len)
541                 || !TEST_mem_eq(Z2, td->Z_len, td->Z, td->Z_len))
542             goto err;
543
544         DH_free(dhA);
545         dhA = NULL;
546         DH_free(dhB);
547         dhB = NULL;
548         OPENSSL_free(Z1);
549         Z1 = NULL;
550         OPENSSL_free(Z2);
551         Z2 = NULL;
552     }
553
554     /* Now i == OSSL_NELEM(rfctd) */
555     /* RFC5114 uses unsafe primes, so now test an invalid y value */
556     if (!TEST_ptr(dhA = DH_get_2048_224())
557             || !TEST_ptr(Z1 = OPENSSL_malloc(DH_size(dhA))))
558         goto bad_err;
559
560     if (!TEST_ptr(bady = BN_bin2bn(dhtest_rfc5114_2048_224_bad_y,
561                                    sizeof(dhtest_rfc5114_2048_224_bad_y),
562                                    NULL)))
563         goto bad_err;
564
565     if (!DH_generate_key(dhA))
566         goto bad_err;
567
568     if (DH_compute_key(Z1, bady, dhA) != -1) {
569         /*
570          * DH_compute_key should fail with -1. If we get here we unexpectedly
571          * allowed an invalid y value
572          */
573         goto err;
574     }
575     /* We'll have a stale error on the queue from the above test so clear it */
576     ERR_clear_error();
577     BN_free(bady);
578     DH_free(dhA);
579     OPENSSL_free(Z1);
580     return 1;
581
582  bad_err:
583     BN_free(bady);
584     DH_free(dhA);
585     DH_free(dhB);
586     BN_free(pub_key);
587     BN_free(priv_key);
588     OPENSSL_free(Z1);
589     OPENSSL_free(Z2);
590     TEST_error("Initialisation error RFC5114 set %d\n", i + 1);
591     return 0;
592
593  err:
594     BN_free(bady);
595     DH_free(dhA);
596     DH_free(dhB);
597     OPENSSL_free(Z1);
598     OPENSSL_free(Z2);
599     TEST_error("Test failed RFC5114 set %d\n", i + 1);
600     return 0;
601 }
602 #endif
603
604
605 int setup_tests(void)
606 {
607 #ifdef OPENSSL_NO_DH
608     TEST_note("No DH support");
609 #else
610     ADD_TEST(dh_test);
611     ADD_TEST(rfc5114_test);
612 #endif
613     return 1;
614 }