diff options
Diffstat (limited to 'crypto/ffc/ffc_dh.c')
-rw-r--r-- | crypto/ffc/ffc_dh.c | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/crypto/ffc/ffc_dh.c b/crypto/ffc/ffc_dh.c new file mode 100644 index 0000000000..313466b0ea --- /dev/null +++ b/crypto/ffc/ffc_dh.c @@ -0,0 +1,154 @@ +/* + * Copyright 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 + */ + +#include "internal/ffc.h" +#include "internal/nelem.h" +#include "crypto/bn_dh.h" +#include "e_os.h" /* strcasecmp */ + +#ifndef OPENSSL_NO_DH + +# 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 \ + } + +#else + +# define FFDHE(sz) { SN_ffdhe##sz, NID_ffdhe##sz } +# define MODP(sz) { SN_modp_##sz, NID_modp_##sz } +# define RFC5114(name, uid, sz, tag) { name, uid } + +#endif + +struct dh_named_group_st { + const char *name; + int uid; +#ifndef OPENSSL_NO_DH + int32_t nbits; + const BIGNUM *p; + const BIGNUM *q; + const BIGNUM *g; +#endif +}; + +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 +}; + +const DH_NAMED_GROUP *ossl_ffc_name_to_dh_named_group(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]; + } + return NULL; +} + +const DH_NAMED_GROUP *ossl_ffc_uid_to_dh_named_group(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]; + } + return NULL; +} + +#ifndef OPENSSL_NO_DH +const DH_NAMED_GROUP *ossl_ffc_numbers_to_dh_named_group(const BIGNUM *p, + const BIGNUM *q, + const BIGNUM *g) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { + /* Keep searching until a matching p and g is found */ + if (BN_cmp(p, dh_named_groups[i].p) == 0 + && BN_cmp(g, dh_named_groups[i].g) == 0 + /* Verify q is correct if it exists */ + && (q == NULL || BN_cmp(q, dh_named_groups[i].q) == 0)) + return &dh_named_groups[i]; + } + return NULL; +} +#endif + +int ossl_ffc_named_group_get_uid(const DH_NAMED_GROUP *group) +{ + if (group == NULL) + return NID_undef; + return group->uid; +} + +const char *ossl_ffc_named_group_get_name(const DH_NAMED_GROUP *group) +{ + if (group == NULL) + return NULL; + return group->name; +} + +#ifndef OPENSSL_NO_DH +const BIGNUM *ossl_ffc_named_group_get_q(const DH_NAMED_GROUP *group) +{ + if (group == NULL) + return NULL; + return group->q; +} + +int ossl_ffc_named_group_set_pqg(FFC_PARAMS *ffc, const DH_NAMED_GROUP *group) +{ + if (ffc == NULL || group == NULL) + return 0; + + ossl_ffc_params_set0_pqg(ffc, (BIGNUM *)group->p, (BIGNUM *)group->q, + (BIGNUM *)group->g); + + /* flush the cached nid, The DH layer is responsible for caching */ + ffc->nid = NID_undef; + return 1; +} +#endif |