Merge "Remove references to AEAD in non-AEAD interface codepath"
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+9
-65
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user