diff --git a/arch/arm/mach-tegra/tegra20/crypto.c b/arch/arm/mach-tegra/tegra20/crypto.c index eae7921..58d6662 100644 --- a/arch/arm/mach-tegra/tegra20/crypto.c +++ b/arch/arm/mach-tegra/tegra20/crypto.c @@ -50,6 +50,7 @@ static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst, u32 num_aes_blocks) { u8 tmp_data[AES_KEY_LENGTH]; + u8 iv[AES_KEY_LENGTH] = {0}; u8 left[AES_KEY_LENGTH]; u8 k1[AES_KEY_LENGTH]; u8 *cbc_chain_data; @@ -61,7 +62,7 @@ static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst, for (i = 0; i < AES_KEY_LENGTH; i++) tmp_data[i] = 0; - aes_cbc_encrypt_blocks(key_schedule, tmp_data, left, 1); + aes_cbc_encrypt_blocks(key_schedule, iv, tmp_data, left, 1); left_shift_vector(left, k1, sizeof(left)); @@ -102,6 +103,7 @@ static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src, { u32 num_aes_blocks; u8 key_schedule[AES_EXPAND_KEY_LENGTH]; + u8 iv[AES_KEY_LENGTH] = {0}; debug("encrypt_and_sign: length = %d\n", length); @@ -116,7 +118,8 @@ static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src, if (oper & SECURITY_ENCRYPT) { /* Perform this in place, resulting in src being encrypted. */ debug("encrypt_and_sign: begin encryption\n"); - aes_cbc_encrypt_blocks(key_schedule, src, src, num_aes_blocks); + aes_cbc_encrypt_blocks(key_schedule, iv, src, src, + num_aes_blocks); debug("encrypt_and_sign: end encryption\n"); } diff --git a/cmd/aes.c b/cmd/aes.c index ee1ae13..9d1a740 100644 --- a/cmd/aes.c +++ b/cmd/aes.c @@ -28,13 +28,13 @@ DECLARE_GLOBAL_DATA_PTR; */ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - uint32_t key_addr, src_addr, dst_addr, len; - uint8_t *key_ptr, *src_ptr, *dst_ptr; + uint32_t key_addr, iv_addr, src_addr, dst_addr, len; + uint8_t *key_ptr, *iv_ptr, *src_ptr, *dst_ptr; uint8_t key_exp[AES_EXPAND_KEY_LENGTH]; uint32_t aes_blocks; int enc; - if (argc != 6) + if (argc != 7) return CMD_RET_USAGE; if (!strncmp(argv[1], "enc", 3)) @@ -45,11 +45,13 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) return CMD_RET_USAGE; key_addr = simple_strtoul(argv[2], NULL, 16); - src_addr = simple_strtoul(argv[3], NULL, 16); - dst_addr = simple_strtoul(argv[4], NULL, 16); - len = simple_strtoul(argv[5], NULL, 16); + iv_addr = simple_strtoul(argv[3], NULL, 16); + src_addr = simple_strtoul(argv[4], NULL, 16); + dst_addr = simple_strtoul(argv[5], NULL, 16); + len = simple_strtoul(argv[6], NULL, 16); key_ptr = (uint8_t *)key_addr; + iv_ptr = (uint8_t *)iv_addr; src_ptr = (uint8_t *)src_addr; dst_ptr = (uint8_t *)dst_addr; @@ -60,9 +62,11 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) aes_blocks = DIV_ROUND_UP(len, AES_KEY_LENGTH); if (enc) - aes_cbc_encrypt_blocks(key_exp, src_ptr, dst_ptr, aes_blocks); + aes_cbc_encrypt_blocks(key_exp, iv_ptr, src_ptr, dst_ptr, + aes_blocks); else - aes_cbc_decrypt_blocks(key_exp, src_ptr, dst_ptr, aes_blocks); + aes_cbc_decrypt_blocks(key_exp, iv_ptr, src_ptr, dst_ptr, + aes_blocks); return 0; } @@ -70,20 +74,22 @@ static int do_aes(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) /***************************************************/ #ifdef CONFIG_SYS_LONGHELP static char aes_help_text[] = - "enc key src dst len - Encrypt block of data $len bytes long\n" - " at address $src using a key at address\n" - " $key and store the result at address\n" - " $dst. The $len size must be multiple of\n" - " 16 bytes and $key must be 16 bytes long.\n" - "aes dec key src dst len - Decrypt block of data $len bytes long\n" - " at address $src using a key at address\n" - " $key and store the result at address\n" - " $dst. The $len size must be multiple of\n" - " 16 bytes and $key must be 16 bytes long."; + "enc key iv src dst len - Encrypt block of data $len bytes long\n" + " at address $src using a key at address\n" + " $key with initialization vector at address\n" + " $iv. Store the result at address $dst.\n" + " The $len size must be multiple of 16 bytes.\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" + " at address $src using a key at address\n" + " $key with initialization vector at address\n" + " $iv. Store the result at address $dst.\n" + " The $len size must be multiple of 16 bytes.\n" + " The $key and $iv must be 16 bytes long."; #endif U_BOOT_CMD( - aes, 6, 1, do_aes, + aes, 7, 1, do_aes, "AES 128 CBC encryption", aes_help_text ); diff --git a/include/uboot_aes.h b/include/uboot_aes.h index 6315c02..b651bca 100644 --- a/include/uboot_aes.h +++ b/include/uboot_aes.h @@ -75,20 +75,24 @@ 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. * * @key_exp Expanded key to use + * @iv Initialization vector * @src Source data to encrypt * @dst Destination buffer * @num_aes_blocks Number of AES blocks to encrypt */ -void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks); +void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst, + u32 num_aes_blocks); /** * Decrypt multiple blocks of data with AES CBC. * * @key_exp Expanded key to use + * @iv Initialization vector * @src Source data to decrypt * @dst Destination buffer * @num_aes_blocks Number of AES blocks to decrypt */ -void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks); +void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst, + u32 num_aes_blocks); #endif /* _AES_REF_H_ */ diff --git a/lib/aes.c b/lib/aes.c index d6144e6..2b0849c 100644 --- a/lib/aes.c +++ b/lib/aes.c @@ -601,12 +601,11 @@ void aes_apply_cbc_chain_data(u8 *cbc_chain_data, u8 *src, u8 *dst) *dst++ = *src++ ^ *cbc_chain_data++; } -void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks) +void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst, + u32 num_aes_blocks) { - u8 zero_key[AES_KEY_LENGTH] = { 0 }; u8 tmp_data[AES_KEY_LENGTH]; - /* Convenient array of 0's for IV */ - u8 *cbc_chain_data = zero_key; + u8 *cbc_chain_data = iv; u32 i; for (i = 0; i < num_aes_blocks; i++) { @@ -628,13 +627,15 @@ void aes_cbc_encrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks) } } -void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *src, u8 *dst, u32 num_aes_blocks) +void aes_cbc_decrypt_blocks(u8 *key_exp, u8 *iv, u8 *src, u8 *dst, + u32 num_aes_blocks) { u8 tmp_data[AES_KEY_LENGTH], tmp_block[AES_KEY_LENGTH]; /* Convenient array of 0's for IV */ - u8 cbc_chain_data[AES_KEY_LENGTH] = { 0 }; + u8 cbc_chain_data[AES_KEY_LENGTH]; u32 i; + memcpy(cbc_chain_data, iv, AES_KEY_LENGTH); for (i = 0; i < num_aes_blocks; i++) { debug("encrypt_object: block %d of %d\n", i, num_aes_blocks); debug_print_vector("AES Src", AES_KEY_LENGTH, src);