blob: e08664fad2aefc298270e27a19241595450d5503 [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()) {
David Benjamin96628432017-01-19 19:05:47 -050089 ADD_FAILURE() << "Tests failed.";
Adam Langley10f97f32016-07-12 08:09:33 -070090 }
Adam Langley10f97f32016-07-12 08:09:33 -070091}
David Benjamin66101182015-05-09 02:27:39 -040092
93static int GenerateCallback(int p, int n, BN_GENCB *arg) {
Adam Langley95c29f32014-06-20 12:00:00 -070094 char c = '*';
95
David Benjaminc9a202f2015-02-11 01:16:26 -050096 if (p == 0) {
Adam Langley95c29f32014-06-20 12:00:00 -070097 c = '.';
David Benjaminc9a202f2015-02-11 01:16:26 -050098 } else if (p == 1) {
Adam Langley95c29f32014-06-20 12:00:00 -070099 c = '+';
David Benjaminc9a202f2015-02-11 01:16:26 -0500100 } else if (p == 2) {
Adam Langley95c29f32014-06-20 12:00:00 -0700101 c = '*';
David Benjaminc9a202f2015-02-11 01:16:26 -0500102 } else if (p == 3) {
Adam Langley95c29f32014-06-20 12:00:00 -0700103 c = '\n';
David Benjaminc9a202f2015-02-11 01:16:26 -0500104 }
David Benjamin66101182015-05-09 02:27:39 -0400105 FILE *out = reinterpret_cast<FILE*>(arg->arg);
106 fputc(c, out);
107 fflush(out);
Adam Langley95c29f32014-06-20 12:00:00 -0700108
109 return 1;
110}
111
David Benjamin66101182015-05-09 02:27:39 -0400112static bool RunBasicTests() {
113 BN_GENCB cb;
114 BN_GENCB_set(&cb, &GenerateCallback, stdout);
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700115 bssl::UniquePtr<DH> a(DH_new());
David Benjamin66101182015-05-09 02:27:39 -0400116 if (!a || !DH_generate_parameters_ex(a.get(), 64, DH_GENERATOR_5, &cb)) {
117 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700118 }
119
David Benjamin66101182015-05-09 02:27:39 -0400120 int check_result;
121 if (!DH_check(a.get(), &check_result)) {
122 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500123 }
David Benjamin66101182015-05-09 02:27:39 -0400124 if (check_result & DH_CHECK_P_NOT_PRIME) {
125 printf("p value is not prime\n");
David Benjaminc9a202f2015-02-11 01:16:26 -0500126 }
David Benjamin66101182015-05-09 02:27:39 -0400127 if (check_result & DH_CHECK_P_NOT_SAFE_PRIME) {
128 printf("p value is not a safe prime\n");
David Benjaminc9a202f2015-02-11 01:16:26 -0500129 }
David Benjamin66101182015-05-09 02:27:39 -0400130 if (check_result & DH_CHECK_UNABLE_TO_CHECK_GENERATOR) {
131 printf("unable to check the generator value\n");
David Benjaminc9a202f2015-02-11 01:16:26 -0500132 }
David Benjamin66101182015-05-09 02:27:39 -0400133 if (check_result & DH_CHECK_NOT_SUITABLE_GENERATOR) {
134 printf("the g value is not a generator\n");
David Benjaminc9a202f2015-02-11 01:16:26 -0500135 }
Adam Langley95c29f32014-06-20 12:00:00 -0700136
David Benjamin66101182015-05-09 02:27:39 -0400137 printf("\np = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800138 BN_print_fp(stdout, a->p);
David Benjamin66101182015-05-09 02:27:39 -0400139 printf("\ng = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800140 BN_print_fp(stdout, a->g);
David Benjamin66101182015-05-09 02:27:39 -0400141 printf("\n");
Adam Langley95c29f32014-06-20 12:00:00 -0700142
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700143 bssl::UniquePtr<DH> b(DH_new());
David Benjamin66101182015-05-09 02:27:39 -0400144 if (!b) {
145 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700146 }
147
148 b->p = BN_dup(a->p);
149 b->g = BN_dup(a->g);
David Benjamin66101182015-05-09 02:27:39 -0400150 if (b->p == nullptr || b->g == nullptr) {
151 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700152 }
153
David Benjamin66101182015-05-09 02:27:39 -0400154 if (!DH_generate_key(a.get())) {
155 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500156 }
David Benjamin66101182015-05-09 02:27:39 -0400157 printf("pri1 = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800158 BN_print_fp(stdout, a->priv_key);
David Benjamin66101182015-05-09 02:27:39 -0400159 printf("\npub1 = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800160 BN_print_fp(stdout, a->pub_key);
David Benjamin66101182015-05-09 02:27:39 -0400161 printf("\n");
Adam Langley95c29f32014-06-20 12:00:00 -0700162
David Benjamin66101182015-05-09 02:27:39 -0400163 if (!DH_generate_key(b.get())) {
164 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500165 }
David Benjamin66101182015-05-09 02:27:39 -0400166 printf("pri2 = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800167 BN_print_fp(stdout, b->priv_key);
David Benjamin66101182015-05-09 02:27:39 -0400168 printf("\npub2 = ");
Brian Smith9da82c12015-03-12 11:36:41 +0800169 BN_print_fp(stdout, b->pub_key);
David Benjamin66101182015-05-09 02:27:39 -0400170 printf("\n");
Adam Langley95c29f32014-06-20 12:00:00 -0700171
David Benjamin66101182015-05-09 02:27:39 -0400172 std::vector<uint8_t> key1(DH_size(a.get()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800173 int ret = DH_compute_key(key1.data(), b->pub_key, a.get());
David Benjamin66101182015-05-09 02:27:39 -0400174 if (ret < 0) {
175 return false;
Adam Langley95c29f32014-06-20 12:00:00 -0700176 }
David Benjamin66101182015-05-09 02:27:39 -0400177 key1.resize(ret);
Adam Langley95c29f32014-06-20 12:00:00 -0700178
David Benjamin66101182015-05-09 02:27:39 -0400179 printf("key1 = ");
180 for (size_t i = 0; i < key1.size(); i++) {
181 printf("%02x", key1[i]);
Adam Langley95c29f32014-06-20 12:00:00 -0700182 }
David Benjamin66101182015-05-09 02:27:39 -0400183 printf("\n");
184
185 std::vector<uint8_t> key2(DH_size(b.get()));
David Benjaminef14b2d2015-11-11 14:01:27 -0800186 ret = DH_compute_key(key2.data(), a->pub_key, b.get());
David Benjamin66101182015-05-09 02:27:39 -0400187 if (ret < 0) {
188 return false;
189 }
190 key2.resize(ret);
191
192 printf("key2 = ");
193 for (size_t i = 0; i < key2.size(); i++) {
194 printf("%02x", key2[i]);
195 }
196 printf("\n");
197
198 if (key1.size() < 4 || key1 != key2) {
Adam Langley95c29f32014-06-20 12:00:00 -0700199 fprintf(stderr, "Error in DH routines\n");
David Benjamin66101182015-05-09 02:27:39 -0400200 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500201 }
Adam Langley95c29f32014-06-20 12:00:00 -0700202
David Benjamin66101182015-05-09 02:27:39 -0400203 return true;
Adam Langley95c29f32014-06-20 12:00:00 -0700204}
205
206/* Test data from RFC 5114 */
207
David Benjamin66101182015-05-09 02:27:39 -0400208static const uint8_t kDHTest1024_160_xA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700209 0xB9, 0xA3, 0xB3, 0xAE, 0x8F, 0xEF, 0xC1, 0xA2, 0x93, 0x04,
210 0x96, 0x50, 0x70, 0x86, 0xF8, 0x45, 0x5D, 0x48, 0x94, 0x3E};
David Benjamin66101182015-05-09 02:27:39 -0400211static const uint8_t kDHTest1024_160_yA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700212 0x2A, 0x85, 0x3B, 0x3D, 0x92, 0x19, 0x75, 0x01, 0xB9, 0x01, 0x5B, 0x2D,
213 0xEB, 0x3E, 0xD8, 0x4F, 0x5E, 0x02, 0x1D, 0xCC, 0x3E, 0x52, 0xF1, 0x09,
214 0xD3, 0x27, 0x3D, 0x2B, 0x75, 0x21, 0x28, 0x1C, 0xBA, 0xBE, 0x0E, 0x76,
215 0xFF, 0x57, 0x27, 0xFA, 0x8A, 0xCC, 0xE2, 0x69, 0x56, 0xBA, 0x9A, 0x1F,
216 0xCA, 0x26, 0xF2, 0x02, 0x28, 0xD8, 0x69, 0x3F, 0xEB, 0x10, 0x84, 0x1D,
217 0x84, 0xA7, 0x36, 0x00, 0x54, 0xEC, 0xE5, 0xA7, 0xF5, 0xB7, 0xA6, 0x1A,
218 0xD3, 0xDF, 0xB3, 0xC6, 0x0D, 0x2E, 0x43, 0x10, 0x6D, 0x87, 0x27, 0xDA,
219 0x37, 0xDF, 0x9C, 0xCE, 0x95, 0xB4, 0x78, 0x75, 0x5D, 0x06, 0xBC, 0xEA,
220 0x8F, 0x9D, 0x45, 0x96, 0x5F, 0x75, 0xA5, 0xF3, 0xD1, 0xDF, 0x37, 0x01,
221 0x16, 0x5F, 0xC9, 0xE5, 0x0C, 0x42, 0x79, 0xCE, 0xB0, 0x7F, 0x98, 0x95,
222 0x40, 0xAE, 0x96, 0xD5, 0xD8, 0x8E, 0xD7, 0x76};
David Benjamin66101182015-05-09 02:27:39 -0400223static const uint8_t kDHTest1024_160_xB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700224 0x93, 0x92, 0xC9, 0xF9, 0xEB, 0x6A, 0x7A, 0x6A, 0x90, 0x22,
225 0xF7, 0xD8, 0x3E, 0x72, 0x23, 0xC6, 0x83, 0x5B, 0xBD, 0xDA};
David Benjamin66101182015-05-09 02:27:39 -0400226static const uint8_t kDHTest1024_160_yB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700227 0x71, 0x7A, 0x6C, 0xB0, 0x53, 0x37, 0x1F, 0xF4, 0xA3, 0xB9, 0x32, 0x94,
228 0x1C, 0x1E, 0x56, 0x63, 0xF8, 0x61, 0xA1, 0xD6, 0xAD, 0x34, 0xAE, 0x66,
229 0x57, 0x6D, 0xFB, 0x98, 0xF6, 0xC6, 0xCB, 0xF9, 0xDD, 0xD5, 0xA5, 0x6C,
230 0x78, 0x33, 0xF6, 0xBC, 0xFD, 0xFF, 0x09, 0x55, 0x82, 0xAD, 0x86, 0x8E,
231 0x44, 0x0E, 0x8D, 0x09, 0xFD, 0x76, 0x9E, 0x3C, 0xEC, 0xCD, 0xC3, 0xD3,
232 0xB1, 0xE4, 0xCF, 0xA0, 0x57, 0x77, 0x6C, 0xAA, 0xF9, 0x73, 0x9B, 0x6A,
233 0x9F, 0xEE, 0x8E, 0x74, 0x11, 0xF8, 0xD6, 0xDA, 0xC0, 0x9D, 0x6A, 0x4E,
234 0xDB, 0x46, 0xCC, 0x2B, 0x5D, 0x52, 0x03, 0x09, 0x0E, 0xAE, 0x61, 0x26,
235 0x31, 0x1E, 0x53, 0xFD, 0x2C, 0x14, 0xB5, 0x74, 0xE6, 0xA3, 0x10, 0x9A,
236 0x3D, 0xA1, 0xBE, 0x41, 0xBD, 0xCE, 0xAA, 0x18, 0x6F, 0x5C, 0xE0, 0x67,
237 0x16, 0xA2, 0xB6, 0xA0, 0x7B, 0x3C, 0x33, 0xFE};
David Benjamin66101182015-05-09 02:27:39 -0400238static const uint8_t kDHTest1024_160_Z[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700239 0x5C, 0x80, 0x4F, 0x45, 0x4D, 0x30, 0xD9, 0xC4, 0xDF, 0x85, 0x27, 0x1F,
240 0x93, 0x52, 0x8C, 0x91, 0xDF, 0x6B, 0x48, 0xAB, 0x5F, 0x80, 0xB3, 0xB5,
241 0x9C, 0xAA, 0xC1, 0xB2, 0x8F, 0x8A, 0xCB, 0xA9, 0xCD, 0x3E, 0x39, 0xF3,
242 0xCB, 0x61, 0x45, 0x25, 0xD9, 0x52, 0x1D, 0x2E, 0x64, 0x4C, 0x53, 0xB8,
243 0x07, 0xB8, 0x10, 0xF3, 0x40, 0x06, 0x2F, 0x25, 0x7D, 0x7D, 0x6F, 0xBF,
244 0xE8, 0xD5, 0xE8, 0xF0, 0x72, 0xE9, 0xB6, 0xE9, 0xAF, 0xDA, 0x94, 0x13,
245 0xEA, 0xFB, 0x2E, 0x8B, 0x06, 0x99, 0xB1, 0xFB, 0x5A, 0x0C, 0xAC, 0xED,
246 0xDE, 0xAE, 0xAD, 0x7E, 0x9C, 0xFB, 0xB3, 0x6A, 0xE2, 0xB4, 0x20, 0x83,
247 0x5B, 0xD8, 0x3A, 0x19, 0xFB, 0x0B, 0x5E, 0x96, 0xBF, 0x8F, 0xA4, 0xD0,
248 0x9E, 0x34, 0x55, 0x25, 0x16, 0x7E, 0xCD, 0x91, 0x55, 0x41, 0x6F, 0x46,
249 0xF4, 0x08, 0xED, 0x31, 0xB6, 0x3C, 0x6E, 0x6D};
David Benjamin66101182015-05-09 02:27:39 -0400250static const uint8_t kDHTest2048_224_xA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700251 0x22, 0xE6, 0x26, 0x01, 0xDB, 0xFF, 0xD0, 0x67, 0x08, 0xA6,
252 0x80, 0xF7, 0x47, 0xF3, 0x61, 0xF7, 0x6D, 0x8F, 0x4F, 0x72,
253 0x1A, 0x05, 0x48, 0xE4, 0x83, 0x29, 0x4B, 0x0C};
David Benjamin66101182015-05-09 02:27:39 -0400254static const uint8_t kDHTest2048_224_yA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700255 0x1B, 0x3A, 0x63, 0x45, 0x1B, 0xD8, 0x86, 0xE6, 0x99, 0xE6, 0x7B, 0x49,
256 0x4E, 0x28, 0x8B, 0xD7, 0xF8, 0xE0, 0xD3, 0x70, 0xBA, 0xDD, 0xA7, 0xA0,
257 0xEF, 0xD2, 0xFD, 0xE7, 0xD8, 0xF6, 0x61, 0x45, 0xCC, 0x9F, 0x28, 0x04,
258 0x19, 0x97, 0x5E, 0xB8, 0x08, 0x87, 0x7C, 0x8A, 0x4C, 0x0C, 0x8E, 0x0B,
259 0xD4, 0x8D, 0x4A, 0x54, 0x01, 0xEB, 0x1E, 0x87, 0x76, 0xBF, 0xEE, 0xE1,
260 0x34, 0xC0, 0x38, 0x31, 0xAC, 0x27, 0x3C, 0xD9, 0xD6, 0x35, 0xAB, 0x0C,
261 0xE0, 0x06, 0xA4, 0x2A, 0x88, 0x7E, 0x3F, 0x52, 0xFB, 0x87, 0x66, 0xB6,
262 0x50, 0xF3, 0x80, 0x78, 0xBC, 0x8E, 0xE8, 0x58, 0x0C, 0xEF, 0xE2, 0x43,
263 0x96, 0x8C, 0xFC, 0x4F, 0x8D, 0xC3, 0xDB, 0x08, 0x45, 0x54, 0x17, 0x1D,
264 0x41, 0xBF, 0x2E, 0x86, 0x1B, 0x7B, 0xB4, 0xD6, 0x9D, 0xD0, 0xE0, 0x1E,
265 0xA3, 0x87, 0xCB, 0xAA, 0x5C, 0xA6, 0x72, 0xAF, 0xCB, 0xE8, 0xBD, 0xB9,
266 0xD6, 0x2D, 0x4C, 0xE1, 0x5F, 0x17, 0xDD, 0x36, 0xF9, 0x1E, 0xD1, 0xEE,
267 0xDD, 0x65, 0xCA, 0x4A, 0x06, 0x45, 0x5C, 0xB9, 0x4C, 0xD4, 0x0A, 0x52,
268 0xEC, 0x36, 0x0E, 0x84, 0xB3, 0xC9, 0x26, 0xE2, 0x2C, 0x43, 0x80, 0xA3,
269 0xBF, 0x30, 0x9D, 0x56, 0x84, 0x97, 0x68, 0xB7, 0xF5, 0x2C, 0xFD, 0xF6,
270 0x55, 0xFD, 0x05, 0x3A, 0x7E, 0xF7, 0x06, 0x97, 0x9E, 0x7E, 0x58, 0x06,
271 0xB1, 0x7D, 0xFA, 0xE5, 0x3A, 0xD2, 0xA5, 0xBC, 0x56, 0x8E, 0xBB, 0x52,
272 0x9A, 0x7A, 0x61, 0xD6, 0x8D, 0x25, 0x6F, 0x8F, 0xC9, 0x7C, 0x07, 0x4A,
273 0x86, 0x1D, 0x82, 0x7E, 0x2E, 0xBC, 0x8C, 0x61, 0x34, 0x55, 0x31, 0x15,
274 0xB7, 0x0E, 0x71, 0x03, 0x92, 0x0A, 0xA1, 0x6D, 0x85, 0xE5, 0x2B, 0xCB,
275 0xAB, 0x8D, 0x78, 0x6A, 0x68, 0x17, 0x8F, 0xA8, 0xFF, 0x7C, 0x2F, 0x5C,
276 0x71, 0x64, 0x8D, 0x6F};
David Benjamin66101182015-05-09 02:27:39 -0400277static const uint8_t kDHTest2048_224_xB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700278 0x4F, 0xF3, 0xBC, 0x96, 0xC7, 0xFC, 0x6A, 0x6D, 0x71, 0xD3,
279 0xB3, 0x63, 0x80, 0x0A, 0x7C, 0xDF, 0xEF, 0x6F, 0xC4, 0x1B,
280 0x44, 0x17, 0xEA, 0x15, 0x35, 0x3B, 0x75, 0x90};
David Benjamin66101182015-05-09 02:27:39 -0400281static const uint8_t kDHTest2048_224_yB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700282 0x4D, 0xCE, 0xE9, 0x92, 0xA9, 0x76, 0x2A, 0x13, 0xF2, 0xF8, 0x38, 0x44,
283 0xAD, 0x3D, 0x77, 0xEE, 0x0E, 0x31, 0xC9, 0x71, 0x8B, 0x3D, 0xB6, 0xC2,
284 0x03, 0x5D, 0x39, 0x61, 0x18, 0x2C, 0x3E, 0x0B, 0xA2, 0x47, 0xEC, 0x41,
285 0x82, 0xD7, 0x60, 0xCD, 0x48, 0xD9, 0x95, 0x99, 0x97, 0x06, 0x22, 0xA1,
286 0x88, 0x1B, 0xBA, 0x2D, 0xC8, 0x22, 0x93, 0x9C, 0x78, 0xC3, 0x91, 0x2C,
287 0x66, 0x61, 0xFA, 0x54, 0x38, 0xB2, 0x07, 0x66, 0x22, 0x2B, 0x75, 0xE2,
288 0x4C, 0x2E, 0x3A, 0xD0, 0xC7, 0x28, 0x72, 0x36, 0x12, 0x95, 0x25, 0xEE,
289 0x15, 0xB5, 0xDD, 0x79, 0x98, 0xAA, 0x04, 0xC4, 0xA9, 0x69, 0x6C, 0xAC,
290 0xD7, 0x17, 0x20, 0x83, 0xA9, 0x7A, 0x81, 0x66, 0x4E, 0xAD, 0x2C, 0x47,
291 0x9E, 0x44, 0x4E, 0x4C, 0x06, 0x54, 0xCC, 0x19, 0xE2, 0x8D, 0x77, 0x03,
292 0xCE, 0xE8, 0xDA, 0xCD, 0x61, 0x26, 0xF5, 0xD6, 0x65, 0xEC, 0x52, 0xC6,
293 0x72, 0x55, 0xDB, 0x92, 0x01, 0x4B, 0x03, 0x7E, 0xB6, 0x21, 0xA2, 0xAC,
294 0x8E, 0x36, 0x5D, 0xE0, 0x71, 0xFF, 0xC1, 0x40, 0x0A, 0xCF, 0x07, 0x7A,
295 0x12, 0x91, 0x3D, 0xD8, 0xDE, 0x89, 0x47, 0x34, 0x37, 0xAB, 0x7B, 0xA3,
296 0x46, 0x74, 0x3C, 0x1B, 0x21, 0x5D, 0xD9, 0xC1, 0x21, 0x64, 0xA7, 0xE4,
297 0x05, 0x31, 0x18, 0xD1, 0x99, 0xBE, 0xC8, 0xEF, 0x6F, 0xC5, 0x61, 0x17,
298 0x0C, 0x84, 0xC8, 0x7D, 0x10, 0xEE, 0x9A, 0x67, 0x4A, 0x1F, 0xA8, 0xFF,
299 0xE1, 0x3B, 0xDF, 0xBA, 0x1D, 0x44, 0xDE, 0x48, 0x94, 0x6D, 0x68, 0xDC,
300 0x0C, 0xDD, 0x77, 0x76, 0x35, 0xA7, 0xAB, 0x5B, 0xFB, 0x1E, 0x4B, 0xB7,
301 0xB8, 0x56, 0xF9, 0x68, 0x27, 0x73, 0x4C, 0x18, 0x41, 0x38, 0xE9, 0x15,
302 0xD9, 0xC3, 0x00, 0x2E, 0xBC, 0xE5, 0x31, 0x20, 0x54, 0x6A, 0x7E, 0x20,
303 0x02, 0x14, 0x2B, 0x6C};
David Benjamin66101182015-05-09 02:27:39 -0400304static const uint8_t kDHTest2048_224_Z[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700305 0x34, 0xD9, 0xBD, 0xDC, 0x1B, 0x42, 0x17, 0x6C, 0x31, 0x3F, 0xEA, 0x03,
306 0x4C, 0x21, 0x03, 0x4D, 0x07, 0x4A, 0x63, 0x13, 0xBB, 0x4E, 0xCD, 0xB3,
307 0x70, 0x3F, 0xFF, 0x42, 0x45, 0x67, 0xA4, 0x6B, 0xDF, 0x75, 0x53, 0x0E,
308 0xDE, 0x0A, 0x9D, 0xA5, 0x22, 0x9D, 0xE7, 0xD7, 0x67, 0x32, 0x28, 0x6C,
309 0xBC, 0x0F, 0x91, 0xDA, 0x4C, 0x3C, 0x85, 0x2F, 0xC0, 0x99, 0xC6, 0x79,
310 0x53, 0x1D, 0x94, 0xC7, 0x8A, 0xB0, 0x3D, 0x9D, 0xEC, 0xB0, 0xA4, 0xE4,
311 0xCA, 0x8B, 0x2B, 0xB4, 0x59, 0x1C, 0x40, 0x21, 0xCF, 0x8C, 0xE3, 0xA2,
312 0x0A, 0x54, 0x1D, 0x33, 0x99, 0x40, 0x17, 0xD0, 0x20, 0x0A, 0xE2, 0xC9,
313 0x51, 0x6E, 0x2F, 0xF5, 0x14, 0x57, 0x79, 0x26, 0x9E, 0x86, 0x2B, 0x0F,
314 0xB4, 0x74, 0xA2, 0xD5, 0x6D, 0xC3, 0x1E, 0xD5, 0x69, 0xA7, 0x70, 0x0B,
315 0x4C, 0x4A, 0xB1, 0x6B, 0x22, 0xA4, 0x55, 0x13, 0x53, 0x1E, 0xF5, 0x23,
316 0xD7, 0x12, 0x12, 0x07, 0x7B, 0x5A, 0x16, 0x9B, 0xDE, 0xFF, 0xAD, 0x7A,
317 0xD9, 0x60, 0x82, 0x84, 0xC7, 0x79, 0x5B, 0x6D, 0x5A, 0x51, 0x83, 0xB8,
318 0x70, 0x66, 0xDE, 0x17, 0xD8, 0xD6, 0x71, 0xC9, 0xEB, 0xD8, 0xEC, 0x89,
319 0x54, 0x4D, 0x45, 0xEC, 0x06, 0x15, 0x93, 0xD4, 0x42, 0xC6, 0x2A, 0xB9,
320 0xCE, 0x3B, 0x1C, 0xB9, 0x94, 0x3A, 0x1D, 0x23, 0xA5, 0xEA, 0x3B, 0xCF,
321 0x21, 0xA0, 0x14, 0x71, 0xE6, 0x7E, 0x00, 0x3E, 0x7F, 0x8A, 0x69, 0xC7,
322 0x28, 0xBE, 0x49, 0x0B, 0x2F, 0xC8, 0x8C, 0xFE, 0xB9, 0x2D, 0xB6, 0xA2,
323 0x15, 0xE5, 0xD0, 0x3C, 0x17, 0xC4, 0x64, 0xC9, 0xAC, 0x1A, 0x46, 0xE2,
324 0x03, 0xE1, 0x3F, 0x95, 0x29, 0x95, 0xFB, 0x03, 0xC6, 0x9D, 0x3C, 0xC4,
325 0x7F, 0xCB, 0x51, 0x0B, 0x69, 0x98, 0xFF, 0xD3, 0xAA, 0x6D, 0xE7, 0x3C,
326 0xF9, 0xF6, 0x38, 0x69};
David Benjamin66101182015-05-09 02:27:39 -0400327static const uint8_t kDHTest2048_256_xA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700328 0x08, 0x81, 0x38, 0x2C, 0xDB, 0x87, 0x66, 0x0C, 0x6D, 0xC1, 0x3E,
329 0x61, 0x49, 0x38, 0xD5, 0xB9, 0xC8, 0xB2, 0xF2, 0x48, 0x58, 0x1C,
330 0xC5, 0xE3, 0x1B, 0x35, 0x45, 0x43, 0x97, 0xFC, 0xE5, 0x0E};
David Benjamin66101182015-05-09 02:27:39 -0400331static const uint8_t kDHTest2048_256_yA[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700332 0x2E, 0x93, 0x80, 0xC8, 0x32, 0x3A, 0xF9, 0x75, 0x45, 0xBC, 0x49, 0x41,
333 0xDE, 0xB0, 0xEC, 0x37, 0x42, 0xC6, 0x2F, 0xE0, 0xEC, 0xE8, 0x24, 0xA6,
334 0xAB, 0xDB, 0xE6, 0x6C, 0x59, 0xBE, 0xE0, 0x24, 0x29, 0x11, 0xBF, 0xB9,
335 0x67, 0x23, 0x5C, 0xEB, 0xA3, 0x5A, 0xE1, 0x3E, 0x4E, 0xC7, 0x52, 0xBE,
336 0x63, 0x0B, 0x92, 0xDC, 0x4B, 0xDE, 0x28, 0x47, 0xA9, 0xC6, 0x2C, 0xB8,
337 0x15, 0x27, 0x45, 0x42, 0x1F, 0xB7, 0xEB, 0x60, 0xA6, 0x3C, 0x0F, 0xE9,
338 0x15, 0x9F, 0xCC, 0xE7, 0x26, 0xCE, 0x7C, 0xD8, 0x52, 0x3D, 0x74, 0x50,
339 0x66, 0x7E, 0xF8, 0x40, 0xE4, 0x91, 0x91, 0x21, 0xEB, 0x5F, 0x01, 0xC8,
340 0xC9, 0xB0, 0xD3, 0xD6, 0x48, 0xA9, 0x3B, 0xFB, 0x75, 0x68, 0x9E, 0x82,
341 0x44, 0xAC, 0x13, 0x4A, 0xF5, 0x44, 0x71, 0x1C, 0xE7, 0x9A, 0x02, 0xDC,
342 0xC3, 0x42, 0x26, 0x68, 0x47, 0x80, 0xDD, 0xDC, 0xB4, 0x98, 0x59, 0x41,
343 0x06, 0xC3, 0x7F, 0x5B, 0xC7, 0x98, 0x56, 0x48, 0x7A, 0xF5, 0xAB, 0x02,
344 0x2A, 0x2E, 0x5E, 0x42, 0xF0, 0x98, 0x97, 0xC1, 0xA8, 0x5A, 0x11, 0xEA,
345 0x02, 0x12, 0xAF, 0x04, 0xD9, 0xB4, 0xCE, 0xBC, 0x93, 0x7C, 0x3C, 0x1A,
346 0x3E, 0x15, 0xA8, 0xA0, 0x34, 0x2E, 0x33, 0x76, 0x15, 0xC8, 0x4E, 0x7F,
347 0xE3, 0xB8, 0xB9, 0xB8, 0x7F, 0xB1, 0xE7, 0x3A, 0x15, 0xAF, 0x12, 0xA3,
348 0x0D, 0x74, 0x6E, 0x06, 0xDF, 0xC3, 0x4F, 0x29, 0x0D, 0x79, 0x7C, 0xE5,
349 0x1A, 0xA1, 0x3A, 0xA7, 0x85, 0xBF, 0x66, 0x58, 0xAF, 0xF5, 0xE4, 0xB0,
350 0x93, 0x00, 0x3C, 0xBE, 0xAF, 0x66, 0x5B, 0x3C, 0x2E, 0x11, 0x3A, 0x3A,
351 0x4E, 0x90, 0x52, 0x69, 0x34, 0x1D, 0xC0, 0x71, 0x14, 0x26, 0x68, 0x5F,
352 0x4E, 0xF3, 0x7E, 0x86, 0x8A, 0x81, 0x26, 0xFF, 0x3F, 0x22, 0x79, 0xB5,
353 0x7C, 0xA6, 0x7E, 0x29};
David Benjamin66101182015-05-09 02:27:39 -0400354static const uint8_t kDHTest2048_256_xB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700355 0x7D, 0x62, 0xA7, 0xE3, 0xEF, 0x36, 0xDE, 0x61, 0x7B, 0x13, 0xD1,
356 0xAF, 0xB8, 0x2C, 0x78, 0x0D, 0x83, 0xA2, 0x3B, 0xD4, 0xEE, 0x67,
357 0x05, 0x64, 0x51, 0x21, 0xF3, 0x71, 0xF5, 0x46, 0xA5, 0x3D};
David Benjamin66101182015-05-09 02:27:39 -0400358static const uint8_t kDHTest2048_256_yB[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700359 0x57, 0x5F, 0x03, 0x51, 0xBD, 0x2B, 0x1B, 0x81, 0x74, 0x48, 0xBD, 0xF8,
360 0x7A, 0x6C, 0x36, 0x2C, 0x1E, 0x28, 0x9D, 0x39, 0x03, 0xA3, 0x0B, 0x98,
361 0x32, 0xC5, 0x74, 0x1F, 0xA2, 0x50, 0x36, 0x3E, 0x7A, 0xCB, 0xC7, 0xF7,
362 0x7F, 0x3D, 0xAC, 0xBC, 0x1F, 0x13, 0x1A, 0xDD, 0x8E, 0x03, 0x36, 0x7E,
363 0xFF, 0x8F, 0xBB, 0xB3, 0xE1, 0xC5, 0x78, 0x44, 0x24, 0x80, 0x9B, 0x25,
364 0xAF, 0xE4, 0xD2, 0x26, 0x2A, 0x1A, 0x6F, 0xD2, 0xFA, 0xB6, 0x41, 0x05,
365 0xCA, 0x30, 0xA6, 0x74, 0xE0, 0x7F, 0x78, 0x09, 0x85, 0x20, 0x88, 0x63,
366 0x2F, 0xC0, 0x49, 0x23, 0x37, 0x91, 0xAD, 0x4E, 0xDD, 0x08, 0x3A, 0x97,
367 0x8B, 0x88, 0x3E, 0xE6, 0x18, 0xBC, 0x5E, 0x0D, 0xD0, 0x47, 0x41, 0x5F,
368 0x2D, 0x95, 0xE6, 0x83, 0xCF, 0x14, 0x82, 0x6B, 0x5F, 0xBE, 0x10, 0xD3,
369 0xCE, 0x41, 0xC6, 0xC1, 0x20, 0xC7, 0x8A, 0xB2, 0x00, 0x08, 0xC6, 0x98,
370 0xBF, 0x7F, 0x0B, 0xCA, 0xB9, 0xD7, 0xF4, 0x07, 0xBE, 0xD0, 0xF4, 0x3A,
371 0xFB, 0x29, 0x70, 0xF5, 0x7F, 0x8D, 0x12, 0x04, 0x39, 0x63, 0xE6, 0x6D,
372 0xDD, 0x32, 0x0D, 0x59, 0x9A, 0xD9, 0x93, 0x6C, 0x8F, 0x44, 0x13, 0x7C,
373 0x08, 0xB1, 0x80, 0xEC, 0x5E, 0x98, 0x5C, 0xEB, 0xE1, 0x86, 0xF3, 0xD5,
374 0x49, 0x67, 0x7E, 0x80, 0x60, 0x73, 0x31, 0xEE, 0x17, 0xAF, 0x33, 0x80,
375 0xA7, 0x25, 0xB0, 0x78, 0x23, 0x17, 0xD7, 0xDD, 0x43, 0xF5, 0x9D, 0x7A,
376 0xF9, 0x56, 0x8A, 0x9B, 0xB6, 0x3A, 0x84, 0xD3, 0x65, 0xF9, 0x22, 0x44,
377 0xED, 0x12, 0x09, 0x88, 0x21, 0x93, 0x02, 0xF4, 0x29, 0x24, 0xC7, 0xCA,
378 0x90, 0xB8, 0x9D, 0x24, 0xF7, 0x1B, 0x0A, 0xB6, 0x97, 0x82, 0x3D, 0x7D,
379 0xEB, 0x1A, 0xFF, 0x5B, 0x0E, 0x8E, 0x4A, 0x45, 0xD4, 0x9F, 0x7F, 0x53,
380 0x75, 0x7E, 0x19, 0x13};
David Benjamin66101182015-05-09 02:27:39 -0400381static const uint8_t kDHTest2048_256_Z[] = {
Adam Langley95c29f32014-06-20 12:00:00 -0700382 0x86, 0xC7, 0x0B, 0xF8, 0xD0, 0xBB, 0x81, 0xBB, 0x01, 0x07, 0x8A, 0x17,
383 0x21, 0x9C, 0xB7, 0xD2, 0x72, 0x03, 0xDB, 0x2A, 0x19, 0xC8, 0x77, 0xF1,
384 0xD1, 0xF1, 0x9F, 0xD7, 0xD7, 0x7E, 0xF2, 0x25, 0x46, 0xA6, 0x8F, 0x00,
385 0x5A, 0xD5, 0x2D, 0xC8, 0x45, 0x53, 0xB7, 0x8F, 0xC6, 0x03, 0x30, 0xBE,
386 0x51, 0xEA, 0x7C, 0x06, 0x72, 0xCA, 0xC1, 0x51, 0x5E, 0x4B, 0x35, 0xC0,
387 0x47, 0xB9, 0xA5, 0x51, 0xB8, 0x8F, 0x39, 0xDC, 0x26, 0xDA, 0x14, 0xA0,
388 0x9E, 0xF7, 0x47, 0x74, 0xD4, 0x7C, 0x76, 0x2D, 0xD1, 0x77, 0xF9, 0xED,
389 0x5B, 0xC2, 0xF1, 0x1E, 0x52, 0xC8, 0x79, 0xBD, 0x95, 0x09, 0x85, 0x04,
390 0xCD, 0x9E, 0xEC, 0xD8, 0xA8, 0xF9, 0xB3, 0xEF, 0xBD, 0x1F, 0x00, 0x8A,
391 0xC5, 0x85, 0x30, 0x97, 0xD9, 0xD1, 0x83, 0x7F, 0x2B, 0x18, 0xF7, 0x7C,
392 0xD7, 0xBE, 0x01, 0xAF, 0x80, 0xA7, 0xC7, 0xB5, 0xEA, 0x3C, 0xA5, 0x4C,
393 0xC0, 0x2D, 0x0C, 0x11, 0x6F, 0xEE, 0x3F, 0x95, 0xBB, 0x87, 0x39, 0x93,
394 0x85, 0x87, 0x5D, 0x7E, 0x86, 0x74, 0x7E, 0x67, 0x6E, 0x72, 0x89, 0x38,
395 0xAC, 0xBF, 0xF7, 0x09, 0x8E, 0x05, 0xBE, 0x4D, 0xCF, 0xB2, 0x40, 0x52,
396 0xB8, 0x3A, 0xEF, 0xFB, 0x14, 0x78, 0x3F, 0x02, 0x9A, 0xDB, 0xDE, 0x7F,
397 0x53, 0xFA, 0xE9, 0x20, 0x84, 0x22, 0x40, 0x90, 0xE0, 0x07, 0xCE, 0xE9,
398 0x4D, 0x4B, 0xF2, 0xBA, 0xCE, 0x9F, 0xFD, 0x4B, 0x57, 0xD2, 0xAF, 0x7C,
399 0x72, 0x4D, 0x0C, 0xAA, 0x19, 0xBF, 0x05, 0x01, 0xF6, 0xF1, 0x7B, 0x4A,
400 0xA1, 0x0F, 0x42, 0x5E, 0x3E, 0xA7, 0x60, 0x80, 0xB4, 0xB9, 0xD6, 0xB3,
401 0xCE, 0xFE, 0xA1, 0x15, 0xB2, 0xCE, 0xB8, 0x78, 0x9B, 0xB8, 0xA3, 0xB0,
402 0xEA, 0x87, 0xFE, 0xBE, 0x63, 0xB6, 0xC8, 0xF8, 0x46, 0xEC, 0x6D, 0xB0,
403 0xC2, 0x6C, 0x5D, 0x7C};
404
David Benjamin66101182015-05-09 02:27:39 -0400405struct RFC5114TestData {
Adam Langley95c29f32014-06-20 12:00:00 -0700406 DH *(*get_param)(const ENGINE *engine);
David Benjamin66101182015-05-09 02:27:39 -0400407 const uint8_t *xA;
Adam Langley95c29f32014-06-20 12:00:00 -0700408 size_t xA_len;
David Benjamin66101182015-05-09 02:27:39 -0400409 const uint8_t *yA;
Adam Langley95c29f32014-06-20 12:00:00 -0700410 size_t yA_len;
David Benjamin66101182015-05-09 02:27:39 -0400411 const uint8_t *xB;
Adam Langley95c29f32014-06-20 12:00:00 -0700412 size_t xB_len;
David Benjamin66101182015-05-09 02:27:39 -0400413 const uint8_t *yB;
Adam Langley95c29f32014-06-20 12:00:00 -0700414 size_t yB_len;
David Benjamin66101182015-05-09 02:27:39 -0400415 const uint8_t *Z;
Adam Langley95c29f32014-06-20 12:00:00 -0700416 size_t Z_len;
David Benjamin66101182015-05-09 02:27:39 -0400417};
Adam Langley95c29f32014-06-20 12:00:00 -0700418
David Benjamin66101182015-05-09 02:27:39 -0400419#define MAKE_RFC5114_TEST_DATA(pre) \
Adam Langley95c29f32014-06-20 12:00:00 -0700420 { \
David Benjamin66101182015-05-09 02:27:39 -0400421 DH_get_##pre, kDHTest##pre##_xA, sizeof(kDHTest##pre##_xA), \
422 kDHTest##pre##_yA, sizeof(kDHTest##pre##_yA), kDHTest##pre##_xB, \
423 sizeof(kDHTest##pre##_xB), kDHTest##pre##_yB, \
424 sizeof(kDHTest##pre##_yB), kDHTest##pre##_Z, sizeof(kDHTest##pre##_Z) \
Adam Langley95c29f32014-06-20 12:00:00 -0700425 }
426
David Benjamin66101182015-05-09 02:27:39 -0400427static const RFC5114TestData kRFCTestData[] = {
428 MAKE_RFC5114_TEST_DATA(1024_160),
429 MAKE_RFC5114_TEST_DATA(2048_224),
430 MAKE_RFC5114_TEST_DATA(2048_256),
431 };
Adam Langley95c29f32014-06-20 12:00:00 -0700432
David Benjamin66101182015-05-09 02:27:39 -0400433static bool RunRFC5114Tests() {
434 for (unsigned i = 0; i < sizeof(kRFCTestData) / sizeof(RFC5114TestData); i++) {
435 const RFC5114TestData *td = kRFCTestData + i;
Adam Langley95c29f32014-06-20 12:00:00 -0700436 /* Set up DH structures setting key components */
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700437 bssl::UniquePtr<DH> dhA(td->get_param(nullptr));
438 bssl::UniquePtr<DH> dhB(td->get_param(nullptr));
David Benjaminc9a202f2015-02-11 01:16:26 -0500439 if (!dhA || !dhB) {
David Benjamin66101182015-05-09 02:27:39 -0400440 fprintf(stderr, "Initialisation error RFC5114 set %u\n", i + 1);
441 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500442 }
Adam Langley95c29f32014-06-20 12:00:00 -0700443
David Benjamin66101182015-05-09 02:27:39 -0400444 dhA->priv_key = BN_bin2bn(td->xA, td->xA_len, nullptr);
445 dhA->pub_key = BN_bin2bn(td->yA, td->yA_len, nullptr);
Adam Langley95c29f32014-06-20 12:00:00 -0700446
David Benjamin66101182015-05-09 02:27:39 -0400447 dhB->priv_key = BN_bin2bn(td->xB, td->xB_len, nullptr);
448 dhB->pub_key = BN_bin2bn(td->yB, td->yB_len, nullptr);
Adam Langley95c29f32014-06-20 12:00:00 -0700449
David Benjaminc9a202f2015-02-11 01:16:26 -0500450 if (!dhA->priv_key || !dhA->pub_key || !dhB->priv_key || !dhB->pub_key) {
David Benjamin66101182015-05-09 02:27:39 -0400451 fprintf(stderr, "BN_bin2bn error RFC5114 set %u\n", i + 1);
452 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500453 }
Adam Langley95c29f32014-06-20 12:00:00 -0700454
David Benjamin66101182015-05-09 02:27:39 -0400455 if ((td->Z_len != (size_t)DH_size(dhA.get())) ||
456 (td->Z_len != (size_t)DH_size(dhB.get()))) {
457 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500458 }
Adam Langley95c29f32014-06-20 12:00:00 -0700459
David Benjamin66101182015-05-09 02:27:39 -0400460 std::vector<uint8_t> Z1(DH_size(dhA.get()));
461 std::vector<uint8_t> Z2(DH_size(dhB.get()));
Adam Langley95c29f32014-06-20 12:00:00 -0700462 /* Work out shared secrets using both sides and compare
David Benjamin66101182015-05-09 02:27:39 -0400463 * with expected values. */
David Benjaminef14b2d2015-11-11 14:01:27 -0800464 int ret1 = DH_compute_key(Z1.data(), dhB->pub_key, dhA.get());
465 int ret2 = DH_compute_key(Z2.data(), dhA->pub_key, dhB.get());
David Benjamin66101182015-05-09 02:27:39 -0400466 if (ret1 < 0 || ret2 < 0) {
467 fprintf(stderr, "DH_compute_key error RFC5114 set %u\n", i + 1);
468 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500469 }
Adam Langley95c29f32014-06-20 12:00:00 -0700470
David Benjamin66101182015-05-09 02:27:39 -0400471 if (static_cast<size_t>(ret1) != td->Z_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500472 OPENSSL_memcmp(Z1.data(), td->Z, td->Z_len) != 0 ||
David Benjamin66101182015-05-09 02:27:39 -0400473 static_cast<size_t>(ret2) != td->Z_len ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500474 OPENSSL_memcmp(Z2.data(), td->Z, td->Z_len) != 0) {
David Benjamin66101182015-05-09 02:27:39 -0400475 fprintf(stderr, "Test failed RFC5114 set %u\n", i + 1);
476 return false;
David Benjaminc9a202f2015-02-11 01:16:26 -0500477 }
Adam Langley95c29f32014-06-20 12:00:00 -0700478
David Benjamin66101182015-05-09 02:27:39 -0400479 printf("RFC5114 parameter test %u OK\n", i + 1);
Adam Langley95c29f32014-06-20 12:00:00 -0700480 }
481
Adam Langley95c29f32014-06-20 12:00:00 -0700482 return 1;
Adam Langley95c29f32014-06-20 12:00:00 -0700483}
David Benjamin47ebec12016-01-28 14:57:35 -0500484
485// kRFC5114_2048_224BadY is a bad y-coordinate for RFC 5114's 2048-bit MODP
486// Group with 224-bit Prime Order Subgroup (section 2.2).
487static const uint8_t kRFC5114_2048_224BadY[] = {
488 0x45, 0x32, 0x5f, 0x51, 0x07, 0xe5, 0xdf, 0x1c, 0xd6, 0x02, 0x82, 0xb3,
489 0x32, 0x8f, 0xa4, 0x0f, 0x87, 0xb8, 0x41, 0xfe, 0xb9, 0x35, 0xde, 0xad,
490 0xc6, 0x26, 0x85, 0xb4, 0xff, 0x94, 0x8c, 0x12, 0x4c, 0xbf, 0x5b, 0x20,
491 0xc4, 0x46, 0xa3, 0x26, 0xeb, 0xa4, 0x25, 0xb7, 0x68, 0x8e, 0xcc, 0x67,
492 0xba, 0xea, 0x58, 0xd0, 0xf2, 0xe9, 0xd2, 0x24, 0x72, 0x60, 0xda, 0x88,
493 0x18, 0x9c, 0xe0, 0x31, 0x6a, 0xad, 0x50, 0x6d, 0x94, 0x35, 0x8b, 0x83,
494 0x4a, 0x6e, 0xfa, 0x48, 0x73, 0x0f, 0x83, 0x87, 0xff, 0x6b, 0x66, 0x1f,
495 0xa8, 0x82, 0xc6, 0x01, 0xe5, 0x80, 0xb5, 0xb0, 0x52, 0xd0, 0xe9, 0xd8,
496 0x72, 0xf9, 0x7d, 0x5b, 0x8b, 0xa5, 0x4c, 0xa5, 0x25, 0x95, 0x74, 0xe2,
497 0x7a, 0x61, 0x4e, 0xa7, 0x8f, 0x12, 0xe2, 0xd2, 0x9d, 0x8c, 0x02, 0x70,
498 0x34, 0x44, 0x32, 0xc7, 0xb2, 0xf3, 0xb9, 0xfe, 0x17, 0x2b, 0xd6, 0x1f,
499 0x8b, 0x7e, 0x4a, 0xfa, 0xa3, 0xb5, 0x3e, 0x7a, 0x81, 0x9a, 0x33, 0x66,
500 0x62, 0xa4, 0x50, 0x18, 0x3e, 0xa2, 0x5f, 0x00, 0x07, 0xd8, 0x9b, 0x22,
501 0xe4, 0xec, 0x84, 0xd5, 0xeb, 0x5a, 0xf3, 0x2a, 0x31, 0x23, 0xd8, 0x44,
502 0x22, 0x2a, 0x8b, 0x37, 0x44, 0xcc, 0xc6, 0x87, 0x4b, 0xbe, 0x50, 0x9d,
503 0x4a, 0xc4, 0x8e, 0x45, 0xcf, 0x72, 0x4d, 0xc0, 0x89, 0xb3, 0x72, 0xed,
504 0x33, 0x2c, 0xbc, 0x7f, 0x16, 0x39, 0x3b, 0xeb, 0xd2, 0xdd, 0xa8, 0x01,
505 0x73, 0x84, 0x62, 0xb9, 0x29, 0xd2, 0xc9, 0x51, 0x32, 0x9e, 0x7a, 0x6a,
506 0xcf, 0xc1, 0x0a, 0xdb, 0x0e, 0xe0, 0x62, 0x77, 0x6f, 0x59, 0x62, 0x72,
507 0x5a, 0x69, 0xa6, 0x5b, 0x70, 0xca, 0x65, 0xc4, 0x95, 0x6f, 0x9a, 0xc2,
508 0xdf, 0x72, 0x6d, 0xb1, 0x1e, 0x54, 0x7b, 0x51, 0xb4, 0xef, 0x7f, 0x89,
509 0x93, 0x74, 0x89, 0x59,
510};
511
512static bool TestBadY() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700513 bssl::UniquePtr<DH> dh(DH_get_2048_224(nullptr));
514 bssl::UniquePtr<BIGNUM> pub_key(
David Benjamin47ebec12016-01-28 14:57:35 -0500515 BN_bin2bn(kRFC5114_2048_224BadY, sizeof(kRFC5114_2048_224BadY), nullptr));
516 if (!dh || !pub_key || !DH_generate_key(dh.get())) {
517 return false;
518 }
519
520 int flags;
521 if (!DH_check_pub_key(dh.get(), pub_key.get(), &flags)) {
522 return false;
523 }
524 if (!(flags & DH_CHECK_PUBKEY_INVALID)) {
525 fprintf(stderr, "DH_check_pub_key did not reject the key.\n");
526 return false;
527 }
528
529 std::vector<uint8_t> result(DH_size(dh.get()));
530 if (DH_compute_key(result.data(), pub_key.get(), dh.get()) >= 0) {
531 fprintf(stderr, "DH_compute_key unexpectedly succeeded.\n");
532 return false;
533 }
534 ERR_clear_error();
535
536 return true;
537}
David Benjamin34733152016-05-07 17:40:02 -0400538
539static bool BIGNUMEqualsHex(const BIGNUM *bn, const char *hex) {
540 BIGNUM *hex_bn = NULL;
541 if (!BN_hex2bn(&hex_bn, hex)) {
542 return false;
543 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700544 bssl::UniquePtr<BIGNUM> free_hex_bn(hex_bn);
David Benjamin34733152016-05-07 17:40:02 -0400545 return BN_cmp(bn, hex_bn) == 0;
546}
547
548static bool TestASN1() {
549 // kParams are a set of Diffie-Hellman parameters generated with
550 // openssl dhparam 256
551 static const uint8_t kParams[] = {
552 0x30, 0x26, 0x02, 0x21, 0x00, 0xd7, 0x20, 0x34, 0xa3, 0x27,
553 0x4f, 0xdf, 0xbf, 0x04, 0xfd, 0x24, 0x68, 0x25, 0xb6, 0x56,
554 0xd8, 0xab, 0x2a, 0x41, 0x2d, 0x74, 0x0a, 0x52, 0x08, 0x7c,
555 0x40, 0x71, 0x4e, 0xd2, 0x57, 0x93, 0x13, 0x02, 0x01, 0x02,
556 };
557
558 CBS cbs;
559 CBS_init(&cbs, kParams, sizeof(kParams));
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700560 bssl::UniquePtr<DH> dh(DH_parse_parameters(&cbs));
David Benjamin34733152016-05-07 17:40:02 -0400561 if (!dh || CBS_len(&cbs) != 0 ||
562 !BIGNUMEqualsHex(
563 dh->p,
564 "d72034a3274fdfbf04fd246825b656d8ab2a412d740a52087c40714ed2579313") ||
565 !BIGNUMEqualsHex(dh->g, "2") || dh->priv_length != 0) {
566 return false;
567 }
568
David Benjaminaac1e2d2016-12-06 22:35:41 -0500569 bssl::ScopedCBB cbb;
David Benjamin34733152016-05-07 17:40:02 -0400570 uint8_t *der;
571 size_t der_len;
572 if (!CBB_init(cbb.get(), 0) ||
573 !DH_marshal_parameters(cbb.get(), dh.get()) ||
574 !CBB_finish(cbb.get(), &der, &der_len)) {
575 return false;
576 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700577 bssl::UniquePtr<uint8_t> free_der(der);
David Benjamin17cf2cb2016-12-13 01:07:13 -0500578 if (der_len != sizeof(kParams) ||
579 OPENSSL_memcmp(der, kParams, der_len) != 0) {
David Benjamin34733152016-05-07 17:40:02 -0400580 return false;
581 }
582
583 // kParamsDSA are a set of Diffie-Hellman parameters generated with
584 // openssl dhparam 256 -dsaparam
585 static const uint8_t kParamsDSA[] = {
586 0x30, 0x81, 0x89, 0x02, 0x41, 0x00, 0x93, 0xf3, 0xc1, 0x18, 0x01, 0xe6,
587 0x62, 0xb6, 0xd1, 0x46, 0x9a, 0x2c, 0x72, 0xea, 0x31, 0xd9, 0x18, 0x10,
588 0x30, 0x28, 0x63, 0xe2, 0x34, 0x7d, 0x80, 0xca, 0xee, 0x82, 0x2b, 0x19,
589 0x3c, 0x19, 0xbb, 0x42, 0x83, 0x02, 0x70, 0xdd, 0xdb, 0x8c, 0x03, 0xab,
590 0xe9, 0x9c, 0xc4, 0x00, 0x4d, 0x70, 0x5f, 0x52, 0x03, 0x31, 0x2c, 0xa4,
591 0x67, 0x34, 0x51, 0x95, 0x2a, 0xac, 0x11, 0xe2, 0x6a, 0x55, 0x02, 0x40,
592 0x44, 0xc8, 0x10, 0x53, 0x44, 0x32, 0x31, 0x63, 0xd8, 0xd1, 0x8c, 0x75,
593 0xc8, 0x98, 0x53, 0x3b, 0x5b, 0x4a, 0x2a, 0x0a, 0x09, 0xe7, 0xd0, 0x3c,
594 0x53, 0x72, 0xa8, 0x6b, 0x70, 0x41, 0x9c, 0x26, 0x71, 0x44, 0xfc, 0x7f,
595 0x08, 0x75, 0xe1, 0x02, 0xab, 0x74, 0x41, 0xe8, 0x2a, 0x3d, 0x3c, 0x26,
596 0x33, 0x09, 0xe4, 0x8b, 0xb4, 0x41, 0xec, 0xa6, 0xa8, 0xba, 0x1a, 0x07,
597 0x8a, 0x77, 0xf5, 0x5f, 0x02, 0x02, 0x00, 0xa0,
598 };
599
600 CBS_init(&cbs, kParamsDSA, sizeof(kParamsDSA));
601 dh.reset(DH_parse_parameters(&cbs));
602 if (!dh || CBS_len(&cbs) != 0 ||
603 !BIGNUMEqualsHex(dh->p,
604 "93f3c11801e662b6d1469a2c72ea31d91810302863e2347d80caee8"
605 "22b193c19bb42830270dddb8c03abe99cc4004d705f5203312ca467"
606 "3451952aac11e26a55") ||
607 !BIGNUMEqualsHex(dh->g,
608 "44c8105344323163d8d18c75c898533b5b4a2a0a09e7d03c5372a86"
609 "b70419c267144fc7f0875e102ab7441e82a3d3c263309e48bb441ec"
610 "a6a8ba1a078a77f55f") ||
611 dh->priv_length != 160) {
612 return false;
613 }
614
615 if (!CBB_init(cbb.get(), 0) ||
616 !DH_marshal_parameters(cbb.get(), dh.get()) ||
617 !CBB_finish(cbb.get(), &der, &der_len)) {
618 return false;
619 }
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700620 bssl::UniquePtr<uint8_t> free_der2(der);
David Benjamin17cf2cb2016-12-13 01:07:13 -0500621 if (der_len != sizeof(kParamsDSA) ||
622 OPENSSL_memcmp(der, kParamsDSA, der_len) != 0) {
David Benjamin34733152016-05-07 17:40:02 -0400623 return false;
624 }
625
626 return true;
627}
David Benjamin96e1a252016-08-10 13:38:51 -0400628
629static bool TestRFC3526() {
Matt Braithwaited17d74d2016-08-17 20:10:28 -0700630 bssl::UniquePtr<BIGNUM> bn(BN_get_rfc3526_prime_1536(nullptr));
David Benjamin96e1a252016-08-10 13:38:51 -0400631 if (!bn) {
632 return false;
633 }
634
635 static const uint8_t kPrime1536[] = {
636 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2,
637 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1,
638 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6,
639 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd,
640 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d,
641 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45,
642 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xf4, 0x4c, 0x42, 0xe9,
643 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed,
644 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11,
645 0x7c, 0x4b, 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51, 0xec, 0xe4, 0x5b, 0x3d,
646 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05, 0x98, 0xda, 0x48, 0x36,
647 0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8, 0xfd, 0x24, 0xcf, 0x5f,
648 0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96, 0x1c, 0x62, 0xf3, 0x56,
649 0x20, 0x85, 0x52, 0xbb, 0x9e, 0xd5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6d,
650 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04, 0xf1, 0x74, 0x6c, 0x08,
651 0xca, 0x23, 0x73, 0x27, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
652 };
653
654 uint8_t buffer[sizeof(kPrime1536)];
655 if (BN_num_bytes(bn.get()) != sizeof(kPrime1536) ||
656 BN_bn2bin(bn.get(), buffer) != sizeof(kPrime1536) ||
David Benjamin17cf2cb2016-12-13 01:07:13 -0500657 OPENSSL_memcmp(buffer, kPrime1536, sizeof(kPrime1536)) != 0) {
David Benjamin96e1a252016-08-10 13:38:51 -0400658 fprintf(stderr, "1536-bit MODP prime did not match.\n");
659 return false;
660 }
661
662 return true;
663}