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