blob: bb80cc6af5028061e424c2219cc49ec5d724f1de [file] [log] [blame]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001/* Copyright (c) 2014, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15#include <assert.h>
16#include <limits.h>
17#include <string.h>
18
19#include <openssl/aead.h>
20#include <openssl/cipher.h>
21#include <openssl/err.h>
22#include <openssl/hmac.h>
Adam Langley4139edb2016-01-13 15:00:54 -080023#include <openssl/md5.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080024#include <openssl/mem.h>
25#include <openssl/sha.h>
Adam Langleye9ada862015-05-11 17:20:37 -070026#include <openssl/type_check.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080027
David Benjaminf0c4a6c2016-08-11 13:26:41 -040028#include "../internal.h"
Adam Langleyd9e397b2015-01-22 14:27:53 -080029#include "internal.h"
30
31
32typedef struct {
33 EVP_CIPHER_CTX cipher_ctx;
34 HMAC_CTX hmac_ctx;
35 /* mac_key is the portion of the key used for the MAC. It is retained
36 * separately for the constant-time CBC code. */
37 uint8_t mac_key[EVP_MAX_MD_SIZE];
38 uint8_t mac_key_len;
Adam Langleyd9e397b2015-01-22 14:27:53 -080039 /* implicit_iv is one iff this is a pre-TLS-1.1 CBC cipher without an explicit
40 * IV. */
41 char implicit_iv;
Adam Langleyd9e397b2015-01-22 14:27:53 -080042} AEAD_TLS_CTX;
43
Adam Langleye9ada862015-05-11 17:20:37 -070044OPENSSL_COMPILE_ASSERT(EVP_MAX_MD_SIZE < 256, mac_key_len_fits_in_uint8_t);
Adam Langleyd9e397b2015-01-22 14:27:53 -080045
46static void aead_tls_cleanup(EVP_AEAD_CTX *ctx) {
47 AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state;
48 EVP_CIPHER_CTX_cleanup(&tls_ctx->cipher_ctx);
49 HMAC_CTX_cleanup(&tls_ctx->hmac_ctx);
50 OPENSSL_cleanse(&tls_ctx->mac_key, sizeof(tls_ctx->mac_key));
Adam Langleyd9e397b2015-01-22 14:27:53 -080051 OPENSSL_free(tls_ctx);
52 ctx->aead_state = NULL;
53}
54
55static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
Adam Langleye9ada862015-05-11 17:20:37 -070056 size_t tag_len, enum evp_aead_direction_t dir,
57 const EVP_CIPHER *cipher, const EVP_MD *md,
58 char implicit_iv) {
Adam Langleyd9e397b2015-01-22 14:27:53 -080059 if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
60 tag_len != EVP_MD_size(md)) {
Kenny Rootb8494592015-09-25 02:29:14 +000061 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
Adam Langleyd9e397b2015-01-22 14:27:53 -080062 return 0;
63 }
64
65 if (key_len != EVP_AEAD_key_length(ctx->aead)) {
Kenny Rootb8494592015-09-25 02:29:14 +000066 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
Adam Langleyd9e397b2015-01-22 14:27:53 -080067 return 0;
68 }
69
70 size_t mac_key_len = EVP_MD_size(md);
71 size_t enc_key_len = EVP_CIPHER_key_length(cipher);
Adam Langleye9ada862015-05-11 17:20:37 -070072 assert(mac_key_len + enc_key_len +
73 (implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0) == key_len);
Adam Langleyd9e397b2015-01-22 14:27:53 -080074
75 AEAD_TLS_CTX *tls_ctx = OPENSSL_malloc(sizeof(AEAD_TLS_CTX));
76 if (tls_ctx == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +000077 OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
Adam Langleyd9e397b2015-01-22 14:27:53 -080078 return 0;
79 }
80 EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx);
81 HMAC_CTX_init(&tls_ctx->hmac_ctx);
Adam Langleye9ada862015-05-11 17:20:37 -070082 assert(mac_key_len <= EVP_MAX_MD_SIZE);
Robert Sloan69939df2017-01-09 10:53:07 -080083 OPENSSL_memcpy(tls_ctx->mac_key, key, mac_key_len);
Adam Langleyd9e397b2015-01-22 14:27:53 -080084 tls_ctx->mac_key_len = (uint8_t)mac_key_len;
Adam Langleyd9e397b2015-01-22 14:27:53 -080085 tls_ctx->implicit_iv = implicit_iv;
Adam Langleyd9e397b2015-01-22 14:27:53 -080086
87 ctx->aead_state = tls_ctx;
Adam Langleye9ada862015-05-11 17:20:37 -070088 if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len],
89 implicit_iv ? &key[mac_key_len + enc_key_len] : NULL,
90 dir == evp_aead_seal) ||
Adam Langleyd9e397b2015-01-22 14:27:53 -080091 !HMAC_Init_ex(&tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) {
92 aead_tls_cleanup(ctx);
Adam Langleye9ada862015-05-11 17:20:37 -070093 ctx->aead_state = NULL;
Adam Langleyd9e397b2015-01-22 14:27:53 -080094 return 0;
95 }
96 EVP_CIPHER_CTX_set_padding(&tls_ctx->cipher_ctx, 0);
97
98 return 1;
99}
100
Adam Langleyd9e397b2015-01-22 14:27:53 -0800101static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
102 size_t *out_len, size_t max_out_len,
103 const uint8_t *nonce, size_t nonce_len,
104 const uint8_t *in, size_t in_len,
105 const uint8_t *ad, size_t ad_len) {
106 AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state;
107 size_t total = 0;
108
Adam Langleye9ada862015-05-11 17:20:37 -0700109 if (!tls_ctx->cipher_ctx.encrypt) {
110 /* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
Kenny Rootb8494592015-09-25 02:29:14 +0000111 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
Adam Langleye9ada862015-05-11 17:20:37 -0700112 return 0;
Adam Langleye9ada862015-05-11 17:20:37 -0700113 }
114
Adam Langleyd9e397b2015-01-22 14:27:53 -0800115 if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
116 in_len > INT_MAX) {
117 /* EVP_CIPHER takes int as input. */
Kenny Rootb8494592015-09-25 02:29:14 +0000118 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800119 return 0;
120 }
121
122 if (max_out_len < in_len + EVP_AEAD_max_overhead(ctx->aead)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000123 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800124 return 0;
125 }
126
127 if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000128 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800129 return 0;
130 }
131
132 if (ad_len != 13 - 2 /* length bytes */) {
Kenny Rootb8494592015-09-25 02:29:14 +0000133 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800134 return 0;
135 }
136
Adam Langleyd9e397b2015-01-22 14:27:53 -0800137 /* To allow for CBC mode which changes cipher length, |ad| doesn't include the
138 * length for legacy ciphers. */
139 uint8_t ad_extra[2];
140 ad_extra[0] = (uint8_t)(in_len >> 8);
141 ad_extra[1] = (uint8_t)(in_len & 0xff);
142
143 /* Compute the MAC. This must be first in case the operation is being done
144 * in-place. */
145 uint8_t mac[EVP_MAX_MD_SIZE];
146 unsigned mac_len;
Adam Langley4139edb2016-01-13 15:00:54 -0800147 if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) ||
148 !HMAC_Update(&tls_ctx->hmac_ctx, ad, ad_len) ||
149 !HMAC_Update(&tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) ||
150 !HMAC_Update(&tls_ctx->hmac_ctx, in, in_len) ||
151 !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800152 return 0;
153 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800154
155 /* Configure the explicit IV. */
156 if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
157 !tls_ctx->implicit_iv &&
158 !EVP_EncryptInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, NULL, nonce)) {
159 return 0;
160 }
161
162 /* Encrypt the input. */
163 int len;
164 if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out, &len, in,
165 (int)in_len)) {
166 return 0;
167 }
168 total = len;
169
170 /* Feed the MAC into the cipher. */
171 if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out + total, &len, mac,
172 (int)mac_len)) {
173 return 0;
174 }
175 total += len;
176
177 unsigned block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx);
178 if (block_size > 1) {
179 assert(block_size <= 256);
180 assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE);
181
182 /* Compute padding and feed that into the cipher. */
183 uint8_t padding[256];
184 unsigned padding_len = block_size - ((in_len + mac_len) % block_size);
Robert Sloan69939df2017-01-09 10:53:07 -0800185 OPENSSL_memset(padding, padding_len - 1, padding_len);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800186 if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out + total, &len, padding,
187 (int)padding_len)) {
188 return 0;
189 }
190 total += len;
191 }
192
193 if (!EVP_EncryptFinal_ex(&tls_ctx->cipher_ctx, out + total, &len)) {
194 return 0;
195 }
196 total += len;
197
198 *out_len = total;
199 return 1;
200}
201
202static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
203 size_t *out_len, size_t max_out_len,
204 const uint8_t *nonce, size_t nonce_len,
205 const uint8_t *in, size_t in_len,
206 const uint8_t *ad, size_t ad_len) {
207 AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state;
208
Adam Langleye9ada862015-05-11 17:20:37 -0700209 if (tls_ctx->cipher_ctx.encrypt) {
210 /* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
Kenny Rootb8494592015-09-25 02:29:14 +0000211 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
Adam Langleye9ada862015-05-11 17:20:37 -0700212 return 0;
Adam Langleye9ada862015-05-11 17:20:37 -0700213 }
214
Adam Langleyd9e397b2015-01-22 14:27:53 -0800215 if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000216 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800217 return 0;
218 }
219
220 if (max_out_len < in_len) {
221 /* This requires that the caller provide space for the MAC, even though it
222 * will always be removed on return. */
Kenny Rootb8494592015-09-25 02:29:14 +0000223 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800224 return 0;
225 }
226
227 if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000228 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800229 return 0;
230 }
231
232 if (ad_len != 13 - 2 /* length bytes */) {
Kenny Rootb8494592015-09-25 02:29:14 +0000233 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800234 return 0;
235 }
236
237 if (in_len > INT_MAX) {
238 /* EVP_CIPHER takes int as input. */
Kenny Rootb8494592015-09-25 02:29:14 +0000239 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800240 return 0;
241 }
242
Adam Langleyd9e397b2015-01-22 14:27:53 -0800243 /* Configure the explicit IV. */
244 if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
245 !tls_ctx->implicit_iv &&
246 !EVP_DecryptInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, NULL, nonce)) {
247 return 0;
248 }
249
250 /* Decrypt to get the plaintext + MAC + padding. */
251 size_t total = 0;
252 int len;
253 if (!EVP_DecryptUpdate(&tls_ctx->cipher_ctx, out, &len, in, (int)in_len)) {
254 return 0;
255 }
256 total += len;
257 if (!EVP_DecryptFinal_ex(&tls_ctx->cipher_ctx, out + total, &len)) {
258 return 0;
259 }
260 total += len;
261 assert(total == in_len);
262
263 /* Remove CBC padding. Code from here on is timing-sensitive with respect to
264 * |padding_ok| and |data_plus_mac_len| for CBC ciphers. */
Robert Sloan9254e682017-04-24 09:42:06 -0700265 size_t data_plus_mac_len;
266 crypto_word_t padding_ok;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800267 if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400268 if (!EVP_tls_cbc_remove_padding(
269 &padding_ok, &data_plus_mac_len, out, total,
270 EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx),
Robert Sloan6f79a502017-04-03 09:16:40 -0700271 HMAC_size(&tls_ctx->hmac_ctx))) {
David Benjaminc895d6b2016-08-11 13:26:41 -0400272 /* Publicly invalid. This can be rejected in non-constant time. */
Kenny Rootb8494592015-09-25 02:29:14 +0000273 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800274 return 0;
275 }
276 } else {
Robert Sloan9254e682017-04-24 09:42:06 -0700277 padding_ok = CONSTTIME_TRUE_W;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800278 data_plus_mac_len = total;
279 /* |data_plus_mac_len| = |total| = |in_len| at this point. |in_len| has
280 * already been checked against the MAC size at the top of the function. */
281 assert(data_plus_mac_len >= HMAC_size(&tls_ctx->hmac_ctx));
282 }
Robert Sloan6f79a502017-04-03 09:16:40 -0700283 size_t data_len = data_plus_mac_len - HMAC_size(&tls_ctx->hmac_ctx);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800284
David Benjaminc895d6b2016-08-11 13:26:41 -0400285 /* At this point, if the padding is valid, the first |data_plus_mac_len| bytes
286 * after |out| are the plaintext and MAC. Otherwise, |data_plus_mac_len| is
287 * still large enough to extract a MAC, but it will be irrelevant. */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800288
289 /* To allow for CBC mode which changes cipher length, |ad| doesn't include the
290 * length for legacy ciphers. */
291 uint8_t ad_fixed[13];
Robert Sloan69939df2017-01-09 10:53:07 -0800292 OPENSSL_memcpy(ad_fixed, ad, 11);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800293 ad_fixed[11] = (uint8_t)(data_len >> 8);
294 ad_fixed[12] = (uint8_t)(data_len & 0xff);
295 ad_len += 2;
296
297 /* Compute the MAC and extract the one in the record. */
298 uint8_t mac[EVP_MAX_MD_SIZE];
299 size_t mac_len;
300 uint8_t record_mac_tmp[EVP_MAX_MD_SIZE];
301 uint8_t *record_mac;
302 if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE &&
303 EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx.md)) {
304 if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len,
305 ad_fixed, out, data_plus_mac_len, total,
306 tls_ctx->mac_key, tls_ctx->mac_key_len)) {
Kenny Rootb8494592015-09-25 02:29:14 +0000307 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800308 return 0;
309 }
310 assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx));
311
312 record_mac = record_mac_tmp;
313 EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total);
314 } else {
315 /* We should support the constant-time path for all CBC-mode ciphers
316 * implemented. */
317 assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE);
318
Adam Langleyd9e397b2015-01-22 14:27:53 -0800319 unsigned mac_len_u;
Adam Langley4139edb2016-01-13 15:00:54 -0800320 if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) ||
321 !HMAC_Update(&tls_ctx->hmac_ctx, ad_fixed, ad_len) ||
322 !HMAC_Update(&tls_ctx->hmac_ctx, out, data_len) ||
323 !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len_u)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800324 return 0;
325 }
326 mac_len = mac_len_u;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800327
328 assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx));
329 record_mac = &out[data_len];
330 }
331
332 /* Perform the MAC check and the padding check in constant-time. It should be
333 * safe to simply perform the padding check first, but it would not be under a
334 * different choice of MAC location on padding failure. See
335 * EVP_tls_cbc_remove_padding. */
Robert Sloan9254e682017-04-24 09:42:06 -0700336 crypto_word_t good =
Robert Sloan6f79a502017-04-03 09:16:40 -0700337 constant_time_eq_int(CRYPTO_memcmp(record_mac, mac, mac_len), 0);
David Benjaminc895d6b2016-08-11 13:26:41 -0400338 good &= padding_ok;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800339 if (!good) {
Kenny Rootb8494592015-09-25 02:29:14 +0000340 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800341 return 0;
342 }
343
344 /* End of timing-sensitive code. */
345
346 *out_len = data_len;
347 return 1;
348}
349
Adam Langleyd9e397b2015-01-22 14:27:53 -0800350static int aead_aes_128_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
Adam Langleye9ada862015-05-11 17:20:37 -0700351 size_t key_len, size_t tag_len,
352 enum evp_aead_direction_t dir) {
353 return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(),
Adam Langleyd9e397b2015-01-22 14:27:53 -0800354 EVP_sha1(), 0);
355}
356
Adam Langleye9ada862015-05-11 17:20:37 -0700357static int aead_aes_128_cbc_sha1_tls_implicit_iv_init(
358 EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len,
359 enum evp_aead_direction_t dir) {
360 return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(),
Adam Langleyd9e397b2015-01-22 14:27:53 -0800361 EVP_sha1(), 1);
362}
363
364static int aead_aes_128_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx,
365 const uint8_t *key, size_t key_len,
Adam Langleye9ada862015-05-11 17:20:37 -0700366 size_t tag_len,
367 enum evp_aead_direction_t dir) {
368 return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(),
Adam Langleyd9e397b2015-01-22 14:27:53 -0800369 EVP_sha256(), 0);
370}
371
372static int aead_aes_256_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
Adam Langleye9ada862015-05-11 17:20:37 -0700373 size_t key_len, size_t tag_len,
374 enum evp_aead_direction_t dir) {
375 return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(),
Adam Langleyd9e397b2015-01-22 14:27:53 -0800376 EVP_sha1(), 0);
377}
378
Adam Langleye9ada862015-05-11 17:20:37 -0700379static int aead_aes_256_cbc_sha1_tls_implicit_iv_init(
380 EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len,
381 enum evp_aead_direction_t dir) {
382 return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(),
Adam Langleyd9e397b2015-01-22 14:27:53 -0800383 EVP_sha1(), 1);
384}
385
386static int aead_aes_256_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx,
387 const uint8_t *key, size_t key_len,
Adam Langleye9ada862015-05-11 17:20:37 -0700388 size_t tag_len,
389 enum evp_aead_direction_t dir) {
390 return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(),
Adam Langleyd9e397b2015-01-22 14:27:53 -0800391 EVP_sha256(), 0);
392}
393
394static int aead_aes_256_cbc_sha384_tls_init(EVP_AEAD_CTX *ctx,
395 const uint8_t *key, size_t key_len,
Adam Langleye9ada862015-05-11 17:20:37 -0700396 size_t tag_len,
397 enum evp_aead_direction_t dir) {
398 return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(),
Adam Langleyd9e397b2015-01-22 14:27:53 -0800399 EVP_sha384(), 0);
400}
401
402static int aead_des_ede3_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx,
403 const uint8_t *key, size_t key_len,
Adam Langleye9ada862015-05-11 17:20:37 -0700404 size_t tag_len,
405 enum evp_aead_direction_t dir) {
406 return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(),
Adam Langleyd9e397b2015-01-22 14:27:53 -0800407 EVP_sha1(), 0);
408}
409
Adam Langleye9ada862015-05-11 17:20:37 -0700410static int aead_des_ede3_cbc_sha1_tls_implicit_iv_init(
411 EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len,
412 enum evp_aead_direction_t dir) {
413 return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(),
Adam Langleyd9e397b2015-01-22 14:27:53 -0800414 EVP_sha1(), 1);
415}
416
Adam Langleyfad63272015-11-12 12:15:39 -0800417static int aead_tls_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
418 size_t *out_iv_len) {
419 const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX*) ctx->aead_state;
420 const size_t iv_len = EVP_CIPHER_CTX_iv_length(&tls_ctx->cipher_ctx);
421 if (iv_len <= 1) {
422 return 0;
423 }
424
425 *out_iv = tls_ctx->cipher_ctx.iv;
426 *out_iv_len = iv_len;
427 return 1;
428}
429
Kenny Rootb8494592015-09-25 02:29:14 +0000430static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
431 size_t key_len, size_t tag_len,
432 enum evp_aead_direction_t dir) {
433 return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(),
434 EVP_sha1(), 1 /* implicit iv */);
435}
436
Adam Langleyd9e397b2015-01-22 14:27:53 -0800437static const EVP_AEAD aead_aes_128_cbc_sha1_tls = {
438 SHA_DIGEST_LENGTH + 16, /* key len (SHA1 + AES128) */
439 16, /* nonce len (IV) */
440 16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
441 SHA_DIGEST_LENGTH, /* max tag length */
Adam Langleye9ada862015-05-11 17:20:37 -0700442 NULL, /* init */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800443 aead_aes_128_cbc_sha1_tls_init,
444 aead_tls_cleanup,
445 aead_tls_seal,
446 aead_tls_open,
Adam Langleyfad63272015-11-12 12:15:39 -0800447 NULL, /* get_iv */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800448};
449
450static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = {
451 SHA_DIGEST_LENGTH + 16 + 16, /* key len (SHA1 + AES128 + IV) */
452 0, /* nonce len */
453 16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
454 SHA_DIGEST_LENGTH, /* max tag length */
Adam Langleye9ada862015-05-11 17:20:37 -0700455 NULL, /* init */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800456 aead_aes_128_cbc_sha1_tls_implicit_iv_init,
457 aead_tls_cleanup,
458 aead_tls_seal,
459 aead_tls_open,
Adam Langleyfad63272015-11-12 12:15:39 -0800460 aead_tls_get_iv, /* get_iv */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800461};
462
463static const EVP_AEAD aead_aes_128_cbc_sha256_tls = {
464 SHA256_DIGEST_LENGTH + 16, /* key len (SHA256 + AES128) */
465 16, /* nonce len (IV) */
466 16 + SHA256_DIGEST_LENGTH, /* overhead (padding + SHA256) */
Kenny Roote99801b2015-11-06 15:31:15 -0800467 SHA256_DIGEST_LENGTH, /* max tag length */
Adam Langleye9ada862015-05-11 17:20:37 -0700468 NULL, /* init */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800469 aead_aes_128_cbc_sha256_tls_init,
470 aead_tls_cleanup,
471 aead_tls_seal,
472 aead_tls_open,
Adam Langleyfad63272015-11-12 12:15:39 -0800473 NULL, /* get_iv */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800474};
475
476static const EVP_AEAD aead_aes_256_cbc_sha1_tls = {
477 SHA_DIGEST_LENGTH + 32, /* key len (SHA1 + AES256) */
478 16, /* nonce len (IV) */
479 16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
480 SHA_DIGEST_LENGTH, /* max tag length */
Adam Langleye9ada862015-05-11 17:20:37 -0700481 NULL, /* init */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800482 aead_aes_256_cbc_sha1_tls_init,
483 aead_tls_cleanup,
484 aead_tls_seal,
485 aead_tls_open,
Adam Langleyfad63272015-11-12 12:15:39 -0800486 NULL, /* get_iv */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800487};
488
489static const EVP_AEAD aead_aes_256_cbc_sha1_tls_implicit_iv = {
490 SHA_DIGEST_LENGTH + 32 + 16, /* key len (SHA1 + AES256 + IV) */
491 0, /* nonce len */
492 16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
493 SHA_DIGEST_LENGTH, /* max tag length */
Adam Langleye9ada862015-05-11 17:20:37 -0700494 NULL, /* init */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800495 aead_aes_256_cbc_sha1_tls_implicit_iv_init,
496 aead_tls_cleanup,
497 aead_tls_seal,
498 aead_tls_open,
Adam Langleyfad63272015-11-12 12:15:39 -0800499 aead_tls_get_iv, /* get_iv */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800500};
501
502static const EVP_AEAD aead_aes_256_cbc_sha256_tls = {
503 SHA256_DIGEST_LENGTH + 32, /* key len (SHA256 + AES256) */
504 16, /* nonce len (IV) */
505 16 + SHA256_DIGEST_LENGTH, /* overhead (padding + SHA256) */
Kenny Roote99801b2015-11-06 15:31:15 -0800506 SHA256_DIGEST_LENGTH, /* max tag length */
Adam Langleye9ada862015-05-11 17:20:37 -0700507 NULL, /* init */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800508 aead_aes_256_cbc_sha256_tls_init,
509 aead_tls_cleanup,
510 aead_tls_seal,
511 aead_tls_open,
Adam Langleyfad63272015-11-12 12:15:39 -0800512 NULL, /* get_iv */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800513};
514
515static const EVP_AEAD aead_aes_256_cbc_sha384_tls = {
516 SHA384_DIGEST_LENGTH + 32, /* key len (SHA384 + AES256) */
517 16, /* nonce len (IV) */
518 16 + SHA384_DIGEST_LENGTH, /* overhead (padding + SHA384) */
Kenny Roote99801b2015-11-06 15:31:15 -0800519 SHA384_DIGEST_LENGTH, /* max tag length */
Adam Langleye9ada862015-05-11 17:20:37 -0700520 NULL, /* init */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800521 aead_aes_256_cbc_sha384_tls_init,
522 aead_tls_cleanup,
523 aead_tls_seal,
524 aead_tls_open,
Adam Langleyfad63272015-11-12 12:15:39 -0800525 NULL, /* get_iv */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800526};
527
528static const EVP_AEAD aead_des_ede3_cbc_sha1_tls = {
529 SHA_DIGEST_LENGTH + 24, /* key len (SHA1 + 3DES) */
530 8, /* nonce len (IV) */
531 8 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
532 SHA_DIGEST_LENGTH, /* max tag length */
Adam Langleye9ada862015-05-11 17:20:37 -0700533 NULL, /* init */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800534 aead_des_ede3_cbc_sha1_tls_init,
535 aead_tls_cleanup,
536 aead_tls_seal,
537 aead_tls_open,
Adam Langleyfad63272015-11-12 12:15:39 -0800538 NULL, /* get_iv */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800539};
540
541static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = {
542 SHA_DIGEST_LENGTH + 24 + 8, /* key len (SHA1 + 3DES + IV) */
543 0, /* nonce len */
544 8 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */
545 SHA_DIGEST_LENGTH, /* max tag length */
Adam Langleye9ada862015-05-11 17:20:37 -0700546 NULL, /* init */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800547 aead_des_ede3_cbc_sha1_tls_implicit_iv_init,
548 aead_tls_cleanup,
549 aead_tls_seal,
550 aead_tls_open,
Adam Langleyfad63272015-11-12 12:15:39 -0800551 aead_tls_get_iv, /* get_iv */
Adam Langleyd9e397b2015-01-22 14:27:53 -0800552};
553
Kenny Rootb8494592015-09-25 02:29:14 +0000554static const EVP_AEAD aead_null_sha1_tls = {
555 SHA_DIGEST_LENGTH, /* key len */
556 0, /* nonce len */
557 SHA_DIGEST_LENGTH, /* overhead (SHA1) */
558 SHA_DIGEST_LENGTH, /* max tag length */
559 NULL, /* init */
560 aead_null_sha1_tls_init,
561 aead_tls_cleanup,
562 aead_tls_seal,
563 aead_tls_open,
Adam Langleyfad63272015-11-12 12:15:39 -0800564 NULL, /* get_iv */
Kenny Rootb8494592015-09-25 02:29:14 +0000565};
566
Adam Langleyd9e397b2015-01-22 14:27:53 -0800567const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) {
568 return &aead_aes_128_cbc_sha1_tls;
569}
570
571const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void) {
572 return &aead_aes_128_cbc_sha1_tls_implicit_iv;
573}
574
575const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void) {
576 return &aead_aes_128_cbc_sha256_tls;
577}
578
579const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void) {
580 return &aead_aes_256_cbc_sha1_tls;
581}
582
583const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void) {
584 return &aead_aes_256_cbc_sha1_tls_implicit_iv;
585}
586
587const EVP_AEAD *EVP_aead_aes_256_cbc_sha256_tls(void) {
588 return &aead_aes_256_cbc_sha256_tls;
589}
590
591const EVP_AEAD *EVP_aead_aes_256_cbc_sha384_tls(void) {
592 return &aead_aes_256_cbc_sha384_tls;
593}
594
595const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void) {
596 return &aead_des_ede3_cbc_sha1_tls;
597}
598
599const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void) {
600 return &aead_des_ede3_cbc_sha1_tls_implicit_iv;
601}
Kenny Rootb8494592015-09-25 02:29:14 +0000602
603const EVP_AEAD *EVP_aead_null_sha1_tls(void) { return &aead_null_sha1_tls; }