blob: 4ca9eec4ef1506cde0ddf6bcb0104fee087c89b0 [file] [log] [blame]
Philippe Reynes3148e422019-12-18 18:25:41 +01001// 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>
12DECLARE_GLOBAL_DATA_PTR;
Simon Glass4dcacfc2020-05-10 11:40:13 -060013#endif /* !USE_HOSdTCC*/
Philippe Reynes3148e422019-12-18 18:25:41 +010014#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,
Philippe Reynes3d964702019-12-18 18:25:42 +010027 .decrypt = image_aes_decrypt,
Philippe Reynes3148e422019-12-18 18:25:41 +010028 .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,
Philippe Reynes3d964702019-12-18 18:25:42 +010038 .decrypt = image_aes_decrypt,
Philippe Reynes3148e422019-12-18 18:25:41 +010039 .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,
Philippe Reynes3d964702019-12-18 18:25:42 +010049 .decrypt = image_aes_decrypt,
Philippe Reynes3148e422019-12-18 18:25:41 +010050 .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}
Philippe Reynes3d964702019-12-18 18:25:42 +010067
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
Simon Glassd7aabcc2020-03-18 11:44:06 -060091 info->keyname = fdt_getprop(fit, cipher_noffset, FIT_KEY_HINT, NULL);
Philippe Reynes3d964702019-12-18 18:25:42 +010092 if (!info->keyname) {
93 printf("Can't get key name\n");
94 return -1;
95 }
96
Philippe Reynesa82ea9d2020-09-17 15:01:47 +020097 info->iv = fdt_getprop(fit, cipher_noffset, "iv", NULL);
Philippe Reynes3d964702019-12-18 18:25:42 +010098 info->ivname = fdt_getprop(fit, cipher_noffset, "iv-name-hint", NULL);
Philippe Reynesa82ea9d2020-09-17 15:01:47 +020099
100 if (!info->iv && !info->ivname) {
101 printf("Can't get IV or IV name\n");
Philippe Reynes3d964702019-12-18 18:25:42 +0100102 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 */
Philippe Reynesa82ea9d2020-09-17 15:01:47 +0200125 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);
Philippe Reynes3d964702019-12-18 18:25:42 +0100131
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 */
Philippe Reynes3d964702019-12-18 18:25:42 +0100146 if (!info->iv) {
Philippe Reynesa82ea9d2020-09-17 15:01:47 +0200147 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 }
Philippe Reynes3d964702019-12-18 18:25:42 +0100152 }
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}