blob: 9cde67961ed417d1167f4c44c6561a1781bbf1e0 [file] [log] [blame]
Adam Langley95c29f32014-06-20 12:00:00 -07001/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
57#include <openssl/dh.h>
58
59#include <stdio.h>
Adam Langley2b2d66d2015-01-30 17:08:37 -080060#include <string.h>
Adam Langley95c29f32014-06-20 12:00:00 -070061
David Benjamin66101182015-05-09 02:27:39 -040062#include <vector>
63
David Benjamin96628432017-01-19 19:05:47 -050064#include <gtest/gtest.h>
65
Adam Langley95c29f32014-06-20 12:00:00 -070066#include <openssl/bn.h>
David Benjaminf0e935d2016-09-06 18:10:19 -040067#include <openssl/bytestring.h>
David Benjamina70c75c2014-09-11 19:11:15 -040068#include <openssl/crypto.h>
Matt Braithwaited17d74d2016-08-17 20:10:28 -070069#include <openssl/dh.h>
Brian Smith83a82982015-04-09 16:21:10 -100070#include <openssl/err.h>
Adam Langley95c29f32014-06-20 12:00:00 -070071#include <openssl/mem.h>
72
David Benjamin17cf2cb2016-12-13 01:07:13 -050073#include "../internal.h"
74
Adam Langley95c29f32014-06-20 12:00:00 -070075
Adam Langley10f97f32016-07-12 08:09:33 -070076static bool RunBasicTests();
77static bool RunRFC5114Tests();
78static bool TestBadY();
79static bool TestASN1();
David Benjamin96e1a252016-08-10 13:38:51 -040080static bool TestRFC3526();
Adam Langley10f97f32016-07-12 08:09:33 -070081
David Benjamin96628432017-01-19 19:05:47 -050082// TODO(davidben): Convert this file to GTest properly.
83TEST(DHTest, AllTests) {
Adam Langley10f97f32016-07-12 08:09:33 -070084 if (!RunBasicTests() ||
85 !RunRFC5114Tests() ||
86 !TestBadY() ||
David Benjamin96e1a252016-08-10 13:38:51 -040087 !TestASN1() ||
88 !TestRFC3526()) {
Adam Langley10f97f32016-07-12 08:09:33 -070089 ERR_print_errors_fp(stderr);
David Benjamin96628432017-01-19 19:05:47 -050090 ADD_FAILURE() << "Tests failed.";
Adam Langley10f97f32016-07-12 08:09:33 -070091 }
Adam Langley10f97f32016-07-12 08:09:33 -070092}
David Benjamin66101182015-05-09 02:27:39 -040093
94static int GenerateCallback(int p, int n, BN_GENCB *arg) {
Adam Langley95c29f32014-06-20 12:00:00 -070095 char c = '*';
96
David Benjaminc9a202f2015-02-11 01:16:26 -050097 if (p == 0) {
Adam Langley95c29f32014-06-20 12:00:00 -070098 c = '.';
David Benjaminc9a202f2015-02-11 01:16:26 -050099 } else if (p == 1) {
Adam Langley95c29f32014-06-20 12:00:00 -0700100 c = '+';
David Benjaminc9a202f2015-02-11 01:16:26 -0500101 } else if (p == 2) {
Adam Langley95c29f32014-06-20 12:00:00 -0700102 c = '*';
David Benjaminc9a202f2015-02-11 01:16:26 -0500103 } else if (p == 3) {
Adam Langley95c29f32014-06-20 12:00:00 -0700104 c = '\n';
David Benjaminc9a202f2015-02-11 01:16:26 -0500105 }
David Benjamin66101182015-05-09 02:27:39 -0400106 FILE *out = reinterpret_cast<FILE*>(arg->arg);
107 fputc(c, out);
108 fflush(out);
Adam Langley95c29f32014-06-20 12:00:00 -0700109
110 return 1;
111}
112
David Benjamin66101182015-05-09 02:27:39 -0400113static bool RunBasicTests() {
114 BN_GENCB cb;
115 BN_GENCB_set(&cb, &GenerateCallback, stdout);
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700116 bssl::UniquePtr<DH> a(DH_new());
David Benjamin66101182015-05-09 02:27:39 -0400117 if (!a || !DH_generate_parameters_ex(a.get(), 64, DH_GENERATOR_5, &cb)) {
118 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700119 }
120
David Benjamin66101182015-05-09 02:27:39 -0400121 int check_result;
122 if (!DH_check(a.get(), &check_result)) {
123 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500124 }
David Benjamin66101182015-05-09 02:27:39 -0400125 if (check_result & DH_CHECK_P_NOT_PRIME) {
126 printf("p value is not prime\n");
David Benjaminc9a202f2015-02-11 01:16:26 -0500127 }
David Benjamin66101182015-05-09 02:27:39 -0400128 if (check_result & DH_CHECK_P_NOT_SAFE_PRIME) {
129 printf("p value is not a safe prime\n");
David Benjaminc9a202f2015-02-11 01:16:26 -0500130 }
David Benjamin66101182015-05-09 02:27:39 -0400131 if (check_result & DH_CHECK_UNABLE_TO_CHECK_GENERATOR) {
132 printf("unable to check the generator value\n");
David Benjaminc9a202f2015-02-11 01:16:26 -0500133 }
David Benjamin66101182015-05-09 02:27:39 -0400134 if (check_result & DH_CHECK_NOT_SUITABLE_GENERATOR) {
135 printf("the g value is not a generator\n");
David Benjaminc9a202f2015-02-11 01:16:26 -0500136 }
Adam Langley95c29f32014-06-20 12:00:00 -0700137
David Benjamin66101182015-05-09 02:27:39 -0400138 printf("\np = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800139 BN_print_fp(stdout, a->p);
David Benjamin66101182015-05-09 02:27:39 -0400140 printf("\ng = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800141 BN_print_fp(stdout, a->g);
David Benjamin66101182015-05-09 02:27:39 -0400142 printf("\n");
Adam Langley95c29f32014-06-20 12:00:00 -0700143
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700144 bssl::UniquePtr<DH> b(DH_new());
David Benjamin66101182015-05-09 02:27:39 -0400145 if (!b) {
146 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700147 }
148
149 b->p = BN_dup(a->p);
150 b->g = BN_dup(a->g);
David Benjamin66101182015-05-09 02:27:39 -0400151 if (b->p == nullptr || b->g == nullptr) {
152 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700153 }
154
David Benjamin66101182015-05-09 02:27:39 -0400155 if (!DH_generate_key(a.get())) {
156 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500157 }
David Benjamin66101182015-05-09 02:27:39 -0400158 printf("pri1 = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800159 BN_print_fp(stdout, a->priv_key);
David Benjamin66101182015-05-09 02:27:39 -0400160 printf("\npub1 = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800161 BN_print_fp(stdout, a->pub_key);
David Benjamin66101182015-05-09 02:27:39 -0400162 printf("\n");
Adam Langley95c29f32014-06-20 12:00:00 -0700163
David Benjamin66101182015-05-09 02:27:39 -0400164 if (!DH_generate_key(b.get())) {
165 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500166 }
David Benjamin66101182015-05-09 02:27:39 -0400167 printf("pri2 = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800168 BN_print_fp(stdout, b->priv_key);
David Benjamin66101182015-05-09 02:27:39 -0400169 printf("\npub2 = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800170 BN_print_fp(stdout, b->pub_key);
David Benjamin66101182015-05-09 02:27:39 -0400171 printf("\n");
Adam Langley95c29f32014-06-20 12:00:00 -0700172
David Benjamin66101182015-05-09 02:27:39 -0400173 std::vector<uint8_t> key1(DH_size(a.get()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800174 int ret = DH_compute_key(key1.data(), b->pub_key, a.get());
David Benjamin66101182015-05-09 02:27:39 -0400175 if (ret < 0) {
176 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700177 }
David Benjamin66101182015-05-09 02:27:39 -0400178 key1.resize(ret);
Adam Langley95c29f32014-06-20 12:00:00 -0700179
David Benjamin66101182015-05-09 02:27:39 -0400180 printf("key1 = ");
181 for (size_t i = 0; i < key1.size(); i++) {
182 printf("%02x", key1[i]);
Adam Langley95c29f32014-06-20 12:00:00 -0700183 }
David Benjamin66101182015-05-09 02:27:39 -0400184 printf("\n");
185
186 std::vector<uint8_t> key2(DH_size(b.get()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800187 ret = DH_compute_key(key2.data(), a->pub_key, b.get());
David Benjamin66101182015-05-09 02:27:39 -0400188 if (ret < 0) {
189 return false;
190 }
191 key2.resize(ret);
192
193 printf("key2 = ");
194 for (size_t i = 0; i < key2.size(); i++) {
195 printf("%02x", key2[i]);
196 }
197 printf("\n");
198
199 if (key1.size() < 4 || key1 != key2) {
Adam Langley95c29f32014-06-20 12:00:00 -0700200 fprintf(stderr, "Error in DH routines\n");
David Benjamin66101182015-05-09 02:27:39 -0400201 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500202 }
Adam Langley95c29f32014-06-20 12:00:00 -0700203
David Benjamin66101182015-05-09 02:27:39 -0400204 return true;
Adam Langley95c29f32014-06-20 12:00:00 -0700205}
206
207/* Test data from RFC 5114 */
208
David Benjamin66101182015-05-09 02:27:39 -0400209static const uint8_t kDHTest1024_160_xA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700210 0xB9, 0xA3, 0xB3, 0xAE, 0x8F, 0xEF, 0xC1, 0xA2, 0x93, 0x04,
211 0x96, 0x50, 0x70, 0x86, 0xF8, 0x45, 0x5D, 0x48, 0x94, 0x3E};
David Benjamin66101182015-05-09 02:27:39 -0400212static const uint8_t kDHTest1024_160_yA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700213 0x2A, 0x85, 0x3B, 0x3D, 0x92, 0x19, 0x75, 0x01, 0xB9, 0x01, 0x5B, 0x2D,
214 0xEB, 0x3E, 0xD8, 0x4F, 0x5E, 0x02, 0x1D, 0xCC, 0x3E, 0x52, 0xF1, 0x09,
215 0xD3, 0x27, 0x3D, 0x2B, 0x75, 0x21, 0x28, 0x1C, 0xBA, 0xBE, 0x0E, 0x76,
216 0xFF, 0x57, 0x27, 0xFA, 0x8A, 0xCC, 0xE2, 0x69, 0x56, 0xBA, 0x9A, 0x1F,
217 0xCA, 0x26, 0xF2, 0x02, 0x28, 0xD8, 0x69, 0x3F, 0xEB, 0x10, 0x84, 0x1D,
218 0x84, 0xA7, 0x36, 0x00, 0x54, 0xEC, 0xE5, 0xA7, 0xF5, 0xB7, 0xA6, 0x1A,
219 0xD3, 0xDF, 0xB3, 0xC6, 0x0D, 0x2E, 0x43, 0x10, 0x6D, 0x87, 0x27, 0xDA,
220 0x37, 0xDF, 0x9C, 0xCE, 0x95, 0xB4, 0x78, 0x75, 0x5D, 0x06, 0xBC, 0xEA,
221 0x8F, 0x9D, 0x45, 0x96, 0x5F, 0x75, 0xA5, 0xF3, 0xD1, 0xDF, 0x37, 0x01,
222 0x16, 0x5F, 0xC9, 0xE5, 0x0C, 0x42, 0x79, 0xCE, 0xB0, 0x7F, 0x98, 0x95,
223 0x40, 0xAE, 0x96, 0xD5, 0xD8, 0x8E, 0xD7, 0x76};
David Benjamin66101182015-05-09 02:27:39 -0400224static const uint8_t kDHTest1024_160_xB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700225 0x93, 0x92, 0xC9, 0xF9, 0xEB, 0x6A, 0x7A, 0x6A, 0x90, 0x22,
226 0xF7, 0xD8, 0x3E, 0x72, 0x23, 0xC6, 0x83, 0x5B, 0xBD, 0xDA};
David Benjamin66101182015-05-09 02:27:39 -0400227static const uint8_t kDHTest1024_160_yB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700228 0x71, 0x7A, 0x6C, 0xB0, 0x53, 0x37, 0x1F, 0xF4, 0xA3, 0xB9, 0x32, 0x94,
229 0x1C, 0x1E, 0x56, 0x63, 0xF8, 0x61, 0xA1, 0xD6, 0xAD, 0x34, 0xAE, 0x66,
230 0x57, 0x6D, 0xFB, 0x98, 0xF6, 0xC6, 0xCB, 0xF9, 0xDD, 0xD5, 0xA5, 0x6C,
231 0x78, 0x33, 0xF6, 0xBC, 0xFD, 0xFF, 0x09, 0x55, 0x82, 0xAD, 0x86, 0x8E,
232 0x44, 0x0E, 0x8D, 0x09, 0xFD, 0x76, 0x9E, 0x3C, 0xEC, 0xCD, 0xC3, 0xD3,
233 0xB1, 0xE4, 0xCF, 0xA0, 0x57, 0x77, 0x6C, 0xAA, 0xF9, 0x73, 0x9B, 0x6A,
234 0x9F, 0xEE, 0x8E, 0x74, 0x11, 0xF8, 0xD6, 0xDA, 0xC0, 0x9D, 0x6A, 0x4E,
235 0xDB, 0x46, 0xCC, 0x2B, 0x5D, 0x52, 0x03, 0x09, 0x0E, 0xAE, 0x61, 0x26,
236 0x31, 0x1E, 0x53, 0xFD, 0x2C, 0x14, 0xB5, 0x74, 0xE6, 0xA3, 0x10, 0x9A,
237 0x3D, 0xA1, 0xBE, 0x41, 0xBD, 0xCE, 0xAA, 0x18, 0x6F, 0x5C, 0xE0, 0x67,
238 0x16, 0xA2, 0xB6, 0xA0, 0x7B, 0x3C, 0x33, 0xFE};
David Benjamin66101182015-05-09 02:27:39 -0400239static const uint8_t kDHTest1024_160_Z[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700240 0x5C, 0x80, 0x4F, 0x45, 0x4D, 0x30, 0xD9, 0xC4, 0xDF, 0x85, 0x27, 0x1F,
241 0x93, 0x52, 0x8C, 0x91, 0xDF, 0x6B, 0x48, 0xAB, 0x5F, 0x80, 0xB3, 0xB5,
242 0x9C, 0xAA, 0xC1, 0xB2, 0x8F, 0x8A, 0xCB, 0xA9, 0xCD, 0x3E, 0x39, 0xF3,
243 0xCB, 0x61, 0x45, 0x25, 0xD9, 0x52, 0x1D, 0x2E, 0x64, 0x4C, 0x53, 0xB8,
244 0x07, 0xB8, 0x10, 0xF3, 0x40, 0x06, 0x2F, 0x25, 0x7D, 0x7D, 0x6F, 0xBF,
245 0xE8, 0xD5, 0xE8, 0xF0, 0x72, 0xE9, 0xB6, 0xE9, 0xAF, 0xDA, 0x94, 0x13,
246 0xEA, 0xFB, 0x2E, 0x8B, 0x06, 0x99, 0xB1, 0xFB, 0x5A, 0x0C, 0xAC, 0xED,
247 0xDE, 0xAE, 0xAD, 0x7E, 0x9C, 0xFB, 0xB3, 0x6A, 0xE2, 0xB4, 0x20, 0x83,
248 0x5B, 0xD8, 0x3A, 0x19, 0xFB, 0x0B, 0x5E, 0x96, 0xBF, 0x8F, 0xA4, 0xD0,
249 0x9E, 0x34, 0x55, 0x25, 0x16, 0x7E, 0xCD, 0x91, 0x55, 0x41, 0x6F, 0x46,
250 0xF4, 0x08, 0xED, 0x31, 0xB6, 0x3C, 0x6E, 0x6D};
David Benjamin66101182015-05-09 02:27:39 -0400251static const uint8_t kDHTest2048_224_xA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700252 0x22, 0xE6, 0x26, 0x01, 0xDB, 0xFF, 0xD0, 0x67, 0x08, 0xA6,
253 0x80, 0xF7, 0x47, 0xF3, 0x61, 0xF7, 0x6D, 0x8F, 0x4F, 0x72,
254 0x1A, 0x05, 0x48, 0xE4, 0x83, 0x29, 0x4B, 0x0C};
David Benjamin66101182015-05-09 02:27:39 -0400255static const uint8_t kDHTest2048_224_yA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700256 0x1B, 0x3A, 0x63, 0x45, 0x1B, 0xD8, 0x86, 0xE6, 0x99, 0xE6, 0x7B, 0x49,
257 0x4E, 0x28, 0x8B, 0xD7, 0xF8, 0xE0, 0xD3, 0x70, 0xBA, 0xDD, 0xA7, 0xA0,
258 0xEF, 0xD2, 0xFD, 0xE7, 0xD8, 0xF6, 0x61, 0x45, 0xCC, 0x9F, 0x28, 0x04,
259 0x19, 0x97, 0x5E, 0xB8, 0x08, 0x87, 0x7C, 0x8A, 0x4C, 0x0C, 0x8E, 0x0B,
260 0xD4, 0x8D, 0x4A, 0x54, 0x01, 0xEB, 0x1E, 0x87, 0x76, 0xBF, 0xEE, 0xE1,
261 0x34, 0xC0, 0x38, 0x31, 0xAC, 0x27, 0x3C, 0xD9, 0xD6, 0x35, 0xAB, 0x0C,
262 0xE0, 0x06, 0xA4, 0x2A, 0x88, 0x7E, 0x3F, 0x52, 0xFB, 0x87, 0x66, 0xB6,
263 0x50, 0xF3, 0x80, 0x78, 0xBC, 0x8E, 0xE8, 0x58, 0x0C, 0xEF, 0xE2, 0x43,
264 0x96, 0x8C, 0xFC, 0x4F, 0x8D, 0xC3, 0xDB, 0x08, 0x45, 0x54, 0x17, 0x1D,
265 0x41, 0xBF, 0x2E, 0x86, 0x1B, 0x7B, 0xB4, 0xD6, 0x9D, 0xD0, 0xE0, 0x1E,
266 0xA3, 0x87, 0xCB, 0xAA, 0x5C, 0xA6, 0x72, 0xAF, 0xCB, 0xE8, 0xBD, 0xB9,
267 0xD6, 0x2D, 0x4C, 0xE1, 0x5F, 0x17, 0xDD, 0x36, 0xF9, 0x1E, 0xD1, 0xEE,
268 0xDD, 0x65, 0xCA, 0x4A, 0x06, 0x45, 0x5C, 0xB9, 0x4C, 0xD4, 0x0A, 0x52,
269 0xEC, 0x36, 0x0E, 0x84, 0xB3, 0xC9, 0x26, 0xE2, 0x2C, 0x43, 0x80, 0xA3,
270 0xBF, 0x30, 0x9D, 0x56, 0x84, 0x97, 0x68, 0xB7, 0xF5, 0x2C, 0xFD, 0xF6,
271 0x55, 0xFD, 0x05, 0x3A, 0x7E, 0xF7, 0x06, 0x97, 0x9E, 0x7E, 0x58, 0x06,
272 0xB1, 0x7D, 0xFA, 0xE5, 0x3A, 0xD2, 0xA5, 0xBC, 0x56, 0x8E, 0xBB, 0x52,
273 0x9A, 0x7A, 0x61, 0xD6, 0x8D, 0x25, 0x6F, 0x8F, 0xC9, 0x7C, 0x07, 0x4A,
274 0x86, 0x1D, 0x82, 0x7E, 0x2E, 0xBC, 0x8C, 0x61, 0x34, 0x55, 0x31, 0x15,
275 0xB7, 0x0E, 0x71, 0x03, 0x92, 0x0A, 0xA1, 0x6D, 0x85, 0xE5, 0x2B, 0xCB,
276 0xAB, 0x8D, 0x78, 0x6A, 0x68, 0x17, 0x8F, 0xA8, 0xFF, 0x7C, 0x2F, 0x5C,
277 0x71, 0x64, 0x8D, 0x6F};
David Benjamin66101182015-05-09 02:27:39 -0400278static const uint8_t kDHTest2048_224_xB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700279 0x4F, 0xF3, 0xBC, 0x96, 0xC7, 0xFC, 0x6A, 0x6D, 0x71, 0xD3,
280 0xB3, 0x63, 0x80, 0x0A, 0x7C, 0xDF, 0xEF, 0x6F, 0xC4, 0x1B,
281 0x44, 0x17, 0xEA, 0x15, 0x35, 0x3B, 0x75, 0x90};
David Benjamin66101182015-05-09 02:27:39 -0400282static const uint8_t kDHTest2048_224_yB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700283 0x4D, 0xCE, 0xE9, 0x92, 0xA9, 0x76, 0x2A, 0x13, 0xF2, 0xF8, 0x38, 0x44,
284 0xAD, 0x3D, 0x77, 0xEE, 0x0E, 0x31, 0xC9, 0x71, 0x8B, 0x3D, 0xB6, 0xC2,
285 0x03, 0x5D, 0x39, 0x61, 0x18, 0x2C, 0x3E, 0x0B, 0xA2, 0x47, 0xEC, 0x41,
286 0x82, 0xD7, 0x60, 0xCD, 0x48, 0xD9, 0x95, 0x99, 0x97, 0x06, 0x22, 0xA1,
287 0x88, 0x1B, 0xBA, 0x2D, 0xC8, 0x22, 0x93, 0x9C, 0x78, 0xC3, 0x91, 0x2C,
288 0x66, 0x61, 0xFA, 0x54, 0x38, 0xB2, 0x07, 0x66, 0x22, 0x2B, 0x75, 0xE2,
289 0x4C, 0x2E, 0x3A, 0xD0, 0xC7, 0x28, 0x72, 0x36, 0x12, 0x95, 0x25, 0xEE,
290 0x15, 0xB5, 0xDD, 0x79, 0x98, 0xAA, 0x04, 0xC4, 0xA9, 0x69, 0x6C, 0xAC,
291 0xD7, 0x17, 0x20, 0x83, 0xA9, 0x7A, 0x81, 0x66, 0x4E, 0xAD, 0x2C, 0x47,
292 0x9E, 0x44, 0x4E, 0x4C, 0x06, 0x54, 0xCC, 0x19, 0xE2, 0x8D, 0x77, 0x03,
293 0xCE, 0xE8, 0xDA, 0xCD, 0x61, 0x26, 0xF5, 0xD6, 0x65, 0xEC, 0x52, 0xC6,
294 0x72, 0x55, 0xDB, 0x92, 0x01, 0x4B, 0x03, 0x7E, 0xB6, 0x21, 0xA2, 0xAC,
295 0x8E, 0x36, 0x5D, 0xE0, 0x71, 0xFF, 0xC1, 0x40, 0x0A, 0xCF, 0x07, 0x7A,
296 0x12, 0x91, 0x3D, 0xD8, 0xDE, 0x89, 0x47, 0x34, 0x37, 0xAB, 0x7B, 0xA3,
297 0x46, 0x74, 0x3C, 0x1B, 0x21, 0x5D, 0xD9, 0xC1, 0x21, 0x64, 0xA7, 0xE4,
298 0x05, 0x31, 0x18, 0xD1, 0x99, 0xBE, 0xC8, 0xEF, 0x6F, 0xC5, 0x61, 0x17,
299 0x0C, 0x84, 0xC8, 0x7D, 0x10, 0xEE, 0x9A, 0x67, 0x4A, 0x1F, 0xA8, 0xFF,
300 0xE1, 0x3B, 0xDF, 0xBA, 0x1D, 0x44, 0xDE, 0x48, 0x94, 0x6D, 0x68, 0xDC,
301 0x0C, 0xDD, 0x77, 0x76, 0x35, 0xA7, 0xAB, 0x5B, 0xFB, 0x1E, 0x4B, 0xB7,
302 0xB8, 0x56, 0xF9, 0x68, 0x27, 0x73, 0x4C, 0x18, 0x41, 0x38, 0xE9, 0x15,
303 0xD9, 0xC3, 0x00, 0x2E, 0xBC, 0xE5, 0x31, 0x20, 0x54, 0x6A, 0x7E, 0x20,
304 0x02, 0x14, 0x2B, 0x6C};
David Benjamin66101182015-05-09 02:27:39 -0400305static const uint8_t kDHTest2048_224_Z[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700306 0x34, 0xD9, 0xBD, 0xDC, 0x1B, 0x42, 0x17, 0x6C, 0x31, 0x3F, 0xEA, 0x03,
307 0x4C, 0x21, 0x03, 0x4D, 0x07, 0x4A, 0x63, 0x13, 0xBB, 0x4E, 0xCD, 0xB3,
308 0x70, 0x3F, 0xFF, 0x42, 0x45, 0x67, 0xA4, 0x6B, 0xDF, 0x75, 0x53, 0x0E,
309 0xDE, 0x0A, 0x9D, 0xA5, 0x22, 0x9D, 0xE7, 0xD7, 0x67, 0x32, 0x28, 0x6C,
310 0xBC, 0x0F, 0x91, 0xDA, 0x4C, 0x3C, 0x85, 0x2F, 0xC0, 0x99, 0xC6, 0x79,
311 0x53, 0x1D, 0x94, 0xC7, 0x8A, 0xB0, 0x3D, 0x9D, 0xEC, 0xB0, 0xA4, 0xE4,
312 0xCA, 0x8B, 0x2B, 0xB4, 0x59, 0x1C, 0x40, 0x21, 0xCF, 0x8C, 0xE3, 0xA2,
313 0x0A, 0x54, 0x1D, 0x33, 0x99, 0x40, 0x17, 0xD0, 0x20, 0x0A, 0xE2, 0xC9,
314 0x51, 0x6E, 0x2F, 0xF5, 0x14, 0x57, 0x79, 0x26, 0x9E, 0x86, 0x2B, 0x0F,
315 0xB4, 0x74, 0xA2, 0xD5, 0x6D, 0xC3, 0x1E, 0xD5, 0x69, 0xA7, 0x70, 0x0B,
316 0x4C, 0x4A, 0xB1, 0x6B, 0x22, 0xA4, 0x55, 0x13, 0x53, 0x1E, 0xF5, 0x23,
317 0xD7, 0x12, 0x12, 0x07, 0x7B, 0x5A, 0x16, 0x9B, 0xDE, 0xFF, 0xAD, 0x7A,
318 0xD9, 0x60, 0x82, 0x84, 0xC7, 0x79, 0x5B, 0x6D, 0x5A, 0x51, 0x83, 0xB8,
319 0x70, 0x66, 0xDE, 0x17, 0xD8, 0xD6, 0x71, 0xC9, 0xEB, 0xD8, 0xEC, 0x89,
320 0x54, 0x4D, 0x45, 0xEC, 0x06, 0x15, 0x93, 0xD4, 0x42, 0xC6, 0x2A, 0xB9,
321 0xCE, 0x3B, 0x1C, 0xB9, 0x94, 0x3A, 0x1D, 0x23, 0xA5, 0xEA, 0x3B, 0xCF,
322 0x21, 0xA0, 0x14, 0x71, 0xE6, 0x7E, 0x00, 0x3E, 0x7F, 0x8A, 0x69, 0xC7,
323 0x28, 0xBE, 0x49, 0x0B, 0x2F, 0xC8, 0x8C, 0xFE, 0xB9, 0x2D, 0xB6, 0xA2,
324 0x15, 0xE5, 0xD0, 0x3C, 0x17, 0xC4, 0x64, 0xC9, 0xAC, 0x1A, 0x46, 0xE2,
325 0x03, 0xE1, 0x3F, 0x95, 0x29, 0x95, 0xFB, 0x03, 0xC6, 0x9D, 0x3C, 0xC4,
326 0x7F, 0xCB, 0x51, 0x0B, 0x69, 0x98, 0xFF, 0xD3, 0xAA, 0x6D, 0xE7, 0x3C,
327 0xF9, 0xF6, 0x38, 0x69};
David Benjamin66101182015-05-09 02:27:39 -0400328static const uint8_t kDHTest2048_256_xA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700329 0x08, 0x81, 0x38, 0x2C, 0xDB, 0x87, 0x66, 0x0C, 0x6D, 0xC1, 0x3E,
330 0x61, 0x49, 0x38, 0xD5, 0xB9, 0xC8, 0xB2, 0xF2, 0x48, 0x58, 0x1C,
331 0xC5, 0xE3, 0x1B, 0x35, 0x45, 0x43, 0x97, 0xFC, 0xE5, 0x0E};
David Benjamin66101182015-05-09 02:27:39 -0400332static const uint8_t kDHTest2048_256_yA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700333 0x2E, 0x93, 0x80, 0xC8, 0x32, 0x3A, 0xF9, 0x75, 0x45, 0xBC, 0x49, 0x41,
334 0xDE, 0xB0, 0xEC, 0x37, 0x42, 0xC6, 0x2F, 0xE0, 0xEC, 0xE8, 0x24, 0xA6,
335 0xAB, 0xDB, 0xE6, 0x6C, 0x59, 0xBE, 0xE0, 0x24, 0x29, 0x11, 0xBF, 0xB9,
336 0x67, 0x23, 0x5C, 0xEB, 0xA3, 0x5A, 0xE1, 0x3E, 0x4E, 0xC7, 0x52, 0xBE,
337 0x63, 0x0B, 0x92, 0xDC, 0x4B, 0xDE, 0x28, 0x47, 0xA9, 0xC6, 0x2C, 0xB8,
338 0x15, 0x27, 0x45, 0x42, 0x1F, 0xB7, 0xEB, 0x60, 0xA6, 0x3C, 0x0F, 0xE9,
339 0x15, 0x9F, 0xCC, 0xE7, 0x26, 0xCE, 0x7C, 0xD8, 0x52, 0x3D, 0x74, 0x50,
340 0x66, 0x7E, 0xF8, 0x40, 0xE4, 0x91, 0x91, 0x21, 0xEB, 0x5F, 0x01, 0xC8,
341 0xC9, 0xB0, 0xD3, 0xD6, 0x48, 0xA9, 0x3B, 0xFB, 0x75, 0x68, 0x9E, 0x82,
342 0x44, 0xAC, 0x13, 0x4A, 0xF5, 0x44, 0x71, 0x1C, 0xE7, 0x9A, 0x02, 0xDC,
343 0xC3, 0x42, 0x26, 0x68, 0x47, 0x80, 0xDD, 0xDC, 0xB4, 0x98, 0x59, 0x41,
344 0x06, 0xC3, 0x7F, 0x5B, 0xC7, 0x98, 0x56, 0x48, 0x7A, 0xF5, 0xAB, 0x02,
345 0x2A, 0x2E, 0x5E, 0x42, 0xF0, 0x98, 0x97, 0xC1, 0xA8, 0x5A, 0x11, 0xEA,
346 0x02, 0x12, 0xAF, 0x04, 0xD9, 0xB4, 0xCE, 0xBC, 0x93, 0x7C, 0x3C, 0x1A,
347 0x3E, 0x15, 0xA8, 0xA0, 0x34, 0x2E, 0x33, 0x76, 0x15, 0xC8, 0x4E, 0x7F,
348 0xE3, 0xB8, 0xB9, 0xB8, 0x7F, 0xB1, 0xE7, 0x3A, 0x15, 0xAF, 0x12, 0xA3,
349 0x0D, 0x74, 0x6E, 0x06, 0xDF, 0xC3, 0x4F, 0x29, 0x0D, 0x79, 0x7C, 0xE5,
350 0x1A, 0xA1, 0x3A, 0xA7, 0x85, 0xBF, 0x66, 0x58, 0xAF, 0xF5, 0xE4, 0xB0,
351 0x93, 0x00, 0x3C, 0xBE, 0xAF, 0x66, 0x5B, 0x3C, 0x2E, 0x11, 0x3A, 0x3A,
352 0x4E, 0x90, 0x52, 0x69, 0x34, 0x1D, 0xC0, 0x71, 0x14, 0x26, 0x68, 0x5F,
353 0x4E, 0xF3, 0x7E, 0x86, 0x8A, 0x81, 0x26, 0xFF, 0x3F, 0x22, 0x79, 0xB5,
354 0x7C, 0xA6, 0x7E, 0x29};
David Benjamin66101182015-05-09 02:27:39 -0400355static const uint8_t kDHTest2048_256_xB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700356 0x7D, 0x62, 0xA7, 0xE3, 0xEF, 0x36, 0xDE, 0x61, 0x7B, 0x13, 0xD1,
357 0xAF, 0xB8, 0x2C, 0x78, 0x0D, 0x83, 0xA2, 0x3B, 0xD4, 0xEE, 0x67,
358 0x05, 0x64, 0x51, 0x21, 0xF3, 0x71, 0xF5, 0x46, 0xA5, 0x3D};
David Benjamin66101182015-05-09 02:27:39 -0400359static const uint8_t kDHTest2048_256_yB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700360 0x57, 0x5F, 0x03, 0x51, 0xBD, 0x2B, 0x1B, 0x81, 0x74, 0x48, 0xBD, 0xF8,
361 0x7A, 0x6C, 0x36, 0x2C, 0x1E, 0x28, 0x9D, 0x39, 0x03, 0xA3, 0x0B, 0x98,
362 0x32, 0xC5, 0x74, 0x1F, 0xA2, 0x50, 0x36, 0x3E, 0x7A, 0xCB, 0xC7, 0xF7,
363 0x7F, 0x3D, 0xAC, 0xBC, 0x1F, 0x13, 0x1A, 0xDD, 0x8E, 0x03, 0x36, 0x7E,
364 0xFF, 0x8F, 0xBB, 0xB3, 0xE1, 0xC5, 0x78, 0x44, 0x24, 0x80, 0x9B, 0x25,
365 0xAF, 0xE4, 0xD2, 0x26, 0x2A, 0x1A, 0x6F, 0xD2, 0xFA, 0xB6, 0x41, 0x05,
366 0xCA, 0x30, 0xA6, 0x74, 0xE0, 0x7F, 0x78, 0x09, 0x85, 0x20, 0x88, 0x63,
367 0x2F, 0xC0, 0x49, 0x23, 0x37, 0x91, 0xAD, 0x4E, 0xDD, 0x08, 0x3A, 0x97,
368 0x8B, 0x88, 0x3E, 0xE6, 0x18, 0xBC, 0x5E, 0x0D, 0xD0, 0x47, 0x41, 0x5F,
369 0x2D, 0x95, 0xE6, 0x83, 0xCF, 0x14, 0x82, 0x6B, 0x5F, 0xBE, 0x10, 0xD3,
370 0xCE, 0x41, 0xC6, 0xC1, 0x20, 0xC7, 0x8A, 0xB2, 0x00, 0x08, 0xC6, 0x98,
371 0xBF, 0x7F, 0x0B, 0xCA, 0xB9, 0xD7, 0xF4, 0x07, 0xBE, 0xD0, 0xF4, 0x3A,
372 0xFB, 0x29, 0x70, 0xF5, 0x7F, 0x8D, 0x12, 0x04, 0x39, 0x63, 0xE6, 0x6D,
373 0xDD, 0x32, 0x0D, 0x59, 0x9A, 0xD9, 0x93, 0x6C, 0x8F, 0x44, 0x13, 0x7C,
374 0x08, 0xB1, 0x80, 0xEC, 0x5E, 0x98, 0x5C, 0xEB, 0xE1, 0x86, 0xF3, 0xD5,
375 0x49, 0x67, 0x7E, 0x80, 0x60, 0x73, 0x31, 0xEE, 0x17, 0xAF, 0x33, 0x80,
376 0xA7, 0x25, 0xB0, 0x78, 0x23, 0x17, 0xD7, 0xDD, 0x43, 0xF5, 0x9D, 0x7A,
377 0xF9, 0x56, 0x8A, 0x9B, 0xB6, 0x3A, 0x84, 0xD3, 0x65, 0xF9, 0x22, 0x44,
378 0xED, 0x12, 0x09, 0x88, 0x21, 0x93, 0x02, 0xF4, 0x29, 0x24, 0xC7, 0xCA,
379 0x90, 0xB8, 0x9D, 0x24, 0xF7, 0x1B, 0x0A, 0xB6, 0x97, 0x82, 0x3D, 0x7D,
380 0xEB, 0x1A, 0xFF, 0x5B, 0x0E, 0x8E, 0x4A, 0x45, 0xD4, 0x9F, 0x7F, 0x53,
381 0x75, 0x7E, 0x19, 0x13};
David Benjamin66101182015-05-09 02:27:39 -0400382static const uint8_t kDHTest2048_256_Z[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700383 0x86, 0xC7, 0x0B, 0xF8, 0xD0, 0xBB, 0x81, 0xBB, 0x01, 0x07, 0x8A, 0x17,
384 0x21, 0x9C, 0xB7, 0xD2, 0x72, 0x03, 0xDB, 0x2A, 0x19, 0xC8, 0x77, 0xF1,
385 0xD1, 0xF1, 0x9F, 0xD7, 0xD7, 0x7E, 0xF2, 0x25, 0x46, 0xA6, 0x8F, 0x00,
386 0x5A, 0xD5, 0x2D, 0xC8, 0x45, 0x53, 0xB7, 0x8F, 0xC6, 0x03, 0x30, 0xBE,
387 0x51, 0xEA, 0x7C, 0x06, 0x72, 0xCA, 0xC1, 0x51, 0x5E, 0x4B, 0x35, 0xC0,
388 0x47, 0xB9, 0xA5, 0x51, 0xB8, 0x8F, 0x39, 0xDC, 0x26, 0xDA, 0x14, 0xA0,
389 0x9E, 0xF7, 0x47, 0x74, 0xD4, 0x7C, 0x76, 0x2D, 0xD1, 0x77, 0xF9, 0xED,
390 0x5B, 0xC2, 0xF1, 0x1E, 0x52, 0xC8, 0x79, 0xBD, 0x95, 0x09, 0x85, 0x04,
391 0xCD, 0x9E, 0xEC, 0xD8, 0xA8, 0xF9, 0xB3, 0xEF, 0xBD, 0x1F, 0x00, 0x8A,
392 0xC5, 0x85, 0x30, 0x97, 0xD9, 0xD1, 0x83, 0x7F, 0x2B, 0x18, 0xF7, 0x7C,
393 0xD7, 0xBE, 0x01, 0xAF, 0x80, 0xA7, 0xC7, 0xB5, 0xEA, 0x3C, 0xA5, 0x4C,
394 0xC0, 0x2D, 0x0C, 0x11, 0x6F, 0xEE, 0x3F, 0x95, 0xBB, 0x87, 0x39, 0x93,
395 0x85, 0x87, 0x5D, 0x7E, 0x86, 0x74, 0x7E, 0x67, 0x6E, 0x72, 0x89, 0x38,
396 0xAC, 0xBF, 0xF7, 0x09, 0x8E, 0x05, 0xBE, 0x4D, 0xCF, 0xB2, 0x40, 0x52,
397 0xB8, 0x3A, 0xEF, 0xFB, 0x14, 0x78, 0x3F, 0x02, 0x9A, 0xDB, 0xDE, 0x7F,
398 0x53, 0xFA, 0xE9, 0x20, 0x84, 0x22, 0x40, 0x90, 0xE0, 0x07, 0xCE, 0xE9,
399 0x4D, 0x4B, 0xF2, 0xBA, 0xCE, 0x9F, 0xFD, 0x4B, 0x57, 0xD2, 0xAF, 0x7C,
400 0x72, 0x4D, 0x0C, 0xAA, 0x19, 0xBF, 0x05, 0x01, 0xF6, 0xF1, 0x7B, 0x4A,
401 0xA1, 0x0F, 0x42, 0x5E, 0x3E, 0xA7, 0x60, 0x80, 0xB4, 0xB9, 0xD6, 0xB3,
402 0xCE, 0xFE, 0xA1, 0x15, 0xB2, 0xCE, 0xB8, 0x78, 0x9B, 0xB8, 0xA3, 0xB0,
403 0xEA, 0x87, 0xFE, 0xBE, 0x63, 0xB6, 0xC8, 0xF8, 0x46, 0xEC, 0x6D, 0xB0,
404 0xC2, 0x6C, 0x5D, 0x7C};
405
David Benjamin66101182015-05-09 02:27:39 -0400406struct RFC5114TestData {
Adam Langley95c29f32014-06-20 12:00:00 -0700407 DH *(*get_param)(const ENGINE *engine);
David Benjamin66101182015-05-09 02:27:39 -0400408 const uint8_t *xA;
Adam Langley95c29f32014-06-20 12:00:00 -0700409 size_t xA_len;
David Benjamin66101182015-05-09 02:27:39 -0400410 const uint8_t *yA;
Adam Langley95c29f32014-06-20 12:00:00 -0700411 size_t yA_len;
David Benjamin66101182015-05-09 02:27:39 -0400412 const uint8_t *xB;
Adam Langley95c29f32014-06-20 12:00:00 -0700413 size_t xB_len;
David Benjamin66101182015-05-09 02:27:39 -0400414 const uint8_t *yB;
Adam Langley95c29f32014-06-20 12:00:00 -0700415 size_t yB_len;
David Benjamin66101182015-05-09 02:27:39 -0400416 const uint8_t *Z;
Adam Langley95c29f32014-06-20 12:00:00 -0700417 size_t Z_len;
David Benjamin66101182015-05-09 02:27:39 -0400418};
Adam Langley95c29f32014-06-20 12:00:00 -0700419
David Benjamin66101182015-05-09 02:27:39 -0400420#define MAKE_RFC5114_TEST_DATA(pre) \
Adam Langley95c29f32014-06-20 12:00:00 -0700421 { \
David Benjamin66101182015-05-09 02:27:39 -0400422 DH_get_##pre, kDHTest##pre##_xA, sizeof(kDHTest##pre##_xA), \
423 kDHTest##pre##_yA, sizeof(kDHTest##pre##_yA), kDHTest##pre##_xB, \
424 sizeof(kDHTest##pre##_xB), kDHTest##pre##_yB, \
425 sizeof(kDHTest##pre##_yB), kDHTest##pre##_Z, sizeof(kDHTest##pre##_Z) \
Adam Langley95c29f32014-06-20 12:00:00 -0700426 }
427
David Benjamin66101182015-05-09 02:27:39 -0400428static const RFC5114TestData kRFCTestData[] = {
429 MAKE_RFC5114_TEST_DATA(1024_160),
430 MAKE_RFC5114_TEST_DATA(2048_224),
431 MAKE_RFC5114_TEST_DATA(2048_256),
432 };
Adam Langley95c29f32014-06-20 12:00:00 -0700433
David Benjamin66101182015-05-09 02:27:39 -0400434static bool RunRFC5114Tests() {
435 for (unsigned i = 0; i < sizeof(kRFCTestData) / sizeof(RFC5114TestData); i++) {
436 const RFC5114TestData *td = kRFCTestData + i;
Adam Langley95c29f32014-06-20 12:00:00 -0700437 /* Set up DH structures setting key components */
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700438 bssl::UniquePtr<DH> dhA(td->get_param(nullptr));
439 bssl::UniquePtr<DH> dhB(td->get_param(nullptr));
David Benjaminc9a202f2015-02-11 01:16:26 -0500440 if (!dhA || !dhB) {
David Benjamin66101182015-05-09 02:27:39 -0400441 fprintf(stderr, "Initialisation error RFC5114 set %u\n", i + 1);
442 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500443 }
Adam Langley95c29f32014-06-20 12:00:00 -0700444
David Benjamin66101182015-05-09 02:27:39 -0400445 dhA->priv_key = BN_bin2bn(td->xA, td->xA_len, nullptr);
446 dhA->pub_key = BN_bin2bn(td->yA, td->yA_len, nullptr);
Adam Langley95c29f32014-06-20 12:00:00 -0700447
David Benjamin66101182015-05-09 02:27:39 -0400448 dhB->priv_key = BN_bin2bn(td->xB, td->xB_len, nullptr);
449 dhB->pub_key = BN_bin2bn(td->yB, td->yB_len, nullptr);
Adam Langley95c29f32014-06-20 12:00:00 -0700450
David Benjaminc9a202f2015-02-11 01:16:26 -0500451 if (!dhA->priv_key || !dhA->pub_key || !dhB->priv_key || !dhB->pub_key) {
David Benjamin66101182015-05-09 02:27:39 -0400452 fprintf(stderr, "BN_bin2bn error RFC5114 set %u\n", i + 1);
453 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500454 }
Adam Langley95c29f32014-06-20 12:00:00 -0700455
David Benjamin66101182015-05-09 02:27:39 -0400456 if ((td->Z_len != (size_t)DH_size(dhA.get())) ||
457 (td->Z_len != (size_t)DH_size(dhB.get()))) {
458 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500459 }
Adam Langley95c29f32014-06-20 12:00:00 -0700460
David Benjamin66101182015-05-09 02:27:39 -0400461 std::vector<uint8_t> Z1(DH_size(dhA.get()));
462 std::vector<uint8_t> Z2(DH_size(dhB.get()));
Adam Langley95c29f32014-06-20 12:00:00 -0700463 /* Work out shared secrets using both sides and compare
David Benjamin66101182015-05-09 02:27:39 -0400464 * with expected values. */
David Benjaminef14b2d2015-11-11 14:01:27 -0800465 int ret1 = DH_compute_key(Z1.data(), dhB->pub_key, dhA.get());
466 int ret2 = DH_compute_key(Z2.data(), dhA->pub_key, dhB.get());
David Benjamin66101182015-05-09 02:27:39 -0400467 if (ret1 < 0 || ret2 < 0) {
468 fprintf(stderr, "DH_compute_key error RFC5114 set %u\n", i + 1);
469 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500470 }
Adam Langley95c29f32014-06-20 12:00:00 -0700471
David Benjamin66101182015-05-09 02:27:39 -0400472 if (static_cast<size_t>(ret1) != td->Z_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500473 OPENSSL_memcmp(Z1.data(), td->Z, td->Z_len) != 0 ||
David Benjamin66101182015-05-09 02:27:39 -0400474 static_cast<size_t>(ret2) != td->Z_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500475 OPENSSL_memcmp(Z2.data(), td->Z, td->Z_len) != 0) {
David Benjamin66101182015-05-09 02:27:39 -0400476 fprintf(stderr, "Test failed RFC5114 set %u\n", i + 1);
477 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500478 }
Adam Langley95c29f32014-06-20 12:00:00 -0700479
David Benjamin66101182015-05-09 02:27:39 -0400480 printf("RFC5114 parameter test %u OK\n", i + 1);
Adam Langley95c29f32014-06-20 12:00:00 -0700481 }
482
Adam Langley95c29f32014-06-20 12:00:00 -0700483 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700484}
David Benjamin47ebec12016-01-28 14:57:35 -0500485
486// kRFC5114_2048_224BadY is a bad y-coordinate for RFC 5114's 2048-bit MODP
487// Group with 224-bit Prime Order Subgroup (section 2.2).
488static const uint8_t kRFC5114_2048_224BadY[] = {
489 0x45, 0x32, 0x5f, 0x51, 0x07, 0xe5, 0xdf, 0x1c, 0xd6, 0x02, 0x82, 0xb3,
490 0x32, 0x8f, 0xa4, 0x0f, 0x87, 0xb8, 0x41, 0xfe, 0xb9, 0x35, 0xde, 0xad,
491 0xc6, 0x26, 0x85, 0xb4, 0xff, 0x94, 0x8c, 0x12, 0x4c, 0xbf, 0x5b, 0x20,
492 0xc4, 0x46, 0xa3, 0x26, 0xeb, 0xa4, 0x25, 0xb7, 0x68, 0x8e, 0xcc, 0x67,
493 0xba, 0xea, 0x58, 0xd0, 0xf2, 0xe9, 0xd2, 0x24, 0x72, 0x60, 0xda, 0x88,
494 0x18, 0x9c, 0xe0, 0x31, 0x6a, 0xad, 0x50, 0x6d, 0x94, 0x35, 0x8b, 0x83,
495 0x4a, 0x6e, 0xfa, 0x48, 0x73, 0x0f, 0x83, 0x87, 0xff, 0x6b, 0x66, 0x1f,
496 0xa8, 0x82, 0xc6, 0x01, 0xe5, 0x80, 0xb5, 0xb0, 0x52, 0xd0, 0xe9, 0xd8,
497 0x72, 0xf9, 0x7d, 0x5b, 0x8b, 0xa5, 0x4c, 0xa5, 0x25, 0x95, 0x74, 0xe2,
498 0x7a, 0x61, 0x4e, 0xa7, 0x8f, 0x12, 0xe2, 0xd2, 0x9d, 0x8c, 0x02, 0x70,
499 0x34, 0x44, 0x32, 0xc7, 0xb2, 0xf3, 0xb9, 0xfe, 0x17, 0x2b, 0xd6, 0x1f,
500 0x8b, 0x7e, 0x4a, 0xfa, 0xa3, 0xb5, 0x3e, 0x7a, 0x81, 0x9a, 0x33, 0x66,
501 0x62, 0xa4, 0x50, 0x18, 0x3e, 0xa2, 0x5f, 0x00, 0x07, 0xd8, 0x9b, 0x22,
502 0xe4, 0xec, 0x84, 0xd5, 0xeb, 0x5a, 0xf3, 0x2a, 0x31, 0x23, 0xd8, 0x44,
503 0x22, 0x2a, 0x8b, 0x37, 0x44, 0xcc, 0xc6, 0x87, 0x4b, 0xbe, 0x50, 0x9d,
504 0x4a, 0xc4, 0x8e, 0x45, 0xcf, 0x72, 0x4d, 0xc0, 0x89, 0xb3, 0x72, 0xed,
505 0x33, 0x2c, 0xbc, 0x7f, 0x16, 0x39, 0x3b, 0xeb, 0xd2, 0xdd, 0xa8, 0x01,
506 0x73, 0x84, 0x62, 0xb9, 0x29, 0xd2, 0xc9, 0x51, 0x32, 0x9e, 0x7a, 0x6a,
507 0xcf, 0xc1, 0x0a, 0xdb, 0x0e, 0xe0, 0x62, 0x77, 0x6f, 0x59, 0x62, 0x72,
508 0x5a, 0x69, 0xa6, 0x5b, 0x70, 0xca, 0x65, 0xc4, 0x95, 0x6f, 0x9a, 0xc2,
509 0xdf, 0x72, 0x6d, 0xb1, 0x1e, 0x54, 0x7b, 0x51, 0xb4, 0xef, 0x7f, 0x89,
510 0x93, 0x74, 0x89, 0x59,
511};
512
513static bool TestBadY() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700514 bssl::UniquePtr<DH> dh(DH_get_2048_224(nullptr));
515 bssl::UniquePtr<BIGNUM> pub_key(
David Benjamin47ebec12016-01-28 14:57:35 -0500516 BN_bin2bn(kRFC5114_2048_224BadY, sizeof(kRFC5114_2048_224BadY), nullptr));
517 if (!dh || !pub_key || !DH_generate_key(dh.get())) {
518 return false;
519 }
520
521 int flags;
522 if (!DH_check_pub_key(dh.get(), pub_key.get(), &flags)) {
523 return false;
524 }
525 if (!(flags & DH_CHECK_PUBKEY_INVALID)) {
526 fprintf(stderr, "DH_check_pub_key did not reject the key.\n");
527 return false;
528 }
529
530 std::vector<uint8_t> result(DH_size(dh.get()));
531 if (DH_compute_key(result.data(), pub_key.get(), dh.get()) >= 0) {
532 fprintf(stderr, "DH_compute_key unexpectedly succeeded.\n");
533 return false;
534 }
535 ERR_clear_error();
536
537 return true;
538}
David Benjamin34733152016-05-07 17:40:02 -0400539
540static bool BIGNUMEqualsHex(const BIGNUM *bn, const char *hex) {
541 BIGNUM *hex_bn = NULL;
542 if (!BN_hex2bn(&hex_bn, hex)) {
543 return false;
544 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700545 bssl::UniquePtr<BIGNUM> free_hex_bn(hex_bn);
David Benjamin34733152016-05-07 17:40:02 -0400546 return BN_cmp(bn, hex_bn) == 0;
547}
548
549static bool TestASN1() {
550 // kParams are a set of Diffie-Hellman parameters generated with
551 // openssl dhparam 256
552 static const uint8_t kParams[] = {
553 0x30, 0x26, 0x02, 0x21, 0x00, 0xd7, 0x20, 0x34, 0xa3, 0x27,
554 0x4f, 0xdf, 0xbf, 0x04, 0xfd, 0x24, 0x68, 0x25, 0xb6, 0x56,
555 0xd8, 0xab, 0x2a, 0x41, 0x2d, 0x74, 0x0a, 0x52, 0x08, 0x7c,
556 0x40, 0x71, 0x4e, 0xd2, 0x57, 0x93, 0x13, 0x02, 0x01, 0x02,
557 };
558
559 CBS cbs;
560 CBS_init(&cbs, kParams, sizeof(kParams));
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700561 bssl::UniquePtr<DH> dh(DH_parse_parameters(&cbs));
David Benjamin34733152016-05-07 17:40:02 -0400562 if (!dh || CBS_len(&cbs) != 0 ||
563 !BIGNUMEqualsHex(
564 dh->p,
565 "d72034a3274fdfbf04fd246825b656d8ab2a412d740a52087c40714ed2579313") ||
566 !BIGNUMEqualsHex(dh->g, "2") || dh->priv_length != 0) {
567 return false;
568 }
569
David Benjaminaac1e2d2016-12-06 22:35:41 -0500570 bssl::ScopedCBB cbb;
David Benjamin34733152016-05-07 17:40:02 -0400571 uint8_t *der;
572 size_t der_len;
573 if (!CBB_init(cbb.get(), 0) ||
574 !DH_marshal_parameters(cbb.get(), dh.get()) ||
575 !CBB_finish(cbb.get(), &der, &der_len)) {
576 return false;
577 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700578 bssl::UniquePtr<uint8_t> free_der(der);
David Benjamin17cf2cb2016-12-13 01:07:13 -0500579 if (der_len != sizeof(kParams) ||
580 OPENSSL_memcmp(der, kParams, der_len) != 0) {
David Benjamin34733152016-05-07 17:40:02 -0400581 return false;
582 }
583
584 // kParamsDSA are a set of Diffie-Hellman parameters generated with
585 // openssl dhparam 256 -dsaparam
586 static const uint8_t kParamsDSA[] = {
587 0x30, 0x81, 0x89, 0x02, 0x41, 0x00, 0x93, 0xf3, 0xc1, 0x18, 0x01, 0xe6,
588 0x62, 0xb6, 0xd1, 0x46, 0x9a, 0x2c, 0x72, 0xea, 0x31, 0xd9, 0x18, 0x10,
589 0x30, 0x28, 0x63, 0xe2, 0x34, 0x7d, 0x80, 0xca, 0xee, 0x82, 0x2b, 0x19,
590 0x3c, 0x19, 0xbb, 0x42, 0x83, 0x02, 0x70, 0xdd, 0xdb, 0x8c, 0x03, 0xab,
591 0xe9, 0x9c, 0xc4, 0x00, 0x4d, 0x70, 0x5f, 0x52, 0x03, 0x31, 0x2c, 0xa4,
592 0x67, 0x34, 0x51, 0x95, 0x2a, 0xac, 0x11, 0xe2, 0x6a, 0x55, 0x02, 0x40,
593 0x44, 0xc8, 0x10, 0x53, 0x44, 0x32, 0x31, 0x63, 0xd8, 0xd1, 0x8c, 0x75,
594 0xc8, 0x98, 0x53, 0x3b, 0x5b, 0x4a, 0x2a, 0x0a, 0x09, 0xe7, 0xd0, 0x3c,
595 0x53, 0x72, 0xa8, 0x6b, 0x70, 0x41, 0x9c, 0x26, 0x71, 0x44, 0xfc, 0x7f,
596 0x08, 0x75, 0xe1, 0x02, 0xab, 0x74, 0x41, 0xe8, 0x2a, 0x3d, 0x3c, 0x26,
597 0x33, 0x09, 0xe4, 0x8b, 0xb4, 0x41, 0xec, 0xa6, 0xa8, 0xba, 0x1a, 0x07,
598 0x8a, 0x77, 0xf5, 0x5f, 0x02, 0x02, 0x00, 0xa0,
599 };
600
601 CBS_init(&cbs, kParamsDSA, sizeof(kParamsDSA));
602 dh.reset(DH_parse_parameters(&cbs));
603 if (!dh || CBS_len(&cbs) != 0 ||
604 !BIGNUMEqualsHex(dh->p,
605 "93f3c11801e662b6d1469a2c72ea31d91810302863e2347d80caee8"
606 "22b193c19bb42830270dddb8c03abe99cc4004d705f5203312ca467"
607 "3451952aac11e26a55") ||
608 !BIGNUMEqualsHex(dh->g,
609 "44c8105344323163d8d18c75c898533b5b4a2a0a09e7d03c5372a86"
610 "b70419c267144fc7f0875e102ab7441e82a3d3c263309e48bb441ec"
611 "a6a8ba1a078a77f55f") ||
612 dh->priv_length != 160) {
613 return false;
614 }
615
616 if (!CBB_init(cbb.get(), 0) ||
617 !DH_marshal_parameters(cbb.get(), dh.get()) ||
618 !CBB_finish(cbb.get(), &der, &der_len)) {
619 return false;
620 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700621 bssl::UniquePtr<uint8_t> free_der2(der);
David Benjamin17cf2cb2016-12-13 01:07:13 -0500622 if (der_len != sizeof(kParamsDSA) ||
623 OPENSSL_memcmp(der, kParamsDSA, der_len) != 0) {
David Benjamin34733152016-05-07 17:40:02 -0400624 return false;
625 }
626
627 return true;
628}
David Benjamin96e1a252016-08-10 13:38:51 -0400629
630static bool TestRFC3526() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700631 bssl::UniquePtr<BIGNUM> bn(BN_get_rfc3526_prime_1536(nullptr));
David Benjamin96e1a252016-08-10 13:38:51 -0400632 if (!bn) {
633 return false;
634 }
635
636 static const uint8_t kPrime1536[] = {
637 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2,
638 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1,
639 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6,
640 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd,
641 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d,
642 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45,
643 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xf4, 0x4c, 0x42, 0xe9,
644 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed,
645 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11,
646 0x7c, 0x4b, 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51, 0xec, 0xe4, 0x5b, 0x3d,
647 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05, 0x98, 0xda, 0x48, 0x36,
648 0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8, 0xfd, 0x24, 0xcf, 0x5f,
649 0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96, 0x1c, 0x62, 0xf3, 0x56,
650 0x20, 0x85, 0x52, 0xbb, 0x9e, 0xd5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6d,
651 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04, 0xf1, 0x74, 0x6c, 0x08,
652 0xca, 0x23, 0x73, 0x27, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
653 };
654
655 uint8_t buffer[sizeof(kPrime1536)];
656 if (BN_num_bytes(bn.get()) != sizeof(kPrime1536) ||
657 BN_bn2bin(bn.get(), buffer) != sizeof(kPrime1536) ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500658 OPENSSL_memcmp(buffer, kPrime1536, sizeof(kPrime1536)) != 0) {
David Benjamin96e1a252016-08-10 13:38:51 -0400659 fprintf(stderr, "1536-bit MODP prime did not match.\n");
660 return false;
661 }
662
663 return true;
664}