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