/*
 * 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
 */

/*
 * NB: These functions have been upgraded - the previous prototypes are in
 * dh_depr.c as wrappers to these ones.  - Geoff
 */

/*
 * DH low level APIs are deprecated for public use, but still ok for
 * internal use.
 *
 * NOTE: When generating keys for key-agreement schemes - FIPS 140-2 IG 9.9
 * states that no additional pairwise tests are required (apart from the tests
 * specified in SP800-56A) when generating keys. Hence DH pairwise tests are
 * omitted here.
 */
#include "internal/deprecated.h"

#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/bn.h>
#include <openssl/sha.h>
#include "crypto/dh.h"
#include "dh_local.h"

#ifndef FIPS_MODULE
static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
                                BN_GENCB *cb);
#endif /* FIPS_MODULE */

int ossl_dh_generate_ffc_parameters(DH *dh, int type, int pbits, int qbits,
                                    BN_GENCB *cb)
{
    int ret, res;

#ifndef FIPS_MODULE
    if (type == DH_PARAMGEN_TYPE_FIPS_186_2)
        ret = ossl_ffc_params_FIPS186_2_generate(dh->libctx, &dh->params,
                                                 FFC_PARAM_TYPE_DH,
                                                 pbits, qbits, &res, cb);
    else
#endif
        ret = ossl_ffc_params_FIPS186_4_generate(dh->libctx, &dh->params,
                                                 FFC_PARAM_TYPE_DH,
                                                 pbits, qbits, &res, cb);
    if (ret > 0)
        dh->dirty_cnt++;
    return ret;
}

int ossl_dh_get_named_group_uid_from_size(int pbits)
{
    /*
     * Just choose an approved safe prime group.
     * The alternative to this is to generate FIPS186-4 domain parameters i.e.
     * return dh_generate_ffc_parameters(ret, prime_len, 0, NULL, cb);
     * As the FIPS186-4 generated params are for backwards compatibility,
     * the safe prime group should be used as the default.
     */
    int nid;

    switch (pbits) {
    case 2048:
        nid = NID_ffdhe2048;
        break;
    case 3072:
        nid = NID_ffdhe3072;
        break;
    case 4096:
        nid = NID_ffdhe4096;
        break;
    case 6144:
        nid = NID_ffdhe6144;
        break;
    case 8192:
        nid = NID_ffdhe8192;
        break;
    /* unsupported prime_len */
    default:
        return NID_undef;
    }
    return nid;
}

#ifdef FIPS_MODULE

static int dh_gen_named_group(OSSL_LIB_CTX *libctx, DH *ret, int prime_len)
{
    DH *dh;
    int ok = 0;
    int nid = ossl_dh_get_named_group_uid_from_size(prime_len);

    if (nid == NID_undef)
        return 0;

    dh = ossl_dh_new_by_nid_ex(libctx, nid);
    if (dh != NULL
        && ossl_ffc_params_copy(&ret->params, &dh->params)) {
        ok = 1;
        ret->dirty_cnt++;
    }
    DH_free(dh);
    return ok;
}
#endif /* FIPS_MODULE */

int DH_generate_parameters_ex(DH *ret, int prime_len, int generator,
                              BN_GENCB *cb)
{
#ifdef FIPS_MODULE
    if (generator != 2)
        return 0;
    return dh_gen_named_group(ret->libctx, ret, prime_len);
#else
    if (ret->meth->generate_params)
        return ret->meth->generate_params(ret, prime_len, generator, cb);
    return dh_builtin_genparams(ret, prime_len, generator, cb);
#endif /* FIPS_MODULE */
}

#ifndef FIPS_MODULE
/*-
 * We generate DH parameters as follows
 * find a prime p which is prime_len bits long,
 * where q=(p-1)/2 is also prime.
 * In the following we assume that g is not 0, 1 or p-1, since it
 * would generate only trivial subgroups.
 * For this case, g is a generator of the order-q subgroup if
 * g^q mod p == 1.
 * Or in terms of the Legendre symbol: (g/p) == 1.
 *
 * Having said all that,
 * there is another special case method for the generators 2, 3 and 5.
 * Using the quadratic reciprocity law it is possible to solve
 * (g/p) == 1 for the special values 2, 3, 5:
 * (2/p) == 1 if p mod 8 == 1 or 7.
 * (3/p) == 1 if p mod 12 == 1 or 11.
 * (5/p) == 1 if p mod 5 == 1 or 4.
 * See for instance: https://en.wikipedia.org/wiki/Legendre_symbol
 *
 * Since all safe primes > 7 must satisfy p mod 12 == 11
 * and all safe primes > 11 must satisfy p mod 5 != 1
 * we can further improve the condition for g = 2, 3 and 5:
 * for 2, p mod 24 == 23
 * for 3, p mod 12 == 11
 * for 5, p mod 60 == 59
 */
static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
                                BN_GENCB *cb)
{
    BIGNUM *t1, *t2;
    int g, ok = -1;
    BN_CTX *ctx = NULL;

    if (prime_len > OPENSSL_DH_MAX_MODULUS_BITS) {
        ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE);
        return 0;
    }

    if (prime_len < DH_MIN_MODULUS_BITS) {
        ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL);
        return 0;
    }

    ctx = BN_CTX_new();
    if (ctx == NULL)
        goto err;
    BN_CTX_start(ctx);
    t1 = BN_CTX_get(ctx);
    t2 = BN_CTX_get(ctx);
    if (t2 == NULL)
        goto err;

    /* Make sure 'ret' has the necessary elements */
    if (ret->params.p == NULL && ((ret->params.p = BN_new()) == NULL))
        goto err;
    if (ret->params.g == NULL && ((ret->params.g = BN_new()) == NULL))
        goto err;

    if (generator <= 1) {
        ERR_raise(ERR_LIB_DH, DH_R_BAD_GENERATOR);
        goto err;
    }
    if (generator == DH_GENERATOR_2) {
        if (!BN_set_word(t1, 24))
            goto err;
        if (!BN_set_word(t2, 23))
            goto err;
        g = 2;
    } else if (generator == DH_GENERATOR_5) {
        if (!BN_set_word(t1, 60))
            goto err;
        if (!BN_set_word(t2, 59))
            goto err;
        g = 5;
    } else {
        /*
         * in the general case, don't worry if 'generator' is a generator or
         * not: since we are using safe primes, it will generate either an
         * order-q or an order-2q group, which both is OK
         */
        if (!BN_set_word(t1, 12))
            goto err;
        if (!BN_set_word(t2, 11))
            goto err;
        g = generator;
    }

    if (!BN_generate_prime_ex(ret->params.p, prime_len, 1, t1, t2, cb))
        goto err;
    if (!BN_GENCB_call(cb, 3, 0))
        goto err;
    if (!BN_set_word(ret->params.g, g))
        goto err;
    ret->dirty_cnt++;
    ok = 1;
 err:
    if (ok == -1) {
        ERR_raise(ERR_LIB_DH, ERR_R_BN_LIB);
        ok = 0;
    }

    BN_CTX_end(ctx);
    BN_CTX_free(ctx);
    return ok;
}
#endif /* FIPS_MODULE */
