Commit 7806a782 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

DH named parameter support



Add functions to return DH parameters using NID and to return the
NID if parameters match a named set. Currently this supports only
RFC7919 parameters but could be expanded in future.

Reviewed-by: default avatarAndy Polyakov <appro@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4485)
parent f682bd60
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -487,6 +487,10 @@ static const BN_ULONG ffdhe8192_p[] = {
                        OSSL_NELEM(x),\
                        0, BN_FLG_STATIC_DATA };

static const BN_ULONG value_2 = 2;

const BIGNUM _bignum_const_2 =
    { (BN_ULONG *)&value_2, 1, 1, 0, BN_FLG_STATIC_DATA };

make_dh_bn(dh1024_160_p)
make_dh_bn(dh1024_160_g)
+2 −1
Original line number Diff line number Diff line
LIBS=../../libcrypto
SOURCE[../../libcrypto]=\
        dh_asn1.c dh_gen.c dh_key.c dh_lib.c dh_check.c dh_err.c dh_depr.c \
        dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_kdf.c dh_meth.c
        dh_ameth.c dh_pmeth.c dh_prn.c dh_rfc5114.c dh_kdf.c dh_meth.c \
        dh_rfc7919.c

crypto/dh/dh_rfc7919.c

0 → 100644
+75 −0
Original line number Diff line number Diff line
/*
 * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
 *
 * Licensed under the OpenSSL license (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 <stdio.h>
#include "internal/cryptlib.h"
#include "dh_locl.h"
#include <openssl/bn.h>
#include <openssl/objects.h>
#include "internal/bn_dh.h"

static DH *dh_param_init(const BIGNUM *p, int32_t nbits)
{
    DH *dh = DH_new();
    if (dh == NULL)
        return NULL;
    dh->p = (BIGNUM *)p;
    dh->g = (BIGNUM *)&_bignum_const_2;
    dh->length = nbits;
    return dh;
}

DH *DH_new_by_nid(int nid)
{
    switch (nid) {
    case NID_ffdhe2048:
        return dh_param_init(&_bignum_ffdhe2048_p, 225);
    case NID_ffdhe3072:
        return dh_param_init(&_bignum_ffdhe3072_p, 275);
    case NID_ffdhe4096:
        return dh_param_init(&_bignum_ffdhe4096_p, 325);
    case NID_ffdhe6144:
        return dh_param_init(&_bignum_ffdhe6144_p, 375);
    case NID_ffdhe8192:
        return dh_param_init(&_bignum_ffdhe8192_p, 400);
    default:
        DHerr(DH_F_DH_NEW_BY_NID, DH_R_INVALID_PARAMETER_NID);
        return NULL;
    }
}

int DH_get_nid(const DH *dh)
{
    int nid;

    if (BN_get_word(dh->g) != 2)
        return NID_undef;
    if (!BN_cmp(dh->p, &_bignum_ffdhe2048_p))
        nid = NID_ffdhe2048;
    else if (!BN_cmp(dh->p, &_bignum_ffdhe3072_p))
        nid = NID_ffdhe3072;
    else if (!BN_cmp(dh->p, &_bignum_ffdhe4096_p))
        nid = NID_ffdhe4096;
    else if (!BN_cmp(dh->p, &_bignum_ffdhe6144_p))
        nid = NID_ffdhe6144;
    else if (!BN_cmp(dh->p, &_bignum_ffdhe8192_p))
        nid = NID_ffdhe8192;
    else
        return NID_undef;
    if (dh->q != NULL) {
        BIGNUM *q = BN_dup(dh->p);

        /* Check q = p * 2 + 1 we already know q is odd, so just shift right */
        if (q == NULL || !BN_rshift1(q, q) || !BN_cmp(dh->q, q)) {
            BN_free(q);
            return NID_undef;
        }
    }
    return nid;
}
+7 −0
Original line number Diff line number Diff line
@@ -15,3 +15,10 @@
declare_dh_bn(1024_160)
declare_dh_bn(2048_224)
declare_dh_bn(2048_256)

extern const BIGNUM _bignum_ffdhe2048_p;
extern const BIGNUM _bignum_ffdhe3072_p;
extern const BIGNUM _bignum_ffdhe4096_p;
extern const BIGNUM _bignum_ffdhe6144_p;
extern const BIGNUM _bignum_ffdhe8192_p;
extern const BIGNUM _bignum_const_2;
+4 −0
Original line number Diff line number Diff line
@@ -162,6 +162,10 @@ DH *DH_get_1024_160(void);
DH *DH_get_2048_224(void);
DH *DH_get_2048_256(void);

/* Named parameters, currently RFC7919 */
DH *DH_new_by_nid(int nid);
int DH_get_nid(const DH *dh);

# ifndef OPENSSL_NO_CMS
/* RFC2631 KDF */
int DH_KDF_X9_42(unsigned char *out, size_t outlen,