From 508c29fec9ed975eaf001f45c0b6c51addb34bef Mon Sep 17 00:00:00 2001 From: Victor Vasiliev Date: Wed, 25 Jun 2014 11:19:26 -0400 Subject: [PATCH] Remove references to AEAD in non-AEAD interface codepath Since all AEAD ciphers now go through EVP_AEAD interface, the code which uses EVP_Cipher interface no longer needs any of AEAD handling logic. This also removes EVP_CTRL_AEAD_TLS1_AAD from GCM interface, which was duplicating non-TLS-specific GCM logic and is not used anymore. Change-Id: I5ddae880e7bc921337f9149a0acfdd00c9a478c3 --- crypto/cipher/cipher.h | 1 - crypto/cipher/e_aes.c | 125 ----------------------------------------- ssl/t1_enc.c | 74 +++--------------------- 3 files changed, 9 insertions(+), 191 deletions(-) diff --git a/crypto/cipher/cipher.h b/crypto/cipher/cipher.h index 5ce1d63e0..74f08efb7 100644 --- a/crypto/cipher/cipher.h +++ b/crypto/cipher/cipher.h @@ -346,7 +346,6 @@ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, #define EVP_CTRL_GCM_SET_TAG 0x11 #define EVP_CTRL_GCM_SET_IV_FIXED 0x12 #define EVP_CTRL_GCM_IV_GEN 0x13 -#define EVP_CTRL_AEAD_TLS1_AAD 0x16 #define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 /* Set the GCM invocation field, decrypt only */ #define EVP_CTRL_GCM_SET_IV_INV 0x18 diff --git a/crypto/cipher/e_aes.c b/crypto/cipher/e_aes.c index c88eb076f..741fd013f 100644 --- a/crypto/cipher/e_aes.c +++ b/crypto/cipher/e_aes.c @@ -84,7 +84,6 @@ typedef struct { int ivlen; /* IV length */ int taglen; int iv_gen; /* It is OK to generate IVs */ - int tls_aad_len; /* TLS AAD length */ ctr128_f ctr; } EVP_AES_GCM_CTX; @@ -399,7 +398,6 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { gctx->iv = c->iv; gctx->taglen = -1; gctx->iv_gen = 0; - gctx->tls_aad_len = -1; return 1; case EVP_CTRL_GCM_SET_IVLEN: @@ -482,131 +480,11 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { gctx->iv_set = 1; return 1; - case EVP_CTRL_AEAD_TLS1_AAD: - /* Save the AAD for later use */ - if (arg != 13) { - return 0; - } - memcpy(c->buf, ptr, arg); - gctx->tls_aad_len = arg; - { - unsigned int len = c->buf[arg - 2] << 8 | c->buf[arg - 1]; - /* Correct length for explicit IV */ - len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; - /* If decrypting correct for tag too */ - if (!c->encrypt) - len -= EVP_GCM_TLS_TAG_LEN; - c->buf[arg - 2] = len >> 8; - c->buf[arg - 1] = len & 0xff; - } - - /* Extra padding: tag appended to record */ - return EVP_GCM_TLS_TAG_LEN; - default: return -1; } } -/* Handle TLS GCM packet format. This consists of the last portion of the IV - * followed by the payload and finally the tag. On encrypt generate IV, encrypt - * payload and write the tag. On verify retrieve IV, decrypt payload and verify - * tag. */ -static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, - const uint8_t *in, size_t len) { - EVP_AES_GCM_CTX *gctx = ctx->cipher_data; - int rv = -1; - /* Encrypt/decrypt must be performed in place */ - if (out != in || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) { - return -1; - } - /* Set IV from start of buffer or generate IV and write to start - * of buffer. */ - if (EVP_CIPHER_CTX_ctrl( - ctx, ctx->encrypt ? EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, - EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) { - goto err; - } - /* Use saved AAD */ - if (!CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len)) { - goto err; - } - /* Fix buffer and length to point to payload */ - in += EVP_GCM_TLS_EXPLICIT_IV_LEN; - out += EVP_GCM_TLS_EXPLICIT_IV_LEN; - len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; - if (ctx->encrypt) { - /* Encrypt payload */ - if (gctx->ctr) { - size_t bulk = 0; -#if defined(AES_GCM_ASM) - if (len >= 32 && AES_GCM_ASM(gctx)) { - if (!CRYPTO_gcm128_encrypt(&gctx->gcm, NULL, NULL, 0)) { - return -1; - } - - bulk = AES_gcm_encrypt(in, out, len, gctx->gcm.key, gctx->gcm.Yi.c, - gctx->gcm.Xi.u); - gctx->gcm.len.u[1] += bulk; - } -#endif - if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, in + bulk, out + bulk, - len - bulk, gctx->ctr)) { - goto err; - } - } else { - size_t bulk = 0; - if (!CRYPTO_gcm128_encrypt(&gctx->gcm, in + bulk, out + bulk, - len - bulk)) { - goto err; - } - } - out += len; - /* Finally write tag */ - CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); - rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; - } else { - /* Decrypt */ - if (gctx->ctr) { - size_t bulk = 0; -#if defined(AES_GCM_ASM) - if (len >= 16 && AES_GCM_ASM(gctx)) { - if (!CRYPTO_gcm128_decrypt(&gctx->gcm, NULL, NULL, 0)) { - return -1; - } - - bulk = AES_gcm_decrypt(in, out, len, gctx->gcm.key, gctx->gcm.Yi.c, - gctx->gcm.Xi.u); - gctx->gcm.len.u[1] += bulk; - } -#endif - if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, in + bulk, out + bulk, - len - bulk, gctx->ctr)) { - goto err; - } - } else { - size_t bulk = 0; - if (!CRYPTO_gcm128_decrypt(&gctx->gcm, in + bulk, out + bulk, - len - bulk)) { - goto err; - } - } - /* Retrieve tag */ - CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN); - /* If tag mismatch wipe buffer */ - if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) { - OPENSSL_cleanse(out, len); - goto err; - } - rv = len; - } - -err: - gctx->iv_set = 0; - gctx->tls_aad_len = -1; - return rv; -} - static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, size_t len) { EVP_AES_GCM_CTX *gctx = ctx->cipher_data; @@ -615,9 +493,6 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, if (!gctx->key_set) { return -1; } - if (gctx->tls_aad_len >= 0) { - return aes_gcm_tls_cipher(ctx, out, in, len); - } if (!gctx->iv_set) { return -1; } diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index 9c168356d..bdc5ae9c9 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -388,7 +388,6 @@ static int tls1_change_cipher_state_cipher( const char is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) != 0; EVP_CIPHER_CTX *cipher_ctx; EVP_MD_CTX *mac_ctx; - char is_aead_cipher; unsigned char export_tmp1[EVP_MAX_KEY_LENGTH]; unsigned char export_tmp2[EVP_MAX_KEY_LENGTH]; @@ -502,34 +501,15 @@ static int tls1_change_cipher_state_cipher( } } - /* is_aead_cipher indicates whether the EVP_CIPHER implements an AEAD - * interface. This is different from the newer EVP_AEAD interface. */ - is_aead_cipher = (EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0; + EVP_PKEY *mac_key = + EVP_PKEY_new_mac_key(s->s3->tmp.new_mac_pkey_type, + NULL, mac_secret, mac_secret_len); + if (!mac_key) + return 0; + EVP_DigestSignInit(mac_ctx, NULL, s->s3->tmp.new_hash, NULL, mac_key); + EVP_PKEY_free(mac_key); - if (!is_aead_cipher) - { - EVP_PKEY *mac_key = - EVP_PKEY_new_mac_key(s->s3->tmp.new_mac_pkey_type, - NULL, mac_secret, mac_secret_len); - if (!mac_key) - return 0; - EVP_DigestSignInit(mac_ctx, NULL, s->s3->tmp.new_hash, NULL, mac_key); - EVP_PKEY_free(mac_key); - } - - if (EVP_CIPHER_mode(cipher) == EVP_CIPH_GCM_MODE) - { - EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, - NULL /* iv */, !is_read); - EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_GCM_SET_IV_FIXED, iv_len, (void*) iv); - } - else - EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, iv, !is_read); - - /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ - if (is_aead_cipher && mac_secret_len > 0) - EVP_CIPHER_CTX_ctrl(cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, - mac_secret_len, (void*) mac_secret); + EVP_CipherInit_ex(cipher_ctx, cipher, NULL /* engine */, key, iv, !is_read); if (is_export) { @@ -959,43 +939,7 @@ int tls1_enc(SSL *s, int send) l=rec->length; bs=EVP_CIPHER_block_size(ds->cipher); - if (EVP_CIPHER_flags(ds->cipher)&EVP_CIPH_FLAG_AEAD_CIPHER) - { - unsigned char buf[13],*seq; - - seq = send?s->s3->write_sequence:s->s3->read_sequence; - - if (SSL_IS_DTLS(s)) - { - unsigned char dtlsseq[9],*p=dtlsseq; - - s2n(send?s->d1->w_epoch:s->d1->r_epoch,p); - memcpy(p,&seq[2],6); - memcpy(buf,dtlsseq,8); - } - else - { - memcpy(buf,seq,8); - for (i=7; i>=0; i--) /* increment */ - { - ++seq[i]; - if (seq[i] != 0) break; - } - } - - buf[8]=rec->type; - buf[9]=(unsigned char)(s->version>>8); - buf[10]=(unsigned char)(s->version); - buf[11]=rec->length>>8; - buf[12]=rec->length&0xff; - pad=EVP_CIPHER_CTX_ctrl(ds,EVP_CTRL_AEAD_TLS1_AAD,13,buf); - if (send) - { - l+=pad; - rec->length+=pad; - } - } - else if ((bs != 1) && send) + if ((bs != 1) && send) { i=bs-((int)l%bs);