summaryrefslogtreecommitdiffstats
path: root/crypto/ffc/ffc_dh.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/ffc/ffc_dh.c')
-rw-r--r--crypto/ffc/ffc_dh.c154
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