Prepare v2020.04-rc3
[oweals/u-boot.git] / common / image-fit.c
index e346fed550e842538430eb6fcb0a6b192784eeaa..f3bb00c98a55d966c3e68869bd180db8a6fefcc9 100644 (file)
@@ -11,6 +11,7 @@
 #ifdef USE_HOSTCC
 #include "mkimage.h"
 #include <time.h>
+#include <u-boot/crc.h>
 #else
 #include <linux/compiler.h>
 #include <linux/kconfig.h>
@@ -946,6 +947,31 @@ int fit_image_get_data_size(const void *fit, int noffset, int *data_size)
        return 0;
 }
 
+/**
+ * Get 'data-size-unciphered' property from a given image node.
+ *
+ * @fit: pointer to the FIT image header
+ * @noffset: component image node offset
+ * @data_size: holds the data-size property
+ *
+ * returns:
+ *     0, on success
+ *     -ENOENT if the property could not be found
+ */
+int fit_image_get_data_size_unciphered(const void *fit, int noffset,
+                                      size_t *data_size)
+{
+       const fdt32_t *val;
+
+       val = fdt_getprop(fit, noffset, "data-size-unciphered", NULL);
+       if (!val)
+               return -ENOENT;
+
+       *data_size = (size_t)fdt32_to_cpu(*val);
+
+       return 0;
+}
+
 /**
  * fit_image_get_data_and_size - get data and its size including
  *                              both embedded and external data
@@ -1079,6 +1105,33 @@ static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
        return 0;
 }
 
+/**
+ * fit_image_cipher_get_algo - get cipher algorithm name
+ * @fit: pointer to the FIT format image header
+ * @noffset: cipher node offset
+ * @algo: double pointer to char, will hold pointer to the algorithm name
+ *
+ * fit_image_cipher_get_algo() finds cipher algorithm property in a given
+ * cipher node. If the property is found its data start address is returned
+ * to the caller.
+ *
+ * returns:
+ *     0, on success
+ *     -1, on failure
+ */
+int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo)
+{
+       int len;
+
+       *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
+       if (!*algo) {
+               fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
+               return -1;
+       }
+
+       return 0;
+}
+
 ulong fit_get_end(const void *fit)
 {
        return map_to_sysmem((void *)(fit + fdt_totalsize(fit)));
@@ -1353,6 +1406,32 @@ int fit_all_image_verify(const void *fit)
        return 1;
 }
 
+#ifdef CONFIG_FIT_CIPHER
+static int fit_image_uncipher(const void *fit, int image_noffset,
+                             void **data, size_t *size)
+{
+       int cipher_noffset, ret;
+       void *dst;
+       size_t size_dst;
+
+       cipher_noffset = fdt_subnode_offset(fit, image_noffset,
+                                           FIT_CIPHER_NODENAME);
+       if (cipher_noffset < 0)
+               return 0;
+
+       ret = fit_image_decrypt_data(fit, image_noffset, cipher_noffset,
+                                    *data, *size, &dst, &size_dst);
+       if (ret)
+               goto out;
+
+       *data = dst;
+       *size = size_dst;
+
+ out:
+       return ret;
+}
+#endif /* CONFIG_FIT_CIPHER */
+
 /**
  * fit_image_check_os - check whether image node is of a given os type
  * @fit: pointer to the FIT format image header
@@ -1925,7 +2004,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
                image_type == IH_TYPE_FPGA ||
                fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
                fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
-               fit_image_check_os(fit, noffset, IH_OS_OPENRTOS);
+               fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
+               fit_image_check_os(fit, noffset, IH_OS_EFI);
 
        /*
         * If either of the checks fail, we should report an error, but
@@ -1952,6 +2032,18 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
                return -ENOENT;
        }
 
+#ifdef CONFIG_FIT_CIPHER
+       /* Decrypt data before uncompress/move */
+       if (IMAGE_ENABLE_DECRYPT) {
+               puts("   Decrypting Data ... ");
+               if (fit_image_uncipher(fit, noffset, &buf, &size)) {
+                       puts("Error\n");
+                       return -EACCES;
+               }
+               puts("OK\n");
+       }
+#endif
+
 #if !defined(USE_HOSTCC) && defined(CONFIG_FIT_IMAGE_POST_PROCESS)
        /* perform any post-processing on the image data */
        board_fit_image_post_process(&buf, &size);
@@ -1998,10 +2090,11 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
        comp = IH_COMP_NONE;
        loadbuf = buf;
        /* Kernel images get decompressed later in bootm_load_os(). */
-       if (!(image_type == IH_TYPE_KERNEL ||
-             image_type == IH_TYPE_KERNEL_NOLOAD) &&
-           !fit_image_get_comp(fit, noffset, &comp) &&
-           comp != IH_COMP_NONE) {
+       if (!fit_image_get_comp(fit, noffset, &comp) &&
+           comp != IH_COMP_NONE &&
+           !(image_type == IH_TYPE_KERNEL ||
+             image_type == IH_TYPE_KERNEL_NOLOAD ||
+             image_type == IH_TYPE_RAMDISK)) {
                ulong max_decomp_len = len * 20;
                if (load == data) {
                        loadbuf = malloc(max_decomp_len);
@@ -2021,6 +2114,10 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
                memcpy(loadbuf, buf, len);
        }
 
+       if (image_type == IH_TYPE_RAMDISK && comp != IH_COMP_NONE)
+               puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
+                    " please fix your .its file!\n");
+
        /* verify that image data is a proper FDT blob */
        if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
                puts("Subimage data is not a FDT");