Update aes_cbc.c

This commit is contained in:
kokke 2014-12-15 21:18:10 +01:00
parent bb1e5bb93c
commit d9c9ad2ffc

View File

@ -1,6 +1,6 @@
/*
This is an implementation of the AES128 algorithm, specifically ECB mode.
This is an implementation of the AES128 algorithm, specifically ECB and CBC mode.
The implementation is verified against the test vectors in:
National Institute of Standards and Technology Special Publication 800-38A 2001 ED
@ -46,7 +46,7 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
// The number of 32 bit words in a key.
#define Nk 4
// Key length in bytes [128 bit]
#define keyln 16
#define KEYLEN 16
// The number of rounds in AES Cipher.
#define Nr 10
@ -57,13 +57,6 @@ NOTE: String length must be evenly divisible by 16byte (str_len % 16 == 0)
#define MULTIPLY_AS_A_FUNCTION 0
#endif
#ifndef CBC
#define CBC 1
#endif
#ifndef ECB
#define ECB 0
#endif
/*****************************************************************************/
/* Private variables: */
@ -439,10 +432,10 @@ static void InvCipher(void)
AddRoundKey(0);
}
static void BufferCopy(uint8_t* output, uint8_t* input)
static void BlockCopy(uint8_t* output, uint8_t* input)
{
uint8_t i;
for (i=0;i<16;++i)
for (i=0;i<KEYLEN;++i)
{
output[i] = input[i];
}
@ -459,7 +452,7 @@ static void BufferCopy(uint8_t* output, uint8_t* input)
void AES128_ECB_encrypt(uint8_t* input, const uint8_t* key, uint8_t* output)
{
// Copy input to output, and work in-memory on output
BufferCopy(output, input);
BlockCopy(output, input);
state = (state_t*)output;
Key = key;
@ -472,7 +465,7 @@ void AES128_ECB_encrypt(uint8_t* input, const uint8_t* key, uint8_t* output)
void AES128_ECB_decrypt(uint8_t* input, const uint8_t* key, uint8_t *output)
{
// Copy input to output, and work in-memory on output
BufferCopy(output, input);
BlockCopy(output, input);
state = (state_t*)output;
// The KeyExpansion routine must be called before encryption.
@ -495,74 +488,88 @@ void AES128_ECB_decrypt(uint8_t* input, const uint8_t* key, uint8_t *output)
static void XorWithIv(uint8_t* buf)
{
uint8_t i;
for(i = 0; i < 16; ++i)
for(i = 0; i < KEYLEN; ++i)
{
buf[i] ^= Iv[i];
}
}
void AES128_CBC_encrypt_buffer(uint8_t* input, uint32_t length, const uint8_t* key, uint8_t* output, const uint8_t* iv)
void AES128_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
intptr_t i;
uint8_t j;
uint8_t remainders = length % 16; /* Remaining bytes in the last non-full block */
uint8_t remainders = length % KEYLEN; /* Remaining bytes in the last non-full block */
BufferCopy(output, input);
BlockCopy(output, input);
state = (state_t*)output;
Key = key;
KeyExpansion();
// Skip the key expansion if key is passed as 0
if(0 != key)
{
Key = key;
KeyExpansion();
}
Iv = (uint8_t*)iv;
if(iv != 0)
{
Iv = (uint8_t*)iv;
}
for(i = 0; i < length; i += 16)
for(i = 0; i < length; i += KEYLEN)
{
XorWithIv(input);
BufferCopy(output, input);
BlockCopy(output, input);
state = (state_t*)output;
Cipher();
Iv = output;
input += 16;
output += 16;
input += KEYLEN;
output += KEYLEN;
}
if(remainders)
{
BufferCopy(output, input);
memset(output + remainders, 0, 16 - remainders); /* add 0-padding */
BlockCopy(output, input);
memset(output + remainders, 0, KEYLEN - remainders); /* add 0-padding */
state = (state_t*)output;
Cipher();
}
}
void AES128_CBC_decrypt_buffer(uint8_t* input, uint32_t length, const uint8_t* key, uint8_t* output, const uint8_t* iv)
void AES128_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
{
intptr_t i;
uint8_t remainders = length % 16; /* Remaining bytes in the last non-full block */
uint8_t remainders = length % KEYLEN; /* Remaining bytes in the last non-full block */
BufferCopy(output, input);
BlockCopy(output, input);
state = (state_t*)output;
Key = key;
KeyExpansion();
Iv = (uint8_t*)iv;
for(i = 0; i < length; i += 16)
// Skip the key expansion if key is passed as 0
if(0 != key)
{
BufferCopy(output, input);
Key = key;
KeyExpansion();
}
// If iv is passed as 0, we continue to encrypt without re-setting the Iv
if(iv != 0)
{
Iv = (uint8_t*)iv;
}
for(i = 0; i < length; i += KEYLEN)
{
BlockCopy(output, input);
state = (state_t*)output;
InvCipher();
XorWithIv(output);
Iv = input;
input += 16;
output += 16;
input += KEYLEN;
output += KEYLEN;
}
if(remainders)
{
BufferCopy(output, input);
memset(output+remainders, 0, 16-remainders); /* add 0-padding */
BlockCopy(output, input);
memset(output+remainders, 0, KEYLEN - remainders); /* add 0-padding */
state = (state_t*)output;
InvCipher();
}