spi: zynqmp_gqspi: fix set_speed bug on multiple runs
[platform/kernel/u-boot.git] / common / image-cipher.c
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 DECLARE_GLOBAL_DATA_PTR;
13 #endif /* !USE_HOSdTCC*/
14 #include <image.h>
15 #include <uboot_aes.h>
16 #include <u-boot/aes.h>
17
18 struct 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
54 struct 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
68 static 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
157 int 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 }