pem: Avoid integer underflow when verifying padding after decryption
If the padding was larger than the whole blob, all available bytes were
checked for a match and the blob's length was eventually adjusted and
SUCCESS returned. Due to the underflow this could result in a huge size
that would then get copied. Zero-length padding was also incorrectly
accepted as was padding larger than the block size.
Fixes: 160f4c225d ("moved PEM parsing functionality to its own plugin")
This commit is contained in:
@@ -95,6 +95,7 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg,
|
||||
chunk_t decrypted;
|
||||
chunk_t key = {alloca(key_size), key_size};
|
||||
uint8_t padding, *last_padding_pos, *first_padding_pos;
|
||||
size_t block_size;
|
||||
|
||||
if (!key_size)
|
||||
{
|
||||
@@ -141,8 +142,8 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg,
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (iv.len != crypter->get_iv_size(crypter) ||
|
||||
blob->len % crypter->get_block_size(crypter))
|
||||
block_size = crypter->get_block_size(crypter);
|
||||
if (iv.len != crypter->get_iv_size(crypter) || blob->len % block_size)
|
||||
{
|
||||
DBG1(DBG_ASN, " data size is not multiple of block size");
|
||||
crypter->destroy(crypter);
|
||||
@@ -164,14 +165,12 @@ static status_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg,
|
||||
/* determine amount of padding */
|
||||
last_padding_pos = blob->ptr + blob->len - 1;
|
||||
padding = *last_padding_pos;
|
||||
if (padding > blob->len)
|
||||
if (!padding || padding > block_size)
|
||||
{
|
||||
first_padding_pos = blob->ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_padding_pos = last_padding_pos - padding;
|
||||
DBG1(DBG_ASN, " invalid passphrase");
|
||||
return INVALID_ARG;
|
||||
}
|
||||
first_padding_pos = last_padding_pos - padding;
|
||||
/* check the padding pattern */
|
||||
while (--last_padding_pos > first_padding_pos)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user