// Copyright (c) 2015 Egor Tensin // This file is part of the "AES tools" project. // For details, see https://github.com/egor-tensin/aes-tools. // Distributed under the MIT License. #pragma once #include #include namespace aes { typedef AES_Mode Mode; template struct ModeRequiresInitializationVector : public std::true_type { }; template <> struct ModeRequiresInitializationVector : public std::false_type { }; template struct ModeUsesEncryptionKeysOnly : public std::true_type { }; inline bool mode_requires_initialization_vector(Mode mode) { return mode != AES_ECB; } template <> struct ModeUsesEncryptionKeysOnly : public std::false_type { }; template <> struct ModeUsesEncryptionKeysOnly : public std::false_type { }; inline bool mode_uses_encryption_keys_only(Mode mode) { return mode != AES_ECB && mode != AES_CBC; } #define AESXX_ENCRYPT_BLOCK_ECB(prefix) \ template <> \ inline void encrypt_block( \ const typename Types::Block& plaintext, \ const typename Types::RoundKeys& encryption_keys, \ typename Types::Block& ciphertext) \ { \ ciphertext = aes_## prefix ##_encrypt_block_ECB(plaintext, &encryption_keys); \ } #define AESXX_DECRYPT_BLOCK_ECB(prefix) \ template <> \ inline void decrypt_block( \ const typename Types::Block& ciphertext, \ const typename Types::RoundKeys& decryption_keys, \ typename Types::Block& plaintext) \ { \ plaintext = aes_## prefix ##_decrypt_block_ECB(ciphertext, &decryption_keys); \ } #define AESXX_ENCRYPT_BLOCK_CBC(prefix) \ template <> \ inline void encrypt_block( \ const typename Types::Block& plaintext, \ const typename Types::RoundKeys& encryption_keys, \ typename Types::Block& iv, \ typename Types::Block& ciphertext) \ { \ ciphertext = aes_## prefix ##_encrypt_block_CBC(plaintext, &encryption_keys, iv, &iv); \ } #define AESXX_DECRYPT_BLOCK_CBC(prefix) \ template <> \ inline void decrypt_block( \ const typename Types::Block& ciphertext, \ const typename Types::RoundKeys& decryption_keys, \ typename Types::Block& iv, \ typename Types::Block& plaintext) \ { \ plaintext = aes_## prefix ##_decrypt_block_CBC(ciphertext, &decryption_keys, iv, &iv); \ } #define AESXX_ENCRYPT_BLOCK_CFB(prefix) \ template <> \ inline void encrypt_block( \ const typename Types::Block& plaintext, \ const typename Types::RoundKeys& encryption_keys, \ typename Types::Block& iv, \ typename Types::Block& ciphertext) \ { \ ciphertext = aes_## prefix ##_encrypt_block_CFB(plaintext, &encryption_keys, iv, &iv); \ } #define AESXX_DECRYPT_BLOCK_CFB(prefix) \ template <> \ inline void decrypt_block( \ const typename Types::Block& ciphertext, \ const typename Types::RoundKeys& encryption_keys, \ typename Types::Block& iv, \ typename Types::Block& plaintext) \ { \ plaintext = aes_## prefix ##_decrypt_block_CFB(ciphertext, &encryption_keys, iv, &iv); \ } #define AESXX_ENCRYPT_BLOCK_OFB(prefix) \ template <> \ inline void encrypt_block( \ const typename Types::Block& plaintext, \ const typename Types::RoundKeys& encryption_keys, \ typename Types::Block& iv, \ typename Types::Block& ciphertext) \ { \ ciphertext = aes_## prefix ##_encrypt_block_OFB(plaintext, &encryption_keys, iv, &iv); \ } #define AESXX_DECRYPT_BLOCK_OFB(prefix) \ template <> \ inline void decrypt_block( \ const typename Types::Block& ciphertext, \ const typename Types::RoundKeys& encryption_keys, \ typename Types::Block& iv, \ typename Types::Block& plaintext) \ { \ plaintext = aes_## prefix ##_decrypt_block_OFB(ciphertext, &encryption_keys, iv, &iv); \ } #define AESXX_ENCRYPT_BLOCK_CTR(prefix) \ template <> \ inline void encrypt_block( \ const typename Types::Block& plaintext, \ const typename Types::RoundKeys& encryption_keys, \ typename Types::Block& iv, \ typename Types::Block& ciphertext) \ { \ ciphertext = aes_## prefix ##_encrypt_block_CTR(plaintext, &encryption_keys, iv, &iv); \ } #define AESXX_DECRYPT_BLOCK_CTR(prefix) \ template <> \ inline void decrypt_block( \ const typename Types::Block& ciphertext, \ const typename Types::RoundKeys& encryption_keys, \ typename Types::Block& iv, \ typename Types::Block& plaintext) \ { \ plaintext = aes_## prefix ##_decrypt_block_CTR(ciphertext, &encryption_keys, iv, &iv); \ } }