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_20251113[] = {
88 : : &s2n_ecc_curve_secp384r1,
89 : : &s2n_ecc_curve_secp256r1,
90 : : &s2n_ecc_curve_secp521r1,
91 : : };
92 : :
93 : : const struct s2n_ecc_named_curve *const s2n_ecc_pref_list_test_all[] = {
94 : : #if EVP_APIS_SUPPORTED
95 : : &s2n_ecc_curve_x25519,
96 : : #endif
97 : : &s2n_ecc_curve_secp256r1,
98 : : &s2n_ecc_curve_secp384r1,
99 : : &s2n_ecc_curve_secp521r1,
100 : : };
101 : :
102 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20240501 = {
103 : : .count = s2n_array_len(s2n_ecc_pref_list_20240501),
104 : : .ecc_curves = s2n_ecc_pref_list_20240501,
105 : : };
106 : :
107 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20140601 = {
108 : : .count = s2n_array_len(s2n_ecc_pref_list_20140601),
109 : : .ecc_curves = s2n_ecc_pref_list_20140601,
110 : : };
111 : :
112 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20200310 = {
113 : : .count = s2n_array_len(s2n_ecc_pref_list_20200310),
114 : : .ecc_curves = s2n_ecc_pref_list_20200310,
115 : : };
116 : :
117 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20230623 = {
118 : : .count = s2n_array_len(s2n_ecc_pref_list_20230623),
119 : : .ecc_curves = s2n_ecc_pref_list_20230623,
120 : : };
121 : :
122 : : const struct s2n_ecc_preferences s2n_ecc_preferences_default_fips = {
123 : : .count = s2n_array_len(s2n_ecc_pref_list_default_fips),
124 : : .ecc_curves = s2n_ecc_pref_list_default_fips,
125 : : };
126 : :
127 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20201021 = {
128 : : .count = s2n_array_len(s2n_ecc_pref_list_20201021),
129 : : .ecc_curves = s2n_ecc_pref_list_20201021,
130 : : };
131 : :
132 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20210816 = {
133 : : .count = s2n_array_len(s2n_ecc_pref_list_20210816),
134 : : .ecc_curves = s2n_ecc_pref_list_20210816,
135 : : };
136 : :
137 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20240603 = {
138 : : .count = s2n_array_len(s2n_ecc_pref_list_20240603),
139 : : .ecc_curves = s2n_ecc_pref_list_20240603,
140 : : };
141 : :
142 : : const struct s2n_ecc_preferences s2n_ecc_preferences_20251113 = {
143 : : .count = s2n_array_len(s2n_ecc_pref_list_20251113),
144 : : .ecc_curves = s2n_ecc_pref_list_20251113,
145 : : };
146 : :
147 : : const struct s2n_ecc_preferences s2n_ecc_preferences_test_all = {
148 : : .count = s2n_array_len(s2n_ecc_pref_list_test_all),
149 : : .ecc_curves = s2n_ecc_pref_list_test_all,
150 : : };
151 : :
152 : : const struct s2n_ecc_preferences s2n_ecc_preferences_null = {
153 : : .count = 0,
154 : : .ecc_curves = NULL,
155 : : };
156 : :
157 : : /* Checks if the ecc_curves present in s2n_ecc_preferences list is a subset of s2n_all_supported_curves_list
158 : : * maintained in s2n_ecc_evp.c */
159 : : int s2n_check_ecc_preferences_curves_list(const struct s2n_ecc_preferences *ecc_preferences)
160 : 90857 : {
161 : 90857 : int check = 1;
162 [ + + ]: 336833 : for (int i = 0; i < ecc_preferences->count; i++) {
163 : 245977 : const struct s2n_ecc_named_curve *named_curve = ecc_preferences->ecc_curves[i];
164 : 245977 : int curve_found = 0;
165 [ + + ]: 495835 : for (size_t j = 0; j < s2n_all_supported_curves_list_len; j++) {
166 [ + + ]: 495834 : if (named_curve->iana_id == s2n_all_supported_curves_list[j]->iana_id) {
167 : 245976 : curve_found = 1;
168 : 245976 : break;
169 : 245976 : }
170 : 495834 : }
171 : 245977 : check *= curve_found;
172 [ + + ]: 245977 : if (check == 0) {
173 [ + - ]: 1 : POSIX_BAIL(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
174 : 1 : }
175 : 245977 : }
176 : 90856 : return S2N_SUCCESS;
177 : 90857 : }
178 : :
179 : : /* Determines if query_iana_id corresponds to a curve for these ECC preferences. */
180 : : bool s2n_ecc_preferences_includes_curve(const struct s2n_ecc_preferences *ecc_preferences, uint16_t query_iana_id)
181 : 19064 : {
182 [ + + ]: 19064 : if (ecc_preferences == NULL) {
183 : 1 : return false;
184 : 1 : }
185 : :
186 [ + + ]: 27619 : for (size_t i = 0; i < ecc_preferences->count; i++) {
187 [ + + ]: 27588 : if (query_iana_id == ecc_preferences->ecc_curves[i]->iana_id) {
188 : 19032 : return true;
189 : 19032 : }
190 : 27588 : }
191 : :
192 : 31 : return false;
193 : 19063 : }
|