Merge branch 'master' of git://git.denx.de/u-boot
[oweals/u-boot.git] / common / image-fit.c
index 5c63c769de274e721ae767fae96da61f013bb8be..368b73088a2af9d0683e050ec13a9e33513f1481 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>
@@ -167,7 +168,7 @@ static void fit_image_print_data(const void *fit, int noffset, const char *p,
        int value_len;
        char *algo;
        const char *padding;
-       int required;
+       bool required;
        int ret, i;
 
        debug("%s  %s node:    '%s'\n", p, type,
@@ -178,8 +179,8 @@ static void fit_image_print_data(const void *fit, int noffset, const char *p,
                return;
        }
        printf("%s", algo);
-       keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
-       required = fdt_getprop(fit, noffset, "required", NULL) != NULL;
+       keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
+       required = fdt_getprop(fit, noffset, FIT_KEY_REQUIRED, NULL) != NULL;
        if (keyname)
                printf(":%s", keyname);
        if (required)
@@ -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
@@ -985,8 +1011,10 @@ int fit_image_get_data_and_size(const void *fit, int noffset,
        if (external_data) {
                debug("External Data\n");
                ret = fit_image_get_data_size(fit, noffset, &len);
-               *data = fit + offset;
-               *size = len;
+               if (!ret) {
+                       *data = fit + offset;
+                       *size = len;
+               }
        } else {
                ret = fit_image_get_data(fit, noffset, data, size);
        }
@@ -1079,6 +1107,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)));
@@ -1216,7 +1271,7 @@ int fit_image_verify_with_data(const void *fit, int image_noffset,
        int ret;
 
        /* Verify all required signatures */
-       if (IMAGE_ENABLE_VERIFY &&
+       if (FIT_IMAGE_ENABLE_VERIFY &&
            fit_image_verify_required_sigs(fit, image_noffset, data, size,
                                           gd_fdt_blob(), &verify_all)) {
                err_msg = "Unable to verify required signature";
@@ -1238,7 +1293,7 @@ int fit_image_verify_with_data(const void *fit, int image_noffset,
                                                 &err_msg))
                                goto error;
                        puts("+ ");
-               } else if (IMAGE_ENABLE_VERIFY && verify_all &&
+               } else if (FIT_IMAGE_ENABLE_VERIFY && verify_all &&
                                !strncmp(name, FIT_SIG_NODENAME,
                                        strlen(FIT_SIG_NODENAME))) {
                        ret = fit_image_check_sig(fit, noffset, data,
@@ -1353,6 +1408,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
@@ -1631,24 +1712,6 @@ int fit_conf_find_compat(const void *fit, const void *fdt)
        return best_match_offset;
 }
 
-/**
- * fit_conf_get_node - get node offset for configuration of a given unit name
- * @fit: pointer to the FIT format image header
- * @conf_uname: configuration node unit name
- *
- * fit_conf_get_node() finds a configuration (within the '/configurations'
- * parent node) of a provided unit name. If configuration is found its node
- * offset is returned to the caller.
- *
- * When NULL is provided in second argument fit_conf_get_node() will search
- * for a default configuration node instead. Default configuration node unit
- * name is retrieved from FIT_DEFAULT_PROP property of the '/configurations'
- * node.
- *
- * returns:
- *     configuration node offset when found (>=0)
- *     negative number on failure (FDT_ERR_* code)
- */
 int fit_conf_get_node(const void *fit, const char *conf_uname)
 {
        int noffset, confs_noffset;
@@ -1870,7 +1933,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
                if (image_type == IH_TYPE_KERNEL)
                        images->fit_uname_cfg = fit_base_uname_config;
 
-               if (IMAGE_ENABLE_VERIFY && images->verify) {
+               if (FIT_IMAGE_ENABLE_VERIFY && images->verify) {
                        puts("   Verifying Hash Integrity ... ");
                        if (fit_config_verify(fit, cfg_noffset)) {
                                puts("Bad Data Hash\n");
@@ -1888,7 +1951,7 @@ int fit_image_load(bootm_headers_t *images, ulong addr,
                fit_uname = fit_get_name(fit, noffset, NULL);
        }
        if (noffset < 0) {
-               puts("Could not find subimage node\n");
+               printf("Could not find subimage node type '%s'\n", prop_name);
                bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
                return -ENOENT;
        }
@@ -1925,7 +1988,9 @@ 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) ||
+               fit_image_check_os(fit, noffset, IH_OS_VXWORKS);
 
        /*
         * If either of the checks fail, we should report an error, but
@@ -1952,6 +2017,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);