image: Adjust the workings of fit_check_format()
[platform/kernel/u-boot.git] / arch / arm / cpu / armv8 / sec_firmware.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2016 NXP Semiconductor, Inc.
4  */
5
6 #include <common.h>
7 #include <cpu_func.h>
8 #include <errno.h>
9 #include <fdt_support.h>
10 #include <image.h>
11 #include <log.h>
12 #include <asm/cache.h>
13 #include <asm/global_data.h>
14 #include <asm/ptrace.h>
15 #include <linux/kernel.h>
16 #include <asm/io.h>
17 #include <asm/system.h>
18 #include <asm/types.h>
19 #include <asm/macro.h>
20 #include <asm/armv8/sec_firmware.h>
21
22 DECLARE_GLOBAL_DATA_PTR;
23 extern void c_runtime_cpu_setup(void);
24
25 #define SEC_FIRMWARE_LOADED     0x1
26 #define SEC_FIRMWARE_RUNNING    0x2
27 #define SEC_FIRMWARE_ADDR_MASK  (~0x3)
28 /*
29  * Secure firmware load addr
30  * Flags used: 0x1 secure firmware has been loaded to secure memory
31  *             0x2 secure firmware is running
32  */
33 phys_addr_t sec_firmware_addr;
34
35 #ifndef SEC_FIRMWARE_FIT_IMAGE
36 #define SEC_FIRMWARE_FIT_IMAGE          "firmware"
37 #endif
38 #ifndef SEC_FIRMWARE_FIT_CNF_NAME
39 #define SEC_FIRMWARE_FIT_CNF_NAME       "config-1"
40 #endif
41 #ifndef SEC_FIRMWARE_TARGET_EL
42 #define SEC_FIRMWARE_TARGET_EL          2
43 #endif
44
45 static int sec_firmware_get_data(const void *sec_firmware_img,
46                                 const void **data, size_t *size)
47 {
48         int conf_node_off, fw_node_off;
49         char *conf_node_name = NULL;
50         char *desc;
51         int ret;
52
53         conf_node_name = SEC_FIRMWARE_FIT_CNF_NAME;
54
55         conf_node_off = fit_conf_get_node(sec_firmware_img, conf_node_name);
56         if (conf_node_off < 0) {
57                 printf("SEC Firmware: %s: no such config\n", conf_node_name);
58                 return -ENOENT;
59         }
60
61         fw_node_off = fit_conf_get_prop_node(sec_firmware_img, conf_node_off,
62                         SEC_FIRMWARE_FIT_IMAGE);
63         if (fw_node_off < 0) {
64                 printf("SEC Firmware: No '%s' in config\n",
65                        SEC_FIRMWARE_FIT_IMAGE);
66                 return -ENOLINK;
67         }
68
69         /* Verify secure firmware image */
70         if (!(fit_image_verify(sec_firmware_img, fw_node_off))) {
71                 printf("SEC Firmware: Bad firmware image (bad CRC)\n");
72                 return -EINVAL;
73         }
74
75         if (fit_image_get_data(sec_firmware_img, fw_node_off, data, size)) {
76                 printf("SEC Firmware: Can't get %s subimage data/size",
77                        SEC_FIRMWARE_FIT_IMAGE);
78                 return -ENOENT;
79         }
80
81         ret = fit_get_desc(sec_firmware_img, fw_node_off, &desc);
82         if (ret)
83                 printf("SEC Firmware: Can't get description\n");
84         else
85                 printf("%s\n", desc);
86
87         return ret;
88 }
89
90 /*
91  * SEC Firmware FIT image parser checks if the image is in FIT
92  * format, verifies integrity of the image and calculates raw
93  * image address and size values.
94  *
95  * Returns 0 on success and a negative errno on error task fail.
96  */
97 static int sec_firmware_parse_image(const void *sec_firmware_img,
98                                         const void **raw_image_addr,
99                                         size_t *raw_image_size)
100 {
101         int ret;
102
103         ret = sec_firmware_get_data(sec_firmware_img, raw_image_addr,
104                                         raw_image_size);
105         if (ret)
106                 return ret;
107
108         debug("SEC Firmware: raw_image_addr = 0x%p, raw_image_size = 0x%lx\n",
109               *raw_image_addr, *raw_image_size);
110
111         return 0;
112 }
113
114 /*
115  * SEC Firmware FIT image parser to check if any loadable is
116  * present. If present, verify integrity of the loadable and
117  * copy loadable to address provided in (loadable_h, loadable_l).
118  *
119  * Returns 0 on success and a negative errno on error task fail.
120  */
121 static int sec_firmware_check_copy_loadable(const void *sec_firmware_img,
122                                             u32 *loadable_l, u32 *loadable_h)
123 {
124         phys_addr_t sec_firmware_loadable_addr = 0;
125         int conf_node_off, ld_node_off, images;
126         char *conf_node_name = NULL;
127         const void *data;
128         size_t size;
129         ulong load;
130         const char *name, *str, *type;
131         int len;
132
133         conf_node_name = SEC_FIRMWARE_FIT_CNF_NAME;
134
135         conf_node_off = fit_conf_get_node(sec_firmware_img, conf_node_name);
136         if (conf_node_off < 0) {
137                 printf("SEC Firmware: %s: no such config\n", conf_node_name);
138                 return -ENOENT;
139         }
140
141         /* find the node holding the images information */
142         images = fdt_path_offset(sec_firmware_img, FIT_IMAGES_PATH);
143         if (images < 0) {
144                 printf("%s: Cannot find /images node: %d\n", __func__, images);
145                 return -1;
146         }
147
148         type = FIT_LOADABLE_PROP;
149
150         name = fdt_getprop(sec_firmware_img, conf_node_off, type, &len);
151         if (!name) {
152                 /* Loadables not present */
153                 return 0;
154         }
155
156         printf("SEC Firmware: '%s' present in config\n", type);
157
158         for (str = name; str && ((str - name) < len);
159              str = strchr(str, '\0') + 1) {
160                 printf("%s: '%s'\n", type, str);
161                 ld_node_off = fdt_subnode_offset(sec_firmware_img, images, str);
162                 if (ld_node_off < 0) {
163                         printf("cannot find image node '%s': %d\n", str,
164                                ld_node_off);
165                         return -EINVAL;
166                 }
167
168                 /* Verify secure firmware image */
169                 if (!(fit_image_verify(sec_firmware_img, ld_node_off))) {
170                         printf("SEC Loadable: Bad loadable image (bad CRC)\n");
171                         return -EINVAL;
172                 }
173
174                 if (fit_image_get_data(sec_firmware_img, ld_node_off,
175                                        &data, &size)) {
176                         printf("SEC Loadable: Can't get subimage data/size");
177                         return -ENOENT;
178                 }
179
180                 /* Get load address, treated as load offset to secure memory */
181                 if (fit_image_get_load(sec_firmware_img, ld_node_off, &load)) {
182                         printf("SEC Loadable: Can't get subimage load");
183                         return -ENOENT;
184                 }
185
186                 /* Compute load address for loadable in secure memory */
187                 sec_firmware_loadable_addr = (sec_firmware_addr -
188                                                 gd->arch.tlb_size) + load;
189
190                 /* Copy loadable to secure memory and flush dcache */
191                 debug("%s copied to address 0x%p\n",
192                       FIT_LOADABLE_PROP, (void *)sec_firmware_loadable_addr);
193                 memcpy((void *)sec_firmware_loadable_addr, data, size);
194                 flush_dcache_range(sec_firmware_loadable_addr,
195                                    sec_firmware_loadable_addr + size);
196
197                 /* Populate loadable address only for Trusted OS */
198                 if (!strcmp(str, "trustedOS@1")) {
199                         /*
200                          * Populate address ptrs for loadable image with
201                          * loadbale addr
202                          */
203                         out_le32(loadable_l, (sec_firmware_loadable_addr &
204                                               WORD_MASK));
205                         out_le32(loadable_h, (sec_firmware_loadable_addr >>
206                                               WORD_SHIFT));
207                 }
208         }
209
210         return 0;
211 }
212
213 static int sec_firmware_copy_image(const char *title,
214                          u64 image_addr, u32 image_size, u64 sec_firmware)
215 {
216         debug("%s copied to address 0x%p\n", title, (void *)sec_firmware);
217         memcpy((void *)sec_firmware, (void *)image_addr, image_size);
218         flush_dcache_range(sec_firmware, sec_firmware + image_size);
219
220         return 0;
221 }
222
223 /*
224  * This function will parse the SEC Firmware image, and then load it
225  * to secure memory. Also load any loadable if present along with SEC
226  * Firmware image.
227  */
228 static int sec_firmware_load_image(const void *sec_firmware_img,
229                                    u32 *loadable_l, u32 *loadable_h)
230 {
231         const void *raw_image_addr;
232         size_t raw_image_size = 0;
233         int ret;
234
235         /*
236          * The Excetpion Level must be EL3 to load and initialize
237          * the SEC Firmware.
238          */
239         if (current_el() != 3) {
240                 ret = -EACCES;
241                 goto out;
242         }
243
244 #ifdef CONFIG_SYS_MEM_RESERVE_SECURE
245         /*
246          * The SEC Firmware must be stored in secure memory.
247          * Append SEC Firmware to secure mmu table.
248          */
249         if (!(gd->arch.secure_ram & MEM_RESERVE_SECURE_MAINTAINED)) {
250                 ret = -ENXIO;
251                 goto out;
252         }
253
254         sec_firmware_addr = (gd->arch.secure_ram & MEM_RESERVE_SECURE_ADDR_MASK) +
255                         gd->arch.tlb_size;
256 #else
257 #error "The CONFIG_SYS_MEM_RESERVE_SECURE must be defined when enabled SEC Firmware support"
258 #endif
259
260         /* Align SEC Firmware base address to 4K */
261         sec_firmware_addr = (sec_firmware_addr + 0xfff) & ~0xfff;
262         debug("SEC Firmware: Load address: 0x%llx\n",
263               sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);
264
265         ret = sec_firmware_parse_image(sec_firmware_img, &raw_image_addr,
266                         &raw_image_size);
267         if (ret)
268                 goto out;
269
270         /* TODO:
271          * Check if the end addr of SEC Firmware has been extend the secure
272          * memory.
273          */
274
275         /* Copy the secure firmware to secure memory */
276         ret = sec_firmware_copy_image("SEC Firmware", (u64)raw_image_addr,
277                         raw_image_size, sec_firmware_addr &
278                         SEC_FIRMWARE_ADDR_MASK);
279         if (ret)
280                 goto out;
281
282         /*
283          * Check if any loadable are present along with firmware image, if
284          * present load them.
285          */
286         ret = sec_firmware_check_copy_loadable(sec_firmware_img, loadable_l,
287                                                loadable_h);
288         if (ret)
289                 goto out;
290
291         sec_firmware_addr |= SEC_FIRMWARE_LOADED;
292         debug("SEC Firmware: Entry point: 0x%llx\n",
293               sec_firmware_addr & SEC_FIRMWARE_ADDR_MASK);
294
295         return 0;
296
297 out:
298         printf("SEC Firmware: error (%d)\n", ret);
299         sec_firmware_addr = 0;
300
301         return ret;
302 }
303
304 static int sec_firmware_entry(u32 *eret_hold_l, u32 *eret_hold_h)
305 {
306         const void *entry = (void *)(sec_firmware_addr &
307                                 SEC_FIRMWARE_ADDR_MASK);
308
309         return _sec_firmware_entry(entry, eret_hold_l, eret_hold_h);
310 }
311
312 /* Check the secure firmware FIT image */
313 __weak bool sec_firmware_is_valid(const void *sec_firmware_img)
314 {
315         if (fdt_check_header(sec_firmware_img)) {
316                 printf("SEC Firmware: Bad firmware image (not a FIT image)\n");
317                 return false;
318         }
319
320         if (fit_check_format(sec_firmware_img, IMAGE_SIZE_INVAL)) {
321                 printf("SEC Firmware: Bad firmware image (bad FIT header)\n");
322                 return false;
323         }
324
325         return true;
326 }
327
328 #ifdef CONFIG_SEC_FIRMWARE_ARMV8_PSCI
329 /*
330  * The PSCI_VERSION function is added from PSCI v0.2. When the PSCI
331  * v0.1 received this function, the NOT_SUPPORTED (0xffff_ffff) error
332  * number will be returned according to SMC Calling Conventions. But
333  * when getting the NOT_SUPPORTED error number, we cannot ensure if
334  * the PSCI version is v0.1 or other error occurred. So, PSCI v0.1
335  * won't be supported by this framework.
336  * And if the secure firmware isn't running, return NOT_SUPPORTED.
337  *
338  * The return value on success is PSCI version in format
339  * major[31:16]:minor[15:0].
340  */
341 unsigned int sec_firmware_support_psci_version(void)
342 {
343         if (current_el() == SEC_FIRMWARE_TARGET_EL)
344                 return _sec_firmware_support_psci_version();
345
346         return PSCI_INVALID_VER;
347 }
348 #endif
349
350 /*
351  * Check with sec_firmware if it supports random number generation
352  * via HW RNG
353  *
354  * The return value will be true if it is supported
355  */
356 bool sec_firmware_support_hwrng(void)
357 {
358 #ifdef CONFIG_TFABOOT
359         /* return true as TFA has one job ring reserved */
360         return true;
361 #endif
362         if (sec_firmware_addr & SEC_FIRMWARE_RUNNING) {
363                 return true;
364         }
365
366         return false;
367 }
368
369 /*
370  * sec_firmware_get_random - Get a random number from SEC Firmware
371  * @rand:               random number buffer to be filled
372  * @bytes:              Number of bytes of random number to be supported
373  * @eret:               -1 in case of error, 0 for success
374  */
375 int sec_firmware_get_random(uint8_t *rand, int bytes)
376 {
377         unsigned long long num;
378         struct pt_regs regs;
379         int param1;
380
381         if (!bytes || bytes > 8) {
382                 printf("Max Random bytes genration supported is 8\n");
383                 return -1;
384         }
385 #define SIP_RNG_64 0xC200FF11
386         regs.regs[0] = SIP_RNG_64;
387
388         if (bytes <= 4)
389                 param1 = 0;
390         else
391                 param1 = 1;
392         regs.regs[1] = param1;
393
394         smc_call(&regs);
395
396         if (regs.regs[0])
397                 return -1;
398
399         num = regs.regs[1];
400         memcpy(rand, &num, bytes);
401
402         return 0;
403 }
404
405 /*
406  * sec_firmware_init - Initialize the SEC Firmware
407  * @sec_firmware_img:   the SEC Firmware image address
408  * @eret_hold_l:        the address to hold exception return address low
409  * @eret_hold_h:        the address to hold exception return address high
410  * @loadable_l:         the address to hold loadable address low
411  * @loadable_h:         the address to hold loadable address high
412  */
413 int sec_firmware_init(const void *sec_firmware_img,
414                         u32 *eret_hold_l,
415                         u32 *eret_hold_h,
416                         u32 *loadable_l,
417                         u32 *loadable_h)
418 {
419         int ret;
420
421         if (!sec_firmware_is_valid(sec_firmware_img))
422                 return -EINVAL;
423
424         ret = sec_firmware_load_image(sec_firmware_img, loadable_l,
425                                       loadable_h);
426         if (ret) {
427                 printf("SEC Firmware: Failed to load image\n");
428                 return ret;
429         } else if (sec_firmware_addr & SEC_FIRMWARE_LOADED) {
430                 ret = sec_firmware_entry(eret_hold_l, eret_hold_h);
431                 if (ret) {
432                         printf("SEC Firmware: Failed to initialize\n");
433                         return ret;
434                 }
435         }
436
437         debug("SEC Firmware: Return from SEC Firmware: current_el = %d\n",
438               current_el());
439
440         /*
441          * The PE will be turned into target EL when returned from
442          * SEC Firmware.
443          */
444         if (current_el() != SEC_FIRMWARE_TARGET_EL)
445                 return -EACCES;
446
447         sec_firmware_addr |= SEC_FIRMWARE_RUNNING;
448
449         /* Set exception table and enable caches if it isn't EL3 */
450         if (current_el() != 3) {
451                 c_runtime_cpu_setup();
452                 enable_caches();
453         }
454
455         return 0;
456 }
457
458 /*
459  * fdt_fix_kaslr - Add kalsr-seed node in Device tree
460  * @fdt:                Device tree
461  * @eret:               0 in case of error, 1 for success
462  */
463 int fdt_fixup_kaslr(void *fdt)
464 {
465         int nodeoffset;
466         int err, ret = 0;
467         u8 rand[8];
468
469 #if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT)
470         /* Check if random seed generation is  supported */
471         if (sec_firmware_support_hwrng() == false) {
472                 printf("WARNING: SEC firmware not running, no kaslr-seed\n");
473                 return 0;
474         }
475
476         ret = sec_firmware_get_random(rand, 8);
477         if (ret < 0) {
478                 printf("WARNING: No random number to set kaslr-seed\n");
479                 return 0;
480         }
481
482         err = fdt_check_header(fdt);
483         if (err < 0) {
484                 printf("fdt_chosen: %s\n", fdt_strerror(err));
485                 return 0;
486         }
487
488         /* find or create "/chosen" node. */
489         nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");
490         if (nodeoffset < 0)
491                 return 0;
492
493         err = fdt_setprop(fdt, nodeoffset, "kaslr-seed", rand,
494                                   sizeof(rand));
495         if (err < 0) {
496                 printf("WARNING: can't set kaslr-seed %s.\n",
497                        fdt_strerror(err));
498                 return 0;
499         }
500         ret = 1;
501 #endif
502
503         return ret;
504 }