aesni: Fix memory leak on failed ICV verification if not using in-place decryption
The `aead_t` interface states that `decrypt()` only allocates a plaintext
buffer if successful, so callers might not free it if the call failed.
Fixes: 313811b72d ("aesni: Add a GCM AEAD based on the AES-NI key schedule")
This commit is contained in:
@@ -760,6 +760,7 @@ METHOD(aead_t, decrypt, bool,
|
|||||||
chunk_t *plain)
|
chunk_t *plain)
|
||||||
{
|
{
|
||||||
u_char *out, icv[this->icv_size];
|
u_char *out, icv[this->icv_size];
|
||||||
|
bool valid;
|
||||||
|
|
||||||
if (!this->key || iv.len != IV_SIZE || encr.len < this->icv_size)
|
if (!this->key || iv.len != IV_SIZE || encr.len < this->icv_size)
|
||||||
{
|
{
|
||||||
@@ -772,10 +773,14 @@ METHOD(aead_t, decrypt, bool,
|
|||||||
*plain = chunk_alloc(encr.len);
|
*plain = chunk_alloc(encr.len);
|
||||||
out = plain->ptr;
|
out = plain->ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->decrypt(this, encr.len, encr.ptr, out, iv.ptr,
|
this->decrypt(this, encr.len, encr.ptr, out, iv.ptr,
|
||||||
assoc.len, assoc.ptr, icv);
|
assoc.len, assoc.ptr, icv);
|
||||||
return memeq_const(icv, encr.ptr + encr.len, this->icv_size);
|
valid = memeq_const(icv, encr.ptr + encr.len, this->icv_size);
|
||||||
|
if (!valid && plain)
|
||||||
|
{
|
||||||
|
chunk_free(plain);
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(aead_t, get_block_size, size_t,
|
METHOD(aead_t, get_block_size, size_t,
|
||||||
|
|||||||
@@ -1268,6 +1268,7 @@ METHOD(aead_t, decrypt, bool,
|
|||||||
chunk_t *plain)
|
chunk_t *plain)
|
||||||
{
|
{
|
||||||
u_char *out, icv[this->icv_size];
|
u_char *out, icv[this->icv_size];
|
||||||
|
bool valid;
|
||||||
|
|
||||||
if (!this->key || iv.len != IV_SIZE || encr.len < this->icv_size)
|
if (!this->key || iv.len != IV_SIZE || encr.len < this->icv_size)
|
||||||
{
|
{
|
||||||
@@ -1282,7 +1283,12 @@ METHOD(aead_t, decrypt, bool,
|
|||||||
}
|
}
|
||||||
this->decrypt(this, encr.len, encr.ptr, out, iv.ptr,
|
this->decrypt(this, encr.len, encr.ptr, out, iv.ptr,
|
||||||
assoc.len, assoc.ptr, icv);
|
assoc.len, assoc.ptr, icv);
|
||||||
return memeq_const(icv, encr.ptr + encr.len, this->icv_size);
|
valid = memeq_const(icv, encr.ptr + encr.len, this->icv_size);
|
||||||
|
if (!valid && plain)
|
||||||
|
{
|
||||||
|
chunk_free(plain);
|
||||||
|
}
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(aead_t, get_block_size, size_t,
|
METHOD(aead_t, get_block_size, size_t,
|
||||||
|
|||||||
Reference in New Issue
Block a user