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 --- common/image-cipher.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) (limited to 'common/image-cipher.c') diff --git a/common/image-cipher.c b/common/image-cipher.c index ab8b45b..cee3b03 100644 --- a/common/image-cipher.c +++ b/common/image-cipher.c @@ -24,6 +24,7 @@ struct cipher_algo cipher_algos[] = { .calculate_type = EVP_aes_128_cbc, #endif .encrypt = image_aes_encrypt, + .decrypt = image_aes_decrypt, .add_cipher_data = image_aes_add_cipher_data }, { @@ -34,6 +35,7 @@ struct cipher_algo cipher_algos[] = { .calculate_type = EVP_aes_192_cbc, #endif .encrypt = image_aes_encrypt, + .decrypt = image_aes_decrypt, .add_cipher_data = image_aes_add_cipher_data }, { @@ -44,6 +46,7 @@ struct cipher_algo cipher_algos[] = { .calculate_type = EVP_aes_256_cbc, #endif .encrypt = image_aes_encrypt, + .decrypt = image_aes_decrypt, .add_cipher_data = image_aes_add_cipher_data } }; @@ -61,3 +64,104 @@ struct cipher_algo *image_get_cipher_algo(const char *full_name) return NULL; } + +static int fit_image_setup_decrypt(struct image_cipher_info *info, + const void *fit, int image_noffset, + int cipher_noffset) +{ + const void *fdt = gd_fdt_blob(); + const char *node_name; + char node_path[128]; + int noffset; + char *algo_name; + int ret; + + node_name = fit_get_name(fit, image_noffset, NULL); + if (!node_name) { + printf("Can't get node name\n"); + return -1; + } + + if (fit_image_cipher_get_algo(fit, cipher_noffset, &algo_name)) { + printf("Can't get algo name for cipher '%s' in image '%s'\n", + node_name, node_name); + return -1; + } + + info->keyname = fdt_getprop(fit, cipher_noffset, "key-name-hint", NULL); + if (!info->keyname) { + printf("Can't get key name\n"); + return -1; + } + + info->ivname = fdt_getprop(fit, cipher_noffset, "iv-name-hint", NULL); + if (!info->ivname) { + printf("Can't get IV name\n"); + return -1; + } + + info->fit = fit; + info->node_noffset = image_noffset; + info->name = algo_name; + info->cipher = image_get_cipher_algo(algo_name); + if (!info->cipher) { + printf("Can't get cipher\n"); + return -1; + } + + ret = fit_image_get_data_size_unciphered(fit, image_noffset, + &info->size_unciphered); + if (ret) { + printf("Can't get size of unciphered data\n"); + return -1; + } + + /* + * Search the cipher node in the u-boot fdt + * the path should be: /cipher/key--- + */ + snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s-%s", + FIT_CIPHER_NODENAME, algo_name, info->keyname, info->ivname); + + noffset = fdt_path_offset(fdt, node_path); + if (noffset < 0) { + printf("Can't found cipher node offset\n"); + return -1; + } + + /* read key */ + info->key = fdt_getprop(fdt, noffset, "key", NULL); + if (!info->key) { + printf("Can't get key in cipher node '%s'\n", node_path); + return -1; + } + + /* read iv */ + info->iv = fdt_getprop(fdt, noffset, "iv", NULL); + if (!info->iv) { + printf("Can't get IV in cipher node '%s'\n", node_path); + return -1; + } + + return 0; +} + +int fit_image_decrypt_data(const void *fit, + int image_noffset, int cipher_noffset, + const void *data_ciphered, size_t size_ciphered, + void **data_unciphered, size_t *size_unciphered) +{ + struct image_cipher_info info; + int ret; + + ret = fit_image_setup_decrypt(&info, fit, image_noffset, + cipher_noffset); + if (ret < 0) + goto out; + + ret = info.cipher->decrypt(&info, data_ciphered, size_ciphered, + data_unciphered, size_unciphered); + + out: + return ret; +} -- cgit v1.1