/src/gnutls/lib/algorithms/groups.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2017 Red Hat, Inc. |
3 | | * |
4 | | * Author: Nikos Mavrogiannopoulos |
5 | | * |
6 | | * This file is part of GnuTLS. |
7 | | * |
8 | | * The GnuTLS is free software; you can redistribute it and/or |
9 | | * modify it under the terms of the GNU Lesser General Public License |
10 | | * as published by the Free Software Foundation; either version 2.1 of |
11 | | * the License, or (at your option) any later version. |
12 | | * |
13 | | * This library is distributed in the hope that it will be useful, but |
14 | | * WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | | * Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public License |
19 | | * along with this program. If not, see <https://www.gnu.org/licenses/> |
20 | | * |
21 | | */ |
22 | | |
23 | | #include "gnutls_int.h" |
24 | | #include <algorithms.h> |
25 | | #include "errors.h" |
26 | | #include <x509/common.h> |
27 | | #include <pk.h> |
28 | | #include "c-strcase.h" |
29 | | |
30 | | /* Supported ECC curves |
31 | | */ |
32 | | |
33 | | static const gnutls_group_entry_st supported_groups[] = { |
34 | | { |
35 | | .name = "SECP192R1", |
36 | | .id = GNUTLS_GROUP_SECP192R1, |
37 | | .curve = GNUTLS_ECC_CURVE_SECP192R1, |
38 | | .tls_id = 19, |
39 | | .pk = GNUTLS_PK_ECDSA, |
40 | | }, |
41 | | { |
42 | | .name = "SECP224R1", |
43 | | .id = GNUTLS_GROUP_SECP224R1, |
44 | | .curve = GNUTLS_ECC_CURVE_SECP224R1, |
45 | | .tls_id = 21, |
46 | | .pk = GNUTLS_PK_ECDSA, |
47 | | }, |
48 | | { |
49 | | .name = "SECP256R1", |
50 | | .id = GNUTLS_GROUP_SECP256R1, |
51 | | .curve = GNUTLS_ECC_CURVE_SECP256R1, |
52 | | .tls_id = 23, |
53 | | .pk = GNUTLS_PK_ECDSA, |
54 | | }, |
55 | | { |
56 | | .name = "SECP384R1", |
57 | | .id = GNUTLS_GROUP_SECP384R1, |
58 | | .curve = GNUTLS_ECC_CURVE_SECP384R1, |
59 | | .tls_id = 24, |
60 | | .pk = GNUTLS_PK_ECDSA, |
61 | | }, |
62 | | { |
63 | | .name = "SECP521R1", |
64 | | .id = GNUTLS_GROUP_SECP521R1, |
65 | | .curve = GNUTLS_ECC_CURVE_SECP521R1, |
66 | | .tls_id = 25, |
67 | | .pk = GNUTLS_PK_ECDSA, |
68 | | }, |
69 | | { |
70 | | .name = "X25519", |
71 | | .id = GNUTLS_GROUP_X25519, |
72 | | .curve = GNUTLS_ECC_CURVE_X25519, |
73 | | .tls_id = 29, |
74 | | .pk = GNUTLS_PK_ECDH_X25519}, |
75 | | #ifdef ENABLE_GOST |
76 | | /* draft-smyshlyaev-tls12-gost-suites-06, Section 6 */ |
77 | | { |
78 | | .name = "GC256A", |
79 | | .id = GNUTLS_GROUP_GC256A, |
80 | | .curve = GNUTLS_ECC_CURVE_GOST256A, |
81 | | .pk = GNUTLS_PK_GOST_12_256, |
82 | | .tls_id = 34, |
83 | | }, |
84 | | { |
85 | | .name = "GC256B", |
86 | | .id = GNUTLS_GROUP_GC256B, |
87 | | .curve = GNUTLS_ECC_CURVE_GOST256B, |
88 | | .pk = GNUTLS_PK_GOST_12_256, |
89 | | .tls_id = 35, |
90 | | }, |
91 | | { |
92 | | .name = "GC256C", |
93 | | .id = GNUTLS_GROUP_GC256C, |
94 | | .curve = GNUTLS_ECC_CURVE_GOST256C, |
95 | | .pk = GNUTLS_PK_GOST_12_256, |
96 | | .tls_id = 36, |
97 | | }, |
98 | | { |
99 | | .name = "GC256D", |
100 | | .id = GNUTLS_GROUP_GC256D, |
101 | | .curve = GNUTLS_ECC_CURVE_GOST256D, |
102 | | .pk = GNUTLS_PK_GOST_12_256, |
103 | | .tls_id = 37, |
104 | | }, |
105 | | { |
106 | | .name = "GC512A", |
107 | | .id = GNUTLS_GROUP_GC512A, |
108 | | .curve = GNUTLS_ECC_CURVE_GOST512A, |
109 | | .pk = GNUTLS_PK_GOST_12_512, |
110 | | .tls_id = 38, |
111 | | }, |
112 | | { |
113 | | .name = "GC512B", |
114 | | .id = GNUTLS_GROUP_GC512B, |
115 | | .curve = GNUTLS_ECC_CURVE_GOST512B, |
116 | | .pk = GNUTLS_PK_GOST_12_512, |
117 | | .tls_id = 39, |
118 | | }, |
119 | | { |
120 | | .name = "GC512C", |
121 | | .id = GNUTLS_GROUP_GC512C, |
122 | | .curve = GNUTLS_ECC_CURVE_GOST512C, |
123 | | .pk = GNUTLS_PK_GOST_12_512, |
124 | | .tls_id = 40, |
125 | | }, |
126 | | #endif |
127 | | { |
128 | | .name = "X448", |
129 | | .id = GNUTLS_GROUP_X448, |
130 | | .curve = GNUTLS_ECC_CURVE_X448, |
131 | | .tls_id = 30, |
132 | | .pk = GNUTLS_PK_ECDH_X448}, |
133 | | #ifdef ENABLE_DHE |
134 | | { |
135 | | .name = "FFDHE2048", |
136 | | .id = GNUTLS_GROUP_FFDHE2048, |
137 | | .generator = &gnutls_ffdhe_2048_group_generator, |
138 | | .prime = &gnutls_ffdhe_2048_group_prime, |
139 | | .q = &gnutls_ffdhe_2048_group_q, |
140 | | .q_bits = &gnutls_ffdhe_2048_key_bits, |
141 | | .pk = GNUTLS_PK_DH, |
142 | | .tls_id = 0x100}, |
143 | | { |
144 | | .name = "FFDHE3072", |
145 | | .id = GNUTLS_GROUP_FFDHE3072, |
146 | | .generator = &gnutls_ffdhe_3072_group_generator, |
147 | | .prime = &gnutls_ffdhe_3072_group_prime, |
148 | | .q = &gnutls_ffdhe_3072_group_q, |
149 | | .q_bits = &gnutls_ffdhe_3072_key_bits, |
150 | | .pk = GNUTLS_PK_DH, |
151 | | .tls_id = 0x101}, |
152 | | { |
153 | | .name = "FFDHE4096", |
154 | | .id = GNUTLS_GROUP_FFDHE4096, |
155 | | .generator = &gnutls_ffdhe_4096_group_generator, |
156 | | .prime = &gnutls_ffdhe_4096_group_prime, |
157 | | .q = &gnutls_ffdhe_4096_group_q, |
158 | | .q_bits = &gnutls_ffdhe_4096_key_bits, |
159 | | .pk = GNUTLS_PK_DH, |
160 | | .tls_id = 0x102}, |
161 | | { |
162 | | .name = "FFDHE6144", |
163 | | .id = GNUTLS_GROUP_FFDHE6144, |
164 | | .generator = &gnutls_ffdhe_6144_group_generator, |
165 | | .prime = &gnutls_ffdhe_6144_group_prime, |
166 | | .q = &gnutls_ffdhe_6144_group_q, |
167 | | .q_bits = &gnutls_ffdhe_6144_key_bits, |
168 | | .pk = GNUTLS_PK_DH, |
169 | | .tls_id = 0x103}, |
170 | | { |
171 | | .name = "FFDHE8192", |
172 | | .id = GNUTLS_GROUP_FFDHE8192, |
173 | | .generator = &gnutls_ffdhe_8192_group_generator, |
174 | | .prime = &gnutls_ffdhe_8192_group_prime, |
175 | | .q = &gnutls_ffdhe_8192_group_q, |
176 | | .q_bits = &gnutls_ffdhe_8192_key_bits, |
177 | | .pk = GNUTLS_PK_DH, |
178 | | .tls_id = 0x104}, |
179 | | #endif |
180 | | {0, 0, 0} |
181 | | }; |
182 | | |
183 | | #define GNUTLS_GROUP_LOOP(b) \ |
184 | 0 | { const gnutls_group_entry_st *p; \ |
185 | 0 | for(p = supported_groups; p->name != NULL; p++) { b ; } } |
186 | | |
187 | | /* Returns the TLS id of the given curve |
188 | | */ |
189 | | const gnutls_group_entry_st *_gnutls_tls_id_to_group(unsigned num) |
190 | 0 | { |
191 | 0 | GNUTLS_GROUP_LOOP(if (p->tls_id == num && |
192 | 0 | (p->curve == 0 |
193 | 0 | || _gnutls_ecc_curve_is_supported(p->curve))) { |
194 | 0 | return p;} |
195 | 0 | ) ; |
196 | |
|
197 | 0 | return NULL; |
198 | 0 | } |
199 | | |
200 | | const gnutls_group_entry_st *_gnutls_id_to_group(unsigned id) |
201 | 0 | { |
202 | 0 | if (id == 0) |
203 | 0 | return NULL; |
204 | | |
205 | 0 | GNUTLS_GROUP_LOOP(if (p->id == id && |
206 | 0 | (p->curve == 0 |
207 | 0 | || _gnutls_ecc_curve_is_supported(p->curve))) { |
208 | 0 | return p;} |
209 | 0 | ) ; |
210 | |
|
211 | 0 | return NULL; |
212 | 0 | } |
213 | | |
214 | | /** |
215 | | * gnutls_group_list: |
216 | | * |
217 | | * Get the list of supported elliptic curves. |
218 | | * |
219 | | * This function is not thread safe. |
220 | | * |
221 | | * Returns: Return a (0)-terminated list of #gnutls_group_t |
222 | | * integers indicating the available groups. |
223 | | * |
224 | | * Since: 3.6.0 |
225 | | **/ |
226 | | const gnutls_group_t *gnutls_group_list(void) |
227 | 0 | { |
228 | 0 | static gnutls_group_t groups[MAX_ALGOS] = { 0 }; |
229 | |
|
230 | 0 | if (groups[0] == 0) { |
231 | 0 | int i = 0; |
232 | |
|
233 | 0 | GNUTLS_GROUP_LOOP(if |
234 | 0 | (p->curve == 0 |
235 | 0 | || _gnutls_ecc_curve_is_supported(p->curve)) |
236 | 0 | groups[i++] = p->id;) ; |
237 | 0 | groups[i++] = 0; |
238 | 0 | } |
239 | |
|
240 | 0 | return groups; |
241 | 0 | } |
242 | | |
243 | | /** |
244 | | * gnutls_group_get_id: |
245 | | * @name: is a group name |
246 | | * |
247 | | * The names are compared in a case insensitive way. |
248 | | * |
249 | | * Returns: return a #gnutls_group_t value corresponding to |
250 | | * the specified group, or %GNUTLS_GROUP_INVALID on error. |
251 | | * |
252 | | * Since: 3.6.0 |
253 | | **/ |
254 | | gnutls_group_t gnutls_group_get_id(const char *name) |
255 | 0 | { |
256 | 0 | gnutls_group_t ret = GNUTLS_GROUP_INVALID; |
257 | |
|
258 | 0 | GNUTLS_GROUP_LOOP(if |
259 | 0 | (c_strcasecmp(p->name, name) == 0 |
260 | 0 | && (p->curve == 0 |
261 | 0 | || _gnutls_ecc_curve_is_supported(p->curve))) { |
262 | 0 | ret = p->id; break;} |
263 | 0 | ) ; |
264 | |
|
265 | 0 | return ret; |
266 | 0 | } |
267 | | |
268 | | /* Similar to gnutls_group_get_id, except that it does not check if |
269 | | * the curve is supported. |
270 | | */ |
271 | | gnutls_group_t _gnutls_group_get_id(const char *name) |
272 | 0 | { |
273 | 0 | gnutls_group_t ret = GNUTLS_GROUP_INVALID; |
274 | |
|
275 | 0 | GNUTLS_GROUP_LOOP(if (c_strcasecmp(p->name, name) == 0) { |
276 | 0 | ret = p->id; break;} |
277 | 0 | ) ; |
278 | |
|
279 | 0 | return ret; |
280 | 0 | } |
281 | | |
282 | | /** |
283 | | * gnutls_group_get_name: |
284 | | * @group: is an element from %gnutls_group_t |
285 | | * |
286 | | * Convert a #gnutls_group_t value to a string. |
287 | | * |
288 | | * Returns: a string that contains the name of the specified |
289 | | * group or %NULL. |
290 | | * |
291 | | * Since: 3.6.0 |
292 | | **/ |
293 | | const char *gnutls_group_get_name(gnutls_group_t group) |
294 | 0 | { |
295 | 0 | GNUTLS_GROUP_LOOP(if (p->id == group) { |
296 | 0 | return p->name;} |
297 | 0 | ) ; |
298 | |
|
299 | 0 | return NULL; |
300 | 0 | } |