diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2015-06-10 17:57:41 +0300 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2015-06-10 17:57:41 +0300 |
commit | 84c7f952f01b53ee4be00899cf4e60d62f6bd5e7 (patch) | |
tree | 7c915e8e5d39a30b7de9b313031e09af5e7a943d /src | |
parent | utils: bugfix (diff) | |
download | aes-tools-84c7f952f01b53ee4be00899cf4e60d62f6bd5e7.tar.gz aes-tools-84c7f952f01b53ee4be00899cf4e60d62f6bd5e7.zip |
bugfix
Buffer decryption routine used to look at the last byte of the plaintext
to determine the padding size.
If used with a wrong key, the last byte could be, say, 0xff, which is
definitely not the right padding size.
Now it checks for proper padding at the end of the plaintext and drops
the last block if no valid padding was found.
Diffstat (limited to '')
-rw-r--r-- | src/buffer.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/src/buffer.c b/src/buffer.c index d8ff9c7..ff14f18 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -11,6 +11,8 @@ #include <stdlib.h> #include <string.h> +static unsigned char FULL_BLOCK_PADDING[16] = { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; + size_t aes128ecb_encrypt_buffer( const unsigned char* src, size_t src_size, @@ -33,9 +35,13 @@ size_t aes128ecb_encrypt_buffer( store_aes_block128(ciphertext, dest); } - unsigned char padding[16] = { 0x10 }; + unsigned char padding[16]; - if (rem_size != 0) + if (rem_size == 0) + { + memcpy(padding, FULL_BLOCK_PADDING, 16); + } + else { memcpy(padding, src, rem_size); memset(padding + rem_size, padding_size, padding_size); @@ -48,6 +54,18 @@ size_t aes128ecb_encrypt_buffer( return dest_size; } +static unsigned char get_padding_size(const unsigned char* padding) +{ + if (padding[15] < 0x01 || padding[15] > 0x10) + return 0; + + for (int i = 16 - padding[15]; i < 15; ++i) + if (padding[i] != padding[15]) + return 0; + + return padding[15]; +} + size_t aes128ecb_decrypt_buffer( const unsigned char* src, size_t src_size, @@ -73,9 +91,15 @@ size_t aes128ecb_decrypt_buffer( unsigned char padding[16]; store_aes_block128(plaintext, padding); - if (padding[0] == 0x10) - return dest_size - 16; + unsigned char padding_size = get_padding_size(padding); - memcpy(dest, padding, 16 - padding[15]); - return dest_size - padding[15]; + if (padding_size == 0) + { + return dest_size - 16; + } + else + { + memcpy(dest, padding, 16 - padding_size); + return dest_size - padding_size; + } } |