mirror of https://github.com/kokke/tiny-AES-c
Update aes_cbc.c
This commit is contained in:
parent
bb1e5bb93c
commit
d9c9ad2ffc
89
aes_cbc.c
89
aes_cbc.c
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue