diff options
Diffstat (limited to 'Libraries/LibCrypto/Cipher/AES.cpp')
-rw-r--r-- | Libraries/LibCrypto/Cipher/AES.cpp | 398 |
1 files changed, 199 insertions, 199 deletions
diff --git a/Libraries/LibCrypto/Cipher/AES.cpp b/Libraries/LibCrypto/Cipher/AES.cpp index b1655fe357..adcb760260 100644 --- a/Libraries/LibCrypto/Cipher/AES.cpp +++ b/Libraries/LibCrypto/Cipher/AES.cpp @@ -30,165 +30,165 @@ namespace Crypto { namespace Cipher { - template <typename T> - constexpr u32 get_key(T pt) - { - return ((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]); - } +template<typename T> +constexpr u32 get_key(T pt) +{ + return ((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]); +} - constexpr void swap_keys(u32* keys, size_t i, size_t j) - { - u32 temp = keys[i]; - keys[i] = keys[j]; - keys[j] = temp; - } +constexpr void swap_keys(u32* keys, size_t i, size_t j) +{ + u32 temp = keys[i]; + keys[i] = keys[j]; + keys[j] = temp; +} - String AESCipherBlock::to_string() const - { - StringBuilder builder; - for (size_t i = 0; i < BLOCK_SIZE / 8; ++i) - builder.appendf("%02x", m_data[i]); - return builder.build(); - } +String AESCipherBlock::to_string() const +{ + StringBuilder builder; + for (size_t i = 0; i < BlockSizeInBits / 8; ++i) + builder.appendf("%02x", m_data[i]); + return builder.build(); +} - String AESCipherKey::to_string() const - { - StringBuilder builder; - for (size_t i = 0; i < (rounds() + 1) * 4; ++i) - builder.appendf("%02x", m_rd_keys[i]); - return builder.build(); - } +String AESCipherKey::to_string() const +{ + StringBuilder builder; + for (size_t i = 0; i < (rounds() + 1) * 4; ++i) + builder.appendf("%02x", m_rd_keys[i]); + return builder.build(); +} - void AESCipherKey::expand_encrypt_key(const ByteBuffer& user_key, size_t bits) - { - u32* round_key; - u32 temp; - size_t i { 0 }; +void AESCipherKey::expand_encrypt_key(const ByteBuffer& user_key, size_t bits) +{ + u32* round_key; + u32 temp; + size_t i { 0 }; - ASSERT(!user_key.is_null()); - ASSERT(is_valid_key_size(bits)); + ASSERT(!user_key.is_null()); + ASSERT(is_valid_key_size(bits)); - round_key = round_keys(); + round_key = round_keys(); - if (bits == 128) { - m_rounds = 10; - } else if (bits == 192) { - m_rounds = 12; - } else { - m_rounds = 14; - } + if (bits == 128) { + m_rounds = 10; + } else if (bits == 192) { + m_rounds = 12; + } else { + m_rounds = 14; + } - round_key[0] = get_key(user_key.slice_view(0, 4).data()); - round_key[1] = get_key(user_key.slice_view(4, 4).data()); - round_key[2] = get_key(user_key.slice_view(8, 4).data()); - round_key[3] = get_key(user_key.slice_view(12, 4).data()); - if (bits == 128) { - for (;;) { - temp = round_key[3]; - // clang-format off + round_key[0] = get_key(user_key.slice_view(0, 4).data()); + round_key[1] = get_key(user_key.slice_view(4, 4).data()); + round_key[2] = get_key(user_key.slice_view(8, 4).data()); + round_key[3] = get_key(user_key.slice_view(12, 4).data()); + if (bits == 128) { + for (;;) { + temp = round_key[3]; + // clang-format off round_key[4] = round_key[0] ^ (AESTables::Encode2[(temp >> 16) & 0xff] & 0xff000000) ^ (AESTables::Encode3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (AESTables::Encode0[(temp ) & 0xff] & 0x0000ff00) ^ (AESTables::Encode1[(temp >> 24) ] & 0x000000ff) ^ AESTables::RCON[i]; - // clang-format on - round_key[5] = round_key[1] ^ round_key[4]; - round_key[6] = round_key[2] ^ round_key[5]; - round_key[7] = round_key[3] ^ round_key[6]; - ++i; - if (i == 10) - break; - round_key += 4; - } - return; + // clang-format on + round_key[5] = round_key[1] ^ round_key[4]; + round_key[6] = round_key[2] ^ round_key[5]; + round_key[7] = round_key[3] ^ round_key[6]; + ++i; + if (i == 10) + break; + round_key += 4; } + return; + } - round_key[4] = get_key(user_key.slice_view(16, 4).data()); - round_key[5] = get_key(user_key.slice_view(20, 4).data()); - if (bits == 192) { - for (;;) { - temp = round_key[5]; - // clang-format off + round_key[4] = get_key(user_key.slice_view(16, 4).data()); + round_key[5] = get_key(user_key.slice_view(20, 4).data()); + if (bits == 192) { + for (;;) { + temp = round_key[5]; + // clang-format off round_key[6] = round_key[0] ^ (AESTables::Encode2[(temp >> 16) & 0xff] & 0xff000000) ^ (AESTables::Encode3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (AESTables::Encode0[(temp ) & 0xff] & 0x0000ff00) ^ (AESTables::Encode1[(temp >> 24) ] & 0x000000ff) ^ AESTables::RCON[i]; - // clang-format on - round_key[7] = round_key[1] ^ round_key[6]; - round_key[8] = round_key[2] ^ round_key[7]; - round_key[9] = round_key[3] ^ round_key[8]; + // clang-format on + round_key[7] = round_key[1] ^ round_key[6]; + round_key[8] = round_key[2] ^ round_key[7]; + round_key[9] = round_key[3] ^ round_key[8]; - ++i; - if (i == 8) - break; + ++i; + if (i == 8) + break; - round_key[10] = round_key[4] ^ round_key[9]; - round_key[11] = round_key[5] ^ round_key[10]; + round_key[10] = round_key[4] ^ round_key[9]; + round_key[11] = round_key[5] ^ round_key[10]; - round_key += 6; - } - return; + round_key += 6; } + return; + } - round_key[6] = get_key(user_key.slice_view(24, 4).data()); - round_key[7] = get_key(user_key.slice_view(28, 4).data()); - if (true) { // bits == 256 - for (;;) { - temp = round_key[7]; - // clang-format off + round_key[6] = get_key(user_key.slice_view(24, 4).data()); + round_key[7] = get_key(user_key.slice_view(28, 4).data()); + if (true) { // bits == 256 + for (;;) { + temp = round_key[7]; + // clang-format off round_key[8] = round_key[0] ^ (AESTables::Encode2[(temp >> 16) & 0xff] & 0xff000000) ^ (AESTables::Encode3[(temp >> 8) & 0xff] & 0x00ff0000) ^ (AESTables::Encode0[(temp ) & 0xff] & 0x0000ff00) ^ (AESTables::Encode1[(temp >> 24) ] & 0x000000ff) ^ AESTables::RCON[i]; - // clang-format on - round_key[9] = round_key[1] ^ round_key[8]; - round_key[10] = round_key[2] ^ round_key[9]; - round_key[11] = round_key[3] ^ round_key[10]; + // clang-format on + round_key[9] = round_key[1] ^ round_key[8]; + round_key[10] = round_key[2] ^ round_key[9]; + round_key[11] = round_key[3] ^ round_key[10]; - ++i; - if (i == 7) - break; + ++i; + if (i == 7) + break; - temp = round_key[11]; - // clang-format off + temp = round_key[11]; + // clang-format off round_key[12] = round_key[4] ^ (AESTables::Encode2[(temp >> 24) ] & 0xff000000) ^ (AESTables::Encode3[(temp >> 16) & 0xff] & 0x00ff0000) ^ (AESTables::Encode0[(temp >> 8) & 0xff] & 0x0000ff00) ^ (AESTables::Encode1[(temp ) & 0xff] & 0x000000ff) ; - // clang-format on - round_key[13] = round_key[5] ^ round_key[12]; - round_key[14] = round_key[6] ^ round_key[13]; - round_key[15] = round_key[7] ^ round_key[14]; - - round_key += 8; - } - return; + // clang-format on + round_key[13] = round_key[5] ^ round_key[12]; + round_key[14] = round_key[6] ^ round_key[13]; + round_key[15] = round_key[7] ^ round_key[14]; + + round_key += 8; } + return; } +} - void AESCipherKey::expand_decrypt_key(const ByteBuffer& user_key, size_t bits) - { - u32* round_key; +void AESCipherKey::expand_decrypt_key(const ByteBuffer& user_key, size_t bits) +{ + u32* round_key; - expand_encrypt_key(user_key, bits); + expand_encrypt_key(user_key, bits); - round_key = round_keys(); + round_key = round_keys(); - // reorder round keys - for (size_t i = 0, j = 4 * rounds(); i < j; i += 4, j -= 4) { - swap_keys(round_key, i, j); - swap_keys(round_key, i + 1, j + 1); - swap_keys(round_key, i + 2, j + 2); - swap_keys(round_key, i + 3, j + 3); - } + // reorder round keys + for (size_t i = 0, j = 4 * rounds(); i < j; i += 4, j -= 4) { + swap_keys(round_key, i, j); + swap_keys(round_key, i + 1, j + 1); + swap_keys(round_key, i + 2, j + 2); + swap_keys(round_key, i + 3, j + 3); + } - // apply inverse mix-column to middle rounds - for (size_t i = 1; i < rounds(); ++i) { - round_key += 4; - // clang-format off + // apply inverse mix-column to middle rounds + for (size_t i = 1; i < rounds(); ++i) { + round_key += 4; + // clang-format off round_key[0] = AESTables::Decode0[AESTables::Encode1[(round_key[0] >> 24) ] & 0xff] ^ AESTables::Decode1[AESTables::Encode1[(round_key[0] >> 16) & 0xff] & 0xff] ^ @@ -209,30 +209,30 @@ namespace Cipher { AESTables::Decode1[AESTables::Encode1[(round_key[3] >> 16) & 0xff] & 0xff] ^ AESTables::Decode2[AESTables::Encode1[(round_key[3] >> 8) & 0xff] & 0xff] ^ AESTables::Decode3[AESTables::Encode1[(round_key[3] ) & 0xff] & 0xff] ; - // clang-format on - } + // clang-format on } +} - void AESCipher::encrypt_block(const AESCipherBlock& in, AESCipherBlock& out) - { - u32 s0, s1, s2, s3, t0, t1, t2, t3; - size_t r { 0 }; +void AESCipher::encrypt_block(const AESCipherBlock& in, AESCipherBlock& out) +{ + u32 s0, s1, s2, s3, t0, t1, t2, t3; + size_t r { 0 }; - const auto& dec_key = key(); - const auto* round_keys = dec_key.round_keys(); + const auto& dec_key = key(); + const auto* round_keys = dec_key.round_keys(); - s0 = get_key(in.data().offset_pointer(0)) ^ round_keys[0]; - s1 = get_key(in.data().offset_pointer(4)) ^ round_keys[1]; - s2 = get_key(in.data().offset_pointer(8)) ^ round_keys[2]; - s3 = get_key(in.data().offset_pointer(12)) ^ round_keys[3]; + s0 = get_key(in.data().offset_pointer(0)) ^ round_keys[0]; + s1 = get_key(in.data().offset_pointer(4)) ^ round_keys[1]; + s2 = get_key(in.data().offset_pointer(8)) ^ round_keys[2]; + s3 = get_key(in.data().offset_pointer(12)) ^ round_keys[3]; - r = dec_key.rounds() >> 1; + r = dec_key.rounds() >> 1; - // apply the first |r - 1| rounds - auto i { 0 }; - for (;;) { - ++i; - // clang-format off + // apply the first |r - 1| rounds + auto i { 0 }; + for (;;) { + ++i; + // clang-format off t0 = AESTables::Encode0[(s0 >> 24) ] ^ AESTables::Encode1[(s1 >> 16) & 0xff] ^ AESTables::Encode2[(s2 >> 8) & 0xff] ^ @@ -249,15 +249,15 @@ namespace Cipher { AESTables::Encode1[(s0 >> 16) & 0xff] ^ AESTables::Encode2[(s1 >> 8) & 0xff] ^ AESTables::Encode3[(s2 ) & 0xff] ^ round_keys[7]; - // clang-format on + // clang-format on - round_keys += 8; - --r; - ++i; - if (r == 0) - break; + round_keys += 8; + --r; + ++i; + if (r == 0) + break; - // clang-format off + // clang-format off s0 = AESTables::Encode0[(t0 >> 24) ] ^ AESTables::Encode1[(t1 >> 16) & 0xff] ^ AESTables::Encode2[(t2 >> 8) & 0xff] ^ @@ -274,11 +274,11 @@ namespace Cipher { AESTables::Encode1[(t0 >> 16) & 0xff] ^ AESTables::Encode2[(t1 >> 8) & 0xff] ^ AESTables::Encode3[(t2 ) & 0xff] ^ round_keys[3]; - // clang-format on - } + // clang-format on + } - // apply the last round and put the encrypted data into out - // clang-format off + // apply the last round and put the encrypted data into out + // clang-format off s0 = (AESTables::Encode2[(t0 >> 24) ] & 0xff000000) ^ (AESTables::Encode3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (AESTables::Encode0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ @@ -302,28 +302,28 @@ namespace Cipher { (AESTables::Encode0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (AESTables::Encode1[(t2 ) & 0xff] & 0x000000ff) ^ round_keys[3]; out.put(12, s3); - // clang-format on - } + // clang-format on +} - void AESCipher::decrypt_block(const AESCipherBlock& in, AESCipherBlock& out) - { +void AESCipher::decrypt_block(const AESCipherBlock& in, AESCipherBlock& out) +{ - u32 s0, s1, s2, s3, t0, t1, t2, t3; - size_t r { 0 }; + u32 s0, s1, s2, s3, t0, t1, t2, t3; + size_t r { 0 }; - const auto& dec_key = key(); - const auto* round_keys = dec_key.round_keys(); + const auto& dec_key = key(); + const auto* round_keys = dec_key.round_keys(); - s0 = get_key(in.data().offset_pointer(0)) ^ round_keys[0]; - s1 = get_key(in.data().offset_pointer(4)) ^ round_keys[1]; - s2 = get_key(in.data().offset_pointer(8)) ^ round_keys[2]; - s3 = get_key(in.data().offset_pointer(12)) ^ round_keys[3]; + s0 = get_key(in.data().offset_pointer(0)) ^ round_keys[0]; + s1 = get_key(in.data().offset_pointer(4)) ^ round_keys[1]; + s2 = get_key(in.data().offset_pointer(8)) ^ round_keys[2]; + s3 = get_key(in.data().offset_pointer(12)) ^ round_keys[3]; - r = dec_key.rounds() >> 1; + r = dec_key.rounds() >> 1; - // apply the first |r - 1| rounds - for (;;) { - // clang-format off + // apply the first |r - 1| rounds + for (;;) { + // clang-format off t0 = AESTables::Decode0[(s0 >> 24) ] ^ AESTables::Decode1[(s3 >> 16) & 0xff] ^ AESTables::Decode2[(s2 >> 8) & 0xff] ^ @@ -340,14 +340,14 @@ namespace Cipher { AESTables::Decode1[(s2 >> 16) & 0xff] ^ AESTables::Decode2[(s1 >> 8) & 0xff] ^ AESTables::Decode3[(s0 ) & 0xff] ^ round_keys[7]; - // clang-format on + // clang-format on - round_keys += 8; - --r; - if (r == 0) - break; + round_keys += 8; + --r; + if (r == 0) + break; - // clang-format off + // clang-format off s0 = AESTables::Decode0[(t0 >> 24) ] ^ AESTables::Decode1[(t3 >> 16) & 0xff] ^ AESTables::Decode2[(t2 >> 8) & 0xff] ^ @@ -364,11 +364,11 @@ namespace Cipher { AESTables::Decode1[(t2 >> 16) & 0xff] ^ AESTables::Decode2[(t1 >> 8) & 0xff] ^ AESTables::Decode3[(t0 ) & 0xff] ^ round_keys[3]; - // clang-format on - } + // clang-format on + } - // apply the last round and put the decrypted data into out - // clang-format off + // apply the last round and put the decrypted data into out + // clang-format off s0 = ((u32)AESTables::Decode4[(t0 >> 24) ] << 24) ^ ((u32)AESTables::Decode4[(t3 >> 16) & 0xff] << 16) ^ ((u32)AESTables::Decode4[(t2 >> 8) & 0xff] << 8) ^ @@ -392,39 +392,39 @@ namespace Cipher { ((u32)AESTables::Decode4[(t1 >> 8) & 0xff] << 8) ^ ((u32)AESTables::Decode4[(t0 ) & 0xff] ) ^ round_keys[3]; out.put(12, s3); - // clang-format on - } + // clang-format on +} - void AESCipherBlock::overwrite(const ByteBuffer& buffer) - { - overwrite(buffer.data(), buffer.size()); - } +void AESCipherBlock::overwrite(const ByteBuffer& buffer) +{ + overwrite(buffer.data(), buffer.size()); +} - void AESCipherBlock::overwrite(const u8* data, size_t length) - { - ASSERT(length <= m_data.size()); - m_data.overwrite(0, data, length); - if (length < m_data.size()) { - switch (padding_mode()) { - case PaddingMode::Null: - // fill with zeros - __builtin_memset(m_data.data() + length, 0, m_data.size() - length); - break; - case PaddingMode::CMS: - // fill with the length of the padding bytes - __builtin_memset(m_data.data() + length, m_data.size() - length, m_data.size() - length); - break; - case PaddingMode::RFC5246: - // fill with the length of the padding bytes minus one - __builtin_memset(m_data.data() + length, m_data.size() - length - 1, m_data.size() - length); - break; - default: - // FIXME: We should handle the rest of the common padding modes - ASSERT_NOT_REACHED(); - break; - } +void AESCipherBlock::overwrite(const u8* data, size_t length) +{ + ASSERT(length <= m_data.size()); + m_data.overwrite(0, data, length); + if (length < m_data.size()) { + switch (padding_mode()) { + case PaddingMode::Null: + // fill with zeros + __builtin_memset(m_data.data() + length, 0, m_data.size() - length); + break; + case PaddingMode::CMS: + // fill with the length of the padding bytes + __builtin_memset(m_data.data() + length, m_data.size() - length, m_data.size() - length); + break; + case PaddingMode::RFC5246: + // fill with the length of the padding bytes minus one + __builtin_memset(m_data.data() + length, m_data.size() - length - 1, m_data.size() - length); + break; + default: + // FIXME: We should handle the rest of the common padding modes + ASSERT_NOT_REACHED(); + break; } } } +} } |