diff --git a/lib/des/aes.c b/lib/des/aes.c index 2f6c8fcf9..6195bd5f3 100644 --- a/lib/des/aes.c +++ b/lib/des/aes.c @@ -43,6 +43,8 @@ RCSID("$Id$"); #include #endif +#include + #include "rijndael-alg-fst.h" #include "aes.h" @@ -75,3 +77,50 @@ AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key) { rijndaelDecrypt(key->key, key->rounds, in, out); } + +void +AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + unsigned long size, const AES_KEY *key, + unsigned char *iv, int encrypt) +{ + char tmp[AES_BLOCK_SIZE]; + int i; + + if (encrypt) { + while (size >= AES_BLOCK_SIZE) { + for (i = 0; i < AES_BLOCK_SIZE; i++) + tmp[i] = in[i] ^ iv[i]; + AES_encrypt(tmp, out, key); + memcpy(iv, out, AES_BLOCK_SIZE); + size -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + if (size) { + for (i = 0; i < size; i++) + tmp[i] = in[i] ^ iv[i]; + for (i = size; i < AES_BLOCK_SIZE; i++) + tmp[i] = iv[i]; + AES_encrypt(tmp, out, key); + memcpy(iv, out, AES_BLOCK_SIZE); + } + } else { + while (size >= AES_BLOCK_SIZE) { + memcpy(tmp, in, AES_BLOCK_SIZE); + AES_decrypt(tmp, out, key); + for (i = 0; i < AES_BLOCK_SIZE; i++) + out[i] ^= iv[i]; + memcpy(iv, tmp, AES_BLOCK_SIZE); + size -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + if (size) { + memcpy(tmp, in, AES_BLOCK_SIZE); + AES_decrypt(tmp, out, key); + for (i = 0; i < size; i++) + out[i] ^= iv[i]; + memcpy(iv, tmp, AES_BLOCK_SIZE); + } + } +} diff --git a/lib/des/aes.h b/lib/des/aes.h index e4c890a38..3ab264d34 100644 --- a/lib/des/aes.h +++ b/lib/des/aes.h @@ -52,3 +52,7 @@ int AES_set_decrypt_key(const unsigned char *, const int, AES_KEY *); void AES_encrypt(const unsigned char *, unsigned char *, const AES_KEY *); void AES_decrypt(const unsigned char *, unsigned char *, const AES_KEY *); + +void AES_cbc_encrypt(const unsigned char *, unsigned char *, + const unsigned long, const AES_KEY *, + unsigned char *, int);