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 <openssl/aes.h>
17 : : #include <openssl/evp.h>
18 : :
19 : : #include "crypto/s2n_cipher.h"
20 : : #include "crypto/s2n_ktls_crypto.h"
21 : : #include "tls/s2n_crypto.h"
22 : : #include "utils/s2n_blob.h"
23 : : #include "utils/s2n_safety.h"
24 : :
25 : : static bool s2n_aead_cipher_aes128_gcm_available(void)
26 : 2725 : {
27 : : #if defined(S2N_LIBCRYPTO_SUPPORTS_EVP_AEAD_TLS)
28 : : return (EVP_aead_aes_128_gcm() ? true : false);
29 : : #else
30 [ + - ]: 2725 : return (EVP_aes_128_gcm() ? true : false);
31 : 2725 : #endif
32 : 2725 : }
33 : :
34 : : static bool s2n_aead_cipher_aes256_gcm_available(void)
35 : 2725 : {
36 : : #if defined(S2N_LIBCRYPTO_SUPPORTS_EVP_AEAD_TLS)
37 : : return (EVP_aead_aes_256_gcm() ? true : false);
38 : : #else
39 [ + - ]: 2725 : return (EVP_aes_256_gcm() ? true : false);
40 : 2725 : #endif
41 : 2725 : }
42 : :
43 : : #if defined(S2N_LIBCRYPTO_SUPPORTS_EVP_AEAD_TLS) /* BoringSSL and AWS-LC AEAD API implementation */
44 : :
45 : : static int s2n_aead_cipher_aes_gcm_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
46 : : {
47 : : POSIX_ENSURE_REF(in);
48 : : POSIX_ENSURE_REF(out);
49 : : POSIX_ENSURE_REF(iv);
50 : : POSIX_ENSURE_REF(key);
51 : : POSIX_ENSURE_REF(aad);
52 : :
53 : : /* The size of the |in| blob includes the size of the data and the size of the AES-GCM tag */
54 : : POSIX_ENSURE_GTE(in->size, S2N_TLS_GCM_TAG_LEN);
55 : : POSIX_ENSURE_GTE(out->size, in->size);
56 : : POSIX_ENSURE_EQ(iv->size, S2N_TLS_GCM_IV_LEN);
57 : :
58 : : /* Adjust input length to account for the Tag length */
59 : : size_t in_len = in->size - S2N_TLS_GCM_TAG_LEN;
60 : : /* out_len is set by EVP_AEAD_CTX_seal and checked post operation */
61 : : size_t out_len = 0;
62 : :
63 : : POSIX_GUARD_OSSL(EVP_AEAD_CTX_seal(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
64 : :
65 : : S2N_ERROR_IF((in_len + S2N_TLS_GCM_TAG_LEN) != out_len, S2N_ERR_ENCRYPT);
66 : :
67 : : return S2N_SUCCESS;
68 : : }
69 : :
70 : : static int s2n_aead_cipher_aes_gcm_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
71 : : {
72 : : POSIX_ENSURE_REF(in);
73 : : POSIX_ENSURE_REF(out);
74 : : POSIX_ENSURE_REF(iv);
75 : : POSIX_ENSURE_REF(key);
76 : : POSIX_ENSURE_REF(aad);
77 : :
78 : : POSIX_ENSURE_GTE(in->size, S2N_TLS_GCM_TAG_LEN);
79 : : POSIX_ENSURE_GTE(out->size, in->size - S2N_TLS_GCM_TAG_LEN);
80 : : POSIX_ENSURE_EQ(iv->size, S2N_TLS_GCM_IV_LEN);
81 : :
82 : : /* out_len is set by EVP_AEAD_CTX_open and checked post operation */
83 : : size_t out_len = 0;
84 : :
85 : : POSIX_GUARD_OSSL(EVP_AEAD_CTX_open(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in->size, aad->data, aad->size), S2N_ERR_DECRYPT);
86 : :
87 : : S2N_ERROR_IF((in->size - S2N_TLS_GCM_TAG_LEN) != out_len, S2N_ERR_ENCRYPT);
88 : :
89 : : return S2N_SUCCESS;
90 : : }
91 : :
92 : : static S2N_RESULT s2n_aead_cipher_aes128_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
93 : : {
94 : : RESULT_ENSURE_REF(key);
95 : : RESULT_ENSURE_REF(in);
96 : :
97 : : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
98 : :
99 : : RESULT_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm_tls12(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
100 : :
101 : : return S2N_RESULT_OK;
102 : : }
103 : :
104 : : static S2N_RESULT s2n_aead_cipher_aes256_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
105 : : {
106 : : RESULT_ENSURE_REF(key);
107 : : RESULT_ENSURE_REF(in);
108 : :
109 : : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
110 : :
111 : : RESULT_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm_tls12(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
112 : :
113 : : return S2N_RESULT_OK;
114 : : }
115 : :
116 : : static S2N_RESULT s2n_aead_cipher_aes128_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
117 : : {
118 : : RESULT_ENSURE_REF(key);
119 : : RESULT_ENSURE_REF(in);
120 : :
121 : : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
122 : :
123 : : RESULT_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm_tls12(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
124 : :
125 : : return S2N_RESULT_OK;
126 : : }
127 : :
128 : : static S2N_RESULT s2n_aead_cipher_aes256_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
129 : : {
130 : : RESULT_ENSURE_REF(key);
131 : : RESULT_ENSURE_REF(in);
132 : :
133 : : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
134 : :
135 : : RESULT_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm_tls12(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
136 : :
137 : : return S2N_RESULT_OK;
138 : : }
139 : :
140 : : static S2N_RESULT s2n_aead_cipher_aes128_gcm_set_encryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in)
141 : : {
142 : : RESULT_ENSURE_REF(key);
143 : : RESULT_ENSURE_REF(in);
144 : :
145 : : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
146 : :
147 : : RESULT_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm_tls13(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
148 : :
149 : : return S2N_RESULT_OK;
150 : : }
151 : :
152 : : static S2N_RESULT s2n_aead_cipher_aes256_gcm_set_encryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in)
153 : : {
154 : : RESULT_ENSURE_REF(key);
155 : : RESULT_ENSURE_REF(in);
156 : :
157 : : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
158 : :
159 : : RESULT_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm_tls13(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
160 : :
161 : : return S2N_RESULT_OK;
162 : : }
163 : :
164 : : static S2N_RESULT s2n_aead_cipher_aes128_gcm_set_decryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in)
165 : : {
166 : : RESULT_ENSURE_REF(key);
167 : : RESULT_ENSURE_REF(in);
168 : :
169 : : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
170 : :
171 : : RESULT_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm_tls13(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
172 : :
173 : : return S2N_RESULT_OK;
174 : : }
175 : :
176 : : static S2N_RESULT s2n_aead_cipher_aes256_gcm_set_decryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in)
177 : : {
178 : : RESULT_ENSURE_REF(key);
179 : : RESULT_ENSURE_REF(in);
180 : :
181 : : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
182 : :
183 : : RESULT_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm_tls13(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
184 : :
185 : : return S2N_RESULT_OK;
186 : : }
187 : :
188 : : static S2N_RESULT s2n_aead_cipher_aes_gcm_init(struct s2n_session_key *key)
189 : : {
190 : : RESULT_ENSURE_REF(key);
191 : :
192 : : EVP_AEAD_CTX_zero(key->evp_aead_ctx);
193 : :
194 : : return S2N_RESULT_OK;
195 : : }
196 : :
197 : : static S2N_RESULT s2n_aead_cipher_aes_gcm_destroy_key(struct s2n_session_key *key)
198 : : {
199 : : RESULT_ENSURE_REF(key);
200 : :
201 : : EVP_AEAD_CTX_cleanup(key->evp_aead_ctx);
202 : :
203 : : return S2N_RESULT_OK;
204 : : }
205 : :
206 : : #else /* Standard AES-GCM implementation */
207 : :
208 : : static int s2n_aead_cipher_aes_gcm_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
209 : 2287053 : {
210 : : /* The size of the |in| blob includes the size of the data and the size of the AES-GCM tag */
211 [ - + ][ # # ]: 2287053 : POSIX_ENSURE_GTE(in->size, S2N_TLS_GCM_TAG_LEN);
212 [ - + ][ # # ]: 2287053 : POSIX_ENSURE_GTE(out->size, in->size);
213 [ - + ][ # # ]: 2287053 : POSIX_ENSURE_EQ(iv->size, S2N_TLS_GCM_IV_LEN);
214 : :
215 : : /* Initialize the IV */
216 [ - + ][ # # ]: 2287053 : POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
217 : :
218 : : /* Adjust input length and buffer pointer to account for the Tag length */
219 : 2287053 : int in_len = in->size - S2N_TLS_GCM_TAG_LEN;
220 : 2287053 : uint8_t *tag_data = out->data + out->size - S2N_TLS_GCM_TAG_LEN;
221 : :
222 : : /* out_len is set by EVP_EncryptUpdate and checked post operation */
223 : 2287053 : int out_len = 0;
224 : : /* Specify the AAD */
225 [ - + ][ # # ]: 2287053 : POSIX_GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
226 : :
227 : : /* Encrypt the data */
228 [ - + ][ # # ]: 2287053 : POSIX_GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &out_len, in->data, in_len), S2N_ERR_ENCRYPT);
229 : :
230 : : /* When using AES-GCM, *out_len is the number of bytes written by EVP_EncryptUpdate. Since the tag is not written during this call, we do not take S2N_TLS_GCM_TAG_LEN into account */
231 [ - + ][ # # ]: 2287053 : S2N_ERROR_IF(in_len != out_len, S2N_ERR_ENCRYPT);
232 : :
233 : : /* Finalize */
234 [ - + ][ # # ]: 2287053 : POSIX_GUARD_OSSL(EVP_EncryptFinal_ex(key->evp_cipher_ctx, out->data, &out_len), S2N_ERR_ENCRYPT);
235 : :
236 : : /* write the tag */
237 [ - + ][ # # ]: 2287053 : POSIX_GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_GET_TAG, S2N_TLS_GCM_TAG_LEN, tag_data), S2N_ERR_ENCRYPT);
238 : :
239 : : /* When using AES-GCM, EVP_EncryptFinal_ex does not write any bytes. So, we should expect *out_len = 0. */
240 [ - + ][ # # ]: 2287053 : S2N_ERROR_IF(0 != out_len, S2N_ERR_ENCRYPT);
241 : :
242 : 2287053 : return S2N_SUCCESS;
243 : 2287053 : }
244 : :
245 : : static int s2n_aead_cipher_aes_gcm_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
246 : 2338681 : {
247 [ - + ][ # # ]: 2338681 : POSIX_ENSURE_GTE(in->size, S2N_TLS_GCM_TAG_LEN);
248 [ # # ][ - + ]: 2338681 : POSIX_ENSURE_GTE(out->size, in->size);
249 [ # # ][ - + ]: 2338681 : POSIX_ENSURE_EQ(iv->size, S2N_TLS_GCM_IV_LEN);
250 : :
251 : : /* Initialize the IV */
252 [ - + ][ # # ]: 2338681 : POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
253 : :
254 : : /* Adjust input length and buffer pointer to account for the Tag length */
255 : 2338681 : int in_len = in->size - S2N_TLS_GCM_TAG_LEN;
256 : 2338681 : uint8_t *tag_data = in->data + in->size - S2N_TLS_GCM_TAG_LEN;
257 : :
258 : : /* Set the TAG */
259 [ - + ][ # # ]: 2338681 : POSIX_GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_TAG, S2N_TLS_GCM_TAG_LEN, tag_data), S2N_ERR_DECRYPT);
260 : :
261 : : /* out_len is set by EVP_DecryptUpdate. While we verify the content of out_len in
262 : : * s2n_aead_chacha20_poly1305_encrypt, we refrain from this here. This is to avoid
263 : : * doing any branching before the ciphertext is verified. */
264 : 2338681 : int out_len = 0;
265 : : /* Specify the AAD */
266 [ # # ][ - + ]: 2338681 : POSIX_GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_DECRYPT);
267 : :
268 : 2338681 : int evp_decrypt_rc = 1;
269 : : /* Decrypt the data, but don't short circuit tag verification. EVP_Decrypt* return 0 on failure, 1 for success. */
270 : 2338681 : evp_decrypt_rc &= EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &out_len, in->data, in_len);
271 : :
272 : : /* Verify the tag */
273 : 2338681 : evp_decrypt_rc &= EVP_DecryptFinal_ex(key->evp_cipher_ctx, out->data, &out_len);
274 : :
275 [ + + ][ + - ]: 2338681 : S2N_ERROR_IF(evp_decrypt_rc != 1, S2N_ERR_DECRYPT);
276 : :
277 : 202329 : return S2N_SUCCESS;
278 : 2338681 : }
279 : :
280 : : static S2N_RESULT s2n_aead_cipher_aes128_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
281 : 1086562 : {
282 [ - + ][ # # ]: 1086562 : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
283 : :
284 [ # # ][ - + ]: 1086562 : RESULT_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
285 : :
286 : 1086562 : EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
287 : :
288 [ # # ][ - + ]: 1086562 : RESULT_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
289 : :
290 : 1086562 : return S2N_RESULT_OK;
291 : 1086562 : }
292 : :
293 : : static S2N_RESULT s2n_aead_cipher_aes256_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
294 : 1070567 : {
295 [ - + ][ # # ]: 1070567 : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
296 : :
297 [ - + ][ # # ]: 1070567 : RESULT_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
298 : :
299 : 1070567 : EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
300 : :
301 [ - + ][ # # ]: 1070567 : RESULT_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
302 : :
303 : 1070567 : return S2N_RESULT_OK;
304 : 1070567 : }
305 : :
306 : : static S2N_RESULT s2n_aead_cipher_aes128_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
307 : 1086036 : {
308 [ # # ][ - + ]: 1086036 : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
309 : :
310 [ - + ][ # # ]: 1086036 : RESULT_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
311 : :
312 : 1086036 : EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
313 : :
314 [ - + ][ # # ]: 1086036 : RESULT_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
315 : :
316 : 1086036 : return S2N_RESULT_OK;
317 : 1086036 : }
318 : :
319 : : static S2N_RESULT s2n_aead_cipher_aes256_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
320 : 1069861 : {
321 [ # # ][ - + ]: 1069861 : RESULT_ENSURE_EQ(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
322 : :
323 [ - + ][ # # ]: 1069861 : RESULT_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
324 : :
325 : 1069861 : EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
326 : :
327 [ # # ][ - + ]: 1069861 : RESULT_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
328 : :
329 : 1069861 : return S2N_RESULT_OK;
330 : 1069861 : }
331 : :
332 : : static S2N_RESULT s2n_aead_cipher_aes128_gcm_set_encryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in)
333 : 14361 : {
334 [ - + ]: 14361 : RESULT_GUARD(s2n_aead_cipher_aes128_gcm_set_encryption_key(key, in));
335 : :
336 : 14361 : return S2N_RESULT_OK;
337 : 14361 : }
338 : :
339 : : static S2N_RESULT s2n_aead_cipher_aes256_gcm_set_encryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in)
340 : 843 : {
341 [ - + ]: 843 : RESULT_GUARD(s2n_aead_cipher_aes256_gcm_set_encryption_key(key, in));
342 : :
343 : 843 : return S2N_RESULT_OK;
344 : 843 : }
345 : :
346 : : static S2N_RESULT s2n_aead_cipher_aes128_gcm_set_decryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in)
347 : 13835 : {
348 [ - + ]: 13835 : RESULT_GUARD(s2n_aead_cipher_aes128_gcm_set_decryption_key(key, in));
349 : :
350 : 13835 : return S2N_RESULT_OK;
351 : 13835 : }
352 : :
353 : : static S2N_RESULT s2n_aead_cipher_aes256_gcm_set_decryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in)
354 : 442 : {
355 [ - + ]: 442 : RESULT_GUARD(s2n_aead_cipher_aes256_gcm_set_decryption_key(key, in));
356 : :
357 : 442 : return S2N_RESULT_OK;
358 : 442 : }
359 : :
360 : : static S2N_RESULT s2n_aead_cipher_aes_gcm_init(struct s2n_session_key *key)
361 : 4283937 : {
362 [ # # ][ - + ]: 4283937 : RESULT_EVP_CTX_INIT(key->evp_cipher_ctx);
363 : :
364 : 4283937 : return S2N_RESULT_OK;
365 : 4283937 : }
366 : :
367 : : static S2N_RESULT s2n_aead_cipher_aes_gcm_destroy_key(struct s2n_session_key *key)
368 : 12833062 : {
369 : 12833062 : EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
370 : :
371 : 12833062 : return S2N_RESULT_OK;
372 : 12833062 : }
373 : :
374 : : #endif
375 : :
376 : : static S2N_RESULT s2n_tls12_aead_cipher_aes128_gcm_set_ktls_info(
377 : : struct s2n_ktls_crypto_info_inputs *in, struct s2n_ktls_crypto_info *out)
378 : 18 : {
379 [ - + ][ # # ]: 18 : RESULT_ENSURE_REF(in);
380 [ # # ][ - + ]: 18 : RESULT_ENSURE_REF(out);
381 : :
382 : 18 : s2n_ktls_crypto_info_tls12_aes_gcm_128 *crypto_info = &out->ciphers.aes_gcm_128;
383 : 18 : crypto_info->info.version = TLS_1_2_VERSION;
384 : 18 : crypto_info->info.cipher_type = TLS_CIPHER_AES_GCM_128;
385 : :
386 [ - + ][ # # ]: 18 : RESULT_ENSURE_LTE(sizeof(crypto_info->key), in->key.size);
387 [ # # ][ - + ]: 18 : RESULT_CHECKED_MEMCPY(crypto_info->key, in->key.data, sizeof(crypto_info->key));
[ + - ]
388 [ - + ][ # # ]: 18 : RESULT_ENSURE_LTE(sizeof(crypto_info->rec_seq), in->seq.size);
389 [ - + ][ # # ]: 18 : RESULT_CHECKED_MEMCPY(crypto_info->rec_seq, in->seq.data, sizeof(crypto_info->rec_seq));
[ + - ]
390 : :
391 : : /* TLS1.2 uses partially explicit nonces. That means that although part of the
392 : : * nonce is still fixed and implicit (the salt), the remainder is explicit
393 : : * (written into the record) and must be unique per record. The RFC5288 suggests
394 : : * using the sequence number as the explicit part.
395 : : *
396 : : * Therefore, ktls expects the salt to contain the iv derived from the secret
397 : : * and should generate the remainder of the nonce per-record.
398 : : *
399 : : * See the TLS1.2 RFC:
400 : : * - https://datatracker.ietf.org/doc/html/rfc5246#section-6.2.3.3
401 : : * And RFC5288, which defines the TLS1.2 AES-GCM cipher suites:
402 : : * - https://datatracker.ietf.org/doc/html/rfc5288#section-3
403 : : */
404 [ - + ][ # # ]: 18 : RESULT_ENSURE_LTE(sizeof(crypto_info->salt), in->iv.size);
405 [ - + ][ # # ]: 18 : RESULT_CHECKED_MEMCPY(crypto_info->salt, in->iv.data, sizeof(crypto_info->salt));
[ + - ]
406 : :
407 : : /* Because TLS1.2 uses partially explicit nonces, the kernel should not
408 : : * use the iv in crypto_info but instead use a unique value for each record.
409 : : *
410 : : * As of this commit, Openssl has chosen to set the TLS1.2 IV to random
411 : : * bytes when sending and all zeroes when receiving:
412 : : * https://github.com/openssl/openssl/blob/de8e0851a1c0d22533801f081781a9f0be56c2c2/ssl/record/methods/ktls_meth.c#L197-L204
413 : : * And GnuTLS has chosen to set the TLS1.2 IV to the sequence number:
414 : : * https://github.com/gnutls/gnutls/blob/3f42ae70a1672673cb8f27c2dd3da1a34d1cbdd7/lib/system/ktls.c#L547-L550
415 : : *
416 : : * We (fairly arbitrarily) choose to also set it to the current sequence number.
417 : : */
418 [ # # ][ - + ]: 18 : RESULT_ENSURE_LTE(sizeof(crypto_info->iv), in->seq.size);
419 [ # # ][ - + ]: 18 : RESULT_CHECKED_MEMCPY(crypto_info->iv, in->seq.data, sizeof(crypto_info->iv));
[ + - ]
420 : :
421 [ - + ]: 18 : RESULT_GUARD_POSIX(s2n_blob_init(&out->value, (uint8_t *) (void *) crypto_info,
422 : 18 : sizeof(s2n_ktls_crypto_info_tls12_aes_gcm_128)));
423 : 18 : return S2N_RESULT_OK;
424 : 18 : }
425 : :
426 : : /* TLS1.2 AES256 is configured like TLS1.2 AES128, but with a larger key size.
427 : : * See TLS1.2 AES128 for details (particularly a discussion of salt + iv).
428 : : */
429 : : static S2N_RESULT s2n_tls12_aead_cipher_aes256_gcm_set_ktls_info(
430 : : struct s2n_ktls_crypto_info_inputs *in, struct s2n_ktls_crypto_info *out)
431 : 1 : {
432 [ # # ][ - + ]: 1 : RESULT_ENSURE_REF(in);
433 [ # # ][ - + ]: 1 : RESULT_ENSURE_REF(out);
434 : :
435 : 1 : s2n_ktls_crypto_info_tls12_aes_gcm_256 *crypto_info = &out->ciphers.aes_gcm_256;
436 : 1 : crypto_info->info.version = TLS_1_2_VERSION;
437 : 1 : crypto_info->info.cipher_type = TLS_CIPHER_AES_GCM_256;
438 : :
439 [ # # ][ - + ]: 1 : RESULT_ENSURE_LTE(sizeof(crypto_info->key), in->key.size);
440 [ # # ][ - + ]: 1 : RESULT_CHECKED_MEMCPY(crypto_info->key, in->key.data, sizeof(crypto_info->key));
[ + - ]
441 [ # # ][ - + ]: 1 : RESULT_ENSURE_LTE(sizeof(crypto_info->rec_seq), in->seq.size);
442 [ # # ][ - + ]: 1 : RESULT_CHECKED_MEMCPY(crypto_info->rec_seq, in->seq.data, sizeof(crypto_info->rec_seq));
[ + - ]
443 [ # # ][ - + ]: 1 : RESULT_ENSURE_LTE(sizeof(crypto_info->salt), in->iv.size);
444 [ - + ][ # # ]: 1 : RESULT_CHECKED_MEMCPY(crypto_info->salt, in->iv.data, sizeof(crypto_info->salt));
[ + - ]
445 [ # # ][ - + ]: 1 : RESULT_ENSURE_LTE(sizeof(crypto_info->iv), in->seq.size);
446 [ # # ][ - + ]: 1 : RESULT_CHECKED_MEMCPY(crypto_info->iv, in->seq.data, sizeof(crypto_info->iv));
[ + - ]
447 : :
448 [ - + ]: 1 : RESULT_GUARD_POSIX(s2n_blob_init(&out->value, (uint8_t *) (void *) crypto_info,
449 : 1 : sizeof(s2n_ktls_crypto_info_tls12_aes_gcm_256)));
450 : 1 : return S2N_RESULT_OK;
451 : 1 : }
452 : :
453 : : static S2N_RESULT s2n_tls13_aead_cipher_aes128_gcm_set_ktls_info(
454 : : struct s2n_ktls_crypto_info_inputs *in, struct s2n_ktls_crypto_info *out)
455 : 1 : {
456 [ # # ][ - + ]: 1 : RESULT_ENSURE_REF(in);
457 [ # # ][ - + ]: 1 : RESULT_ENSURE_REF(out);
458 : :
459 : 1 : s2n_ktls_crypto_info_tls12_aes_gcm_128 *crypto_info = &out->ciphers.aes_gcm_128;
460 : 1 : crypto_info->info.version = TLS_1_3_VERSION;
461 : 1 : crypto_info->info.cipher_type = TLS_CIPHER_AES_GCM_128;
462 : :
463 [ - + ][ # # ]: 1 : RESULT_ENSURE_LTE(sizeof(crypto_info->key), in->key.size);
464 [ - + ][ # # ]: 1 : RESULT_CHECKED_MEMCPY(crypto_info->key, in->key.data, sizeof(crypto_info->key));
[ + - ]
465 [ # # ][ - + ]: 1 : RESULT_ENSURE_LTE(sizeof(crypto_info->rec_seq), in->seq.size);
466 [ # # ][ - + ]: 1 : RESULT_CHECKED_MEMCPY(crypto_info->rec_seq, in->seq.data, sizeof(crypto_info->rec_seq));
[ + - ]
467 : :
468 : : /* TLS1.3 uses fully implicit nonces. The fixed, implicit IV value derived from
469 : : * the secret is xored with the sequence number to produce a unique per-record nonce.
470 : : *
471 : : * See the TLS1.3 RFC:
472 : : * - https://www.rfc-editor.org/rfc/rfc8446.html#section-5.3
473 : : *
474 : : * ktls handles this with the same structure as TLS1.2 uses for its partially
475 : : * explicit nonces by splitting the implicit IV between the salt and iv fields.
476 : : */
477 : 1 : size_t salt_size = sizeof(crypto_info->salt);
478 [ - + ][ # # ]: 1 : RESULT_ENSURE_LTE(salt_size, in->iv.size);
479 [ - + ][ # # ]: 1 : RESULT_CHECKED_MEMCPY(crypto_info->salt, in->iv.data, salt_size);
[ + - ]
480 : 1 : size_t iv_remainder = in->iv.size - salt_size;
481 [ # # ][ - + ]: 1 : RESULT_ENSURE_LTE(sizeof(crypto_info->iv), iv_remainder);
482 [ - + ][ # # ]: 1 : RESULT_CHECKED_MEMCPY(crypto_info->iv, in->iv.data + salt_size, sizeof(crypto_info->iv));
[ + - ]
483 : :
484 [ - + ]: 1 : RESULT_GUARD_POSIX(s2n_blob_init(&out->value, (uint8_t *) (void *) crypto_info,
485 : 1 : sizeof(s2n_ktls_crypto_info_tls12_aes_gcm_128)));
486 : 1 : return S2N_RESULT_OK;
487 : 1 : }
488 : :
489 : : /* TLS1.3 AES256 is configured like TLS1.3 AES128, but with a larger key size.
490 : : * See TLS1.3 AES128 for details (particularly a discussion of salt + iv).
491 : : */
492 : : static S2N_RESULT s2n_tls13_aead_cipher_aes256_gcm_set_ktls_info(
493 : : struct s2n_ktls_crypto_info_inputs *in, struct s2n_ktls_crypto_info *out)
494 : 0 : {
495 [ # # ][ # # ]: 0 : RESULT_ENSURE_REF(in);
496 [ # # ][ # # ]: 0 : RESULT_ENSURE_REF(out);
497 : :
498 : 0 : s2n_ktls_crypto_info_tls12_aes_gcm_256 *crypto_info = &out->ciphers.aes_gcm_256;
499 : 0 : crypto_info->info.version = TLS_1_3_VERSION;
500 : 0 : crypto_info->info.cipher_type = TLS_CIPHER_AES_GCM_256;
501 : :
502 [ # # ][ # # ]: 0 : RESULT_ENSURE_LTE(sizeof(crypto_info->key), in->key.size);
503 [ # # ][ # # ]: 0 : RESULT_CHECKED_MEMCPY(crypto_info->key, in->key.data, sizeof(crypto_info->key));
[ # # ]
504 [ # # ][ # # ]: 0 : RESULT_ENSURE_LTE(sizeof(crypto_info->rec_seq), in->seq.size);
505 [ # # ][ # # ]: 0 : RESULT_CHECKED_MEMCPY(crypto_info->rec_seq, in->seq.data, sizeof(crypto_info->rec_seq));
[ # # ]
506 : :
507 : 0 : size_t salt_size = sizeof(crypto_info->salt);
508 [ # # ][ # # ]: 0 : RESULT_ENSURE_LTE(salt_size, in->iv.size);
509 [ # # ][ # # ]: 0 : RESULT_CHECKED_MEMCPY(crypto_info->salt, in->iv.data, salt_size);
[ # # ]
510 : 0 : size_t iv_remainder = in->iv.size - salt_size;
511 [ # # ][ # # ]: 0 : RESULT_ENSURE_LTE(sizeof(crypto_info->iv), iv_remainder);
512 [ # # ][ # # ]: 0 : RESULT_CHECKED_MEMCPY(crypto_info->iv, in->iv.data + salt_size, sizeof(crypto_info->iv));
[ # # ]
513 : :
514 [ # # ]: 0 : RESULT_GUARD_POSIX(s2n_blob_init(&out->value, (uint8_t *) (void *) crypto_info,
515 : 0 : sizeof(s2n_ktls_crypto_info_tls12_aes_gcm_256)));
516 : 0 : return S2N_RESULT_OK;
517 : 0 : }
518 : :
519 : : const struct s2n_cipher s2n_aes128_gcm = {
520 : : .key_material_size = S2N_TLS_AES_128_GCM_KEY_LEN,
521 : : .type = S2N_AEAD,
522 : : .io.aead = {
523 : : .record_iv_size = S2N_TLS_GCM_EXPLICIT_IV_LEN,
524 : : .fixed_iv_size = S2N_TLS_GCM_FIXED_IV_LEN,
525 : : .tag_size = S2N_TLS_GCM_TAG_LEN,
526 : : .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
527 : : .encrypt = s2n_aead_cipher_aes_gcm_encrypt },
528 : : .is_available = s2n_aead_cipher_aes128_gcm_available,
529 : : .init = s2n_aead_cipher_aes_gcm_init,
530 : : .set_encryption_key = s2n_aead_cipher_aes128_gcm_set_encryption_key,
531 : : .set_decryption_key = s2n_aead_cipher_aes128_gcm_set_decryption_key,
532 : : .destroy_key = s2n_aead_cipher_aes_gcm_destroy_key,
533 : : .set_ktls_info = s2n_tls12_aead_cipher_aes128_gcm_set_ktls_info,
534 : : };
535 : :
536 : : const struct s2n_cipher s2n_aes256_gcm = {
537 : : .key_material_size = S2N_TLS_AES_256_GCM_KEY_LEN,
538 : : .type = S2N_AEAD,
539 : : .io.aead = {
540 : : .record_iv_size = S2N_TLS_GCM_EXPLICIT_IV_LEN,
541 : : .fixed_iv_size = S2N_TLS_GCM_FIXED_IV_LEN,
542 : : .tag_size = S2N_TLS_GCM_TAG_LEN,
543 : : .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
544 : : .encrypt = s2n_aead_cipher_aes_gcm_encrypt },
545 : : .is_available = s2n_aead_cipher_aes256_gcm_available,
546 : : .init = s2n_aead_cipher_aes_gcm_init,
547 : : .set_encryption_key = s2n_aead_cipher_aes256_gcm_set_encryption_key,
548 : : .set_decryption_key = s2n_aead_cipher_aes256_gcm_set_decryption_key,
549 : : .destroy_key = s2n_aead_cipher_aes_gcm_destroy_key,
550 : : .set_ktls_info = s2n_tls12_aead_cipher_aes256_gcm_set_ktls_info,
551 : : };
552 : :
553 : : /* TLS 1.3 GCM ciphers */
554 : : const struct s2n_cipher s2n_tls13_aes128_gcm = {
555 : : .key_material_size = S2N_TLS_AES_128_GCM_KEY_LEN,
556 : : .type = S2N_AEAD,
557 : : .io.aead = {
558 : : .record_iv_size = S2N_TLS13_RECORD_IV_LEN,
559 : : .fixed_iv_size = S2N_TLS13_FIXED_IV_LEN,
560 : : .tag_size = S2N_TLS_GCM_TAG_LEN,
561 : : .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
562 : : .encrypt = s2n_aead_cipher_aes_gcm_encrypt },
563 : : .is_available = s2n_aead_cipher_aes128_gcm_available,
564 : : .init = s2n_aead_cipher_aes_gcm_init,
565 : : .set_encryption_key = s2n_aead_cipher_aes128_gcm_set_encryption_key_tls13,
566 : : .set_decryption_key = s2n_aead_cipher_aes128_gcm_set_decryption_key_tls13,
567 : : .destroy_key = s2n_aead_cipher_aes_gcm_destroy_key,
568 : : .set_ktls_info = s2n_tls13_aead_cipher_aes128_gcm_set_ktls_info,
569 : : };
570 : :
571 : : const struct s2n_cipher s2n_tls13_aes256_gcm = {
572 : : .key_material_size = S2N_TLS_AES_256_GCM_KEY_LEN,
573 : : .type = S2N_AEAD,
574 : : .io.aead = {
575 : : .record_iv_size = S2N_TLS13_RECORD_IV_LEN,
576 : : .fixed_iv_size = S2N_TLS13_FIXED_IV_LEN,
577 : : .tag_size = S2N_TLS_GCM_TAG_LEN,
578 : : .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
579 : : .encrypt = s2n_aead_cipher_aes_gcm_encrypt },
580 : : .is_available = s2n_aead_cipher_aes256_gcm_available,
581 : : .init = s2n_aead_cipher_aes_gcm_init,
582 : : .set_encryption_key = s2n_aead_cipher_aes256_gcm_set_encryption_key_tls13,
583 : : .set_decryption_key = s2n_aead_cipher_aes256_gcm_set_decryption_key_tls13,
584 : : .destroy_key = s2n_aead_cipher_aes_gcm_destroy_key,
585 : : .set_ktls_info = s2n_tls13_aead_cipher_aes256_gcm_set_ktls_info,
586 : : };
|