uboot/boot/image-fit.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (c) 2013, Google Inc.
   4 *
   5 * (C) Copyright 2008 Semihalf
   6 *
   7 * (C) Copyright 2000-2006
   8 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   9 */
  10
  11#define LOG_CATEGORY LOGC_BOOT
  12
  13#ifdef USE_HOSTCC
  14#include "mkimage.h"
  15#include <time.h>
  16#include <linux/libfdt.h>
  17#include <u-boot/crc.h>
  18#else
  19#include <linux/compiler.h>
  20#include <linux/sizes.h>
  21#include <common.h>
  22#include <errno.h>
  23#include <log.h>
  24#include <mapmem.h>
  25#include <asm/io.h>
  26#include <malloc.h>
  27#include <asm/global_data.h>
  28#ifdef CONFIG_DM_HASH
  29#include <dm.h>
  30#include <u-boot/hash.h>
  31#endif
  32DECLARE_GLOBAL_DATA_PTR;
  33#endif /* !USE_HOSTCC*/
  34
  35#include <bootm.h>
  36#include <image.h>
  37#include <bootstage.h>
  38#include <linux/kconfig.h>
  39#include <u-boot/crc.h>
  40#include <u-boot/md5.h>
  41#include <u-boot/sha1.h>
  42#include <u-boot/sha256.h>
  43#include <u-boot/sha512.h>
  44
  45/*****************************************************************************/
  46/* New uImage format routines */
  47/*****************************************************************************/
  48#ifndef USE_HOSTCC
  49static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr,
  50                ulong *addr, const char **name)
  51{
  52        const char *sep;
  53
  54        *addr = addr_curr;
  55        *name = NULL;
  56
  57        sep = strchr(spec, sepc);
  58        if (sep) {
  59                if (sep - spec > 0)
  60                        *addr = hextoul(spec, NULL);
  61
  62                *name = sep + 1;
  63                return 1;
  64        }
  65
  66        return 0;
  67}
  68
  69/**
  70 * fit_parse_conf - parse FIT configuration spec
  71 * @spec: input string, containing configuration spec
  72 * @add_curr: current image address (to be used as a possible default)
  73 * @addr: pointer to a ulong variable, will hold FIT image address of a given
  74 * configuration
  75 * @conf_name double pointer to a char, will hold pointer to a configuration
  76 * unit name
  77 *
  78 * fit_parse_conf() expects configuration spec in the form of [<addr>]#<conf>,
  79 * where <addr> is a FIT image address that contains configuration
  80 * with a <conf> unit name.
  81 *
  82 * Address part is optional, and if omitted default add_curr will
  83 * be used instead.
  84 *
  85 * returns:
  86 *     1 if spec is a valid configuration string,
  87 *     addr and conf_name are set accordingly
  88 *     0 otherwise
  89 */
  90int fit_parse_conf(const char *spec, ulong addr_curr,
  91                ulong *addr, const char **conf_name)
  92{
  93        return fit_parse_spec(spec, '#', addr_curr, addr, conf_name);
  94}
  95
  96/**
  97 * fit_parse_subimage - parse FIT subimage spec
  98 * @spec: input string, containing subimage spec
  99 * @add_curr: current image address (to be used as a possible default)
 100 * @addr: pointer to a ulong variable, will hold FIT image address of a given
 101 * subimage
 102 * @image_name: double pointer to a char, will hold pointer to a subimage name
 103 *
 104 * fit_parse_subimage() expects subimage spec in the form of
 105 * [<addr>]:<subimage>, where <addr> is a FIT image address that contains
 106 * subimage with a <subimg> unit name.
 107 *
 108 * Address part is optional, and if omitted default add_curr will
 109 * be used instead.
 110 *
 111 * returns:
 112 *     1 if spec is a valid subimage string,
 113 *     addr and image_name are set accordingly
 114 *     0 otherwise
 115 */
 116int fit_parse_subimage(const char *spec, ulong addr_curr,
 117                ulong *addr, const char **image_name)
 118{
 119        return fit_parse_spec(spec, ':', addr_curr, addr, image_name);
 120}
 121#endif /* !USE_HOSTCC */
 122
 123#ifdef USE_HOSTCC
 124/* Host tools use these implementations for Cipher and Signature support */
 125static void *host_blob;
 126
 127void image_set_host_blob(void *blob)
 128{
 129        host_blob = blob;
 130}
 131
 132void *image_get_host_blob(void)
 133{
 134        return host_blob;
 135}
 136#endif /* USE_HOSTCC */
 137
 138static void fit_get_debug(const void *fit, int noffset,
 139                char *prop_name, int err)
 140{
 141        debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n",
 142              prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL),
 143              fdt_strerror(err));
 144}
 145
 146/**
 147 * fit_get_subimage_count - get component (sub-image) count
 148 * @fit: pointer to the FIT format image header
 149 * @images_noffset: offset of images node
 150 *
 151 * returns:
 152 *     number of image components
 153 */
 154int fit_get_subimage_count(const void *fit, int images_noffset)
 155{
 156        int noffset;
 157        int ndepth;
 158        int count = 0;
 159
 160        /* Process its subnodes, print out component images details */
 161        for (ndepth = 0, count = 0,
 162                noffset = fdt_next_node(fit, images_noffset, &ndepth);
 163             (noffset >= 0) && (ndepth > 0);
 164             noffset = fdt_next_node(fit, noffset, &ndepth)) {
 165                if (ndepth == 1) {
 166                        count++;
 167                }
 168        }
 169
 170        return count;
 171}
 172
 173/**
 174 * fit_image_print_data() - prints out the hash node details
 175 * @fit: pointer to the FIT format image header
 176 * @noffset: offset of the hash node
 177 * @p: pointer to prefix string
 178 * @type: Type of information to print ("hash" or "sign")
 179 *
 180 * fit_image_print_data() lists properties for the processed hash node
 181 *
 182 * This function avoid using puts() since it prints a newline on the host
 183 * but does not in U-Boot.
 184 *
 185 * returns:
 186 *     no returned results
 187 */
 188static void fit_image_print_data(const void *fit, int noffset, const char *p,
 189                                 const char *type)
 190{
 191        const char *keyname;
 192        uint8_t *value;
 193        int value_len;
 194        char *algo;
 195        const char *padding;
 196        bool required;
 197        int ret, i;
 198
 199        debug("%s  %s node:    '%s'\n", p, type,
 200              fit_get_name(fit, noffset, NULL));
 201        printf("%s  %s algo:    ", p, type);
 202        if (fit_image_hash_get_algo(fit, noffset, &algo)) {
 203                printf("invalid/unsupported\n");
 204                return;
 205        }
 206        printf("%s", algo);
 207        keyname = fdt_getprop(fit, noffset, FIT_KEY_HINT, NULL);
 208        required = fdt_getprop(fit, noffset, FIT_KEY_REQUIRED, NULL) != NULL;
 209        if (keyname)
 210                printf(":%s", keyname);
 211        if (required)
 212                printf(" (required)");
 213        printf("\n");
 214
 215        padding = fdt_getprop(fit, noffset, "padding", NULL);
 216        if (padding)
 217                printf("%s  %s padding: %s\n", p, type, padding);
 218
 219        ret = fit_image_hash_get_value(fit, noffset, &value,
 220                                       &value_len);
 221        printf("%s  %s value:   ", p, type);
 222        if (ret) {
 223                printf("unavailable\n");
 224        } else {
 225                for (i = 0; i < value_len; i++)
 226                        printf("%02x", value[i]);
 227                printf("\n");
 228        }
 229
 230        debug("%s  %s len:     %d\n", p, type, value_len);
 231
 232        /* Signatures have a time stamp */
 233        if (IMAGE_ENABLE_TIMESTAMP && keyname) {
 234                time_t timestamp;
 235
 236                printf("%s  Timestamp:    ", p);
 237                if (fit_get_timestamp(fit, noffset, &timestamp))
 238                        printf("unavailable\n");
 239                else
 240                        genimg_print_time(timestamp);
 241        }
 242}
 243
 244/**
 245 * fit_image_print_verification_data() - prints out the hash/signature details
 246 * @fit: pointer to the FIT format image header
 247 * @noffset: offset of the hash or signature node
 248 * @p: pointer to prefix string
 249 *
 250 * This lists properties for the processed hash node
 251 *
 252 * returns:
 253 *     no returned results
 254 */
 255static void fit_image_print_verification_data(const void *fit, int noffset,
 256                                              const char *p)
 257{
 258        const char *name;
 259
 260        /*
 261         * Check subnode name, must be equal to "hash" or "signature".
 262         * Multiple hash/signature nodes require unique unit node
 263         * names, e.g. hash-1, hash-2, signature-1, signature-2, etc.
 264         */
 265        name = fit_get_name(fit, noffset, NULL);
 266        if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) {
 267                fit_image_print_data(fit, noffset, p, "Hash");
 268        } else if (!strncmp(name, FIT_SIG_NODENAME,
 269                                strlen(FIT_SIG_NODENAME))) {
 270                fit_image_print_data(fit, noffset, p, "Sign");
 271        }
 272}
 273
 274/**
 275 * fit_conf_print - prints out the FIT configuration details
 276 * @fit: pointer to the FIT format image header
 277 * @noffset: offset of the configuration node
 278 * @p: pointer to prefix string
 279 *
 280 * fit_conf_print() lists all mandatory properties for the processed
 281 * configuration node.
 282 *
 283 * returns:
 284 *     no returned results
 285 */
 286static void fit_conf_print(const void *fit, int noffset, const char *p)
 287{
 288        char *desc;
 289        const char *uname;
 290        int ret;
 291        int fdt_index, loadables_index;
 292        int ndepth;
 293
 294        /* Mandatory properties */
 295        ret = fit_get_desc(fit, noffset, &desc);
 296        printf("%s  Description:  ", p);
 297        if (ret)
 298                printf("unavailable\n");
 299        else
 300                printf("%s\n", desc);
 301
 302        uname = fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL);
 303        printf("%s  Kernel:       ", p);
 304        if (!uname)
 305                printf("unavailable\n");
 306        else
 307                printf("%s\n", uname);
 308
 309        /* Optional properties */
 310        uname = fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL);
 311        if (uname)
 312                printf("%s  Init Ramdisk: %s\n", p, uname);
 313
 314        uname = fdt_getprop(fit, noffset, FIT_FIRMWARE_PROP, NULL);
 315        if (uname)
 316                printf("%s  Firmware:     %s\n", p, uname);
 317
 318        for (fdt_index = 0;
 319             uname = fdt_stringlist_get(fit, noffset, FIT_FDT_PROP,
 320                                        fdt_index, NULL), uname;
 321             fdt_index++) {
 322                if (fdt_index == 0)
 323                        printf("%s  FDT:          ", p);
 324                else
 325                        printf("%s                ", p);
 326                printf("%s\n", uname);
 327        }
 328
 329        uname = fdt_getprop(fit, noffset, FIT_FPGA_PROP, NULL);
 330        if (uname)
 331                printf("%s  FPGA:         %s\n", p, uname);
 332
 333        /* Print out all of the specified loadables */
 334        for (loadables_index = 0;
 335             uname = fdt_stringlist_get(fit, noffset, FIT_LOADABLE_PROP,
 336                                        loadables_index, NULL), uname;
 337             loadables_index++) {
 338                if (loadables_index == 0) {
 339                        printf("%s  Loadables:    ", p);
 340                } else {
 341                        printf("%s                ", p);
 342                }
 343                printf("%s\n", uname);
 344        }
 345
 346        /* Process all hash subnodes of the component configuration node */
 347        for (ndepth = 0, noffset = fdt_next_node(fit, noffset, &ndepth);
 348             (noffset >= 0) && (ndepth > 0);
 349             noffset = fdt_next_node(fit, noffset, &ndepth)) {
 350                if (ndepth == 1) {
 351                        /* Direct child node of the component configuration node */
 352                        fit_image_print_verification_data(fit, noffset, p);
 353                }
 354        }
 355}
 356
 357/**
 358 * fit_print_contents - prints out the contents of the FIT format image
 359 * @fit: pointer to the FIT format image header
 360 * @p: pointer to prefix string
 361 *
 362 * fit_print_contents() formats a multi line FIT image contents description.
 363 * The routine prints out FIT image properties (root node level) followed by
 364 * the details of each component image.
 365 *
 366 * returns:
 367 *     no returned results
 368 */
 369void fit_print_contents(const void *fit)
 370{
 371        char *desc;
 372        char *uname;
 373        int images_noffset;
 374        int confs_noffset;
 375        int noffset;
 376        int ndepth;
 377        int count = 0;
 378        int ret;
 379        const char *p;
 380        time_t timestamp;
 381
 382        if (!CONFIG_IS_ENABLED(FIT_PRINT))
 383                return;
 384
 385        /* Indent string is defined in header image.h */
 386        p = IMAGE_INDENT_STRING;
 387
 388        /* Root node properties */
 389        ret = fit_get_desc(fit, 0, &desc);
 390        printf("%sFIT description: ", p);
 391        if (ret)
 392                printf("unavailable\n");
 393        else
 394                printf("%s\n", desc);
 395
 396        if (IMAGE_ENABLE_TIMESTAMP) {
 397                ret = fit_get_timestamp(fit, 0, &timestamp);
 398                printf("%sCreated:         ", p);
 399                if (ret)
 400                        printf("unavailable\n");
 401                else
 402                        genimg_print_time(timestamp);
 403        }
 404
 405        /* Find images parent node offset */
 406        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
 407        if (images_noffset < 0) {
 408                printf("Can't find images parent node '%s' (%s)\n",
 409                       FIT_IMAGES_PATH, fdt_strerror(images_noffset));
 410                return;
 411        }
 412
 413        /* Process its subnodes, print out component images details */
 414        for (ndepth = 0, count = 0,
 415                noffset = fdt_next_node(fit, images_noffset, &ndepth);
 416             (noffset >= 0) && (ndepth > 0);
 417             noffset = fdt_next_node(fit, noffset, &ndepth)) {
 418                if (ndepth == 1) {
 419                        /*
 420                         * Direct child node of the images parent node,
 421                         * i.e. component image node.
 422                         */
 423                        printf("%s Image %u (%s)\n", p, count++,
 424                               fit_get_name(fit, noffset, NULL));
 425
 426                        fit_image_print(fit, noffset, p);
 427                }
 428        }
 429
 430        /* Find configurations parent node offset */
 431        confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
 432        if (confs_noffset < 0) {
 433                debug("Can't get configurations parent node '%s' (%s)\n",
 434                      FIT_CONFS_PATH, fdt_strerror(confs_noffset));
 435                return;
 436        }
 437
 438        /* get default configuration unit name from default property */
 439        uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL);
 440        if (uname)
 441                printf("%s Default Configuration: '%s'\n", p, uname);
 442
 443        /* Process its subnodes, print out configurations details */
 444        for (ndepth = 0, count = 0,
 445                noffset = fdt_next_node(fit, confs_noffset, &ndepth);
 446             (noffset >= 0) && (ndepth > 0);
 447             noffset = fdt_next_node(fit, noffset, &ndepth)) {
 448                if (ndepth == 1) {
 449                        /*
 450                         * Direct child node of the configurations parent node,
 451                         * i.e. configuration node.
 452                         */
 453                        printf("%s Configuration %u (%s)\n", p, count++,
 454                               fit_get_name(fit, noffset, NULL));
 455
 456                        fit_conf_print(fit, noffset, p);
 457                }
 458        }
 459}
 460
 461/**
 462 * fit_image_print - prints out the FIT component image details
 463 * @fit: pointer to the FIT format image header
 464 * @image_noffset: offset of the component image node
 465 * @p: pointer to prefix string
 466 *
 467 * fit_image_print() lists all mandatory properties for the processed component
 468 * image. If present, hash nodes are printed out as well. Load
 469 * address for images of type firmware is also printed out. Since the load
 470 * address is not mandatory for firmware images, it will be output as
 471 * "unavailable" when not present.
 472 *
 473 * returns:
 474 *     no returned results
 475 */
 476void fit_image_print(const void *fit, int image_noffset, const char *p)
 477{
 478        char *desc;
 479        uint8_t type, arch, os, comp;
 480        size_t size;
 481        ulong load, entry;
 482        const void *data;
 483        int noffset;
 484        int ndepth;
 485        int ret;
 486
 487        if (!CONFIG_IS_ENABLED(FIT_PRINT))
 488                return;
 489
 490        /* Mandatory properties */
 491        ret = fit_get_desc(fit, image_noffset, &desc);
 492        printf("%s  Description:  ", p);
 493        if (ret)
 494                printf("unavailable\n");
 495        else
 496                printf("%s\n", desc);
 497
 498        if (IMAGE_ENABLE_TIMESTAMP) {
 499                time_t timestamp;
 500
 501                ret = fit_get_timestamp(fit, 0, &timestamp);
 502                printf("%s  Created:      ", p);
 503                if (ret)
 504                        printf("unavailable\n");
 505                else
 506                        genimg_print_time(timestamp);
 507        }
 508
 509        fit_image_get_type(fit, image_noffset, &type);
 510        printf("%s  Type:         %s\n", p, genimg_get_type_name(type));
 511
 512        fit_image_get_comp(fit, image_noffset, &comp);
 513        printf("%s  Compression:  %s\n", p, genimg_get_comp_name(comp));
 514
 515        ret = fit_image_get_data_and_size(fit, image_noffset, &data, &size);
 516
 517        if (!tools_build()) {
 518                printf("%s  Data Start:   ", p);
 519                if (ret) {
 520                        printf("unavailable\n");
 521                } else {
 522                        void *vdata = (void *)data;
 523
 524                        printf("0x%08lx\n", (ulong)map_to_sysmem(vdata));
 525                }
 526        }
 527
 528        printf("%s  Data Size:    ", p);
 529        if (ret)
 530                printf("unavailable\n");
 531        else
 532                genimg_print_size(size);
 533
 534        /* Remaining, type dependent properties */
 535        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
 536            (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||
 537            (type == IH_TYPE_FLATDT)) {
 538                fit_image_get_arch(fit, image_noffset, &arch);
 539                printf("%s  Architecture: %s\n", p, genimg_get_arch_name(arch));
 540        }
 541
 542        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK) ||
 543            (type == IH_TYPE_FIRMWARE)) {
 544                fit_image_get_os(fit, image_noffset, &os);
 545                printf("%s  OS:           %s\n", p, genimg_get_os_name(os));
 546        }
 547
 548        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
 549            (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK) ||
 550            (type == IH_TYPE_FPGA)) {
 551                ret = fit_image_get_load(fit, image_noffset, &load);
 552                printf("%s  Load Address: ", p);
 553                if (ret)
 554                        printf("unavailable\n");
 555                else
 556                        printf("0x%08lx\n", load);
 557        }
 558
 559        /* optional load address for FDT */
 560        if (type == IH_TYPE_FLATDT && !fit_image_get_load(fit, image_noffset, &load))
 561                printf("%s  Load Address: 0x%08lx\n", p, load);
 562
 563        if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||
 564            (type == IH_TYPE_RAMDISK)) {
 565                ret = fit_image_get_entry(fit, image_noffset, &entry);
 566                printf("%s  Entry Point:  ", p);
 567                if (ret)
 568                        printf("unavailable\n");
 569                else
 570                        printf("0x%08lx\n", entry);
 571        }
 572
 573        /* Process all hash subnodes of the component image node */
 574        for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth);
 575             (noffset >= 0) && (ndepth > 0);
 576             noffset = fdt_next_node(fit, noffset, &ndepth)) {
 577                if (ndepth == 1) {
 578                        /* Direct child node of the component image node */
 579                        fit_image_print_verification_data(fit, noffset, p);
 580                }
 581        }
 582}
 583
 584/**
 585 * fit_get_desc - get node description property
 586 * @fit: pointer to the FIT format image header
 587 * @noffset: node offset
 588 * @desc: double pointer to the char, will hold pointer to the description
 589 *
 590 * fit_get_desc() reads description property from a given node, if
 591 * description is found pointer to it is returned in third call argument.
 592 *
 593 * returns:
 594 *     0, on success
 595 *     -1, on failure
 596 */
 597int fit_get_desc(const void *fit, int noffset, char **desc)
 598{
 599        int len;
 600
 601        *desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len);
 602        if (*desc == NULL) {
 603                fit_get_debug(fit, noffset, FIT_DESC_PROP, len);
 604                return -1;
 605        }
 606
 607        return 0;
 608}
 609
 610/**
 611 * fit_get_timestamp - get node timestamp property
 612 * @fit: pointer to the FIT format image header
 613 * @noffset: node offset
 614 * @timestamp: pointer to the time_t, will hold read timestamp
 615 *
 616 * fit_get_timestamp() reads timestamp property from given node, if timestamp
 617 * is found and has a correct size its value is returned in third call
 618 * argument.
 619 *
 620 * returns:
 621 *     0, on success
 622 *     -1, on property read failure
 623 *     -2, on wrong timestamp size
 624 */
 625int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp)
 626{
 627        int len;
 628        const void *data;
 629
 630        data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len);
 631        if (data == NULL) {
 632                fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len);
 633                return -1;
 634        }
 635        if (len != sizeof(uint32_t)) {
 636                debug("FIT timestamp with incorrect size of (%u)\n", len);
 637                return -2;
 638        }
 639
 640        *timestamp = uimage_to_cpu(*((uint32_t *)data));
 641        return 0;
 642}
 643
 644/**
 645 * fit_image_get_node - get node offset for component image of a given unit name
 646 * @fit: pointer to the FIT format image header
 647 * @image_uname: component image node unit name
 648 *
 649 * fit_image_get_node() finds a component image (within the '/images'
 650 * node) of a provided unit name. If image is found its node offset is
 651 * returned to the caller.
 652 *
 653 * returns:
 654 *     image node offset when found (>=0)
 655 *     negative number on failure (FDT_ERR_* code)
 656 */
 657int fit_image_get_node(const void *fit, const char *image_uname)
 658{
 659        int noffset, images_noffset;
 660
 661        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
 662        if (images_noffset < 0) {
 663                debug("Can't find images parent node '%s' (%s)\n",
 664                      FIT_IMAGES_PATH, fdt_strerror(images_noffset));
 665                return images_noffset;
 666        }
 667
 668        noffset = fdt_subnode_offset(fit, images_noffset, image_uname);
 669        if (noffset < 0) {
 670                debug("Can't get node offset for image unit name: '%s' (%s)\n",
 671                      image_uname, fdt_strerror(noffset));
 672        }
 673
 674        return noffset;
 675}
 676
 677/**
 678 * fit_image_get_os - get os id for a given component image node
 679 * @fit: pointer to the FIT format image header
 680 * @noffset: component image node offset
 681 * @os: pointer to the uint8_t, will hold os numeric id
 682 *
 683 * fit_image_get_os() finds os property in a given component image node.
 684 * If the property is found, its (string) value is translated to the numeric
 685 * id which is returned to the caller.
 686 *
 687 * returns:
 688 *     0, on success
 689 *     -1, on failure
 690 */
 691int fit_image_get_os(const void *fit, int noffset, uint8_t *os)
 692{
 693        int len;
 694        const void *data;
 695
 696        /* Get OS name from property data */
 697        data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len);
 698        if (data == NULL) {
 699                fit_get_debug(fit, noffset, FIT_OS_PROP, len);
 700                *os = -1;
 701                return -1;
 702        }
 703
 704        /* Translate OS name to id */
 705        *os = genimg_get_os_id(data);
 706        return 0;
 707}
 708
 709/**
 710 * fit_image_get_arch - get arch id for a given component image node
 711 * @fit: pointer to the FIT format image header
 712 * @noffset: component image node offset
 713 * @arch: pointer to the uint8_t, will hold arch numeric id
 714 *
 715 * fit_image_get_arch() finds arch property in a given component image node.
 716 * If the property is found, its (string) value is translated to the numeric
 717 * id which is returned to the caller.
 718 *
 719 * returns:
 720 *     0, on success
 721 *     -1, on failure
 722 */
 723int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch)
 724{
 725        int len;
 726        const void *data;
 727
 728        /* Get architecture name from property data */
 729        data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len);
 730        if (data == NULL) {
 731                fit_get_debug(fit, noffset, FIT_ARCH_PROP, len);
 732                *arch = -1;
 733                return -1;
 734        }
 735
 736        /* Translate architecture name to id */
 737        *arch = genimg_get_arch_id(data);
 738        return 0;
 739}
 740
 741/**
 742 * fit_image_get_type - get type id for a given component image node
 743 * @fit: pointer to the FIT format image header
 744 * @noffset: component image node offset
 745 * @type: pointer to the uint8_t, will hold type numeric id
 746 *
 747 * fit_image_get_type() finds type property in a given component image node.
 748 * If the property is found, its (string) value is translated to the numeric
 749 * id which is returned to the caller.
 750 *
 751 * returns:
 752 *     0, on success
 753 *     -1, on failure
 754 */
 755int fit_image_get_type(const void *fit, int noffset, uint8_t *type)
 756{
 757        int len;
 758        const void *data;
 759
 760        /* Get image type name from property data */
 761        data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len);
 762        if (data == NULL) {
 763                fit_get_debug(fit, noffset, FIT_TYPE_PROP, len);
 764                *type = -1;
 765                return -1;
 766        }
 767
 768        /* Translate image type name to id */
 769        *type = genimg_get_type_id(data);
 770        return 0;
 771}
 772
 773/**
 774 * fit_image_get_comp - get comp id for a given component image node
 775 * @fit: pointer to the FIT format image header
 776 * @noffset: component image node offset
 777 * @comp: pointer to the uint8_t, will hold comp numeric id
 778 *
 779 * fit_image_get_comp() finds comp property in a given component image node.
 780 * If the property is found, its (string) value is translated to the numeric
 781 * id which is returned to the caller.
 782 *
 783 * returns:
 784 *     0, on success
 785 *     -1, on failure
 786 */
 787int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp)
 788{
 789        int len;
 790        const void *data;
 791
 792        /* Get compression name from property data */
 793        data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len);
 794        if (data == NULL) {
 795                fit_get_debug(fit, noffset, FIT_COMP_PROP, len);
 796                *comp = -1;
 797                return -1;
 798        }
 799
 800        /* Translate compression name to id */
 801        *comp = genimg_get_comp_id(data);
 802        return 0;
 803}
 804
 805static int fit_image_get_address(const void *fit, int noffset, char *name,
 806                          ulong *load)
 807{
 808        int len, cell_len;
 809        const fdt32_t *cell;
 810        uint64_t load64 = 0;
 811
 812        cell = fdt_getprop(fit, noffset, name, &len);
 813        if (cell == NULL) {
 814                fit_get_debug(fit, noffset, name, len);
 815                return -1;
 816        }
 817
 818        cell_len = len >> 2;
 819        /* Use load64 to avoid compiling warning for 32-bit target */
 820        while (cell_len--) {
 821                load64 = (load64 << 32) | uimage_to_cpu(*cell);
 822                cell++;
 823        }
 824
 825        if (len > sizeof(ulong) && (uint32_t)(load64 >> 32)) {
 826                printf("Unsupported %s address size\n", name);
 827                return -1;
 828        }
 829
 830        *load = (ulong)load64;
 831
 832        return 0;
 833}
 834/**
 835 * fit_image_get_load() - get load addr property for given component image node
 836 * @fit: pointer to the FIT format image header
 837 * @noffset: component image node offset
 838 * @load: pointer to the uint32_t, will hold load address
 839 *
 840 * fit_image_get_load() finds load address property in a given component
 841 * image node. If the property is found, its value is returned to the caller.
 842 *
 843 * returns:
 844 *     0, on success
 845 *     -1, on failure
 846 */
 847int fit_image_get_load(const void *fit, int noffset, ulong *load)
 848{
 849        return fit_image_get_address(fit, noffset, FIT_LOAD_PROP, load);
 850}
 851
 852/**
 853 * fit_image_get_entry() - get entry point address property
 854 * @fit: pointer to the FIT format image header
 855 * @noffset: component image node offset
 856 * @entry: pointer to the uint32_t, will hold entry point address
 857 *
 858 * This gets the entry point address property for a given component image
 859 * node.
 860 *
 861 * fit_image_get_entry() finds entry point address property in a given
 862 * component image node.  If the property is found, its value is returned
 863 * to the caller.
 864 *
 865 * returns:
 866 *     0, on success
 867 *     -1, on failure
 868 */
 869int fit_image_get_entry(const void *fit, int noffset, ulong *entry)
 870{
 871        return fit_image_get_address(fit, noffset, FIT_ENTRY_PROP, entry);
 872}
 873
 874/**
 875 * fit_image_get_data - get data property and its size for a given component image node
 876 * @fit: pointer to the FIT format image header
 877 * @noffset: component image node offset
 878 * @data: double pointer to void, will hold data property's data address
 879 * @size: pointer to size_t, will hold data property's data size
 880 *
 881 * fit_image_get_data() finds data property in a given component image node.
 882 * If the property is found its data start address and size are returned to
 883 * the caller.
 884 *
 885 * returns:
 886 *     0, on success
 887 *     -1, on failure
 888 */
 889int fit_image_get_data(const void *fit, int noffset,
 890                const void **data, size_t *size)
 891{
 892        int len;
 893
 894        *data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len);
 895        if (*data == NULL) {
 896                fit_get_debug(fit, noffset, FIT_DATA_PROP, len);
 897                *size = 0;
 898                return -1;
 899        }
 900
 901        *size = len;
 902        return 0;
 903}
 904
 905/**
 906 * Get 'data-offset' property from a given image node.
 907 *
 908 * @fit: pointer to the FIT image header
 909 * @noffset: component image node offset
 910 * @data_offset: holds the data-offset property
 911 *
 912 * returns:
 913 *     0, on success
 914 *     -ENOENT if the property could not be found
 915 */
 916int fit_image_get_data_offset(const void *fit, int noffset, int *data_offset)
 917{
 918        const fdt32_t *val;
 919
 920        val = fdt_getprop(fit, noffset, FIT_DATA_OFFSET_PROP, NULL);
 921        if (!val)
 922                return -ENOENT;
 923
 924        *data_offset = fdt32_to_cpu(*val);
 925
 926        return 0;
 927}
 928
 929/**
 930 * Get 'data-position' property from a given image node.
 931 *
 932 * @fit: pointer to the FIT image header
 933 * @noffset: component image node offset
 934 * @data_position: holds the data-position property
 935 *
 936 * returns:
 937 *     0, on success
 938 *     -ENOENT if the property could not be found
 939 */
 940int fit_image_get_data_position(const void *fit, int noffset,
 941                                int *data_position)
 942{
 943        const fdt32_t *val;
 944
 945        val = fdt_getprop(fit, noffset, FIT_DATA_POSITION_PROP, NULL);
 946        if (!val)
 947                return -ENOENT;
 948
 949        *data_position = fdt32_to_cpu(*val);
 950
 951        return 0;
 952}
 953
 954/**
 955 * Get 'data-size' property from a given image node.
 956 *
 957 * @fit: pointer to the FIT image header
 958 * @noffset: component image node offset
 959 * @data_size: holds the data-size property
 960 *
 961 * returns:
 962 *     0, on success
 963 *     -ENOENT if the property could not be found
 964 */
 965int fit_image_get_data_size(const void *fit, int noffset, int *data_size)
 966{
 967        const fdt32_t *val;
 968
 969        val = fdt_getprop(fit, noffset, FIT_DATA_SIZE_PROP, NULL);
 970        if (!val)
 971                return -ENOENT;
 972
 973        *data_size = fdt32_to_cpu(*val);
 974
 975        return 0;
 976}
 977
 978/**
 979 * Get 'data-size-unciphered' property from a given image node.
 980 *
 981 * @fit: pointer to the FIT image header
 982 * @noffset: component image node offset
 983 * @data_size: holds the data-size property
 984 *
 985 * returns:
 986 *     0, on success
 987 *     -ENOENT if the property could not be found
 988 */
 989int fit_image_get_data_size_unciphered(const void *fit, int noffset,
 990                                       size_t *data_size)
 991{
 992        const fdt32_t *val;
 993
 994        val = fdt_getprop(fit, noffset, "data-size-unciphered", NULL);
 995        if (!val)
 996                return -ENOENT;
 997
 998        *data_size = (size_t)fdt32_to_cpu(*val);
 999
1000        return 0;
1001}
1002
1003/**
1004 * fit_image_get_data_and_size - get data and its size including
1005 *                               both embedded and external data
1006 * @fit: pointer to the FIT format image header
1007 * @noffset: component image node offset
1008 * @data: double pointer to void, will hold data property's data address
1009 * @size: pointer to size_t, will hold data property's data size
1010 *
1011 * fit_image_get_data_and_size() finds data and its size including
1012 * both embedded and external data. If the property is found
1013 * its data start address and size are returned to the caller.
1014 *
1015 * returns:
1016 *     0, on success
1017 *     otherwise, on failure
1018 */
1019int fit_image_get_data_and_size(const void *fit, int noffset,
1020                                const void **data, size_t *size)
1021{
1022        bool external_data = false;
1023        int offset;
1024        int len;
1025        int ret;
1026
1027        if (!fit_image_get_data_position(fit, noffset, &offset)) {
1028                external_data = true;
1029        } else if (!fit_image_get_data_offset(fit, noffset, &offset)) {
1030                external_data = true;
1031                /*
1032                 * For FIT with external data, figure out where
1033                 * the external images start. This is the base
1034                 * for the data-offset properties in each image.
1035                 */
1036                offset += ((fdt_totalsize(fit) + 3) & ~3);
1037        }
1038
1039        if (external_data) {
1040                debug("External Data\n");
1041                ret = fit_image_get_data_size(fit, noffset, &len);
1042                if (!ret) {
1043                        *data = fit + offset;
1044                        *size = len;
1045                }
1046        } else {
1047                ret = fit_image_get_data(fit, noffset, data, size);
1048        }
1049
1050        return ret;
1051}
1052
1053/**
1054 * fit_image_hash_get_algo - get hash algorithm name
1055 * @fit: pointer to the FIT format image header
1056 * @noffset: hash node offset
1057 * @algo: double pointer to char, will hold pointer to the algorithm name
1058 *
1059 * fit_image_hash_get_algo() finds hash algorithm property in a given hash node.
1060 * If the property is found its data start address is returned to the caller.
1061 *
1062 * returns:
1063 *     0, on success
1064 *     -1, on failure
1065 */
1066int fit_image_hash_get_algo(const void *fit, int noffset, char **algo)
1067{
1068        int len;
1069
1070        *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
1071        if (*algo == NULL) {
1072                fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
1073                return -1;
1074        }
1075
1076        return 0;
1077}
1078
1079/**
1080 * fit_image_hash_get_value - get hash value and length
1081 * @fit: pointer to the FIT format image header
1082 * @noffset: hash node offset
1083 * @value: double pointer to uint8_t, will hold address of a hash value data
1084 * @value_len: pointer to an int, will hold hash data length
1085 *
1086 * fit_image_hash_get_value() finds hash value property in a given hash node.
1087 * If the property is found its data start address and size are returned to
1088 * the caller.
1089 *
1090 * returns:
1091 *     0, on success
1092 *     -1, on failure
1093 */
1094int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value,
1095                                int *value_len)
1096{
1097        int len;
1098
1099        *value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len);
1100        if (*value == NULL) {
1101                fit_get_debug(fit, noffset, FIT_VALUE_PROP, len);
1102                *value_len = 0;
1103                return -1;
1104        }
1105
1106        *value_len = len;
1107        return 0;
1108}
1109
1110/**
1111 * fit_image_hash_get_ignore - get hash ignore flag
1112 * @fit: pointer to the FIT format image header
1113 * @noffset: hash node offset
1114 * @ignore: pointer to an int, will hold hash ignore flag
1115 *
1116 * fit_image_hash_get_ignore() finds hash ignore property in a given hash node.
1117 * If the property is found and non-zero, the hash algorithm is not verified by
1118 * u-boot automatically.
1119 *
1120 * returns:
1121 *     0, on ignore not found
1122 *     value, on ignore found
1123 */
1124static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore)
1125{
1126        int len;
1127        int *value;
1128
1129        value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len);
1130        if (value == NULL || len != sizeof(int))
1131                *ignore = 0;
1132        else
1133                *ignore = *value;
1134
1135        return 0;
1136}
1137
1138/**
1139 * fit_image_cipher_get_algo - get cipher algorithm name
1140 * @fit: pointer to the FIT format image header
1141 * @noffset: cipher node offset
1142 * @algo: double pointer to char, will hold pointer to the algorithm name
1143 *
1144 * fit_image_cipher_get_algo() finds cipher algorithm property in a given
1145 * cipher node. If the property is found its data start address is returned
1146 * to the caller.
1147 *
1148 * returns:
1149 *     0, on success
1150 *     -1, on failure
1151 */
1152int fit_image_cipher_get_algo(const void *fit, int noffset, char **algo)
1153{
1154        int len;
1155
1156        *algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len);
1157        if (!*algo) {
1158                fit_get_debug(fit, noffset, FIT_ALGO_PROP, len);
1159                return -1;
1160        }
1161
1162        return 0;
1163}
1164
1165ulong fit_get_end(const void *fit)
1166{
1167        return map_to_sysmem((void *)(fit + fdt_totalsize(fit)));
1168}
1169
1170/**
1171 * fit_set_timestamp - set node timestamp property
1172 * @fit: pointer to the FIT format image header
1173 * @noffset: node offset
1174 * @timestamp: timestamp value to be set
1175 *
1176 * fit_set_timestamp() attempts to set timestamp property in the requested
1177 * node and returns operation status to the caller.
1178 *
1179 * returns:
1180 *     0, on success
1181 *     -ENOSPC if no space in device tree, -1 for other error
1182 */
1183int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
1184{
1185        uint32_t t;
1186        int ret;
1187
1188        t = cpu_to_uimage(timestamp);
1189        ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
1190                                sizeof(uint32_t));
1191        if (ret) {
1192                debug("Can't set '%s' property for '%s' node (%s)\n",
1193                      FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
1194                      fdt_strerror(ret));
1195                return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -1;
1196        }
1197
1198        return 0;
1199}
1200
1201/**
1202 * calculate_hash - calculate and return hash for provided input data
1203 * @data: pointer to the input data
1204 * @data_len: data length
1205 * @algo: requested hash algorithm
1206 * @value: pointer to the char, will hold hash value data (caller must
1207 * allocate enough free space)
1208 * value_len: length of the calculated hash
1209 *
1210 * calculate_hash() computes input data hash according to the requested
1211 * algorithm.
1212 * Resulting hash value is placed in caller provided 'value' buffer, length
1213 * of the calculated hash is returned via value_len pointer argument.
1214 *
1215 * returns:
1216 *     0, on success
1217 *    -1, when algo is unsupported
1218 */
1219int calculate_hash(const void *data, int data_len, const char *name,
1220                        uint8_t *value, int *value_len)
1221{
1222#if !defined(USE_HOSTCC) && defined(CONFIG_DM_HASH)
1223        int rc;
1224        enum HASH_ALGO hash_algo;
1225        struct udevice *dev;
1226
1227        rc = uclass_get_device(UCLASS_HASH, 0, &dev);
1228        if (rc) {
1229                debug("failed to get hash device, rc=%d\n", rc);
1230                return -1;
1231        }
1232
1233        hash_algo = hash_algo_lookup_by_name(algo);
1234        if (hash_algo == HASH_ALGO_INVALID) {
1235                debug("Unsupported hash algorithm\n");
1236                return -1;
1237        };
1238
1239        rc = hash_digest_wd(dev, hash_algo, data, data_len, value, CHUNKSZ);
1240        if (rc) {
1241                debug("failed to get hash value, rc=%d\n", rc);
1242                return -1;
1243        }
1244
1245        *value_len = hash_algo_digest_size(hash_algo);
1246#else
1247        struct hash_algo *algo;
1248        int ret;
1249
1250        ret = hash_lookup_algo(name, &algo);
1251        if (ret < 0) {
1252                debug("Unsupported hash alogrithm\n");
1253                return -1;
1254        }
1255
1256        algo->hash_func_ws(data, data_len, value, algo->chunk_size);
1257        *value_len = algo->digest_size;
1258#endif
1259
1260        return 0;
1261}
1262
1263static int fit_image_check_hash(const void *fit, int noffset, const void *data,
1264                                size_t size, char **err_msgp)
1265{
1266        uint8_t value[FIT_MAX_HASH_LEN];
1267        int value_len;
1268        char *algo;
1269        uint8_t *fit_value;
1270        int fit_value_len;
1271        int ignore;
1272
1273        *err_msgp = NULL;
1274
1275        if (fit_image_hash_get_algo(fit, noffset, &algo)) {
1276                *err_msgp = "Can't get hash algo property";
1277                return -1;
1278        }
1279        printf("%s", algo);
1280
1281        if (!tools_build()) {
1282                fit_image_hash_get_ignore(fit, noffset, &ignore);
1283                if (ignore) {
1284                        printf("-skipped ");
1285                        return 0;
1286                }
1287        }
1288
1289        if (fit_image_hash_get_value(fit, noffset, &fit_value,
1290                                     &fit_value_len)) {
1291                *err_msgp = "Can't get hash value property";
1292                return -1;
1293        }
1294
1295        if (calculate_hash(data, size, algo, value, &value_len)) {
1296                *err_msgp = "Unsupported hash algorithm";
1297                return -1;
1298        }
1299
1300        if (value_len != fit_value_len) {
1301                *err_msgp = "Bad hash value len";
1302                return -1;
1303        } else if (memcmp(value, fit_value, value_len) != 0) {
1304                *err_msgp = "Bad hash value";
1305                return -1;
1306        }
1307
1308        return 0;
1309}
1310
1311int fit_image_verify_with_data(const void *fit, int image_noffset,
1312                               const void *data, size_t size)
1313{
1314        int             noffset = 0;
1315        char            *err_msg = "";
1316        int verify_all = 1;
1317        int ret;
1318
1319        /* Verify all required signatures */
1320        if (FIT_IMAGE_ENABLE_VERIFY &&
1321            fit_image_verify_required_sigs(fit, image_noffset, data, size,
1322                                           gd_fdt_blob(), &verify_all)) {
1323                err_msg = "Unable to verify required signature";
1324                goto error;
1325        }
1326
1327        /* Process all hash subnodes of the component image node */
1328        fdt_for_each_subnode(noffset, fit, image_noffset) {
1329                const char *name = fit_get_name(fit, noffset, NULL);
1330
1331                /*
1332                 * Check subnode name, must be equal to "hash".
1333                 * Multiple hash nodes require unique unit node
1334                 * names, e.g. hash-1, hash-2, etc.
1335                 */
1336                if (!strncmp(name, FIT_HASH_NODENAME,
1337                             strlen(FIT_HASH_NODENAME))) {
1338                        if (fit_image_check_hash(fit, noffset, data, size,
1339                                                 &err_msg))
1340                                goto error;
1341                        puts("+ ");
1342                } else if (FIT_IMAGE_ENABLE_VERIFY && verify_all &&
1343                                !strncmp(name, FIT_SIG_NODENAME,
1344                                        strlen(FIT_SIG_NODENAME))) {
1345                        ret = fit_image_check_sig(fit, noffset, data,
1346                                                        size, -1, &err_msg);
1347
1348                        /*
1349                         * Show an indication on failure, but do not return
1350                         * an error. Only keys marked 'required' can cause
1351                         * an image validation failure. See the call to
1352                         * fit_image_verify_required_sigs() above.
1353                         */
1354                        if (ret)
1355                                puts("- ");
1356                        else
1357                                puts("+ ");
1358                }
1359        }
1360
1361        if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
1362                err_msg = "Corrupted or truncated tree";
1363                goto error;
1364        }
1365
1366        return 1;
1367
1368error:
1369        printf(" error!\n%s for '%s' hash node in '%s' image node\n",
1370               err_msg, fit_get_name(fit, noffset, NULL),
1371               fit_get_name(fit, image_noffset, NULL));
1372        return 0;
1373}
1374
1375/**
1376 * fit_image_verify - verify data integrity
1377 * @fit: pointer to the FIT format image header
1378 * @image_noffset: component image node offset
1379 *
1380 * fit_image_verify() goes over component image hash nodes,
1381 * re-calculates each data hash and compares with the value stored in hash
1382 * node.
1383 *
1384 * returns:
1385 *     1, if all hashes are valid
1386 *     0, otherwise (or on error)
1387 */
1388int fit_image_verify(const void *fit, int image_noffset)
1389{
1390        const char *name = fit_get_name(fit, image_noffset, NULL);
1391        const void      *data;
1392        size_t          size;
1393        char            *err_msg = "";
1394
1395        if (IS_ENABLED(CONFIG_FIT_SIGNATURE) && strchr(name, '@')) {
1396                /*
1397                 * We don't support this since libfdt considers names with the
1398                 * name root but different @ suffix to be equal
1399                 */
1400                err_msg = "Node name contains @";
1401                goto err;
1402        }
1403        /* Get image data and data length */
1404        if (fit_image_get_data_and_size(fit, image_noffset, &data, &size)) {
1405                err_msg = "Can't get image data/size";
1406                goto err;
1407        }
1408
1409        return fit_image_verify_with_data(fit, image_noffset, data, size);
1410
1411err:
1412        printf("error!\n%s in '%s' image node\n", err_msg,
1413               fit_get_name(fit, image_noffset, NULL));
1414        return 0;
1415}
1416
1417/**
1418 * fit_all_image_verify - verify data integrity for all images
1419 * @fit: pointer to the FIT format image header
1420 *
1421 * fit_all_image_verify() goes over all images in the FIT and
1422 * for every images checks if all it's hashes are valid.
1423 *
1424 * returns:
1425 *     1, if all hashes of all images are valid
1426 *     0, otherwise (or on error)
1427 */
1428int fit_all_image_verify(const void *fit)
1429{
1430        int images_noffset;
1431        int noffset;
1432        int ndepth;
1433        int count;
1434
1435        /* Find images parent node offset */
1436        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1437        if (images_noffset < 0) {
1438                printf("Can't find images parent node '%s' (%s)\n",
1439                       FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1440                return 0;
1441        }
1442
1443        /* Process all image subnodes, check hashes for each */
1444        printf("## Checking hash(es) for FIT Image at %08lx ...\n",
1445               (ulong)fit);
1446        for (ndepth = 0, count = 0,
1447             noffset = fdt_next_node(fit, images_noffset, &ndepth);
1448                        (noffset >= 0) && (ndepth > 0);
1449                        noffset = fdt_next_node(fit, noffset, &ndepth)) {
1450                if (ndepth == 1) {
1451                        /*
1452                         * Direct child node of the images parent node,
1453                         * i.e. component image node.
1454                         */
1455                        printf("   Hash(es) for Image %u (%s): ", count,
1456                               fit_get_name(fit, noffset, NULL));
1457                        count++;
1458
1459                        if (!fit_image_verify(fit, noffset))
1460                                return 0;
1461                        printf("\n");
1462                }
1463        }
1464        return 1;
1465}
1466
1467static int fit_image_uncipher(const void *fit, int image_noffset,
1468                              void **data, size_t *size)
1469{
1470        int cipher_noffset, ret;
1471        void *dst;
1472        size_t size_dst;
1473
1474        cipher_noffset = fdt_subnode_offset(fit, image_noffset,
1475                                            FIT_CIPHER_NODENAME);
1476        if (cipher_noffset < 0)
1477                return 0;
1478
1479        ret = fit_image_decrypt_data(fit, image_noffset, cipher_noffset,
1480                                     *data, *size, &dst, &size_dst);
1481        if (ret)
1482                goto out;
1483
1484        *data = dst;
1485        *size = size_dst;
1486
1487 out:
1488        return ret;
1489}
1490
1491/**
1492 * fit_image_check_os - check whether image node is of a given os type
1493 * @fit: pointer to the FIT format image header
1494 * @noffset: component image node offset
1495 * @os: requested image os
1496 *
1497 * fit_image_check_os() reads image os property and compares its numeric
1498 * id with the requested os. Comparison result is returned to the caller.
1499 *
1500 * returns:
1501 *     1 if image is of given os type
1502 *     0 otherwise (or on error)
1503 */
1504int fit_image_check_os(const void *fit, int noffset, uint8_t os)
1505{
1506        uint8_t image_os;
1507
1508        if (fit_image_get_os(fit, noffset, &image_os))
1509                return 0;
1510        return (os == image_os);
1511}
1512
1513/**
1514 * fit_image_check_arch - check whether image node is of a given arch
1515 * @fit: pointer to the FIT format image header
1516 * @noffset: component image node offset
1517 * @arch: requested imagearch
1518 *
1519 * fit_image_check_arch() reads image arch property and compares its numeric
1520 * id with the requested arch. Comparison result is returned to the caller.
1521 *
1522 * returns:
1523 *     1 if image is of given arch
1524 *     0 otherwise (or on error)
1525 */
1526int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
1527{
1528        uint8_t image_arch;
1529        int aarch32_support = 0;
1530
1531        /* Let's assume that sandbox can load any architecture */
1532        if (IS_ENABLED(CONFIG_SANDBOX))
1533                return true;
1534
1535        if (IS_ENABLED(CONFIG_ARM64_SUPPORT_AARCH32))
1536                aarch32_support = 1;
1537
1538        if (fit_image_get_arch(fit, noffset, &image_arch))
1539                return 0;
1540        return (arch == image_arch) ||
1541                (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
1542                (arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
1543                 aarch32_support);
1544}
1545
1546/**
1547 * fit_image_check_type - check whether image node is of a given type
1548 * @fit: pointer to the FIT format image header
1549 * @noffset: component image node offset
1550 * @type: requested image type
1551 *
1552 * fit_image_check_type() reads image type property and compares its numeric
1553 * id with the requested type. Comparison result is returned to the caller.
1554 *
1555 * returns:
1556 *     1 if image is of given type
1557 *     0 otherwise (or on error)
1558 */
1559int fit_image_check_type(const void *fit, int noffset, uint8_t type)
1560{
1561        uint8_t image_type;
1562
1563        if (fit_image_get_type(fit, noffset, &image_type))
1564                return 0;
1565        return (type == image_type);
1566}
1567
1568/**
1569 * fit_image_check_comp - check whether image node uses given compression
1570 * @fit: pointer to the FIT format image header
1571 * @noffset: component image node offset
1572 * @comp: requested image compression type
1573 *
1574 * fit_image_check_comp() reads image compression property and compares its
1575 * numeric id with the requested compression type. Comparison result is
1576 * returned to the caller.
1577 *
1578 * returns:
1579 *     1 if image uses requested compression
1580 *     0 otherwise (or on error)
1581 */
1582int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
1583{
1584        uint8_t image_comp;
1585
1586        if (fit_image_get_comp(fit, noffset, &image_comp))
1587                return 0;
1588        return (comp == image_comp);
1589}
1590
1591/**
1592 * fdt_check_no_at() - Check for nodes whose names contain '@'
1593 *
1594 * This checks the parent node and all subnodes recursively
1595 *
1596 * @fit: FIT to check
1597 * @parent: Parent node to check
1598 * @return 0 if OK, -EADDRNOTAVAIL is a node has a name containing '@'
1599 */
1600static int fdt_check_no_at(const void *fit, int parent)
1601{
1602        const char *name;
1603        int node;
1604        int ret;
1605
1606        name = fdt_get_name(fit, parent, NULL);
1607        if (!name || strchr(name, '@'))
1608                return -EADDRNOTAVAIL;
1609
1610        fdt_for_each_subnode(node, fit, parent) {
1611                ret = fdt_check_no_at(fit, node);
1612                if (ret)
1613                        return ret;
1614        }
1615
1616        return 0;
1617}
1618
1619int fit_check_format(const void *fit, ulong size)
1620{
1621        int ret;
1622
1623        /* A FIT image must be a valid FDT */
1624        ret = fdt_check_header(fit);
1625        if (ret) {
1626                log_debug("Wrong FIT format: not a flattened device tree (err=%d)\n",
1627                          ret);
1628                return -ENOEXEC;
1629        }
1630
1631        if (CONFIG_IS_ENABLED(FIT_FULL_CHECK)) {
1632                /*
1633                 * If we are not given the size, make do wtih calculating it.
1634                 * This is not as secure, so we should consider a flag to
1635                 * control this.
1636                 */
1637                if (size == IMAGE_SIZE_INVAL)
1638                        size = fdt_totalsize(fit);
1639                ret = fdt_check_full(fit, size);
1640                if (ret)
1641                        ret = -EINVAL;
1642
1643                /*
1644                 * U-Boot stopped using unit addressed in 2017. Since libfdt
1645                 * can match nodes ignoring any unit address, signature
1646                 * verification can see the wrong node if one is inserted with
1647                 * the same name as a valid node but with a unit address
1648                 * attached. Protect against this by disallowing unit addresses.
1649                 */
1650                if (!ret && CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
1651                        ret = fdt_check_no_at(fit, 0);
1652
1653                        if (ret) {
1654                                log_debug("FIT check error %d\n", ret);
1655                                return ret;
1656                        }
1657                }
1658                if (ret) {
1659                        log_debug("FIT check error %d\n", ret);
1660                        return ret;
1661                }
1662        }
1663
1664        /* mandatory / node 'description' property */
1665        if (!fdt_getprop(fit, 0, FIT_DESC_PROP, NULL)) {
1666                log_debug("Wrong FIT format: no description\n");
1667                return -ENOMSG;
1668        }
1669
1670        if (IMAGE_ENABLE_TIMESTAMP) {
1671                /* mandatory / node 'timestamp' property */
1672                if (!fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL)) {
1673                        log_debug("Wrong FIT format: no timestamp\n");
1674                        return -EBADMSG;
1675                }
1676        }
1677
1678        /* mandatory subimages parent '/images' node */
1679        if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
1680                log_debug("Wrong FIT format: no images parent node\n");
1681                return -ENOENT;
1682        }
1683
1684        return 0;
1685}
1686
1687/**
1688 * fit_conf_find_compat
1689 * @fit: pointer to the FIT format image header
1690 * @fdt: pointer to the device tree to compare against
1691 *
1692 * fit_conf_find_compat() attempts to find the configuration whose fdt is the
1693 * most compatible with the passed in device tree.
1694 *
1695 * Example:
1696 *
1697 * / o image-tree
1698 *   |-o images
1699 *   | |-o fdt-1
1700 *   | |-o fdt-2
1701 *   |
1702 *   |-o configurations
1703 *     |-o config-1
1704 *     | |-fdt = fdt-1
1705 *     |
1706 *     |-o config-2
1707 *       |-fdt = fdt-2
1708 *
1709 * / o U-Boot fdt
1710 *   |-compatible = "foo,bar", "bim,bam"
1711 *
1712 * / o kernel fdt1
1713 *   |-compatible = "foo,bar",
1714 *
1715 * / o kernel fdt2
1716 *   |-compatible = "bim,bam", "baz,biz"
1717 *
1718 * Configuration 1 would be picked because the first string in U-Boot's
1719 * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
1720 * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
1721 *
1722 * As an optimization, the compatible property from the FDT's root node can be
1723 * copied into the configuration node in the FIT image. This is required to
1724 * match configurations with compressed FDTs.
1725 *
1726 * returns:
1727 *     offset to the configuration to use if one was found
1728 *     -1 otherwise
1729 */
1730int fit_conf_find_compat(const void *fit, const void *fdt)
1731{
1732        int ndepth = 0;
1733        int noffset, confs_noffset, images_noffset;
1734        const void *fdt_compat;
1735        int fdt_compat_len;
1736        int best_match_offset = 0;
1737        int best_match_pos = 0;
1738
1739        confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1740        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1741        if (confs_noffset < 0 || images_noffset < 0) {
1742                debug("Can't find configurations or images nodes.\n");
1743                return -1;
1744        }
1745
1746        fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
1747        if (!fdt_compat) {
1748                debug("Fdt for comparison has no \"compatible\" property.\n");
1749                return -1;
1750        }
1751
1752        /*
1753         * Loop over the configurations in the FIT image.
1754         */
1755        for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
1756                        (noffset >= 0) && (ndepth > 0);
1757                        noffset = fdt_next_node(fit, noffset, &ndepth)) {
1758                const void *fdt;
1759                const char *kfdt_name;
1760                int kfdt_noffset, compat_noffset;
1761                const char *cur_fdt_compat;
1762                int len;
1763                size_t sz;
1764                int i;
1765
1766                if (ndepth > 1)
1767                        continue;
1768
1769                /* If there's a compat property in the config node, use that. */
1770                if (fdt_getprop(fit, noffset, "compatible", NULL)) {
1771                        fdt = fit;                /* search in FIT image */
1772                        compat_noffset = noffset; /* search under config node */
1773                } else {        /* Otherwise extract it from the kernel FDT. */
1774                        kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
1775                        if (!kfdt_name) {
1776                                debug("No fdt property found.\n");
1777                                continue;
1778                        }
1779                        kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
1780                                                          kfdt_name);
1781                        if (kfdt_noffset < 0) {
1782                                debug("No image node named \"%s\" found.\n",
1783                                      kfdt_name);
1784                                continue;
1785                        }
1786
1787                        if (!fit_image_check_comp(fit, kfdt_noffset,
1788                                                  IH_COMP_NONE)) {
1789                                debug("Can't extract compat from \"%s\" "
1790                                      "(compressed)\n", kfdt_name);
1791                                continue;
1792                        }
1793
1794                        /* search in this config's kernel FDT */
1795                        if (fit_image_get_data_and_size(fit, kfdt_noffset,
1796                                                        &fdt, &sz)) {
1797                                debug("Failed to get fdt \"%s\".\n", kfdt_name);
1798                                continue;
1799                        }
1800
1801                        compat_noffset = 0;  /* search kFDT under root node */
1802                }
1803
1804                len = fdt_compat_len;
1805                cur_fdt_compat = fdt_compat;
1806                /*
1807                 * Look for a match for each U-Boot compatibility string in
1808                 * turn in the compat string property.
1809                 */
1810                for (i = 0; len > 0 &&
1811                     (!best_match_offset || best_match_pos > i); i++) {
1812                        int cur_len = strlen(cur_fdt_compat) + 1;
1813
1814                        if (!fdt_node_check_compatible(fdt, compat_noffset,
1815                                                       cur_fdt_compat)) {
1816                                best_match_offset = noffset;
1817                                best_match_pos = i;
1818                                break;
1819                        }
1820                        len -= cur_len;
1821                        cur_fdt_compat += cur_len;
1822                }
1823        }
1824        if (!best_match_offset) {
1825                debug("No match found.\n");
1826                return -1;
1827        }
1828
1829        return best_match_offset;
1830}
1831
1832int fit_conf_get_node(const void *fit, const char *conf_uname)
1833{
1834        int noffset, confs_noffset;
1835        int len;
1836        const char *s;
1837        char *conf_uname_copy = NULL;
1838
1839        confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1840        if (confs_noffset < 0) {
1841                debug("Can't find configurations parent node '%s' (%s)\n",
1842                      FIT_CONFS_PATH, fdt_strerror(confs_noffset));
1843                return confs_noffset;
1844        }
1845
1846        if (conf_uname == NULL) {
1847                /* get configuration unit name from the default property */
1848                debug("No configuration specified, trying default...\n");
1849                if (!tools_build() && IS_ENABLED(CONFIG_MULTI_DTB_FIT)) {
1850                        noffset = fit_find_config_node(fit);
1851                        if (noffset < 0)
1852                                return noffset;
1853                        conf_uname = fdt_get_name(fit, noffset, NULL);
1854                } else {
1855                        conf_uname = (char *)fdt_getprop(fit, confs_noffset,
1856                                                         FIT_DEFAULT_PROP, &len);
1857                        if (conf_uname == NULL) {
1858                                fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
1859                                              len);
1860                                return len;
1861                        }
1862                }
1863                debug("Found default configuration: '%s'\n", conf_uname);
1864        }
1865
1866        s = strchr(conf_uname, '#');
1867        if (s) {
1868                len = s - conf_uname;
1869                conf_uname_copy = malloc(len + 1);
1870                if (!conf_uname_copy) {
1871                        debug("Can't allocate uname copy: '%s'\n",
1872                                        conf_uname);
1873                        return -ENOMEM;
1874                }
1875                memcpy(conf_uname_copy, conf_uname, len);
1876                conf_uname_copy[len] = '\0';
1877                conf_uname = conf_uname_copy;
1878        }
1879
1880        noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
1881        if (noffset < 0) {
1882                debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
1883                      conf_uname, fdt_strerror(noffset));
1884        }
1885
1886        if (conf_uname_copy)
1887                free(conf_uname_copy);
1888
1889        return noffset;
1890}
1891
1892int fit_conf_get_prop_node_count(const void *fit, int noffset,
1893                const char *prop_name)
1894{
1895        return fdt_stringlist_count(fit, noffset, prop_name);
1896}
1897
1898int fit_conf_get_prop_node_index(const void *fit, int noffset,
1899                const char *prop_name, int index)
1900{
1901        const char *uname;
1902        int len;
1903
1904        /* get kernel image unit name from configuration kernel property */
1905        uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
1906        if (uname == NULL)
1907                return len;
1908
1909        return fit_image_get_node(fit, uname);
1910}
1911
1912int fit_conf_get_prop_node(const void *fit, int noffset,
1913                const char *prop_name)
1914{
1915        return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
1916}
1917
1918static int fit_image_select(const void *fit, int rd_noffset, int verify)
1919{
1920        fit_image_print(fit, rd_noffset, "   ");
1921
1922        if (verify) {
1923                puts("   Verifying Hash Integrity ... ");
1924                if (!fit_image_verify(fit, rd_noffset)) {
1925                        puts("Bad Data Hash\n");
1926                        return -EACCES;
1927                }
1928                puts("OK\n");
1929        }
1930
1931        return 0;
1932}
1933
1934int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
1935                        ulong addr)
1936{
1937        int cfg_noffset;
1938        void *fit_hdr;
1939        int noffset;
1940
1941        debug("*  %s: using config '%s' from image at 0x%08lx\n",
1942              prop_name, images->fit_uname_cfg, addr);
1943
1944        /* Check whether configuration has this property defined */
1945        fit_hdr = map_sysmem(addr, 0);
1946        cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
1947        if (cfg_noffset < 0) {
1948                debug("*  %s: no such config\n", prop_name);
1949                return -EINVAL;
1950        }
1951
1952        noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
1953        if (noffset < 0) {
1954                debug("*  %s: no '%s' in config\n", prop_name, prop_name);
1955                return -ENOENT;
1956        }
1957
1958        return noffset;
1959}
1960
1961/**
1962 * fit_get_image_type_property() - get property name for IH_TYPE_...
1963 *
1964 * @return the properly name where we expect to find the image in the
1965 * config node
1966 */
1967static const char *fit_get_image_type_property(int type)
1968{
1969        /*
1970         * This is sort-of available in the uimage_type[] table in image.c
1971         * but we don't have access to the short name, and "fdt" is different
1972         * anyway. So let's just keep it here.
1973         */
1974        switch (type) {
1975        case IH_TYPE_FLATDT:
1976                return FIT_FDT_PROP;
1977        case IH_TYPE_KERNEL:
1978                return FIT_KERNEL_PROP;
1979        case IH_TYPE_FIRMWARE:
1980                return FIT_FIRMWARE_PROP;
1981        case IH_TYPE_RAMDISK:
1982                return FIT_RAMDISK_PROP;
1983        case IH_TYPE_X86_SETUP:
1984                return FIT_SETUP_PROP;
1985        case IH_TYPE_LOADABLE:
1986                return FIT_LOADABLE_PROP;
1987        case IH_TYPE_FPGA:
1988                return FIT_FPGA_PROP;
1989        case IH_TYPE_STANDALONE:
1990                return FIT_STANDALONE_PROP;
1991        }
1992
1993        return "unknown";
1994}
1995
1996int fit_image_load(bootm_headers_t *images, ulong addr,
1997                   const char **fit_unamep, const char **fit_uname_configp,
1998                   int arch, int image_type, int bootstage_id,
1999                   enum fit_load_op load_op, ulong *datap, ulong *lenp)
2000{
2001        int cfg_noffset, noffset;
2002        const char *fit_uname;
2003        const char *fit_uname_config;
2004        const char *fit_base_uname_config;
2005        const void *fit;
2006        void *buf;
2007        void *loadbuf;
2008        size_t size;
2009        int type_ok, os_ok;
2010        ulong load, load_end, data, len;
2011        uint8_t os, comp;
2012        const char *prop_name;
2013        int ret;
2014
2015        fit = map_sysmem(addr, 0);
2016        fit_uname = fit_unamep ? *fit_unamep : NULL;
2017        fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
2018        fit_base_uname_config = NULL;
2019        prop_name = fit_get_image_type_property(image_type);
2020        printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
2021
2022        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
2023        ret = fit_check_format(fit, IMAGE_SIZE_INVAL);
2024        if (ret) {
2025                printf("Bad FIT %s image format! (err=%d)\n", prop_name, ret);
2026                if (CONFIG_IS_ENABLED(FIT_SIGNATURE) && ret == -EADDRNOTAVAIL)
2027                        printf("Signature checking prevents use of unit addresses (@) in nodes\n");
2028                bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
2029                return ret;
2030        }
2031        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
2032        if (fit_uname) {
2033                /* get FIT component image node offset */
2034                bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
2035                noffset = fit_image_get_node(fit, fit_uname);
2036        } else {
2037                /*
2038                 * no image node unit name, try to get config
2039                 * node first. If config unit node name is NULL
2040                 * fit_conf_get_node() will try to find default config node
2041                 */
2042                bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
2043                if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config) {
2044                        cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
2045                } else {
2046                        cfg_noffset = fit_conf_get_node(fit,
2047                                                        fit_uname_config);
2048                }
2049                if (cfg_noffset < 0) {
2050                        puts("Could not find configuration node\n");
2051                        bootstage_error(bootstage_id +
2052                                        BOOTSTAGE_SUB_NO_UNIT_NAME);
2053                        return -ENOENT;
2054                }
2055
2056                fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
2057                printf("   Using '%s' configuration\n", fit_base_uname_config);
2058                /* Remember this config */
2059                if (image_type == IH_TYPE_KERNEL)
2060                        images->fit_uname_cfg = fit_base_uname_config;
2061
2062                if (FIT_IMAGE_ENABLE_VERIFY && images->verify) {
2063                        puts("   Verifying Hash Integrity ... ");
2064                        if (fit_config_verify(fit, cfg_noffset)) {
2065                                puts("Bad Data Hash\n");
2066                                bootstage_error(bootstage_id +
2067                                        BOOTSTAGE_SUB_HASH);
2068                                return -EACCES;
2069                        }
2070                        puts("OK\n");
2071                }
2072
2073                bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
2074
2075                noffset = fit_conf_get_prop_node(fit, cfg_noffset,
2076                                                 prop_name);
2077                fit_uname = fit_get_name(fit, noffset, NULL);
2078        }
2079        if (noffset < 0) {
2080                printf("Could not find subimage node type '%s'\n", prop_name);
2081                bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
2082                return -ENOENT;
2083        }
2084
2085        printf("   Trying '%s' %s subimage\n", fit_uname, prop_name);
2086
2087        ret = fit_image_select(fit, noffset, images->verify);
2088        if (ret) {
2089                bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
2090                return ret;
2091        }
2092
2093        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
2094        if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) {
2095                if (!fit_image_check_target_arch(fit, noffset)) {
2096                        puts("Unsupported Architecture\n");
2097                        bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
2098                        return -ENOEXEC;
2099                }
2100        }
2101
2102#ifndef USE_HOSTCC
2103        {
2104        uint8_t os_arch;
2105
2106        fit_image_get_arch(fit, noffset, &os_arch);
2107        images->os.arch = os_arch;
2108        }
2109#endif
2110
2111        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
2112        type_ok = fit_image_check_type(fit, noffset, image_type) ||
2113                  fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
2114                  fit_image_check_type(fit, noffset, IH_TYPE_TEE) ||
2115                  (image_type == IH_TYPE_KERNEL &&
2116                   fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
2117
2118        os_ok = image_type == IH_TYPE_FLATDT ||
2119                image_type == IH_TYPE_FPGA ||
2120                fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
2121                fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
2122                fit_image_check_os(fit, noffset, IH_OS_TEE) ||
2123                fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
2124                fit_image_check_os(fit, noffset, IH_OS_EFI) ||
2125                fit_image_check_os(fit, noffset, IH_OS_VXWORKS);
2126
2127        /*
2128         * If either of the checks fail, we should report an error, but
2129         * if the image type is coming from the "loadables" field, we
2130         * don't care what it is
2131         */
2132        if ((!type_ok || !os_ok) && image_type != IH_TYPE_LOADABLE) {
2133                fit_image_get_os(fit, noffset, &os);
2134                printf("No %s %s %s Image\n",
2135                       genimg_get_os_name(os),
2136                       genimg_get_arch_name(arch),
2137                       genimg_get_type_name(image_type));
2138                bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
2139                return -EIO;
2140        }
2141
2142        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
2143
2144        /* get image data address and length */
2145        if (fit_image_get_data_and_size(fit, noffset,
2146                                        (const void **)&buf, &size)) {
2147                printf("Could not find %s subimage data!\n", prop_name);
2148                bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
2149                return -ENOENT;
2150        }
2151
2152        /* Decrypt data before uncompress/move */
2153        if (IS_ENABLED(CONFIG_FIT_CIPHER) && IMAGE_ENABLE_DECRYPT) {
2154                puts("   Decrypting Data ... ");
2155                if (fit_image_uncipher(fit, noffset, &buf, &size)) {
2156                        puts("Error\n");
2157                        return -EACCES;
2158                }
2159                puts("OK\n");
2160        }
2161
2162        /* perform any post-processing on the image data */
2163        if (!tools_build() && IS_ENABLED(CONFIG_FIT_IMAGE_POST_PROCESS))
2164                board_fit_image_post_process(fit, noffset, &buf, &size);
2165
2166        len = (ulong)size;
2167
2168        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
2169
2170        data = map_to_sysmem(buf);
2171        load = data;
2172        if (load_op == FIT_LOAD_IGNORED) {
2173                /* Don't load */
2174        } else if (fit_image_get_load(fit, noffset, &load)) {
2175                if (load_op == FIT_LOAD_REQUIRED) {
2176                        printf("Can't get %s subimage load address!\n",
2177                               prop_name);
2178                        bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
2179                        return -EBADF;
2180                }
2181        } else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
2182                ulong image_start, image_end;
2183
2184                /*
2185                 * move image data to the load address,
2186                 * make sure we don't overwrite initial image
2187                 */
2188                image_start = addr;
2189                image_end = addr + fit_get_size(fit);
2190
2191                load_end = load + len;
2192                if (image_type != IH_TYPE_KERNEL &&
2193                    load < image_end && load_end > image_start) {
2194                        printf("Error: %s overwritten\n", prop_name);
2195                        return -EXDEV;
2196                }
2197
2198                printf("   Loading %s from 0x%08lx to 0x%08lx\n",
2199                       prop_name, data, load);
2200        } else {
2201                load = data;    /* No load address specified */
2202        }
2203
2204        comp = IH_COMP_NONE;
2205        loadbuf = buf;
2206        /* Kernel images get decompressed later in bootm_load_os(). */
2207        if (!fit_image_get_comp(fit, noffset, &comp) &&
2208            comp != IH_COMP_NONE &&
2209            !(image_type == IH_TYPE_KERNEL ||
2210              image_type == IH_TYPE_KERNEL_NOLOAD ||
2211              image_type == IH_TYPE_RAMDISK)) {
2212                ulong max_decomp_len = len * 20;
2213                if (load == data) {
2214                        loadbuf = malloc(max_decomp_len);
2215                        load = map_to_sysmem(loadbuf);
2216                } else {
2217                        loadbuf = map_sysmem(load, max_decomp_len);
2218                }
2219                if (image_decomp(comp, load, data, image_type,
2220                                loadbuf, buf, len, max_decomp_len, &load_end)) {
2221                        printf("Error decompressing %s\n", prop_name);
2222
2223                        return -ENOEXEC;
2224                }
2225                len = load_end - load;
2226        } else if (load != data) {
2227                loadbuf = map_sysmem(load, len);
2228                memcpy(loadbuf, buf, len);
2229        }
2230
2231        if (image_type == IH_TYPE_RAMDISK && comp != IH_COMP_NONE)
2232                puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
2233                     " please fix your .its file!\n");
2234
2235        /* verify that image data is a proper FDT blob */
2236        if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
2237                puts("Subimage data is not a FDT");
2238                return -ENOEXEC;
2239        }
2240
2241        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
2242
2243        *datap = load;
2244        *lenp = len;
2245        if (fit_unamep)
2246                *fit_unamep = (char *)fit_uname;
2247        if (fit_uname_configp)
2248                *fit_uname_configp = (char *)(fit_uname_config ? :
2249                                              fit_base_uname_config);
2250
2251        return noffset;
2252}
2253
2254int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
2255                        ulong *setup_start, ulong *setup_len)
2256{
2257        int noffset;
2258        ulong addr;
2259        ulong len;
2260        int ret;
2261
2262        addr = map_to_sysmem(images->fit_hdr_os);
2263        noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
2264        if (noffset < 0)
2265                return noffset;
2266
2267        ret = fit_image_load(images, addr, NULL, NULL, arch,
2268                             IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
2269                             FIT_LOAD_REQUIRED, setup_start, &len);
2270
2271        return ret;
2272}
2273
2274#ifndef USE_HOSTCC
2275int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
2276                   const char **fit_unamep, const char **fit_uname_configp,
2277                   int arch, ulong *datap, ulong *lenp)
2278{
2279        int fdt_noffset, cfg_noffset, count;
2280        const void *fit;
2281        const char *fit_uname = NULL;
2282        const char *fit_uname_config = NULL;
2283        char *fit_uname_config_copy = NULL;
2284        char *next_config = NULL;
2285        ulong load, len;
2286#ifdef CONFIG_OF_LIBFDT_OVERLAY
2287        ulong image_start, image_end;
2288        ulong ovload, ovlen, ovcopylen;
2289        const char *uconfig;
2290        const char *uname;
2291        void *base, *ov, *ovcopy = NULL;
2292        int i, err, noffset, ov_noffset;
2293#endif
2294
2295        fit_uname = fit_unamep ? *fit_unamep : NULL;
2296
2297        if (fit_uname_configp && *fit_uname_configp) {
2298                fit_uname_config_copy = strdup(*fit_uname_configp);
2299                if (!fit_uname_config_copy)
2300                        return -ENOMEM;
2301
2302                next_config = strchr(fit_uname_config_copy, '#');
2303                if (next_config)
2304                        *next_config++ = '\0';
2305                if (next_config - 1 > fit_uname_config_copy)
2306                        fit_uname_config = fit_uname_config_copy;
2307        }
2308
2309        fdt_noffset = fit_image_load(images,
2310                addr, &fit_uname, &fit_uname_config,
2311                arch, IH_TYPE_FLATDT,
2312                BOOTSTAGE_ID_FIT_FDT_START,
2313                FIT_LOAD_OPTIONAL, &load, &len);
2314
2315        if (fdt_noffset < 0)
2316                goto out;
2317
2318        debug("fit_uname=%s, fit_uname_config=%s\n",
2319                        fit_uname ? fit_uname : "<NULL>",
2320                        fit_uname_config ? fit_uname_config : "<NULL>");
2321
2322        fit = map_sysmem(addr, 0);
2323
2324        cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
2325
2326        /* single blob, or error just return as well */
2327        count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
2328        if (count <= 1 && !next_config)
2329                goto out;
2330
2331        /* we need to apply overlays */
2332
2333#ifdef CONFIG_OF_LIBFDT_OVERLAY
2334        image_start = addr;
2335        image_end = addr + fit_get_size(fit);
2336        /* verify that relocation took place by load address not being in fit */
2337        if (load >= image_start && load < image_end) {
2338                /* check is simplified; fit load checks for overlaps */
2339                printf("Overlayed FDT requires relocation\n");
2340                fdt_noffset = -EBADF;
2341                goto out;
2342        }
2343
2344        base = map_sysmem(load, len);
2345
2346        /* apply extra configs in FIT first, followed by args */
2347        for (i = 1; ; i++) {
2348                if (i < count) {
2349                        noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
2350                                                               FIT_FDT_PROP, i);
2351                        uname = fit_get_name(fit, noffset, NULL);
2352                        uconfig = NULL;
2353                } else {
2354                        if (!next_config)
2355                                break;
2356                        uconfig = next_config;
2357                        next_config = strchr(next_config, '#');
2358                        if (next_config)
2359                                *next_config++ = '\0';
2360                        uname = NULL;
2361
2362                        /*
2363                         * fit_image_load() would load the first FDT from the
2364                         * extra config only when uconfig is specified.
2365                         * Check if the extra config contains multiple FDTs and
2366                         * if so, load them.
2367                         */
2368                        cfg_noffset = fit_conf_get_node(fit, uconfig);
2369
2370                        i = 0;
2371                        count = fit_conf_get_prop_node_count(fit, cfg_noffset,
2372                                                             FIT_FDT_PROP);
2373                }
2374
2375                debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
2376
2377                ov_noffset = fit_image_load(images,
2378                        addr, &uname, &uconfig,
2379                        arch, IH_TYPE_FLATDT,
2380                        BOOTSTAGE_ID_FIT_FDT_START,
2381                        FIT_LOAD_IGNORED, &ovload, &ovlen);
2382                if (ov_noffset < 0) {
2383                        printf("load of %s failed\n", uname);
2384                        continue;
2385                }
2386                debug("%s loaded at 0x%08lx len=0x%08lx\n",
2387                                uname, ovload, ovlen);
2388                ov = map_sysmem(ovload, ovlen);
2389
2390                ovcopylen = ALIGN(fdt_totalsize(ov), SZ_4K);
2391                ovcopy = malloc(ovcopylen);
2392                if (!ovcopy) {
2393                        printf("failed to duplicate DTO before application\n");
2394                        fdt_noffset = -ENOMEM;
2395                        goto out;
2396                }
2397
2398                err = fdt_open_into(ov, ovcopy, ovcopylen);
2399                if (err < 0) {
2400                        printf("failed on fdt_open_into for DTO\n");
2401                        fdt_noffset = err;
2402                        goto out;
2403                }
2404
2405                base = map_sysmem(load, len + ovlen);
2406                err = fdt_open_into(base, base, len + ovlen);
2407                if (err < 0) {
2408                        printf("failed on fdt_open_into\n");
2409                        fdt_noffset = err;
2410                        goto out;
2411                }
2412
2413                /* the verbose method prints out messages on error */
2414                err = fdt_overlay_apply_verbose(base, ovcopy);
2415                if (err < 0) {
2416                        fdt_noffset = err;
2417                        goto out;
2418                }
2419                fdt_pack(base);
2420                len = fdt_totalsize(base);
2421
2422                free(ovcopy);
2423                ovcopy = NULL;
2424        }
2425#else
2426        printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
2427        fdt_noffset = -EBADF;
2428#endif
2429
2430out:
2431        if (datap)
2432                *datap = load;
2433        if (lenp)
2434                *lenp = len;
2435        if (fit_unamep)
2436                *fit_unamep = fit_uname;
2437        if (fit_uname_configp)
2438                *fit_uname_configp = fit_uname_config;
2439
2440#ifdef CONFIG_OF_LIBFDT_OVERLAY
2441        if (ovcopy)
2442                free(ovcopy);
2443#endif
2444        if (fit_uname_config_copy)
2445                free(fit_uname_config_copy);
2446        return fdt_noffset;
2447}
2448#endif
2449