/src/openssl31/crypto/ffc/ffc_dh.c
Line | Count | Source (jump to first uncovered line) |
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 | 1.31k | { |
92 | 1.31k | size_t i; |
93 | | |
94 | 3.81k | for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { |
95 | 3.81k | if (OPENSSL_strcasecmp(dh_named_groups[i].name, name) == 0) |
96 | 1.31k | return &dh_named_groups[i]; |
97 | 3.81k | } |
98 | 0 | return NULL; |
99 | 1.31k | } |
100 | | |
101 | | const DH_NAMED_GROUP *ossl_ffc_uid_to_dh_named_group(int uid) |
102 | 5.36k | { |
103 | 5.36k | size_t i; |
104 | | |
105 | 17.3k | for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { |
106 | 17.3k | if (dh_named_groups[i].uid == uid) |
107 | 5.36k | return &dh_named_groups[i]; |
108 | 17.3k | } |
109 | 0 | return NULL; |
110 | 5.36k | } |
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 | 47.7k | { |
117 | 47.7k | size_t i; |
118 | | |
119 | 716k | for (i = 0; i < OSSL_NELEM(dh_named_groups); ++i) { |
120 | | /* Keep searching until a matching p and g is found */ |
121 | 668k | if (BN_cmp(p, dh_named_groups[i].p) == 0 |
122 | 668k | && BN_cmp(g, dh_named_groups[i].g) == 0 |
123 | | /* Verify q is correct if it exists */ |
124 | 668k | && (q == NULL || BN_cmp(q, dh_named_groups[i].q) == 0)) |
125 | 122 | return &dh_named_groups[i]; |
126 | 668k | } |
127 | 47.6k | return NULL; |
128 | 47.7k | } |
129 | | #endif |
130 | | |
131 | | int ossl_ffc_named_group_get_uid(const DH_NAMED_GROUP *group) |
132 | 2.74k | { |
133 | 2.74k | if (group == NULL) |
134 | 0 | return NID_undef; |
135 | 2.74k | return group->uid; |
136 | 2.74k | } |
137 | | |
138 | | const char *ossl_ffc_named_group_get_name(const DH_NAMED_GROUP *group) |
139 | 4.05k | { |
140 | 4.05k | if (group == NULL) |
141 | 0 | return NULL; |
142 | 4.05k | return group->name; |
143 | 4.05k | } |
144 | | |
145 | | #ifndef OPENSSL_NO_DH |
146 | | int ossl_ffc_named_group_get_keylength(const DH_NAMED_GROUP *group) |
147 | 122 | { |
148 | 122 | if (group == NULL) |
149 | 0 | return 0; |
150 | 122 | return group->keylength; |
151 | 122 | } |
152 | | |
153 | | const BIGNUM *ossl_ffc_named_group_get_q(const DH_NAMED_GROUP *group) |
154 | 122 | { |
155 | 122 | if (group == NULL) |
156 | 0 | return NULL; |
157 | 122 | return group->q; |
158 | 122 | } |
159 | | |
160 | | int ossl_ffc_named_group_set(FFC_PARAMS *ffc, const DH_NAMED_GROUP *group) |
161 | 1.31k | { |
162 | 1.31k | if (ffc == NULL || group == NULL) |
163 | 0 | return 0; |
164 | | |
165 | 1.31k | ossl_ffc_params_set0_pqg(ffc, (BIGNUM *)group->p, (BIGNUM *)group->q, |
166 | 1.31k | (BIGNUM *)group->g); |
167 | 1.31k | ffc->keylength = group->keylength; |
168 | | |
169 | | /* flush the cached nid, The DH layer is responsible for caching */ |
170 | 1.31k | ffc->nid = NID_undef; |
171 | 1.31k | return 1; |
172 | 1.31k | } |
173 | | #endif |