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 #include <sys/param.h>
18 
19 #include "error/s2n_errno.h"
20 
21 #include "tls/s2n_cipher_suites.h"
22 #include "tls/s2n_connection.h"
23 #include "tls/s2n_record.h"
24 #include "tls/s2n_crypto.h"
25 
26 #include "stuffer/s2n_stuffer.h"
27 
28 #include "crypto/s2n_sequence.h"
29 #include "crypto/s2n_cipher.h"
30 #include "crypto/s2n_hmac.h"
31 
32 #include "utils/s2n_safety.h"
33 #include "utils/s2n_random.h"
34 #include "utils/s2n_blob.h"
35 
36 extern uint8_t s2n_unknown_protocol_version;
37 
38 /* How much overhead does the IV, MAC, TAG and padding bytes introduce ? */
s2n_tls_record_overhead(struct s2n_connection * conn,uint16_t * out)39 static S2N_RESULT s2n_tls_record_overhead(struct s2n_connection *conn, uint16_t *out)
40 {
41     RESULT_ENSURE_REF(conn);
42     RESULT_ENSURE_MUT(out);
43     struct s2n_crypto_parameters *active = conn->server;
44 
45     if (conn->mode == S2N_CLIENT) {
46         active = conn->client;
47     }
48 
49     uint8_t extra;
50     RESULT_GUARD_POSIX(s2n_hmac_digest_size(active->cipher_suite->record_alg->hmac_alg, &extra));
51 
52     if (active->cipher_suite->record_alg->cipher->type == S2N_CBC) {
53         /* Subtract one for the padding length byte */
54         extra += 1;
55 
56         if (conn->actual_protocol_version > S2N_TLS10) {
57             extra += active->cipher_suite->record_alg->cipher->io.cbc.record_iv_size;
58         }
59     } else if (active->cipher_suite->record_alg->cipher->type == S2N_AEAD) {
60         extra += active->cipher_suite->record_alg->cipher->io.aead.tag_size;
61         extra += active->cipher_suite->record_alg->cipher->io.aead.record_iv_size;
62     } else if (active->cipher_suite->record_alg->cipher->type == S2N_COMPOSITE && conn->actual_protocol_version > S2N_TLS10) {
63         extra += active->cipher_suite->record_alg->cipher->io.comp.record_iv_size;
64     }
65 
66     *out = extra;
67 
68     return S2N_RESULT_OK;
69 }
70 
71 /* This function returns maximum size of plaintext data to write for the payload.
72  * Record overheads are not included here.
73  */
s2n_record_max_write_payload_size(struct s2n_connection * conn,uint16_t * max_fragment_size)74 S2N_RESULT s2n_record_max_write_payload_size(struct s2n_connection *conn, uint16_t *max_fragment_size)
75 {
76     RESULT_ENSURE_REF(conn);
77     RESULT_ENSURE_MUT(max_fragment_size);
78     RESULT_ENSURE(conn->max_outgoing_fragment_length > 0, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
79 
80     *max_fragment_size = MIN(conn->max_outgoing_fragment_length, S2N_TLS_MAXIMUM_FRAGMENT_LENGTH);
81 
82     return S2N_RESULT_OK;
83 }
84 
s2n_record_max_write_size(struct s2n_connection * conn,uint16_t max_fragment_size,uint16_t * max_record_size)85 S2N_RESULT s2n_record_max_write_size(struct s2n_connection *conn, uint16_t max_fragment_size, uint16_t *max_record_size)
86 {
87     RESULT_ENSURE_REF(conn);
88     RESULT_ENSURE_MUT(max_record_size);
89 
90     if(!IS_NEGOTIATED(conn)) {
91         *max_record_size = S2N_TLS_MAX_RECORD_LEN_FOR(max_fragment_size);
92     } else if (conn->actual_protocol_version < S2N_TLS13) {
93         *max_record_size = S2N_TLS12_MAX_RECORD_LEN_FOR(max_fragment_size);
94     } else {
95         *max_record_size = S2N_TLS13_MAX_RECORD_LEN_FOR(max_fragment_size);
96     }
97     return S2N_RESULT_OK;
98 }
99 
100 /* Find the largest size that will fit within an ethernet frame for a "small" payload */
s2n_record_min_write_payload_size(struct s2n_connection * conn,uint16_t * payload_size)101 S2N_RESULT s2n_record_min_write_payload_size(struct s2n_connection *conn, uint16_t *payload_size)
102 {
103     RESULT_ENSURE_REF(conn);
104     RESULT_ENSURE_MUT(payload_size);
105 
106     /* remove ethernet, TCP/IP and TLS header overheads */
107     const uint16_t min_outgoing_fragment_length = ETH_MTU - (conn->ipv6 ? IP_V6_HEADER_LENGTH : IP_V4_HEADER_LENGTH)
108         - TCP_HEADER_LENGTH - TCP_OPTIONS_LENGTH - S2N_TLS_RECORD_HEADER_LENGTH;
109 
110     RESULT_ENSURE(min_outgoing_fragment_length <= S2N_TLS_MAXIMUM_FRAGMENT_LENGTH, S2N_ERR_FRAGMENT_LENGTH_TOO_LARGE);
111     uint16_t size = min_outgoing_fragment_length;
112 
113     const struct s2n_crypto_parameters *active = conn->mode == S2N_CLIENT ? conn->client : conn->server;
114 
115     /* Round the fragment size down to be block aligned */
116     if (active->cipher_suite->record_alg->cipher->type == S2N_CBC) {
117         size -= size % active->cipher_suite->record_alg->cipher->io.cbc.block_size;
118     } else if (active->cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
119         size -= size % active->cipher_suite->record_alg->cipher->io.comp.block_size;
120         /* Composite digest length */
121         size -= active->cipher_suite->record_alg->cipher->io.comp.mac_key_size;
122         /* Padding length byte */
123         size -= 1;
124     }
125 
126     /* If TLS1.3, remove content type */
127     if (conn->actual_protocol_version >= S2N_TLS13) {
128         RESULT_ENSURE(size > S2N_TLS_CONTENT_TYPE_LENGTH, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
129         size -= S2N_TLS_CONTENT_TYPE_LENGTH;
130     }
131 
132     /* subtract overheads of a TLS record */
133     uint16_t overhead = 0;
134     RESULT_GUARD(s2n_tls_record_overhead(conn, &overhead));
135     RESULT_ENSURE(size > overhead, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
136     size -= overhead;
137 
138     RESULT_ENSURE(size > 0, S2N_ERR_FRAGMENT_LENGTH_TOO_SMALL);
139     RESULT_ENSURE(size <= ETH_MTU, S2N_ERR_FRAGMENT_LENGTH_TOO_LARGE);
140 
141     *payload_size = size;
142 
143     return S2N_RESULT_OK;
144 }
145 
s2n_record_write_protocol_version(struct s2n_connection * conn)146 int s2n_record_write_protocol_version(struct s2n_connection *conn)
147 {
148     uint8_t record_protocol_version = conn->actual_protocol_version;
149     if (conn->server_protocol_version == s2n_unknown_protocol_version
150             && conn->early_data_state != S2N_EARLY_DATA_REQUESTED) {
151         /* Some legacy TLS implementations can't handle records with protocol version higher than TLS1.0.
152          * To provide maximum compatibility, send record version as TLS1.0 if server protocol version isn't
153          * established yet, which happens only during ClientHello message. Note, this has no effect on
154          * protocol version in ClientHello, so we're still able to negotiate protocol versions above TLS1.0 */
155         record_protocol_version = MIN(record_protocol_version, S2N_TLS10);
156     }
157 
158     /* In accordance to TLS 1.3 spec, https://tools.ietf.org/html/rfc8446#section-5.1
159      * tls record version should never be greater than 33 (legacy TLS 1.2 version).
160      */
161     record_protocol_version = MIN(record_protocol_version, S2N_TLS12);
162 
163     uint8_t protocol_version[S2N_TLS_PROTOCOL_VERSION_LEN];
164     protocol_version[0] = record_protocol_version / 10;
165     protocol_version[1] = record_protocol_version % 10;
166 
167     POSIX_GUARD(s2n_stuffer_write_bytes(&conn->out, protocol_version, S2N_TLS_PROTOCOL_VERSION_LEN));
168 
169     return 0;
170 }
171 
s2n_record_encrypt(struct s2n_connection * conn,const struct s2n_cipher_suite * cipher_suite,struct s2n_session_key * session_key,struct s2n_blob * iv,struct s2n_blob * aad,struct s2n_blob * en,uint8_t * implicit_iv,uint16_t block_size)172 static inline int s2n_record_encrypt(
173     struct s2n_connection *conn,
174     const struct s2n_cipher_suite *cipher_suite,
175     struct s2n_session_key *session_key,
176     struct s2n_blob *iv,
177     struct s2n_blob *aad,
178     struct s2n_blob *en,
179     uint8_t *implicit_iv, uint16_t block_size)
180 {
181     POSIX_ENSURE_REF(en->data);
182 
183     switch (cipher_suite->record_alg->cipher->type) {
184     case S2N_STREAM:
185         POSIX_GUARD(cipher_suite->record_alg->cipher->io.stream.encrypt(session_key, en, en));
186         break;
187     case S2N_CBC:
188         POSIX_GUARD(cipher_suite->record_alg->cipher->io.cbc.encrypt(session_key, iv, en, en));
189 
190         /* Copy the last encrypted block to be the next IV */
191         if (conn->actual_protocol_version < S2N_TLS11) {
192             POSIX_ENSURE_GTE(en->size, block_size);
193             POSIX_CHECKED_MEMCPY(implicit_iv, en->data + en->size - block_size, block_size);
194         }
195         break;
196     case S2N_AEAD:
197         POSIX_GUARD(cipher_suite->record_alg->cipher->io.aead.encrypt(session_key, iv, aad, en, en));
198         break;
199     case S2N_COMPOSITE:
200         /* This will: compute mac, append padding, append padding length, and encrypt */
201         POSIX_GUARD(cipher_suite->record_alg->cipher->io.comp.encrypt(session_key, iv, en, en));
202 
203         /* Copy the last encrypted block to be the next IV */
204         POSIX_ENSURE_GTE(en->size, block_size);
205         POSIX_CHECKED_MEMCPY(implicit_iv, en->data + en->size - block_size, block_size);
206         break;
207     default:
208         POSIX_BAIL(S2N_ERR_CIPHER_TYPE);
209         break;
210     }
211 
212     return 0;
213 }
214 
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)215 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)
216 {
217     struct s2n_blob iv = { 0 };
218     uint8_t padding = 0;
219     uint16_t block_size = 0;
220     uint8_t aad_iv[S2N_TLS_MAX_IV_LEN] = { 0 };
221 
222     /* In TLS 1.3, handle CCS message as unprotected records */
223     struct s2n_crypto_parameters *current_client_crypto = conn->client;
224     struct s2n_crypto_parameters *current_server_crypto = conn->server;
225     if (conn->actual_protocol_version == S2N_TLS13 && content_type == TLS_CHANGE_CIPHER_SPEC) {
226         conn->client = &conn->initial;
227         conn->server = &conn->initial;
228     }
229 
230     uint8_t *sequence_number = conn->server->server_sequence_number;
231     struct s2n_hmac_state *mac = &conn->server->server_record_mac;
232     struct s2n_session_key *session_key = &conn->server->server_key;
233     const struct s2n_cipher_suite *cipher_suite = conn->server->cipher_suite;
234     uint8_t *implicit_iv = conn->server->server_implicit_iv;
235 
236     if (conn->mode == S2N_CLIENT) {
237         sequence_number = conn->client->client_sequence_number;
238         mac = &conn->client->client_record_mac;
239         session_key = &conn->client->client_key;
240         cipher_suite = conn->client->cipher_suite;
241         implicit_iv = conn->client->client_implicit_iv;
242     }
243 
244     /* The NULL stream cipher MUST NEVER be used for ApplicationData.
245      * Writing ApplicationData unencrypted defeats the purpose of TLS. */
246     if (cipher_suite->record_alg->cipher == &s2n_null_cipher) {
247         POSIX_ENSURE(content_type != TLS_APPLICATION_DATA, S2N_ERR_ENCRYPT);
248     }
249 
250     const int is_tls13_record = cipher_suite->record_alg->flags & S2N_TLS13_RECORD_AEAD_NONCE;
251     s2n_stack_blob(aad, is_tls13_record ? S2N_TLS13_AAD_LEN : S2N_TLS_MAX_AAD_LEN, S2N_TLS_MAX_AAD_LEN);
252 
253     S2N_ERROR_IF(s2n_stuffer_data_available(&conn->out), S2N_ERR_RECORD_STUFFER_NEEDS_DRAINING);
254 
255     uint8_t mac_digest_size;
256     POSIX_GUARD(s2n_hmac_digest_size(mac->alg, &mac_digest_size));
257 
258     /* Before we do anything, we need to figure out what the length of the
259      * fragment is going to be.
260      */
261     uint16_t max_write_payload_size = 0;
262     POSIX_GUARD_RESULT(s2n_record_max_write_payload_size(conn, &max_write_payload_size));
263     const uint16_t data_bytes_to_take = MIN(to_write, max_write_payload_size);
264 
265     uint16_t extra = 0;
266     POSIX_GUARD_RESULT(s2n_tls_record_overhead(conn, &extra));
267 
268     /* If we have padding to worry about, figure that out too */
269     if (cipher_suite->record_alg->cipher->type == S2N_CBC) {
270         block_size = cipher_suite->record_alg->cipher->io.cbc.block_size;
271         if (((data_bytes_to_take + extra) % block_size)) {
272             padding = block_size - ((data_bytes_to_take + extra) % block_size);
273         }
274     } else if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
275         block_size = cipher_suite->record_alg->cipher->io.comp.block_size;
276     }
277 
278     /* Start the MAC with the sequence number */
279     POSIX_GUARD(s2n_hmac_update(mac, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
280 
281     if (s2n_stuffer_is_freed(&conn->out)) {
282         /* If the output buffer has not been allocated yet, allocate enough memory to hold
283          * a record with the local maximum fragment length. Because this only occurs if the
284          * output buffer has not been allocated, it does NOT resize existing buffers.
285          *
286          * The maximum fragment length is:
287          * 1) The local default configured for new connections
288          * 2) The local value set by the user via s2n_connection_prefer_throughput()
289          *    or s2n_connection_prefer_low_latency()
290          * 3) On the server, the minimum of the local value and the value negotiated with the
291          *    client via the max_fragment_length extension
292          */
293         uint16_t max_wire_record_size = 0;
294         POSIX_GUARD_RESULT(s2n_record_max_write_size(conn, max_write_payload_size, &max_wire_record_size));
295         POSIX_GUARD(s2n_stuffer_growable_alloc(&conn->out, max_wire_record_size));
296     }
297 
298     /* Now that we know the length, start writing the record */
299     POSIX_GUARD(s2n_stuffer_write_uint8(&conn->out, is_tls13_record ?
300         /* tls 1.3 opaque type */ TLS_APPLICATION_DATA :
301         /* actual content_type */ content_type ));
302     POSIX_GUARD(s2n_record_write_protocol_version(conn));
303 
304     /* First write a header that has the payload length, this is for the MAC */
305     POSIX_GUARD(s2n_stuffer_write_uint16(&conn->out, data_bytes_to_take));
306 
307     if (conn->actual_protocol_version > S2N_SSLv3) {
308         POSIX_GUARD(s2n_hmac_update(mac, conn->out.blob.data, S2N_TLS_RECORD_HEADER_LENGTH));
309     } else {
310         /* SSLv3 doesn't include the protocol version in the MAC */
311         POSIX_GUARD(s2n_hmac_update(mac, conn->out.blob.data, 1));
312         POSIX_GUARD(s2n_hmac_update(mac, conn->out.blob.data + 3, 2));
313     }
314 
315     /* Compute non-payload parts of the MAC(seq num, type, proto vers, fragment length) for composite ciphers.
316      * Composite "encrypt" will MAC the payload data and fill in padding.
317      */
318     if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
319         /* Only fragment length is needed for MAC, but the EVP ctrl function needs fragment length + eiv len. */
320         uint16_t payload_and_eiv_len = data_bytes_to_take;
321         if (conn->actual_protocol_version > S2N_TLS10) {
322             payload_and_eiv_len += block_size;
323         }
324 
325         /* Outputs number of extra bytes required for MAC and padding */
326         int pad_and_mac_len;
327         POSIX_GUARD(cipher_suite->record_alg->cipher->io.comp.initial_hmac(session_key, sequence_number, content_type, conn->actual_protocol_version,
328                                                                      payload_and_eiv_len, &pad_and_mac_len));
329         extra += pad_and_mac_len;
330     }
331 
332     /* TLS 1.3 protected record occupies one extra byte for content type */
333     if (is_tls13_record) {
334         extra += S2N_TLS_CONTENT_TYPE_LENGTH;
335     }
336 
337     /* Rewrite the length to be the actual fragment length */
338     const uint16_t actual_fragment_length = data_bytes_to_take + padding + extra;
339     /* ensure actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH <= max record length */
340     const uint16_t max_record_length = is_tls13_record ? S2N_TLS13_MAXIMUM_RECORD_LENGTH : S2N_TLS_MAXIMUM_RECORD_LENGTH;
341     S2N_ERROR_IF(actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH > max_record_length, S2N_ERR_RECORD_LENGTH_TOO_LARGE);
342     POSIX_GUARD(s2n_stuffer_wipe_n(&conn->out, 2));
343     POSIX_GUARD(s2n_stuffer_write_uint16(&conn->out, actual_fragment_length));
344 
345     /* If we're AEAD, write the sequence number as an IV, and generate the AAD */
346     if (cipher_suite->record_alg->cipher->type == S2N_AEAD) {
347         struct s2n_stuffer iv_stuffer = {0};
348         s2n_blob_init(&iv, aad_iv, sizeof(aad_iv));
349         POSIX_GUARD(s2n_stuffer_init(&iv_stuffer, &iv));
350 
351         if (cipher_suite->record_alg->flags & S2N_TLS12_AES_GCM_AEAD_NONCE) {
352             /* Partially explicit nonce. See RFC 5288 Section 3 */
353             POSIX_GUARD(s2n_stuffer_write_bytes(&conn->out, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
354             POSIX_GUARD(s2n_stuffer_write_bytes(&iv_stuffer, implicit_iv, cipher_suite->record_alg->cipher->io.aead.fixed_iv_size));
355             POSIX_GUARD(s2n_stuffer_write_bytes(&iv_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
356         } else if (cipher_suite->record_alg->flags & S2N_TLS12_CHACHA_POLY_AEAD_NONCE || is_tls13_record) {
357             /* Fully implicit nonce. See RFC7905 Section 2 */
358             uint8_t four_zeroes[4] = { 0 };
359             POSIX_GUARD(s2n_stuffer_write_bytes(&iv_stuffer, four_zeroes, 4));
360             POSIX_GUARD(s2n_stuffer_write_bytes(&iv_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
361             for(int i = 0; i < cipher_suite->record_alg->cipher->io.aead.fixed_iv_size; i++) {
362                 aad_iv[i] = aad_iv[i] ^ implicit_iv[i];
363             }
364         } else {
365             POSIX_BAIL(S2N_ERR_INVALID_NONCE_TYPE);
366         }
367 
368         /* Set the IV size to the amount of data written */
369         iv.size = s2n_stuffer_data_available(&iv_stuffer);
370         if (is_tls13_record) {
371             POSIX_GUARD_RESULT(s2n_tls13_aead_aad_init(data_bytes_to_take + S2N_TLS_CONTENT_TYPE_LENGTH, cipher_suite->record_alg->cipher->io.aead.tag_size, &aad));
372         } else {
373             POSIX_GUARD_RESULT(s2n_aead_aad_init(conn, sequence_number, content_type, data_bytes_to_take, &aad));
374         }
375     } else if (cipher_suite->record_alg->cipher->type == S2N_CBC || cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
376         s2n_blob_init(&iv, implicit_iv, block_size);
377 
378         /* For TLS1.1/1.2; write the IV with random data */
379         if (conn->actual_protocol_version > S2N_TLS10) {
380             POSIX_GUARD_RESULT(s2n_get_public_random_data(&iv));
381             if (cipher_suite->record_alg->cipher->type == S2N_COMPOSITE) {
382                 /* Write a separate random block to the record. This will be used along with the previously generated
383                  * iv blob to generate the final explicit_iv for this record.
384                  *
385                  * How? Openssl's AES-CBC stitched encrypt populates the first block of application data with:
386                  * AES(Key, XOR(iv, initial_block))
387                  *
388                  * If we make initial_block a random block unrelated to random_iv, explicit IV for this record
389                  * is random value based on the two random blobs we just generated:
390                  * AES(Key, XOR(random_iv, explicit_iv_placeholder) == AES(Key, XOR(random_iv, random_iv2))
391                  *
392                  * NOTE: We can't use the same random IV blob as both the initial block and IV since it will result in:
393                  * AES(Key, XOR(random_iv, random_iv)) == AES(Key, 0), which will be shared by all records in this session.
394                  */
395                 struct s2n_blob explicit_iv_placeholder;
396                 uint8_t zero_block[S2N_TLS_MAX_IV_LEN] = { 0 };
397                 POSIX_GUARD(s2n_blob_init(&explicit_iv_placeholder, zero_block, block_size));
398                 POSIX_GUARD_RESULT(s2n_get_public_random_data(&explicit_iv_placeholder));
399                 POSIX_GUARD(s2n_stuffer_write(&conn->out, &explicit_iv_placeholder));
400             } else {
401                 /* We can write the explicit IV directly to the record for non composite CBC because
402                  * s2n starts AES *after* the explicit IV.
403                  */
404                 POSIX_GUARD(s2n_stuffer_write(&conn->out, &iv));
405             }
406         }
407     }
408 
409     /* We are done with this sequence number, so we can increment it */
410     struct s2n_blob seq = {.data = sequence_number,.size = S2N_TLS_SEQUENCE_NUM_LEN };
411     POSIX_GUARD(s2n_increment_sequence_number(&seq));
412 
413     /* Write the plaintext data */
414     POSIX_GUARD(s2n_stuffer_writev_bytes(&conn->out, in, in_count, offs, data_bytes_to_take));
415     void *orig_write_ptr = conn->out.blob.data + conn->out.write_cursor - data_bytes_to_take;
416     POSIX_GUARD(s2n_hmac_update(mac, orig_write_ptr, data_bytes_to_take));
417 
418     /* Write the digest */
419     uint8_t *digest = s2n_stuffer_raw_write(&conn->out, mac_digest_size);
420     POSIX_ENSURE_REF(digest);
421 
422     POSIX_GUARD(s2n_hmac_digest(mac, digest, mac_digest_size));
423     POSIX_GUARD(s2n_hmac_reset(mac));
424 
425     /* Write content type for TLS 1.3 record (RFC 8446 Section 5.2) */
426     if (is_tls13_record) {
427         POSIX_GUARD(s2n_stuffer_write_uint8(&conn->out, content_type));
428     }
429 
430     if (cipher_suite->record_alg->cipher->type == S2N_CBC) {
431         /* Include padding bytes, each with the value 'p', and
432          * include an extra padding length byte, also with the value 'p'.
433          */
434         for (int i = 0; i <= padding; i++) {
435             POSIX_GUARD(s2n_stuffer_write_uint8(&conn->out, padding));
436         }
437     }
438 
439     /* Rewind to rewrite/encrypt the packet */
440     POSIX_GUARD(s2n_stuffer_rewrite(&conn->out));
441 
442     /* Skip the header */
443     POSIX_GUARD(s2n_stuffer_skip_write(&conn->out, S2N_TLS_RECORD_HEADER_LENGTH));
444 
445     uint16_t encrypted_length = data_bytes_to_take + mac_digest_size;
446     switch (cipher_suite->record_alg->cipher->type) {
447     case S2N_AEAD:
448         POSIX_GUARD(s2n_stuffer_skip_write(&conn->out, cipher_suite->record_alg->cipher->io.aead.record_iv_size));
449         encrypted_length += cipher_suite->record_alg->cipher->io.aead.tag_size;
450         if (is_tls13_record) {
451             /* one extra byte for content type */
452             encrypted_length += S2N_TLS_CONTENT_TYPE_LENGTH;
453         }
454         break;
455     case S2N_CBC:
456         if (conn->actual_protocol_version > S2N_TLS10) {
457             /* Leave the IV alone and unencrypted */
458             POSIX_GUARD(s2n_stuffer_skip_write(&conn->out, iv.size));
459         }
460         /* Encrypt the padding and the padding length byte too */
461         encrypted_length += padding + 1;
462         break;
463     case S2N_COMPOSITE:
464         /* Composite CBC expects a pointer starting at explicit IV: [Explicit IV | fragment | MAC | padding | padding len ]
465         * extra will account for the explicit IV len(if applicable), MAC digest len, padding len + padding byte.
466         */
467         encrypted_length += extra;
468         break;
469     default:
470         break;
471     }
472 
473     /* Check that stuffer have enough space to write encrypted record, because raw_write cannot expand tainted stuffer */
474     S2N_ERROR_IF(s2n_stuffer_space_remaining(&conn->out) < encrypted_length, S2N_ERR_RECORD_STUFFER_SIZE);
475 
476     /* Do the encryption */
477     struct s2n_blob en = { .size = encrypted_length, .data = s2n_stuffer_raw_write(&conn->out, encrypted_length) };
478     POSIX_GUARD(s2n_record_encrypt(conn, cipher_suite, session_key, &iv, &aad, &en, implicit_iv, block_size));
479 
480     if (conn->actual_protocol_version == S2N_TLS13 && content_type == TLS_CHANGE_CIPHER_SPEC) {
481         conn->client = current_client_crypto;
482         conn->server = current_server_crypto;
483     }
484 
485     conn->wire_bytes_out += actual_fragment_length + S2N_TLS_RECORD_HEADER_LENGTH;
486 
487     return data_bytes_to_take;
488 }
489 
s2n_record_write(struct s2n_connection * conn,uint8_t content_type,struct s2n_blob * in)490 int s2n_record_write(struct s2n_connection *conn, uint8_t content_type, struct s2n_blob *in)
491 {
492     struct iovec iov;
493     iov.iov_base = in->data;
494     iov.iov_len = in->size;
495     return s2n_record_writev(conn, content_type, &iov, 1, 0, in->size);
496 }
497