1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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> 60 #include <string.h> 61 62 #include <vector> 63 64 #include <gtest/gtest.h> 65 66 #include <openssl/bn.h> 67 #include <openssl/bytestring.h> 68 #include <openssl/crypto.h> 69 #include <openssl/dh.h> 70 #include <openssl/err.h> 71 #include <openssl/mem.h> 72 73 #include "../internal.h" 74 75 76 static bool RunBasicTests(); 77 static bool TestBadY(); 78 static bool TestASN1(); 79 static bool TestRFC3526(); 80 81 // TODO(davidben): Convert this file to GTest properly. 82 TEST(DHTest, AllTests) { 83 if (!RunBasicTests() || 84 !TestBadY() || 85 !TestASN1() || 86 !TestRFC3526()) { 87 ADD_FAILURE() << "Tests failed."; 88 } 89 } 90 91 static int GenerateCallback(int p, int n, BN_GENCB *arg) { 92 char c = '*'; 93 94 if (p == 0) { 95 c = '.'; 96 } else if (p == 1) { 97 c = '+'; 98 } else if (p == 2) { 99 c = '*'; 100 } else if (p == 3) { 101 c = '\n'; 102 } 103 FILE *out = reinterpret_cast<FILE*>(arg->arg); 104 fputc(c, out); 105 fflush(out); 106 107 return 1; 108 } 109 110 static bool RunBasicTests() { 111 BN_GENCB cb; 112 BN_GENCB_set(&cb, &GenerateCallback, stdout); 113 bssl::UniquePtr<DH> a(DH_new()); 114 if (!a || !DH_generate_parameters_ex(a.get(), 64, DH_GENERATOR_5, &cb)) { 115 return false; 116 } 117 118 int check_result; 119 if (!DH_check(a.get(), &check_result)) { 120 return false; 121 } 122 if (check_result & DH_CHECK_P_NOT_PRIME) { 123 printf("p value is not prime\n"); 124 } 125 if (check_result & DH_CHECK_P_NOT_SAFE_PRIME) { 126 printf("p value is not a safe prime\n"); 127 } 128 if (check_result & DH_CHECK_UNABLE_TO_CHECK_GENERATOR) { 129 printf("unable to check the generator value\n"); 130 } 131 if (check_result & DH_CHECK_NOT_SUITABLE_GENERATOR) { 132 printf("the g value is not a generator\n"); 133 } 134 135 printf("\np = "); 136 BN_print_fp(stdout, a->p); 137 printf("\ng = "); 138 BN_print_fp(stdout, a->g); 139 printf("\n"); 140 141 bssl::UniquePtr<DH> b(DH_new()); 142 if (!b) { 143 return false; 144 } 145 146 b->p = BN_dup(a->p); 147 b->g = BN_dup(a->g); 148 if (b->p == nullptr || b->g == nullptr) { 149 return false; 150 } 151 152 if (!DH_generate_key(a.get())) { 153 return false; 154 } 155 printf("pri1 = "); 156 BN_print_fp(stdout, a->priv_key); 157 printf("\npub1 = "); 158 BN_print_fp(stdout, a->pub_key); 159 printf("\n"); 160 161 if (!DH_generate_key(b.get())) { 162 return false; 163 } 164 printf("pri2 = "); 165 BN_print_fp(stdout, b->priv_key); 166 printf("\npub2 = "); 167 BN_print_fp(stdout, b->pub_key); 168 printf("\n"); 169 170 std::vector<uint8_t> key1(DH_size(a.get())); 171 int ret = DH_compute_key(key1.data(), b->pub_key, a.get()); 172 if (ret < 0) { 173 return false; 174 } 175 key1.resize(ret); 176 177 printf("key1 = "); 178 for (size_t i = 0; i < key1.size(); i++) { 179 printf("%02x", key1[i]); 180 } 181 printf("\n"); 182 183 std::vector<uint8_t> key2(DH_size(b.get())); 184 ret = DH_compute_key(key2.data(), a->pub_key, b.get()); 185 if (ret < 0) { 186 return false; 187 } 188 key2.resize(ret); 189 190 printf("key2 = "); 191 for (size_t i = 0; i < key2.size(); i++) { 192 printf("%02x", key2[i]); 193 } 194 printf("\n"); 195 196 if (key1.size() < 4 || key1 != key2) { 197 fprintf(stderr, "Error in DH routines\n"); 198 return false; 199 } 200 201 return true; 202 } 203 204 // The following parameters are taken from RFC 5114, section 2.2. This is not a 205 // safe prime. Do not use these parameters. 206 static const uint8_t kRFC5114_2048_224P[] = { 207 0xad, 0x10, 0x7e, 0x1e, 0x91, 0x23, 0xa9, 0xd0, 0xd6, 0x60, 0xfa, 0xa7, 208 0x95, 0x59, 0xc5, 0x1f, 0xa2, 0x0d, 0x64, 0xe5, 0x68, 0x3b, 0x9f, 0xd1, 209 0xb5, 0x4b, 0x15, 0x97, 0xb6, 0x1d, 0x0a, 0x75, 0xe6, 0xfa, 0x14, 0x1d, 210 0xf9, 0x5a, 0x56, 0xdb, 0xaf, 0x9a, 0x3c, 0x40, 0x7b, 0xa1, 0xdf, 0x15, 211 0xeb, 0x3d, 0x68, 0x8a, 0x30, 0x9c, 0x18, 0x0e, 0x1d, 0xe6, 0xb8, 0x5a, 212 0x12, 0x74, 0xa0, 0xa6, 0x6d, 0x3f, 0x81, 0x52, 0xad, 0x6a, 0xc2, 0x12, 213 0x90, 0x37, 0xc9, 0xed, 0xef, 0xda, 0x4d, 0xf8, 0xd9, 0x1e, 0x8f, 0xef, 214 0x55, 0xb7, 0x39, 0x4b, 0x7a, 0xd5, 0xb7, 0xd0, 0xb6, 0xc1, 0x22, 0x07, 215 0xc9, 0xf9, 0x8d, 0x11, 0xed, 0x34, 0xdb, 0xf6, 0xc6, 0xba, 0x0b, 0x2c, 216 0x8b, 0xbc, 0x27, 0xbe, 0x6a, 0x00, 0xe0, 0xa0, 0xb9, 0xc4, 0x97, 0x08, 217 0xb3, 0xbf, 0x8a, 0x31, 0x70, 0x91, 0x88, 0x36, 0x81, 0x28, 0x61, 0x30, 218 0xbc, 0x89, 0x85, 0xdb, 0x16, 0x02, 0xe7, 0x14, 0x41, 0x5d, 0x93, 0x30, 219 0x27, 0x82, 0x73, 0xc7, 0xde, 0x31, 0xef, 0xdc, 0x73, 0x10, 0xf7, 0x12, 220 0x1f, 0xd5, 0xa0, 0x74, 0x15, 0x98, 0x7d, 0x9a, 0xdc, 0x0a, 0x48, 0x6d, 221 0xcd, 0xf9, 0x3a, 0xcc, 0x44, 0x32, 0x83, 0x87, 0x31, 0x5d, 0x75, 0xe1, 222 0x98, 0xc6, 0x41, 0xa4, 0x80, 0xcd, 0x86, 0xa1, 0xb9, 0xe5, 0x87, 0xe8, 223 0xbe, 0x60, 0xe6, 0x9c, 0xc9, 0x28, 0xb2, 0xb9, 0xc5, 0x21, 0x72, 0xe4, 224 0x13, 0x04, 0x2e, 0x9b, 0x23, 0xf1, 0x0b, 0x0e, 0x16, 0xe7, 0x97, 0x63, 225 0xc9, 0xb5, 0x3d, 0xcf, 0x4b, 0xa8, 0x0a, 0x29, 0xe3, 0xfb, 0x73, 0xc1, 226 0x6b, 0x8e, 0x75, 0xb9, 0x7e, 0xf3, 0x63, 0xe2, 0xff, 0xa3, 0x1f, 0x71, 227 0xcf, 0x9d, 0xe5, 0x38, 0x4e, 0x71, 0xb8, 0x1c, 0x0a, 0xc4, 0xdf, 0xfe, 228 0x0c, 0x10, 0xe6, 0x4f, 229 }; 230 static const uint8_t kRFC5114_2048_224G[] = { 231 0xac, 0x40, 0x32, 0xef, 0x4f, 0x2d, 0x9a, 0xe3, 0x9d, 0xf3, 0x0b, 0x5c, 232 0x8f, 0xfd, 0xac, 0x50, 0x6c, 0xde, 0xbe, 0x7b, 0x89, 0x99, 0x8c, 0xaf, 233 0x74, 0x86, 0x6a, 0x08, 0xcf, 0xe4, 0xff, 0xe3, 0xa6, 0x82, 0x4a, 0x4e, 234 0x10, 0xb9, 0xa6, 0xf0, 0xdd, 0x92, 0x1f, 0x01, 0xa7, 0x0c, 0x4a, 0xfa, 235 0xab, 0x73, 0x9d, 0x77, 0x00, 0xc2, 0x9f, 0x52, 0xc5, 0x7d, 0xb1, 0x7c, 236 0x62, 0x0a, 0x86, 0x52, 0xbe, 0x5e, 0x90, 0x01, 0xa8, 0xd6, 0x6a, 0xd7, 237 0xc1, 0x76, 0x69, 0x10, 0x19, 0x99, 0x02, 0x4a, 0xf4, 0xd0, 0x27, 0x27, 238 0x5a, 0xc1, 0x34, 0x8b, 0xb8, 0xa7, 0x62, 0xd0, 0x52, 0x1b, 0xc9, 0x8a, 239 0xe2, 0x47, 0x15, 0x04, 0x22, 0xea, 0x1e, 0xd4, 0x09, 0x93, 0x9d, 0x54, 240 0xda, 0x74, 0x60, 0xcd, 0xb5, 0xf6, 0xc6, 0xb2, 0x50, 0x71, 0x7c, 0xbe, 241 0xf1, 0x80, 0xeb, 0x34, 0x11, 0x8e, 0x98, 0xd1, 0x19, 0x52, 0x9a, 0x45, 242 0xd6, 0xf8, 0x34, 0x56, 0x6e, 0x30, 0x25, 0xe3, 0x16, 0xa3, 0x30, 0xef, 243 0xbb, 0x77, 0xa8, 0x6f, 0x0c, 0x1a, 0xb1, 0x5b, 0x05, 0x1a, 0xe3, 0xd4, 244 0x28, 0xc8, 0xf8, 0xac, 0xb7, 0x0a, 0x81, 0x37, 0x15, 0x0b, 0x8e, 0xeb, 245 0x10, 0xe1, 0x83, 0xed, 0xd1, 0x99, 0x63, 0xdd, 0xd9, 0xe2, 0x63, 0xe4, 246 0x77, 0x05, 0x89, 0xef, 0x6a, 0xa2, 0x1e, 0x7f, 0x5f, 0x2f, 0xf3, 0x81, 247 0xb5, 0x39, 0xcc, 0xe3, 0x40, 0x9d, 0x13, 0xcd, 0x56, 0x6a, 0xfb, 0xb4, 248 0x8d, 0x6c, 0x01, 0x91, 0x81, 0xe1, 0xbc, 0xfe, 0x94, 0xb3, 0x02, 0x69, 249 0xed, 0xfe, 0x72, 0xfe, 0x9b, 0x6a, 0xa4, 0xbd, 0x7b, 0x5a, 0x0f, 0x1c, 250 0x71, 0xcf, 0xff, 0x4c, 0x19, 0xc4, 0x18, 0xe1, 0xf6, 0xec, 0x01, 0x79, 251 0x81, 0xbc, 0x08, 0x7f, 0x2a, 0x70, 0x65, 0xb3, 0x84, 0xb8, 0x90, 0xd3, 252 0x19, 0x1f, 0x2b, 0xfa, 253 }; 254 static const uint8_t kRFC5114_2048_224Q[] = { 255 0x80, 0x1c, 0x0d, 0x34, 0xc5, 0x8d, 0x93, 0xfe, 0x99, 0x71, 256 0x77, 0x10, 0x1f, 0x80, 0x53, 0x5a, 0x47, 0x38, 0xce, 0xbc, 257 0xbf, 0x38, 0x9a, 0x99, 0xb3, 0x63, 0x71, 0xeb, 258 }; 259 260 // kRFC5114_2048_224BadY is a bad y-coordinate for RFC 5114's 2048-bit MODP 261 // Group with 224-bit Prime Order Subgroup (section 2.2). 262 static const uint8_t kRFC5114_2048_224BadY[] = { 263 0x45, 0x32, 0x5f, 0x51, 0x07, 0xe5, 0xdf, 0x1c, 0xd6, 0x02, 0x82, 0xb3, 264 0x32, 0x8f, 0xa4, 0x0f, 0x87, 0xb8, 0x41, 0xfe, 0xb9, 0x35, 0xde, 0xad, 265 0xc6, 0x26, 0x85, 0xb4, 0xff, 0x94, 0x8c, 0x12, 0x4c, 0xbf, 0x5b, 0x20, 266 0xc4, 0x46, 0xa3, 0x26, 0xeb, 0xa4, 0x25, 0xb7, 0x68, 0x8e, 0xcc, 0x67, 267 0xba, 0xea, 0x58, 0xd0, 0xf2, 0xe9, 0xd2, 0x24, 0x72, 0x60, 0xda, 0x88, 268 0x18, 0x9c, 0xe0, 0x31, 0x6a, 0xad, 0x50, 0x6d, 0x94, 0x35, 0x8b, 0x83, 269 0x4a, 0x6e, 0xfa, 0x48, 0x73, 0x0f, 0x83, 0x87, 0xff, 0x6b, 0x66, 0x1f, 270 0xa8, 0x82, 0xc6, 0x01, 0xe5, 0x80, 0xb5, 0xb0, 0x52, 0xd0, 0xe9, 0xd8, 271 0x72, 0xf9, 0x7d, 0x5b, 0x8b, 0xa5, 0x4c, 0xa5, 0x25, 0x95, 0x74, 0xe2, 272 0x7a, 0x61, 0x4e, 0xa7, 0x8f, 0x12, 0xe2, 0xd2, 0x9d, 0x8c, 0x02, 0x70, 273 0x34, 0x44, 0x32, 0xc7, 0xb2, 0xf3, 0xb9, 0xfe, 0x17, 0x2b, 0xd6, 0x1f, 274 0x8b, 0x7e, 0x4a, 0xfa, 0xa3, 0xb5, 0x3e, 0x7a, 0x81, 0x9a, 0x33, 0x66, 275 0x62, 0xa4, 0x50, 0x18, 0x3e, 0xa2, 0x5f, 0x00, 0x07, 0xd8, 0x9b, 0x22, 276 0xe4, 0xec, 0x84, 0xd5, 0xeb, 0x5a, 0xf3, 0x2a, 0x31, 0x23, 0xd8, 0x44, 277 0x22, 0x2a, 0x8b, 0x37, 0x44, 0xcc, 0xc6, 0x87, 0x4b, 0xbe, 0x50, 0x9d, 278 0x4a, 0xc4, 0x8e, 0x45, 0xcf, 0x72, 0x4d, 0xc0, 0x89, 0xb3, 0x72, 0xed, 279 0x33, 0x2c, 0xbc, 0x7f, 0x16, 0x39, 0x3b, 0xeb, 0xd2, 0xdd, 0xa8, 0x01, 280 0x73, 0x84, 0x62, 0xb9, 0x29, 0xd2, 0xc9, 0x51, 0x32, 0x9e, 0x7a, 0x6a, 281 0xcf, 0xc1, 0x0a, 0xdb, 0x0e, 0xe0, 0x62, 0x77, 0x6f, 0x59, 0x62, 0x72, 282 0x5a, 0x69, 0xa6, 0x5b, 0x70, 0xca, 0x65, 0xc4, 0x95, 0x6f, 0x9a, 0xc2, 283 0xdf, 0x72, 0x6d, 0xb1, 0x1e, 0x54, 0x7b, 0x51, 0xb4, 0xef, 0x7f, 0x89, 284 0x93, 0x74, 0x89, 0x59, 285 }; 286 287 static bool TestBadY() { 288 bssl::UniquePtr<DH> dh(DH_new()); 289 dh->p = BN_bin2bn(kRFC5114_2048_224P, sizeof(kRFC5114_2048_224P), nullptr); 290 dh->g = BN_bin2bn(kRFC5114_2048_224G, sizeof(kRFC5114_2048_224G), nullptr); 291 dh->q = BN_bin2bn(kRFC5114_2048_224Q, sizeof(kRFC5114_2048_224Q), nullptr); 292 if (!dh->p || !dh->g || !dh->q) { 293 return false; 294 } 295 296 bssl::UniquePtr<BIGNUM> pub_key( 297 BN_bin2bn(kRFC5114_2048_224BadY, sizeof(kRFC5114_2048_224BadY), nullptr)); 298 if (!dh || !pub_key || !DH_generate_key(dh.get())) { 299 return false; 300 } 301 302 int flags; 303 if (!DH_check_pub_key(dh.get(), pub_key.get(), &flags)) { 304 return false; 305 } 306 if (!(flags & DH_CHECK_PUBKEY_INVALID)) { 307 fprintf(stderr, "DH_check_pub_key did not reject the key.\n"); 308 return false; 309 } 310 311 std::vector<uint8_t> result(DH_size(dh.get())); 312 if (DH_compute_key(result.data(), pub_key.get(), dh.get()) >= 0) { 313 fprintf(stderr, "DH_compute_key unexpectedly succeeded.\n"); 314 return false; 315 } 316 ERR_clear_error(); 317 318 return true; 319 } 320 321 static bool BIGNUMEqualsHex(const BIGNUM *bn, const char *hex) { 322 BIGNUM *hex_bn = NULL; 323 if (!BN_hex2bn(&hex_bn, hex)) { 324 return false; 325 } 326 bssl::UniquePtr<BIGNUM> free_hex_bn(hex_bn); 327 return BN_cmp(bn, hex_bn) == 0; 328 } 329 330 static bool TestASN1() { 331 // kParams are a set of Diffie-Hellman parameters generated with 332 // openssl dhparam 256 333 static const uint8_t kParams[] = { 334 0x30, 0x26, 0x02, 0x21, 0x00, 0xd7, 0x20, 0x34, 0xa3, 0x27, 335 0x4f, 0xdf, 0xbf, 0x04, 0xfd, 0x24, 0x68, 0x25, 0xb6, 0x56, 336 0xd8, 0xab, 0x2a, 0x41, 0x2d, 0x74, 0x0a, 0x52, 0x08, 0x7c, 337 0x40, 0x71, 0x4e, 0xd2, 0x57, 0x93, 0x13, 0x02, 0x01, 0x02, 338 }; 339 340 CBS cbs; 341 CBS_init(&cbs, kParams, sizeof(kParams)); 342 bssl::UniquePtr<DH> dh(DH_parse_parameters(&cbs)); 343 if (!dh || CBS_len(&cbs) != 0 || 344 !BIGNUMEqualsHex( 345 dh->p, 346 "d72034a3274fdfbf04fd246825b656d8ab2a412d740a52087c40714ed2579313") || 347 !BIGNUMEqualsHex(dh->g, "2") || dh->priv_length != 0) { 348 return false; 349 } 350 351 bssl::ScopedCBB cbb; 352 uint8_t *der; 353 size_t der_len; 354 if (!CBB_init(cbb.get(), 0) || 355 !DH_marshal_parameters(cbb.get(), dh.get()) || 356 !CBB_finish(cbb.get(), &der, &der_len)) { 357 return false; 358 } 359 bssl::UniquePtr<uint8_t> free_der(der); 360 if (der_len != sizeof(kParams) || 361 OPENSSL_memcmp(der, kParams, der_len) != 0) { 362 return false; 363 } 364 365 // kParamsDSA are a set of Diffie-Hellman parameters generated with 366 // openssl dhparam 256 -dsaparam 367 static const uint8_t kParamsDSA[] = { 368 0x30, 0x81, 0x89, 0x02, 0x41, 0x00, 0x93, 0xf3, 0xc1, 0x18, 0x01, 0xe6, 369 0x62, 0xb6, 0xd1, 0x46, 0x9a, 0x2c, 0x72, 0xea, 0x31, 0xd9, 0x18, 0x10, 370 0x30, 0x28, 0x63, 0xe2, 0x34, 0x7d, 0x80, 0xca, 0xee, 0x82, 0x2b, 0x19, 371 0x3c, 0x19, 0xbb, 0x42, 0x83, 0x02, 0x70, 0xdd, 0xdb, 0x8c, 0x03, 0xab, 372 0xe9, 0x9c, 0xc4, 0x00, 0x4d, 0x70, 0x5f, 0x52, 0x03, 0x31, 0x2c, 0xa4, 373 0x67, 0x34, 0x51, 0x95, 0x2a, 0xac, 0x11, 0xe2, 0x6a, 0x55, 0x02, 0x40, 374 0x44, 0xc8, 0x10, 0x53, 0x44, 0x32, 0x31, 0x63, 0xd8, 0xd1, 0x8c, 0x75, 375 0xc8, 0x98, 0x53, 0x3b, 0x5b, 0x4a, 0x2a, 0x0a, 0x09, 0xe7, 0xd0, 0x3c, 376 0x53, 0x72, 0xa8, 0x6b, 0x70, 0x41, 0x9c, 0x26, 0x71, 0x44, 0xfc, 0x7f, 377 0x08, 0x75, 0xe1, 0x02, 0xab, 0x74, 0x41, 0xe8, 0x2a, 0x3d, 0x3c, 0x26, 378 0x33, 0x09, 0xe4, 0x8b, 0xb4, 0x41, 0xec, 0xa6, 0xa8, 0xba, 0x1a, 0x07, 379 0x8a, 0x77, 0xf5, 0x5f, 0x02, 0x02, 0x00, 0xa0, 380 }; 381 382 CBS_init(&cbs, kParamsDSA, sizeof(kParamsDSA)); 383 dh.reset(DH_parse_parameters(&cbs)); 384 if (!dh || CBS_len(&cbs) != 0 || 385 !BIGNUMEqualsHex(dh->p, 386 "93f3c11801e662b6d1469a2c72ea31d91810302863e2347d80caee8" 387 "22b193c19bb42830270dddb8c03abe99cc4004d705f5203312ca467" 388 "3451952aac11e26a55") || 389 !BIGNUMEqualsHex(dh->g, 390 "44c8105344323163d8d18c75c898533b5b4a2a0a09e7d03c5372a86" 391 "b70419c267144fc7f0875e102ab7441e82a3d3c263309e48bb441ec" 392 "a6a8ba1a078a77f55f") || 393 dh->priv_length != 160) { 394 return false; 395 } 396 397 if (!CBB_init(cbb.get(), 0) || 398 !DH_marshal_parameters(cbb.get(), dh.get()) || 399 !CBB_finish(cbb.get(), &der, &der_len)) { 400 return false; 401 } 402 bssl::UniquePtr<uint8_t> free_der2(der); 403 if (der_len != sizeof(kParamsDSA) || 404 OPENSSL_memcmp(der, kParamsDSA, der_len) != 0) { 405 return false; 406 } 407 408 return true; 409 } 410 411 static bool TestRFC3526() { 412 bssl::UniquePtr<BIGNUM> bn(BN_get_rfc3526_prime_1536(nullptr)); 413 if (!bn) { 414 return false; 415 } 416 417 static const uint8_t kPrime1536[] = { 418 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc9, 0x0f, 0xda, 0xa2, 419 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1, 420 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74, 0x02, 0x0b, 0xbe, 0xa6, 421 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd, 422 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b, 0x30, 0x2b, 0x0a, 0x6d, 423 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45, 424 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6, 0xf4, 0x4c, 0x42, 0xe9, 425 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed, 426 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5, 0xae, 0x9f, 0x24, 0x11, 427 0x7c, 0x4b, 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51, 0xec, 0xe4, 0x5b, 0x3d, 428 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05, 0x98, 0xda, 0x48, 0x36, 429 0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8, 0xfd, 0x24, 0xcf, 0x5f, 430 0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96, 0x1c, 0x62, 0xf3, 0x56, 431 0x20, 0x85, 0x52, 0xbb, 0x9e, 0xd5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6d, 432 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04, 0xf1, 0x74, 0x6c, 0x08, 433 0xca, 0x23, 0x73, 0x27, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 434 }; 435 436 uint8_t buffer[sizeof(kPrime1536)]; 437 if (BN_num_bytes(bn.get()) != sizeof(kPrime1536) || 438 BN_bn2bin(bn.get(), buffer) != sizeof(kPrime1536) || 439 OPENSSL_memcmp(buffer, kPrime1536, sizeof(kPrime1536)) != 0) { 440 fprintf(stderr, "1536-bit MODP prime did not match.\n"); 441 return false; 442 } 443 444 return true; 445 } 446