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_connection_serialize.h"
17 : :
18 : : #include "crypto/s2n_sequence.h"
19 : : #include "tls/s2n_connection.h"
20 : : #include "tls/s2n_tls.h"
21 : : #include "tls/s2n_tls13_key_schedule.h"
22 : :
23 : : static bool s2n_libcrypto_supports_evp_aead_tls(void)
24 : 17 : {
25 : : #ifdef S2N_LIBCRYPTO_SUPPORTS_EVP_AEAD_TLS
26 : : return true;
27 : : #else
28 : 17 : return false;
29 : 17 : #endif
30 : 17 : }
31 : :
32 : : /* True if a serialized blob carries the CBC implicit IV state. Only TLS1.0
33 : : * and SSLv3 chain the implicit IV across records (TLS1.1+ uses an explicit
34 : : * per-record IV), and only for CBC and composite (CBC + HMAC fused) record
35 : : * algorithms. */
36 : : static bool s2n_serialization_includes_implicit_iv(uint8_t protocol_version,
37 : : const struct s2n_cipher_suite *cipher_suite)
38 : 76 : {
39 [ + + ]: 76 : if (protocol_version >= S2N_TLS11) {
40 : 62 : return false;
41 : 62 : }
42 : 14 : int type = cipher_suite->record_alg->cipher->type;
43 [ + + ][ + + ]: 14 : return type == S2N_CBC || type == S2N_COMPOSITE;
44 : 76 : }
45 : :
46 : : int s2n_connection_serialization_length(struct s2n_connection *conn, uint32_t *length)
47 : 80 : {
48 [ + - ][ + + ]: 80 : POSIX_ENSURE_REF(conn);
49 [ # # ][ - + ]: 79 : POSIX_ENSURE_REF(conn->config);
50 [ - + ][ # # ]: 79 : POSIX_ENSURE_REF(conn->secure);
51 [ - + ][ # # ]: 79 : POSIX_ENSURE_REF(conn->secure->cipher_suite);
52 [ + + ][ + - ]: 79 : POSIX_ENSURE_REF(length);
53 : :
54 [ - + ][ # # ]: 78 : POSIX_ENSURE(conn->config->serialized_connection_version != S2N_SERIALIZED_CONN_NONE,
55 : 78 : S2N_ERR_INVALID_STATE);
56 : :
57 [ + + ]: 78 : if (conn->actual_protocol_version >= S2N_TLS13) {
58 : 56 : uint8_t secret_size = 0;
59 [ - + ]: 56 : POSIX_GUARD(s2n_hmac_digest_size(conn->secure->cipher_suite->prf_alg, &secret_size));
60 : 56 : *length = S2N_SERIALIZED_CONN_FIXED_SIZE + (secret_size * 3);
61 [ + + ]: 56 : } else if (s2n_serialization_includes_implicit_iv(conn->actual_protocol_version,
62 : 22 : conn->secure->cipher_suite)) {
63 : 4 : *length = S2N_SERIALIZED_CONN_TLS10_SIZE;
64 : 18 : } else {
65 : 18 : *length = S2N_SERIALIZED_CONN_TLS12_SIZE;
66 : 18 : }
67 : :
68 : 78 : return S2N_SUCCESS;
69 : 78 : }
70 : :
71 : : static S2N_RESULT s2n_connection_serialize_tls13_secrets(struct s2n_connection *conn, struct s2n_stuffer *output)
72 : 18 : {
73 [ # # ][ - + ]: 18 : RESULT_ENSURE_REF(conn);
74 [ - + ][ # # ]: 18 : RESULT_ENSURE_REF(conn->secure);
75 [ - + ][ # # ]: 18 : RESULT_ENSURE_REF(conn->secure->cipher_suite);
76 : :
77 : 18 : uint8_t secret_size = 0;
78 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_hmac_digest_size(conn->secure->cipher_suite->prf_alg, &secret_size));
79 : :
80 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->secrets.version.tls13.client_app_secret,
81 : 18 : secret_size));
82 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->secrets.version.tls13.server_app_secret,
83 : 18 : secret_size));
84 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->secrets.version.tls13.resumption_master_secret,
85 : 18 : secret_size));
86 : 18 : return S2N_RESULT_OK;
87 : 18 : }
88 : :
89 : : static S2N_RESULT s2n_connection_serialize_secrets(struct s2n_connection *conn, struct s2n_stuffer *output)
90 : 18 : {
91 [ - + ][ # # ]: 18 : RESULT_ENSURE_REF(conn);
92 [ # # ][ - + ]: 18 : RESULT_ENSURE_REF(conn->secure);
93 : :
94 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->secrets.version.tls12.master_secret,
95 : 18 : S2N_TLS_SECRET_LEN));
96 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->client_hello.random,
97 : 18 : S2N_TLS_RANDOM_DATA_LEN));
98 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->handshake_params.server_random,
99 : 18 : S2N_TLS_RANDOM_DATA_LEN));
100 : :
101 : : /* TLS1.0 and SSLv3 CBC chain the implicit IV across records; capture it so
102 : : * the deserialized connection can keep talking to its peer.
103 : : */
104 [ + + ]: 18 : if (s2n_serialization_includes_implicit_iv(conn->actual_protocol_version,
105 : 18 : conn->secure->cipher_suite)) {
106 [ - + ]: 2 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->secure->client_implicit_iv,
107 : 2 : S2N_TLS_MAX_IV_LEN));
108 [ - + ]: 2 : RESULT_GUARD_POSIX(s2n_stuffer_write_bytes(output, conn->secure->server_implicit_iv,
109 : 2 : S2N_TLS_MAX_IV_LEN));
110 : 2 : }
111 : 18 : return S2N_RESULT_OK;
112 : 18 : }
113 : :
114 : : int s2n_connection_serialize(struct s2n_connection *conn, uint8_t *buffer, uint32_t buffer_length)
115 : 43 : {
116 [ + + ][ + - ]: 43 : POSIX_ENSURE_REF(conn);
117 [ - + ][ # # ]: 42 : POSIX_ENSURE_REF(conn->secure);
118 [ # # ][ - + ]: 42 : POSIX_ENSURE_REF(conn->secure->cipher_suite);
119 [ - + ][ # # ]: 42 : POSIX_ENSURE_REF(conn->config);
120 [ + + ][ + - ]: 42 : POSIX_ENSURE_REF(buffer);
121 : :
122 [ + + ][ + - ]: 41 : POSIX_ENSURE(conn->config->serialized_connection_version != S2N_SERIALIZED_CONN_NONE,
123 : 40 : S2N_ERR_INVALID_STATE);
124 : :
125 : : /* This method must be called after negotiation */
126 [ + + ][ + - ]: 40 : POSIX_ENSURE(s2n_handshake_is_complete(conn), S2N_ERR_HANDSHAKE_NOT_COMPLETE);
127 : :
128 : : /* The connection must not be closed already. Otherwise, we might have an alert
129 : : * queued up that would be sent in cleartext after we disable encryption. */
130 : 39 : s2n_io_status status = S2N_IO_FULL_DUPLEX;
131 [ + + ][ + - ]: 39 : POSIX_ENSURE(s2n_connection_check_io_status(conn, status), S2N_ERR_CLOSED);
132 : :
133 : : /* Best effort check for pending input or output data.
134 : : * This method should not be called until the application has stopped sending and receiving.
135 : : * Saving partial read or partial write state would complicate this problem.
136 : : */
137 [ + + ][ + - ]: 38 : POSIX_ENSURE(s2n_stuffer_data_available(&conn->header_in) == 0, S2N_ERR_INVALID_STATE);
138 [ # # ][ - + ]: 37 : POSIX_ENSURE(s2n_stuffer_data_available(&conn->in) == 0, S2N_ERR_INVALID_STATE);
139 [ - + ][ # # ]: 37 : POSIX_ENSURE(s2n_stuffer_data_available(&conn->out) == 0, S2N_ERR_INVALID_STATE);
140 : :
141 : 37 : uint32_t context_length = 0;
142 [ - + ]: 37 : POSIX_GUARD(s2n_connection_serialization_length(conn, &context_length));
143 [ + + ][ + - ]: 37 : POSIX_ENSURE(buffer_length >= context_length, S2N_ERR_INSUFFICIENT_MEM_SIZE);
144 : :
145 : : /* Stream ciphers (RC4) hold keystream position in libcrypto state that
146 : : * this API does not capture, so a deserialized stream-cipher connection
147 : : * cannot decrypt records from its peer. Reject rather than producing a
148 : : * blob that can't be used.
149 : : */
150 [ - + ][ # # ]: 36 : POSIX_ENSURE_REF(conn->secure->cipher_suite->record_alg);
151 [ # # ][ - + ]: 36 : POSIX_ENSURE_REF(conn->secure->cipher_suite->record_alg->cipher);
152 [ # # ][ - + ]: 36 : POSIX_ENSURE(conn->secure->cipher_suite->record_alg->cipher->type != S2N_STREAM,
153 : 36 : S2N_ERR_INVALID_STATE);
154 : :
155 : 36 : struct s2n_blob context_blob = { 0 };
156 [ - + ]: 36 : POSIX_GUARD(s2n_blob_init(&context_blob, buffer, buffer_length));
157 : 36 : struct s2n_stuffer output = { 0 };
158 [ - + ]: 36 : POSIX_GUARD(s2n_stuffer_init(&output, &context_blob));
159 : :
160 [ - + ]: 36 : POSIX_GUARD(s2n_stuffer_write_uint64(&output, S2N_SERIALIZED_CONN_V1));
161 : :
162 [ - + ]: 36 : POSIX_GUARD(s2n_stuffer_write_uint8(&output, conn->actual_protocol_version / 10));
163 [ - + ]: 36 : POSIX_GUARD(s2n_stuffer_write_uint8(&output, conn->actual_protocol_version % 10));
164 [ - + ]: 36 : POSIX_GUARD(s2n_stuffer_write_bytes(&output, conn->secure->cipher_suite->iana_value, S2N_TLS_CIPHER_SUITE_LEN));
165 : :
166 [ - + ]: 36 : POSIX_GUARD(s2n_stuffer_write_bytes(&output, conn->secure->client_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
167 [ - + ]: 36 : POSIX_GUARD(s2n_stuffer_write_bytes(&output, conn->secure->server_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
168 : :
169 [ - + ]: 36 : POSIX_GUARD(s2n_stuffer_write_uint16(&output, conn->max_outgoing_fragment_length));
170 : :
171 [ + + ]: 36 : if (conn->actual_protocol_version >= S2N_TLS13) {
172 [ - + ]: 18 : POSIX_GUARD_RESULT(s2n_connection_serialize_tls13_secrets(conn, &output));
173 : 18 : } else {
174 [ - + ]: 18 : POSIX_GUARD_RESULT(s2n_connection_serialize_secrets(conn, &output));
175 : 18 : }
176 : :
177 : : /* Users should not be able to send/recv on the connection after serialization as that
178 : : * could lead to nonce reuse. We close the connection to prevent the application from sending
179 : : * more application data. However, the application could still send a close_notify alert record
180 : : * to shutdown the connection, so we also intentionally wipe keys and disable encryption.
181 : : *
182 : : * A plaintext close_notify alert is not a security concern, although the peer will likely consider
183 : : * it an error.
184 : : */
185 [ - + ]: 36 : POSIX_GUARD_RESULT(s2n_connection_set_closed(conn));
186 [ - + ]: 36 : POSIX_GUARD_RESULT(s2n_crypto_parameters_wipe(conn->secure));
187 : :
188 : 36 : return S2N_SUCCESS;
189 : 36 : }
190 : :
191 : : struct s2n_connection_deserialize {
192 : : uint8_t protocol_version;
193 : : struct s2n_cipher_suite *cipher_suite;
194 : : uint8_t client_sequence_number[S2N_TLS_SEQUENCE_NUM_LEN];
195 : : uint8_t server_sequence_number[S2N_TLS_SEQUENCE_NUM_LEN];
196 : : uint16_t max_fragment_len;
197 : : union {
198 : : struct {
199 : : uint8_t master_secret[S2N_TLS_SECRET_LEN];
200 : : uint8_t client_random[S2N_TLS_RANDOM_DATA_LEN];
201 : : uint8_t server_random[S2N_TLS_RANDOM_DATA_LEN];
202 : : /* Only set for blobs with protocol_version < S2N_TLS11 + CBC/composite cipher */
203 : : uint8_t client_implicit_iv[S2N_TLS_MAX_IV_LEN];
204 : : uint8_t server_implicit_iv[S2N_TLS_MAX_IV_LEN];
205 : : } tls12;
206 : : struct {
207 : : uint8_t secret_size;
208 : : uint8_t client_application_secret[S2N_TLS_SECRET_LEN];
209 : : uint8_t server_application_secret[S2N_TLS_SECRET_LEN];
210 : : uint8_t resumption_master_secret[S2N_TLS_SECRET_LEN];
211 : : } tls13;
212 : : } version;
213 : : };
214 : :
215 : : static S2N_RESULT s2n_connection_deserialize_tls13_secrets(struct s2n_stuffer *input,
216 : : struct s2n_connection_deserialize *parsed_values)
217 : 17 : {
218 [ # # ][ - + ]: 17 : RESULT_ENSURE_REF(input);
219 [ - + ][ # # ]: 17 : RESULT_ENSURE_REF(parsed_values);
220 : :
221 [ - + ]: 17 : RESULT_GUARD_POSIX(s2n_hmac_digest_size(parsed_values->cipher_suite->prf_alg,
222 : 17 : &parsed_values->version.tls13.secret_size));
223 [ - + ]: 17 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls13.client_application_secret,
224 : 17 : parsed_values->version.tls13.secret_size));
225 [ - + ]: 17 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls13.server_application_secret,
226 : 17 : parsed_values->version.tls13.secret_size));
227 [ - + ]: 17 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls13.resumption_master_secret,
228 : 17 : parsed_values->version.tls13.secret_size));
229 : :
230 : 17 : return S2N_RESULT_OK;
231 : 17 : }
232 : :
233 : : static S2N_RESULT s2n_connection_deserialize_secrets(struct s2n_stuffer *input,
234 : : struct s2n_connection_deserialize *parsed_values)
235 : 18 : {
236 [ - + ][ # # ]: 18 : RESULT_ENSURE_REF(input);
237 [ - + ][ # # ]: 18 : RESULT_ENSURE_REF(parsed_values);
238 [ - + ][ # # ]: 18 : RESULT_ENSURE_REF(parsed_values->cipher_suite);
239 [ - + ][ # # ]: 18 : RESULT_ENSURE_REF(parsed_values->cipher_suite->record_alg);
240 [ # # ][ - + ]: 18 : RESULT_ENSURE_REF(parsed_values->cipher_suite->record_alg->cipher);
241 : :
242 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls12.master_secret, S2N_TLS_SECRET_LEN));
243 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls12.client_random, S2N_TLS_RANDOM_DATA_LEN));
244 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls12.server_random, S2N_TLS_RANDOM_DATA_LEN));
245 : :
246 : : /* TLS1.0 and SSLv3 CBC blobs trail the implicit IVs. See
247 : : * s2n_connection_serialize_secrets. Other blobs end at server_random. */
248 [ + + ]: 18 : if (s2n_serialization_includes_implicit_iv(parsed_values->protocol_version,
249 : 18 : parsed_values->cipher_suite)) {
250 [ - + ]: 2 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls12.client_implicit_iv,
251 : 2 : S2N_TLS_MAX_IV_LEN));
252 [ - + ]: 2 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(input, parsed_values->version.tls12.server_implicit_iv,
253 : 2 : S2N_TLS_MAX_IV_LEN));
254 : 2 : }
255 : :
256 : 18 : return S2N_RESULT_OK;
257 : 18 : }
258 : :
259 : : static S2N_RESULT s2n_connection_deserialize_parse(uint8_t *buffer, uint32_t buffer_length,
260 : : struct s2n_connection_deserialize *parsed_values)
261 : 38 : {
262 [ # # ][ - + ]: 38 : RESULT_ENSURE_REF(parsed_values);
263 : :
264 : 38 : struct s2n_blob context_blob = { 0 };
265 [ - + ]: 38 : RESULT_GUARD_POSIX(s2n_blob_init(&context_blob, buffer, buffer_length));
266 : 38 : struct s2n_stuffer input = { 0 };
267 [ - + ]: 38 : RESULT_GUARD_POSIX(s2n_stuffer_init_written(&input, &context_blob));
268 : :
269 : 38 : uint64_t serialized_version = 0;
270 [ - + ]: 38 : RESULT_GUARD_POSIX(s2n_stuffer_read_uint64(&input, &serialized_version));
271 : : /* No other version is supported currently */
272 [ + + ][ + - ]: 38 : RESULT_ENSURE_EQ(serialized_version, S2N_SERIALIZED_CONN_V1);
273 : :
274 : 37 : uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN] = { 0 };
275 [ - + ]: 37 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(&input, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
276 : 37 : parsed_values->protocol_version = (protocol_version[0] * 10) + protocol_version[1];
277 : :
278 [ + - ][ + + ]: 37 : RESULT_ENSURE(parsed_values->protocol_version >= S2N_SSLv3 && parsed_values->protocol_version <= s2n_highest_protocol_version,
[ + + ]
279 : 35 : S2N_ERR_PROTOCOL_VERSION_UNSUPPORTED);
280 : :
281 : 35 : uint8_t cipher_suite[S2N_TLS_CIPHER_SUITE_LEN] = { 0 };
282 [ - + ]: 35 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(&input, cipher_suite, S2N_TLS_CIPHER_SUITE_LEN));
283 [ - + ]: 35 : RESULT_GUARD(s2n_cipher_suite_from_iana(cipher_suite, S2N_TLS_CIPHER_SUITE_LEN, &parsed_values->cipher_suite));
284 : :
285 : : /* SSLv3 uses a cloned cipher suite variant with the SSLv3-specific
286 : : * record_alg. s2n_cipher_suite_from_iana returns the base; swap to the
287 : : * variant. Same lookup-then-swap pattern as s2n_set_cipher_as_client and
288 : : * s2n_set_cipher_as_server during handshake.
289 : : */
290 [ + + ]: 35 : if (parsed_values->protocol_version == S2N_SSLv3) {
291 [ # # ][ - + ]: 2 : RESULT_ENSURE_REF(parsed_values->cipher_suite->sslv3_cipher_suite);
292 : 2 : parsed_values->cipher_suite = parsed_values->cipher_suite->sslv3_cipher_suite;
293 : 2 : }
294 : :
295 [ - + ]: 35 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(&input, parsed_values->client_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
296 [ - + ]: 35 : RESULT_GUARD_POSIX(s2n_stuffer_read_bytes(&input, parsed_values->server_sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
297 : :
298 [ - + ]: 35 : RESULT_GUARD_POSIX(s2n_stuffer_read_uint16(&input, &parsed_values->max_fragment_len));
299 : :
300 [ + + ]: 35 : if (parsed_values->protocol_version >= S2N_TLS13) {
301 [ - + ]: 17 : RESULT_GUARD(s2n_connection_deserialize_tls13_secrets(&input, parsed_values));
302 : 18 : } else {
303 [ - + ]: 18 : RESULT_GUARD(s2n_connection_deserialize_secrets(&input, parsed_values));
304 : 18 : }
305 : :
306 : 35 : return S2N_RESULT_OK;
307 : 35 : }
308 : :
309 : : /* Boringssl and AWS-LC do a special check in tls13 during the first call to encrypt after
310 : : * initialization. In the first call they assume that the sequence number will be 0, and therefore
311 : : * the provided nonce is equivalent to the implicit IV because 0 ^ iv = iv. The recovered implicit IV
312 : : * is stored and used later on to ensure the monotonicity of sequence numbers.
313 : : *
314 : : * In the case of deserialization, in the first call the sequence number may not be 0.
315 : : * Therefore the provided nonce cannot be considered to be the implicit IV because n ^ iv != iv.
316 : : * This inability to get the correct implicit IV causes issues with encryption later on.
317 : : *
318 : : * To resolve this we perform one throwaway encryption call with a zero sequence number after
319 : : * deserialization. This allows the libcrypto to recover the implicit IV correctly.
320 : : */
321 : : static S2N_RESULT s2n_initialize_implicit_iv(struct s2n_connection *conn, struct s2n_connection_deserialize *parsed_values)
322 : 17 : {
323 [ # # ][ - + ]: 17 : RESULT_ENSURE_REF(conn);
324 [ # # ][ - + ]: 17 : RESULT_ENSURE_REF(parsed_values);
325 [ # # ][ - + ]: 17 : RESULT_ENSURE_REF(conn->secure);
326 [ - + ][ # # ]: 17 : RESULT_ENSURE_REF(conn->server);
327 [ - + ][ # # ]: 17 : RESULT_ENSURE_REF(conn->client);
328 : :
329 [ + - ]: 17 : if (!s2n_libcrypto_supports_evp_aead_tls()) {
330 : 17 : return S2N_RESULT_OK;
331 : 17 : }
332 : :
333 : 0 : uint8_t *seq_num = parsed_values->server_sequence_number;
334 : 0 : uint8_t *implicit_iv = conn->server->server_implicit_iv;
335 : 0 : struct s2n_session_key key = conn->server->server_key;
336 [ # # ]: 0 : if (conn->mode == S2N_CLIENT) {
337 : 0 : seq_num = parsed_values->client_sequence_number;
338 : 0 : implicit_iv = conn->client->client_implicit_iv;
339 : 0 : key = conn->client->client_key;
340 : 0 : }
341 : :
342 : 0 : uint64_t parsed_sequence_num = 0;
343 : 0 : struct s2n_blob seq_num_blob = { 0 };
344 [ # # ]: 0 : RESULT_GUARD_POSIX(s2n_blob_init(&seq_num_blob, seq_num, S2N_TLS_SEQUENCE_NUM_LEN));
345 [ # # ]: 0 : RESULT_GUARD_POSIX(s2n_sequence_number_to_uint64(&seq_num_blob, &parsed_sequence_num));
346 : :
347 : : /* we don't need to initialize the context when the sequence number is 0 */
348 [ # # ]: 0 : if (parsed_sequence_num == 0) {
349 : 0 : return S2N_RESULT_OK;
350 : 0 : }
351 : :
352 : 0 : uint8_t in_data[S2N_TLS_GCM_TAG_LEN] = { 0 };
353 : 0 : struct s2n_blob in_blob = { 0 };
354 [ # # ]: 0 : RESULT_GUARD_POSIX(s2n_blob_init(&in_blob, in_data, sizeof(in_data)));
355 : :
356 : 0 : struct s2n_blob iv_blob = { 0 };
357 [ # # ]: 0 : RESULT_GUARD_POSIX(s2n_blob_init(&iv_blob, implicit_iv, S2N_TLS13_FIXED_IV_LEN));
358 : :
359 : 0 : struct s2n_blob aad_blob = { 0 };
360 [ # # ]: 0 : RESULT_GUARD_POSIX(s2n_blob_init(&aad_blob, NULL, 0));
361 : :
362 [ # # ][ # # ]: 0 : RESULT_ENSURE_REF(conn->secure->cipher_suite);
363 [ # # ][ # # ]: 0 : RESULT_ENSURE_REF(conn->secure->cipher_suite->record_alg);
364 [ # # ][ # # ]: 0 : RESULT_ENSURE_REF(conn->secure->cipher_suite->record_alg->cipher);
365 [ # # ]: 0 : RESULT_GUARD_POSIX(conn->secure->cipher_suite->record_alg->cipher->io.aead.encrypt(&key,
366 : 0 : &iv_blob, &aad_blob, &in_blob, &in_blob));
367 : :
368 : 0 : return S2N_RESULT_OK;
369 : 0 : }
370 : :
371 : : static S2N_RESULT s2n_restore_tls13_secrets(struct s2n_connection *conn, struct s2n_connection_deserialize *parsed_values)
372 : 17 : {
373 [ # # ][ - + ]: 17 : RESULT_ENSURE_REF(conn);
374 [ - + ][ # # ]: 17 : RESULT_ENSURE_REF(parsed_values);
375 : :
376 [ # # ][ - + ]: 17 : RESULT_CHECKED_MEMCPY(conn->secrets.version.tls13.client_app_secret,
[ + - ]
377 : 17 : parsed_values->version.tls13.client_application_secret, parsed_values->version.tls13.secret_size);
378 [ # # ][ - + ]: 17 : RESULT_CHECKED_MEMCPY(conn->secrets.version.tls13.server_app_secret,
[ + - ]
379 : 17 : parsed_values->version.tls13.server_application_secret, parsed_values->version.tls13.secret_size);
380 [ - + ][ # # ]: 17 : RESULT_CHECKED_MEMCPY(conn->secrets.version.tls13.resumption_master_secret,
[ + - ]
381 : 17 : parsed_values->version.tls13.resumption_master_secret, parsed_values->version.tls13.secret_size);
382 : :
383 [ - + ]: 17 : RESULT_GUARD(s2n_tls13_key_schedule_set_key(conn, S2N_MASTER_SECRET, S2N_SERVER));
384 [ - + ]: 17 : RESULT_GUARD(s2n_tls13_key_schedule_set_key(conn, S2N_MASTER_SECRET, S2N_CLIENT));
385 : :
386 [ - + ]: 17 : RESULT_GUARD(s2n_initialize_implicit_iv(conn, parsed_values));
387 : :
388 : 17 : return S2N_RESULT_OK;
389 : 17 : }
390 : :
391 : : static S2N_RESULT s2n_restore_secrets(struct s2n_connection *conn, struct s2n_connection_deserialize *parsed_values)
392 : 18 : {
393 [ # # ][ - + ]: 18 : RESULT_ENSURE_REF(conn);
394 [ # # ][ - + ]: 18 : RESULT_ENSURE_REF(parsed_values);
395 [ # # ][ - + ]: 18 : RESULT_ENSURE_REF(conn->secure);
396 : :
397 [ - + ][ # # ]: 18 : RESULT_CHECKED_MEMCPY(conn->secrets.version.tls12.master_secret, parsed_values->version.tls12.master_secret,
[ + - ]
398 : 18 : S2N_TLS_SECRET_LEN);
399 [ - + ][ # # ]: 18 : RESULT_CHECKED_MEMCPY(conn->client_hello.random, parsed_values->version.tls12.client_random,
[ + - ]
400 : 18 : S2N_TLS_RANDOM_DATA_LEN);
401 [ - + ][ # # ]: 18 : RESULT_CHECKED_MEMCPY(conn->handshake_params.server_random, parsed_values->version.tls12.server_random,
[ + - ]
402 : 18 : S2N_TLS_RANDOM_DATA_LEN);
403 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_prf_key_expansion(conn));
404 : :
405 : : /* PRF key expansion seeds the implicit IVs from the master secret, which is
406 : : * only correct at record 0. For TLS1.0 and SSLv3 CBC the blob ships the
407 : : * current IV state so the connection can continue where it left off.
408 : : */
409 [ + + ]: 18 : if (s2n_serialization_includes_implicit_iv(parsed_values->protocol_version,
410 : 18 : parsed_values->cipher_suite)) {
411 [ - + ][ # # ]: 2 : RESULT_CHECKED_MEMCPY(conn->secure->client_implicit_iv,
[ + - ]
412 : 2 : parsed_values->version.tls12.client_implicit_iv, S2N_TLS_MAX_IV_LEN);
413 [ - + ][ # # ]: 2 : RESULT_CHECKED_MEMCPY(conn->secure->server_implicit_iv,
[ + - ]
414 : 2 : parsed_values->version.tls12.server_implicit_iv, S2N_TLS_MAX_IV_LEN);
415 : 2 : }
416 : :
417 : 18 : return S2N_RESULT_OK;
418 : 18 : }
419 : :
420 : : int s2n_connection_deserialize(struct s2n_connection *conn, uint8_t *buffer, uint32_t buffer_length)
421 : 40 : {
422 [ + + ][ + - ]: 40 : POSIX_ENSURE_REF(conn);
423 [ - + ][ # # ]: 39 : POSIX_ENSURE_REF(conn->secure);
424 [ + + ][ + - ]: 39 : POSIX_ENSURE_REF(buffer);
425 : :
426 : : /* The serialized blob does not include a MAC or signature. All values from the buffer
427 : : * are trusted after basic format validation. Callers must verify the integrity of the
428 : : * buffer before calling this function. See the s2n_connection_deserialize API docs.
429 : : */
430 : :
431 : : /* Read parsed values into a temporary struct so that the connection is unaltered if parsing fails */
432 : 38 : struct s2n_connection_deserialize parsed_values = { 0 };
433 [ + + ][ + - ]: 38 : POSIX_ENSURE(s2n_result_is_ok(s2n_connection_deserialize_parse(buffer, buffer_length, &parsed_values)),
434 : 35 : S2N_ERR_INVALID_SERIALIZED_CONNECTION);
435 : :
436 : : /* Rehydrate fields now that parsing has completed successfully */
437 : 35 : conn->actual_protocol_version = parsed_values.protocol_version;
438 : 35 : conn->secure->cipher_suite = parsed_values.cipher_suite;
439 [ - + ]: 35 : POSIX_GUARD_RESULT(s2n_connection_set_max_fragment_length(conn, parsed_values.max_fragment_len));
440 : :
441 : : /* Mark the connection as having been deserialized */
442 : 35 : conn->deserialized_conn = true;
443 : :
444 : : /* Key expansion */
445 [ + + ]: 35 : if (parsed_values.protocol_version >= S2N_TLS13) {
446 [ - + ]: 17 : POSIX_GUARD_RESULT(s2n_restore_tls13_secrets(conn, &parsed_values));
447 : 18 : } else {
448 [ - + ]: 18 : POSIX_GUARD_RESULT(s2n_restore_secrets(conn, &parsed_values));
449 : 18 : }
450 : :
451 : : /* Wait until after key generation to restore sequence numbers since they get zeroed during
452 : : * key expansion */
453 [ # # ][ - + ]: 35 : POSIX_CHECKED_MEMCPY(conn->secure->client_sequence_number, parsed_values.client_sequence_number,
[ + - ]
454 : 35 : S2N_TLS_SEQUENCE_NUM_LEN);
455 [ - + ][ # # ]: 35 : POSIX_CHECKED_MEMCPY(conn->secure->server_sequence_number, parsed_values.server_sequence_number,
[ + - ]
456 : 35 : S2N_TLS_SEQUENCE_NUM_LEN);
457 : :
458 : 35 : conn->client = conn->secure;
459 : 35 : conn->server = conn->secure;
460 : :
461 : 35 : return S2N_SUCCESS;
462 : 35 : }
|