/src/gnutls/lib/algorithms/ecc.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2011-2012 Free Software Foundation, 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 SYSTEM_CONFIG_OR_CONST gnutls_ecc_curve_entry_st ecc_curves[] = { |
34 | | #ifdef ENABLE_NON_SUITEB_CURVES |
35 | | { |
36 | | .name = "SECP192R1", |
37 | | .oid = "1.2.840.10045.3.1.1", |
38 | | .id = GNUTLS_ECC_CURVE_SECP192R1, |
39 | | .group = GNUTLS_GROUP_SECP192R1, |
40 | | .pk = GNUTLS_PK_ECDSA, |
41 | | .size = 24, |
42 | | .supported = 1, |
43 | | }, |
44 | | { |
45 | | .name = "SECP224R1", |
46 | | .oid = "1.3.132.0.33", |
47 | | .id = GNUTLS_ECC_CURVE_SECP224R1, |
48 | | .group = GNUTLS_GROUP_SECP224R1, |
49 | | .pk = GNUTLS_PK_ECDSA, |
50 | | .size = 28, |
51 | | .supported = 1, |
52 | | }, |
53 | | #endif |
54 | | { |
55 | | .name = "SECP256R1", |
56 | | .oid = "1.2.840.10045.3.1.7", |
57 | | .id = GNUTLS_ECC_CURVE_SECP256R1, |
58 | | .group = GNUTLS_GROUP_SECP256R1, |
59 | | .pk = GNUTLS_PK_ECDSA, |
60 | | .size = 32, |
61 | | .supported = 1, |
62 | | }, |
63 | | { |
64 | | .name = "SECP384R1", |
65 | | .oid = "1.3.132.0.34", |
66 | | .id = GNUTLS_ECC_CURVE_SECP384R1, |
67 | | .group = GNUTLS_GROUP_SECP384R1, |
68 | | .pk = GNUTLS_PK_ECDSA, |
69 | | .size = 48, |
70 | | .supported = 1, |
71 | | }, |
72 | | { |
73 | | .name = "SECP521R1", |
74 | | .oid = "1.3.132.0.35", |
75 | | .id = GNUTLS_ECC_CURVE_SECP521R1, |
76 | | .group = GNUTLS_GROUP_SECP521R1, |
77 | | .pk = GNUTLS_PK_ECDSA, |
78 | | .size = 66, |
79 | | .supported = 1, |
80 | | }, |
81 | | { |
82 | | .name = "X25519", |
83 | | .oid = ECDH_X25519_OID, |
84 | | .id = GNUTLS_ECC_CURVE_X25519, |
85 | | .group = GNUTLS_GROUP_X25519, |
86 | | .pk = GNUTLS_PK_ECDH_X25519, |
87 | | .size = 32, |
88 | | .supported = 1, |
89 | | }, |
90 | | { |
91 | | .name = "Ed25519", |
92 | | .oid = SIG_EDDSA_SHA512_OID, |
93 | | .id = GNUTLS_ECC_CURVE_ED25519, |
94 | | .pk = GNUTLS_PK_EDDSA_ED25519, |
95 | | .size = 32, |
96 | | .sig_size = 64, |
97 | | .supported = 1, |
98 | | }, |
99 | | { |
100 | | .name = "X448", |
101 | | .oid = ECDH_X448_OID, |
102 | | .id = GNUTLS_ECC_CURVE_X448, |
103 | | .pk = GNUTLS_PK_ECDH_X448, |
104 | | .size = 56, |
105 | | .supported = 1, |
106 | | }, |
107 | | { |
108 | | .name = "Ed448", |
109 | | .oid = SIG_ED448_OID, |
110 | | .id = GNUTLS_ECC_CURVE_ED448, |
111 | | .pk = GNUTLS_PK_EDDSA_ED448, |
112 | | .size = 57, |
113 | | .sig_size = 114, |
114 | | .supported = 1, |
115 | | }, |
116 | | #if ENABLE_GOST |
117 | | /* Curves for usage in GOST digital signature algorithm (GOST R |
118 | | * 34.10-2001/-2012) and key agreement (VKO GOST R 34.10-2001/-2012). |
119 | | * |
120 | | * Historically CryptoPro has defined three 256-bit curves for use with |
121 | | * digital signature algorithm (CryptoPro-A, -B, -C). |
122 | | * |
123 | | * Also it has reissues two of them with different OIDs for key |
124 | | * exchange (CryptoPro-XchA = CryptoPro-A and CryptoPro-XchB = |
125 | | * CryptoPro-C). |
126 | | * |
127 | | * Then TC26 (Standard committee working on cryptographic standards) has |
128 | | * defined one 256-bit curve (TC26-256-A) and three 512-bit curves |
129 | | * (TC26-512-A, -B, -C). |
130 | | * |
131 | | * And finally TC26 has reissues original CryptoPro curves under their |
132 | | * own OID namespace (TC26-256-B = CryptoPro-A, TC26-256-C = |
133 | | * CryptoPro-B and TC26-256-D = CryptoPro-C). |
134 | | * |
135 | | * CryptoPro OIDs are usable for both GOST R 34.10-2001 and |
136 | | * GOST R 34.10-2012 keys (thus they have GNUTLS_PK_UNKNOWN in this |
137 | | * table). |
138 | | * TC26 OIDs are usable only for GOST R 34.10-2012 keys. |
139 | | */ |
140 | | { |
141 | | .name = "CryptoPro-A", |
142 | | .oid = "1.2.643.2.2.35.1", |
143 | | .id = GNUTLS_ECC_CURVE_GOST256CPA, |
144 | | .group = GNUTLS_GROUP_GC256B, |
145 | | .pk = GNUTLS_PK_UNKNOWN, |
146 | | .size = 32, |
147 | | .gost_curve = 1, |
148 | | .supported = 1, |
149 | | }, |
150 | | { |
151 | | .name = "CryptoPro-B", |
152 | | .oid = "1.2.643.2.2.35.2", |
153 | | .id = GNUTLS_ECC_CURVE_GOST256CPB, |
154 | | .group = GNUTLS_GROUP_GC256C, |
155 | | .pk = GNUTLS_PK_UNKNOWN, |
156 | | .size = 32, |
157 | | .gost_curve = 1, |
158 | | .supported = 1, |
159 | | }, |
160 | | { |
161 | | .name = "CryptoPro-C", |
162 | | .oid = "1.2.643.2.2.35.3", |
163 | | .id = GNUTLS_ECC_CURVE_GOST256CPC, |
164 | | .group = GNUTLS_GROUP_GC256D, |
165 | | .pk = GNUTLS_PK_UNKNOWN, |
166 | | .size = 32, |
167 | | .gost_curve = 1, |
168 | | .supported = 1, |
169 | | }, |
170 | | { |
171 | | .name = "CryptoPro-XchA", |
172 | | .oid = "1.2.643.2.2.36.0", |
173 | | .id = GNUTLS_ECC_CURVE_GOST256CPXA, |
174 | | .group = GNUTLS_GROUP_GC256B, |
175 | | .pk = GNUTLS_PK_UNKNOWN, |
176 | | .size = 32, |
177 | | .gost_curve = 1, |
178 | | .supported = 1, |
179 | | }, |
180 | | { |
181 | | .name = "CryptoPro-XchB", |
182 | | .oid = "1.2.643.2.2.36.1", |
183 | | .id = GNUTLS_ECC_CURVE_GOST256CPXB, |
184 | | .group = GNUTLS_GROUP_GC256D, |
185 | | .pk = GNUTLS_PK_UNKNOWN, |
186 | | .size = 32, |
187 | | .gost_curve = 1, |
188 | | .supported = 1, |
189 | | }, |
190 | | { |
191 | | .name = "TC26-256-A", |
192 | | .oid = "1.2.643.7.1.2.1.1.1", |
193 | | .id = GNUTLS_ECC_CURVE_GOST256A, |
194 | | .group = GNUTLS_GROUP_GC256A, |
195 | | .pk = GNUTLS_PK_GOST_12_256, |
196 | | .size = 32, |
197 | | .gost_curve = 1, |
198 | | .supported = 1, |
199 | | }, |
200 | | { |
201 | | .name = "TC26-256-B", |
202 | | .oid = "1.2.643.7.1.2.1.1.2", |
203 | | .id = GNUTLS_ECC_CURVE_GOST256B, |
204 | | .group = GNUTLS_GROUP_GC256B, |
205 | | .pk = GNUTLS_PK_GOST_12_256, |
206 | | .size = 32, |
207 | | .gost_curve = 1, |
208 | | .supported = 1, |
209 | | }, |
210 | | { |
211 | | .name = "TC26-256-C", |
212 | | .oid = "1.2.643.7.1.2.1.1.3", |
213 | | .id = GNUTLS_ECC_CURVE_GOST256C, |
214 | | .group = GNUTLS_GROUP_GC256C, |
215 | | .pk = GNUTLS_PK_GOST_12_256, |
216 | | .size = 32, |
217 | | .gost_curve = 1, |
218 | | .supported = 1, |
219 | | }, |
220 | | { |
221 | | .name = "TC26-256-D", |
222 | | .oid = "1.2.643.7.1.2.1.1.4", |
223 | | .id = GNUTLS_ECC_CURVE_GOST256D, |
224 | | .group = GNUTLS_GROUP_GC256D, |
225 | | .pk = GNUTLS_PK_GOST_12_256, |
226 | | .size = 32, |
227 | | .gost_curve = 1, |
228 | | .supported = 1, |
229 | | }, |
230 | | { |
231 | | .name = "TC26-512-A", |
232 | | .oid = "1.2.643.7.1.2.1.2.1", |
233 | | .id = GNUTLS_ECC_CURVE_GOST512A, |
234 | | .group = GNUTLS_GROUP_GC512A, |
235 | | .pk = GNUTLS_PK_GOST_12_512, |
236 | | .size = 64, |
237 | | .gost_curve = 1, |
238 | | .supported = 1, |
239 | | }, |
240 | | { |
241 | | .name = "TC26-512-B", |
242 | | .oid = "1.2.643.7.1.2.1.2.2", |
243 | | .id = GNUTLS_ECC_CURVE_GOST512B, |
244 | | .group = GNUTLS_GROUP_GC512B, |
245 | | .pk = GNUTLS_PK_GOST_12_512, |
246 | | .size = 64, |
247 | | .gost_curve = 1, |
248 | | .supported = 1, |
249 | | }, |
250 | | { |
251 | | .name = "TC26-512-C", |
252 | | .oid = "1.2.643.7.1.2.1.2.3", |
253 | | .id = GNUTLS_ECC_CURVE_GOST512C, |
254 | | .group = GNUTLS_GROUP_GC512C, |
255 | | .pk = GNUTLS_PK_GOST_12_512, |
256 | | .size = 64, |
257 | | .gost_curve = 1, |
258 | | .supported = 1, |
259 | | }, |
260 | | #endif |
261 | | {0, 0, 0} |
262 | | }; |
263 | | |
264 | | #define GNUTLS_ECC_CURVE_LOOP(b) \ |
265 | 0 | { const gnutls_ecc_curve_entry_st *p; \ |
266 | 0 | for(p = ecc_curves; p->name != NULL; p++) { b ; } } |
267 | | |
268 | | /** |
269 | | * gnutls_ecc_curve_list: |
270 | | * |
271 | | * Get the list of supported elliptic curves. |
272 | | * |
273 | | * This function is not thread safe. |
274 | | * |
275 | | * Returns: Return a (0)-terminated list of #gnutls_ecc_curve_t |
276 | | * integers indicating the available curves. |
277 | | **/ |
278 | | const gnutls_ecc_curve_t *gnutls_ecc_curve_list(void) |
279 | 0 | { |
280 | 0 | static gnutls_ecc_curve_t supported_curves[MAX_ALGOS] = { 0 }; |
281 | |
|
282 | 0 | if (supported_curves[0] == 0) { |
283 | 0 | int i = 0; |
284 | |
|
285 | 0 | GNUTLS_ECC_CURVE_LOOP(if |
286 | 0 | (p->supported |
287 | 0 | && _gnutls_pk_curve_exists(p->id)) |
288 | 0 | supported_curves[i++] = p->id;) ; |
289 | 0 | supported_curves[i++] = 0; |
290 | 0 | } |
291 | |
|
292 | 0 | return supported_curves; |
293 | 0 | } |
294 | | |
295 | | unsigned _gnutls_ecc_curve_is_supported(gnutls_ecc_curve_t curve) |
296 | 0 | { |
297 | 0 | GNUTLS_ECC_CURVE_LOOP(if |
298 | 0 | (p->id == curve && p->supported |
299 | 0 | && _gnutls_pk_curve_exists(p->id)) |
300 | 0 | return 1;) ; |
301 | 0 | return 0; |
302 | 0 | } |
303 | | |
304 | | /** |
305 | | * gnutls_oid_to_ecc_curve: |
306 | | * @oid: is a curve's OID |
307 | | * |
308 | | * Returns: return a #gnutls_ecc_curve_t value corresponding to |
309 | | * the specified OID, or %GNUTLS_ECC_CURVE_INVALID on error. |
310 | | * |
311 | | * Since: 3.4.3 |
312 | | **/ |
313 | | gnutls_ecc_curve_t gnutls_oid_to_ecc_curve(const char *oid) |
314 | 0 | { |
315 | 0 | gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID; |
316 | |
|
317 | 0 | GNUTLS_ECC_CURVE_LOOP(if |
318 | 0 | (p->oid != NULL && c_strcasecmp(p->oid, oid) == 0 |
319 | 0 | && p->supported |
320 | 0 | && _gnutls_pk_curve_exists(p->id)) { |
321 | 0 | ret = p->id; break;} |
322 | 0 | ) ; |
323 | |
|
324 | 0 | return ret; |
325 | 0 | } |
326 | | |
327 | | /** |
328 | | * gnutls_ecc_curve_get_id: |
329 | | * @name: is a curve name |
330 | | * |
331 | | * The names are compared in a case insensitive way. |
332 | | * |
333 | | * Returns: return a #gnutls_ecc_curve_t value corresponding to |
334 | | * the specified curve, or %GNUTLS_ECC_CURVE_INVALID on error. |
335 | | * |
336 | | * Since: 3.4.3 |
337 | | **/ |
338 | | gnutls_ecc_curve_t gnutls_ecc_curve_get_id(const char *name) |
339 | 0 | { |
340 | 0 | gnutls_ecc_curve_t ret = GNUTLS_ECC_CURVE_INVALID; |
341 | |
|
342 | 0 | GNUTLS_ECC_CURVE_LOOP(if |
343 | 0 | (c_strcasecmp(p->name, name) == 0 && p->supported |
344 | 0 | && _gnutls_pk_curve_exists(p->id)) { |
345 | 0 | ret = p->id; break;} |
346 | 0 | ) ; |
347 | |
|
348 | 0 | return ret; |
349 | 0 | } |
350 | | |
351 | | /* This is only called by cfg_apply in priority.c, in blocklisting mode. */ |
352 | | int _gnutls_ecc_curve_mark_disabled(gnutls_ecc_curve_t curve) |
353 | 0 | { |
354 | 0 | gnutls_ecc_curve_entry_st *p; |
355 | |
|
356 | 0 | for (p = ecc_curves; p->name != NULL; p++) { |
357 | 0 | if (p->id == curve) { |
358 | 0 | p->supported = false; |
359 | 0 | return 0; |
360 | 0 | } |
361 | 0 | } |
362 | | |
363 | 0 | return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); |
364 | 0 | } |
365 | | |
366 | | /* This is only called by cfg_apply in priority.c, in allowlisting mode. */ |
367 | | void _gnutls_ecc_curve_mark_disabled_all(void) |
368 | 0 | { |
369 | 0 | gnutls_ecc_curve_entry_st *p; |
370 | |
|
371 | 0 | for (p = ecc_curves; p->name != NULL; p++) { |
372 | 0 | p->supported = false; |
373 | 0 | p->supported_revertible = true; |
374 | 0 | } |
375 | 0 | } |
376 | | |
377 | | int |
378 | | _gnutls_ecc_curve_set_enabled(gnutls_ecc_curve_t curve, unsigned int enabled) |
379 | 0 | { |
380 | 0 | gnutls_ecc_curve_entry_st *p; |
381 | |
|
382 | 0 | for (p = ecc_curves; p->name != NULL; p++) { |
383 | 0 | if (p->id == curve) { |
384 | 0 | if (!p->supported_revertible) { |
385 | 0 | return |
386 | 0 | gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); |
387 | 0 | } |
388 | 0 | p->supported = enabled; |
389 | 0 | return 0; |
390 | 0 | } |
391 | 0 | } |
392 | | |
393 | 0 | return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); |
394 | 0 | } |
395 | | |
396 | | static int _gnutls_ecc_pk_compatible(const gnutls_ecc_curve_entry_st * p, |
397 | | gnutls_pk_algorithm_t pk) |
398 | 0 | { |
399 | 0 | if (!p->supported || !_gnutls_pk_curve_exists(p->id)) |
400 | 0 | return 0; |
401 | | |
402 | 0 | if (pk == GNUTLS_PK_GOST_01 || pk == GNUTLS_PK_GOST_12_256) |
403 | 0 | return p->gost_curve && p->size == 32; |
404 | | |
405 | 0 | return pk == p->pk; |
406 | 0 | } |
407 | | |
408 | | /*- |
409 | | * _gnutls_ecc_bits_to_curve: |
410 | | * @bits: is a security parameter in bits |
411 | | * |
412 | | * Returns: return a #gnutls_ecc_curve_t value corresponding to |
413 | | * the specified bit length, or %GNUTLS_ECC_CURVE_INVALID on error. |
414 | | -*/ |
415 | | gnutls_ecc_curve_t _gnutls_ecc_bits_to_curve(gnutls_pk_algorithm_t pk, int bits) |
416 | 0 | { |
417 | 0 | gnutls_ecc_curve_t ret; |
418 | |
|
419 | 0 | if (pk == GNUTLS_PK_ECDSA) |
420 | 0 | ret = GNUTLS_ECC_CURVE_SECP256R1; |
421 | 0 | else if (pk == GNUTLS_PK_GOST_01 || pk == GNUTLS_PK_GOST_12_256) |
422 | 0 | ret = GNUTLS_ECC_CURVE_GOST256CPA; |
423 | 0 | else if (pk == GNUTLS_PK_GOST_12_512) |
424 | 0 | ret = GNUTLS_ECC_CURVE_GOST512A; |
425 | 0 | else |
426 | 0 | ret = GNUTLS_ECC_CURVE_ED25519; |
427 | |
|
428 | 0 | GNUTLS_ECC_CURVE_LOOP(if (_gnutls_ecc_pk_compatible(p, pk) |
429 | 0 | && 8 * p->size >= (unsigned)bits) { |
430 | 0 | ret = p->id; break;} |
431 | 0 | ) ; |
432 | |
|
433 | 0 | return ret; |
434 | 0 | } |
435 | | |
436 | | /** |
437 | | * gnutls_ecc_curve_get_name: |
438 | | * @curve: is an ECC curve |
439 | | * |
440 | | * Convert a #gnutls_ecc_curve_t value to a string. |
441 | | * |
442 | | * Returns: a string that contains the name of the specified |
443 | | * curve or %NULL. |
444 | | * |
445 | | * Since: 3.0 |
446 | | **/ |
447 | | const char *gnutls_ecc_curve_get_name(gnutls_ecc_curve_t curve) |
448 | 0 | { |
449 | 0 | const char *ret = NULL; |
450 | |
|
451 | 0 | GNUTLS_ECC_CURVE_LOOP(if (p->id == curve) { |
452 | 0 | ret = p->name; break;} |
453 | 0 | ) ; |
454 | |
|
455 | 0 | return ret; |
456 | 0 | } |
457 | | |
458 | | /** |
459 | | * gnutls_ecc_curve_get_oid: |
460 | | * @curve: is an ECC curve |
461 | | * |
462 | | * Convert a #gnutls_ecc_curve_t value to its object identifier. |
463 | | * |
464 | | * Returns: a string that contains the OID of the specified |
465 | | * curve or %NULL. |
466 | | * |
467 | | * Since: 3.4.3 |
468 | | **/ |
469 | | const char *gnutls_ecc_curve_get_oid(gnutls_ecc_curve_t curve) |
470 | 0 | { |
471 | 0 | const char *ret = NULL; |
472 | |
|
473 | 0 | GNUTLS_ECC_CURVE_LOOP(if (p->id == curve) { |
474 | 0 | ret = p->oid; break;} |
475 | 0 | ) ; |
476 | |
|
477 | 0 | return ret; |
478 | 0 | } |
479 | | |
480 | | /*- |
481 | | * _gnutls_ecc_curve_get_params: |
482 | | * @curve: is an ECC curve |
483 | | * |
484 | | * Returns the information on a curve. |
485 | | * |
486 | | * Returns: a pointer to #gnutls_ecc_curve_entry_st or %NULL. |
487 | | -*/ |
488 | | const gnutls_ecc_curve_entry_st |
489 | | * _gnutls_ecc_curve_get_params(gnutls_ecc_curve_t curve) |
490 | 0 | { |
491 | 0 | const gnutls_ecc_curve_entry_st *ret = NULL; |
492 | |
|
493 | 0 | GNUTLS_ECC_CURVE_LOOP(if (p->id == curve) { |
494 | 0 | ret = p; break;} |
495 | 0 | ) ; |
496 | |
|
497 | 0 | return ret; |
498 | 0 | } |
499 | | |
500 | | /** |
501 | | * gnutls_ecc_curve_get_size: |
502 | | * @curve: is an ECC curve |
503 | | * |
504 | | * Returns: the size in bytes of the curve or 0 on failure. |
505 | | * |
506 | | * Since: 3.0 |
507 | | **/ |
508 | | int gnutls_ecc_curve_get_size(gnutls_ecc_curve_t curve) |
509 | 0 | { |
510 | 0 | int ret = 0; |
511 | |
|
512 | 0 | GNUTLS_ECC_CURVE_LOOP(if (p->id == curve) { |
513 | 0 | ret = p->size; break;} |
514 | 0 | ) ; |
515 | |
|
516 | 0 | return ret; |
517 | 0 | } |
518 | | |
519 | | /** |
520 | | * gnutls_ecc_curve_get_pk: |
521 | | * @curve: is an ECC curve |
522 | | * |
523 | | * Returns: the public key algorithm associated with the named curve or %GNUTLS_PK_UNKNOWN. |
524 | | * |
525 | | * Since: 3.5.0 |
526 | | **/ |
527 | | gnutls_pk_algorithm_t gnutls_ecc_curve_get_pk(gnutls_ecc_curve_t curve) |
528 | 0 | { |
529 | 0 | int ret = GNUTLS_PK_UNKNOWN; |
530 | |
|
531 | 0 | GNUTLS_ECC_CURVE_LOOP(if (p->id == curve && p->supported) { |
532 | 0 | ret = p->pk; break;} |
533 | 0 | ) ; |
534 | |
|
535 | 0 | return ret; |
536 | 0 | } |
537 | | |
538 | | /** |
539 | | * _gnutls_ecc_curve_get_group: |
540 | | * @curve: is an ECC curve |
541 | | * |
542 | | * Returns: the group associated with the named curve or %GNUTLS_GROUP_INVALID. |
543 | | * |
544 | | * Since: 3.6.11 |
545 | | */ |
546 | | gnutls_group_t _gnutls_ecc_curve_get_group(gnutls_ecc_curve_t curve) |
547 | 0 | { |
548 | 0 | gnutls_group_t ret = GNUTLS_GROUP_INVALID; |
549 | |
|
550 | 0 | GNUTLS_ECC_CURVE_LOOP(if |
551 | 0 | (p->id == curve && p->supported |
552 | 0 | && _gnutls_pk_curve_exists(p->id)) { |
553 | 0 | ret = p->group; break;} |
554 | 0 | ) ; |
555 | |
|
556 | 0 | return ret; |
557 | 0 | } |