aboutsummaryrefslogtreecommitdiffstats
path: root/src/block/aes
diff options
context:
space:
mode:
authorlloyd <[email protected]>2010-10-14 18:04:35 +0000
committerlloyd <[email protected]>2010-10-14 18:04:35 +0000
commit0cb6bcfedef6ffa797801acd7cb945feb2d05d50 (patch)
treea89de84b769036989fd59364dfb2d4fa000c697f /src/block/aes
parenta142500346e9bef5c4b0905103eac9a494d6822e (diff)
In all cases where the block size of the cipher is fixed, the key
parameters are as well. So make them template paramters. The sole exception was AES, because you could either initialize AES with a fixed key length, in which case it would only be that specific key length, or not, in which case it would support any valid AES key size. This is removed in this checkin; you have to specifically ask for AES-128, AES-192, or AES-256, depending on which one you want. This is probably actually a good thing, because every implementation other than the base one (SSSE3, AES-NI, OpenSSL) did not support "AES", only the versions with specific fixed key sizes. So forcing the user to ask for the one they want ensures they get the ones that are faster and/or safer.
Diffstat (limited to 'src/block/aes')
-rw-r--r--src/block/aes/aes.cpp111
-rw-r--r--src/block/aes/aes.h69
2 files changed, 115 insertions, 65 deletions
diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp
index b317fa735..7f6c5ea9c 100644
--- a/src/block/aes/aes.cpp
+++ b/src/block/aes/aes.cpp
@@ -410,13 +410,16 @@ const u32bit TD[1024] = {
0x3C498B28, 0x0D9541FF, 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064,
0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0 };
-}
-
/*
* AES Encryption
*/
-void AES::encrypt_n(const byte in[], byte out[], size_t blocks) const
+void aes_encrypt_n(const byte in[], byte out[],
+ size_t blocks,
+ const MemoryRegion<u32bit>& EK,
+ const MemoryRegion<byte>& ME)
{
+ const size_t BLOCK_SIZE = 16;
+
const u32bit* TE0 = TE;
const u32bit* TE1 = TE + 256;
const u32bit* TE2 = TE + 512;
@@ -522,8 +525,12 @@ void AES::encrypt_n(const byte in[], byte out[], size_t blocks) const
/*
* AES Decryption
*/
-void AES::decrypt_n(const byte in[], byte out[], size_t blocks) const
+void aes_decrypt_n(const byte in[], byte out[], size_t blocks,
+ const MemoryRegion<u32bit>& DK,
+ const MemoryRegion<byte>& MD)
{
+ const size_t BLOCK_SIZE = 16;
+
const u32bit* TD0 = TD;
const u32bit* TD1 = TD + 256;
const u32bit* TD2 = TD + 512;
@@ -600,9 +607,19 @@ void AES::decrypt_n(const byte in[], byte out[], size_t blocks) const
}
/*
-* AES Key Schedule
+* AES Byte Substitution
*/
-void AES::key_schedule(const byte key[], size_t length)
+u32bit aes_S(u32bit input)
+ {
+ return make_u32bit(SE[get_byte(0, input)], SE[get_byte(1, input)],
+ SE[get_byte(2, input)], SE[get_byte(3, input)]);
+ }
+
+void aes_key_schedule(const byte key[], size_t length,
+ MemoryRegion<u32bit>& EK,
+ MemoryRegion<u32bit>& DK,
+ MemoryRegion<byte>& ME,
+ MemoryRegion<byte>& MD)
{
static const u32bit RC[10] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000,
@@ -618,11 +635,11 @@ void AES::key_schedule(const byte key[], size_t length)
for(size_t i = X; i < 4*(rounds+1); i += X)
{
- XEK[i] = XEK[i-X] ^ S(rotate_left(XEK[i-1], 8)) ^ RC[(i-X)/X];
+ XEK[i] = XEK[i-X] ^ aes_S(rotate_left(XEK[i-1], 8)) ^ RC[(i-X)/X];
for(size_t j = 1; j != X; ++j)
{
if(X == 8 && j == 4)
- XEK[i+j] = XEK[i+j-X] ^ S(XEK[i+j-1]);
+ XEK[i+j] = XEK[i+j-X] ^ aes_S(XEK[i+j-1]);
else
XEK[i+j] = XEK[i+j-X] ^ XEK[i+j-1];
}
@@ -652,38 +669,70 @@ void AES::key_schedule(const byte key[], size_t length)
DK.set(&XDK[0], length + 24);
}
-/*
-* AES Byte Substitution
-*/
-u32bit AES::S(u32bit input)
+}
+
+void AES_128::encrypt_n(const byte in[], byte out[], size_t blocks) const
{
- return make_u32bit(SE[get_byte(0, input)], SE[get_byte(1, input)],
- SE[get_byte(2, input)], SE[get_byte(3, input)]);
+ aes_encrypt_n(in, out, blocks, EK, ME);
}
-/*
-* AES Constructor
-*/
-AES::AES() : BlockCipher_Fixed_Block_Size(16, 32, 8),
- EK(0), ME(16), DK(0), MD(16)
+void AES_128::decrypt_n(const byte in[], byte out[], size_t blocks) const
{
+ aes_decrypt_n(in, out, blocks, DK, MD);
}
-/*
-* AES Constructor
-*/
-AES::AES(size_t key_size) : BlockCipher_Fixed_Block_Size(key_size),
- EK(key_size+24), ME(16),
- DK(key_size+24), MD(16)
+void AES_128::key_schedule(const byte key[], size_t length)
{
- if(key_size != 16 && key_size != 24 && key_size != 32)
- throw Invalid_Key_Length(name(), key_size);
+ aes_key_schedule(key, length, EK, DK, ME, MD);
}
-/*
-* Clear memory of sensitive data
-*/
-void AES::clear()
+void AES_128::clear()
+ {
+ zeroise(EK);
+ zeroise(DK);
+ zeroise(ME);
+ zeroise(MD);
+ }
+
+void AES_192::encrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ aes_encrypt_n(in, out, blocks, EK, ME);
+ }
+
+void AES_192::decrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ aes_decrypt_n(in, out, blocks, DK, MD);
+ }
+
+void AES_192::key_schedule(const byte key[], size_t length)
+ {
+ aes_key_schedule(key, length, EK, DK, ME, MD);
+ }
+
+void AES_192::clear()
+ {
+ zeroise(EK);
+ zeroise(DK);
+ zeroise(ME);
+ zeroise(MD);
+ }
+
+void AES_256::encrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ aes_encrypt_n(in, out, blocks, EK, ME);
+ }
+
+void AES_256::decrypt_n(const byte in[], byte out[], size_t blocks) const
+ {
+ aes_decrypt_n(in, out, blocks, DK, MD);
+ }
+
+void AES_256::key_schedule(const byte key[], size_t length)
+ {
+ aes_key_schedule(key, length, EK, DK, ME, MD);
+ }
+
+void AES_256::clear()
{
zeroise(EK);
zeroise(DK);
diff --git a/src/block/aes/aes.h b/src/block/aes/aes.h
index d2e051f83..a165f83b5 100644
--- a/src/block/aes/aes.h
+++ b/src/block/aes/aes.h
@@ -1,6 +1,6 @@
/*
* AES
-* (C) 1999-2009 Jack Lloyd
+* (C) 1999-2010 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -13,68 +13,69 @@
namespace Botan {
/**
-* Rijndael aka AES
+* AES-128
*/
-class BOTAN_DLL AES : public BlockCipher_Fixed_Block_Size<16>
+class BOTAN_DLL AES_128 : public Block_Cipher_Fixed_Params<16, 16>
{
public:
- std::string name() const { return "AES"; }
+ AES_128() : EK(40), DK(40), ME(16), MD(16) {}
void encrypt_n(const byte in[], byte out[], size_t blocks) const;
void decrypt_n(const byte in[], byte out[], size_t blocks) const;
void clear();
- BlockCipher* clone() const { return new AES; }
-
- AES();
-
- /**
- * AES fixed to a particular key_size (16, 24, or 32 bytes)
- * @param key_size the chosen fixed key size
- */
- AES(size_t key_size);
- private:
- void key_schedule(const byte[], size_t);
- static u32bit S(u32bit);
- SecureVector<u32bit> EK;
- SecureVector<byte> ME;
-
- SecureVector<u32bit > DK;
- SecureVector<byte> MD;
- };
-
-/**
-* AES-128
-*/
-class BOTAN_DLL AES_128 : public AES
- {
- public:
std::string name() const { return "AES-128"; }
BlockCipher* clone() const { return new AES_128; }
- AES_128() : AES(16) {}
+ private:
+ void key_schedule(const byte key[], size_t length);
+
+ SecureVector<u32bit> EK, DK;
+ SecureVector<byte> ME, MD;
};
/**
* AES-192
*/
-class BOTAN_DLL AES_192 : public AES
+class BOTAN_DLL AES_192 : public Block_Cipher_Fixed_Params<16, 24>
{
public:
+ AES_192() : EK(48), DK(48), ME(16), MD(16) {}
+
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+
+ void clear();
+
std::string name() const { return "AES-192"; }
BlockCipher* clone() const { return new AES_192; }
- AES_192() : AES(24) {}
+ private:
+ void key_schedule(const byte key[], size_t length);
+
+ SecureVector<u32bit> EK, DK;
+ SecureVector<byte> ME, MD;
};
/**
* AES-256
*/
-class BOTAN_DLL AES_256 : public AES
+class BOTAN_DLL AES_256 : public Block_Cipher_Fixed_Params<16, 32>
{
public:
+ AES_256() : EK(56), DK(56), ME(16), MD(16) {}
+
+ void encrypt_n(const byte in[], byte out[], size_t blocks) const;
+ void decrypt_n(const byte in[], byte out[], size_t blocks) const;
+
+ void clear();
+
std::string name() const { return "AES-256"; }
BlockCipher* clone() const { return new AES_256; }
- AES_256() : AES(32) {}
+ private:
+ void key_schedule(const byte key[], size_t length);
+
+ SecureVector<u32bit> EK, DK;
+ SecureVector<byte> ME, MD;
};
}