/*
 * Copyright 2017-2020 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
 */

/* DH parameters from RFC7919 and RFC3526 */

/*
 * DH low level APIs are deprecated for public use, but still ok for
 * internal use.
 */
#include "internal/deprecated.h"

#include <stdio.h>
#include "internal/cryptlib.h"
#include "internal/ffc.h"
#include "dh_local.h"
#include <openssl/bn.h>
#include <openssl/objects.h>
#include "crypto/bn_dh.h"
#include "crypto/dh.h"
#include "e_os.h" /* strcasecmp */

#define FFDHE(sz) {                                                            \
    SN_ffdhe##sz, NID_ffdhe##sz,                                               \
    sz,                                                                        \
    &_bignum_ffdhe##sz##_p, &_bignum_ffdhe##sz##_q, &_bignum_const_2           \
}

#define MODP(sz)  {                                                            \
    SN_modp_##sz, NID_modp_##sz,                                               \
    sz,                                                                        \
    &_bignum_modp_##sz##_p, &_bignum_modp_##sz##_q,  &_bignum_const_2          \
}

#define RFC5114(name, uid, sz, tag)  {                                         \
    name, uid,                                                                 \
    sz,                                                                        \
    &_bignum_dh##tag##_p, &_bignum_dh##tag##_q, &_bignum_dh##tag##_g           \
}

typedef struct dh_named_group_st {
    const char *name;
    int uid;
    int32_t nbits;
    const BIGNUM *p;
    const BIGNUM *q;
    const BIGNUM *g;
} DH_NAMED_GROUP;


static const DH_NAMED_GROUP dh_named_groups[] = {
    FFDHE(2048),
    FFDHE(3072),
    FFDHE(4096),
    FFDHE(6144),
    FFDHE(8192),
#ifndef FIPS_MODULE
    MODP(1536),
#endif
    MODP(2048),
    MODP(3072),
    MODP(4096),
    MODP(6144),
    MODP(8192),
    /*
     * Additional dh named groups from RFC 5114 that have a different g.
     * The uid can be any unique identifier.
     */
#ifndef FIPS_MODULE
    RFC5114("dh_1024_160", 1, 1024, 1024_160),
    RFC5114("dh_2048_224", 2, 2048, 2048_224),
    RFC5114("dh_2048_256", 3, 2048, 2048_256),
#endif
};

int ossl_ffc_named_group_to_uid(const char *name)
{
    size_t i;

    for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
        if (strcasecmp(dh_named_groups[i].name, name) == 0)
            return dh_named_groups[i].uid;
    }
    return NID_undef;
}

const char *ossl_ffc_named_group_from_uid(int uid)
{
    size_t i;

    for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
        if (dh_named_groups[i].uid == uid)
            return dh_named_groups[i].name;
    }
    return NULL;
}

static DH *dh_param_init(OSSL_LIB_CTX *libctx, int uid, const BIGNUM *p,
                         const BIGNUM *q, const BIGNUM *g)
{
    DH *dh = dh_new_ex(libctx);

    if (dh == NULL)
        return NULL;

    dh->params.nid = uid;
    dh->params.p = (BIGNUM *)p;
    dh->params.q = (BIGNUM *)q;
    dh->params.g = (BIGNUM *)g;
    dh->length = BN_num_bits(q);
    dh->dirty_cnt++;
    return dh;
}

static DH *dh_new_by_group_name(OSSL_LIB_CTX *libctx, const char *name)
{
    int i;

    if (name == NULL)
        return NULL;

    for (i = 0; i < (int)OSSL_NELEM(dh_named_groups); ++i) {
        if (strcasecmp(dh_named_groups[i].name, name) == 0) {
            return dh_param_init(libctx, dh_named_groups[i].uid,
                                 dh_named_groups[i].p,
                                 dh_named_groups[i].q,
                                 dh_named_groups[i].g);
        }
    }
    ERR_raise(ERR_LIB_DH, DH_R_INVALID_PARAMETER_NID);
    return NULL;
}

DH *dh_new_by_nid_ex(OSSL_LIB_CTX *libctx, int nid)
{
    const char *name = ossl_ffc_named_group_from_uid(nid);

    return dh_new_by_group_name(libctx, name);
}

DH *DH_new_by_nid(int nid)
{
    return dh_new_by_nid_ex(NULL, nid);
}

int ossl_ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name)
{
    int i;
    BIGNUM *q = NULL;

    if (ffc == NULL)
        return 0;

    for (i = 0; i < (int)OSSL_NELEM(dh_named_groups); ++i) {
        if (strcasecmp(dh_named_groups[i].name, group_name) == 0) {
            ossl_ffc_params_set0_pqg(ffc,
                                     (BIGNUM *)dh_named_groups[i].p,
                                     (BIGNUM *)dh_named_groups[i].q,
                                     (BIGNUM *)dh_named_groups[i].g);
            /* flush the cached nid, The DH layer is responsible for caching */
            ffc->nid = NID_undef;
            return 1;
        }
    }
    /* gets here on error or if the name was not found */
    BN_free(q);
    return 0;
}

void dh_cache_named_group(DH *dh)
{
    int i;

    if (dh == NULL)
        return;

    dh->params.nid = NID_undef; /* flush cached value */

    /* Exit if p or g is not set */
    if (dh->params.p == NULL
        || dh->params.g == NULL)
        return;

    for (i = 0; i < (int)OSSL_NELEM(dh_named_groups); ++i) {
        /* Keep searching until a matching p and g is found */
        if (BN_cmp(dh->params.p, dh_named_groups[i].p) == 0
            && BN_cmp(dh->params.g, dh_named_groups[i].g) == 0) {
                /* Verify q is correct if it exists */
                if (dh->params.q != NULL) {
                    if (BN_cmp(dh->params.q, dh_named_groups[i].q) != 0)
                        continue;  /* ignore if q does not match */
                } else {
                    dh->params.q = (BIGNUM *)dh_named_groups[i].q;
                }
                dh->params.nid = dh_named_groups[i].uid; /* cache the nid */
                dh->length = BN_num_bits(dh->params.q);
                dh->dirty_cnt++;
                break;
        }
    }
}

int DH_get_nid(const DH *dh)
{
    if (dh == NULL)
        return NID_undef;

    return dh->params.nid;
}
