/*
 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 */

#include <openssl/evp.h>
#include <openssl/core_names.h>
#include <openssl/param_build.h>

#include "predefined_dhparams.h"

#ifndef OPENSSL_NO_DH

static EVP_PKEY *get_dh_from_pg_bn(OSSL_LIB_CTX *libctx, const char *type,
                                   BIGNUM *p, BIGNUM *g, BIGNUM *q)
{
    EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(libctx, type, NULL);
    OSSL_PARAM_BLD *tmpl = NULL;
    OSSL_PARAM *params = NULL;
    EVP_PKEY *dhpkey = NULL;

    if (pctx == NULL || !EVP_PKEY_fromdata_init(pctx))
        goto err;

    if ((tmpl = OSSL_PARAM_BLD_new()) == NULL
            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
            || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g)
            || (q != NULL
                && !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q)))
        goto err;

    params = OSSL_PARAM_BLD_to_param(tmpl);
    if (params == NULL
        || !EVP_PKEY_fromdata(pctx, &dhpkey, EVP_PKEY_KEY_PARAMETERS, params))
        goto err;

 err:
    EVP_PKEY_CTX_free(pctx);
    OSSL_PARAM_free(params);
    OSSL_PARAM_BLD_free(tmpl);
    return dhpkey;
}

static EVP_PKEY *get_dh_from_pg(OSSL_LIB_CTX *libctx, const char *type,
                                unsigned char *pdata, size_t plen,
                                unsigned char *gdata, size_t glen,
                                unsigned char *qdata, size_t qlen)
{
    EVP_PKEY *dhpkey = NULL;
    BIGNUM *p = NULL, *g = NULL, *q = NULL;

    p = BN_bin2bn(pdata, plen, NULL);
    g = BN_bin2bn(gdata, glen, NULL);
    if (p == NULL || g == NULL)
        goto err;
    if (qdata != NULL && (q = BN_bin2bn(qdata, qlen, NULL)) == NULL)
        goto err;

    dhpkey = get_dh_from_pg_bn(libctx, type, p, g, q);

 err:
    BN_free(p);
    BN_free(g);
    BN_free(q);
    return dhpkey;
}

EVP_PKEY *get_dh512(OSSL_LIB_CTX *libctx)
{
    static unsigned char dh512_p[] = {
        0xCB, 0xC8, 0xE1, 0x86, 0xD0, 0x1F, 0x94, 0x17, 0xA6, 0x99, 0xF0, 0xC6,
        0x1F, 0x0D, 0xAC, 0xB6, 0x25, 0x3E, 0x06, 0x39, 0xCA, 0x72, 0x04, 0xB0,
        0x6E, 0xDA, 0xC0, 0x61, 0xE6, 0x7A, 0x77, 0x25, 0xE8, 0x3B, 0xB9, 0x5F,
        0x9A, 0xB6, 0xB5, 0xFE, 0x99, 0x0B, 0xA1, 0x93, 0x4E, 0x35, 0x33, 0xB8,
        0xE1, 0xF1, 0x13, 0x4F, 0x59, 0x1A, 0xD2, 0x57, 0xC0, 0x26, 0x21, 0x33,
        0x02, 0xC5, 0xAE, 0x23,
    };
    static unsigned char dh512_g[] = {
        0x02,
    };

    return get_dh_from_pg(libctx, "DH", dh512_p, sizeof(dh512_p),
                          dh512_g, sizeof(dh512_g), NULL, 0);
}

EVP_PKEY *get_dhx512(OSSL_LIB_CTX *libctx)
{
    static unsigned char dhx512_p[] = {
        0x00, 0xe8, 0x1a, 0xb7, 0x9a, 0x02, 0x65, 0x64, 0x94, 0x7b, 0xba, 0x09,
        0x1c, 0x12, 0x27, 0x1e, 0xea, 0x89, 0x32, 0x64, 0x78, 0xf8, 0x1c, 0x78,
        0x8e, 0x96, 0xc3, 0xc6, 0x9f, 0x41, 0x05, 0x41, 0x65, 0xae, 0xe3, 0x05,
        0xea, 0x66, 0x21, 0xf7, 0x38, 0xb7, 0x2b, 0x32, 0x40, 0x5a, 0x14, 0x86,
        0x51, 0x94, 0xb1, 0xcf, 0x01, 0xe3, 0x27, 0x28, 0xf6, 0x75, 0xa3, 0x15,
        0xbb, 0x12, 0x4d, 0x99, 0xe7,
    };
    static unsigned char dhx512_g[] = {
        0x00, 0x91, 0xc1, 0x43, 0x6d, 0x0d, 0xb0, 0xa4, 0xde, 0x41, 0xb7, 0x93,
        0xad, 0x51, 0x94, 0x1b, 0x43, 0xd8, 0x42, 0xf1, 0x5e, 0x46, 0x83, 0x5d,
        0xf1, 0xd1, 0xf0, 0x41, 0x10, 0xd1, 0x1c, 0x5e, 0xad, 0x9b, 0x68, 0xb1,
        0x6f, 0xf5, 0x8e, 0xaa, 0x6d, 0x71, 0x88, 0x37, 0xdf, 0x05, 0xf7, 0x6e,
        0x7a, 0xb4, 0x25, 0x10, 0x6c, 0x7f, 0x38, 0xb4, 0xc8, 0xfc, 0xcc, 0x0c,
        0x6a, 0x02, 0x08, 0x61, 0xf6,
    };
    static unsigned char dhx512_q[] = {
        0x00, 0xdd, 0xf6, 0x35, 0xad, 0xfa, 0x70, 0xc7, 0xe7, 0xa8, 0xf0, 0xe3,
        0xda, 0x79, 0x34, 0x3f, 0x5b, 0xcf, 0x73, 0x82, 0x91,
    };

    return get_dh_from_pg(libctx, "X9.42 DH",
                          dhx512_p, sizeof(dhx512_p),
                          dhx512_g, sizeof(dhx512_g),
                          dhx512_q, sizeof(dhx512_q));
}

