Add a new file crypto/aes-helpers.c with simple functions to support some AES modes: - AES cbc: AES_cbc_encrypt() AES_cbc_decrypt() - AES ctr: AES_ctr_encrypt() - AES xts: AES_xts_encrypt() AES_xts_decrypt() and some AES related helpers: - AES_xor() - AES_xts_prep_next_tweak()
Signed-off-by: Harald Freudenberger <[email protected]> --- crypto/aes-helpers.c | 101 +++++++++++++++++++++++++++++++++++++++++++ crypto/meson.build | 1 + include/crypto/aes.h | 14 ++++++ 3 files changed, 116 insertions(+) create mode 100644 crypto/aes-helpers.c diff --git a/crypto/aes-helpers.c b/crypto/aes-helpers.c new file mode 100644 index 0000000000..8ad3c5132a --- /dev/null +++ b/crypto/aes-helpers.c @@ -0,0 +1,101 @@ +/* + * AES helper functions and mode implementations + * + * Authors: + * Harald Freudenberger <[email protected]> + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include <stdint.h> +#include <string.h> +#include "crypto/aes.h" + +void AES_xor(const unsigned char *src1, const unsigned char *src2, + unsigned char *dst) +{ + int i; + + for (i = 0; i < AES_BLOCK_SIZE; i++) { + dst[i] = src1[i] ^ src2[i]; + } +} + +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key) +{ + unsigned char buf[AES_BLOCK_SIZE]; + + /* in xor iv => buf */ + AES_xor(in, iv, buf); + /* encrypt buf => out */ + AES_encrypt(buf, out, key); + /* prep iv for next round */ + memcpy(iv, out, AES_BLOCK_SIZE); +} + +void AES_cbc_decrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key) +{ + unsigned char buf[AES_BLOCK_SIZE]; + + /* decrypt in => buf */ + AES_decrypt(in, buf, key); + /* buf xor iv => out */ + AES_xor(buf, iv, out); + /* prep iv for next round */ + memcpy(iv, in, AES_BLOCK_SIZE); +} + +void AES_ctr_encrypt(const unsigned char *in, unsigned char *out, + const unsigned char *ctr, const AES_KEY *key) +{ + unsigned char buf[AES_BLOCK_SIZE]; + + /* encrypt ctr => buf */ + AES_encrypt(ctr, buf, key); + /* exor input data with encrypted ctr => out */ + AES_xor(in, buf, out); +} + +void AES_xts_prep_next_tweak(unsigned char *tweak) +{ + unsigned char carry; + int i; + + carry = tweak[AES_BLOCK_SIZE - 1] >> 7; + + for (i = AES_BLOCK_SIZE - 1; i > 0; i--) { + tweak[i] = (unsigned char)((tweak[i] << 1) | (tweak[i - 1] >> 7)); + } + + tweak[i] = (unsigned char)(tweak[i] << 1); + tweak[i] ^= (unsigned char)(0x87 & (unsigned char)(-(unsigned char)carry)); +} + +void AES_xts_encrypt(const unsigned char *in, unsigned char *out, + const unsigned char *tweak, const AES_KEY *key) +{ + unsigned char buf1[AES_BLOCK_SIZE], buf2[AES_BLOCK_SIZE]; + + /* in xor tweak => buf1 */ + AES_xor(in, tweak, buf1); + /* encrypt buf1 => buf2 */ + AES_encrypt(buf1, buf2, key); + /* buf2 xor tweak => out */ + AES_xor(buf2, tweak, out); +} + +void AES_xts_decrypt(const unsigned char *in, unsigned char *out, + const unsigned char *tweak, const AES_KEY *key) +{ + unsigned char buf1[AES_BLOCK_SIZE], buf2[AES_BLOCK_SIZE]; + + /* in xor tweak => buf1 */ + AES_xor(in, tweak, buf1); + /* encrypt buf1 => buf2 */ + AES_decrypt(buf1, buf2, key); + /* buf2 xor tweak => out */ + AES_xor(buf2, tweak, out); +} diff --git a/crypto/meson.build b/crypto/meson.build index b51597a879..675f27311c 100644 --- a/crypto/meson.build +++ b/crypto/meson.build @@ -55,6 +55,7 @@ system_ss.add(when: gnutls, if_true: files('tls-cipher-suites.c')) util_ss.add(files( 'aes.c', + 'aes-helpers.c', 'clmul.c', 'init.c', 'sm4.c', diff --git a/include/crypto/aes.h b/include/crypto/aes.h index 381f24c902..df6239cb9c 100644 --- a/include/crypto/aes.h +++ b/include/crypto/aes.h @@ -37,4 +37,18 @@ AES_Td0[x] = Si[x].[0e, 09, 0d, 0b]; extern const uint32_t AES_Te0[256], AES_Td0[256]; +void AES_xor(const unsigned char *src1, const unsigned char *src2, + unsigned char *dst); +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key); +void AES_cbc_decrypt(const unsigned char *in, unsigned char *out, + unsigned char *iv, const AES_KEY *key); +void AES_ctr_encrypt(const unsigned char *in, unsigned char *out, + const unsigned char *ctr, const AES_KEY *key); +void AES_xts_prep_next_tweak(unsigned char *tweak); +void AES_xts_encrypt(const unsigned char *in, unsigned char *out, + const unsigned char *tweak, const AES_KEY *key); +void AES_xts_decrypt(const unsigned char *in, unsigned char *out, + const unsigned char *tweak, const AES_KEY *key); + #endif -- 2.43.0
