diff options
| author | Egor Tensin <egor@tensin.name> | 2026-07-22 18:31:50 +0200 |
|---|---|---|
| committer | Egor Tensin <egor@tensin.name> | 2026-07-22 21:07:53 +0200 |
| commit | 4720b5ac21163936fb47f524037a6f12ce6e6ce2 (patch) | |
| tree | 7b1f3f7f0e4047134048bb9b9967498b6f8ead12 /aes/include | |
| parent | minor refactoring (diff) | |
| download | aes-tools-4720b5ac21163936fb47f524037a6f12ce6e6ce2.tar.gz aes-tools-4720b5ac21163936fb47f524037a6f12ce6e6ce2.zip | |
rewrite: the beginning
This a giant fuck-you to myself while I have nothing (actually, tons of
things) to do in a hospital.
* The giant screens of preprocessor code are gone, they always sucked,
fuck them.
* Switched everything to the "boxes" interface as the only one
remaining.
* Restuctured things in aes/ so that the files they're in make at least
a little bit of sense.
* Removed a bunch of cruft and prematurely generic code.
* This is half-baked at best: I just made sure that the tests pass. A
lot of cleanup awaits.
Diffstat (limited to 'aes/include')
| -rw-r--r-- | aes/include/aes/aes.h | 245 | ||||
| -rw-r--r-- | aes/include/aes/algorithm.h | 70 | ||||
| -rw-r--r-- | aes/include/aes/all.h | 6 | ||||
| -rw-r--r-- | aes/include/aes/block.h | 66 | ||||
| -rw-r--r-- | aes/include/aes/box.h | 42 | ||||
| -rw-r--r-- | aes/include/aes/box_aes.h | 20 | ||||
| -rw-r--r-- | aes/include/aes/box_data.h | 95 | ||||
| -rw-r--r-- | aes/include/aes/data.h | 60 | ||||
| -rw-r--r-- | aes/include/aes/error.h | 3 | ||||
| -rw-r--r-- | aes/include/aes/key.h | 80 | ||||
| -rw-r--r-- | aes/include/aes/mode.h | 146 | ||||
| -rw-r--r-- | aes/include/aes/round_keys.h | 111 |
12 files changed, 374 insertions, 570 deletions
diff --git a/aes/include/aes/aes.h b/aes/include/aes/aes.h index 80f2b6f..01ab441 100644 --- a/aes/include/aes/aes.h +++ b/aes/include/aes/aes.h @@ -5,9 +5,8 @@ #pragma once -#include "data.h" -#include "error.h" -#include "mode.h" +#include "block.h" +#include "round_keys.h" #include <assert.h> @@ -15,234 +14,42 @@ extern "C" { #endif -typedef struct { - AES_Block key; -} AES128_Key; +AES_Block __fastcall aes128_encrypt_block_internal(AES_Block, const AES128_RoundKeys*); +AES_Block __fastcall aes192_encrypt_block_internal(AES_Block, const AES192_RoundKeys*); +AES_Block __fastcall aes256_encrypt_block_internal(AES_Block, const AES256_RoundKeys*); -typedef struct { - AES_Block hi; - AES_Block lo; -} AES192_Key; +AES_Block __fastcall aes128_decrypt_block_internal(AES_Block, const AES128_RoundKeys*); +AES_Block __fastcall aes192_decrypt_block_internal(AES_Block, const AES192_RoundKeys*); +AES_Block __fastcall aes256_decrypt_block_internal(AES_Block, const AES256_RoundKeys*); -typedef struct { - AES_Block hi; - AES_Block lo; -} AES256_Key; - -static inline AES128_Key aes128_make_key(int hi3, int hi2, int lo1, int lo0) { - AES128_Key key; - key.key = aes_make_block(hi3, hi2, lo1, lo0); - return key; -} - -static inline AES192_Key aes192_make_key(int hi5, int hi4, int lo3, int lo2, int lo1, int lo0) { - AES192_Key key; - key.hi = aes_make_block(0, 0, hi5, hi4); - key.lo = aes_make_block(lo3, lo2, lo1, lo0); - return key; -} - -static inline AES256_Key aes256_make_key( - int hi7, - int hi6, - int hi5, - int hi4, - int lo3, - int lo2, - int lo1, - int lo0 -) { - AES256_Key key; - key.hi = aes_make_block(hi7, hi6, hi5, hi4); - key.lo = aes_make_block(lo3, lo2, lo1, lo0); - return key; -} - -typedef struct { - char str[33]; -} AES_BlockString; - -typedef struct { - char str[49]; -} AES_BlockMatrixString; - -AES_StatusCode aes_format_block(AES_BlockString*, const AES_Block*, AES_ErrorDetails*); - -AES_StatusCode aes_format_block_as_matrix( - AES_BlockMatrixString*, - const AES_Block*, - AES_ErrorDetails* -); - -AES_StatusCode aes_print_block(const AES_Block*, AES_ErrorDetails*); - -AES_StatusCode aes_print_block_as_matrix(const AES_Block*, AES_ErrorDetails*); - -AES_StatusCode aes_parse_block(AES_Block* dest, const char* src, AES_ErrorDetails* err_details); - -typedef struct { - char str[33]; -} AES128_KeyString; - -typedef struct { - char str[49]; -} AES192_KeyString; - -typedef struct { - char str[65]; -} AES256_KeyString; - -AES_StatusCode aes128_format_key(AES128_KeyString*, const AES128_Key*, AES_ErrorDetails*); -AES_StatusCode aes192_format_key(AES192_KeyString*, const AES192_Key*, AES_ErrorDetails*); -AES_StatusCode aes256_format_key(AES256_KeyString*, const AES256_Key*, AES_ErrorDetails*); - -AES_StatusCode aes128_print_key(const AES128_Key*, AES_ErrorDetails*); -AES_StatusCode aes192_print_key(const AES192_Key*, AES_ErrorDetails*); -AES_StatusCode aes256_print_key(const AES256_Key*, AES_ErrorDetails*); - -AES_StatusCode aes128_parse_key(AES128_Key* dest, const char* src, AES_ErrorDetails* err_details); -AES_StatusCode aes192_parse_key(AES192_Key* dest, const char* src, AES_ErrorDetails* err_details); -AES_StatusCode aes256_parse_key(AES256_Key* dest, const char* src, AES_ErrorDetails* err_details); - -typedef struct { - AES_Block keys[11]; -} AES128_RoundKeys; - -typedef struct { - AES_Block keys[13]; -} AES192_RoundKeys; - -typedef struct { - AES_Block keys[15]; -} AES256_RoundKeys; - -void __fastcall aes128_expand_key_(AES_Block key, AES128_RoundKeys* encryption_keys); - -void __fastcall aes192_expand_key_( - AES_Block key_lo, - AES_Block key_hi, - AES192_RoundKeys* encryption_keys -); - -void __fastcall aes256_expand_key_( - AES_Block key_lo, - AES_Block key_hi, - AES256_RoundKeys* encryption_keys -); - -void __fastcall aes128_derive_decryption_keys_( - const AES128_RoundKeys* encryption_keys, - AES128_RoundKeys* decryption_keys -); - -void __fastcall aes192_derive_decryption_keys_( - const AES192_RoundKeys* encryption_keys, - AES192_RoundKeys* decryption_keys -); - -void __fastcall aes256_derive_decryption_keys_( - const AES256_RoundKeys* encryption_keys, - AES256_RoundKeys* decryption_keys -); - -AES_Block __fastcall aes128_encrypt_block_(AES_Block plaintext, const AES128_RoundKeys*); -AES_Block __fastcall aes192_encrypt_block_(AES_Block plaintext, const AES192_RoundKeys*); -AES_Block __fastcall aes256_encrypt_block_(AES_Block plaintext, const AES256_RoundKeys*); - -AES_Block __fastcall aes128_decrypt_block_(AES_Block ciphertext, const AES128_RoundKeys*); -AES_Block __fastcall aes192_decrypt_block_(AES_Block ciphertext, const AES192_RoundKeys*); -AES_Block __fastcall aes256_decrypt_block_(AES_Block ciphertext, const AES256_RoundKeys*); - -AES_ENCRYPT_BLOCK_ECB(128) -AES_DECRYPT_BLOCK_ECB(128) -AES_ENCRYPT_BLOCK_CBC(128) -AES_DECRYPT_BLOCK_CBC(128) -AES_ENCRYPT_BLOCK_CFB(128) -AES_DECRYPT_BLOCK_CFB(128) -AES_ENCRYPT_BLOCK_OFB(128) -AES_DECRYPT_BLOCK_OFB(128) -AES_ENCRYPT_BLOCK_CTR(128) -AES_DECRYPT_BLOCK_CTR(128) - -AES_ENCRYPT_BLOCK_ECB(192) -AES_DECRYPT_BLOCK_ECB(192) -AES_ENCRYPT_BLOCK_CBC(192) -AES_DECRYPT_BLOCK_CBC(192) -AES_ENCRYPT_BLOCK_CFB(192) -AES_DECRYPT_BLOCK_CFB(192) -AES_ENCRYPT_BLOCK_OFB(192) -AES_DECRYPT_BLOCK_OFB(192) -AES_ENCRYPT_BLOCK_CTR(192) -AES_DECRYPT_BLOCK_CTR(192) - -AES_ENCRYPT_BLOCK_ECB(256) -AES_DECRYPT_BLOCK_ECB(256) -AES_ENCRYPT_BLOCK_CBC(256) -AES_DECRYPT_BLOCK_CBC(256) -AES_ENCRYPT_BLOCK_CFB(256) -AES_DECRYPT_BLOCK_CFB(256) -AES_ENCRYPT_BLOCK_OFB(256) -AES_DECRYPT_BLOCK_OFB(256) -AES_ENCRYPT_BLOCK_CTR(256) -AES_DECRYPT_BLOCK_CTR(256) - -static inline void __fastcall aes128_expand_key( - const AES128_Key* key, - AES128_RoundKeys* encryption_keys -) { - assert(encryption_keys); - - aes128_expand_key_(key->key, encryption_keys); +static inline AES_Block aes128_encrypt_block(AES_Block plaintext, const AES128_RoundKeys* keys) { + assert(keys); + return aes128_encrypt_block_internal(plaintext, keys); } -static inline void __fastcall aes128_derive_decryption_keys( - const AES128_RoundKeys* encryption_keys, - AES128_RoundKeys* decryption_keys -) { - assert(encryption_keys); - assert(decryption_keys); - - aes128_derive_decryption_keys_(encryption_keys, decryption_keys); +static inline AES_Block aes192_encrypt_block(AES_Block plaintext, const AES192_RoundKeys* keys) { + assert(keys); + return aes192_encrypt_block_internal(plaintext, keys); } -static inline void __fastcall aes192_expand_key( - const AES192_Key* key, - AES192_RoundKeys* encryption_keys -) { - assert(key); - assert(encryption_keys); - - aes192_expand_key_(key->lo, key->hi, encryption_keys); +static inline AES_Block aes256_encrypt_block(AES_Block plaintext, const AES256_RoundKeys* keys) { + assert(keys); + return aes256_encrypt_block_internal(plaintext, keys); } -static inline void __fastcall aes192_derive_decryption_keys( - const AES192_RoundKeys* encryption_keys, - AES192_RoundKeys* decryption_keys -) { - assert(encryption_keys); - assert(decryption_keys); - - aes192_derive_decryption_keys_(encryption_keys, decryption_keys); +static inline AES_Block aes128_decrypt_block(AES_Block ciphertext, const AES128_RoundKeys* keys) { + assert(keys); + return aes128_decrypt_block_internal(ciphertext, keys); } -static inline void __fastcall aes256_expand_key( - const AES256_Key* key, - AES256_RoundKeys* encryption_keys -) { - assert(key); - assert(encryption_keys); - - aes256_expand_key_(key->lo, key->hi, encryption_keys); +static inline AES_Block aes192_decrypt_block(AES_Block ciphertext, const AES192_RoundKeys* keys) { + assert(keys); + return aes192_decrypt_block_internal(ciphertext, keys); } -static inline void __fastcall aes256_derive_decryption_keys( - const AES256_RoundKeys* encryption_keys, - AES256_RoundKeys* decryption_keys -) { - assert(encryption_keys); - assert(decryption_keys); - - aes256_derive_decryption_keys_(encryption_keys, decryption_keys); +static inline AES_Block aes256_decrypt_block(AES_Block ciphertext, const AES256_RoundKeys* keys) { + assert(keys); + return aes256_decrypt_block_internal(ciphertext, keys); } #ifdef __cplusplus diff --git a/aes/include/aes/algorithm.h b/aes/include/aes/algorithm.h index e17a75a..2e283fd 100644 --- a/aes/include/aes/algorithm.h +++ b/aes/include/aes/algorithm.h @@ -15,6 +15,76 @@ typedef enum { AES_AES256, } AES_Algorithm; +typedef union { + AES128_Key aes128_key; + AES192_Key aes192_key; + AES256_Key aes256_key; +} AES_Key; + +typedef union { + AES128_KeyString aes128; + AES192_KeyString aes192; + AES256_KeyString aes256; +} AES_KeyString; + +typedef union { + AES128_RoundKeys aes128_enc_keys; + AES192_RoundKeys aes192_enc_keys; + AES256_RoundKeys aes256_enc_keys; +} AES_EncryptionRoundKeys; + +typedef union { + AES128_RoundKeys aes128_dec_keys; + AES192_RoundKeys aes192_dec_keys; + AES256_RoundKeys aes256_dec_keys; +} AES_DecryptionRoundKeys; + +typedef AES_StatusCode (*AES_ParseKey)( + AES_Key* dest, + const char* src, + AES_ErrorDetails* err_details +); + +typedef AES_StatusCode (*AES_FormatKey)( + AES_KeyString* dest, + const AES_Key* src, + AES_ErrorDetails* err_details +); + +typedef AES_StatusCode (*AES_ExpandKey)( + const AES_Key* params, + AES_EncryptionRoundKeys*, + AES_DecryptionRoundKeys*, + AES_ErrorDetails* err_details +); + +typedef AES_StatusCode (*AES_EncryptBlock)( + const AES_Block* plaintext, + const AES_EncryptionRoundKeys* params, + AES_Block* ciphertext, + AES_ErrorDetails* err_details +); + +typedef AES_StatusCode (*AES_DecryptBlock)( + const AES_Block* ciphertext, + const AES_DecryptionRoundKeys* params, + AES_Block* plaintext, + AES_ErrorDetails* err_details +); + +typedef struct { + AES_ParseKey parse_key; + AES_FormatKey format_key; + AES_ExpandKey expand_key; + AES_EncryptBlock encrypt_block; + AES_DecryptBlock decrypt_block; +} AES_Ops; + +const AES_Ops* aes_get_ops(AES_Algorithm); + +AES_StatusCode aes_parse_key(AES_Algorithm, AES_Key*, const char*, AES_ErrorDetails*); +AES_StatusCode aes_format_key(AES_Algorithm, AES_KeyString*, const AES_Key*, AES_ErrorDetails*); + #ifdef __cplusplus } #endif diff --git a/aes/include/aes/all.h b/aes/include/aes/all.h index 8b60483..fb0a191 100644 --- a/aes/include/aes/all.h +++ b/aes/include/aes/all.h @@ -7,11 +7,11 @@ #include "aes.h" #include "algorithm.h" +#include "block.h" #include "box.h" -#include "box_aes.h" -#include "box_data.h" -#include "data.h" #include "error.h" +#include "key.h" #include "mode.h" #include "padding.h" +#include "round_keys.h" #include "workarounds.h" diff --git a/aes/include/aes/block.h b/aes/include/aes/block.h new file mode 100644 index 0000000..a41f79c --- /dev/null +++ b/aes/include/aes/block.h @@ -0,0 +1,66 @@ +// Copyright (c) 2015 Egor Tensin <Egor.Tensin@gmail.com> +// 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 "error.h" + +#include <emmintrin.h> +#include <tmmintrin.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef __m128i AES_Block; + +/* hi3 - the most significant 4-byte value, lo0 - the least. */ +static inline AES_Block aes_make_block(int hi3, int hi2, int lo1, int lo0) { + return _mm_set_epi32(hi3, hi2, lo1, lo0); +} + +static inline AES_Block aes_load_block(const void* src) { + return _mm_loadu_si128((AES_Block*)src); +} + +static inline AES_Block aes_load_block_aligned(const void* src) { + return _mm_load_si128((AES_Block*)src); +} + +static inline void aes_store_block(void* dest, AES_Block block) { + _mm_storeu_si128((AES_Block*)dest, block); +} + +static inline void aes_store_block_aligned(void* dest, AES_Block block) { + _mm_store_si128((AES_Block*)dest, block); +} + +static inline AES_Block aes_xor_blocks(AES_Block a, AES_Block b) { + return _mm_xor_si128(a, b); +} + +AES_Block aes_inc_block(AES_Block x); + +typedef struct { + char str[33]; +} AES_BlockString; + +typedef struct { + char str[49]; +} AES_BlockMatrixString; + +AES_StatusCode aes_format_block(AES_BlockString*, const AES_Block*, AES_ErrorDetails*); + +AES_StatusCode aes_format_block_as_matrix( + AES_BlockMatrixString*, + const AES_Block*, + AES_ErrorDetails* +); + +AES_StatusCode aes_parse_block(AES_Block* dest, const char* src, AES_ErrorDetails* err_details); + +#ifdef __cplusplus +} +#endif diff --git a/aes/include/aes/box.h b/aes/include/aes/box.h index 37292dd..3347edd 100644 --- a/aes/include/aes/box.h +++ b/aes/include/aes/box.h @@ -6,8 +6,9 @@ #pragma once #include "algorithm.h" -#include "box_data.h" +#include "block.h" #include "error.h" +#include "mode.h" #include <stdlib.h> @@ -15,43 +16,24 @@ extern "C" { #endif +typedef struct { + AES_Algorithm algorithm; + AES_Mode mode; + AES_Block iv; + AES_EncryptionRoundKeys encryption_keys; + AES_DecryptionRoundKeys decryption_keys; + const AES_Ops* ops; +} AES_Box; + AES_StatusCode aes_box_init( AES_Box* box, AES_Algorithm algorithm, - const AES_BoxKey* box_key, + const AES_Key* box_key, AES_Mode mode, const AES_Block* iv, AES_ErrorDetails* err_details ); -AES_StatusCode aes_box_parse_key( - AES_BoxKey* dest, - AES_Algorithm algorithm, - const char* src, - AES_ErrorDetails* err_details -); - -AES_StatusCode aes_box_parse_block( - AES_Block* dest, - AES_Algorithm algorithm, - const char* src, - AES_ErrorDetails* err_details -); - -AES_StatusCode aes_box_format_key( - AES_BoxKeyString* dest, - AES_Algorithm algorithm, - const AES_BoxKey* src, - AES_ErrorDetails* err_details -); - -AES_StatusCode aes_box_format_block( - AES_BlockString* dest, - AES_Algorithm algorithm, - const AES_Block* src, - AES_ErrorDetails* err_details -); - AES_StatusCode aes_box_encrypt_block( AES_Box* box, const AES_Block* plaintext, diff --git a/aes/include/aes/box_aes.h b/aes/include/aes/box_aes.h deleted file mode 100644 index c9b9b67..0000000 --- a/aes/include/aes/box_aes.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2015 Egor Tensin <Egor.Tensin@gmail.com> -// 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 "box_data.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern AES_BoxOps aes128_box_ops; -extern AES_BoxOps aes192_box_ops; -extern AES_BoxOps aes256_box_ops; - -#ifdef __cplusplus -} -#endif diff --git a/aes/include/aes/box_data.h b/aes/include/aes/box_data.h deleted file mode 100644 index 3e49fa0..0000000 --- a/aes/include/aes/box_data.h +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) 2015 Egor Tensin <Egor.Tensin@gmail.com> -// 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 "aes.h" -#include "algorithm.h" -#include "error.h" -#include "mode.h" - -#include <stdlib.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef union { - AES128_Key aes128_key; - AES192_Key aes192_key; - AES256_Key aes256_key; -} AES_BoxKey; - -typedef union { - AES128_RoundKeys aes128_encryption_keys; - AES192_RoundKeys aes192_encryption_keys; - AES256_RoundKeys aes256_encryption_keys; -} AES_BoxEncryptionRoundKeys; - -typedef union { - AES128_RoundKeys aes128_decryption_keys; - AES192_RoundKeys aes192_decryption_keys; - AES256_RoundKeys aes256_decryption_keys; -} AES_BoxDecryptionRoundKeys; - -typedef union { - AES128_KeyString aes128; - AES192_KeyString aes192; - AES256_KeyString aes256; -} AES_BoxKeyString; - -typedef AES_StatusCode (*AES_BoxCalculateRoundKeys)( - const AES_BoxKey* params, - AES_BoxEncryptionRoundKeys*, - AES_BoxDecryptionRoundKeys*, - AES_ErrorDetails* err_details -); - -typedef AES_StatusCode (*AES_BoxParseKey)( - AES_BoxKey* dest, - const char* src, - AES_ErrorDetails* err_details -); - -typedef AES_StatusCode (*AES_BoxFormatKey)( - AES_BoxKeyString* dest, - const AES_BoxKey* src, - AES_ErrorDetails* err_details -); - -typedef AES_StatusCode (*AES_BoxEncryptBlock)( - const AES_Block* plaintext, - const AES_BoxEncryptionRoundKeys* params, - AES_Block* ciphertext, - AES_ErrorDetails* err_details -); - -typedef AES_StatusCode (*AES_BoxDecryptBlock)( - const AES_Block* ciphertext, - const AES_BoxDecryptionRoundKeys* params, - AES_Block* plaintext, - AES_ErrorDetails* err_details -); - -typedef struct { - AES_BoxCalculateRoundKeys calc_round_keys; - AES_BoxParseKey parse_key; - AES_BoxFormatKey format_key; - AES_BoxEncryptBlock encrypt_block; - AES_BoxDecryptBlock decrypt_block; -} AES_BoxOps; - -typedef struct { - AES_Algorithm algorithm; - AES_Mode mode; - AES_Block iv; - AES_BoxEncryptionRoundKeys encryption_keys; - AES_BoxDecryptionRoundKeys decryption_keys; - const AES_BoxOps* ops; -} AES_Box; - -#ifdef __cplusplus -} -#endif diff --git a/aes/include/aes/data.h b/aes/include/aes/data.h deleted file mode 100644 index e06ec33..0000000 --- a/aes/include/aes/data.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2015 Egor Tensin <Egor.Tensin@gmail.com> -// 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 <emmintrin.h> -#include <tmmintrin.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef __m128i AES_Block; - -static inline AES_Block aes_load_block(const void* src) { - return _mm_loadu_si128((AES_Block*)src); -} - -static inline AES_Block aes_load_block_aligned(const void* src) { - return _mm_load_si128((AES_Block*)src); -} - -static inline void __fastcall aes_store_block(void* dest, AES_Block block) { - _mm_storeu_si128((AES_Block*)dest, block); -} - -static inline void __fastcall aes_store_block_aligned(void* dest, AES_Block block) { - _mm_store_si128((AES_Block*)dest, block); -} - -static inline AES_Block __fastcall aes_xor_blocks(AES_Block a, AES_Block b) { - return _mm_xor_si128(a, b); -} - -/** - * hi3 - The most significant 4-byte value. - * hi2 - The more significant 4-byte value. - * lo1 - The less significant 4-byte value. - * lo0 - The least significant 4-byte value. - */ -static inline AES_Block __fastcall aes_make_block(int hi3, int hi2, int lo1, int lo0) { - return _mm_set_epi32(hi3, hi2, lo1, lo0); -} - -static inline AES_Block __fastcall aes_reverse_byte_order_in_block(AES_Block block) { - return _mm_shuffle_epi8(block, aes_make_block(0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f)); -} - -static inline AES_Block __fastcall aes_inc_block(AES_Block x) { - x = aes_reverse_byte_order_in_block(x); - x = _mm_add_epi32(x, aes_make_block(0, 0, 0, 1)); - x = aes_reverse_byte_order_in_block(x); - return x; -} - -#ifdef __cplusplus -} -#endif diff --git a/aes/include/aes/error.h b/aes/include/aes/error.h index d3822de..c32d1b7 100644 --- a/aes/include/aes/error.h +++ b/aes/include/aes/error.h @@ -19,6 +19,7 @@ typedef enum { AES_NOT_IMPLEMENTED_ERROR, AES_MISSING_PADDING_ERROR, AES_MEMORY_ALLOCATION_ERROR, + AES_MODE_REQUIRES_INIT_VECTOR_ERROR, } AES_StatusCode; static inline int aes_is_error(AES_StatusCode ec) { @@ -69,6 +70,8 @@ AES_StatusCode aes_error_missing_padding(AES_ErrorDetails* err_details); AES_StatusCode aes_error_memory_allocation(AES_ErrorDetails* err_details); +AES_StatusCode aes_error_mode_requires_init_vector(AES_ErrorDetails* err_details); + #ifdef __cplusplus } #endif diff --git a/aes/include/aes/key.h b/aes/include/aes/key.h new file mode 100644 index 0000000..95fe8e5 --- /dev/null +++ b/aes/include/aes/key.h @@ -0,0 +1,80 @@ +// Copyright (c) 2026 Egor Tensin <Egor.Tensin@gmail.com> +// 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 "block.h" +#include "error.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + AES_Block key; +} AES128_Key; + +typedef struct { + AES_Block hi; + AES_Block lo; +} AES192_Key; + +typedef struct { + AES_Block hi; + AES_Block lo; +} AES256_Key; + +static inline AES128_Key aes128_make_key(int hi3, int hi2, int lo1, int lo0) { + AES128_Key key; + key.key = aes_make_block(hi3, hi2, lo1, lo0); + return key; +} + +static inline AES192_Key aes192_make_key(int hi5, int hi4, int lo3, int lo2, int lo1, int lo0) { + AES192_Key key; + key.hi = aes_make_block(0, 0, hi5, hi4); + key.lo = aes_make_block(lo3, lo2, lo1, lo0); + return key; +} + +static inline AES256_Key aes256_make_key( + int hi7, + int hi6, + int hi5, + int hi4, + int lo3, + int lo2, + int lo1, + int lo0 +) { + AES256_Key key; + key.hi = aes_make_block(hi7, hi6, hi5, hi4); + key.lo = aes_make_block(lo3, lo2, lo1, lo0); + return key; +} + +typedef struct { + char str[33]; +} AES128_KeyString; + +typedef struct { + char str[49]; +} AES192_KeyString; + +typedef struct { + char str[65]; +} AES256_KeyString; + +AES_StatusCode aes128_format_key(AES128_KeyString*, const AES128_Key*, AES_ErrorDetails*); +AES_StatusCode aes192_format_key(AES192_KeyString*, const AES192_Key*, AES_ErrorDetails*); +AES_StatusCode aes256_format_key(AES256_KeyString*, const AES256_Key*, AES_ErrorDetails*); + +AES_StatusCode aes128_parse_key(AES128_Key* dest, const char* src, AES_ErrorDetails* err_details); +AES_StatusCode aes192_parse_key(AES192_Key* dest, const char* src, AES_ErrorDetails* err_details); +AES_StatusCode aes256_parse_key(AES256_Key* dest, const char* src, AES_ErrorDetails* err_details); + +#ifdef __cplusplus +} +#endif diff --git a/aes/include/aes/mode.h b/aes/include/aes/mode.h index 656388f..57dfb50 100644 --- a/aes/include/aes/mode.h +++ b/aes/include/aes/mode.h @@ -19,149 +19,9 @@ typedef enum { AES_CTR, } AES_Mode; -#define AES_ENCRYPT_BLOCK_ECB(version) \ - static inline AES_Block __fastcall aes##version##_encrypt_block_ECB( \ - AES_Block plaintext, const AES##version##_RoundKeys* encryption_keys \ - ) { \ - assert(encryption_keys); \ - \ - return aes##version##_encrypt_block_(plaintext, encryption_keys); \ - } - -#define AES_DECRYPT_BLOCK_ECB(version) \ - static inline AES_Block __fastcall aes##version##_decrypt_block_ECB( \ - AES_Block ciphertext, const AES##version##_RoundKeys* decryption_keys \ - ) { \ - assert(decryption_keys); \ - \ - return aes##version##_decrypt_block_(ciphertext, decryption_keys); \ - } - -#define AES_ENCRYPT_BLOCK_CBC(version) \ - static inline AES_Block __fastcall aes##version##_encrypt_block_CBC( \ - AES_Block plaintext, \ - const AES##version##_RoundKeys* encryption_keys, \ - AES_Block init_vector, \ - AES_Block* next_init_vector \ - ) { \ - assert(encryption_keys); \ - assert(next_init_vector); \ - \ - return *next_init_vector = aes##version##_encrypt_block_( \ - aes_xor_blocks(plaintext, init_vector), encryption_keys \ - ); \ - } - -#define AES_DECRYPT_BLOCK_CBC(version) \ - static inline AES_Block __fastcall aes##version##_decrypt_block_CBC( \ - AES_Block ciphertext, \ - const AES##version##_RoundKeys* decryption_keys, \ - AES_Block init_vector, \ - AES_Block* next_init_vector \ - ) { \ - assert(decryption_keys); \ - assert(next_init_vector); \ - \ - AES_Block plaintext = aes_xor_blocks( \ - aes##version##_decrypt_block_(ciphertext, decryption_keys), init_vector \ - ); \ - *next_init_vector = ciphertext; \ - return plaintext; \ - } - -#define AES_ENCRYPT_BLOCK_CFB(version) \ - static inline AES_Block __fastcall aes##version##_encrypt_block_CFB( \ - AES_Block plaintext, \ - const AES##version##_RoundKeys* encryption_keys, \ - AES_Block init_vector, \ - AES_Block* next_init_vector \ - ) { \ - assert(encryption_keys); \ - assert(next_init_vector); \ - \ - return *next_init_vector = aes_xor_blocks( \ - aes##version##_encrypt_block_(init_vector, encryption_keys), plaintext \ - ); \ - } - -#define AES_DECRYPT_BLOCK_CFB(version) \ - static inline AES_Block __fastcall aes##version##_decrypt_block_CFB( \ - AES_Block ciphertext, \ - const AES##version##_RoundKeys* encryption_keys, \ - AES_Block init_vector, \ - AES_Block* next_init_vector \ - ) { \ - assert(encryption_keys); \ - assert(next_init_vector); \ - \ - AES_Block plaintext = aes_xor_blocks( \ - aes##version##_encrypt_block_(init_vector, encryption_keys), ciphertext \ - ); \ - *next_init_vector = ciphertext; \ - return plaintext; \ - } - -#define AES_ENCRYPT_BLOCK_OFB(version) \ - static inline AES_Block __fastcall aes##version##_encrypt_block_OFB( \ - AES_Block plaintext, \ - const AES##version##_RoundKeys* encryption_keys, \ - AES_Block init_vector, \ - AES_Block* next_init_vector \ - ) { \ - assert(encryption_keys); \ - assert(next_init_vector); \ - \ - AES_Block tmp = aes##version##_encrypt_block_(init_vector, encryption_keys); \ - *next_init_vector = tmp; \ - return aes_xor_blocks(tmp, plaintext); \ - } - -#define AES_DECRYPT_BLOCK_OFB(version) \ - static inline AES_Block __fastcall aes##version##_decrypt_block_OFB( \ - AES_Block ciphertext, \ - const AES##version##_RoundKeys* encryption_keys, \ - AES_Block init_vector, \ - AES_Block* next_init_vector \ - ) { \ - assert(encryption_keys); \ - assert(next_init_vector); \ - \ - return aes##version##_encrypt_block_OFB( \ - ciphertext, encryption_keys, init_vector, next_init_vector \ - ); \ - } - -#define AES_ENCRYPT_BLOCK_CTR(version) \ - static inline AES_Block __fastcall aes##version##_encrypt_block_CTR( \ - AES_Block plaintext, \ - const AES##version##_RoundKeys* encryption_keys, \ - AES_Block init_vector, \ - AES_Block* next_init_vector \ - ) { \ - assert(encryption_keys); \ - assert(next_init_vector); \ - \ - AES_Block ciphertext = aes_xor_blocks( \ - plaintext, aes##version##_encrypt_block_(init_vector, encryption_keys) \ - ); \ - *next_init_vector = aes_inc_block(init_vector); \ - return ciphertext; \ - } - -#define AES_DECRYPT_BLOCK_CTR(version) \ - static inline AES_Block __fastcall aes##version##_decrypt_block_CTR( \ - AES_Block ciphertext, \ - const AES##version##_RoundKeys* encryption_keys, \ - AES_Block init_vector, \ - AES_Block* next_init_vector \ - ) { \ - assert(encryption_keys); \ - assert(next_init_vector); \ - \ - return aes##version##_encrypt_block_CTR( \ - ciphertext, encryption_keys, init_vector, next_init_vector \ - ); \ - } +static inline int aes_mode_requires_init_vector(AES_Mode mode) { + return mode != AES_ECB; +} #ifdef __cplusplus } diff --git a/aes/include/aes/round_keys.h b/aes/include/aes/round_keys.h new file mode 100644 index 0000000..f5814b6 --- /dev/null +++ b/aes/include/aes/round_keys.h @@ -0,0 +1,111 @@ +// Copyright (c) 2015 Egor Tensin <Egor.Tensin@gmail.com> +// 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 "block.h" +#include "error.h" +#include "key.h" + +#include <assert.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + AES_Block keys[11]; +} AES128_RoundKeys; + +typedef struct { + AES_Block keys[13]; +} AES192_RoundKeys; + +typedef struct { + AES_Block keys[15]; +} AES256_RoundKeys; + +void __fastcall aes128_expand_key_internal(AES_Block key, AES128_RoundKeys* encryption_keys); + +void __fastcall aes192_expand_key_internal( + AES_Block key_lo, + AES_Block key_hi, + AES192_RoundKeys* encryption_keys +); + +void __fastcall aes256_expand_key_internal( + AES_Block key_lo, + AES_Block key_hi, + AES256_RoundKeys* encryption_keys +); + +void __fastcall aes128_derive_decryption_keys_internal( + const AES128_RoundKeys* encryption_keys, + AES128_RoundKeys* decryption_keys +); + +void __fastcall aes192_derive_decryption_keys_internal( + const AES192_RoundKeys* encryption_keys, + AES192_RoundKeys* decryption_keys +); + +void __fastcall aes256_derive_decryption_keys_internal( + const AES256_RoundKeys* encryption_keys, + AES256_RoundKeys* decryption_keys +); + +static inline void aes128_expand_key(const AES128_Key* key, AES128_RoundKeys* encryption_keys) { + assert(encryption_keys); + + aes128_expand_key_internal(key->key, encryption_keys); +} + +static inline void aes128_derive_decryption_keys( + const AES128_RoundKeys* encryption_keys, + AES128_RoundKeys* decryption_keys +) { + assert(encryption_keys); + assert(decryption_keys); + + aes128_derive_decryption_keys_internal(encryption_keys, decryption_keys); +} + +static inline void aes192_expand_key(const AES192_Key* key, AES192_RoundKeys* encryption_keys) { + assert(key); + assert(encryption_keys); + + aes192_expand_key_internal(key->lo, key->hi, encryption_keys); +} + +static inline void aes192_derive_decryption_keys( + const AES192_RoundKeys* encryption_keys, + AES192_RoundKeys* decryption_keys +) { + assert(encryption_keys); + assert(decryption_keys); + + aes192_derive_decryption_keys_internal(encryption_keys, decryption_keys); +} + +static inline void aes256_expand_key(const AES256_Key* key, AES256_RoundKeys* encryption_keys) { + assert(key); + assert(encryption_keys); + + aes256_expand_key_internal(key->lo, key->hi, encryption_keys); +} + +static inline void aes256_derive_decryption_keys( + const AES256_RoundKeys* encryption_keys, + AES256_RoundKeys* decryption_keys +) { + assert(encryption_keys); + assert(decryption_keys); + + aes256_derive_decryption_keys_internal(encryption_keys, decryption_keys); +} + +#ifdef __cplusplus +} +#endif |
