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