EVP_PKEY *get_dh1024dsa(OSSL_LIB_CTX *libctx)
{
    static unsigned char dh1024_p[] = {
        0xC8, 0x00, 0xF7, 0x08, 0x07, 0x89, 0x4D, 0x90, 0x53, 0xF3, 0xD5, 0x00,
        0x21, 0x1B, 0xF7, 0x31, 0xA6, 0xA2, 0xDA, 0x23, 0x9A, 0xC7, 0x87, 0x19,
        0x3B, 0x47, 0xB6, 0x8C, 0x04, 0x6F, 0xFF, 0xC6, 0x9B, 0xB8, 0x65, 0xD2,
        0xC2, 0x5F, 0x31, 0x83, 0x4A, 0xA7, 0x5F, 0x2F, 0x88, 0x38, 0xB6, 0x55,
        0xCF, 0xD9, 0x87, 0x6D, 0x6F, 0x9F, 0xDA, 0xAC, 0xA6, 0x48, 0xAF, 0xFC,
        0x33, 0x84, 0x37, 0x5B, 0x82, 0x4A, 0x31, 0x5D, 0xE7, 0xBD, 0x52, 0x97,
        0xA1, 0x77, 0xBF, 0x10, 0x9E, 0x37, 0xEA, 0x64, 0xFA, 0xCA, 0x28, 0x8D,
        0x9D, 0x3B, 0xD2, 0x6E, 0x09, 0x5C, 0x68, 0xC7, 0x45, 0x90, 0xFD, 0xBB,
        0x70, 0xC9, 0x3A, 0xBB, 0xDF, 0xD4, 0x21, 0x0F, 0xC4, 0x6A, 0x3C, 0xF6,
        0x61, 0xCF, 0x3F, 0xD6, 0x13, 0xF1, 0x5F, 0xBC, 0xCF, 0xBC, 0x26, 0x9E,
        0xBC, 0x0B, 0xBD, 0xAB, 0x5D, 0xC9, 0x54, 0x39,
    };
    static unsigned char dh1024_g[] = {
        0x3B, 0x40, 0x86, 0xE7, 0xF3, 0x6C, 0xDE, 0x67, 0x1C, 0xCC, 0x80, 0x05,
        0x5A, 0xDF, 0xFE, 0xBD, 0x20, 0x27, 0x74, 0x6C, 0x24, 0xC9, 0x03, 0xF3,
        0xE1, 0x8D, 0xC3, 0x7D, 0x98, 0x27, 0x40, 0x08, 0xB8, 0x8C, 0x6A, 0xE9,
        0xBB, 0x1A, 0x3A, 0xD6, 0x86, 0x83, 0x5E, 0x72, 0x41, 0xCE, 0x85, 0x3C,
        0xD2, 0xB3, 0xFC, 0x13, 0xCE, 0x37, 0x81, 0x9E, 0x4C, 0x1C, 0x7B, 0x65,
        0xD3, 0xE6, 0xA6, 0x00, 0xF5, 0x5A, 0x95, 0x43, 0x5E, 0x81, 0xCF, 0x60,
        0xA2, 0x23, 0xFC, 0x36, 0xA7, 0x5D, 0x7A, 0x4C, 0x06, 0x91, 0x6E, 0xF6,
        0x57, 0xEE, 0x36, 0xCB, 0x06, 0xEA, 0xF5, 0x3D, 0x95, 0x49, 0xCB, 0xA7,
        0xDD, 0x81, 0xDF, 0x80, 0x09, 0x4A, 0x97, 0x4D, 0xA8, 0x22, 0x72, 0xA1,
        0x7F, 0xC4, 0x70, 0x56, 0x70, 0xE8, 0x20, 0x10, 0x18, 0x8F, 0x2E, 0x60,
        0x07, 0xE7, 0x68, 0x1A, 0x82, 0x5D, 0x32, 0xA2,
    };

    return get_dh_from_pg(libctx, "DH", dh1024_p, sizeof(dh1024_p),
                          dh1024_g, sizeof(dh1024_g), NULL, 0);
}

EVP_PKEY *get_dh2048(OSSL_LIB_CTX *libctx)
{
    BIGNUM *p = NULL, *g = NULL;
    EVP_PKEY *dhpkey = NULL;

    g = BN_new();
    if (g == NULL || !BN_set_word(g, 2))
        goto err;

    p = BN_get_rfc3526_prime_2048(NULL);
    if (p == NULL)
        goto err;

    dhpkey = get_dh_from_pg_bn(libctx, "DH", p, g, NULL);

 err:
    BN_free(p);
    BN_free(g);
    return dhpkey;
}

#endif
