The various implementations of EVP_CTRL_AEAD_TLS_AAD expect a buffer of at
least 13 bytes long. Add sanity checks to ensure that the length is at
least that. Also add a new constant (EVP_AEAD_TLS1_AAD_LEN) to evp.h to
represent this length. Thanks to Kevin Wojtysiak (Int3 Solutions) and
Paramjot Oberoi (Int3 Solutions) for reporting this issue.
Reviewed-by: Andy Polyakov <appro@openssl.org>
(cherry picked from commit
c8269881093324b881b81472be037055571f73f3)
Conflicts:
ssl/record/ssl3_record.c
print_message(alg_name, 0, mblengths[j]);
Time_F(START);
for (count = 0, run = 1; run && count < 0x7fffffff; count++) {
- unsigned char aad[13];
+ unsigned char aad[EVP_AEAD_TLS1_AAD_LEN];
EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param;
size_t len = mblengths[j];
int packlen;
aad[11] = len >> 8;
aad[12] = len;
pad = EVP_CIPHER_CTX_ctrl(&ctx,
- EVP_CTRL_AEAD_TLS1_AAD, 13, aad);
+ EVP_CTRL_AEAD_TLS1_AAD,
+ EVP_AEAD_TLS1_AAD_LEN, aad);
EVP_Cipher(&ctx, out, inp, len + pad);
}
}
case EVP_CTRL_AEAD_TLS1_AAD:
/* Save the AAD for later use */
- if (arg != 13)
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
return 0;
memcpy(c->buf, ptr, arg);
gctx->tls_aad_len = arg;
case EVP_CTRL_AEAD_TLS1_AAD:
{
unsigned char *p = ptr;
- unsigned int len = p[arg - 2] << 8 | p[arg - 1];
+ unsigned int len;
+
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
+ return -1;
+
+ len = p[arg - 2] << 8 | p[arg - 1];
if (ctx->encrypt) {
key->payload_length = len;
AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
- len);
} else {
- if (arg > 13)
- arg = 13;
memcpy(key->aux.tls_aad, ptr, arg);
key->payload_length = arg;
unsigned char *p = ptr;
unsigned int len = p[arg - 2] << 8 | p[arg - 1];
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
+ return -1;
+
+ len = p[arg - 2] << 8 | p[arg - 1];
+
if (ctx->encrypt) {
key->payload_length = len;
if ((key->aux.tls_ver =
AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)
- len);
} else {
- if (arg > 13)
- arg = 13;
memcpy(key->aux.tls_aad, ptr, arg);
key->payload_length = arg;
case EVP_CTRL_AEAD_TLS1_AAD:
{
unsigned char *p = ptr;
- unsigned int len = p[arg - 2] << 8 | p[arg - 1];
+ unsigned int len;
+
+ if (arg != EVP_AEAD_TLS1_AAD_LEN)
+ return -1;
+
+ len = p[arg - 2] << 8 | p[arg - 1];
if (!ctx->encrypt) {
len -= MD5_DIGEST_LENGTH;
# define EVP_CTRL_TLS1_1_MULTIBLOCK_DECRYPT 0x1b
# define EVP_CTRL_TLS1_1_MULTIBLOCK_MAX_BUFSIZE 0x1c
+/* RFC 5246 defines additional data to be 13 bytes in length */
+# define EVP_AEAD_TLS1_AAD_LEN 13
+
typedef struct {
unsigned char *out;
const unsigned char *inp;
bs = EVP_CIPHER_block_size(ds->cipher);
if (EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) {
- unsigned char buf[13], *seq;
+ unsigned char buf[EVP_AEAD_TLS1_AAD_LEN], *seq;
seq = send ? s->s3->write_sequence : s->s3->read_sequence;
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);
+ pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD,
+ EVP_AEAD_TLS1_AAD_LEN, buf);
+ if (pad <= 0)
+ return -1;
if (send) {
l += pad;
rec->length += pad;