Home | History | Annotate | Line # | Download | only in test
      1 /*
      2  * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 /*
     11  * DH low level APIs are deprecated for public use, but still ok for
     12  * internal use.
     13  */
     14 #include "internal/deprecated.h"
     15 
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <string.h>
     19 
     20 #include "internal/nelem.h"
     21 #include <openssl/crypto.h>
     22 #include <openssl/bio.h>
     23 #include <openssl/bn.h>
     24 #include <openssl/rand.h>
     25 #include <openssl/err.h>
     26 #include <openssl/obj_mac.h>
     27 #include <openssl/core_names.h>
     28 #include "testutil.h"
     29 
     30 #ifndef OPENSSL_NO_DH
     31 #include <openssl/dh.h>
     32 #include "crypto/bn_dh.h"
     33 #include "crypto/dh.h"
     34 
     35 static int cb(int p, int n, BN_GENCB *arg);
     36 
     37 static int dh_test(void)
     38 {
     39     DH *dh = NULL;
     40     BIGNUM *p = NULL, *q = NULL, *g = NULL;
     41     const BIGNUM *p2, *q2, *g2;
     42     BIGNUM *priv_key = NULL;
     43     const BIGNUM *pub_key2, *priv_key2;
     44     BN_GENCB *_cb = NULL;
     45     DH *a = NULL;
     46     DH *b = NULL;
     47     DH *c = NULL;
     48     const BIGNUM *ap = NULL, *ag = NULL, *apub_key = NULL;
     49     const BIGNUM *bpub_key = NULL, *bpriv_key = NULL;
     50     BIGNUM *bp = NULL, *bg = NULL, *cpriv_key = NULL;
     51     unsigned char *abuf = NULL;
     52     unsigned char *bbuf = NULL;
     53     unsigned char *cbuf = NULL;
     54     int i, alen, blen, clen, aout, bout, cout;
     55     int ret = 0;
     56 
     57     if (!TEST_ptr(dh = DH_new())
     58         || !TEST_ptr(p = BN_new())
     59         || !TEST_ptr(q = BN_new())
     60         || !TEST_ptr(g = BN_new())
     61         || !TEST_ptr(priv_key = BN_new()))
     62         goto err1;
     63 
     64     /*
     65      * I) basic tests
     66      */
     67 
     68     /* using a small predefined Sophie Germain DH group with generator 3 */
     69     if (!TEST_true(BN_set_word(p, 4079L))
     70         || !TEST_true(BN_set_word(q, 2039L))
     71         || !TEST_true(BN_set_word(g, 3L))
     72         || !TEST_true(DH_set0_pqg(dh, p, q, g)))
     73         goto err1;
     74 
     75     /* check fails, because p is way too small */
     76     if (!TEST_true(DH_check(dh, &i)))
     77         goto err2;
     78     i ^= DH_MODULUS_TOO_SMALL;
     79     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
     80         || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
     81         || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
     82         || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
     83         || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
     84         || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
     85         || !TEST_false(i & DH_CHECK_INVALID_J_VALUE)
     86         || !TEST_false(i & DH_MODULUS_TOO_SMALL)
     87         || !TEST_false(i & DH_MODULUS_TOO_LARGE)
     88         || !TEST_false(i))
     89         goto err2;
     90 
     91     /* test the combined getter for p, q, and g */
     92     DH_get0_pqg(dh, &p2, &q2, &g2);
     93     if (!TEST_ptr_eq(p2, p)
     94         || !TEST_ptr_eq(q2, q)
     95         || !TEST_ptr_eq(g2, g))
     96         goto err2;
     97 
     98     /* test the simple getters for p, q, and g */
     99     if (!TEST_ptr_eq(DH_get0_p(dh), p2)
    100         || !TEST_ptr_eq(DH_get0_q(dh), q2)
    101         || !TEST_ptr_eq(DH_get0_g(dh), g2))
    102         goto err2;
    103 
    104     /* set the private key only*/
    105     if (!TEST_true(BN_set_word(priv_key, 1234L))
    106         || !TEST_true(DH_set0_key(dh, NULL, priv_key)))
    107         goto err2;
    108 
    109     /* test the combined getter for pub_key and priv_key */
    110     DH_get0_key(dh, &pub_key2, &priv_key2);
    111     if (!TEST_ptr_eq(pub_key2, NULL)
    112         || !TEST_ptr_eq(priv_key2, priv_key))
    113         goto err3;
    114 
    115     /* test the simple getters for pub_key and priv_key */
    116     if (!TEST_ptr_eq(DH_get0_pub_key(dh), pub_key2)
    117         || !TEST_ptr_eq(DH_get0_priv_key(dh), priv_key2))
    118         goto err3;
    119 
    120     /* now generate a key pair (expect failure since modulus is too small) */
    121     if (!TEST_false(DH_generate_key(dh)))
    122         goto err3;
    123 
    124     /* We'll have a stale error on the queue from the above test so clear it */
    125     ERR_clear_error();
    126 
    127     if (!TEST_ptr(BN_copy(q, p)) || !TEST_true(BN_add(q, q, BN_value_one())))
    128         goto err3;
    129 
    130     if (!TEST_true(DH_check(dh, &i)))
    131         goto err3;
    132     if (!TEST_true(i & DH_CHECK_INVALID_Q_VALUE)
    133         || !TEST_false(i & DH_CHECK_Q_NOT_PRIME))
    134         goto err3;
    135 
    136     /* Modulus of size: dh check max modulus bits + 1 */
    137     if (!TEST_true(BN_set_word(p, 1))
    138         || !TEST_true(BN_lshift(p, p, OPENSSL_DH_CHECK_MAX_MODULUS_BITS)))
    139         goto err3;
    140 
    141     /*
    142      * We expect no checks at all for an excessively large modulus
    143      */
    144     if (!TEST_false(DH_check(dh, &i)))
    145         goto err3;
    146 
    147     /* We'll have a stale error on the queue from the above test so clear it */
    148     ERR_clear_error();
    149 
    150     /*
    151      * II) key generation
    152      */
    153 
    154     /* generate a DH group ... */
    155     if (!TEST_ptr(_cb = BN_GENCB_new()))
    156         goto err3;
    157     BN_GENCB_set(_cb, &cb, NULL);
    158     if (!TEST_ptr(a = DH_new())
    159         || !TEST_true(DH_generate_parameters_ex(a, 512,
    160             DH_GENERATOR_5, _cb)))
    161         goto err3;
    162 
    163     /* ... and check whether it is valid */
    164     if (!TEST_true(DH_check(a, &i)))
    165         goto err3;
    166     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
    167         || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
    168         || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
    169         || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
    170         || !TEST_false(i & DH_CHECK_Q_NOT_PRIME)
    171         || !TEST_false(i & DH_CHECK_INVALID_Q_VALUE)
    172         || !TEST_false(i & DH_CHECK_INVALID_J_VALUE)
    173         || !TEST_false(i & DH_MODULUS_TOO_SMALL)
    174         || !TEST_false(i & DH_MODULUS_TOO_LARGE)
    175         || !TEST_false(i))
    176         goto err3;
    177 
    178     DH_get0_pqg(a, &ap, NULL, &ag);
    179 
    180     /* now create another copy of the DH group for the peer */
    181     if (!TEST_ptr(b = DH_new()))
    182         goto err3;
    183 
    184     if (!TEST_ptr(bp = BN_dup(ap))
    185         || !TEST_ptr(bg = BN_dup(ag))
    186         || !TEST_true(DH_set0_pqg(b, bp, NULL, bg)))
    187         goto err3;
    188     bp = bg = NULL;
    189 
    190     /*
    191      * III) simulate a key exchange
    192      */
    193 
    194     if (!DH_generate_key(a))
    195         goto err3;
    196     DH_get0_key(a, &apub_key, NULL);
    197 
    198     if (!DH_generate_key(b))
    199         goto err3;
    200     DH_get0_key(b, &bpub_key, &bpriv_key);
    201 
    202     /* Also test with a private-key-only copy of |b|. */
    203     if (!TEST_ptr(c = DHparams_dup(b))
    204         || !TEST_ptr(cpriv_key = BN_dup(bpriv_key))
    205         || !TEST_true(DH_set0_key(c, NULL, cpriv_key)))
    206         goto err3;
    207     cpriv_key = NULL;
    208 
    209     alen = DH_size(a);
    210     if (!TEST_ptr(abuf = OPENSSL_malloc(alen))
    211         || !TEST_int_gt((aout = DH_compute_key(abuf, bpub_key, a)), 0))
    212         goto err3;
    213 
    214     blen = DH_size(b);
    215     if (!TEST_ptr(bbuf = OPENSSL_malloc(blen))
    216         || !TEST_int_gt((bout = DH_compute_key(bbuf, apub_key, b)), 0))
    217         goto err3;
    218 
    219     clen = DH_size(c);
    220     if (!TEST_ptr(cbuf = OPENSSL_malloc(clen))
    221         || !TEST_int_gt((cout = DH_compute_key(cbuf, apub_key, c)), 0))
    222         goto err3;
    223 
    224     if (!TEST_true(aout >= 20)
    225         || !TEST_mem_eq(abuf, aout, bbuf, bout)
    226         || !TEST_mem_eq(abuf, aout, cbuf, cout))
    227         goto err3;
    228 
    229     ret = 1;
    230     goto success;
    231 
    232 err1:
    233     /* an error occurred before p,q,g were assigned to dh */
    234     BN_free(p);
    235     BN_free(q);
    236     BN_free(g);
    237 err2:
    238     /* an error occurred before priv_key was assigned to dh */
    239     BN_free(priv_key);
    240 err3:
    241 success:
    242     OPENSSL_free(abuf);
    243     OPENSSL_free(bbuf);
    244     OPENSSL_free(cbuf);
    245     DH_free(b);
    246     DH_free(a);
    247     DH_free(c);
    248     BN_free(bp);
    249     BN_free(bg);
    250     BN_free(cpriv_key);
    251     BN_GENCB_free(_cb);
    252     DH_free(dh);
    253 
    254     return ret;
    255 }
    256 
    257 static int cb(int p, int n, BN_GENCB *arg)
    258 {
    259     return 1;
    260 }
    261 
    262 static int dh_computekey_range_test(void)
    263 {
    264     int ret = 0, sz;
    265     DH *dh = NULL;
    266     BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *priv = NULL;
    267     unsigned char *buf = NULL;
    268 
    269     if (!TEST_ptr(p = BN_dup(&ossl_bignum_ffdhe2048_p))
    270         || !TEST_ptr(q = BN_dup(&ossl_bignum_ffdhe2048_q))
    271         || !TEST_ptr(g = BN_dup(&ossl_bignum_const_2))
    272         || !TEST_ptr(dh = DH_new())
    273         || !TEST_true(DH_set0_pqg(dh, p, q, g)))
    274         goto err;
    275     p = q = g = NULL;
    276 
    277     if (!TEST_int_gt(sz = DH_size(dh), 0)
    278         || !TEST_ptr(buf = OPENSSL_malloc(sz))
    279         || !TEST_ptr(pub = BN_new())
    280         || !TEST_ptr(priv = BN_new()))
    281         goto err;
    282 
    283     if (!TEST_true(BN_set_word(priv, 1))
    284         || !TEST_true(DH_set0_key(dh, NULL, priv)))
    285         goto err;
    286     priv = NULL;
    287     if (!TEST_true(BN_set_word(pub, 1)))
    288         goto err;
    289 
    290     /* Given z = pub ^ priv mod p */
    291 
    292     /* Test that z == 1 fails */
    293     if (!TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0))
    294         goto err;
    295     /* Test that z == 0 fails */
    296     if (!TEST_ptr(BN_copy(pub, DH_get0_p(dh)))
    297         || !TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0))
    298         goto err;
    299     /* Test that z == p - 1 fails */
    300     if (!TEST_true(BN_sub_word(pub, 1))
    301         || !TEST_int_le(ossl_dh_compute_key(buf, pub, dh), 0))
    302         goto err;
    303     /* Test that z == p - 2 passes */
    304     if (!TEST_true(BN_sub_word(pub, 1))
    305         || !TEST_int_eq(ossl_dh_compute_key(buf, pub, dh), sz))
    306         goto err;
    307 
    308     ret = 1;
    309 err:
    310     OPENSSL_free(buf);
    311     BN_free(priv);
    312     BN_free(pub);
    313     BN_free(g);
    314     BN_free(q);
    315     BN_free(p);
    316     DH_free(dh);
    317     return ret;
    318 }
    319 
    320 /* Test data from RFC 5114 */
    321 
    322 static const unsigned char dhtest_1024_160_xA[] = {
    323     0xB9, 0xA3, 0xB3, 0xAE, 0x8F, 0xEF, 0xC1, 0xA2, 0x93, 0x04, 0x96, 0x50,
    324     0x70, 0x86, 0xF8, 0x45, 0x5D, 0x48, 0x94, 0x3E
    325 };
    326 
    327 static const unsigned char dhtest_1024_160_yA[] = {
    328     0x2A, 0x85, 0x3B, 0x3D, 0x92, 0x19, 0x75, 0x01, 0xB9, 0x01, 0x5B, 0x2D,
    329     0xEB, 0x3E, 0xD8, 0x4F, 0x5E, 0x02, 0x1D, 0xCC, 0x3E, 0x52, 0xF1, 0x09,
    330     0xD3, 0x27, 0x3D, 0x2B, 0x75, 0x21, 0x28, 0x1C, 0xBA, 0xBE, 0x0E, 0x76,
    331     0xFF, 0x57, 0x27, 0xFA, 0x8A, 0xCC, 0xE2, 0x69, 0x56, 0xBA, 0x9A, 0x1F,
    332     0xCA, 0x26, 0xF2, 0x02, 0x28, 0xD8, 0x69, 0x3F, 0xEB, 0x10, 0x84, 0x1D,
    333     0x84, 0xA7, 0x36, 0x00, 0x54, 0xEC, 0xE5, 0xA7, 0xF5, 0xB7, 0xA6, 0x1A,
    334     0xD3, 0xDF, 0xB3, 0xC6, 0x0D, 0x2E, 0x43, 0x10, 0x6D, 0x87, 0x27, 0xDA,
    335     0x37, 0xDF, 0x9C, 0xCE, 0x95, 0xB4, 0x78, 0x75, 0x5D, 0x06, 0xBC, 0xEA,
    336     0x8F, 0x9D, 0x45, 0x96, 0x5F, 0x75, 0xA5, 0xF3, 0xD1, 0xDF, 0x37, 0x01,
    337     0x16, 0x5F, 0xC9, 0xE5, 0x0C, 0x42, 0x79, 0xCE, 0xB0, 0x7F, 0x98, 0x95,
    338     0x40, 0xAE, 0x96, 0xD5, 0xD8, 0x8E, 0xD7, 0x76
    339 };
    340 
    341 static const unsigned char dhtest_1024_160_xB[] = {
    342     0x93, 0x92, 0xC9, 0xF9, 0xEB, 0x6A, 0x7A, 0x6A, 0x90, 0x22, 0xF7, 0xD8,
    343     0x3E, 0x72, 0x23, 0xC6, 0x83, 0x5B, 0xBD, 0xDA
    344 };
    345 
    346 static const unsigned char dhtest_1024_160_yB[] = {
    347     0x71, 0x7A, 0x6C, 0xB0, 0x53, 0x37, 0x1F, 0xF4, 0xA3, 0xB9, 0x32, 0x94,
    348     0x1C, 0x1E, 0x56, 0x63, 0xF8, 0x61, 0xA1, 0xD6, 0xAD, 0x34, 0xAE, 0x66,
    349     0x57, 0x6D, 0xFB, 0x98, 0xF6, 0xC6, 0xCB, 0xF9, 0xDD, 0xD5, 0xA5, 0x6C,
    350     0x78, 0x33, 0xF6, 0xBC, 0xFD, 0xFF, 0x09, 0x55, 0x82, 0xAD, 0x86, 0x8E,
    351     0x44, 0x0E, 0x8D, 0x09, 0xFD, 0x76, 0x9E, 0x3C, 0xEC, 0xCD, 0xC3, 0xD3,
    352     0xB1, 0xE4, 0xCF, 0xA0, 0x57, 0x77, 0x6C, 0xAA, 0xF9, 0x73, 0x9B, 0x6A,
    353     0x9F, 0xEE, 0x8E, 0x74, 0x11, 0xF8, 0xD6, 0xDA, 0xC0, 0x9D, 0x6A, 0x4E,
    354     0xDB, 0x46, 0xCC, 0x2B, 0x5D, 0x52, 0x03, 0x09, 0x0E, 0xAE, 0x61, 0x26,
    355     0x31, 0x1E, 0x53, 0xFD, 0x2C, 0x14, 0xB5, 0x74, 0xE6, 0xA3, 0x10, 0x9A,
    356     0x3D, 0xA1, 0xBE, 0x41, 0xBD, 0xCE, 0xAA, 0x18, 0x6F, 0x5C, 0xE0, 0x67,
    357     0x16, 0xA2, 0xB6, 0xA0, 0x7B, 0x3C, 0x33, 0xFE
    358 };
    359 
    360 static const unsigned char dhtest_1024_160_Z[] = {
    361     0x5C, 0x80, 0x4F, 0x45, 0x4D, 0x30, 0xD9, 0xC4, 0xDF, 0x85, 0x27, 0x1F,
    362     0x93, 0x52, 0x8C, 0x91, 0xDF, 0x6B, 0x48, 0xAB, 0x5F, 0x80, 0xB3, 0xB5,
    363     0x9C, 0xAA, 0xC1, 0xB2, 0x8F, 0x8A, 0xCB, 0xA9, 0xCD, 0x3E, 0x39, 0xF3,
    364     0xCB, 0x61, 0x45, 0x25, 0xD9, 0x52, 0x1D, 0x2E, 0x64, 0x4C, 0x53, 0xB8,
    365     0x07, 0xB8, 0x10, 0xF3, 0x40, 0x06, 0x2F, 0x25, 0x7D, 0x7D, 0x6F, 0xBF,
    366     0xE8, 0xD5, 0xE8, 0xF0, 0x72, 0xE9, 0xB6, 0xE9, 0xAF, 0xDA, 0x94, 0x13,
    367     0xEA, 0xFB, 0x2E, 0x8B, 0x06, 0x99, 0xB1, 0xFB, 0x5A, 0x0C, 0xAC, 0xED,
    368     0xDE, 0xAE, 0xAD, 0x7E, 0x9C, 0xFB, 0xB3, 0x6A, 0xE2, 0xB4, 0x20, 0x83,
    369     0x5B, 0xD8, 0x3A, 0x19, 0xFB, 0x0B, 0x5E, 0x96, 0xBF, 0x8F, 0xA4, 0xD0,
    370     0x9E, 0x34, 0x55, 0x25, 0x16, 0x7E, 0xCD, 0x91, 0x55, 0x41, 0x6F, 0x46,
    371     0xF4, 0x08, 0xED, 0x31, 0xB6, 0x3C, 0x6E, 0x6D
    372 };
    373 
    374 static const unsigned char dhtest_2048_224_xA[] = {
    375     0x22, 0xE6, 0x26, 0x01, 0xDB, 0xFF, 0xD0, 0x67, 0x08, 0xA6, 0x80, 0xF7,
    376     0x47, 0xF3, 0x61, 0xF7, 0x6D, 0x8F, 0x4F, 0x72, 0x1A, 0x05, 0x48, 0xE4,
    377     0x83, 0x29, 0x4B, 0x0C
    378 };
    379 
    380 static const unsigned char dhtest_2048_224_yA[] = {
    381     0x1B, 0x3A, 0x63, 0x45, 0x1B, 0xD8, 0x86, 0xE6, 0x99, 0xE6, 0x7B, 0x49,
    382     0x4E, 0x28, 0x8B, 0xD7, 0xF8, 0xE0, 0xD3, 0x70, 0xBA, 0xDD, 0xA7, 0xA0,
    383     0xEF, 0xD2, 0xFD, 0xE7, 0xD8, 0xF6, 0x61, 0x45, 0xCC, 0x9F, 0x28, 0x04,
    384     0x19, 0x97, 0x5E, 0xB8, 0x08, 0x87, 0x7C, 0x8A, 0x4C, 0x0C, 0x8E, 0x0B,
    385     0xD4, 0x8D, 0x4A, 0x54, 0x01, 0xEB, 0x1E, 0x87, 0x76, 0xBF, 0xEE, 0xE1,
    386     0x34, 0xC0, 0x38, 0x31, 0xAC, 0x27, 0x3C, 0xD9, 0xD6, 0x35, 0xAB, 0x0C,
    387     0xE0, 0x06, 0xA4, 0x2A, 0x88, 0x7E, 0x3F, 0x52, 0xFB, 0x87, 0x66, 0xB6,
    388     0x50, 0xF3, 0x80, 0x78, 0xBC, 0x8E, 0xE8, 0x58, 0x0C, 0xEF, 0xE2, 0x43,
    389     0x96, 0x8C, 0xFC, 0x4F, 0x8D, 0xC3, 0xDB, 0x08, 0x45, 0x54, 0x17, 0x1D,
    390     0x41, 0xBF, 0x2E, 0x86, 0x1B, 0x7B, 0xB4, 0xD6, 0x9D, 0xD0, 0xE0, 0x1E,
    391     0xA3, 0x87, 0xCB, 0xAA, 0x5C, 0xA6, 0x72, 0xAF, 0xCB, 0xE8, 0xBD, 0xB9,
    392     0xD6, 0x2D, 0x4C, 0xE1, 0x5F, 0x17, 0xDD, 0x36, 0xF9, 0x1E, 0xD1, 0xEE,
    393     0xDD, 0x65, 0xCA, 0x4A, 0x06, 0x45, 0x5C, 0xB9, 0x4C, 0xD4, 0x0A, 0x52,
    394     0xEC, 0x36, 0x0E, 0x84, 0xB3, 0xC9, 0x26, 0xE2, 0x2C, 0x43, 0x80, 0xA3,
    395     0xBF, 0x30, 0x9D, 0x56, 0x84, 0x97, 0x68, 0xB7, 0xF5, 0x2C, 0xFD, 0xF6,
    396     0x55, 0xFD, 0x05, 0x3A, 0x7E, 0xF7, 0x06, 0x97, 0x9E, 0x7E, 0x58, 0x06,
    397     0xB1, 0x7D, 0xFA, 0xE5, 0x3A, 0xD2, 0xA5, 0xBC, 0x56, 0x8E, 0xBB, 0x52,
    398     0x9A, 0x7A, 0x61, 0xD6, 0x8D, 0x25, 0x6F, 0x8F, 0xC9, 0x7C, 0x07, 0x4A,
    399     0x86, 0x1D, 0x82, 0x7E, 0x2E, 0xBC, 0x8C, 0x61, 0x34, 0x55, 0x31, 0x15,
    400     0xB7, 0x0E, 0x71, 0x03, 0x92, 0x0A, 0xA1, 0x6D, 0x85, 0xE5, 0x2B, 0xCB,
    401     0xAB, 0x8D, 0x78, 0x6A, 0x68, 0x17, 0x8F, 0xA8, 0xFF, 0x7C, 0x2F, 0x5C,
    402     0x71, 0x64, 0x8D, 0x6F
    403 };
    404 
    405 static const unsigned char dhtest_2048_224_xB[] = {
    406     0x4F, 0xF3, 0xBC, 0x96, 0xC7, 0xFC, 0x6A, 0x6D, 0x71, 0xD3, 0xB3, 0x63,
    407     0x80, 0x0A, 0x7C, 0xDF, 0xEF, 0x6F, 0xC4, 0x1B, 0x44, 0x17, 0xEA, 0x15,
    408     0x35, 0x3B, 0x75, 0x90
    409 };
    410 
    411 static const unsigned char dhtest_2048_224_yB[] = {
    412     0x4D, 0xCE, 0xE9, 0x92, 0xA9, 0x76, 0x2A, 0x13, 0xF2, 0xF8, 0x38, 0x44,
    413     0xAD, 0x3D, 0x77, 0xEE, 0x0E, 0x31, 0xC9, 0x71, 0x8B, 0x3D, 0xB6, 0xC2,
    414     0x03, 0x5D, 0x39, 0x61, 0x18, 0x2C, 0x3E, 0x0B, 0xA2, 0x47, 0xEC, 0x41,
    415     0x82, 0xD7, 0x60, 0xCD, 0x48, 0xD9, 0x95, 0x99, 0x97, 0x06, 0x22, 0xA1,
    416     0x88, 0x1B, 0xBA, 0x2D, 0xC8, 0x22, 0x93, 0x9C, 0x78, 0xC3, 0x91, 0x2C,
    417     0x66, 0x61, 0xFA, 0x54, 0x38, 0xB2, 0x07, 0x66, 0x22, 0x2B, 0x75, 0xE2,
    418     0x4C, 0x2E, 0x3A, 0xD0, 0xC7, 0x28, 0x72, 0x36, 0x12, 0x95, 0x25, 0xEE,
    419     0x15, 0xB5, 0xDD, 0x79, 0x98, 0xAA, 0x04, 0xC4, 0xA9, 0x69, 0x6C, 0xAC,
    420     0xD7, 0x17, 0x20, 0x83, 0xA9, 0x7A, 0x81, 0x66, 0x4E, 0xAD, 0x2C, 0x47,
    421     0x9E, 0x44, 0x4E, 0x4C, 0x06, 0x54, 0xCC, 0x19, 0xE2, 0x8D, 0x77, 0x03,
    422     0xCE, 0xE8, 0xDA, 0xCD, 0x61, 0x26, 0xF5, 0xD6, 0x65, 0xEC, 0x52, 0xC6,
    423     0x72, 0x55, 0xDB, 0x92, 0x01, 0x4B, 0x03, 0x7E, 0xB6, 0x21, 0xA2, 0xAC,
    424     0x8E, 0x36, 0x5D, 0xE0, 0x71, 0xFF, 0xC1, 0x40, 0x0A, 0xCF, 0x07, 0x7A,
    425     0x12, 0x91, 0x3D, 0xD8, 0xDE, 0x89, 0x47, 0x34, 0x37, 0xAB, 0x7B, 0xA3,
    426     0x46, 0x74, 0x3C, 0x1B, 0x21, 0x5D, 0xD9, 0xC1, 0x21, 0x64, 0xA7, 0xE4,
    427     0x05, 0x31, 0x18, 0xD1, 0x99, 0xBE, 0xC8, 0xEF, 0x6F, 0xC5, 0x61, 0x17,
    428     0x0C, 0x84, 0xC8, 0x7D, 0x10, 0xEE, 0x9A, 0x67, 0x4A, 0x1F, 0xA8, 0xFF,
    429     0xE1, 0x3B, 0xDF, 0xBA, 0x1D, 0x44, 0xDE, 0x48, 0x94, 0x6D, 0x68, 0xDC,
    430     0x0C, 0xDD, 0x77, 0x76, 0x35, 0xA7, 0xAB, 0x5B, 0xFB, 0x1E, 0x4B, 0xB7,
    431     0xB8, 0x56, 0xF9, 0x68, 0x27, 0x73, 0x4C, 0x18, 0x41, 0x38, 0xE9, 0x15,
    432     0xD9, 0xC3, 0x00, 0x2E, 0xBC, 0xE5, 0x31, 0x20, 0x54, 0x6A, 0x7E, 0x20,
    433     0x02, 0x14, 0x2B, 0x6C
    434 };
    435 
    436 static const unsigned char dhtest_2048_224_Z[] = {
    437     0x34, 0xD9, 0xBD, 0xDC, 0x1B, 0x42, 0x17, 0x6C, 0x31, 0x3F, 0xEA, 0x03,
    438     0x4C, 0x21, 0x03, 0x4D, 0x07, 0x4A, 0x63, 0x13, 0xBB, 0x4E, 0xCD, 0xB3,
    439     0x70, 0x3F, 0xFF, 0x42, 0x45, 0x67, 0xA4, 0x6B, 0xDF, 0x75, 0x53, 0x0E,
    440     0xDE, 0x0A, 0x9D, 0xA5, 0x22, 0x9D, 0xE7, 0xD7, 0x67, 0x32, 0x28, 0x6C,
    441     0xBC, 0x0F, 0x91, 0xDA, 0x4C, 0x3C, 0x85, 0x2F, 0xC0, 0x99, 0xC6, 0x79,
    442     0x53, 0x1D, 0x94, 0xC7, 0x8A, 0xB0, 0x3D, 0x9D, 0xEC, 0xB0, 0xA4, 0xE4,
    443     0xCA, 0x8B, 0x2B, 0xB4, 0x59, 0x1C, 0x40, 0x21, 0xCF, 0x8C, 0xE3, 0xA2,
    444     0x0A, 0x54, 0x1D, 0x33, 0x99, 0x40, 0x17, 0xD0, 0x20, 0x0A, 0xE2, 0xC9,
    445     0x51, 0x6E, 0x2F, 0xF5, 0x14, 0x57, 0x79, 0x26, 0x9E, 0x86, 0x2B, 0x0F,
    446     0xB4, 0x74, 0xA2, 0xD5, 0x6D, 0xC3, 0x1E, 0xD5, 0x69, 0xA7, 0x70, 0x0B,
    447     0x4C, 0x4A, 0xB1, 0x6B, 0x22, 0xA4, 0x55, 0x13, 0x53, 0x1E, 0xF5, 0x23,
    448     0xD7, 0x12, 0x12, 0x07, 0x7B, 0x5A, 0x16, 0x9B, 0xDE, 0xFF, 0xAD, 0x7A,
    449     0xD9, 0x60, 0x82, 0x84, 0xC7, 0x79, 0x5B, 0x6D, 0x5A, 0x51, 0x83, 0xB8,
    450     0x70, 0x66, 0xDE, 0x17, 0xD8, 0xD6, 0x71, 0xC9, 0xEB, 0xD8, 0xEC, 0x89,
    451     0x54, 0x4D, 0x45, 0xEC, 0x06, 0x15, 0x93, 0xD4, 0x42, 0xC6, 0x2A, 0xB9,
    452     0xCE, 0x3B, 0x1C, 0xB9, 0x94, 0x3A, 0x1D, 0x23, 0xA5, 0xEA, 0x3B, 0xCF,
    453     0x21, 0xA0, 0x14, 0x71, 0xE6, 0x7E, 0x00, 0x3E, 0x7F, 0x8A, 0x69, 0xC7,
    454     0x28, 0xBE, 0x49, 0x0B, 0x2F, 0xC8, 0x8C, 0xFE, 0xB9, 0x2D, 0xB6, 0xA2,
    455     0x15, 0xE5, 0xD0, 0x3C, 0x17, 0xC4, 0x64, 0xC9, 0xAC, 0x1A, 0x46, 0xE2,
    456     0x03, 0xE1, 0x3F, 0x95, 0x29, 0x95, 0xFB, 0x03, 0xC6, 0x9D, 0x3C, 0xC4,
    457     0x7F, 0xCB, 0x51, 0x0B, 0x69, 0x98, 0xFF, 0xD3, 0xAA, 0x6D, 0xE7, 0x3C,
    458     0xF9, 0xF6, 0x38, 0x69
    459 };
    460 
    461 static const unsigned char dhtest_2048_256_xA[] = {
    462     0x08, 0x81, 0x38, 0x2C, 0xDB, 0x87, 0x66, 0x0C, 0x6D, 0xC1, 0x3E, 0x61,
    463     0x49, 0x38, 0xD5, 0xB9, 0xC8, 0xB2, 0xF2, 0x48, 0x58, 0x1C, 0xC5, 0xE3,
    464     0x1B, 0x35, 0x45, 0x43, 0x97, 0xFC, 0xE5, 0x0E
    465 };
    466 
    467 static const unsigned char dhtest_2048_256_yA[] = {
    468     0x2E, 0x93, 0x80, 0xC8, 0x32, 0x3A, 0xF9, 0x75, 0x45, 0xBC, 0x49, 0x41,
    469     0xDE, 0xB0, 0xEC, 0x37, 0x42, 0xC6, 0x2F, 0xE0, 0xEC, 0xE8, 0x24, 0xA6,
    470     0xAB, 0xDB, 0xE6, 0x6C, 0x59, 0xBE, 0xE0, 0x24, 0x29, 0x11, 0xBF, 0xB9,
    471     0x67, 0x23, 0x5C, 0xEB, 0xA3, 0x5A, 0xE1, 0x3E, 0x4E, 0xC7, 0x52, 0xBE,
    472     0x63, 0x0B, 0x92, 0xDC, 0x4B, 0xDE, 0x28, 0x47, 0xA9, 0xC6, 0x2C, 0xB8,
    473     0x15, 0x27, 0x45, 0x42, 0x1F, 0xB7, 0xEB, 0x60, 0xA6, 0x3C, 0x0F, 0xE9,
    474     0x15, 0x9F, 0xCC, 0xE7, 0x26, 0xCE, 0x7C, 0xD8, 0x52, 0x3D, 0x74, 0x50,
    475     0x66, 0x7E, 0xF8, 0x40, 0xE4, 0x91, 0x91, 0x21, 0xEB, 0x5F, 0x01, 0xC8,
    476     0xC9, 0xB0, 0xD3, 0xD6, 0x48, 0xA9, 0x3B, 0xFB, 0x75, 0x68, 0x9E, 0x82,
    477     0x44, 0xAC, 0x13, 0x4A, 0xF5, 0x44, 0x71, 0x1C, 0xE7, 0x9A, 0x02, 0xDC,
    478     0xC3, 0x42, 0x26, 0x68, 0x47, 0x80, 0xDD, 0xDC, 0xB4, 0x98, 0x59, 0x41,
    479     0x06, 0xC3, 0x7F, 0x5B, 0xC7, 0x98, 0x56, 0x48, 0x7A, 0xF5, 0xAB, 0x02,
    480     0x2A, 0x2E, 0x5E, 0x42, 0xF0, 0x98, 0x97, 0xC1, 0xA8, 0x5A, 0x11, 0xEA,
    481     0x02, 0x12, 0xAF, 0x04, 0xD9, 0xB4, 0xCE, 0xBC, 0x93, 0x7C, 0x3C, 0x1A,
    482     0x3E, 0x15, 0xA8, 0xA0, 0x34, 0x2E, 0x33, 0x76, 0x15, 0xC8, 0x4E, 0x7F,
    483     0xE3, 0xB8, 0xB9, 0xB8, 0x7F, 0xB1, 0xE7, 0x3A, 0x15, 0xAF, 0x12, 0xA3,
    484     0x0D, 0x74, 0x6E, 0x06, 0xDF, 0xC3, 0x4F, 0x29, 0x0D, 0x79, 0x7C, 0xE5,
    485     0x1A, 0xA1, 0x3A, 0xA7, 0x85, 0xBF, 0x66, 0x58, 0xAF, 0xF5, 0xE4, 0xB0,
    486     0x93, 0x00, 0x3C, 0xBE, 0xAF, 0x66, 0x5B, 0x3C, 0x2E, 0x11, 0x3A, 0x3A,
    487     0x4E, 0x90, 0x52, 0x69, 0x34, 0x1D, 0xC0, 0x71, 0x14, 0x26, 0x68, 0x5F,
    488     0x4E, 0xF3, 0x7E, 0x86, 0x8A, 0x81, 0x26, 0xFF, 0x3F, 0x22, 0x79, 0xB5,
    489     0x7C, 0xA6, 0x7E, 0x29
    490 };
    491 
    492 static const unsigned char dhtest_2048_256_xB[] = {
    493     0x7D, 0x62, 0xA7, 0xE3, 0xEF, 0x36, 0xDE, 0x61, 0x7B, 0x13, 0xD1, 0xAF,
    494     0xB8, 0x2C, 0x78, 0x0D, 0x83, 0xA2, 0x3B, 0xD4, 0xEE, 0x67, 0x05, 0x64,
    495     0x51, 0x21, 0xF3, 0x71, 0xF5, 0x46, 0xA5, 0x3D
    496 };
    497 
    498 static const unsigned char dhtest_2048_256_yB[] = {
    499     0x57, 0x5F, 0x03, 0x51, 0xBD, 0x2B, 0x1B, 0x81, 0x74, 0x48, 0xBD, 0xF8,
    500     0x7A, 0x6C, 0x36, 0x2C, 0x1E, 0x28, 0x9D, 0x39, 0x03, 0xA3, 0x0B, 0x98,
    501     0x32, 0xC5, 0x74, 0x1F, 0xA2, 0x50, 0x36, 0x3E, 0x7A, 0xCB, 0xC7, 0xF7,
    502     0x7F, 0x3D, 0xAC, 0xBC, 0x1F, 0x13, 0x1A, 0xDD, 0x8E, 0x03, 0x36, 0x7E,
    503     0xFF, 0x8F, 0xBB, 0xB3, 0xE1, 0xC5, 0x78, 0x44, 0x24, 0x80, 0x9B, 0x25,
    504     0xAF, 0xE4, 0xD2, 0x26, 0x2A, 0x1A, 0x6F, 0xD2, 0xFA, 0xB6, 0x41, 0x05,
    505     0xCA, 0x30, 0xA6, 0x74, 0xE0, 0x7F, 0x78, 0x09, 0x85, 0x20, 0x88, 0x63,
    506     0x2F, 0xC0, 0x49, 0x23, 0x37, 0x91, 0xAD, 0x4E, 0xDD, 0x08, 0x3A, 0x97,
    507     0x8B, 0x88, 0x3E, 0xE6, 0x18, 0xBC, 0x5E, 0x0D, 0xD0, 0x47, 0x41, 0x5F,
    508     0x2D, 0x95, 0xE6, 0x83, 0xCF, 0x14, 0x82, 0x6B, 0x5F, 0xBE, 0x10, 0xD3,
    509     0xCE, 0x41, 0xC6, 0xC1, 0x20, 0xC7, 0x8A, 0xB2, 0x00, 0x08, 0xC6, 0x98,
    510     0xBF, 0x7F, 0x0B, 0xCA, 0xB9, 0xD7, 0xF4, 0x07, 0xBE, 0xD0, 0xF4, 0x3A,
    511     0xFB, 0x29, 0x70, 0xF5, 0x7F, 0x8D, 0x12, 0x04, 0x39, 0x63, 0xE6, 0x6D,
    512     0xDD, 0x32, 0x0D, 0x59, 0x9A, 0xD9, 0x93, 0x6C, 0x8F, 0x44, 0x13, 0x7C,
    513     0x08, 0xB1, 0x80, 0xEC, 0x5E, 0x98, 0x5C, 0xEB, 0xE1, 0x86, 0xF3, 0xD5,
    514     0x49, 0x67, 0x7E, 0x80, 0x60, 0x73, 0x31, 0xEE, 0x17, 0xAF, 0x33, 0x80,
    515     0xA7, 0x25, 0xB0, 0x78, 0x23, 0x17, 0xD7, 0xDD, 0x43, 0xF5, 0x9D, 0x7A,
    516     0xF9, 0x56, 0x8A, 0x9B, 0xB6, 0x3A, 0x84, 0xD3, 0x65, 0xF9, 0x22, 0x44,
    517     0xED, 0x12, 0x09, 0x88, 0x21, 0x93, 0x02, 0xF4, 0x29, 0x24, 0xC7, 0xCA,
    518     0x90, 0xB8, 0x9D, 0x24, 0xF7, 0x1B, 0x0A, 0xB6, 0x97, 0x82, 0x3D, 0x7D,
    519     0xEB, 0x1A, 0xFF, 0x5B, 0x0E, 0x8E, 0x4A, 0x45, 0xD4, 0x9F, 0x7F, 0x53,
    520     0x75, 0x7E, 0x19, 0x13
    521 };
    522 
    523 static const unsigned char dhtest_2048_256_Z[] = {
    524     0x86, 0xC7, 0x0B, 0xF8, 0xD0, 0xBB, 0x81, 0xBB, 0x01, 0x07, 0x8A, 0x17,
    525     0x21, 0x9C, 0xB7, 0xD2, 0x72, 0x03, 0xDB, 0x2A, 0x19, 0xC8, 0x77, 0xF1,
    526     0xD1, 0xF1, 0x9F, 0xD7, 0xD7, 0x7E, 0xF2, 0x25, 0x46, 0xA6, 0x8F, 0x00,
    527     0x5A, 0xD5, 0x2D, 0xC8, 0x45, 0x53, 0xB7, 0x8F, 0xC6, 0x03, 0x30, 0xBE,
    528     0x51, 0xEA, 0x7C, 0x06, 0x72, 0xCA, 0xC1, 0x51, 0x5E, 0x4B, 0x35, 0xC0,
    529     0x47, 0xB9, 0xA5, 0x51, 0xB8, 0x8F, 0x39, 0xDC, 0x26, 0xDA, 0x14, 0xA0,
    530     0x9E, 0xF7, 0x47, 0x74, 0xD4, 0x7C, 0x76, 0x2D, 0xD1, 0x77, 0xF9, 0xED,
    531     0x5B, 0xC2, 0xF1, 0x1E, 0x52, 0xC8, 0x79, 0xBD, 0x95, 0x09, 0x85, 0x04,
    532     0xCD, 0x9E, 0xEC, 0xD8, 0xA8, 0xF9, 0xB3, 0xEF, 0xBD, 0x1F, 0x00, 0x8A,
    533     0xC5, 0x85, 0x30, 0x97, 0xD9, 0xD1, 0x83, 0x7F, 0x2B, 0x18, 0xF7, 0x7C,
    534     0xD7, 0xBE, 0x01, 0xAF, 0x80, 0xA7, 0xC7, 0xB5, 0xEA, 0x3C, 0xA5, 0x4C,
    535     0xC0, 0x2D, 0x0C, 0x11, 0x6F, 0xEE, 0x3F, 0x95, 0xBB, 0x87, 0x39, 0x93,
    536     0x85, 0x87, 0x5D, 0x7E, 0x86, 0x74, 0x7E, 0x67, 0x6E, 0x72, 0x89, 0x38,
    537     0xAC, 0xBF, 0xF7, 0x09, 0x8E, 0x05, 0xBE, 0x4D, 0xCF, 0xB2, 0x40, 0x52,
    538     0xB8, 0x3A, 0xEF, 0xFB, 0x14, 0x78, 0x3F, 0x02, 0x9A, 0xDB, 0xDE, 0x7F,
    539     0x53, 0xFA, 0xE9, 0x20, 0x84, 0x22, 0x40, 0x90, 0xE0, 0x07, 0xCE, 0xE9,
    540     0x4D, 0x4B, 0xF2, 0xBA, 0xCE, 0x9F, 0xFD, 0x4B, 0x57, 0xD2, 0xAF, 0x7C,
    541     0x72, 0x4D, 0x0C, 0xAA, 0x19, 0xBF, 0x05, 0x01, 0xF6, 0xF1, 0x7B, 0x4A,
    542     0xA1, 0x0F, 0x42, 0x5E, 0x3E, 0xA7, 0x60, 0x80, 0xB4, 0xB9, 0xD6, 0xB3,
    543     0xCE, 0xFE, 0xA1, 0x15, 0xB2, 0xCE, 0xB8, 0x78, 0x9B, 0xB8, 0xA3, 0xB0,
    544     0xEA, 0x87, 0xFE, 0xBE, 0x63, 0xB6, 0xC8, 0xF8, 0x46, 0xEC, 0x6D, 0xB0,
    545     0xC2, 0x6C, 0x5D, 0x7C
    546 };
    547 
    548 typedef struct {
    549     DH *(*get_param)(void);
    550     const unsigned char *xA;
    551     size_t xA_len;
    552     const unsigned char *yA;
    553     size_t yA_len;
    554     const unsigned char *xB;
    555     size_t xB_len;
    556     const unsigned char *yB;
    557     size_t yB_len;
    558     const unsigned char *Z;
    559     size_t Z_len;
    560 } rfc5114_td;
    561 
    562 #define make_rfc5114_td(pre) {                    \
    563     DH_get_##pre,                                 \
    564     dhtest_##pre##_xA, sizeof(dhtest_##pre##_xA), \
    565     dhtest_##pre##_yA, sizeof(dhtest_##pre##_yA), \
    566     dhtest_##pre##_xB, sizeof(dhtest_##pre##_xB), \
    567     dhtest_##pre##_yB, sizeof(dhtest_##pre##_yB), \
    568     dhtest_##pre##_Z, sizeof(dhtest_##pre##_Z)    \
    569 }
    570 
    571 static const rfc5114_td rfctd[] = {
    572     make_rfc5114_td(1024_160),
    573     make_rfc5114_td(2048_224),
    574     make_rfc5114_td(2048_256)
    575 };
    576 
    577 static int rfc5114_test(void)
    578 {
    579     int i;
    580     DH *dhA = NULL;
    581     DH *dhB = NULL;
    582     unsigned char *Z1 = NULL;
    583     unsigned char *Z2 = NULL;
    584     int szA, szB;
    585     const rfc5114_td *td = NULL;
    586     BIGNUM *priv_key = NULL, *pub_key = NULL;
    587     const BIGNUM *pub_key_tmp;
    588 
    589     for (i = 0; i < (int)OSSL_NELEM(rfctd); i++) {
    590         td = rfctd + i;
    591         /* Set up DH structures setting key components */
    592         if (!TEST_ptr(dhA = td->get_param())
    593             || !TEST_ptr(dhB = td->get_param()))
    594             goto bad_err;
    595 
    596         if (!TEST_ptr(priv_key = BN_bin2bn(td->xA, td->xA_len, NULL))
    597             || !TEST_ptr(pub_key = BN_bin2bn(td->yA, td->yA_len, NULL))
    598             || !TEST_true(DH_set0_key(dhA, pub_key, priv_key)))
    599             goto bad_err;
    600 
    601         if (!TEST_ptr(priv_key = BN_bin2bn(td->xB, td->xB_len, NULL))
    602             || !TEST_ptr(pub_key = BN_bin2bn(td->yB, td->yB_len, NULL))
    603             || !TEST_true(DH_set0_key(dhB, pub_key, priv_key)))
    604             goto bad_err;
    605         priv_key = pub_key = NULL;
    606 
    607         if (!TEST_int_gt(szA = DH_size(dhA), 0)
    608             || !TEST_int_gt(szB = DH_size(dhB), 0)
    609             || !TEST_size_t_eq(td->Z_len, (size_t)szA)
    610             || !TEST_size_t_eq(td->Z_len, (size_t)szB))
    611             goto err;
    612 
    613         if (!TEST_ptr(Z1 = OPENSSL_malloc((size_t)szA))
    614             || !TEST_ptr(Z2 = OPENSSL_malloc((size_t)szB)))
    615             goto bad_err;
    616         /*
    617          * Work out shared secrets using both sides and compare with expected
    618          * values.
    619          */
    620         DH_get0_key(dhB, &pub_key_tmp, NULL);
    621         if (!TEST_int_ne(DH_compute_key(Z1, pub_key_tmp, dhA), -1))
    622             goto bad_err;
    623 
    624         DH_get0_key(dhA, &pub_key_tmp, NULL);
    625         if (!TEST_int_ne(DH_compute_key(Z2, pub_key_tmp, dhB), -1))
    626             goto bad_err;
    627 
    628         if (!TEST_mem_eq(Z1, td->Z_len, td->Z, td->Z_len)
    629             || !TEST_mem_eq(Z2, td->Z_len, td->Z, td->Z_len))
    630             goto err;
    631 
    632         DH_free(dhA);
    633         dhA = NULL;
    634         DH_free(dhB);
    635         dhB = NULL;
    636         OPENSSL_free(Z1);
    637         Z1 = NULL;
    638         OPENSSL_free(Z2);
    639         Z2 = NULL;
    640     }
    641     return 1;
    642 
    643 bad_err:
    644     DH_free(dhA);
    645     DH_free(dhB);
    646     BN_free(pub_key);
    647     BN_free(priv_key);
    648     OPENSSL_free(Z1);
    649     OPENSSL_free(Z2);
    650     TEST_error("Initialisation error RFC5114 set %d\n", i + 1);
    651     return 0;
    652 
    653 err:
    654     DH_free(dhA);
    655     DH_free(dhB);
    656     OPENSSL_free(Z1);
    657     OPENSSL_free(Z2);
    658     TEST_error("Test failed RFC5114 set %d\n", i + 1);
    659     return 0;
    660 }
    661 
    662 static int rfc7919_test(void)
    663 {
    664     DH *a = NULL, *b = NULL;
    665     const BIGNUM *apub_key = NULL, *bpub_key = NULL;
    666     unsigned char *abuf = NULL;
    667     unsigned char *bbuf = NULL;
    668     int i, alen, blen, aout, bout;
    669     int ret = 0;
    670 
    671     if (!TEST_ptr(a = DH_new_by_nid(NID_ffdhe2048)))
    672         goto err;
    673 
    674     if (!DH_check(a, &i))
    675         goto err;
    676     if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
    677         || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
    678         || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
    679         || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR)
    680         || !TEST_false(i))
    681         goto err;
    682 
    683     if (!DH_generate_key(a))
    684         goto err;
    685     DH_get0_key(a, &apub_key, NULL);
    686 
    687     /* now create another copy of the DH group for the peer */
    688     if (!TEST_ptr(b = DH_new_by_nid(NID_ffdhe2048)))
    689         goto err;
    690 
    691     if (!DH_generate_key(b))
    692         goto err;
    693     DH_get0_key(b, &bpub_key, NULL);
    694 
    695     alen = DH_size(a);
    696     if (!TEST_int_gt(alen, 0) || !TEST_ptr(abuf = OPENSSL_malloc(alen))
    697         || !TEST_int_gt((aout = DH_compute_key(abuf, bpub_key, a)), 0))
    698         goto err;
    699 
    700     blen = DH_size(b);
    701     if (!TEST_int_gt(blen, 0) || !TEST_ptr(bbuf = OPENSSL_malloc(blen))
    702         || !TEST_int_gt((bout = DH_compute_key(bbuf, apub_key, b)), 0))
    703         goto err;
    704 
    705     if (!TEST_true(aout >= 20)
    706         || !TEST_mem_eq(abuf, aout, bbuf, bout))
    707         goto err;
    708 
    709     ret = 1;
    710 
    711 err:
    712     OPENSSL_free(abuf);
    713     OPENSSL_free(bbuf);
    714     DH_free(a);
    715     DH_free(b);
    716     return ret;
    717 }
    718 
    719 static int prime_groups[] = {
    720     NID_ffdhe2048,
    721     NID_ffdhe3072,
    722     NID_ffdhe4096,
    723     NID_ffdhe6144,
    724     NID_ffdhe8192,
    725     NID_modp_2048,
    726     NID_modp_3072,
    727     NID_modp_4096,
    728     NID_modp_6144,
    729 };
    730 
    731 static int dh_test_prime_groups(int index)
    732 {
    733     int ok = 0;
    734     DH *dh = NULL;
    735     const BIGNUM *p, *q, *g;
    736 
    737     if (!TEST_ptr(dh = DH_new_by_nid(prime_groups[index])))
    738         goto err;
    739     DH_get0_pqg(dh, &p, &q, &g);
    740     if (!TEST_ptr(p) || !TEST_ptr(q) || !TEST_ptr(g))
    741         goto err;
    742 
    743     if (!TEST_int_eq(DH_get_nid(dh), prime_groups[index]))
    744         goto err;
    745 
    746     /* Since q is set there is no need for the private length to be set */
    747     if (!TEST_int_eq((int)DH_get_length(dh), 0))
    748         goto err;
    749 
    750     ok = 1;
    751 err:
    752     DH_free(dh);
    753     return ok;
    754 }
    755 
    756 static int dh_rfc5114_fix_nid_test(void)
    757 {
    758     int ok = 0;
    759     EVP_PKEY_CTX *paramgen_ctx;
    760 
    761     /* Run the test. Success is any time the test does not cause a SIGSEGV interrupt */
    762     paramgen_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DHX, 0);
    763     if (!TEST_ptr(paramgen_ctx))
    764         goto err;
    765     if (!TEST_int_eq(EVP_PKEY_paramgen_init(paramgen_ctx), 1))
    766         goto err;
    767     /* Tested function is called here */
    768     if (!TEST_int_eq(EVP_PKEY_CTX_set_dhx_rfc5114(paramgen_ctx, 3), 1))
    769         goto err;
    770     /* Negative test */
    771     if (!TEST_int_eq(EVP_PKEY_CTX_set_dhx_rfc5114(paramgen_ctx, 99), 0))
    772         goto err;
    773     /* If we're still running then the test passed. */
    774     ok = 1;
    775 err:
    776     EVP_PKEY_CTX_free(paramgen_ctx);
    777     return ok;
    778 }
    779 
    780 static int dh_set_dh_nid_test(void)
    781 {
    782     int ok = 0;
    783     EVP_PKEY_CTX *paramgen_ctx;
    784 
    785     /* Run the test. Success is any time the test does not cause a SIGSEGV interrupt */
    786     paramgen_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_DH, 0);
    787     if (!TEST_ptr(paramgen_ctx))
    788         goto err;
    789     if (!TEST_int_eq(EVP_PKEY_paramgen_init(paramgen_ctx), 1))
    790         goto err;
    791     /* Tested function is called here */
    792     if (!TEST_int_eq(EVP_PKEY_CTX_set_dh_nid(paramgen_ctx, NID_ffdhe2048), 1))
    793         goto err;
    794     /* Negative test */
    795     if (!TEST_int_eq(EVP_PKEY_CTX_set_dh_nid(paramgen_ctx, NID_secp521r1), 0))
    796         goto err;
    797     /* If we're still running then the test passed. */
    798     ok = 1;
    799 err:
    800     EVP_PKEY_CTX_free(paramgen_ctx);
    801     return ok;
    802 }
    803 
    804 static int dh_get_nid(void)
    805 {
    806     int ok = 0;
    807     const BIGNUM *p, *q, *g;
    808     BIGNUM *pcpy = NULL, *gcpy = NULL, *qcpy = NULL;
    809     DH *dh1 = DH_new_by_nid(NID_ffdhe2048);
    810     DH *dh2 = DH_new();
    811 
    812     if (!TEST_ptr(dh1)
    813         || !TEST_ptr(dh2))
    814         goto err;
    815 
    816     /* Set new DH parameters manually using a existing named group's p & g */
    817     DH_get0_pqg(dh1, &p, &q, &g);
    818     if (!TEST_ptr(p)
    819         || !TEST_ptr(q)
    820         || !TEST_ptr(g)
    821         || !TEST_ptr(pcpy = BN_dup(p))
    822         || !TEST_ptr(gcpy = BN_dup(g)))
    823         goto err;
    824 
    825     if (!TEST_true(DH_set0_pqg(dh2, pcpy, NULL, gcpy)))
    826         goto err;
    827     pcpy = gcpy = NULL;
    828     /* Test q is set if p and g are provided */
    829     if (!TEST_ptr(DH_get0_q(dh2)))
    830         goto err;
    831 
    832     /* Test that setting p & g manually returns that it is a named group */
    833     if (!TEST_int_eq(DH_get_nid(dh2), NID_ffdhe2048))
    834         goto err;
    835 
    836     /* Test that after changing g it is no longer a named group */
    837     if (!TEST_ptr(gcpy = BN_dup(BN_value_one())))
    838         goto err;
    839     if (!TEST_true(DH_set0_pqg(dh2, NULL, NULL, gcpy)))
    840         goto err;
    841     gcpy = NULL;
    842     if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
    843         goto err;
    844 
    845     /* Test that setting an incorrect q results in this not being a named group */
    846     if (!TEST_ptr(pcpy = BN_dup(p))
    847         || !TEST_ptr(qcpy = BN_dup(q))
    848         || !TEST_ptr(gcpy = BN_dup(g))
    849         || !TEST_int_eq(BN_add_word(qcpy, 2), 1)
    850         || !TEST_true(DH_set0_pqg(dh2, pcpy, qcpy, gcpy)))
    851         goto err;
    852     pcpy = qcpy = gcpy = NULL;
    853     if (!TEST_int_eq(DH_get_nid(dh2), NID_undef))
    854         goto err;
    855 
    856     ok = 1;
    857 err:
    858     BN_free(pcpy);
    859     BN_free(qcpy);
    860     BN_free(gcpy);
    861     DH_free(dh2);
    862     DH_free(dh1);
    863     return ok;
    864 }
    865 
    866 static const unsigned char dh_pub_der[] = {
    867     0x30, 0x82, 0x02, 0x28, 0x30, 0x82, 0x01, 0x1b, 0x06, 0x09, 0x2a, 0x86,
    868     0x48, 0x86, 0xf7, 0x0d, 0x01, 0x03, 0x01, 0x30, 0x82, 0x01, 0x0c, 0x02,
    869     0x82, 0x01, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    870     0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34, 0xc4, 0xc6, 0x62, 0x8b,
    871     0x80, 0xdc, 0x1c, 0xd1, 0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74,
    872     0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22, 0x51, 0x4a, 0x08, 0x79,
    873     0x8e, 0x34, 0x04, 0xdd, 0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b,
    874     0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37, 0x4f, 0xe1, 0x35, 0x6d,
    875     0x6d, 0x51, 0xc2, 0x45, 0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
    876     0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b, 0x0b, 0xff, 0x5c, 0xb6,
    877     0xf4, 0x06, 0xb7, 0xed, 0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5,
    878     0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6, 0x49, 0x28, 0x66, 0x51,
    879     0xec, 0xe4, 0x5b, 0x3d, 0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05,
    880     0x98, 0xda, 0x48, 0x36, 0x1c, 0x55, 0xd3, 0x9a, 0x69, 0x16, 0x3f, 0xa8,
    881     0xfd, 0x24, 0xcf, 0x5f, 0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96,
    882     0x1c, 0x62, 0xf3, 0x56, 0x20, 0x85, 0x52, 0xbb, 0x9e, 0xd5, 0x29, 0x07,
    883     0x70, 0x96, 0x96, 0x6d, 0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04,
    884     0xf1, 0x74, 0x6c, 0x08, 0xca, 0x18, 0x21, 0x7c, 0x32, 0x90, 0x5e, 0x46,
    885     0x2e, 0x36, 0xce, 0x3b, 0xe3, 0x9e, 0x77, 0x2c, 0x18, 0x0e, 0x86, 0x03,
    886     0x9b, 0x27, 0x83, 0xa2, 0xec, 0x07, 0xa2, 0x8f, 0xb5, 0xc5, 0x5d, 0xf0,
    887     0x6f, 0x4c, 0x52, 0xc9, 0xde, 0x2b, 0xcb, 0xf6, 0x95, 0x58, 0x17, 0x18,
    888     0x39, 0x95, 0x49, 0x7c, 0xea, 0x95, 0x6a, 0xe5, 0x15, 0xd2, 0x26, 0x18,
    889     0x98, 0xfa, 0x05, 0x10, 0x15, 0x72, 0x8e, 0x5a, 0x8a, 0xac, 0xaa, 0x68,
    890     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x01, 0x02, 0x02,
    891     0x02, 0x04, 0x00, 0x03, 0x82, 0x01, 0x05, 0x00, 0x02, 0x82, 0x01, 0x00,
    892     0x08, 0x87, 0x8a, 0x5f, 0x4f, 0x3b, 0xef, 0xe1, 0x77, 0x13, 0x3b, 0xd7,
    893     0x58, 0x76, 0xc9, 0xeb, 0x7e, 0x2d, 0xcc, 0x7e, 0xed, 0xc5, 0xee, 0xf9,
    894     0x2d, 0x55, 0xb0, 0xe2, 0x37, 0x8c, 0x51, 0x87, 0x6a, 0x8e, 0x0d, 0xb2,
    895     0x08, 0xed, 0x4f, 0x88, 0x9b, 0x63, 0x19, 0x7a, 0x67, 0xa1, 0x61, 0xd8,
    896     0x17, 0xa0, 0x2c, 0xdb, 0xc2, 0xfa, 0xb3, 0x4f, 0xe7, 0xcb, 0x16, 0xf2,
    897     0xe7, 0xd0, 0x2c, 0xf8, 0xcc, 0x97, 0xd3, 0xe7, 0xae, 0xc2, 0x71, 0xd8,
    898     0x2b, 0x12, 0x83, 0xe9, 0x5a, 0x45, 0xfe, 0x66, 0x5c, 0xa2, 0xb6, 0xce,
    899     0x2f, 0x04, 0x05, 0xe7, 0xa7, 0xbc, 0xe5, 0x63, 0x1a, 0x93, 0x3d, 0x4d,
    900     0xf4, 0x77, 0xdd, 0x2a, 0xc9, 0x51, 0x7b, 0xf5, 0x54, 0xa2, 0xab, 0x26,
    901     0xee, 0x16, 0xd3, 0x83, 0x92, 0x85, 0x40, 0x67, 0xa3, 0xa9, 0x31, 0x16,
    902     0x64, 0x45, 0x5a, 0x2a, 0x9d, 0xa8, 0x1a, 0x84, 0x2f, 0x59, 0x57, 0x6b,
    903     0xbb, 0x51, 0x28, 0xbd, 0x91, 0x60, 0xd9, 0x8f, 0x54, 0x6a, 0xa0, 0x6b,
    904     0xb2, 0xf6, 0x78, 0x79, 0xd2, 0x3a, 0x8f, 0xa6, 0x24, 0x7e, 0xe9, 0x6e,
    905     0x66, 0x30, 0xed, 0xbf, 0x55, 0x71, 0x9c, 0x89, 0x81, 0xf0, 0xa7, 0xe7,
    906     0x05, 0x87, 0x51, 0xc1, 0xff, 0xe5, 0xcf, 0x1f, 0x19, 0xe4, 0xeb, 0x7c,
    907     0x1c, 0x1a, 0x58, 0xd5, 0x22, 0x3d, 0x31, 0x22, 0xc7, 0x8b, 0x60, 0xf5,
    908     0xe8, 0x95, 0x73, 0xe0, 0x20, 0xe2, 0x4f, 0x03, 0x9e, 0x89, 0x34, 0x91,
    909     0x5e, 0xda, 0x4f, 0x60, 0xff, 0xc9, 0x4f, 0x5a, 0x37, 0x1e, 0xb0, 0xed,
    910     0x26, 0x4c, 0xa4, 0xc6, 0x26, 0xc9, 0xcc, 0xab, 0xd2, 0x1a, 0x3a, 0x82,
    911     0x68, 0x03, 0x49, 0x8f, 0xb0, 0xb9, 0xc8, 0x48, 0x9d, 0xc7, 0xdf, 0x8b,
    912     0x1c, 0xbf, 0xda, 0x89, 0x78, 0x6f, 0xd3, 0x62, 0xad, 0x35, 0xb9, 0xd3,
    913     0x9b, 0xd0, 0x25, 0x65
    914 };
    915 
    916 /*
    917  * Load PKCS3 DH Parameters that contain an optional private value length.
    918  * Loading a named group should not overwrite the private value length field.
    919  */
    920 static int dh_load_pkcs3_namedgroup_privlen_test(void)
    921 {
    922     int ret, privlen = 0;
    923     EVP_PKEY *pkey = NULL;
    924     const unsigned char *p = dh_pub_der;
    925 
    926     ret = TEST_ptr(pkey = d2i_PUBKEY_ex(NULL, &p, sizeof(dh_pub_der),
    927                        NULL, NULL))
    928         && TEST_true(EVP_PKEY_get_int_param(pkey, OSSL_PKEY_PARAM_DH_PRIV_LEN,
    929             &privlen))
    930         && TEST_int_eq(privlen, 1024);
    931 
    932     EVP_PKEY_free(pkey);
    933     return ret;
    934 }
    935 
    936 #endif
    937 
    938 int setup_tests(void)
    939 {
    940 #ifdef OPENSSL_NO_DH
    941     TEST_note("No DH support");
    942 #else
    943     ADD_TEST(dh_test);
    944     ADD_TEST(dh_computekey_range_test);
    945     ADD_TEST(rfc5114_test);
    946     ADD_TEST(rfc7919_test);
    947     ADD_ALL_TESTS(dh_test_prime_groups, OSSL_NELEM(prime_groups));
    948     ADD_TEST(dh_get_nid);
    949     ADD_TEST(dh_load_pkcs3_namedgroup_privlen_test);
    950     ADD_TEST(dh_rfc5114_fix_nid_test);
    951     ADD_TEST(dh_set_dh_nid_test);
    952 #endif
    953     return 1;
    954 }
    955