blob: cee3b03ee50622c95ce59d9da8f3e0c4f369afe2 [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;
13#endif /* !USE_HOSTCC*/
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,
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
91 info->keyname = fdt_getprop(fit, cipher_noffset, "key-name-hint", NULL);
92 if (!info->keyname) {
93 printf("Can't get key name\n");
94 return -1;
95 }
96
97 info->ivname = fdt_getprop(fit, cipher_noffset, "iv-name-hint", NULL);
98 if (!info->ivname) {
99 printf("Can't get IV name\n");
100 return -1;
101 }
102
103 info->fit = fit;
104 info->node_noffset = image_noffset;
105 info->name = algo_name;
106 info->cipher = image_get_cipher_algo(algo_name);
107 if (!info->cipher) {
108 printf("Can't get cipher\n");
109 return -1;
110 }
111
112 ret = fit_image_get_data_size_unciphered(fit, image_noffset,
113 &info->size_unciphered);
114 if (ret) {
115 printf("Can't get size of unciphered data\n");
116 return -1;
117 }
118
119 /*
120 * Search the cipher node in the u-boot fdt
121 * the path should be: /cipher/key-<algo>-<key>-<iv>
122 */
123 snprintf(node_path, sizeof(node_path), "/%s/key-%s-%s-%s",
124 FIT_CIPHER_NODENAME, algo_name, info->keyname, info->ivname);
125
126 noffset = fdt_path_offset(fdt, node_path);
127 if (noffset < 0) {
128 printf("Can't found cipher node offset\n");
129 return -1;
130 }
131
132 /* read key */
133 info->key = fdt_getprop(fdt, noffset, "key", NULL);
134 if (!info->key) {
135 printf("Can't get key in cipher node '%s'\n", node_path);
136 return -1;
137 }
138
139 /* read iv */
140 info->iv = fdt_getprop(fdt, noffset, "iv", NULL);
141 if (!info->iv) {
142 printf("Can't get IV in cipher node '%s'\n", node_path);
143 return -1;
144 }
145
146 return 0;
147}
148
149int fit_image_decrypt_data(const void *fit,
150 int image_noffset, int cipher_noffset,
151 const void *data_ciphered, size_t size_ciphered,
152 void **data_unciphered, size_t *size_unciphered)
153{
154 struct image_cipher_info info;
155 int ret;
156
157 ret = fit_image_setup_decrypt(&info, fit, image_noffset,
158 cipher_noffset);
159 if (ret < 0)
160 goto out;
161
162 ret = info.cipher->decrypt(&info, data_ciphered, size_ciphered,
163 data_unciphered, size_unciphered);
164
165 out:
166 return ret;
167}