1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2019, Softathome 4 */ 5 6#ifdef USE_HOSTCC 7#include "mkimage.h" 8#include <time.h> 9#else 10#include <common.h> 11#include <malloc.h> 12#include <asm/global_data.h> 13DECLARE_GLOBAL_DATA_PTR; 14#endif /* !USE_HOSdTCC*/ 15#include <image.h> 16#include <uboot_aes.h> 17#include <u-boot/aes.h> 18 19struct cipher_algo cipher_algos[] = { 20 { 21 .name = "aes128", 22 .key_len = AES128_KEY_LENGTH, 23 .iv_len = AES_BLOCK_LENGTH, 24#if IMAGE_ENABLE_ENCRYPT 25 .calculate_type = EVP_aes_128_cbc, 26#endif 27 .encrypt = image_aes_encrypt, 28 .decrypt = image_aes_decrypt, 29 .add_cipher_data = image_aes_add_cipher_data 30 }, 31 { 32 .name = "aes192", 33 .key_len = AES192_KEY_LENGTH, 34 .iv_len = AES_BLOCK_LENGTH, 35#if IMAGE_ENABLE_ENCRYPT 36 .calculate_type = EVP_aes_192_cbc, 37#endif 38 .encrypt = image_aes_encrypt, 39 .decrypt = image_aes_decrypt, 40 .add_cipher_data = image_aes_add_cipher_data 41 }, 42 { 43 .name = "aes256", 44 .key_len = AES256_KEY_LENGTH, 45 .iv_len = AES_BLOCK_LENGTH, 46#if IMAGE_ENABLE_ENCRYPT 47 .calculate_type = EVP_aes_256_cbc, 48#endif 49 .encrypt = image_aes_encrypt, 50 .decrypt = image_aes_decrypt, 51 .add_cipher_data = image_aes_add_cipher_data 52 } 53}; 54 55struct cipher_algo *image_get_cipher_algo(const char *full_name) 56{ 57 int i; 58 const char *name; 59 60 for (i = 0; i < ARRAY_SIZE(cipher_algos); i++) { 61 name = cipher_algos[i].name; 62 if (!strncmp(name, full_name, strlen(name))) 63 return &cipher_algos[i]; 64 } 65 66 return NULL; 67} 68 69static int fit_image_setup_decrypt(struct image_cipher_info *info, 70 const void *fit, int image_noffset, 71 int cipher_noffset) 72{ 73 const void *fdt = gd_fdt_blob(); 74 const char *node_name; 75 char node_path[128]; 76 int noffset; 77 char *algo_name; 78 int ret; 79 80 node_name = fit_get_name(fit, image_noffset, NULL); 81 if (!node_name) { 82 printf("Can't get node name\n"); 83 return -1; 84 } 85 86 if (fit_image_cipher_get_algo(fit, cipher_noffset, &algo_name)) { 87 printf("Can't get algo name for cipher '%s' in image '%s'\n", 88 node_name, node_name); 89 return -1; 90 } 91 92 info->keyname = fdt_getprop(fit, cipher_noffset, FIT_KEY_HINT, NULL); 93 if (!info->keyname) { 94 printf("Can't get key name\n"); 95 return -1; 96 } 97 98 info->iv = fdt_getprop(fit, cipher_noffset, "iv", NULL); 99 info->ivname = fdt_getprop(fit, cipher_noffset, "iv-name-hint", NULL); 100 101 if (!info->iv && !info->ivname) { 102 printf("Can't get IV or IV name\n"); 103 return -1; 104 } 105 106 info->fit = fit; 107 info->node_noffset = image_noffset; 108 info->name = algo_name; 109 info->cipher = image_get_cipher_algo(algo_name); 110 if (!info->cipher) { 111 printf("Can't get cipher\n"); 112 return -1; 113 } 114 115 ret = fit_image_get_data_size_unciphered(fit, image_noffset, 116 &info->size_unciphered); 117 if (ret) { 118 printf("Can't get size of unciphered data\n"); 119 return -1; 120 } 121 122 /* 123 * Search the cipher node in the u-boot fdt 124 * the path should be: /cipher/key-<algo>-<key>-<iv> 125 */ 126 if (info->ivname) 127 snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s-%s", 128 FIT_CIPHER_NODENAME, algo_name, info->keyname, info->ivname); 129 else 130 snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s", 131 FIT_CIPHER_NODENAME, algo_name, info->keyname); 132 133 noffset = fdt_path_offset(fdt, node_path); 134 if (noffset < 0) { 135 printf("Can't found cipher node offset\n"); 136 return -1; 137 } 138 139 /* read key */ 140 info->key = fdt_getprop(fdt, noffset, "key", NULL); 141 if (!info->key) { 142 printf("Can't get key in cipher node '%s'\n", node_path); 143 return -1; 144 } 145 146 /* read iv */ 147 if (!info->iv) { 148 info->iv = fdt_getprop(fdt, noffset, "iv", NULL); 149 if (!info->iv) { 150 printf("Can't get IV in cipher node '%s'\n", node_path); 151 return -1; 152 } 153 } 154 155 return 0; 156} 157 158int fit_image_decrypt_data(const void *fit, 159 int image_noffset, int cipher_noffset, 160 const void *data_ciphered, size_t size_ciphered, 161 void **data_unciphered, size_t *size_unciphered) 162{ 163 struct image_cipher_info info; 164 int ret; 165 166 ret = fit_image_setup_decrypt(&info, fit, image_noffset, 167 cipher_noffset); 168 if (ret < 0) 169 goto out; 170 171 ret = info.cipher->decrypt(&info, data_ciphered, size_ciphered, 172 data_unciphered, size_unciphered); 173 174 out: 175 return ret; 176} 177