diff --git a/include/axolotl/crypto.hh b/include/axolotl/crypto.hh index c8113c5..42c154b 100644 --- a/include/axolotl/crypto.hh +++ b/include/axolotl/crypto.hh @@ -42,17 +42,11 @@ struct Aes256Iv { }; -std::size_t aes_pkcs_7_padded_length( +std::size_t aes_encrypt_cbc_length( std::size_t input_length ); -void aes_pkcs_7_padding( - std::uint8_t const * input, std::size_t input_length, - std::uint8_t * output -); - - void aes_encrypt_cbc( Aes256Key const & key, Aes256Iv const & iv, @@ -61,7 +55,7 @@ void aes_encrypt_cbc( ); -void aes_decrypt_cbc( +std::size_t aes_decrypt_cbc( Aes256Key const & key, Aes256Iv const & iv, std::uint8_t const * input, std::size_t input_length, diff --git a/include/axolotl/list.hh b/include/axolotl/list.hh index b76abdd..ae41baa 100644 --- a/include/axolotl/list.hh +++ b/include/axolotl/list.hh @@ -15,6 +15,11 @@ public: T const * begin() const { return _data; } T const * end() const { return _end; } + /** + * Is the list empty? + */ + bool empty() { return _end == _data; } + /** * The number of items in the list. */ diff --git a/src/crypto.cpp b/src/crypto.cpp index 5277b86..e93a1e9 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -107,26 +107,13 @@ void axolotl::curve25519_shared_secret( } -std::size_t axolotl::aes_pkcs_7_padded_length( +std::size_t axolotl::aes_encrypt_cbc_length( std::size_t input_length ) { return input_length + AES_BLOCK_LENGTH - input_length % AES_BLOCK_LENGTH; } -void axolotl::aes_pkcs_7_padding( - std::uint8_t const * input, std::size_t input_length, - std::uint8_t * output -) { - std::memcpy(output, input, input_length); - std::size_t padded_length = axolotl::aes_pkcs_7_padded_length(input_length); - std::uint8_t padding = padded_length - input_length; - for (std::size_t i = input_length; i < padded_length; ++i) { - output[i] = padding; - } -} - - void axolotl::aes_encrypt_cbc( axolotl::Aes256Key const & key, axolotl::Aes256Iv const & iv, @@ -137,17 +124,28 @@ void axolotl::aes_encrypt_cbc( ::aes_key_setup(key.key, key_schedule, 256); std::uint8_t input_block[AES_BLOCK_LENGTH]; std::memcpy(input_block, iv.iv, AES_BLOCK_LENGTH); - for (std::size_t i = 0; i < input_length; i += AES_BLOCK_LENGTH) { - xor_block(input_block, &input[i]); - ::aes_encrypt(input_block, &output[i], key_schedule, 256); - std::memcpy(input_block, &output[i], AES_BLOCK_LENGTH); + while (input_length >= AES_BLOCK_LENGTH) { + xor_block(input_block, input); + ::aes_encrypt(input_block, output, key_schedule, 256); + std::memcpy(input_block, output, AES_BLOCK_LENGTH); + input += AES_BLOCK_LENGTH; + output += AES_BLOCK_LENGTH; + input_length -= AES_BLOCK_LENGTH; } + std::size_t i = 0; + for (; i < input_length; ++i) { + input_block[i] ^= input[i]; + } + for (; i < AES_BLOCK_LENGTH; ++i) { + input_block[i] ^= AES_BLOCK_LENGTH - input_length; + } + ::aes_encrypt(input_block, output, key_schedule, 256); std::memset(key_schedule, 0, sizeof(key_schedule)); std::memset(input_block, 0, sizeof(AES_BLOCK_LENGTH)); } -void axolotl::aes_decrypt_cbc( +std::size_t axolotl::aes_decrypt_cbc( axolotl::Aes256Key const & key, axolotl::Aes256Iv const & iv, std::uint8_t const * input, std::size_t input_length, @@ -164,6 +162,8 @@ void axolotl::aes_decrypt_cbc( } } std::memset(key_schedule, 0, sizeof(key_schedule)); + std::size_t padding = output[input_length - 1]; + return (padding > input_length) ? std::size_t(-1) : (input_length - padding); } diff --git a/tests/test_crypto.cpp b/tests/test_crypto.cpp index 78bb738..1838132 100644 --- a/tests/test_crypto.cpp +++ b/tests/test_crypto.cpp @@ -73,24 +73,27 @@ TestCase test_case("AES Test Case 1"); axolotl::Aes256Key key = {}; axolotl::Aes256Iv iv = {}; -std::uint8_t input[32] = {}; +std::uint8_t input[16] = {}; std::uint8_t expected[32] = { 0xDC, 0x95, 0xC0, 0x78, 0xA2, 0x40, 0x89, 0x89, 0xAD, 0x48, 0xA2, 0x14, 0x92, 0x84, 0x20, 0x87, - 0x08, 0xC3, 0x74, 0x84, 0x8C, 0x22, 0x82, 0x33, - 0xC2, 0xB3, 0x4F, 0x33, 0x2B, 0xD2, 0xE9, 0xD3 + 0xF3, 0xC0, 0x03, 0xDD, 0xC4, 0xA7, 0xB8, 0xA9, + 0x4B, 0xAE, 0xDF, 0xFC, 0x3D, 0x21, 0x4C, 0x38 }; +std::size_t length = axolotl::aes_encrypt_cbc_length(sizeof(input)); +assert_equals(std::size_t(32), length); + + std::uint8_t actual[32] = {}; axolotl::aes_encrypt_cbc(key, iv, input, sizeof(input), actual); - assert_equals(expected, actual, 32); -axolotl::aes_decrypt_cbc(key, iv, expected, sizeof(expected), actual); - -assert_equals(input, actual, 32); +length = axolotl::aes_decrypt_cbc(key, iv, expected, sizeof(expected), actual); +assert_equals(std::size_t(16), length); +assert_equals(input, actual, length); } /* AES Test Case 1 */