1 | /*
|
---|
2 | * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License 2.0 (the "License"). You may not use
|
---|
5 | * this file except in compliance with the License. You can obtain a copy
|
---|
6 | * in the file LICENSE in the source distribution or at
|
---|
7 | * https://www.openssl.org/source/license.html
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include "internal/ffc.h"
|
---|
11 | #include "internal/nelem.h"
|
---|
12 | #include "crypto/bn_dh.h"
|
---|
13 |
|
---|
14 | #ifndef OPENSSL_NO_DH
|
---|
15 |
|
---|
16 | # define FFDHE(sz, keylength) { \
|
---|
17 | SN_ffdhe##sz, NID_ffdhe##sz, \
|
---|
18 | sz, \
|
---|
19 | keylength, \
|
---|
20 | &ossl_bignum_ffdhe##sz##_p, &ossl_bignum_ffdhe##sz##_q, \
|
---|
21 | &ossl_bignum_const_2, \
|
---|
22 | }
|
---|
23 |
|
---|
24 | # define MODP(sz, keylength) { \
|
---|
25 | SN_modp_##sz, NID_modp_##sz, \
|
---|
26 | sz, \
|
---|
27 | keylength, \
|
---|
28 | &ossl_bignum_modp_##sz##_p, &ossl_bignum_modp_##sz##_q, \
|
---|
29 | &ossl_bignum_const_2 \
|
---|
30 | }
|
---|
31 |
|
---|
32 | # define RFC5114(name, uid, sz, tag) { \
|
---|
33 | name, uid, \
|
---|
34 | sz, \
|
---|
35 | 0, \
|
---|
36 | &ossl_bignum_dh##tag##_p, &ossl_bignum_dh##tag##_q, \
|
---|
37 | &ossl_bignum_dh##tag##_g \
|
---|
38 | }
|
---|
39 |
|
---|
40 | #else
|
---|
41 |
|
---|
42 | # define FFDHE(sz, keylength) { SN_ffdhe##sz, NID_ffdhe##sz }
|
---|
43 | # define MODP(sz, keylength) { SN_modp_##sz, NID_modp_##sz }
|
---|
44 | # define RFC5114(name, uid, sz, tag) { name, uid }
|
---|
45 |
|
---|
46 | #endif
|
---|
47 |
|
---|
48 | struct dh_named_group_st {
|
---|
49 | const char *name;
|
---|
50 | int uid;
|
---|
51 | #ifndef OPENSSL_NO_DH
|
---|
52 | int32_t nbits;
|
---|
53 | int keylength;
|
---|
54 | const BIGNUM *p;
|
---|
55 | const BIGNUM *q;
|
---|
56 | const BIGNUM *g;
|
---|
57 | #endif
|
---|
58 | };
|
---|
59 |
|
---|
60 | /*
|
---|
61 | * The private key length values are taken from RFC7919 with the values for
|
---|
62 | * MODP primes given the same lengths as the equivalent FFDHE.
|
---|
63 | * The MODP 1536 value is approximated.
|
---|
64 | */
|
---|
65 | static const DH_NAMED_GROUP dh_named_groups[] = {
|
---|
66 | FFDHE(2048, 225),
|
---|
67 | FFDHE(3072, 275),
|
---|
68 | FFDHE(4096, 325),
|
---|
69 | FFDHE(6144, 375),
|
---|
70 | FFDHE(8192, 400),
|
---|
71 | #ifndef FIPS_MODULE
|
---|
72 | MODP(1536, 200),
|
---|
73 | #endif
|
---|
74 | MODP(2048, 225),
|
---|
75 | MODP(3072, 275),
|
---|
76 | MODP(4096, 325),
|
---|
77 | MODP(6144, 375),
|
---|
78 | MODP(8192, 400),
|
---|
79 | /*
|
---|
80 | * Additional dh named groups from RFC 5114 that have a different g.
|
---|
81 | * The uid can be any unique identifier.
|
---|
82 | */
|
---|
83 | #ifndef FIPS_MODULE
|
---|
84 | RFC5114("dh_1024_160", 1, 1024, 1024_160),
|
---|
85 | RFC5114("dh_2048_224", 2, 2048, 2048_224),
|
---|
86 | RFC5114("dh_2048_256", 3, 2048, 2048_256),
|
---|
87 | #endif
|
---|
88 | };
|
---|
89 |
|
---|
90 | const DH_NAMED_GROUP *ossl_ffc_name_to_dh_named_group(const char *name)
|
---|
91 | {
|
---|
92 | size_t i;
|
---|
93 |
|
---|
94 | for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
|
---|
95 | if (OPENSSL_strcasecmp(dh_named_groups[i].name, name) == 0)
|
---|
96 | return &dh_named_groups[i];
|
---|
97 | }
|
---|
98 | return NULL;
|
---|
99 | }
|
---|
100 |
|
---|
101 | const DH_NAMED_GROUP *ossl_ffc_uid_to_dh_named_group(int uid)
|
---|
102 | {
|
---|
103 | size_t i;
|
---|
104 |
|
---|
105 | for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
|
---|
106 | if (dh_named_groups[i].uid == uid)
|
---|
107 | return &dh_named_groups[i];
|
---|
108 | }
|
---|
109 | return NULL;
|
---|
110 | }
|
---|
111 |
|
---|
112 | #ifndef OPENSSL_NO_DH
|
---|
113 | const DH_NAMED_GROUP *ossl_ffc_numbers_to_dh_named_group(const BIGNUM *p,
|
---|
114 | const BIGNUM *q,
|
---|
115 | const BIGNUM *g)
|
---|
116 | {
|
---|
117 | size_t i;
|
---|
118 |
|
---|
119 | for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) {
|
---|
120 | /* Keep searching until a matching p and g is found */
|
---|
121 | if (BN_cmp(p, dh_named_groups[i].p) == 0
|
---|
122 | && BN_cmp(g, dh_named_groups[i].g) == 0
|
---|
123 | /* Verify q is correct if it exists */
|
---|
124 | && (q == NULL || BN_cmp(q, dh_named_groups[i].q) == 0))
|
---|
125 | return &dh_named_groups[i];
|
---|
126 | }
|
---|
127 | return NULL;
|
---|
128 | }
|
---|
129 | #endif
|
---|
130 |
|
---|
131 | int ossl_ffc_named_group_get_uid(const DH_NAMED_GROUP *group)
|
---|
132 | {
|
---|
133 | if (group == NULL)
|
---|
134 | return NID_undef;
|
---|
135 | return group->uid;
|
---|
136 | }
|
---|
137 |
|
---|
138 | const char *ossl_ffc_named_group_get_name(const DH_NAMED_GROUP *group)
|
---|
139 | {
|
---|
140 | if (group == NULL)
|
---|
141 | return NULL;
|
---|
142 | return group->name;
|
---|
143 | }
|
---|
144 |
|
---|
145 | #ifndef OPENSSL_NO_DH
|
---|
146 | int ossl_ffc_named_group_get_keylength(const DH_NAMED_GROUP *group)
|
---|
147 | {
|
---|
148 | if (group == NULL)
|
---|
149 | return 0;
|
---|
150 | return group->keylength;
|
---|
151 | }
|
---|
152 |
|
---|
153 | const BIGNUM *ossl_ffc_named_group_get_q(const DH_NAMED_GROUP *group)
|
---|
154 | {
|
---|
155 | if (group == NULL)
|
---|
156 | return NULL;
|
---|
157 | return group->q;
|
---|
158 | }
|
---|
159 |
|
---|
160 | int ossl_ffc_named_group_set(FFC_PARAMS *ffc, const DH_NAMED_GROUP *group)
|
---|
161 | {
|
---|
162 | if (ffc == NULL || group == NULL)
|
---|
163 | return 0;
|
---|
164 |
|
---|
165 | ossl_ffc_params_set0_pqg(ffc, (BIGNUM *)group->p, (BIGNUM *)group->q,
|
---|
166 | (BIGNUM *)group->g);
|
---|
167 | ffc->keylength = group->keylength;
|
---|
168 |
|
---|
169 | /* flush the cached nid, The DH layer is responsible for caching */
|
---|
170 | ffc->nid = NID_undef;
|
---|
171 | return 1;
|
---|
172 | }
|
---|
173 | #endif
|
---|