Instead, add a separate init_with_direction hook. Normal AEADs ignore the direction, while legacy AEADs must be initialized with it. This avoids maintaining extra state to support the delayed initialization. Change-Id: I25271f0e56ee2783a2fd4d4026434154d58dc0a8 Reviewed-on: https://boringssl-review.googlesource.com/3731 Reviewed-by: Adam Langley <agl@google.com>kris/onging/CECPQ3_patch15
@@ -33,12 +33,29 @@ size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) { return aead->max_tag_len; } | |||
int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, | |||
const uint8_t *key, size_t key_len, size_t tag_len, | |||
ENGINE *impl) { | |||
if (!aead->init) { | |||
OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init, CIPHER_R_NO_DIRECTION_SET); | |||
return 0; | |||
} | |||
return EVP_AEAD_CTX_init_with_direction(ctx, aead, key, key_len, tag_len, | |||
evp_aead_open); | |||
} | |||
int EVP_AEAD_CTX_init_with_direction(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, | |||
const uint8_t *key, size_t key_len, | |||
size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
ctx->aead = aead; | |||
if (key_len != aead->key_len) { | |||
OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init, CIPHER_R_UNSUPPORTED_KEY_SIZE); | |||
OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init_with_direction, | |||
CIPHER_R_UNSUPPORTED_KEY_SIZE); | |||
return 0; | |||
} | |||
return aead->init(ctx, key, key_len, tag_len); | |||
if (aead->init) { | |||
return aead->init(ctx, key, key_len, tag_len); | |||
} else { | |||
return aead->init_with_direction(ctx, key, key_len, tag_len, dir); | |||
} | |||
} | |||
void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx) { | |||
@@ -85,8 +85,8 @@ static int run_test_case(const EVP_AEAD *aead, | |||
* smaller by at least tag length. */ | |||
uint8_t out2[sizeof(out)]; | |||
if (!EVP_AEAD_CTX_init(&ctx, aead, bufs[KEY], lengths[KEY], lengths[TAG], | |||
NULL)) { | |||
if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bufs[KEY], lengths[KEY], | |||
lengths[TAG], evp_aead_seal)) { | |||
fprintf(stderr, "Failed to init AEAD on line %u\n", line_no); | |||
return 0; | |||
} | |||
@@ -123,8 +123,8 @@ static int run_test_case(const EVP_AEAD *aead, | |||
/* The "stateful" AEADs for implementing pre-AEAD cipher suites need to be | |||
* reset after each operation. */ | |||
EVP_AEAD_CTX_cleanup(&ctx); | |||
if (!EVP_AEAD_CTX_init(&ctx, aead, bufs[KEY], lengths[KEY], lengths[TAG], | |||
NULL)) { | |||
if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bufs[KEY], lengths[KEY], | |||
lengths[TAG], evp_aead_open)) { | |||
fprintf(stderr, "Failed to init AEAD on line %u\n", line_no); | |||
return 0; | |||
} | |||
@@ -153,8 +153,8 @@ static int run_test_case(const EVP_AEAD *aead, | |||
/* The "stateful" AEADs for implementing pre-AEAD cipher suites need to be | |||
* reset after each operation. */ | |||
EVP_AEAD_CTX_cleanup(&ctx); | |||
if (!EVP_AEAD_CTX_init(&ctx, aead, bufs[KEY], lengths[KEY], lengths[TAG], | |||
NULL)) { | |||
if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bufs[KEY], lengths[KEY], | |||
lengths[TAG], evp_aead_open)) { | |||
fprintf(stderr, "Failed to init AEAD on line %u\n", line_no); | |||
return 0; | |||
} | |||
@@ -172,8 +172,8 @@ static int run_test_case(const EVP_AEAD *aead, | |||
/* The "stateful" AEADs for implementing pre-AEAD cipher suites need to be | |||
* reset after each operation. */ | |||
EVP_AEAD_CTX_cleanup(&ctx); | |||
if (!EVP_AEAD_CTX_init(&ctx, aead, bufs[KEY], lengths[KEY], lengths[TAG], | |||
NULL)) { | |||
if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bufs[KEY], lengths[KEY], | |||
lengths[TAG], evp_aead_open)) { | |||
fprintf(stderr, "Failed to init AEAD on line %u\n", line_no); | |||
return 0; | |||
} | |||
@@ -1071,8 +1071,11 @@ static const EVP_AEAD aead_aes_128_gcm = { | |||
12, /* nonce len */ | |||
EVP_AEAD_AES_GCM_TAG_LEN, /* overhead */ | |||
EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */ | |||
aead_aes_gcm_init, aead_aes_gcm_cleanup, | |||
aead_aes_gcm_seal, aead_aes_gcm_open, | |||
aead_aes_gcm_init, | |||
NULL, /* init_with_direction */ | |||
aead_aes_gcm_cleanup, | |||
aead_aes_gcm_seal, | |||
aead_aes_gcm_open, | |||
}; | |||
static const EVP_AEAD aead_aes_256_gcm = { | |||
@@ -1080,8 +1083,11 @@ static const EVP_AEAD aead_aes_256_gcm = { | |||
12, /* nonce len */ | |||
EVP_AEAD_AES_GCM_TAG_LEN, /* overhead */ | |||
EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */ | |||
aead_aes_gcm_init, aead_aes_gcm_cleanup, | |||
aead_aes_gcm_seal, aead_aes_gcm_open, | |||
aead_aes_gcm_init, | |||
NULL, /* init_with_direction */ | |||
aead_aes_gcm_cleanup, | |||
aead_aes_gcm_seal, | |||
aead_aes_gcm_open, | |||
}; | |||
const EVP_AEAD *EVP_aead_aes_128_gcm(void) { return &aead_aes_128_gcm; } | |||
@@ -1335,8 +1341,11 @@ static const EVP_AEAD aead_aes_128_key_wrap = { | |||
8, /* nonce len */ | |||
8, /* overhead */ | |||
8, /* max tag length */ | |||
aead_aes_key_wrap_init, aead_aes_key_wrap_cleanup, | |||
aead_aes_key_wrap_seal, aead_aes_key_wrap_open, | |||
aead_aes_key_wrap_init, | |||
NULL, /* init_with_direction */ | |||
aead_aes_key_wrap_cleanup, | |||
aead_aes_key_wrap_seal, | |||
aead_aes_key_wrap_open, | |||
}; | |||
static const EVP_AEAD aead_aes_256_key_wrap = { | |||
@@ -1344,8 +1353,11 @@ static const EVP_AEAD aead_aes_256_key_wrap = { | |||
8, /* nonce len */ | |||
8, /* overhead */ | |||
8, /* max tag length */ | |||
aead_aes_key_wrap_init, aead_aes_key_wrap_cleanup, | |||
aead_aes_key_wrap_seal, aead_aes_key_wrap_open, | |||
aead_aes_key_wrap_init, | |||
NULL, /* init_with_direction */ | |||
aead_aes_key_wrap_cleanup, | |||
aead_aes_key_wrap_seal, | |||
aead_aes_key_wrap_open, | |||
}; | |||
const EVP_AEAD *EVP_aead_aes_128_key_wrap(void) { return &aead_aes_128_key_wrap; } | |||
@@ -209,8 +209,11 @@ static const EVP_AEAD aead_chacha20_poly1305 = { | |||
CHACHA20_NONCE_LEN, /* nonce len */ | |||
POLY1305_TAG_LEN, /* overhead */ | |||
POLY1305_TAG_LEN, /* max tag length */ | |||
aead_chacha20_poly1305_init, aead_chacha20_poly1305_cleanup, | |||
aead_chacha20_poly1305_seal, aead_chacha20_poly1305_open, | |||
aead_chacha20_poly1305_init, | |||
NULL, /* init_with_direction */ | |||
aead_chacha20_poly1305_cleanup, | |||
aead_chacha20_poly1305_seal, | |||
aead_chacha20_poly1305_open, | |||
}; | |||
const EVP_AEAD *EVP_aead_chacha20_poly1305(void) { | |||
@@ -377,8 +377,11 @@ static const EVP_AEAD aead_rc4_md5_tls = { | |||
0, /* nonce len */ | |||
MD5_DIGEST_LENGTH, /* overhead */ | |||
MD5_DIGEST_LENGTH, /* max tag length */ | |||
aead_rc4_md5_tls_init, aead_rc4_md5_tls_cleanup, | |||
aead_rc4_md5_tls_seal, aead_rc4_md5_tls_open, | |||
aead_rc4_md5_tls_init, | |||
NULL, /* init_with_direction */ | |||
aead_rc4_md5_tls_cleanup, | |||
aead_rc4_md5_tls_seal, | |||
aead_rc4_md5_tls_open, | |||
}; | |||
const EVP_AEAD *EVP_aead_rc4_md5_tls(void) { return &aead_rc4_md5_tls; } |
@@ -30,17 +30,6 @@ | |||
typedef struct { | |||
EVP_CIPHER_CTX cipher_ctx; | |||
EVP_MD_CTX md_ctx; | |||
/* enc_key is the portion of the key used for the stream or block cipher. It | |||
* is retained separately to allow the EVP_CIPHER_CTX to be initialized once | |||
* the direction is known. */ | |||
uint8_t enc_key[EVP_MAX_KEY_LENGTH]; | |||
uint8_t enc_key_len; | |||
/* iv is the portion of the key used for the fixed IV. It is retained | |||
* separately to allow the EVP_CIPHER_CTX to be initialized once the direction | |||
* is known. */ | |||
uint8_t iv[EVP_MAX_IV_LENGTH]; | |||
uint8_t iv_len; | |||
char initialized; | |||
} AEAD_SSL3_CTX; | |||
static int ssl3_mac(AEAD_SSL3_CTX *ssl3_ctx, uint8_t *out, unsigned *out_len, | |||
@@ -87,15 +76,13 @@ static void aead_ssl3_cleanup(EVP_AEAD_CTX *ctx) { | |||
AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state; | |||
EVP_CIPHER_CTX_cleanup(&ssl3_ctx->cipher_ctx); | |||
EVP_MD_CTX_cleanup(&ssl3_ctx->md_ctx); | |||
OPENSSL_cleanse(&ssl3_ctx->enc_key, sizeof(ssl3_ctx->enc_key)); | |||
OPENSSL_cleanse(&ssl3_ctx->iv, sizeof(ssl3_ctx->iv)); | |||
OPENSSL_free(ssl3_ctx); | |||
ctx->aead_state = NULL; | |||
} | |||
static int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, | |||
size_t tag_len, const EVP_CIPHER *cipher, | |||
const EVP_MD *md) { | |||
size_t tag_len, enum evp_aead_direction_t dir, | |||
const EVP_CIPHER *cipher, const EVP_MD *md) { | |||
if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH && | |||
tag_len != EVP_MD_size(md)) { | |||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, CIPHER_R_UNSUPPORTED_TAG_SIZE); | |||
@@ -109,11 +96,7 @@ static int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, | |||
size_t mac_key_len = EVP_MD_size(md); | |||
size_t enc_key_len = EVP_CIPHER_key_length(cipher); | |||
size_t iv_len = EVP_CIPHER_iv_length(cipher); | |||
assert(mac_key_len + enc_key_len + iv_len == key_len); | |||
assert(mac_key_len < 256); | |||
assert(enc_key_len < 256); | |||
assert(iv_len < 256); | |||
assert(mac_key_len + enc_key_len + EVP_CIPHER_iv_length(cipher) == key_len); | |||
/* Although EVP_rc4() is a variable-length cipher, the default key size is | |||
* correct for SSL3. */ | |||
@@ -124,14 +107,11 @@ static int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, | |||
} | |||
EVP_CIPHER_CTX_init(&ssl3_ctx->cipher_ctx); | |||
EVP_MD_CTX_init(&ssl3_ctx->md_ctx); | |||
memcpy(ssl3_ctx->enc_key, &key[mac_key_len], enc_key_len); | |||
ssl3_ctx->enc_key_len = (uint8_t)enc_key_len; | |||
memcpy(ssl3_ctx->iv, &key[mac_key_len + enc_key_len], iv_len); | |||
ssl3_ctx->iv_len = (uint8_t)iv_len; | |||
ssl3_ctx->initialized = 0; | |||
ctx->aead_state = ssl3_ctx; | |||
if (!EVP_CipherInit_ex(&ssl3_ctx->cipher_ctx, cipher, NULL, NULL, NULL, 0) || | |||
if (!EVP_CipherInit_ex(&ssl3_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len], | |||
&key[mac_key_len + enc_key_len], | |||
dir == evp_aead_seal) || | |||
!EVP_DigestInit_ex(&ssl3_ctx->md_ctx, md, NULL) || | |||
!EVP_DigestUpdate(&ssl3_ctx->md_ctx, key, mac_key_len)) { | |||
aead_ssl3_cleanup(ctx); | |||
@@ -142,31 +122,6 @@ static int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, | |||
return 1; | |||
} | |||
/* aead_ssl3_ensure_cipher_init initializes |ssl3_ctx| for encryption (or | |||
* decryption, if |encrypt| is zero). If it has already been initialized, it | |||
* ensures the direction matches and fails otherwise. It returns one on success | |||
* and zero on failure. | |||
* | |||
* Note that, unlike normal AEADs, legacy SSL3 AEADs may not be used concurrently | |||
* due to this (and bulk-cipher-internal) statefulness. */ | |||
static int aead_ssl3_ensure_cipher_init(AEAD_SSL3_CTX *ssl3_ctx, int encrypt) { | |||
if (!ssl3_ctx->initialized) { | |||
/* Finish initializing the EVP_CIPHER_CTX now that the direction is | |||
* known. */ | |||
if (!EVP_CipherInit_ex(&ssl3_ctx->cipher_ctx, NULL, NULL, ssl3_ctx->enc_key, | |||
ssl3_ctx->iv, encrypt)) { | |||
return 0; | |||
} | |||
ssl3_ctx->initialized = 1; | |||
} else if (ssl3_ctx->cipher_ctx.encrypt != encrypt) { | |||
/* Unlike a normal AEAD, using an SSL3 AEAD once freezes the direction. */ | |||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_ensure_cipher_init, | |||
CIPHER_R_INVALID_OPERATION); | |||
return 0; | |||
} | |||
return 1; | |||
} | |||
static int aead_ssl3_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
size_t *out_len, size_t max_out_len, | |||
const uint8_t *nonce, size_t nonce_len, | |||
@@ -175,6 +130,12 @@ static int aead_ssl3_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state; | |||
size_t total = 0; | |||
if (!ssl3_ctx->cipher_ctx.encrypt) { | |||
/* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */ | |||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_INVALID_OPERATION); | |||
return 0; | |||
} | |||
if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len || | |||
in_len > INT_MAX) { | |||
/* EVP_CIPHER takes int as input. */ | |||
@@ -197,10 +158,6 @@ static int aead_ssl3_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
return 0; | |||
} | |||
if (!aead_ssl3_ensure_cipher_init(ssl3_ctx, 1)) { | |||
return 0; | |||
} | |||
/* Compute the MAC. This must be first in case the operation is being done | |||
* in-place. */ | |||
uint8_t mac[EVP_MAX_MD_SIZE]; | |||
@@ -257,6 +214,12 @@ static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
const uint8_t *ad, size_t ad_len) { | |||
AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state; | |||
if (ssl3_ctx->cipher_ctx.encrypt) { | |||
/* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */ | |||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_INVALID_OPERATION); | |||
return 0; | |||
} | |||
size_t mac_len = EVP_MD_CTX_size(&ssl3_ctx->md_ctx); | |||
if (in_len < mac_len) { | |||
OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT); | |||
@@ -286,10 +249,6 @@ static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
return 0; | |||
} | |||
if (!aead_ssl3_ensure_cipher_init(ssl3_ctx, 0)) { | |||
return 0; | |||
} | |||
/* Decrypt to get the plaintext + MAC + padding. */ | |||
size_t total = 0; | |||
int len; | |||
@@ -338,30 +297,35 @@ static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
} | |||
static int aead_rc4_md5_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, | |||
size_t key_len, size_t tag_len) { | |||
return aead_ssl3_init(ctx, key, key_len, tag_len, EVP_rc4(), EVP_md5()); | |||
size_t key_len, size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_rc4(), EVP_md5()); | |||
} | |||
static int aead_rc4_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, | |||
size_t key_len, size_t tag_len) { | |||
return aead_ssl3_init(ctx, key, key_len, tag_len, EVP_rc4(), EVP_sha1()); | |||
size_t key_len, size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_rc4(), EVP_sha1()); | |||
} | |||
static int aead_aes_128_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, | |||
size_t key_len, size_t tag_len) { | |||
return aead_ssl3_init(ctx, key, key_len, tag_len, EVP_aes_128_cbc(), | |||
size_t key_len, size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), | |||
EVP_sha1()); | |||
} | |||
static int aead_aes_256_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, | |||
size_t key_len, size_t tag_len) { | |||
return aead_ssl3_init(ctx, key, key_len, tag_len, EVP_aes_256_cbc(), | |||
size_t key_len, size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), | |||
EVP_sha1()); | |||
} | |||
static int aead_des_ede3_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, | |||
const uint8_t *key, size_t key_len, | |||
size_t tag_len) { | |||
return aead_ssl3_init(ctx, key, key_len, tag_len, EVP_des_ede3_cbc(), | |||
const uint8_t *key, size_t key_len, | |||
size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(), | |||
EVP_sha1()); | |||
} | |||
@@ -370,6 +334,7 @@ static const EVP_AEAD aead_rc4_md5_ssl3 = { | |||
0, /* nonce len */ | |||
MD5_DIGEST_LENGTH, /* overhead */ | |||
MD5_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_rc4_md5_ssl3_init, | |||
aead_ssl3_cleanup, | |||
aead_ssl3_seal, | |||
@@ -381,6 +346,7 @@ static const EVP_AEAD aead_rc4_sha1_ssl3 = { | |||
0, /* nonce len */ | |||
SHA_DIGEST_LENGTH, /* overhead */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_rc4_sha1_ssl3_init, | |||
aead_ssl3_cleanup, | |||
aead_ssl3_seal, | |||
@@ -392,6 +358,7 @@ static const EVP_AEAD aead_aes_128_cbc_sha1_ssl3 = { | |||
0, /* nonce len */ | |||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_aes_128_cbc_sha1_ssl3_init, | |||
aead_ssl3_cleanup, | |||
aead_ssl3_seal, | |||
@@ -403,6 +370,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha1_ssl3 = { | |||
0, /* nonce len */ | |||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_aes_256_cbc_sha1_ssl3_init, | |||
aead_ssl3_cleanup, | |||
aead_ssl3_seal, | |||
@@ -414,6 +382,7 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_ssl3 = { | |||
0, /* nonce len */ | |||
8 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_des_ede3_cbc_sha1_ssl3_init, | |||
aead_ssl3_cleanup, | |||
aead_ssl3_seal, | |||
@@ -22,6 +22,7 @@ | |||
#include <openssl/hmac.h> | |||
#include <openssl/mem.h> | |||
#include <openssl/sha.h> | |||
#include <openssl/type_check.h> | |||
#include "../crypto/internal.h" | |||
#include "internal.h" | |||
@@ -34,37 +35,26 @@ typedef struct { | |||
* separately for the constant-time CBC code. */ | |||
uint8_t mac_key[EVP_MAX_MD_SIZE]; | |||
uint8_t mac_key_len; | |||
/* enc_key is the portion of the key used for the stream or block | |||
* cipher. It is retained separately to allow the EVP_CIPHER_CTX to be | |||
* initialized once the direction is known. */ | |||
uint8_t enc_key[EVP_MAX_KEY_LENGTH]; | |||
uint8_t enc_key_len; | |||
/* iv is the portion of the key used for the fixed IV. It is retained | |||
* separately to allow the EVP_CIPHER_CTX to be initialized once the direction | |||
* is known. */ | |||
uint8_t iv[EVP_MAX_IV_LENGTH]; | |||
uint8_t iv_len; | |||
/* implicit_iv is one iff this is a pre-TLS-1.1 CBC cipher without an explicit | |||
* IV. */ | |||
char implicit_iv; | |||
char initialized; | |||
} AEAD_TLS_CTX; | |||
OPENSSL_COMPILE_ASSERT(EVP_MAX_MD_SIZE < 256, mac_key_len_fits_in_uint8_t); | |||
static void aead_tls_cleanup(EVP_AEAD_CTX *ctx) { | |||
AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state; | |||
EVP_CIPHER_CTX_cleanup(&tls_ctx->cipher_ctx); | |||
HMAC_CTX_cleanup(&tls_ctx->hmac_ctx); | |||
OPENSSL_cleanse(&tls_ctx->mac_key, sizeof(tls_ctx->mac_key)); | |||
OPENSSL_cleanse(&tls_ctx->enc_key, sizeof(tls_ctx->enc_key)); | |||
OPENSSL_cleanse(&tls_ctx->iv, sizeof(tls_ctx->iv)); | |||
OPENSSL_free(tls_ctx); | |||
ctx->aead_state = NULL; | |||
} | |||
static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, | |||
size_t tag_len, const EVP_CIPHER *cipher, | |||
const EVP_MD *md, char implicit_iv) { | |||
size_t tag_len, enum evp_aead_direction_t dir, | |||
const EVP_CIPHER *cipher, const EVP_MD *md, | |||
char implicit_iv) { | |||
if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH && | |||
tag_len != EVP_MD_size(md)) { | |||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, CIPHER_R_UNSUPPORTED_TAG_SIZE); | |||
@@ -78,11 +68,8 @@ static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, | |||
size_t mac_key_len = EVP_MD_size(md); | |||
size_t enc_key_len = EVP_CIPHER_key_length(cipher); | |||
size_t iv_len = implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0; | |||
assert(mac_key_len + enc_key_len + iv_len == key_len); | |||
assert(mac_key_len < 256); | |||
assert(enc_key_len < 256); | |||
assert(iv_len < 256); | |||
assert(mac_key_len + enc_key_len + | |||
(implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0) == key_len); | |||
/* Although EVP_rc4() is a variable-length cipher, the default key size is | |||
* correct for TLS. */ | |||
@@ -93,17 +80,15 @@ static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, | |||
} | |||
EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx); | |||
HMAC_CTX_init(&tls_ctx->hmac_ctx); | |||
assert(mac_key_len <= EVP_MAX_MD_SIZE); | |||
memcpy(tls_ctx->mac_key, key, mac_key_len); | |||
tls_ctx->mac_key_len = (uint8_t)mac_key_len; | |||
memcpy(tls_ctx->enc_key, &key[mac_key_len], enc_key_len); | |||
tls_ctx->enc_key_len = (uint8_t)enc_key_len; | |||
memcpy(tls_ctx->iv, &key[mac_key_len + enc_key_len], iv_len); | |||
tls_ctx->iv_len = (uint8_t)iv_len; | |||
tls_ctx->implicit_iv = implicit_iv; | |||
tls_ctx->initialized = 0; | |||
ctx->aead_state = tls_ctx; | |||
if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, cipher, NULL, NULL, NULL, 0) || | |||
if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len], | |||
implicit_iv ? &key[mac_key_len + enc_key_len] : NULL, | |||
dir == evp_aead_seal) || | |||
!HMAC_Init_ex(&tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) { | |||
aead_tls_cleanup(ctx); | |||
return 0; | |||
@@ -113,32 +98,6 @@ static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, | |||
return 1; | |||
} | |||
/* aead_tls_ensure_cipher_init initializes |tls_ctx| for encryption (or | |||
* decryption, if |encrypt| is zero). If it has already been initialized, it | |||
* ensures the direction matches and fails otherwise. It returns one on success | |||
* and zero on failure. | |||
* | |||
* Note that, unlike normal AEADs, legacy TLS AEADs may not be used concurrently | |||
* due to this (and bulk-cipher-internal) statefulness. */ | |||
static int aead_tls_ensure_cipher_init(AEAD_TLS_CTX *tls_ctx, int encrypt) { | |||
if (!tls_ctx->initialized) { | |||
/* Finish initializing the EVP_CIPHER_CTX now that the direction is | |||
* known. */ | |||
if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, tls_ctx->enc_key, | |||
tls_ctx->implicit_iv ? tls_ctx->iv : NULL, | |||
encrypt)) { | |||
return 0; | |||
} | |||
tls_ctx->initialized = 1; | |||
} else if (tls_ctx->cipher_ctx.encrypt != encrypt) { | |||
/* Unlike a normal AEAD, using a TLS AEAD once freezes the direction. */ | |||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_ensure_cipher_init, | |||
CIPHER_R_INVALID_OPERATION); | |||
return 0; | |||
} | |||
return 1; | |||
} | |||
static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
size_t *out_len, size_t max_out_len, | |||
const uint8_t *nonce, size_t nonce_len, | |||
@@ -147,6 +106,13 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state; | |||
size_t total = 0; | |||
if (!tls_ctx->cipher_ctx.encrypt) { | |||
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */ | |||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_OPERATION); | |||
return 0; | |||
} | |||
if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len || | |||
in_len > INT_MAX) { | |||
/* EVP_CIPHER takes int as input. */ | |||
@@ -169,10 +135,6 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
return 0; | |||
} | |||
if (!aead_tls_ensure_cipher_init(tls_ctx, 1)) { | |||
return 0; | |||
} | |||
/* To allow for CBC mode which changes cipher length, |ad| doesn't include the | |||
* length for legacy ciphers. */ | |||
uint8_t ad_extra[2]; | |||
@@ -249,6 +211,13 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
const uint8_t *ad, size_t ad_len) { | |||
AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state; | |||
if (tls_ctx->cipher_ctx.encrypt) { | |||
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */ | |||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_OPERATION); | |||
return 0; | |||
} | |||
if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) { | |||
OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT); | |||
return 0; | |||
@@ -277,10 +246,6 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
return 0; | |||
} | |||
if (!aead_tls_ensure_cipher_init(tls_ctx, 0)) { | |||
return 0; | |||
} | |||
/* Configure the explicit IV. */ | |||
if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && | |||
!tls_ctx->implicit_iv && | |||
@@ -394,71 +359,76 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, | |||
} | |||
static int aead_rc4_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, | |||
size_t key_len, size_t tag_len) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_rc4(), EVP_sha1(), 0); | |||
size_t key_len, size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_rc4(), EVP_sha1(), | |||
0); | |||
} | |||
static int aead_aes_128_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, | |||
size_t key_len, size_t tag_len) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_128_cbc(), | |||
size_t key_len, size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), | |||
EVP_sha1(), 0); | |||
} | |||
static int aead_aes_128_cbc_sha1_tls_implicit_iv_init(EVP_AEAD_CTX *ctx, | |||
const uint8_t *key, | |||
size_t key_len, | |||
size_t tag_len) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_128_cbc(), | |||
static int aead_aes_128_cbc_sha1_tls_implicit_iv_init( | |||
EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), | |||
EVP_sha1(), 1); | |||
} | |||
static int aead_aes_128_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx, | |||
const uint8_t *key, size_t key_len, | |||
size_t tag_len) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_128_cbc(), | |||
size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), | |||
EVP_sha256(), 0); | |||
} | |||
static int aead_aes_256_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, | |||
size_t key_len, size_t tag_len) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_256_cbc(), | |||
size_t key_len, size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), | |||
EVP_sha1(), 0); | |||
} | |||
static int aead_aes_256_cbc_sha1_tls_implicit_iv_init(EVP_AEAD_CTX *ctx, | |||
const uint8_t *key, | |||
size_t key_len, | |||
size_t tag_len) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_256_cbc(), | |||
static int aead_aes_256_cbc_sha1_tls_implicit_iv_init( | |||
EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), | |||
EVP_sha1(), 1); | |||
} | |||
static int aead_aes_256_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx, | |||
const uint8_t *key, size_t key_len, | |||
size_t tag_len) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_256_cbc(), | |||
size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), | |||
EVP_sha256(), 0); | |||
} | |||
static int aead_aes_256_cbc_sha384_tls_init(EVP_AEAD_CTX *ctx, | |||
const uint8_t *key, size_t key_len, | |||
size_t tag_len) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_aes_256_cbc(), | |||
size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), | |||
EVP_sha384(), 0); | |||
} | |||
static int aead_des_ede3_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, | |||
const uint8_t *key, size_t key_len, | |||
size_t tag_len) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_des_ede3_cbc(), | |||
size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(), | |||
EVP_sha1(), 0); | |||
} | |||
static int aead_des_ede3_cbc_sha1_tls_implicit_iv_init(EVP_AEAD_CTX *ctx, | |||
const uint8_t *key, | |||
size_t key_len, | |||
size_t tag_len) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, EVP_des_ede3_cbc(), | |||
static int aead_des_ede3_cbc_sha1_tls_implicit_iv_init( | |||
EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, | |||
enum evp_aead_direction_t dir) { | |||
return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(), | |||
EVP_sha1(), 1); | |||
} | |||
@@ -467,6 +437,7 @@ static const EVP_AEAD aead_rc4_sha1_tls = { | |||
0, /* nonce len */ | |||
SHA_DIGEST_LENGTH, /* overhead */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_rc4_sha1_tls_init, | |||
aead_tls_cleanup, | |||
aead_tls_seal, | |||
@@ -478,6 +449,7 @@ static const EVP_AEAD aead_aes_128_cbc_sha1_tls = { | |||
16, /* nonce len (IV) */ | |||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_aes_128_cbc_sha1_tls_init, | |||
aead_tls_cleanup, | |||
aead_tls_seal, | |||
@@ -489,6 +461,7 @@ static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = { | |||
0, /* nonce len */ | |||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_aes_128_cbc_sha1_tls_implicit_iv_init, | |||
aead_tls_cleanup, | |||
aead_tls_seal, | |||
@@ -500,6 +473,7 @@ static const EVP_AEAD aead_aes_128_cbc_sha256_tls = { | |||
16, /* nonce len (IV) */ | |||
16 + SHA256_DIGEST_LENGTH, /* overhead (padding + SHA256) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_aes_128_cbc_sha256_tls_init, | |||
aead_tls_cleanup, | |||
aead_tls_seal, | |||
@@ -511,6 +485,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha1_tls = { | |||
16, /* nonce len (IV) */ | |||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_aes_256_cbc_sha1_tls_init, | |||
aead_tls_cleanup, | |||
aead_tls_seal, | |||
@@ -522,6 +497,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha1_tls_implicit_iv = { | |||
0, /* nonce len */ | |||
16 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_aes_256_cbc_sha1_tls_implicit_iv_init, | |||
aead_tls_cleanup, | |||
aead_tls_seal, | |||
@@ -533,6 +509,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha256_tls = { | |||
16, /* nonce len (IV) */ | |||
16 + SHA256_DIGEST_LENGTH, /* overhead (padding + SHA256) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_aes_256_cbc_sha256_tls_init, | |||
aead_tls_cleanup, | |||
aead_tls_seal, | |||
@@ -544,6 +521,7 @@ static const EVP_AEAD aead_aes_256_cbc_sha384_tls = { | |||
16, /* nonce len (IV) */ | |||
16 + SHA384_DIGEST_LENGTH, /* overhead (padding + SHA384) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_aes_256_cbc_sha384_tls_init, | |||
aead_tls_cleanup, | |||
aead_tls_seal, | |||
@@ -555,6 +533,7 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_tls = { | |||
8, /* nonce len (IV) */ | |||
8 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_des_ede3_cbc_sha1_tls_init, | |||
aead_tls_cleanup, | |||
aead_tls_seal, | |||
@@ -566,6 +545,7 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = { | |||
0, /* nonce len */ | |||
8 + SHA_DIGEST_LENGTH, /* overhead (padding + SHA1) */ | |||
SHA_DIGEST_LENGTH, /* max tag length */ | |||
NULL, /* init */ | |||
aead_des_ede3_cbc_sha1_tls_implicit_iv_init, | |||
aead_tls_cleanup, | |||
aead_tls_seal, | |||
@@ -59,6 +59,7 @@ | |||
#include <openssl/base.h> | |||
#include <openssl/aead.h> | |||
#include <openssl/asn1t.h> | |||
#if defined(__cplusplus) | |||
@@ -117,6 +118,9 @@ struct evp_aead_st { | |||
int (*init)(struct evp_aead_ctx_st *, const uint8_t *key, | |||
size_t key_len, size_t tag_len); | |||
int (*init_with_direction)(struct evp_aead_ctx_st *, const uint8_t *key, | |||
size_t key_len, size_t tag_len, | |||
enum evp_aead_direction_t dir); | |||
void (*cleanup)(struct evp_aead_ctx_st *); | |||
int (*seal)(const struct evp_aead_ctx_st *ctx, uint8_t *out, | |||
@@ -1,4 +1,5 @@ | |||
CIPHER,function,100,EVP_AEAD_CTX_init | |||
CIPHER,function,131,EVP_AEAD_CTX_init_with_direction | |||
CIPHER,function,101,EVP_AEAD_CTX_open | |||
CIPHER,function,102,EVP_AEAD_CTX_seal | |||
CIPHER,function,103,EVP_CIPHER_CTX_copy | |||
@@ -44,6 +45,7 @@ CIPHER,reason,111,INVALID_NONCE_SIZE | |||
CIPHER,reason,112,INVALID_OPERATION | |||
CIPHER,reason,113,IV_TOO_LARGE | |||
CIPHER,reason,114,NO_CIPHER_SET | |||
CIPHER,reason,124,NO_DIRECTION_SET | |||
CIPHER,reason,115,OUTPUT_ALIASES_INPUT | |||
CIPHER,reason,116,TAG_TOO_LARGE | |||
CIPHER,reason,117,TOO_LARGE | |||
@@ -205,7 +205,13 @@ typedef struct evp_aead_ctx_st { | |||
* be used. */ | |||
#define EVP_AEAD_DEFAULT_TAG_LENGTH 0 | |||
/* EVP_AEAD_init initializes |ctx| for the given AEAD algorithm from |impl|. | |||
/* evp_aead_direction_t denotes the direction of an AEAD operation. */ | |||
enum evp_aead_direction_t { | |||
evp_aead_open, | |||
evp_aead_seal, | |||
}; | |||
/* EVP_AEAD_CTX_init initializes |ctx| for the given AEAD algorithm from |impl|. | |||
* The |impl| argument may be NULL to choose the default implementation. | |||
* Authentication tags may be truncated by passing a size as |tag_len|. A | |||
* |tag_len| of zero indicates the default tag length and this is defined as | |||
@@ -215,6 +221,13 @@ OPENSSL_EXPORT int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, | |||
const uint8_t *key, size_t key_len, | |||
size_t tag_len, ENGINE *impl); | |||
/* EVP_AEAD_CTX_init_with_direction calls |EVP_AEAD_CTX_init| for normal | |||
* AEADs. For TLS-specific and SSL3-specific AEADs, it initializes |ctx| for a | |||
* given direction. */ | |||
OPENSSL_EXPORT int EVP_AEAD_CTX_init_with_direction( | |||
EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, const uint8_t *key, size_t key_len, | |||
size_t tag_len, enum evp_aead_direction_t dir); | |||
/* EVP_AEAD_CTX_cleanup frees any data allocated by |ctx|. */ | |||
OPENSSL_EXPORT void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx); | |||
@@ -530,6 +530,7 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_cbc(void); | |||
#define CIPHER_F_aead_tls_seal 128 | |||
#define CIPHER_F_aes_init_key 129 | |||
#define CIPHER_F_aesni_init_key 130 | |||
#define CIPHER_F_EVP_AEAD_CTX_init_with_direction 131 | |||
#define CIPHER_R_AES_KEY_SETUP_FAILED 100 | |||
#define CIPHER_R_BAD_DECRYPT 101 | |||
#define CIPHER_R_BAD_KEY_LENGTH 102 | |||
@@ -554,5 +555,6 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_cbc(void); | |||
#define CIPHER_R_UNSUPPORTED_NONCE_SIZE 121 | |||
#define CIPHER_R_UNSUPPORTED_TAG_SIZE 122 | |||
#define CIPHER_R_WRONG_FINAL_BLOCK_LENGTH 123 | |||
#define CIPHER_R_NO_DIRECTION_SET 124 | |||
#endif /* OPENSSL_HEADER_CIPHER_H */ |
@@ -353,8 +353,9 @@ static int tls1_change_cipher_state_aead(SSL *s, char is_read, | |||
aead_ctx = s->aead_write_ctx; | |||
} | |||
if (!EVP_AEAD_CTX_init(&aead_ctx->ctx, aead, key, key_len, | |||
EVP_AEAD_DEFAULT_TAG_LENGTH, NULL /* engine */)) { | |||
if (!EVP_AEAD_CTX_init_with_direction( | |||
&aead_ctx->ctx, aead, key, key_len, EVP_AEAD_DEFAULT_TAG_LENGTH, | |||
is_read ? evp_aead_open : evp_aead_seal)) { | |||
OPENSSL_free(aead_ctx); | |||
if (is_read) { | |||
s->aead_read_ctx = NULL; | |||