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 <stdint.h>
17 : :
18 : : #include "crypto/s2n_cipher.h"
19 : : #include "crypto/s2n_hmac.h"
20 : : #include "crypto/s2n_sequence.h"
21 : : #include "error/s2n_errno.h"
22 : : #include "stuffer/s2n_stuffer.h"
23 : : #include "tls/s2n_cipher_suites.h"
24 : : #include "tls/s2n_connection.h"
25 : : #include "tls/s2n_crypto.h"
26 : : #include "tls/s2n_ktls.h"
27 : : #include "tls/s2n_record.h"
28 : : #include "utils/s2n_blob.h"
29 : : #include "utils/s2n_random.h"
30 : : #include "utils/s2n_safety.h"
31 : :
32 : : extern uint8_t s2n_unknown_protocol_version;
33 : :
34 : : /* In TLS1.3 the record type is obfuscated as APPLICATION_DATA once the handshake begins to be encrypted.
35 : : * The real record type is encrypted and written in the final byte of the record.
36 : : * In TLS1.2 the record type is always cleartext. */
37 : 3608542 : #define RECORD_TYPE(is_tls13_record, content_type) (is_tls13_record ? TLS_APPLICATION_DATA : content_type)
38 : :
39 : : /* How much overhead does the IV, MAC, TAG and padding bytes introduce ? */
40 : : static S2N_RESULT s2n_tls_record_overhead(struct s2n_connection *conn, uint16_t *out)
41 : 3608867 : {
42 [ - + ][ # # ]: 3608867 : RESULT_ENSURE_REF(conn);
43 [ # # ][ - + ]: 3608867 : RESULT_ENSURE_MUT(out);
44 : 3608867 : struct s2n_crypto_parameters *active = conn->server;
45 : :
46 [ + + ]: 3608867 : if (conn->mode == S2N_CLIENT) {
47 : 85374 : active = conn->client;
48 : 85374 : }
49 : :
50 : 3608867 : uint8_t extra = 0;
51 [ - + ]: 3608867 : RESULT_GUARD_POSIX(s2n_hmac_digest_size(active->cipher_suite->record_alg->hmac_alg, &extra));
52 : :
53 [ + + ]: 3608867 : if (active->cipher_suite->record_alg->cipher->type == S2N_CBC) {
54 : : /* Subtract one for the padding length byte */
55 : 41818 : extra += 1;
56 : :
57 [ + + ]: 41818 : if (conn->actual_protocol_version > S2N_TLS10) {
58 : 32922 : extra += active->cipher_suite->record_alg->cipher->io.cbc.record_iv_size;
59 : 32922 : }
60 [ + + ]: 3567049 : } else if (active->cipher_suite->record_alg->cipher->type == S2N_AEAD) {
61 : 3348013 : extra += active->cipher_suite->record_alg->cipher->io.aead.tag_size;
62 : 3348013 : extra += active->cipher_suite->record_alg->cipher->io.aead.record_iv_size;
63 [ + + ][ + + ]: 3348013 : } else if (active->cipher_suite->record_alg->cipher->type == S2N_COMPOSITE && conn->actual_protocol_version > S2N_TLS10) {
64 : 131169 : extra += active->cipher_suite->record_alg->cipher->io.comp.record_iv_size;
65 : 131169 : }
66 : :
67 : 3608867 : *out = extra;
68 : :
69 : 3608867 : return S2N_RESULT_OK;
70 : 3608867 : }
71 : :
72 : : /* This function returns maximum size of plaintext data to write for the payload.
73 : : * Record overheads are not included here.
74 : : */
75 : : S2N_RESULT s2n_record_max_write_payload_size(struct s2n_connection *conn, uint16_t *max_fragment_size)
76 : 3632706 : {
77 [ - + ][ # # ]: 3632706 : RESULT_ENSURE_REF(conn);
78 [ # # ][ - + ]: 3632706 : RESULT_ENSURE_REF(conn->config);
79 [ # # ][ - + ]: 3632706 : RESULT_ENSURE_MUT(max_fragment_size);
80 [ + + ][ + - ]: 3632706 : RESULT_ENSURE(conn->max_outgoing_fragment_length > 0, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
81 : :
82 [ + + ]: 3632705 : *max_fragment_size = S2N_MIN(conn->max_outgoing_fragment_length, S2N_TLS_MAXIMUM_FRAGMENT_LENGTH);
83 : :
84 : : /* If a custom send buffer is configured, ensure it will be large enough for the payload.
85 : : * That may mean we need a smaller fragment size.
86 : : */
87 : 3632705 : uint32_t send_buffer_override = conn->config->send_buffer_size_override;
88 [ + + ]: 3632705 : if (send_buffer_override) {
89 : 70 : uint16_t max_record_size = 0;
90 [ - + ]: 70 : RESULT_GUARD(s2n_record_max_write_size(conn, *max_fragment_size, &max_record_size));
91 [ + + ]: 70 : if (send_buffer_override < max_record_size) {
92 : 10 : size_t overhead = (max_record_size - *max_fragment_size);
93 [ - + ][ # # ]: 10 : RESULT_ENSURE_GT(send_buffer_override, overhead);
94 : 10 : *max_fragment_size = send_buffer_override - overhead;
95 : 10 : }
96 : 70 : }
97 : :
98 : 3632705 : return S2N_RESULT_OK;
99 : 3632705 : }
100 : :
101 : : S2N_RESULT s2n_record_max_write_size(struct s2n_connection *conn, uint16_t max_fragment_size, uint16_t *max_record_size)
102 : 3307871 : {
103 [ + + ][ + - ]: 3307871 : RESULT_ENSURE_REF(conn);
104 [ + + ][ + - ]: 3307870 : RESULT_ENSURE_MUT(max_record_size);
105 : :
106 [ + + ]: 3307869 : if (!IS_NEGOTIATED(conn)) {
107 : 3300748 : *max_record_size = S2N_TLS_MAX_RECORD_LEN_FOR(max_fragment_size);
108 [ + + ]: 3300748 : } else if (conn->actual_protocol_version < S2N_TLS13) {
109 : 2394 : *max_record_size = S2N_TLS12_MAX_RECORD_LEN_FOR(max_fragment_size);
110 : 4727 : } else {
111 : 4727 : *max_record_size = S2N_TLS13_MAX_RECORD_LEN_FOR(max_fragment_size);
112 : 4727 : }
113 : 3307869 : return S2N_RESULT_OK;
114 : 3307870 : }
115 : :
116 : : /* Find the largest size that will fit within an ethernet frame for a "small" payload */
117 : : S2N_RESULT s2n_record_min_write_payload_size(struct s2n_connection *conn, uint16_t *payload_size)
118 : 325 : {
119 [ # # ][ - + ]: 325 : RESULT_ENSURE_REF(conn);
120 [ # # ][ - + ]: 325 : RESULT_ENSURE_MUT(payload_size);
121 : :
122 : : /* remove ethernet, TCP/IP and TLS header overheads */
123 : : /* We pessimistically assume that it's an Ipv6 header (40 bytes) vs an Ipv4
124 : : * header (20 bytes) to avoid having to care about the IP protocol. */
125 : 325 : const uint16_t min_outgoing_fragment_length = ETH_MTU - IP_V6_HEADER_LENGTH
126 : 325 : - TCP_HEADER_LENGTH - TCP_OPTIONS_LENGTH - S2N_TLS_RECORD_HEADER_LENGTH;
127 : :
128 [ # # ]: 325 : RESULT_ENSURE(min_outgoing_fragment_length <= S2N_TLS_MAXIMUM_FRAGMENT_LENGTH, S2N_ERR_FRAGMENT_LENGTH_TOO_LARGE);
129 : 325 : uint16_t size = min_outgoing_fragment_length;
130 : :
131 [ + + ]: 325 : const struct s2n_crypto_parameters *active = conn->mode == S2N_CLIENT ? conn->client : conn->server;
132 : :
133 : : /* Round the fragment size down to be block aligned */
134 [ + + ]: 325 : if (active->cipher_suite->record_alg->cipher->type == S2N_CBC) {
135 : 1 : size -= size % active->cipher_suite->record_alg->cipher->io.cbc.block_size;
136 [ + + ]: 324 : } else if (active->cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
137 : 1 : size -= size % active->cipher_suite->record_alg->cipher->io.comp.block_size;
138 : : /* Composite digest length */
139 : 1 : size -= active->cipher_suite->record_alg->cipher->io.comp.mac_key_size;
140 : : /* Padding length byte */
141 : 1 : size -= 1;
142 : 1 : }
143 : :
144 : : /* If TLS1.3, remove content type */
145 [ + + ]: 325 : if (conn->actual_protocol_version >= S2N_TLS13) {
146 [ - + ][ # # ]: 68 : RESULT_ENSURE(size > S2N_TLS_CONTENT_TYPE_LENGTH, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
147 : 68 : size -= S2N_TLS_CONTENT_TYPE_LENGTH;
148 : 68 : }
149 : :
150 : : /* subtract overheads of a TLS record */
151 : 325 : uint16_t overhead = 0;
152 [ - + ]: 325 : RESULT_GUARD(s2n_tls_record_overhead(conn, &overhead));
153 [ - + ][ # # ]: 325 : RESULT_ENSURE(size > overhead, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
154 : 325 : size -= overhead;
155 : :
156 [ - + ][ # # ]: 325 : RESULT_ENSURE(size > 0, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
157 [ # # ][ - + ]: 325 : RESULT_ENSURE(size <= ETH_MTU, S2N_ERR_FRAGMENT_LENGTH_TOO_LARGE);
158 : :
159 : 325 : *payload_size = size;
160 : :
161 : 325 : return S2N_RESULT_OK;
162 : 325 : }
163 : :
164 : : /**
165 : : * Return the protocol version that should be written into the record header.
166 : : *
167 : : * This is the IANA version type (u16), not the internal s2n version type (u8).
168 : : *
169 : : * This may not be the actual protocol version that was negotiated. For example
170 : : * TLS 1.3 records treat the record header protocol as an "opaque" value pinned
171 : : * to TLS 1.2 (0x0303)
172 : : */
173 : : S2N_RESULT s2n_record_protocol_version(struct s2n_connection *conn, uint8_t record_type, uint16_t *out)
174 : 3608542 : {
175 : 3608542 : uint8_t record_protocol_version = conn->actual_protocol_version;
176 : :
177 : : /**
178 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-5.1
179 : : *# This version value is historical, deriving from the use of 0x0301 for
180 : : *# TLS 1.0 and 0x0300 for SSL 3.0. In order to maximize backward
181 : : *# compatibility, a record containing an initial ClientHello SHOULD have
182 : : *# version 0x0301 (reflecting TLS 1.0)
183 : : *
184 : : * We set actual_protocol_version early for clients, but we do not
185 : : * use that assumed value here in case we are talking to a legacy
186 : : * server that expects TLS1.0.
187 : : *
188 : : * Both TLS 1.3 early data and a deserialized connection will
189 : : * send data without the server_protocol_version being known. However,
190 : : * the record type would be set to APPLICATION_DATA in their cases
191 : : * so this check is avoided.
192 : : **/
193 [ + + ]: 3608542 : if (conn->server_protocol_version == s2n_unknown_protocol_version
194 [ + + ]: 3608542 : && record_type == TLS_HANDSHAKE) {
195 [ + + ]: 8336 : record_protocol_version = S2N_MIN(record_protocol_version, S2N_TLS10);
196 : 8336 : }
197 : :
198 : : /**
199 : : *= https://www.rfc-editor.org/rfc/rfc8446#section-5.1
200 : : *# legacy_record_version: MUST be set to 0x0303 for all records
201 : : *# generated by a TLS 1.3 implementation other than an initial
202 : : *# ClientHello (i.e., one not generated after a HelloRetryRequest),
203 : : *# where it MAY also be 0x0301 for compatibility purposes.
204 : : **/
205 [ + + ]: 3608542 : record_protocol_version = S2N_MIN(record_protocol_version, S2N_TLS12);
206 : :
207 : : /* Never send an empty protocol version.
208 : : * If the protocol version is unknown, default to TLS1.0 like we do for initial ClientHellos.
209 : : */
210 [ + + ]: 3608542 : if (record_protocol_version == s2n_unknown_protocol_version) {
211 : 18 : record_protocol_version = S2N_TLS10;
212 : 18 : }
213 : :
214 : 3608542 : uint16_t major_version = record_protocol_version / 10;
215 : 3608542 : uint16_t minor_version = record_protocol_version % 10;
216 : 3608542 : *out = (major_version << 8) | minor_version;
217 : :
218 : 3608542 : return S2N_RESULT_OK;
219 : 3608542 : }
220 : :
221 : : static inline int s2n_record_encrypt(
222 : : struct s2n_connection *conn,
223 : : const struct s2n_cipher_suite *cipher_suite,
224 : : struct s2n_session_key *session_key,
225 : : struct s2n_blob *iv,
226 : : struct s2n_blob *aad,
227 : : struct s2n_blob *en,
228 : : uint8_t *implicit_iv, uint16_t block_size)
229 : 3608541 : {
230 [ # # ][ - + ]: 3608541 : POSIX_ENSURE_REF(en->data);
231 : :
232 : 3608541 : switch (cipher_suite->record_alg->cipher->type) {
233 [ + + ]: 55048 : case S2N_STREAM:
234 [ - + ]: 55048 : POSIX_GUARD(cipher_suite->record_alg->cipher->io.stream.encrypt(session_key, en, en));
235 : 55048 : break;
236 [ + + ]: 55048 : case S2N_CBC:
237 [ - + ]: 41817 : POSIX_GUARD(cipher_suite->record_alg->cipher->io.cbc.encrypt(session_key, iv, en, en));
238 : :
239 : : /* Copy the last encrypted block to be the next IV */
240 [ + + ]: 41817 : if (conn->actual_protocol_version < S2N_TLS11) {
241 [ - + ][ # # ]: 8896 : POSIX_ENSURE_GTE(en->size, block_size);
242 [ - + ][ # # ]: 8896 : POSIX_CHECKED_MEMCPY(implicit_iv, en->data + en->size - block_size, block_size);
[ + - ]
243 : 8896 : }
244 : 41817 : break;
245 [ + + ]: 3347691 : case S2N_AEAD:
246 [ - + ]: 3347691 : POSIX_GUARD(cipher_suite->record_alg->cipher->io.aead.encrypt(session_key, iv, aad, en, en));
247 : 3347691 : break;
248 [ + + ]: 3347691 : case S2N_COMPOSITE:
249 : : /* This will: compute mac, append padding, append padding length, and encrypt */
250 [ - + ]: 163985 : POSIX_GUARD(cipher_suite->record_alg->cipher->io.comp.encrypt(session_key, iv, en, en));
251 : :
252 : : /* Copy the last encrypted block to be the next IV */
253 [ # # ][ - + ]: 163985 : POSIX_ENSURE_GTE(en->size, block_size);
254 [ - + ][ # # ]: 163985 : POSIX_CHECKED_MEMCPY(implicit_iv, en->data + en->size - block_size, block_size);
[ + - ]
255 : 163985 : break;
256 [ - + ]: 163985 : default:
257 [ # # ]: 0 : POSIX_BAIL(S2N_ERR_CIPHER_TYPE);
258 : 0 : break;
259 : 3608541 : }
260 : :
261 : 3608541 : return 0;
262 : 3608541 : }
263 : :
264 : : static S2N_RESULT s2n_record_write_mac(struct s2n_connection *conn, struct s2n_blob *record_header,
265 : : struct s2n_blob *plaintext, struct s2n_stuffer *out, uint32_t *bytes_written)
266 : 3608542 : {
267 [ - + ][ # # ]: 3608542 : RESULT_ENSURE_REF(conn);
268 [ # # ][ - + ]: 3608542 : RESULT_ENSURE_REF(conn->server);
269 [ - + ][ # # ]: 3608542 : RESULT_ENSURE_REF(conn->client);
270 [ - + ][ # # ]: 3608542 : RESULT_ENSURE_REF(record_header);
271 [ - + ][ # # ]: 3608542 : RESULT_ENSURE_REF(plaintext);
272 [ - + ][ # # ]: 3608542 : RESULT_ENSURE_REF(out);
273 [ # # ][ - + ]: 3608542 : RESULT_ENSURE_REF(bytes_written);
274 : 3608542 : *bytes_written = 0;
275 : :
276 : 3608542 : struct s2n_hmac_state *mac = &conn->server->server_record_mac;
277 : 3608542 : const struct s2n_cipher_suite *cipher_suite = conn->server->cipher_suite;
278 : 3608542 : uint8_t *sequence_number = conn->server->server_sequence_number;
279 : :
280 [ + + ]: 3608542 : if (conn->mode == S2N_CLIENT) {
281 : 85056 : mac = &conn->client->client_record_mac;
282 : 85056 : cipher_suite = conn->client->cipher_suite;
283 : 85056 : sequence_number = conn->client->client_sequence_number;
284 : 85056 : }
285 : :
286 [ - + ][ # # ]: 3608542 : RESULT_ENSURE_REF(cipher_suite);
287 [ - + ][ # # ]: 3608542 : RESULT_ENSURE_REF(cipher_suite->record_alg);
288 : :
289 [ + + ]: 3608542 : if (cipher_suite->record_alg->hmac_alg == S2N_HMAC_NONE) {
290 : : /* If the S2N_HMAC_NONE algorithm is specified, a MAC should not be explicitly written.
291 : : * This is the case for AEAD and Composite cipher types, where the MAC is written as part
292 : : * of encryption. This is also the case for plaintext handshake records, where the null
293 : : * stream cipher is used.
294 : : */
295 : 3558634 : return S2N_RESULT_OK;
296 : 3558634 : }
297 : :
298 : : /**
299 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-6.2.3.1
300 : : *# The MAC is generated as:
301 : : *#
302 : : *# MAC(MAC_write_key, seq_num +
303 : : */
304 [ - + ]: 49908 : RESULT_GUARD_POSIX(s2n_hmac_update(mac, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
305 : :
306 : 49908 : struct s2n_stuffer header_stuffer = { 0 };
307 [ - + ]: 49908 : RESULT_GUARD_POSIX(s2n_stuffer_init_written(&header_stuffer, record_header));
308 : :
309 : : /**
310 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-6.2.3.1
311 : : *# TLSCompressed.type +
312 : : */
313 : 49908 : void *record_type_byte = s2n_stuffer_raw_read(&header_stuffer, sizeof(uint8_t));
314 [ # # ][ - + ]: 49908 : RESULT_ENSURE_REF(record_type_byte);
315 [ - + ]: 49908 : RESULT_GUARD_POSIX(s2n_hmac_update(mac, record_type_byte, sizeof(uint8_t)));
316 : :
317 : : /**
318 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-6.2.3.1
319 : : *# TLSCompressed.version +
320 : : */
321 : 49908 : void *protocol_version_bytes = s2n_stuffer_raw_read(&header_stuffer, S2N_TLS_PROTOCOL_VERSION_LEN);
322 [ - + ][ # # ]: 49908 : RESULT_ENSURE_REF(protocol_version_bytes);
323 [ + + ]: 49908 : if (conn->actual_protocol_version > S2N_SSLv3) {
324 : : /* SSLv3 doesn't include the protocol version in the MAC. */
325 [ - + ]: 49242 : RESULT_GUARD_POSIX(s2n_hmac_update(mac, protocol_version_bytes, S2N_TLS_PROTOCOL_VERSION_LEN));
326 : 49242 : }
327 : :
328 : : /**
329 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-6.2.3.1
330 : : *# TLSCompressed.length +
331 : : *
332 : : * Note that the length field refers to the length of the plaintext content, not the length of
333 : : * TLSCiphertext fragment written to the record header, which accounts for additional fields
334 : : * such as the padding and MAC.
335 : : */
336 : 49908 : uint8_t content_length_bytes[sizeof(uint16_t)] = { 0 };
337 : 49908 : struct s2n_blob content_length_blob = { 0 };
338 [ - + ]: 49908 : RESULT_GUARD_POSIX(s2n_blob_init(&content_length_blob, content_length_bytes, sizeof(content_length_bytes)));
339 : 49908 : struct s2n_stuffer content_length_stuffer = { 0 };
340 [ - + ]: 49908 : RESULT_GUARD_POSIX(s2n_stuffer_init(&content_length_stuffer, &content_length_blob));
341 [ - + ]: 49908 : RESULT_GUARD_POSIX(s2n_stuffer_write_uint16(&content_length_stuffer, plaintext->size));
342 [ - + ]: 49908 : RESULT_GUARD_POSIX(s2n_hmac_update(mac, content_length_bytes, sizeof(content_length_bytes)));
343 : :
344 : : /**
345 : : *= https://www.rfc-editor.org/rfc/rfc5246#section-6.2.3.1
346 : : *# TLSCompressed.fragment);
347 : : *#
348 : : *# where "+" denotes concatenation.
349 : : */
350 [ - + ]: 49908 : RESULT_GUARD_POSIX(s2n_hmac_update(mac, plaintext->data, plaintext->size));
351 : :
352 : 49908 : uint8_t mac_digest_size = 0;
353 [ - + ]: 49908 : RESULT_GUARD_POSIX(s2n_hmac_digest_size(mac->alg, &mac_digest_size));
354 : 49908 : uint8_t *digest = s2n_stuffer_raw_write(out, mac_digest_size);
355 [ - + ][ # # ]: 49908 : RESULT_ENSURE_REF(digest);
356 [ - + ]: 49908 : RESULT_GUARD_POSIX(s2n_hmac_digest(mac, digest, mac_digest_size));
357 : 49908 : *bytes_written = mac_digest_size;
358 : :
359 [ - + ]: 49908 : RESULT_GUARD_POSIX(s2n_hmac_reset(mac));
360 : :
361 : 49908 : return S2N_RESULT_OK;
362 : 49908 : }
363 : :
364 : : int s2n_record_writev(struct s2n_connection *conn, uint8_t content_type, const struct iovec *in, int in_count, size_t offs, size_t to_write)
365 : 3608552 : {
366 [ + + ]: 3608552 : if (conn->ktls_send_enabled) {
367 : 8 : return s2n_ktls_record_writev(conn, content_type, in, in_count, offs, to_write);
368 : 8 : }
369 : :
370 : 3608544 : struct s2n_blob iv = { 0 };
371 : 3608544 : uint8_t padding = 0;
372 : 3608544 : uint16_t block_size = 0;
373 : 3608544 : uint8_t aad_iv[S2N_TLS_MAX_IV_LEN] = { 0 };
374 : :
375 : : /* In TLS 1.3, handle CCS message as unprotected records */
376 : 3608544 : struct s2n_crypto_parameters *current_client_crypto = conn->client;
377 : 3608544 : struct s2n_crypto_parameters *current_server_crypto = conn->server;
378 [ + + ][ + + ]: 3608544 : if (conn->actual_protocol_version == S2N_TLS13 && content_type == TLS_CHANGE_CIPHER_SPEC) {
379 [ # # ][ - + ]: 7859 : POSIX_ENSURE_REF(conn->initial);
380 : 7859 : conn->client = conn->initial;
381 : 7859 : conn->server = conn->initial;
382 : 7859 : }
383 : :
384 : 3608544 : uint8_t *sequence_number = conn->server->server_sequence_number;
385 : 3608544 : struct s2n_session_key *session_key = &conn->server->server_key;
386 : 3608544 : const struct s2n_cipher_suite *cipher_suite = conn->server->cipher_suite;
387 : 3608544 : uint8_t *implicit_iv = conn->server->server_implicit_iv;
388 : :
389 [ + + ]: 3608544 : if (conn->mode == S2N_CLIENT) {
390 : 85056 : sequence_number = conn->client->client_sequence_number;
391 : 85056 : session_key = &conn->client->client_key;
392 : 85056 : cipher_suite = conn->client->cipher_suite;
393 : 85056 : implicit_iv = conn->client->client_implicit_iv;
394 : 85056 : }
395 : :
396 : : /* The NULL stream cipher MUST NEVER be used for ApplicationData.
397 : : * Writing ApplicationData unencrypted defeats the purpose of TLS. */
398 [ + + ]: 3608544 : if (cipher_suite->record_alg->cipher == &s2n_null_cipher) {
399 [ + - ][ + + ]: 55050 : POSIX_ENSURE(content_type != TLS_APPLICATION_DATA, S2N_ERR_ENCRYPT);
400 : 55050 : }
401 : :
402 : 3608543 : const int is_tls13_record = cipher_suite->record_alg->flags & S2N_TLS13_RECORD_AEAD_NONCE;
403 [ - + ][ # # ]: 3608543 : s2n_stack_blob(aad, is_tls13_record ? S2N_TLS13_AAD_LEN : S2N_TLS_MAX_AAD_LEN, S2N_TLS_MAX_AAD_LEN);
[ - + ][ + + ]
404 : :
405 : : /* If we aren't buffering multiple records, then the output stuffer should be empty. */
406 [ + + ]: 3608543 : if (!conn->multirecord_send) {
407 [ + + ][ + - ]: 3608513 : POSIX_ENSURE(s2n_stuffer_data_available(&conn->out) == 0, S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING);
408 : 3608513 : }
409 : :
410 : : /* Before we do anything, we need to figure out what the length of the
411 : : * fragment is going to be.
412 : : */
413 : 3608542 : uint16_t max_write_payload_size = 0;
414 [ - + ]: 3608542 : POSIX_GUARD_RESULT(s2n_record_max_write_payload_size(conn, &max_write_payload_size));
415 [ + + ]: 3608542 : const uint16_t data_bytes_to_take = S2N_MIN(to_write, max_write_payload_size);
416 : :
417 : 3608542 : uint16_t extra = 0;
418 [ - + ]: 3608542 : POSIX_GUARD_RESULT(s2n_tls_record_overhead(conn, &extra));
419 : :
420 : : /* If we have padding to worry about, figure that out too */
421 [ + + ]: 3608542 : if (cipher_suite->record_alg->cipher->type == S2N_CBC) {
422 : 41817 : block_size = cipher_suite->record_alg->cipher->io.cbc.block_size;
423 [ + + ]: 41817 : if (((data_bytes_to_take + extra) % block_size)) {
424 : 38764 : padding = block_size - ((data_bytes_to_take + extra) % block_size);
425 : 38764 : }
426 [ + + ]: 3566725 : } else if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
427 : 163985 : block_size = cipher_suite->record_alg->cipher->io.comp.block_size;
428 : 163985 : }
429 : :
430 [ + + ]: 3608542 : if (s2n_stuffer_is_freed(&conn->out)) {
431 : : /* If the output buffer has not been allocated yet, allocate
432 : : * at least enough memory to hold a record with the local maximum fragment length.
433 : : *
434 : : * The local maximum fragment length is:
435 : : * 1) The local default configured for new connections
436 : : * 2) The local value set by the user via s2n_connection_prefer_throughput()
437 : : * or s2n_connection_prefer_low_latency()
438 : : * 3) On the server, the minimum of the local value and the value negotiated with the
439 : : * client via the max_fragment_length extension
440 : : *
441 : : * Because this only occurs if the output buffer has not been allocated,
442 : : * it does NOT resize existing buffers.
443 : : */
444 : 3307383 : uint16_t max_wire_record_size = 0;
445 [ - + ]: 3307383 : POSIX_GUARD_RESULT(s2n_record_max_write_size(conn, max_write_payload_size, &max_wire_record_size));
446 : :
447 [ + + ]: 3307383 : uint32_t buffer_size = S2N_MAX(conn->config->send_buffer_size_override, max_wire_record_size);
448 [ - + ]: 3307383 : POSIX_GUARD(s2n_stuffer_growable_alloc(&conn->out, buffer_size));
449 : 3307383 : }
450 : :
451 : : /* A record only local stuffer used to avoid tainting the conn->out stuffer or overwriting
452 : : * previous records. It should be used to add an individual record to the out stuffer.
453 : : */
454 : 3608542 : struct s2n_blob record_blob = { 0 };
455 : 3608542 : struct s2n_stuffer record_stuffer = { 0 };
456 [ - + ]: 3608542 : POSIX_GUARD(s2n_blob_init(&record_blob,
457 : 3608542 : conn->out.blob.data + conn->out.write_cursor,
458 : 3608542 : s2n_stuffer_space_remaining(&conn->out)));
459 [ - + ]: 3608542 : POSIX_GUARD(s2n_stuffer_init(&record_stuffer, &record_blob));
460 : :
461 : : /* Now that we know the length, start writing the record */
462 [ + + ]: 3608542 : uint8_t record_type = RECORD_TYPE(is_tls13_record, content_type);
463 [ - + ]: 3608542 : POSIX_GUARD(s2n_stuffer_write_uint8(&record_stuffer, record_type));
464 : 3608542 : uint16_t wire_protocol_version = 0;
465 [ - + ]: 3608542 : POSIX_GUARD_RESULT(s2n_record_protocol_version(conn, record_type, &wire_protocol_version));
466 [ - + ]: 3608542 : POSIX_GUARD(s2n_stuffer_write_uint16(&record_stuffer, wire_protocol_version));
467 : :
468 : : /* Compute non-payload parts of the MAC(seq num, type, proto vers, fragment length) for composite ciphers.
469 : : * Composite "encrypt" will MAC the payload data and fill in padding.
470 : : */
471 [ + + ]: 3608542 : if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
472 : : /* Only fragment length is needed for MAC, but the EVP ctrl function needs fragment length + eiv len. */
473 : 163985 : uint16_t payload_and_eiv_len = data_bytes_to_take;
474 [ + + ]: 163985 : if (conn->actual_protocol_version > S2N_TLS10) {
475 : 131168 : payload_and_eiv_len += block_size;
476 : 131168 : }
477 : :
478 : : /* Outputs number of extra bytes required for MAC and padding */
479 : 163985 : int pad_and_mac_len = 0;
480 [ - + ]: 163985 : POSIX_GUARD(cipher_suite->record_alg->cipher->io.comp.initial_hmac(session_key, sequence_number, content_type, wire_protocol_version,
481 : 163985 : payload_and_eiv_len, &pad_and_mac_len));
482 : 163985 : extra += pad_and_mac_len;
483 : 163985 : }
484 : :
485 : : /* TLS 1.3 protected record occupies one extra byte for content type */
486 [ + + ]: 3608542 : if (is_tls13_record) {
487 : 111360 : extra += S2N_TLS_CONTENT_TYPE_LENGTH;
488 : 111360 : }
489 : :
490 : : /* Rewrite the length to be the actual fragment length */
491 : 3608542 : const uint16_t actual_fragment_length = data_bytes_to_take + padding + extra;
492 : : /* ensure actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH <= max record length */
493 [ + + ]: 3608542 : const uint16_t max_record_length = is_tls13_record ? S2N_TLS13_MAXIMUM_RECORD_LENGTH : S2N_TLS_MAXIMUM_RECORD_LENGTH;
494 [ - + ][ # # ]: 3608542 : S2N_ERROR_IF(actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH > max_record_length, S2N_ERR_RECORD_LENGTH_TOO_LARGE);
495 [ - + ]: 3608542 : POSIX_GUARD(s2n_stuffer_write_uint16(&record_stuffer, actual_fragment_length));
496 : :
497 : : /* If we're AEAD, write the sequence number as an IV, and generate the AAD */
498 [ + + ]: 3608542 : if (cipher_suite->record_alg->cipher->type == S2N_AEAD) {
499 : 3347691 : struct s2n_stuffer iv_stuffer = { 0 };
500 [ - + ]: 3347691 : POSIX_GUARD(s2n_blob_init(&iv, aad_iv, sizeof(aad_iv)));
501 [ - + ]: 3347691 : POSIX_GUARD(s2n_stuffer_init(&iv_stuffer, &iv));
502 : :
503 [ + + ]: 3347691 : if (cipher_suite->record_alg->flags & S2N_TLS12_AES_GCM_AEAD_NONCE) {
504 : : /* Partially explicit nonce. See RFC 5288 Section 3 */
505 [ - + ]: 2178487 : POSIX_GUARD(s2n_stuffer_write_bytes(&record_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
506 [ - + ]: 2178487 : POSIX_GUARD(s2n_stuffer_write_bytes(&iv_stuffer, implicit_iv, cipher_suite->record_alg->cipher->io.aead.fixed_iv_size));
507 [ - + ]: 2178487 : POSIX_GUARD(s2n_stuffer_write_bytes(&iv_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
508 [ + + ][ + - ]: 2178487 : } else if (cipher_suite->record_alg->flags & S2N_TLS12_CHACHA_POLY_AEAD_NONCE || is_tls13_record) {
509 : : /* Fully implicit nonce. See RFC7905 Section 2 */
510 : 1169204 : uint8_t four_zeroes[4] = { 0 };
511 [ - + ]: 1169204 : POSIX_GUARD(s2n_stuffer_write_bytes(&iv_stuffer, four_zeroes, 4));
512 [ - + ]: 1169204 : POSIX_GUARD(s2n_stuffer_write_bytes(&iv_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
513 [ + + ]: 15199652 : for (int i = 0; i < cipher_suite->record_alg->cipher->io.aead.fixed_iv_size; i++) {
514 : 14030448 : aad_iv[i] = aad_iv[i] ^ implicit_iv[i];
515 : 14030448 : }
516 : 1169204 : } else {
517 [ # # ]: 0 : POSIX_BAIL(S2N_ERR_INVALID_NONCE_TYPE);
518 : 0 : }
519 : :
520 : : /* Set the IV size to the amount of data written */
521 : 3347691 : iv.size = s2n_stuffer_data_available(&iv_stuffer);
522 [ + + ]: 3347691 : if (is_tls13_record) {
523 : 111360 : struct s2n_record_header header = {
524 : 111360 : .content_type = TLS_APPLICATION_DATA,
525 : 111360 : .version = 0x0303,
526 : 111360 : .length = data_bytes_to_take + S2N_TLS_CONTENT_TYPE_LENGTH + cipher_suite->record_alg->cipher->io.aead.tag_size
527 : 111360 : };
528 [ - + ]: 111360 : POSIX_GUARD_RESULT(s2n_tls13_aead_aad_init(&header, &aad));
529 : 3236331 : } else {
530 [ - + ]: 3236331 : POSIX_GUARD_RESULT(s2n_aead_aad_init(conn, sequence_number, content_type, data_bytes_to_take, &aad));
531 : 3236331 : }
532 [ + + ][ + + ]: 3347691 : } else if (cipher_suite->record_alg->cipher->type == S2N_CBC || cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
533 [ - + ]: 205802 : POSIX_GUARD(s2n_blob_init(&iv, implicit_iv, block_size));
534 : :
535 : : /* For TLS1.1/1.2; write the IV with random data */
536 [ + + ]: 205802 : if (conn->actual_protocol_version > S2N_TLS10) {
537 [ - + ]: 164089 : POSIX_GUARD_RESULT(s2n_get_public_random_data(&iv));
538 [ + + ]: 164089 : if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
539 : : /* Write a separate random block to the record. This will be used along with the previously generated
540 : : * iv blob to generate the final explicit_iv for this record.
541 : : *
542 : : * How? Openssl's AES-CBC stitched encrypt populates the first block of application data with:
543 : : * AES(Key, XOR(iv, initial_block))
544 : : *
545 : : * If we make initial_block a random block unrelated to random_iv, explicit IV for this record
546 : : * is random value based on the two random blobs we just generated:
547 : : * AES(Key, XOR(random_iv, explicit_iv_placeholder) == AES(Key, XOR(random_iv, random_iv2))
548 : : *
549 : : * NOTE: We can't use the same random IV blob as both the initial block and IV since it will result in:
550 : : * AES(Key, XOR(random_iv, random_iv)) == AES(Key, 0), which will be shared by all records in this session.
551 : : */
552 : 131168 : struct s2n_blob explicit_iv_placeholder = { 0 };
553 : 131168 : uint8_t zero_block[S2N_TLS_MAX_IV_LEN] = { 0 };
554 [ - + ]: 131168 : POSIX_GUARD(s2n_blob_init(&explicit_iv_placeholder, zero_block, block_size));
555 [ - + ]: 131168 : POSIX_GUARD_RESULT(s2n_get_public_random_data(&explicit_iv_placeholder));
556 [ - + ]: 131168 : POSIX_GUARD(s2n_stuffer_write(&record_stuffer, &explicit_iv_placeholder));
557 : 131168 : } else {
558 : : /* We can write the explicit IV directly to the record for non composite CBC because
559 : : * s2n starts AES *after* the explicit IV.
560 : : */
561 [ - + ]: 32921 : POSIX_GUARD(s2n_stuffer_write(&record_stuffer, &iv));
562 : 32921 : }
563 : 164089 : }
564 : 205802 : }
565 : :
566 : : /* Write the plaintext data */
567 [ - + ]: 3608542 : POSIX_GUARD(s2n_stuffer_writev_bytes(&record_stuffer, in, in_count, offs, data_bytes_to_take));
568 : 3608542 : void *orig_write_ptr = record_stuffer.blob.data + record_stuffer.write_cursor - data_bytes_to_take;
569 : :
570 : : /* Write the MAC */
571 : 3608542 : struct s2n_blob header_blob = { 0 };
572 [ - + ]: 3608542 : POSIX_GUARD(s2n_blob_slice(&record_blob, &header_blob, 0, S2N_TLS_RECORD_HEADER_LENGTH));
573 : 3608542 : struct s2n_blob plaintext_blob = { 0 };
574 [ - + ]: 3608542 : POSIX_GUARD(s2n_blob_init(&plaintext_blob, orig_write_ptr, data_bytes_to_take));
575 : 3608542 : uint32_t mac_digest_size = 0;
576 [ - + ]: 3608542 : POSIX_GUARD_RESULT(s2n_record_write_mac(conn, &header_blob, &plaintext_blob, &record_stuffer, &mac_digest_size));
577 : :
578 : : /* We are done with this sequence number, so we can increment it */
579 : 3608542 : struct s2n_blob seq = { 0 };
580 [ - + ]: 3608542 : POSIX_GUARD(s2n_blob_init(&seq, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
581 [ + + ]: 3608542 : POSIX_GUARD(s2n_increment_sequence_number(&seq));
582 : :
583 : : /* Write content type for TLS 1.3 record (RFC 8446 Section 5.2) */
584 [ + + ]: 3608541 : if (is_tls13_record) {
585 [ - + ]: 111360 : POSIX_GUARD(s2n_stuffer_write_uint8(&record_stuffer, content_type));
586 : 111360 : }
587 : :
588 [ + + ]: 3608541 : if (cipher_suite->record_alg->cipher->type == S2N_CBC) {
589 : : /* Include padding bytes, each with the value 'p', and
590 : : * include an extra padding length byte, also with the value 'p'.
591 : : */
592 [ + + ]: 363189 : for (int i = 0; i <= padding; i++) {
593 [ - + ]: 321372 : POSIX_GUARD(s2n_stuffer_write_uint8(&record_stuffer, padding));
594 : 321372 : }
595 : 41817 : }
596 : :
597 : : /* Rewind to rewrite/encrypt the packet */
598 [ - + ]: 3608541 : POSIX_GUARD(s2n_stuffer_rewrite(&record_stuffer));
599 : :
600 : : /* Skip the header */
601 [ - + ]: 3608541 : POSIX_GUARD(s2n_stuffer_skip_write(&record_stuffer, S2N_TLS_RECORD_HEADER_LENGTH));
602 : :
603 : 3608541 : uint16_t encrypted_length = data_bytes_to_take + mac_digest_size;
604 : 3608541 : switch (cipher_suite->record_alg->cipher->type) {
605 [ + + ]: 3347691 : case S2N_AEAD:
606 [ - + ]: 3347691 : POSIX_GUARD(s2n_stuffer_skip_write(&record_stuffer, cipher_suite->record_alg->cipher->io.aead.record_iv_size));
607 : 3347691 : encrypted_length += cipher_suite->record_alg->cipher->io.aead.tag_size;
608 [ + + ]: 3347691 : if (is_tls13_record) {
609 : : /* one extra byte for content type */
610 : 111360 : encrypted_length += S2N_TLS_CONTENT_TYPE_LENGTH;
611 : 111360 : }
612 : 3347691 : break;
613 [ + + ]: 41817 : case S2N_CBC:
614 [ + + ]: 41817 : if (conn->actual_protocol_version > S2N_TLS10) {
615 : : /* Leave the IV alone and unencrypted */
616 [ - + ]: 32921 : POSIX_GUARD(s2n_stuffer_skip_write(&record_stuffer, iv.size));
617 : 32921 : }
618 : : /* Encrypt the padding and the padding length byte too */
619 : 41817 : encrypted_length += padding + 1;
620 : 41817 : break;
621 [ + + ]: 163985 : case S2N_COMPOSITE:
622 : : /* Composite CBC expects a pointer starting at explicit IV: [Explicit IV | fragment | MAC | padding | padding len ]
623 : : * extra will account for the explicit IV len(if applicable), MAC digest len, padding len + padding byte.
624 : : */
625 : 163985 : encrypted_length += extra;
626 : 163985 : break;
627 [ + + ]: 55048 : default:
628 : 55048 : break;
629 : 3608541 : }
630 : :
631 : : /* Check that stuffer have enough space to write encrypted record, because raw_write cannot expand tainted stuffer */
632 [ - + ][ # # ]: 3608541 : S2N_ERROR_IF(s2n_stuffer_space_remaining(&record_stuffer) < encrypted_length, S2N_ERR_RECORD_STUFFER_SIZE);
633 : :
634 : : /* Do the encryption */
635 : 3608541 : struct s2n_blob en = { .size = encrypted_length, .data = s2n_stuffer_raw_write(&record_stuffer, encrypted_length) };
636 [ - + ]: 3608541 : POSIX_GUARD(s2n_record_encrypt(conn, cipher_suite, session_key, &iv, &aad, &en, implicit_iv, block_size));
637 : :
638 : : /* Sync the out stuffer write cursor with the record stuffer. */
639 [ - + ]: 3608541 : POSIX_GUARD(s2n_stuffer_skip_write(&conn->out, s2n_stuffer_data_available(&record_stuffer)));
640 : :
641 [ + + ][ + + ]: 3608541 : if (conn->actual_protocol_version == S2N_TLS13 && content_type == TLS_CHANGE_CIPHER_SPEC) {
642 : 7859 : conn->client = current_client_crypto;
643 : 7859 : conn->server = current_server_crypto;
644 : 7859 : }
645 : :
646 : 3608541 : return data_bytes_to_take;
647 : 3608541 : }
648 : :
649 : : S2N_RESULT s2n_record_write(struct s2n_connection *conn, uint8_t content_type, struct s2n_blob *in)
650 : 3392058 : {
651 : 3392058 : struct iovec iov;
652 : 3392058 : iov.iov_base = in->data;
653 : 3392058 : iov.iov_len = in->size;
654 : 3392058 : int written = s2n_record_writev(conn, content_type, &iov, 1, 0, in->size);
655 [ + + ]: 3392058 : RESULT_GUARD_POSIX(written);
656 [ + - ][ + + ]: 3392055 : RESULT_ENSURE((uint32_t) written == in->size, S2N_ERR_FRAGMENT_LENGTH_TOO_LARGE);
657 : 3392035 : return S2N_RESULT_OK;
658 : 3392055 : }
|