From 7012c04ef3dea6ab05cab74879e1ab97c7a086e2 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Mon, 6 Jan 2020 15:22:34 +0100 Subject: aes: add a define for the size of a block In the code, we use the size of the key for the size of the block. It's true when the key is 128 bits, but it become false for key of 192 bits and 256 bits. So to prepare the support of aes192 and 256, we introduce a constant for the iaes block size. Signed-off-by: Philippe Reynes Reviewed-by: Simon Glass --- include/uboot_aes.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/uboot_aes.h b/include/uboot_aes.h index 2fda384e3b..1ae3ac9cb2 100644 --- a/include/uboot_aes.h +++ b/include/uboot_aes.h @@ -18,7 +18,7 @@ typedef unsigned int u32; * AES encryption library, with small code size, supporting only 128-bit AES * * AES is a stream cipher which works a block at a time, with each block - * in this case being AES_KEY_LENGTH bytes. + * in this case being AES_BLOCK_LENGTH bytes. */ enum { @@ -28,6 +28,7 @@ enum { AES_KEY_LENGTH = 128 / 8, AES_EXPAND_KEY_LENGTH = 4 * AES_STATECOLS * (AES_ROUNDS + 1), + AES_BLOCK_LENGTH = 128 / 8, }; /** @@ -62,7 +63,7 @@ void aes_decrypt(u8 *in, u8 *expkey, u8 *out); /** * Apply chain data to the destination using EOR * - * Each array is of length AES_KEY_LENGTH. + * Each array is of length AES_BLOCK_LENGTH. * * @cbc_chain_data Chain data * @src Source data -- cgit From 8302d1708aef720d52942ea47bcebf9c1b8d5de0 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Mon, 6 Jan 2020 15:22:35 +0100 Subject: 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 Reviewed-by: Simon Glass --- include/uboot_aes.h | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/uboot_aes.h b/include/uboot_aes.h index 1ae3ac9cb2..d2583bed99 100644 --- a/include/uboot_aes.h +++ b/include/uboot_aes.h @@ -23,11 +23,18 @@ typedef unsigned int u32; enum { AES_STATECOLS = 4, /* columns in the state & expanded key */ - AES_KEYCOLS = 4, /* columns in a key */ - AES_ROUNDS = 10, /* rounds in encryption */ - - AES_KEY_LENGTH = 128 / 8, - AES_EXPAND_KEY_LENGTH = 4 * AES_STATECOLS * (AES_ROUNDS + 1), + AES128_KEYCOLS = 4, /* columns in a key for aes128 */ + AES192_KEYCOLS = 6, /* columns in a key for aes128 */ + AES256_KEYCOLS = 8, /* columns in a key for aes128 */ + AES128_ROUNDS = 10, /* rounds in encryption for aes128 */ + 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, }; @@ -37,28 +44,31 @@ enum { * Expand a key into a key schedule, which is then used for the other * 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 */ -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 * + * @key_size Size of the aes key (in bits) * @in Input data * @expkey Expanded key to use for encryption (from aes_expand_key()) * @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 * + * @key_size Size of the aes key (in bits) * @in Input data * @expkey Expanded key to use for decryption (from aes_expand_key()) * @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 @@ -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. * + * @key_size Size of the aes key (in bits) * @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 *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); /** * Decrypt multiple blocks of data with AES CBC. * + * @key_size Size of the aes key (in bits) * @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 *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); #endif /* _AES_REF_H_ */ -- cgit From 7298e422504ef4455160216b9b7a1baa1169283f Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Wed, 18 Dec 2019 18:25:41 +0100 Subject: mkimage: fit: add support to encrypt image with aes This commit add the support of encrypting image with aes in mkimage. To enable the ciphering, a node cipher with a reference to a key and IV (Initialization Vector) must be added to the its file. Then mkimage add the encrypted image to the FIT and add the key and IV to the u-boot device tree. Signed-off-by: Philippe Reynes --- include/image.h | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/u-boot/aes.h | 31 ++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 include/u-boot/aes.h (limited to 'include') diff --git a/include/image.h b/include/image.h index 4a280b78e7..bb8abe566f 100644 --- a/include/image.h +++ b/include/image.h @@ -930,6 +930,10 @@ int booti_setup(ulong image, ulong *relocated_addr, ulong *size, #define FIT_IGNORE_PROP "uboot-ignore" #define FIT_SIG_NODENAME "signature" +/* cipher node */ +#define FIT_CIPHER_NODENAME "cipher" +#define FIT_ALGO_PROP "algo" + /* image node */ #define FIT_DATA_PROP "data" #define FIT_DATA_POSITION_PROP "data-position" @@ -1028,6 +1032,10 @@ int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value, int fit_set_timestamp(void *fit, int noffset, time_t timestamp); +int fit_cipher_data(const char *keydir, void *keydest, void *fit, + const char *comment, int require_keys, + const char *engine_id, const char *cmdname); + /** * fit_add_verification_data() - add verification data to FIT image nodes * @@ -1138,6 +1146,7 @@ struct image_sign_info { const char *require_keys; /* Value for 'required' property */ const char *engine_id; /* Engine to use for signing */ }; + #endif /* Allow struct image_region to always be defined for rsa.h */ /* A part of an image, used for hashing */ @@ -1310,6 +1319,60 @@ static inline int fit_image_check_target_arch(const void *fdt, int node) #endif } +/* + * At present we only support ciphering on the host, and unciphering on the + * device + */ +#if defined(USE_HOSTCC) +# if defined(CONFIG_FIT_CIPHER) +# define IMAGE_ENABLE_ENCRYPT 1 +# define IMAGE_ENABLE_DECRYPT 1 +# include +# else +# define IMAGE_ENABLE_ENCRYPT 0 +# define IMAGE_ENABLE_DECRYPT 0 +# endif +#else +# define IMAGE_ENABLE_ENCRYPT 0 +# define IMAGE_ENABLE_DECRYPT CONFIG_IS_ENABLED(FIT_CIPHER) +#endif + +/* Information passed to the ciphering routines */ +struct image_cipher_info { + const char *keydir; /* Directory containing keys */ + const char *keyname; /* Name of key to use */ + const char *ivname; /* Name of IV to use */ + const void *fit; /* Pointer to FIT blob */ + int node_noffset; /* Offset of the cipher node */ + const char *name; /* Algorithm name */ + struct cipher_algo *cipher; /* Cipher algorithm information */ + const void *fdt_blob; /* FDT containing key and IV */ + const void *key; /* Value of the key */ + const void *iv; /* Value of the IV */ + size_t size_unciphered; /* Size of the unciphered data */ +}; + +struct cipher_algo { + const char *name; /* Name of algorithm */ + int key_len; /* Length of the key */ + int iv_len; /* Length of the IV */ + +#if IMAGE_ENABLE_ENCRYPT + const EVP_CIPHER * (*calculate_type)(void); +#endif + + int (*encrypt)(struct image_cipher_info *info, + const unsigned char *data, int data_len, + unsigned char **cipher, int *cipher_len); + + int (*add_cipher_data)(struct image_cipher_info *info, + void *keydest); +}; + +int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo); + +struct cipher_algo *image_get_cipher_algo(const char *full_name); + #ifdef CONFIG_FIT_VERBOSE #define fit_unsupported(msg) printf("! %s:%d " \ "FIT images not supported for '%s'\n", \ diff --git a/include/u-boot/aes.h b/include/u-boot/aes.h new file mode 100644 index 0000000000..4fb2cb7502 --- /dev/null +++ b/include/u-boot/aes.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2019, Softathome + */ + +#ifndef _AES_H +#define _AES_H + +#include +#include + +#if IMAGE_ENABLE_ENCRYPT +int image_aes_encrypt(struct image_cipher_info *info, + const unsigned char *data, int size, + unsigned char **cipher, int *cipher_len); +int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest); +#else +int image_aes_encrypt(struct image_cipher_info *info, + const unsigned char *data, int size, + unsigned char **cipher, int *cipher_len) +{ + return -ENXIO; +} + +int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest) +{ + return -ENXIO; +} +#endif /* IMAGE_ENABLE_ENCRYPT */ + +#endif -- cgit From 4df3578119b043d76b86b50077b06898fc2a4f62 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Wed, 18 Dec 2019 18:25:42 +0100 Subject: u-boot: fit: add support to decrypt fit with aes This commit add to u-boot the support to decrypt fit image encrypted with aes. The FIT image contains the key name and the IV name. Then u-boot look for the key and IV in his device tree and decrypt images before moving to the next stage. Signed-off-by: Philippe Reynes --- include/image.h | 12 ++++++++++++ include/u-boot/aes.h | 13 +++++++++++++ 2 files changed, 25 insertions(+) (limited to 'include') diff --git a/include/image.h b/include/image.h index bb8abe566f..86ebaae4fe 100644 --- a/include/image.h +++ b/include/image.h @@ -1023,6 +1023,8 @@ int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset); int fit_image_get_data_position(const void *fit, int noffset, int *data_position); int fit_image_get_data_size(const void *fit, int noffset, int *data_size); +int fit_image_get_data_size_unciphered(const void *fit, int noffset, + size_t *data_size); int fit_image_get_data_and_size(const void *fit, int noffset, const void **data, size_t *size); @@ -1066,6 +1068,7 @@ int fit_image_verify_with_data(const void *fit, int image_noffset, int fit_image_verify(const void *fit, int noffset); int fit_config_verify(const void *fit, int conf_noffset); int fit_all_image_verify(const void *fit); +int fit_config_decrypt(const void *fit, int conf_noffset); int fit_image_check_os(const void *fit, int noffset, uint8_t os); int fit_image_check_arch(const void *fit, int noffset, uint8_t arch); int fit_image_check_type(const void *fit, int noffset, uint8_t type); @@ -1293,6 +1296,11 @@ int fit_image_verify_required_sigs(const void *fit, int image_noffset, int fit_image_check_sig(const void *fit, int noffset, const void *data, size_t size, int required_keynode, char **err_msgp); +int fit_image_decrypt_data(const void *fit, + int image_noffset, int cipher_noffset, + const void *data, size_t size, + void **data_unciphered, size_t *size_unciphered); + /** * fit_region_make_list() - Make a list of regions to hash * @@ -1367,6 +1375,10 @@ struct cipher_algo { int (*add_cipher_data)(struct image_cipher_info *info, void *keydest); + + int (*decrypt)(struct image_cipher_info *info, + const void *cipher, size_t cipher_len, + void **data, size_t *data_len); }; int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo); diff --git a/include/u-boot/aes.h b/include/u-boot/aes.h index 4fb2cb7502..32281041de 100644 --- a/include/u-boot/aes.h +++ b/include/u-boot/aes.h @@ -28,4 +28,17 @@ int image_aes_add_cipher_data(struct image_cipher_info *info, void *keydest) } #endif /* IMAGE_ENABLE_ENCRYPT */ +#if IMAGE_ENABLE_DECRYPT +int image_aes_decrypt(struct image_cipher_info *info, + const void *cipher, size_t cipher_len, + void **data, size_t *size); +#else +int image_aes_decrypt(struct image_cipher_info *info, + const void *cipher, size_t cipher_len, + void **data, size_t *size) +{ + return -ENXIO; +} +#endif /* IMAGE_ENABLE_DECRYPT */ + #endif -- cgit