diff options
Diffstat (limited to 'cxx')
-rw-r--r-- | cxx/include/aesnixx/aes.hpp | 467 | ||||
-rw-r--r-- | cxx/include/aesnixx/mode.hpp | 15 |
2 files changed, 482 insertions, 0 deletions
diff --git a/cxx/include/aesnixx/aes.hpp b/cxx/include/aesnixx/aes.hpp index 55dfa0e..1273c56 100644 --- a/cxx/include/aesnixx/aes.hpp +++ b/cxx/include/aesnixx/aes.hpp @@ -6,7 +6,9 @@ * See LICENSE.txt for details. */ +#include "algorithm.hpp" #include "data.hpp" +#include "mode.hpp" #include <aesni/all.h> @@ -128,5 +130,470 @@ namespace aesni { return sizeof(round_keys) / sizeof(Block128); } + + inline void expand_key( + const Key128& key, + RoundKeys128& encryption_keys) + { + aesni_aes128_expand_key(&key, &encryption_keys); + } + + inline void expand_key( + const Key192& key, + RoundKeys192& encryption_keys) + { + aesni_aes192_expand_key(&key, &encryption_keys); + } + + inline void expand_key( + const Key256& key, + RoundKeys256& encryption_keys) + { + aesni_aes256_expand_key(&key, &encryption_keys); + } + + inline void derive_decryption_keys( + const RoundKeys128& encryption_keys, + RoundKeys128& decryption_keys) + { + aesni_aes128_derive_decryption_keys( + &encryption_keys, &decryption_keys); + } + + inline void derive_decryption_keys( + const RoundKeys192& encryption_keys, + RoundKeys192& decryption_keys) + { + aesni_aes192_derive_decryption_keys( + &encryption_keys, &decryption_keys); + } + + inline void derive_decryption_keys( + const RoundKeys256& encryption_keys, + RoundKeys256& decryption_keys) + { + aesni_aes256_derive_decryption_keys( + &encryption_keys, &decryption_keys); + } + + inline Block encrypt_ecb( + const Block& plaintext, + const RoundKeys128& encryption_keys) + { + return aesni_aes128_encrypt_block_ecb(plaintext, &encryption_keys); + } + + inline Block decrypt_ecb( + const Block& ciphertext, + const RoundKeys128& decryption_keys) + { + return aesni_aes128_decrypt_block_ecb(ciphertext, &decryption_keys); + } + + inline Block encrypt_cbc( + const Block& plaintext, + const RoundKeys128& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes128_encrypt_block_cbc(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_cbc( + const Block& ciphertext, + const RoundKeys128& decryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes128_decrypt_block_cbc(ciphertext, &decryption_keys, iv, &next_iv); + } + + inline Block encrypt_cfb( + const Block& plaintext, + const RoundKeys128& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes128_encrypt_block_cfb(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_cfb( + const Block& ciphertext, + const RoundKeys128& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes128_decrypt_block_cfb(ciphertext, &encryption_keys, iv, &next_iv); + } + + inline Block encrypt_ofb( + const Block& plaintext, + const RoundKeys128& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes128_encrypt_block_ofb(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_ofb( + const Block& ciphertext, + const RoundKeys128& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes128_decrypt_block_ofb(ciphertext, &encryption_keys, iv, &next_iv); + } + + inline Block encrypt_ctr( + const Block& plaintext, + const RoundKeys128& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes128_encrypt_block_ctr(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_ctr( + const Block& ciphertext, + const RoundKeys128& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes128_decrypt_block_ctr(ciphertext, &encryption_keys, iv, &next_iv); + } + + inline Block encrypt_ecb( + const Block& plaintext, + const RoundKeys192& encryption_keys) + { + return aesni_aes192_encrypt_block_ecb(plaintext, &encryption_keys); + } + + inline Block decrypt_ecb( + const Block& ciphertext, + const RoundKeys192& decryption_keys) + { + return aesni_aes192_decrypt_block_ecb(ciphertext, &decryption_keys); + } + + inline Block encrypt_cbc( + const Block& plaintext, + const RoundKeys192& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes192_encrypt_block_cbc(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_cbc( + const Block& ciphertext, + const RoundKeys192& decryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes192_decrypt_block_cbc(ciphertext, &decryption_keys, iv, &next_iv); + } + + inline Block encrypt_cfb( + const Block& plaintext, + const RoundKeys192& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes192_encrypt_block_cfb(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_cfb( + const Block& ciphertext, + const RoundKeys192& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes192_decrypt_block_cfb(ciphertext, &encryption_keys, iv, &next_iv); + } + + inline Block encrypt_ofb( + const Block& plaintext, + const RoundKeys192& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes192_encrypt_block_ofb(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_ofb( + const Block& ciphertext, + const RoundKeys192& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes192_decrypt_block_ofb(ciphertext, &encryption_keys, iv, &next_iv); + } + + inline Block encrypt_ctr( + const Block& plaintext, + const RoundKeys192& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes192_encrypt_block_ctr(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_ctr( + const Block& ciphertext, + const RoundKeys192& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes192_decrypt_block_ctr(ciphertext, &encryption_keys, iv, &next_iv); + } + + inline Block encrypt_ecb( + const Block& plaintext, + const RoundKeys256& encryption_keys) + { + return aesni_aes256_encrypt_block_ecb(plaintext, &encryption_keys); + } + + inline Block decrypt_ecb( + const Block& ciphertext, + const RoundKeys256& decryption_keys) + { + return aesni_aes256_decrypt_block_ecb(ciphertext, &decryption_keys); + } + + inline Block encrypt_cbc( + const Block& plaintext, + const RoundKeys256& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes256_encrypt_block_cbc(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_cbc( + const Block& ciphertext, + const RoundKeys256& decryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes256_decrypt_block_cbc(ciphertext, &decryption_keys, iv, &next_iv); + } + + inline Block encrypt_cfb( + const Block& plaintext, + const RoundKeys256& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes256_encrypt_block_cfb(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_cfb( + const Block& ciphertext, + const RoundKeys256& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes256_decrypt_block_cfb(ciphertext, &encryption_keys, iv, &next_iv); + } + + inline Block encrypt_ofb( + const Block& plaintext, + const RoundKeys256& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes256_encrypt_block_ofb(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_ofb( + const Block& ciphertext, + const RoundKeys256& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes256_decrypt_block_ofb(ciphertext, &encryption_keys, iv, &next_iv); + } + + inline Block encrypt_ctr( + const Block& plaintext, + const RoundKeys256& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes256_encrypt_block_ctr(plaintext, &encryption_keys, iv, &next_iv); + } + + inline Block decrypt_ctr( + const Block& ciphertext, + const RoundKeys256& encryption_keys, + const Block& iv, + Block& next_iv) + { + return aesni_aes256_decrypt_block_ctr(ciphertext, &encryption_keys, iv, &next_iv); + } + + template <Algorithm> + struct Types; + + template <> + struct Types<AESNI_AES128> + { + typedef aesni::aes::Block BlockT; + typedef aesni::aes::Key128 KeyT; + typedef aesni::aes::RoundKeys128 RoundKeysT; + }; + + template <> + struct Types<AESNI_AES192> + { + typedef aesni::aes::Block BlockT; + typedef aesni::aes::Key192 KeyT; + typedef aesni::aes::RoundKeys192 RoundKeysT; + }; + + template <> + struct Types<AESNI_AES256> + { + typedef aesni::aes::Block BlockT; + typedef aesni::aes::Key256 KeyT; + typedef aesni::aes::RoundKeys256 RoundKeysT; + }; + + template <Algorithm algorithm, Mode mode> + class Encrypt; + + template <Algorithm algorithm> + class Encrypt<algorithm, AESNI_ECB> + { + public: + Encrypt(const typename Types<algorithm>::KeyT& key, + const typename Types<algorithm>::BlockT& iv) + { + expand_key(key, m_encryption_keys); + derive_decryption_keys(m_encryption_keys, m_decryption_keys); + } + + inline typename Types<algorithm>::BlockT encrypt(const typename Types<algorithm>::BlockT& plaintext) + { + return encrypt_ecb(plaintext, m_encryption_keys); + } + + inline typename Types<algorithm>::BlockT decrypt(const typename Types<algorithm>::BlockT& ciphertext) + { + return decrypt_ecb(ciphertext, m_decryption_keys); + } + + private: + typename Types<algorithm>::RoundKeysT m_encryption_keys; + typename Types<algorithm>::RoundKeysT m_decryption_keys; + }; + + template <Algorithm algorithm> + class Encrypt<algorithm, AESNI_CBC> + { + public: + Encrypt(const typename Types<algorithm>::KeyT& key, + const typename Types<algorithm>::BlockT& iv) + : m_iv(iv) + { + expand_key(key, m_encryption_keys); + derive_decryption_keys(m_encryption_keys, m_decryption_keys); + } + + inline typename Types<algorithm>::BlockT encrypt(const typename Types<algorithm>::BlockT& plaintext) + { + return encrypt_cbc(plaintext, m_encryption_keys, m_iv, m_iv); + } + + inline typename Types<algorithm>::BlockT decrypt(const typename Types<algorithm>::BlockT& ciphertext) + { + return decrypt_cbc(ciphertext, m_decryption_keys, m_iv, m_iv); + } + + private: + typename Types<algorithm>::BlockT m_iv; + typename Types<algorithm>::RoundKeysT m_encryption_keys; + typename Types<algorithm>::RoundKeysT m_decryption_keys; + }; + + template <Algorithm algorithm> + class Encrypt<algorithm, AESNI_CFB> + { + public: + Encrypt(const typename Types<algorithm>::KeyT& key, + const typename Types<algorithm>::BlockT& iv) + : m_iv(iv) + { + expand_key(key, m_encryption_keys); + } + + inline typename Types<algorithm>::BlockT encrypt(const typename Types<algorithm>::BlockT& plaintext) + { + return encrypt_cfb(plaintext, m_encryption_keys, m_iv, m_iv); + } + + inline typename Types<algorithm>::BlockT decrypt(const typename Types<algorithm>::BlockT& ciphertext) + { + return decrypt_cfb(ciphertext, m_encryption_keys, m_iv, m_iv); + } + + private: + typename Types<algorithm>::BlockT m_iv; + typename Types<algorithm>::RoundKeysT m_encryption_keys; + }; + + template <Algorithm algorithm> + class Encrypt<algorithm, AESNI_OFB> + { + public: + Encrypt(const typename Types<algorithm>::KeyT& key, + const typename Types<algorithm>::BlockT& iv) + : m_iv(iv) + { + expand_key(key, m_encryption_keys); + } + + inline typename Types<algorithm>::BlockT encrypt(const typename Types<algorithm>::BlockT& plaintext) + { + return encrypt_ofb(plaintext, m_encryption_keys, m_iv, m_iv); + } + + inline typename Types<algorithm>::BlockT decrypt(const typename Types<algorithm>::BlockT& ciphertext) + { + return decrypt_ofb(ciphertext, m_encryption_keys, m_iv, m_iv); + } + + private: + typename Types<algorithm>::BlockT m_iv; + typename Types<algorithm>::RoundKeysT m_encryption_keys; + }; + + template <Algorithm algorithm> + class Encrypt<algorithm, AESNI_CTR> + { + public: + Encrypt(const typename Types<algorithm>::KeyT& key, + const typename Types<algorithm>::BlockT& iv) + : m_iv(iv) + { + expand_key(key, m_encryption_keys); + } + + inline typename Types<algorithm>::BlockT encrypt(const typename Types<algorithm>::BlockT& plaintext) + { + return encrypt_ctr(plaintext, m_encryption_keys, m_iv, m_iv); + } + + inline typename Types<algorithm>::BlockT decrypt(const typename Types<algorithm>::BlockT& ciphertext) + { + return decrypt_ctr(ciphertext, m_encryption_keys, m_iv, m_iv); + } + + private: + typename Types<algorithm>::RoundKeysT m_encryption_keys; + typename Types<algorithm>::BlockT m_iv; + }; } } diff --git a/cxx/include/aesnixx/mode.hpp b/cxx/include/aesnixx/mode.hpp index ec26170..9bcbbd5 100644 --- a/cxx/include/aesnixx/mode.hpp +++ b/cxx/include/aesnixx/mode.hpp @@ -10,7 +10,22 @@ #include <aesni/all.h> +#include <type_traits> + namespace aesni { typedef AesNI_Mode Mode; + + template <Mode mode> + struct ModeRequiresInitializationVector : public std::true_type + { }; + + template <> + struct ModeRequiresInitializationVector<AESNI_ECB> : public std::false_type + { }; + + inline bool mode_requires_initialization_vector(Mode mode) + { + return mode != AESNI_ECB; + } } |