Home | History | Annotate | Download | only in dh
      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