Branch data Line data Source code
1 : : /*
2 : : * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License").
5 : : * You may not use this file except in compliance with the License.
6 : : * A copy of the License is located at
7 : : *
8 : : * http://aws.amazon.com/apache2.0
9 : : *
10 : : * or in the "license" file accompanying this file. This file is distributed
11 : : * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 : : * express or implied. See the License for the specific language governing
13 : : * permissions and limitations under the License.
14 : : */
15 : :
16 : : #include "tls/s2n_ecc_preferences.h"
17 : :
18 : : #include "api/s2n.h"
19 : : #include "crypto/s2n_ecc_evp.h"
20 : : #include "tls/s2n_connection.h"
21 : : #include "utils/s2n_safety.h"
22 : :
23 : : /* Chosen based on AWS server recommendations as of 05/24:
24 : : * - All supported curves
25 : : * - Prefer p256
26 : : */
27 : : const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20240501[] = {
28 : : &s2n_ecc_curve_secp256r1,
29 : : #if EVP_APIS_SUPPORTED
30 : : &s2n_ecc_curve_x25519,
31 : : #endif
32 : : &s2n_ecc_curve_secp384r1,
33 : : &s2n_ecc_curve_secp521r1,
34 : : };
35 : :
36 : : const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20140601[] = {
37 : : &s2n_ecc_curve_secp256r1,
38 : : &s2n_ecc_curve_secp384r1,
39 : : };
40 : :
41 : : const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20200310[] = {
42 : : #if EVP_APIS_SUPPORTED
43 : : &s2n_ecc_curve_x25519,
44 : : #endif
45 : : &s2n_ecc_curve_secp256r1,
46 : : &s2n_ecc_curve_secp384r1,
47 : : };
48 : :
49 : : /* Curve p256 is at the top of the list in order to minimize HRR */
50 : : const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20230623[] = {
51 : : &s2n_ecc_curve_secp256r1,
52 : : #if EVP_APIS_SUPPORTED
53 : : &s2n_ecc_curve_x25519,
54 : : #endif
55 : : &s2n_ecc_curve_secp384r1,
56 : : };
57 : :
58 : : /*
59 : : * These curves were chosen based on the following specification:
60 : : * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf
61 : : */
62 : : const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_default_fips[] = {
63 : : &s2n_ecc_curve_secp256r1,
64 : : &s2n_ecc_curve_secp384r1,
65 : : };
66 : :
67 : : const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20201021[] = {
68 : : &s2n_ecc_curve_secp256r1,
69 : : &s2n_ecc_curve_secp384r1,
70 : : &s2n_ecc_curve_secp521r1,
71 : : };
72 : :
73 : : /* Prefer x25519 over p256 for performance */
74 : : const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20240603[] = {
75 : : #if EVP_APIS_SUPPORTED
76 : : &s2n_ecc_curve_x25519,
77 : : #endif
78 : : &s2n_ecc_curve_secp256r1,
79 : : &s2n_ecc_curve_secp384r1,
80 : : &s2n_ecc_curve_secp521r1,
81 : : };
82 : :
83 : : const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_20210816[] = {
84 : : &s2n_ecc_curve_secp384r1,
85 : : };
86 : :
87 : : const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_test_all[] = {
88 : : #if EVP_APIS_SUPPORTED
89 : : &s2n_ecc_curve_x25519,
90 : : #endif
91 : : &s2n_ecc_curve_secp256r1,
92 : : &s2n_ecc_curve_secp384r1,
93 : : &s2n_ecc_curve_secp521r1,
94 : : };
95 : :
96 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20240501 = {
97 : : .count = s2n_array_len(s2n_ecc_pref_list_20240501),
98 : : .ecc_curves = s2n_ecc_pref_list_20240501,
99 : : };
100 : :
101 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20140601 = {
102 : : .count = s2n_array_len(s2n_ecc_pref_list_20140601),
103 : : .ecc_curves = s2n_ecc_pref_list_20140601,
104 : : };
105 : :
106 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20200310 = {
107 : : .count = s2n_array_len(s2n_ecc_pref_list_20200310),
108 : : .ecc_curves = s2n_ecc_pref_list_20200310,
109 : : };
110 : :
111 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20230623 = {
112 : : .count = s2n_array_len(s2n_ecc_pref_list_20230623),
113 : : .ecc_curves = s2n_ecc_pref_list_20230623,
114 : : };
115 : :
116 : : const struct s2n_ecc_preferences s2n_ecc_preferences_default_fips = {
117 : : .count = s2n_array_len(s2n_ecc_pref_list_default_fips),
118 : : .ecc_curves = s2n_ecc_pref_list_default_fips,
119 : : };
120 : :
121 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20201021 = {
122 : : .count = s2n_array_len(s2n_ecc_pref_list_20201021),
123 : : .ecc_curves = s2n_ecc_pref_list_20201021,
124 : : };
125 : :
126 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20210816 = {
127 : : .count = s2n_array_len(s2n_ecc_pref_list_20210816),
128 : : .ecc_curves = s2n_ecc_pref_list_20210816,
129 : : };
130 : :
131 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20240603 = {
132 : : .count = s2n_array_len(s2n_ecc_pref_list_20240603),
133 : : .ecc_curves = s2n_ecc_pref_list_20240603,
134 : : };
135 : :
136 : : const struct s2n_ecc_preferences s2n_ecc_preferences_test_all = {
137 : : .count = s2n_array_len(s2n_ecc_pref_list_test_all),
138 : : .ecc_curves = s2n_ecc_pref_list_test_all,
139 : : };
140 : :
141 : : const struct s2n_ecc_preferences s2n_ecc_preferences_null = {
142 : : .count = 0,
143 : : .ecc_curves = NULL,
144 : : };
145 : :
146 : : /* Checks if the ecc_curves present in s2n_ecc_preferences list is a subset of s2n_all_supported_curves_list
147 : : * maintained in s2n_ecc_evp.c */
148 : : int s2n_check_ecc_preferences_curves_list(const struct s2n_ecc_preferences *ecc_preferences)
149 : 68126 : {
150 : 68126 : int check = 1;
151 [ + + ]: 249611 : for (int i = 0; i < ecc_preferences->count; i++) {
152 : 181486 : const struct s2n_ecc_named_curve *named_curve = ecc_preferences->ecc_curves[i];
153 : 181486 : int curve_found = 0;
154 [ + + ]: 363520 : for (size_t j = 0; j < s2n_all_supported_curves_list_len; j++) {
155 [ + + ]: 363519 : if (named_curve->iana_id == s2n_all_supported_curves_list[j]->iana_id) {
156 : 181485 : curve_found = 1;
157 : 181485 : break;
158 : 181485 : }
159 : 363519 : }
160 : 181486 : check *= curve_found;
161 [ + + ]: 181486 : if (check == 0) {
162 [ + - ]: 1 : POSIX_BAIL(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
163 : 1 : }
164 : 181486 : }
165 : 68125 : return S2N_SUCCESS;
166 : 68126 : }
167 : :
168 : : /* Determines if query_iana_id corresponds to a curve for these ECC preferences. */
169 : : bool s2n_ecc_preferences_includes_curve(const struct s2n_ecc_preferences *ecc_preferences, uint16_t query_iana_id)
170 : 17889 : {
171 [ + + ]: 17889 : if (ecc_preferences == NULL) {
172 : 1 : return false;
173 : 1 : }
174 : :
175 [ + + ]: 26328 : for (size_t i = 0; i < ecc_preferences->count; i++) {
176 [ + + ]: 26293 : if (query_iana_id == ecc_preferences->ecc_curves[i]->iana_id) {
177 : 17853 : return true;
178 : 17853 : }
179 : 26293 : }
180 : :
181 : 35 : return false;
182 : 17888 : }
|