]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/image-fit.c
Merge branch 'master' of git://git.denx.de/u-boot-i2c
[karo-tx-uboot.git] / common / image-fit.c
index 7bf82d33cf7bce134b13613a445a5311e2988031..683c1a511d8f4882e6f16119d92569ffb6a36801 100644 (file)
@@ -6,23 +6,7 @@
  * (C) Copyright 2000-2006
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #ifdef USE_HOSTCC
@@ -234,42 +218,45 @@ void fit_print_contents(const void *fit)
  * @fit: pointer to the FIT format image header
  * @noffset: offset of the hash node
  * @p: pointer to prefix string
+ * @type: Type of information to print ("hash" or "sign")
  *
  * fit_image_print_data() lists properies for the processed hash node
  *
+ * This function avoid using puts() since it prints a newline on the host
+ * but does not in U-Boot.
+ *
  * returns:
  *     no returned results
  */
-static void fit_image_print_data(const void *fit, int noffset, const char *p)
+static void fit_image_print_data(const void *fit, int noffset, const char *p,
+                                const char *type)
 {
-       char *algo;
+       const char *keyname;
        uint8_t *value;
        int value_len;
-       int i, ret;
-
-       /*
-        * Check subnode name, must be equal to "hash".
-        * Multiple hash nodes require unique unit node
-        * names, e.g. hash@1, hash@2, etc.
-        */
-       if (strncmp(fit_get_name(fit, noffset, NULL),
-                   FIT_HASH_NODENAME,
-                   strlen(FIT_HASH_NODENAME)) != 0)
-               return;
+       char *algo;
+       int required;
+       int ret, i;
 
-       debug("%s  Hash node:    '%s'\n", p,
+       debug("%s  %s node:    '%s'\n", p, type,
              fit_get_name(fit, noffset, NULL));
-
-       printf("%s  Hash algo:    ", p);
+       printf("%s  %s algo:    ", p, type);
        if (fit_image_hash_get_algo(fit, noffset, &algo)) {
                printf("invalid/unsupported\n");
                return;
        }
-       printf("%s\n", algo);
+       printf("%s", algo);
+       keyname = fdt_getprop(fit, noffset, "key-name-hint", NULL);
+       required = fdt_getprop(fit, noffset, "required", NULL) != NULL;
+       if (keyname)
+               printf(":%s", keyname);
+       if (required)
+               printf(" (required)");
+       printf("\n");
 
        ret = fit_image_hash_get_value(fit, noffset, &value,
                                        &value_len);
-       printf("%s  Hash value:   ", p);
+       printf("%s  %s value:   ", p, type);
        if (ret) {
                printf("unavailable\n");
        } else {
@@ -278,7 +265,18 @@ static void fit_image_print_data(const void *fit, int noffset, const char *p)
                printf("\n");
        }
 
-       debug("%s  Hash len:     %d\n", p, value_len);
+       debug("%s  %s len:     %d\n", p, type, value_len);
+
+       /* Signatures have a time stamp */
+       if (IMAGE_ENABLE_TIMESTAMP && keyname) {
+               time_t timestamp;
+
+               printf("%s  Timestamp:    ", p);
+               if (fit_get_timestamp(fit, noffset, &timestamp))
+                       printf("unavailable\n");
+               else
+                       genimg_print_time(timestamp);
+       }
 }
 
 /**
@@ -303,8 +301,12 @@ static void fit_image_print_verification_data(const void *fit, int noffset,
         * names, e.g. hash@1, hash@2, signature@1, signature@2, etc.
         */
        name = fit_get_name(fit, noffset, NULL);
-       if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME)))
-               fit_image_print_data(fit, noffset, p);
+       if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) {
+               fit_image_print_data(fit, noffset, p, "Hash");
+       } else if (!strncmp(name, FIT_SIG_NODENAME,
+                               strlen(FIT_SIG_NODENAME))) {
+               fit_image_print_data(fit, noffset, p, "Sign");
+       }
 }
 
 /**
@@ -944,13 +946,23 @@ int fit_image_verify(const void *fit, int image_noffset)
 {
        const void      *data;
        size_t          size;
-       int             noffset;
+       int             noffset = 0;
        char            *err_msg = "";
+       int verify_all = 1;
+       int ret;
 
        /* Get image data and data length */
        if (fit_image_get_data(fit, image_noffset, &data, &size)) {
                err_msg = "Can't get image data/size";
-               return 0;
+               goto error;
+       }
+
+       /* Verify all required signatures */
+       if (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";
+               goto error;
        }
 
        /* Process all hash subnodes of the component image node */
@@ -970,6 +982,15 @@ int fit_image_verify(const void *fit, int image_noffset)
                                                 &err_msg))
                                goto error;
                        puts("+ ");
+               } else if (IMAGE_ENABLE_VERIFY && verify_all &&
+                               !strncmp(name, FIT_SIG_NODENAME,
+                                       strlen(FIT_SIG_NODENAME))) {
+                       ret = fit_image_check_sig(fit, noffset, data,
+                                                       size, -1, &err_msg);
+                       if (ret)
+                               puts("- ");
+                       else
+                               puts("+ ");
                }
        }
 
@@ -1441,12 +1462,13 @@ int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
 }
 
 int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
-                  const char **fit_unamep, const char *fit_uname_config,
+                  const char **fit_unamep, const char **fit_uname_configp,
                   int arch, int image_type, int bootstage_id,
                   enum fit_load_op load_op, ulong *datap, ulong *lenp)
 {
        int cfg_noffset, noffset;
        const char *fit_uname;
+       const char *fit_uname_config;
        const void *fit;
        const void *buf;
        size_t size;
@@ -1456,6 +1478,7 @@ int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
 
        fit = map_sysmem(addr, 0);
        fit_uname = fit_unamep ? *fit_unamep : NULL;
+       fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
        printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
 
        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
@@ -1557,7 +1580,7 @@ int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
        if (fit_image_get_data(fit, noffset, &buf, &size)) {
                printf("Could not find %s subimage data!\n", prop_name);
                bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
-               return -ENOMEDIUM;
+               return -ENOENT;
        }
        len = (ulong)size;
 
@@ -1621,6 +1644,8 @@ int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
        *lenp = len;
        if (fit_unamep)
                *fit_unamep = (char *)fit_uname;
+       if (fit_uname_configp)
+               *fit_uname_configp = (char *)fit_uname_config;
 
        return noffset;
 }