mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-23 22:14:54 +00:00
aes: add support of aes192 and aes256
Until now, we only support aes128. This commit add the support of aes192 and aes256. Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
7012c04ef3
commit
8302d1708a
4 changed files with 125 additions and 65 deletions
|
@ -39,34 +39,35 @@ static void left_shift_vector(u8 *in, u8 *out, int size)
|
||||||
/**
|
/**
|
||||||
* Sign a block of data, putting the result into dst.
|
* Sign a block of data, putting the result into dst.
|
||||||
*
|
*
|
||||||
* \param key Input AES key, length AES_KEY_LENGTH
|
* \param key Input AES key, length AES128_KEY_LENGTH
|
||||||
* \param key_schedule Expanded key to use
|
* \param key_schedule Expanded key to use
|
||||||
* \param src Source data of length 'num_aes_blocks' blocks
|
* \param src Source data of length 'num_aes_blocks' blocks
|
||||||
* \param dst Destination buffer, length AES_KEY_LENGTH
|
* \param dst Destination buffer, length AES128_KEY_LENGTH
|
||||||
* \param num_aes_blocks Number of AES blocks to encrypt
|
* \param num_aes_blocks Number of AES blocks to encrypt
|
||||||
*/
|
*/
|
||||||
static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst,
|
static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst,
|
||||||
u32 num_aes_blocks)
|
u32 num_aes_blocks)
|
||||||
{
|
{
|
||||||
u8 tmp_data[AES_KEY_LENGTH];
|
u8 tmp_data[AES128_KEY_LENGTH];
|
||||||
u8 iv[AES_KEY_LENGTH] = {0};
|
u8 iv[AES128_KEY_LENGTH] = {0};
|
||||||
u8 left[AES_KEY_LENGTH];
|
u8 left[AES128_KEY_LENGTH];
|
||||||
u8 k1[AES_KEY_LENGTH];
|
u8 k1[AES128_KEY_LENGTH];
|
||||||
u8 *cbc_chain_data;
|
u8 *cbc_chain_data;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
cbc_chain_data = zero_key; /* Convenient array of 0's for IV */
|
cbc_chain_data = zero_key; /* Convenient array of 0's for IV */
|
||||||
|
|
||||||
/* compute K1 constant needed by AES-CMAC calculation */
|
/* compute K1 constant needed by AES-CMAC calculation */
|
||||||
for (i = 0; i < AES_KEY_LENGTH; i++)
|
for (i = 0; i < AES128_KEY_LENGTH; i++)
|
||||||
tmp_data[i] = 0;
|
tmp_data[i] = 0;
|
||||||
|
|
||||||
aes_cbc_encrypt_blocks(key_schedule, iv, tmp_data, left, 1);
|
aes_cbc_encrypt_blocks(AES128_KEY_LENGTH, key_schedule, iv,
|
||||||
|
tmp_data, left, 1);
|
||||||
|
|
||||||
left_shift_vector(left, k1, sizeof(left));
|
left_shift_vector(left, k1, sizeof(left));
|
||||||
|
|
||||||
if ((left[0] >> 7) != 0) /* get MSB of L */
|
if ((left[0] >> 7) != 0) /* get MSB of L */
|
||||||
k1[AES_KEY_LENGTH-1] ^= AES_CMAC_CONST_RB;
|
k1[AES128_KEY_LENGTH - 1] ^= AES_CMAC_CONST_RB;
|
||||||
|
|
||||||
/* compute the AES-CMAC value */
|
/* compute the AES-CMAC value */
|
||||||
for (i = 0; i < num_aes_blocks; i++) {
|
for (i = 0; i < num_aes_blocks; i++) {
|
||||||
|
@ -78,31 +79,32 @@ static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst,
|
||||||
aes_apply_cbc_chain_data(tmp_data, k1, tmp_data);
|
aes_apply_cbc_chain_data(tmp_data, k1, tmp_data);
|
||||||
|
|
||||||
/* encrypt the AES block */
|
/* encrypt the AES block */
|
||||||
aes_encrypt(tmp_data, key_schedule, dst);
|
aes_encrypt(AES128_KEY_LENGTH, tmp_data,
|
||||||
|
key_schedule, dst);
|
||||||
|
|
||||||
debug("sign_obj: block %d of %d\n", i, num_aes_blocks);
|
debug("sign_obj: block %d of %d\n", i, num_aes_blocks);
|
||||||
|
|
||||||
/* Update pointers for next loop. */
|
/* Update pointers for next loop. */
|
||||||
cbc_chain_data = dst;
|
cbc_chain_data = dst;
|
||||||
src += AES_KEY_LENGTH;
|
src += AES128_KEY_LENGTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt and sign a block of data (depending on security mode).
|
* Encrypt and sign a block of data (depending on security mode).
|
||||||
*
|
*
|
||||||
* \param key Input AES key, length AES_KEY_LENGTH
|
* \param key Input AES key, length AES128_KEY_LENGTH
|
||||||
* \param oper Security operations mask to perform (enum security_op)
|
* \param oper Security operations mask to perform (enum security_op)
|
||||||
* \param src Source data
|
* \param src Source data
|
||||||
* \param length Size of source data
|
* \param length Size of source data
|
||||||
* \param sig_dst Destination address for signature, AES_KEY_LENGTH bytes
|
* \param sig_dst Destination address for signature, AES128_KEY_LENGTH bytes
|
||||||
*/
|
*/
|
||||||
static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src,
|
static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src,
|
||||||
u32 length, u8 *sig_dst)
|
u32 length, u8 *sig_dst)
|
||||||
{
|
{
|
||||||
u32 num_aes_blocks;
|
u32 num_aes_blocks;
|
||||||
u8 key_schedule[AES_EXPAND_KEY_LENGTH];
|
u8 key_schedule[AES128_EXPAND_KEY_LENGTH];
|
||||||
u8 iv[AES_KEY_LENGTH] = {0};
|
u8 iv[AES128_KEY_LENGTH] = {0};
|
||||||
|
|
||||||
debug("encrypt_and_sign: length = %d\n", length);
|
debug("encrypt_and_sign: length = %d\n", length);
|
||||||
|
|
||||||
|
@ -110,15 +112,16 @@ static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src,
|
||||||
* The only need for a key is for signing/checksum purposes, so
|
* The only need for a key is for signing/checksum purposes, so
|
||||||
* if not encrypting, expand a key of 0s.
|
* if not encrypting, expand a key of 0s.
|
||||||
*/
|
*/
|
||||||
aes_expand_key(oper & SECURITY_ENCRYPT ? key : zero_key, key_schedule);
|
aes_expand_key(oper & SECURITY_ENCRYPT ? key : zero_key,
|
||||||
|
AES128_KEY_LENGTH, key_schedule);
|
||||||
|
|
||||||
num_aes_blocks = (length + AES_KEY_LENGTH - 1) / AES_KEY_LENGTH;
|
num_aes_blocks = (length + AES128_KEY_LENGTH - 1) / AES128_KEY_LENGTH;
|
||||||
|
|
||||||
if (oper & SECURITY_ENCRYPT) {
|
if (oper & SECURITY_ENCRYPT) {
|
||||||
/* Perform this in place, resulting in src being encrypted. */
|
/* Perform this in place, resulting in src being encrypted. */
|
||||||
debug("encrypt_and_sign: begin encryption\n");
|
debug("encrypt_and_sign: begin encryption\n");
|
||||||
aes_cbc_encrypt_blocks(key_schedule, iv, src, src,
|
aes_cbc_encrypt_blocks(AES128_KEY_LENGTH, key_schedule, iv, src,
|
||||||
num_aes_blocks);
|
src, num_aes_blocks);
|
||||||
debug("encrypt_and_sign: end encryption\n");
|
debug("encrypt_and_sign: end encryption\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
38
cmd/aes.c
38
cmd/aes.c
|
@ -2,7 +2,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2014 Marek Vasut <marex@denx.de>
|
* Copyright (C) 2014 Marek Vasut <marex@denx.de>
|
||||||
*
|
*
|
||||||
* Command for en/de-crypting block of memory with AES-128-CBC cipher.
|
* Command for en/de-crypting block of memory with AES-[128/192/256]-CBC cipher.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
@ -13,6 +13,18 @@
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <mapmem.h>
|
#include <mapmem.h>
|
||||||
|
|
||||||
|
u32 aes_get_key_len(char *command)
|
||||||
|
{
|
||||||
|
u32 key_len = AES128_KEY_LENGTH;
|
||||||
|
|
||||||
|
if (!strcmp(command, "aes.192"))
|
||||||
|
key_len = AES192_KEY_LENGTH;
|
||||||
|
else if (!strcmp(command, "aes.256"))
|
||||||
|
key_len = AES256_KEY_LENGTH;
|
||||||
|
|
||||||
|
return key_len;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* do_aes() - Handle the "aes" command-line command
|
* do_aes() - Handle the "aes" command-line command
|
||||||
* @cmdtp: Command data struct pointer
|
* @cmdtp: Command data struct pointer
|
||||||
|
@ -27,13 +39,15 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||||
{
|
{
|
||||||
uint32_t key_addr, iv_addr, src_addr, dst_addr, len;
|
uint32_t key_addr, iv_addr, src_addr, dst_addr, len;
|
||||||
uint8_t *key_ptr, *iv_ptr, *src_ptr, *dst_ptr;
|
uint8_t *key_ptr, *iv_ptr, *src_ptr, *dst_ptr;
|
||||||
uint8_t key_exp[AES_EXPAND_KEY_LENGTH];
|
u8 key_exp[AES256_EXPAND_KEY_LENGTH];
|
||||||
uint32_t aes_blocks;
|
u32 aes_blocks, key_len;
|
||||||
int enc;
|
int enc;
|
||||||
|
|
||||||
if (argc != 7)
|
if (argc != 7)
|
||||||
return CMD_RET_USAGE;
|
return CMD_RET_USAGE;
|
||||||
|
|
||||||
|
key_len = aes_get_key_len(argv[0]);
|
||||||
|
|
||||||
if (!strncmp(argv[1], "enc", 3))
|
if (!strncmp(argv[1], "enc", 3))
|
||||||
enc = 1;
|
enc = 1;
|
||||||
else if (!strncmp(argv[1], "dec", 3))
|
else if (!strncmp(argv[1], "dec", 3))
|
||||||
|
@ -47,23 +61,23 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||||
dst_addr = simple_strtoul(argv[5], NULL, 16);
|
dst_addr = simple_strtoul(argv[5], NULL, 16);
|
||||||
len = simple_strtoul(argv[6], NULL, 16);
|
len = simple_strtoul(argv[6], NULL, 16);
|
||||||
|
|
||||||
key_ptr = (uint8_t *)map_sysmem(key_addr, 128 / 8);
|
key_ptr = (uint8_t *)map_sysmem(key_addr, key_len);
|
||||||
iv_ptr = (uint8_t *)map_sysmem(iv_addr, 128 / 8);
|
iv_ptr = (uint8_t *)map_sysmem(iv_addr, 128 / 8);
|
||||||
src_ptr = (uint8_t *)map_sysmem(src_addr, len);
|
src_ptr = (uint8_t *)map_sysmem(src_addr, len);
|
||||||
dst_ptr = (uint8_t *)map_sysmem(dst_addr, len);
|
dst_ptr = (uint8_t *)map_sysmem(dst_addr, len);
|
||||||
|
|
||||||
/* First we expand the key. */
|
/* First we expand the key. */
|
||||||
aes_expand_key(key_ptr, key_exp);
|
aes_expand_key(key_ptr, key_len, key_exp);
|
||||||
|
|
||||||
/* Calculate the number of AES blocks to encrypt. */
|
/* Calculate the number of AES blocks to encrypt. */
|
||||||
aes_blocks = DIV_ROUND_UP(len, AES_BLOCK_LENGTH);
|
aes_blocks = DIV_ROUND_UP(len, AES_BLOCK_LENGTH);
|
||||||
|
|
||||||
if (enc)
|
if (enc)
|
||||||
aes_cbc_encrypt_blocks(key_exp, iv_ptr, src_ptr, dst_ptr,
|
aes_cbc_encrypt_blocks(key_len, key_exp, iv_ptr, src_ptr,
|
||||||
aes_blocks);
|
dst_ptr, aes_blocks);
|
||||||
else
|
else
|
||||||
aes_cbc_decrypt_blocks(key_exp, iv_ptr, src_ptr, dst_ptr,
|
aes_cbc_decrypt_blocks(key_len, key_exp, iv_ptr, src_ptr,
|
||||||
aes_blocks);
|
dst_ptr, aes_blocks);
|
||||||
|
|
||||||
unmap_sysmem(key_ptr);
|
unmap_sysmem(key_ptr);
|
||||||
unmap_sysmem(iv_ptr);
|
unmap_sysmem(iv_ptr);
|
||||||
|
@ -76,13 +90,13 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||||
/***************************************************/
|
/***************************************************/
|
||||||
#ifdef CONFIG_SYS_LONGHELP
|
#ifdef CONFIG_SYS_LONGHELP
|
||||||
static char aes_help_text[] =
|
static char aes_help_text[] =
|
||||||
"enc key iv src dst len - Encrypt block of data $len bytes long\n"
|
"[.128,.192,.256] enc key iv src dst len - Encrypt block of data $len bytes long\n"
|
||||||
" at address $src using a key at address\n"
|
" at address $src using a key at address\n"
|
||||||
" $key with initialization vector at address\n"
|
" $key with initialization vector at address\n"
|
||||||
" $iv. Store the result at address $dst.\n"
|
" $iv. Store the result at address $dst.\n"
|
||||||
" The $len size must be multiple of 16 bytes.\n"
|
" The $len size must be multiple of 16 bytes.\n"
|
||||||
" The $key and $iv must be 16 bytes long.\n"
|
" The $key and $iv must be 16 bytes long.\n"
|
||||||
"aes dec key iv src dst len - Decrypt block of data $len bytes long\n"
|
"aes [.128,.192,.256] dec key iv src dst len - Decrypt block of data $len bytes long\n"
|
||||||
" at address $src using a key at address\n"
|
" at address $src using a key at address\n"
|
||||||
" $key with initialization vector at address\n"
|
" $key with initialization vector at address\n"
|
||||||
" $iv. Store the result at address $dst.\n"
|
" $iv. Store the result at address $dst.\n"
|
||||||
|
@ -92,6 +106,6 @@ static char aes_help_text[] =
|
||||||
|
|
||||||
U_BOOT_CMD(
|
U_BOOT_CMD(
|
||||||
aes, 7, 1, do_aes,
|
aes, 7, 1, do_aes,
|
||||||
"AES 128 CBC encryption",
|
"AES 128/192/256 CBC encryption",
|
||||||
aes_help_text
|
aes_help_text
|
||||||
);
|
);
|
||||||
|
|
|
@ -23,11 +23,18 @@ typedef unsigned int u32;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
AES_STATECOLS = 4, /* columns in the state & expanded key */
|
AES_STATECOLS = 4, /* columns in the state & expanded key */
|
||||||
AES_KEYCOLS = 4, /* columns in a key */
|
AES128_KEYCOLS = 4, /* columns in a key for aes128 */
|
||||||
AES_ROUNDS = 10, /* rounds in encryption */
|
AES192_KEYCOLS = 6, /* columns in a key for aes128 */
|
||||||
|
AES256_KEYCOLS = 8, /* columns in a key for aes128 */
|
||||||
AES_KEY_LENGTH = 128 / 8,
|
AES128_ROUNDS = 10, /* rounds in encryption for aes128 */
|
||||||
AES_EXPAND_KEY_LENGTH = 4 * AES_STATECOLS * (AES_ROUNDS + 1),
|
AES192_ROUNDS = 12, /* rounds in encryption for aes192 */
|
||||||
|
AES256_ROUNDS = 14, /* rounds in encryption for aes256 */
|
||||||
|
AES128_KEY_LENGTH = 128 / 8,
|
||||||
|
AES192_KEY_LENGTH = 192 / 8,
|
||||||
|
AES256_KEY_LENGTH = 256 / 8,
|
||||||
|
AES128_EXPAND_KEY_LENGTH = 4 * AES_STATECOLS * (AES128_ROUNDS + 1),
|
||||||
|
AES192_EXPAND_KEY_LENGTH = 4 * AES_STATECOLS * (AES192_ROUNDS + 1),
|
||||||
|
AES256_EXPAND_KEY_LENGTH = 4 * AES_STATECOLS * (AES256_ROUNDS + 1),
|
||||||
AES_BLOCK_LENGTH = 128 / 8,
|
AES_BLOCK_LENGTH = 128 / 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,28 +44,31 @@ enum {
|
||||||
* Expand a key into a key schedule, which is then used for the other
|
* Expand a key into a key schedule, which is then used for the other
|
||||||
* operations.
|
* operations.
|
||||||
*
|
*
|
||||||
* @key Key, of length AES_KEY_LENGTH bytes
|
* @key Key
|
||||||
|
* @key_size Size of the key (in bits)
|
||||||
* @expkey Buffer to place expanded key, AES_EXPAND_KEY_LENGTH
|
* @expkey Buffer to place expanded key, AES_EXPAND_KEY_LENGTH
|
||||||
*/
|
*/
|
||||||
void aes_expand_key(u8 *key, u8 *expkey);
|
void aes_expand_key(u8 *key, u32 key_size, u8 *expkey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* aes_encrypt() - Encrypt single block of data with AES 128
|
* aes_encrypt() - Encrypt single block of data with AES 128
|
||||||
*
|
*
|
||||||
|
* @key_size Size of the aes key (in bits)
|
||||||
* @in Input data
|
* @in Input data
|
||||||
* @expkey Expanded key to use for encryption (from aes_expand_key())
|
* @expkey Expanded key to use for encryption (from aes_expand_key())
|
||||||
* @out Output data
|
* @out Output data
|
||||||
*/
|
*/
|
||||||
void aes_encrypt(u8 *in, u8 *expkey, u8 *out);
|
void aes_encrypt(u32 key_size, u8 *in, u8 *expkey, u8 *out);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* aes_decrypt() - Decrypt single block of data with AES 128
|
* aes_decrypt() - Decrypt single block of data with AES 128
|
||||||
*
|
*
|
||||||
|
* @key_size Size of the aes key (in bits)
|
||||||
* @in Input data
|
* @in Input data
|
||||||
* @expkey Expanded key to use for decryption (from aes_expand_key())
|
* @expkey Expanded key to use for decryption (from aes_expand_key())
|
||||||
* @out Output data
|
* @out Output data
|
||||||
*/
|
*/
|
||||||
void aes_decrypt(u8 *in, u8 *expkey, u8 *out);
|
void aes_decrypt(u32 key_size, u8 *in, u8 *expkey, u8 *out);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply chain data to the destination using EOR
|
* Apply chain data to the destination using EOR
|
||||||
|
@ -74,25 +84,27 @@ void aes_apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst);
|
||||||
/**
|
/**
|
||||||
* aes_cbc_encrypt_blocks() - Encrypt multiple blocks of data with AES CBC.
|
* aes_cbc_encrypt_blocks() - Encrypt multiple blocks of data with AES CBC.
|
||||||
*
|
*
|
||||||
|
* @key_size Size of the aes key (in bits)
|
||||||
* @key_exp Expanded key to use
|
* @key_exp Expanded key to use
|
||||||
* @iv Initialization vector
|
* @iv Initialization vector
|
||||||
* @src Source data to encrypt
|
* @src Source data to encrypt
|
||||||
* @dst Destination buffer
|
* @dst Destination buffer
|
||||||
* @num_aes_blocks Number of AES blocks to encrypt
|
* @num_aes_blocks Number of AES blocks to encrypt
|
||||||
*/
|
*/
|
||||||
void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
void aes_cbc_encrypt_blocks(u32 key_size, u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
||||||
u32 num_aes_blocks);
|
u32 num_aes_blocks);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decrypt multiple blocks of data with AES CBC.
|
* Decrypt multiple blocks of data with AES CBC.
|
||||||
*
|
*
|
||||||
|
* @key_size Size of the aes key (in bits)
|
||||||
* @key_exp Expanded key to use
|
* @key_exp Expanded key to use
|
||||||
* @iv Initialization vector
|
* @iv Initialization vector
|
||||||
* @src Source data to decrypt
|
* @src Source data to decrypt
|
||||||
* @dst Destination buffer
|
* @dst Destination buffer
|
||||||
* @num_aes_blocks Number of AES blocks to decrypt
|
* @num_aes_blocks Number of AES blocks to decrypt
|
||||||
*/
|
*/
|
||||||
void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
void aes_cbc_decrypt_blocks(u32 key_size, u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
||||||
u32 num_aes_blocks);
|
u32 num_aes_blocks);
|
||||||
|
|
||||||
#endif /* _AES_REF_H_ */
|
#endif /* _AES_REF_H_ */
|
||||||
|
|
77
lib/aes.c
77
lib/aes.c
|
@ -508,50 +508,79 @@ static u8 rcon[11] = {
|
||||||
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
|
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static u32 aes_get_rounds(u32 key_len)
|
||||||
|
{
|
||||||
|
u32 rounds = AES128_ROUNDS;
|
||||||
|
|
||||||
|
if (key_len == AES192_KEY_LENGTH)
|
||||||
|
rounds = AES192_ROUNDS;
|
||||||
|
else if (key_len == AES256_KEY_LENGTH)
|
||||||
|
rounds = AES256_ROUNDS;
|
||||||
|
|
||||||
|
return rounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 aes_get_keycols(u32 key_len)
|
||||||
|
{
|
||||||
|
u32 keycols = AES128_KEYCOLS;
|
||||||
|
|
||||||
|
if (key_len == AES192_KEY_LENGTH)
|
||||||
|
keycols = AES192_KEYCOLS;
|
||||||
|
else if (key_len == AES256_KEY_LENGTH)
|
||||||
|
keycols = AES256_KEYCOLS;
|
||||||
|
|
||||||
|
return keycols;
|
||||||
|
}
|
||||||
|
|
||||||
/* produce AES_STATECOLS bytes for each round */
|
/* produce AES_STATECOLS bytes for each round */
|
||||||
void aes_expand_key(u8 *key, u8 *expkey)
|
void aes_expand_key(u8 *key, u32 key_len, u8 *expkey)
|
||||||
{
|
{
|
||||||
u8 tmp0, tmp1, tmp2, tmp3, tmp4;
|
u8 tmp0, tmp1, tmp2, tmp3, tmp4;
|
||||||
u32 idx;
|
u32 idx, aes_rounds, aes_keycols;
|
||||||
|
|
||||||
memcpy(expkey, key, AES_KEYCOLS * 4);
|
aes_rounds = aes_get_rounds(key_len);
|
||||||
|
aes_keycols = aes_get_keycols(key_len);
|
||||||
|
|
||||||
for (idx = AES_KEYCOLS; idx < AES_STATECOLS * (AES_ROUNDS + 1); idx++) {
|
memcpy(expkey, key, key_len);
|
||||||
|
|
||||||
|
for (idx = aes_keycols; idx < AES_STATECOLS * (aes_rounds + 1); idx++) {
|
||||||
tmp0 = expkey[4*idx - 4];
|
tmp0 = expkey[4*idx - 4];
|
||||||
tmp1 = expkey[4*idx - 3];
|
tmp1 = expkey[4*idx - 3];
|
||||||
tmp2 = expkey[4*idx - 2];
|
tmp2 = expkey[4*idx - 2];
|
||||||
tmp3 = expkey[4*idx - 1];
|
tmp3 = expkey[4*idx - 1];
|
||||||
if (!(idx % AES_KEYCOLS)) {
|
if (!(idx % aes_keycols)) {
|
||||||
tmp4 = tmp3;
|
tmp4 = tmp3;
|
||||||
tmp3 = sbox[tmp0];
|
tmp3 = sbox[tmp0];
|
||||||
tmp0 = sbox[tmp1] ^ rcon[idx / AES_KEYCOLS];
|
tmp0 = sbox[tmp1] ^ rcon[idx / aes_keycols];
|
||||||
tmp1 = sbox[tmp2];
|
tmp1 = sbox[tmp2];
|
||||||
tmp2 = sbox[tmp4];
|
tmp2 = sbox[tmp4];
|
||||||
} else if ((AES_KEYCOLS > 6) && (idx % AES_KEYCOLS == 4)) {
|
} else if ((aes_keycols > 6) && (idx % aes_keycols == 4)) {
|
||||||
tmp0 = sbox[tmp0];
|
tmp0 = sbox[tmp0];
|
||||||
tmp1 = sbox[tmp1];
|
tmp1 = sbox[tmp1];
|
||||||
tmp2 = sbox[tmp2];
|
tmp2 = sbox[tmp2];
|
||||||
tmp3 = sbox[tmp3];
|
tmp3 = sbox[tmp3];
|
||||||
}
|
}
|
||||||
|
|
||||||
expkey[4*idx+0] = expkey[4*idx - 4*AES_KEYCOLS + 0] ^ tmp0;
|
expkey[4*idx+0] = expkey[4*idx - 4*aes_keycols + 0] ^ tmp0;
|
||||||
expkey[4*idx+1] = expkey[4*idx - 4*AES_KEYCOLS + 1] ^ tmp1;
|
expkey[4*idx+1] = expkey[4*idx - 4*aes_keycols + 1] ^ tmp1;
|
||||||
expkey[4*idx+2] = expkey[4*idx - 4*AES_KEYCOLS + 2] ^ tmp2;
|
expkey[4*idx+2] = expkey[4*idx - 4*aes_keycols + 2] ^ tmp2;
|
||||||
expkey[4*idx+3] = expkey[4*idx - 4*AES_KEYCOLS + 3] ^ tmp3;
|
expkey[4*idx+3] = expkey[4*idx - 4*aes_keycols + 3] ^ tmp3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* encrypt one 128 bit block */
|
/* encrypt one 128 bit block */
|
||||||
void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
|
void aes_encrypt(u32 key_len, u8 *in, u8 *expkey, u8 *out)
|
||||||
{
|
{
|
||||||
u8 state[AES_STATECOLS * 4];
|
u8 state[AES_STATECOLS * 4];
|
||||||
u32 round;
|
u32 round, aes_rounds;
|
||||||
|
|
||||||
|
aes_rounds = aes_get_rounds(key_len);
|
||||||
|
|
||||||
memcpy(state, in, AES_STATECOLS * 4);
|
memcpy(state, in, AES_STATECOLS * 4);
|
||||||
add_round_key((u32 *)state, (u32 *)expkey);
|
add_round_key((u32 *)state, (u32 *)expkey);
|
||||||
|
|
||||||
for (round = 1; round < AES_ROUNDS + 1; round++) {
|
for (round = 1; round < aes_rounds + 1; round++) {
|
||||||
if (round < AES_ROUNDS)
|
if (round < aes_rounds)
|
||||||
mix_sub_columns(state);
|
mix_sub_columns(state);
|
||||||
else
|
else
|
||||||
shift_rows(state);
|
shift_rows(state);
|
||||||
|
@ -563,18 +592,20 @@ void aes_encrypt(u8 *in, u8 *expkey, u8 *out)
|
||||||
memcpy(out, state, sizeof(state));
|
memcpy(out, state, sizeof(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
void aes_decrypt(u8 *in, u8 *expkey, u8 *out)
|
void aes_decrypt(u32 key_len, u8 *in, u8 *expkey, u8 *out)
|
||||||
{
|
{
|
||||||
u8 state[AES_STATECOLS * 4];
|
u8 state[AES_STATECOLS * 4];
|
||||||
int round;
|
int round, aes_rounds;
|
||||||
|
|
||||||
|
aes_rounds = aes_get_rounds(key_len);
|
||||||
|
|
||||||
memcpy(state, in, sizeof(state));
|
memcpy(state, in, sizeof(state));
|
||||||
|
|
||||||
add_round_key((u32 *)state,
|
add_round_key((u32 *)state,
|
||||||
(u32 *)expkey + AES_ROUNDS * AES_STATECOLS);
|
(u32 *)expkey + aes_rounds * AES_STATECOLS);
|
||||||
inv_shift_rows(state);
|
inv_shift_rows(state);
|
||||||
|
|
||||||
for (round = AES_ROUNDS; round--; ) {
|
for (round = aes_rounds; round--; ) {
|
||||||
add_round_key((u32 *)state,
|
add_round_key((u32 *)state,
|
||||||
(u32 *)expkey + round * AES_STATECOLS);
|
(u32 *)expkey + round * AES_STATECOLS);
|
||||||
if (round)
|
if (round)
|
||||||
|
@ -600,7 +631,7 @@ void aes_apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst)
|
||||||
*dst++ = *src++ ^ *cbc_chain_data++;
|
*dst++ = *src++ ^ *cbc_chain_data++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
void aes_cbc_encrypt_blocks(u32 key_len, u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
||||||
u32 num_aes_blocks)
|
u32 num_aes_blocks)
|
||||||
{
|
{
|
||||||
u8 tmp_data[AES_BLOCK_LENGTH];
|
u8 tmp_data[AES_BLOCK_LENGTH];
|
||||||
|
@ -616,7 +647,7 @@ void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
||||||
debug_print_vector("AES Xor", AES_BLOCK_LENGTH, tmp_data);
|
debug_print_vector("AES Xor", AES_BLOCK_LENGTH, tmp_data);
|
||||||
|
|
||||||
/* Encrypt the AES block */
|
/* Encrypt the AES block */
|
||||||
aes_encrypt(tmp_data, key_exp, dst);
|
aes_encrypt(key_len, tmp_data, key_exp, dst);
|
||||||
debug_print_vector("AES Dst", AES_BLOCK_LENGTH, dst);
|
debug_print_vector("AES Dst", AES_BLOCK_LENGTH, dst);
|
||||||
|
|
||||||
/* Update pointers for next loop. */
|
/* Update pointers for next loop. */
|
||||||
|
@ -626,7 +657,7 @@ void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
void aes_cbc_decrypt_blocks(u32 key_len, u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
||||||
u32 num_aes_blocks)
|
u32 num_aes_blocks)
|
||||||
{
|
{
|
||||||
u8 tmp_data[AES_BLOCK_LENGTH], tmp_block[AES_BLOCK_LENGTH];
|
u8 tmp_data[AES_BLOCK_LENGTH], tmp_block[AES_BLOCK_LENGTH];
|
||||||
|
@ -642,7 +673,7 @@ void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst,
|
||||||
memcpy(tmp_block, src, AES_BLOCK_LENGTH);
|
memcpy(tmp_block, src, AES_BLOCK_LENGTH);
|
||||||
|
|
||||||
/* Decrypt the AES block */
|
/* Decrypt the AES block */
|
||||||
aes_decrypt(src, key_exp, tmp_data);
|
aes_decrypt(key_len, src, key_exp, tmp_data);
|
||||||
debug_print_vector("AES Xor", AES_BLOCK_LENGTH, tmp_data);
|
debug_print_vector("AES Xor", AES_BLOCK_LENGTH, tmp_data);
|
||||||
|
|
||||||
/* Apply the chain data */
|
/* Apply the chain data */
|
||||||
|
|
Loading…
Add table
Reference in a new issue