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 <sys/param.h>
17 : :
18 : : #include "api/s2n.h"
19 : : #include "crypto/s2n_dhe.h"
20 : : #include "crypto/s2n_pkey.h"
21 : : #include "error/s2n_errno.h"
22 : : #include "stuffer/s2n_stuffer.h"
23 : : #include "tls/s2n_async_pkey.h"
24 : : #include "tls/s2n_cipher_suites.h"
25 : : #include "tls/s2n_connection.h"
26 : : #include "tls/s2n_handshake.h"
27 : : #include "tls/s2n_kem.h"
28 : : #include "tls/s2n_kex.h"
29 : : #include "tls/s2n_key_log.h"
30 : : #include "tls/s2n_resume.h"
31 : : #include "utils/s2n_random.h"
32 : : #include "utils/s2n_safety.h"
33 : :
34 : : typedef S2N_RESULT s2n_kex_client_key_method(const struct s2n_kex *kex, struct s2n_connection *conn, struct s2n_blob *shared_key);
35 : : typedef void *s2n_stuffer_action(struct s2n_stuffer *stuffer, uint32_t data_len);
36 : :
37 : : static int s2n_rsa_client_key_recv_complete(struct s2n_connection *conn, bool rsa_failed, struct s2n_blob *shared_key);
38 : :
39 : : /*
40 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-7.4.7.1
41 : : *# client_version
42 : : *# The latest (newest) version supported by the client. This is
43 : : *# used to detect version rollback attacks.
44 : : *
45 : : * However, TLS1.2 rsa kex does not account for the existence of TLS1.3.
46 : : * Therefore "latest" actually means "latest up to TLS1.2".
47 : : */
48 : : static S2N_RESULT s2n_client_key_exchange_get_rsa_client_version(struct s2n_connection *conn,
49 : : uint8_t client_version[S2N_TLS_PROTOCOL_VERSION_LEN])
50 : 3142 : {
51 [ - + ][ # # ]: 3142 : RESULT_ENSURE_REF(conn);
52 [ - + ][ # # ]: 3142 : RESULT_ENSURE_REF(client_version);
53 : 3142 : uint8_t client_version_for_rsa = MIN(conn->client_protocol_version, S2N_TLS12);
54 : 3142 : client_version[0] = client_version_for_rsa / 10;
55 : 3142 : client_version[1] = client_version_for_rsa % 10;
56 : 3142 : return S2N_RESULT_OK;
57 : 3142 : }
58 : :
59 : : static int s2n_hybrid_client_action(struct s2n_connection *conn, struct s2n_blob *combined_shared_key,
60 : : s2n_kex_client_key_method kex_method, uint32_t *cursor, s2n_stuffer_action stuffer_action)
61 : 0 : {
62 [ # # ][ # # ]: 0 : POSIX_ENSURE_REF(conn);
63 [ # # ][ # # ]: 0 : POSIX_ENSURE_REF(conn->secure);
64 [ # # ][ # # ]: 0 : POSIX_ENSURE_REF(kex_method);
65 [ # # ][ # # ]: 0 : POSIX_ENSURE_REF(stuffer_action);
66 : :
67 : 0 : struct s2n_stuffer *io = &conn->handshake.io;
68 : 0 : const struct s2n_kex *hybrid_kex_0 = conn->secure->cipher_suite->key_exchange_alg->hybrid[0];
69 : 0 : const struct s2n_kex *hybrid_kex_1 = conn->secure->cipher_suite->key_exchange_alg->hybrid[1];
70 : :
71 : : /* Keep a copy to the start of the entire hybrid client key exchange message for the hybrid PRF */
72 : 0 : struct s2n_blob *client_key_exchange_message = &conn->kex_params.client_key_exchange_message;
73 : 0 : client_key_exchange_message->data = stuffer_action(io, 0);
74 [ # # ][ # # ]: 0 : POSIX_ENSURE_REF(client_key_exchange_message->data);
75 : 0 : const uint32_t start_cursor = *cursor;
76 : :
77 : 0 : DEFER_CLEANUP(struct s2n_blob shared_key_0 = { 0 }, s2n_free);
78 [ # # ]: 0 : POSIX_GUARD_RESULT(kex_method(hybrid_kex_0, conn, &shared_key_0));
79 : :
80 : 0 : struct s2n_blob *shared_key_1 = &(conn->kex_params.kem_params.shared_secret);
81 [ # # ]: 0 : POSIX_GUARD_RESULT(kex_method(hybrid_kex_1, conn, shared_key_1));
82 : :
83 : 0 : const uint32_t end_cursor = *cursor;
84 [ # # ][ # # ]: 0 : POSIX_ENSURE_GTE(end_cursor, start_cursor);
85 : 0 : client_key_exchange_message->size = end_cursor - start_cursor;
86 : :
87 [ # # ]: 0 : POSIX_GUARD(s2n_alloc(combined_shared_key, shared_key_0.size + shared_key_1->size));
88 : 0 : struct s2n_stuffer stuffer_combiner = { 0 };
89 [ # # ]: 0 : POSIX_GUARD(s2n_stuffer_init(&stuffer_combiner, combined_shared_key));
90 [ # # ]: 0 : POSIX_GUARD(s2n_stuffer_write(&stuffer_combiner, &shared_key_0));
91 [ # # ]: 0 : POSIX_GUARD(s2n_stuffer_write(&stuffer_combiner, shared_key_1));
92 : :
93 [ # # ]: 0 : POSIX_GUARD(s2n_kem_free(&conn->kex_params.kem_params));
94 : :
95 : 0 : return 0;
96 : 0 : }
97 : :
98 : : static int s2n_calculate_keys(struct s2n_connection *conn, struct s2n_blob *shared_key)
99 : 4440 : {
100 [ - + ][ # # ]: 4440 : POSIX_ENSURE_REF(conn);
101 [ - + ][ # # ]: 4440 : POSIX_ENSURE_REF(conn->secure);
102 [ # # ][ - + ]: 4440 : POSIX_ENSURE_REF(conn->secure->cipher_suite);
103 : :
104 : : /* Turn the pre-master secret into a master secret */
105 [ - + ]: 4440 : POSIX_GUARD_RESULT(s2n_kex_tls_prf(conn->secure->cipher_suite->key_exchange_alg, conn, shared_key));
106 : :
107 : : /* Expand the keys */
108 [ - + ]: 4440 : POSIX_GUARD(s2n_prf_key_expansion(conn));
109 : : /* Save the master secret in the cache.
110 : : * Failing to cache the session should not affect the current handshake.
111 : : */
112 [ + + ]: 4440 : if (s2n_allowed_to_cache_connection(conn)) {
113 : 7 : s2n_result_ignore(s2n_store_to_cache(conn));
114 : 7 : }
115 : : /* log the secret, if needed */
116 : 4440 : s2n_result_ignore(s2n_key_log_tls12_secret(conn));
117 : 4440 : return 0;
118 : 4440 : }
119 : :
120 : : int s2n_rsa_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
121 : 1511 : {
122 : : /* Set shared_key before async guard to pass the proper shared_key to the caller upon async completion */
123 [ # # ][ - + ]: 1511 : POSIX_ENSURE_REF(shared_key);
124 : 1511 : shared_key->data = conn->secrets.version.tls12.rsa_premaster_secret;
125 : 1511 : shared_key->size = S2N_TLS_SECRET_LEN;
126 : :
127 [ - + ][ + + ]: 1511 : S2N_ASYNC_PKEY_GUARD(conn);
[ + + ][ + + ]
[ - + ][ + - ]
128 : :
129 : 1450 : struct s2n_stuffer *in = &conn->handshake.io;
130 : 1450 : uint16_t length = 0;
131 : :
132 [ + + ]: 1450 : if (conn->actual_protocol_version == S2N_SSLv3) {
133 : 35 : length = s2n_stuffer_data_available(in);
134 : 1415 : } else {
135 [ - + ]: 1415 : POSIX_GUARD(s2n_stuffer_read_uint16(in, &length));
136 : 1415 : }
137 : :
138 [ - + ][ # # ]: 1450 : S2N_ERROR_IF(length > s2n_stuffer_data_available(in), S2N_ERR_BAD_MESSAGE);
139 : :
140 : 1450 : uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
141 [ - + ]: 1450 : POSIX_GUARD_RESULT(s2n_client_key_exchange_get_rsa_client_version(conn, protocol_version));
142 : :
143 : : /* Decrypt the pre-master secret */
144 : 1450 : struct s2n_blob encrypted = { 0 };
145 [ - + ]: 1450 : POSIX_GUARD(s2n_blob_init(&encrypted, s2n_stuffer_raw_read(in, length), length));
146 [ # # ][ - + ]: 1450 : POSIX_ENSURE_REF(encrypted.data);
147 [ - + ][ # # ]: 1450 : POSIX_ENSURE_GT(encrypted.size, 0);
148 : :
149 : : /* First: use a random pre-master secret */
150 [ - + ]: 1450 : POSIX_GUARD_RESULT(s2n_get_private_random_data(shared_key));
151 : 1450 : conn->secrets.version.tls12.rsa_premaster_secret[0] = protocol_version[0];
152 : 1450 : conn->secrets.version.tls12.rsa_premaster_secret[1] = protocol_version[1];
153 : :
154 [ + + ]: 1450 : S2N_ASYNC_PKEY_DECRYPT(conn, &encrypted, shared_key, s2n_rsa_client_key_recv_complete);
155 : 0 : }
156 : :
157 : : int s2n_rsa_client_key_recv_complete(struct s2n_connection *conn, bool rsa_failed, struct s2n_blob *decrypted)
158 : 1448 : {
159 [ - + ][ # # ]: 1448 : S2N_ERROR_IF(decrypted->size != S2N_TLS_SECRET_LEN, S2N_ERR_SIZE_MISMATCH);
160 : :
161 : : /* Avoid copying the same buffer for the case where async pkey is not used */
162 [ + + ]: 1448 : if (conn->secrets.version.tls12.rsa_premaster_secret != decrypted->data) {
163 : : /* Copy (maybe) decrypted data into shared key */
164 [ - + ][ # # ]: 837 : POSIX_CHECKED_MEMCPY(conn->secrets.version.tls12.rsa_premaster_secret, decrypted->data, S2N_TLS_SECRET_LEN);
[ + - ]
165 : 837 : }
166 : :
167 : : /* Get client hello protocol version for comparison with decrypted data */
168 : 1448 : uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
169 [ - + ]: 1448 : POSIX_GUARD_RESULT(s2n_client_key_exchange_get_rsa_client_version(conn, protocol_version));
170 : :
171 : 1448 : conn->handshake.rsa_failed = rsa_failed;
172 : :
173 : : /* Set rsa_failed to true, if it isn't already, if the protocol version isn't what we expect */
174 : 1448 : conn->handshake.rsa_failed |= !s2n_constant_time_equals(protocol_version,
175 : 1448 : conn->secrets.version.tls12.rsa_premaster_secret, S2N_TLS_PROTOCOL_VERSION_LEN);
176 : :
177 : : /* Required to protect against Bleichenbacher attack.
178 : : * See https://www.rfc-editor.org/rfc/rfc5246#section-7.4.7.1
179 : : * We choose the first option: always setting the version in the rsa_premaster_secret
180 : : * from our local view of the client_hello value.
181 : : */
182 : 1448 : conn->secrets.version.tls12.rsa_premaster_secret[0] = protocol_version[0];
183 : 1448 : conn->secrets.version.tls12.rsa_premaster_secret[1] = protocol_version[1];
184 : :
185 : 1448 : return 0;
186 : 1448 : }
187 : :
188 : : int s2n_dhe_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
189 : 24 : {
190 : 24 : struct s2n_stuffer *in = &conn->handshake.io;
191 : :
192 : : /* Get the shared key */
193 [ - + ]: 24 : POSIX_GUARD(s2n_dh_compute_shared_secret_as_server(&conn->kex_params.server_dh_params, in, shared_key));
194 : : /* We don't need the server params any more */
195 [ - + ]: 24 : POSIX_GUARD(s2n_dh_params_free(&conn->kex_params.server_dh_params));
196 : 24 : return 0;
197 : 24 : }
198 : :
199 : : int s2n_ecdhe_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
200 : 764 : {
201 : 764 : struct s2n_stuffer *in = &conn->handshake.io;
202 : :
203 : : /* Get the shared key */
204 [ - + ]: 764 : POSIX_GUARD(s2n_ecc_evp_compute_shared_secret_as_server(&conn->kex_params.server_ecc_evp_params, in, shared_key));
205 : : /* We don't need the server params any more */
206 [ - + ]: 764 : POSIX_GUARD(s2n_ecc_evp_params_free(&conn->kex_params.server_ecc_evp_params));
207 : 764 : return 0;
208 : 764 : }
209 : :
210 : : int s2n_kem_client_key_recv(struct s2n_connection *conn, struct s2n_blob *shared_key)
211 : 0 : {
212 : : /* s2n_kem_recv_ciphertext() writes the KEM shared secret directly to
213 : : * conn->kex_params.kem_params. However, the calling function
214 : : * likely expects *shared_key to point to the shared secret. We
215 : : * can't reassign *shared_key to point to kem_params.shared_secret,
216 : : * because that would require us to take struct s2n_blob **shared_key
217 : : * as the argument, but we can't (easily) change the function signature
218 : : * because it has to be consistent with what is defined in s2n_kex.
219 : : *
220 : : * So, we assert that the caller already has *shared_key pointing
221 : : * to kem_params.shared_secret. */
222 [ # # ][ # # ]: 0 : POSIX_ENSURE_REF(shared_key);
223 [ # # ][ # # ]: 0 : S2N_ERROR_IF(shared_key != &(conn->kex_params.kem_params.shared_secret), S2N_ERR_SAFETY);
224 : 0 : conn->kex_params.kem_params.len_prefixed = true; /* PQ TLS 1.2 is always length prefixed. */
225 : :
226 [ # # ]: 0 : POSIX_GUARD(s2n_kem_recv_ciphertext(&(conn->handshake.io), &(conn->kex_params.kem_params)));
227 : :
228 : 0 : return 0;
229 : 0 : }
230 : :
231 : : int s2n_hybrid_client_key_recv(struct s2n_connection *conn, struct s2n_blob *combined_shared_key)
232 : 0 : {
233 : 0 : return s2n_hybrid_client_action(conn, combined_shared_key, &s2n_kex_client_key_recv, &conn->handshake.io.read_cursor,
234 : 0 : &s2n_stuffer_raw_read);
235 : 0 : }
236 : :
237 : : int s2n_client_key_recv(struct s2n_connection *conn)
238 : 2299 : {
239 [ # # ][ - + ]: 2299 : POSIX_ENSURE_REF(conn);
240 [ - + ][ # # ]: 2299 : POSIX_ENSURE_REF(conn->secure);
241 [ - + ][ # # ]: 2299 : POSIX_ENSURE_REF(conn->secure->cipher_suite);
242 : :
243 : 2299 : const struct s2n_kex *key_exchange = conn->secure->cipher_suite->key_exchange_alg;
244 : 2299 : DEFER_CLEANUP(struct s2n_blob shared_key = { 0 }, s2n_free_or_wipe);
245 [ + + ]: 2299 : POSIX_GUARD_RESULT(s2n_kex_client_key_recv(key_exchange, conn, &shared_key));
246 : :
247 [ - + ]: 2236 : POSIX_GUARD(s2n_calculate_keys(conn, &shared_key));
248 : 2236 : return 0;
249 : 2236 : }
250 : :
251 : : int s2n_dhe_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
252 : 24 : {
253 : 24 : struct s2n_stuffer *out = &conn->handshake.io;
254 [ - + ]: 24 : POSIX_GUARD(s2n_dh_compute_shared_secret_as_client(&conn->kex_params.server_dh_params, out, shared_key));
255 : :
256 : : /* We don't need the server params any more */
257 [ - + ]: 24 : POSIX_GUARD(s2n_dh_params_free(&conn->kex_params.server_dh_params));
258 : 24 : return 0;
259 : 24 : }
260 : :
261 : : int s2n_ecdhe_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
262 : 730 : {
263 : 730 : struct s2n_stuffer *out = &conn->handshake.io;
264 [ - + ]: 730 : POSIX_GUARD(s2n_ecc_evp_compute_shared_secret_as_client(&conn->kex_params.server_ecc_evp_params, out, shared_key));
265 : :
266 : : /* We don't need the server params any more */
267 [ - + ]: 730 : POSIX_GUARD(s2n_ecc_evp_params_free(&conn->kex_params.server_ecc_evp_params));
268 : 730 : return 0;
269 : 730 : }
270 : :
271 : : int s2n_rsa_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
272 : 244 : {
273 : 244 : uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
274 [ - + ]: 244 : POSIX_GUARD_RESULT(s2n_client_key_exchange_get_rsa_client_version(conn, protocol_version));
275 : :
276 : 244 : shared_key->data = conn->secrets.version.tls12.rsa_premaster_secret;
277 : 244 : shared_key->size = S2N_TLS_SECRET_LEN;
278 : :
279 [ - + ]: 244 : POSIX_GUARD_RESULT(s2n_get_private_random_data(shared_key));
280 : :
281 : : /* Over-write the first two bytes with the client hello version, per RFC2246/RFC4346/RFC5246 7.4.7.1.
282 : : * The latest version supported by client (as seen from the the client hello version) are <= TLS1.2
283 : : * for all clients, because TLS 1.3 clients freezes the TLS1.2 legacy version in client hello.
284 : : */
285 [ # # ][ - + ]: 244 : POSIX_CHECKED_MEMCPY(conn->secrets.version.tls12.rsa_premaster_secret, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN);
[ + - ]
286 : :
287 : 244 : uint32_t encrypted_size = 0;
288 [ - + ]: 244 : POSIX_GUARD_RESULT(s2n_pkey_size(&conn->handshake_params.server_public_key, &encrypted_size));
289 [ - + ][ # # ]: 244 : S2N_ERROR_IF(encrypted_size > 0xffff, S2N_ERR_SIZE_MISMATCH);
290 : :
291 [ + + ]: 244 : if (conn->actual_protocol_version > S2N_SSLv3) {
292 [ - + ]: 209 : POSIX_GUARD(s2n_stuffer_write_uint16(&conn->handshake.io, encrypted_size));
293 : 209 : }
294 : :
295 : 244 : struct s2n_blob encrypted = { 0 };
296 : 244 : encrypted.data = s2n_stuffer_raw_write(&conn->handshake.io, encrypted_size);
297 : 244 : encrypted.size = encrypted_size;
298 [ - + ][ # # ]: 244 : POSIX_ENSURE_REF(encrypted.data);
299 : :
300 : : /* Encrypt the secret and send it on */
301 [ - + ]: 244 : POSIX_GUARD(s2n_pkey_encrypt(&conn->handshake_params.server_public_key, shared_key, &encrypted));
302 : :
303 : : /* We don't need the key any more, so free it */
304 [ - + ]: 244 : POSIX_GUARD(s2n_pkey_free(&conn->handshake_params.server_public_key));
305 : 244 : return 0;
306 : 244 : }
307 : :
308 : : int s2n_kem_client_key_send(struct s2n_connection *conn, struct s2n_blob *shared_key)
309 : 0 : {
310 : : /* s2n_kem_send_ciphertext() writes the KEM shared secret directly to
311 : : * conn->kex_params.kem_params. However, the calling function
312 : : * likely expects *shared_key to point to the shared secret. We
313 : : * can't reassign *shared_key to point to kem_params.shared_secret,
314 : : * because that would require us to take struct s2n_blob **shared_key
315 : : * as the argument, but we can't (easily) change the function signature
316 : : * because it has to be consistent with what is defined in s2n_kex.
317 : : *
318 : : * So, we assert that the caller already has *shared_key pointing
319 : : * to kem_params.shared_secret. */
320 [ # # ][ # # ]: 0 : POSIX_ENSURE_REF(shared_key);
321 [ # # ][ # # ]: 0 : S2N_ERROR_IF(shared_key != &(conn->kex_params.kem_params.shared_secret), S2N_ERR_SAFETY);
322 : :
323 : 0 : conn->kex_params.kem_params.len_prefixed = true; /* PQ TLS 1.2 is always length prefixed */
324 : :
325 [ # # ]: 0 : POSIX_GUARD(s2n_kem_send_ciphertext(&(conn->handshake.io), &(conn->kex_params.kem_params)));
326 : :
327 : 0 : return 0;
328 : 0 : }
329 : :
330 : : int s2n_hybrid_client_key_send(struct s2n_connection *conn, struct s2n_blob *combined_shared_key)
331 : 0 : {
332 : 0 : return s2n_hybrid_client_action(conn, combined_shared_key, &s2n_kex_client_key_send, &conn->handshake.io.write_cursor,
333 : 0 : s2n_stuffer_raw_write);
334 : 0 : }
335 : :
336 : : int s2n_client_key_send(struct s2n_connection *conn)
337 : 2204 : {
338 [ - + ][ # # ]: 2204 : POSIX_ENSURE_REF(conn);
339 [ # # ][ - + ]: 2204 : POSIX_ENSURE_REF(conn->secure);
340 [ - + ][ # # ]: 2204 : POSIX_ENSURE_REF(conn->secure->cipher_suite);
341 : :
342 : 2204 : const struct s2n_kex *key_exchange = conn->secure->cipher_suite->key_exchange_alg;
343 : 2204 : DEFER_CLEANUP(struct s2n_blob shared_key = { 0 }, s2n_free_or_wipe);
344 : :
345 [ - + ]: 2204 : POSIX_GUARD_RESULT(s2n_kex_client_key_send(key_exchange, conn, &shared_key));
346 : :
347 [ - + ]: 2204 : POSIX_GUARD(s2n_calculate_keys(conn, &shared_key));
348 : 2204 : return 0;
349 : 2204 : }
|