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        const 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, const char **algo)
1067{
1068        int len;
1069
1070        *algo = (const 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 * @name: requested hash algorithm name
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(name);
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        const 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 *key_blob, const void *data,
1313                               size_t size)
1314{
1315        int             noffset = 0;
1316        char            *err_msg = "";
1317        int verify_all = 1;
1318        int ret;
1319
1320        /* Verify all required signatures */
1321        if (FIT_IMAGE_ENABLE_VERIFY &&
1322            fit_image_verify_required_sigs(fit, image_noffset, data, size,
1323                                           key_blob, &verify_all)) {
1324                err_msg = "Unable to verify required signature";
1325                goto error;
1326        }
1327
1328        /* Process all hash subnodes of the component image node */
1329        fdt_for_each_subnode(noffset, fit, image_noffset) {
1330                const char *name = fit_get_name(fit, noffset, NULL);
1331
1332                /*
1333                 * Check subnode name, must be equal to "hash".
1334                 * Multiple hash nodes require unique unit node
1335                 * names, e.g. hash-1, hash-2, etc.
1336                 */
1337                if (!strncmp(name, FIT_HASH_NODENAME,
1338                             strlen(FIT_HASH_NODENAME))) {
1339                        if (fit_image_check_hash(fit, noffset, data, size,
1340                                                 &err_msg))
1341                                goto error;
1342                        puts("+ ");
1343                } else if (FIT_IMAGE_ENABLE_VERIFY && verify_all &&
1344                                !strncmp(name, FIT_SIG_NODENAME,
1345                                        strlen(FIT_SIG_NODENAME))) {
1346                        ret = fit_image_check_sig(fit, noffset, data, size,
1347                                                  gd_fdt_blob(), -1, &err_msg);
1348
1349                        /*
1350                         * Show an indication on failure, but do not return
1351                         * an error. Only keys marked 'required' can cause
1352                         * an image validation failure. See the call to
1353                         * fit_image_verify_required_sigs() above.
1354                         */
1355                        if (ret)
1356                                puts("- ");
1357                        else
1358                                puts("+ ");
1359                }
1360        }
1361
1362        if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) {
1363                err_msg = "Corrupted or truncated tree";
1364                goto error;
1365        }
1366
1367        return 1;
1368
1369error:
1370        printf(" error!\n%s for '%s' hash node in '%s' image node\n",
1371               err_msg, fit_get_name(fit, noffset, NULL),
1372               fit_get_name(fit, image_noffset, NULL));
1373        return 0;
1374}
1375
1376/**
1377 * fit_image_verify - verify data integrity
1378 * @fit: pointer to the FIT format image header
1379 * @image_noffset: component image node offset
1380 *
1381 * fit_image_verify() goes over component image hash nodes,
1382 * re-calculates each data hash and compares with the value stored in hash
1383 * node.
1384 *
1385 * returns:
1386 *     1, if all hashes are valid
1387 *     0, otherwise (or on error)
1388 */
1389int fit_image_verify(const void *fit, int image_noffset)
1390{
1391        const char *name = fit_get_name(fit, image_noffset, NULL);
1392        const void      *data;
1393        size_t          size;
1394        char            *err_msg = "";
1395
1396        if (IS_ENABLED(CONFIG_FIT_SIGNATURE) && strchr(name, '@')) {
1397                /*
1398                 * We don't support this since libfdt considers names with the
1399                 * name root but different @ suffix to be equal
1400                 */
1401                err_msg = "Node name contains @";
1402                goto err;
1403        }
1404        /* Get image data and data length */
1405        if (fit_image_get_data_and_size(fit, image_noffset, &data, &size)) {
1406                err_msg = "Can't get image data/size";
1407                goto err;
1408        }
1409
1410        return fit_image_verify_with_data(fit, image_noffset, gd_fdt_blob(),
1411                                          data, size);
1412
1413err:
1414        printf("error!\n%s in '%s' image node\n", err_msg,
1415               fit_get_name(fit, image_noffset, NULL));
1416        return 0;
1417}
1418
1419/**
1420 * fit_all_image_verify - verify data integrity for all images
1421 * @fit: pointer to the FIT format image header
1422 *
1423 * fit_all_image_verify() goes over all images in the FIT and
1424 * for every images checks if all it's hashes are valid.
1425 *
1426 * returns:
1427 *     1, if all hashes of all images are valid
1428 *     0, otherwise (or on error)
1429 */
1430int fit_all_image_verify(const void *fit)
1431{
1432        int images_noffset;
1433        int noffset;
1434        int ndepth;
1435        int count;
1436
1437        /* Find images parent node offset */
1438        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1439        if (images_noffset < 0) {
1440                printf("Can't find images parent node '%s' (%s)\n",
1441                       FIT_IMAGES_PATH, fdt_strerror(images_noffset));
1442                return 0;
1443        }
1444
1445        /* Process all image subnodes, check hashes for each */
1446        printf("## Checking hash(es) for FIT Image at %08lx ...\n",
1447               (ulong)fit);
1448        for (ndepth = 0, count = 0,
1449             noffset = fdt_next_node(fit, images_noffset, &ndepth);
1450                        (noffset >= 0) && (ndepth > 0);
1451                        noffset = fdt_next_node(fit, noffset, &ndepth)) {
1452                if (ndepth == 1) {
1453                        /*
1454                         * Direct child node of the images parent node,
1455                         * i.e. component image node.
1456                         */
1457                        printf("   Hash(es) for Image %u (%s): ", count,
1458                               fit_get_name(fit, noffset, NULL));
1459                        count++;
1460
1461                        if (!fit_image_verify(fit, noffset))
1462                                return 0;
1463                        printf("\n");
1464                }
1465        }
1466        return 1;
1467}
1468
1469static int fit_image_uncipher(const void *fit, int image_noffset,
1470                              void **data, size_t *size)
1471{
1472        int cipher_noffset, ret;
1473        void *dst;
1474        size_t size_dst;
1475
1476        cipher_noffset = fdt_subnode_offset(fit, image_noffset,
1477                                            FIT_CIPHER_NODENAME);
1478        if (cipher_noffset < 0)
1479                return 0;
1480
1481        ret = fit_image_decrypt_data(fit, image_noffset, cipher_noffset,
1482                                     *data, *size, &dst, &size_dst);
1483        if (ret)
1484                goto out;
1485
1486        *data = dst;
1487        *size = size_dst;
1488
1489 out:
1490        return ret;
1491}
1492
1493/**
1494 * fit_image_check_os - check whether image node is of a given os type
1495 * @fit: pointer to the FIT format image header
1496 * @noffset: component image node offset
1497 * @os: requested image os
1498 *
1499 * fit_image_check_os() reads image os property and compares its numeric
1500 * id with the requested os. Comparison result is returned to the caller.
1501 *
1502 * returns:
1503 *     1 if image is of given os type
1504 *     0 otherwise (or on error)
1505 */
1506int fit_image_check_os(const void *fit, int noffset, uint8_t os)
1507{
1508        uint8_t image_os;
1509
1510        if (fit_image_get_os(fit, noffset, &image_os))
1511                return 0;
1512        return (os == image_os);
1513}
1514
1515/**
1516 * fit_image_check_arch - check whether image node is of a given arch
1517 * @fit: pointer to the FIT format image header
1518 * @noffset: component image node offset
1519 * @arch: requested imagearch
1520 *
1521 * fit_image_check_arch() reads image arch property and compares its numeric
1522 * id with the requested arch. Comparison result is returned to the caller.
1523 *
1524 * returns:
1525 *     1 if image is of given arch
1526 *     0 otherwise (or on error)
1527 */
1528int fit_image_check_arch(const void *fit, int noffset, uint8_t arch)
1529{
1530        uint8_t image_arch;
1531        int aarch32_support = 0;
1532
1533        /* Let's assume that sandbox can load any architecture */
1534        if (IS_ENABLED(CONFIG_SANDBOX))
1535                return true;
1536
1537        if (IS_ENABLED(CONFIG_ARM64_SUPPORT_AARCH32))
1538                aarch32_support = 1;
1539
1540        if (fit_image_get_arch(fit, noffset, &image_arch))
1541                return 0;
1542        return (arch == image_arch) ||
1543                (arch == IH_ARCH_I386 && image_arch == IH_ARCH_X86_64) ||
1544                (arch == IH_ARCH_ARM64 && image_arch == IH_ARCH_ARM &&
1545                 aarch32_support);
1546}
1547
1548/**
1549 * fit_image_check_type - check whether image node is of a given type
1550 * @fit: pointer to the FIT format image header
1551 * @noffset: component image node offset
1552 * @type: requested image type
1553 *
1554 * fit_image_check_type() reads image type property and compares its numeric
1555 * id with the requested type. Comparison result is returned to the caller.
1556 *
1557 * returns:
1558 *     1 if image is of given type
1559 *     0 otherwise (or on error)
1560 */
1561int fit_image_check_type(const void *fit, int noffset, uint8_t type)
1562{
1563        uint8_t image_type;
1564
1565        if (fit_image_get_type(fit, noffset, &image_type))
1566                return 0;
1567        return (type == image_type);
1568}
1569
1570/**
1571 * fit_image_check_comp - check whether image node uses given compression
1572 * @fit: pointer to the FIT format image header
1573 * @noffset: component image node offset
1574 * @comp: requested image compression type
1575 *
1576 * fit_image_check_comp() reads image compression property and compares its
1577 * numeric id with the requested compression type. Comparison result is
1578 * returned to the caller.
1579 *
1580 * returns:
1581 *     1 if image uses requested compression
1582 *     0 otherwise (or on error)
1583 */
1584int fit_image_check_comp(const void *fit, int noffset, uint8_t comp)
1585{
1586        uint8_t image_comp;
1587
1588        if (fit_image_get_comp(fit, noffset, &image_comp))
1589                return 0;
1590        return (comp == image_comp);
1591}
1592
1593/**
1594 * fdt_check_no_at() - Check for nodes whose names contain '@'
1595 *
1596 * This checks the parent node and all subnodes recursively
1597 *
1598 * @fit: FIT to check
1599 * @parent: Parent node to check
1600 * Return: 0 if OK, -EADDRNOTAVAIL is a node has a name containing '@'
1601 */
1602static int fdt_check_no_at(const void *fit, int parent)
1603{
1604        const char *name;
1605        int node;
1606        int ret;
1607
1608        name = fdt_get_name(fit, parent, NULL);
1609        if (!name || strchr(name, '@'))
1610                return -EADDRNOTAVAIL;
1611
1612        fdt_for_each_subnode(node, fit, parent) {
1613                ret = fdt_check_no_at(fit, node);
1614                if (ret)
1615                        return ret;
1616        }
1617
1618        return 0;
1619}
1620
1621int fit_check_format(const void *fit, ulong size)
1622{
1623        int ret;
1624
1625        /* A FIT image must be a valid FDT */
1626        ret = fdt_check_header(fit);
1627        if (ret) {
1628                log_debug("Wrong FIT format: not a flattened device tree (err=%d)\n",
1629                          ret);
1630                return -ENOEXEC;
1631        }
1632
1633        if (CONFIG_IS_ENABLED(FIT_FULL_CHECK)) {
1634                /*
1635                 * If we are not given the size, make do wtih calculating it.
1636                 * This is not as secure, so we should consider a flag to
1637                 * control this.
1638                 */
1639                if (size == IMAGE_SIZE_INVAL)
1640                        size = fdt_totalsize(fit);
1641                ret = fdt_check_full(fit, size);
1642                if (ret)
1643                        ret = -EINVAL;
1644
1645                /*
1646                 * U-Boot stopped using unit addressed in 2017. Since libfdt
1647                 * can match nodes ignoring any unit address, signature
1648                 * verification can see the wrong node if one is inserted with
1649                 * the same name as a valid node but with a unit address
1650                 * attached. Protect against this by disallowing unit addresses.
1651                 */
1652                if (!ret && CONFIG_IS_ENABLED(FIT_SIGNATURE)) {
1653                        ret = fdt_check_no_at(fit, 0);
1654
1655                        if (ret) {
1656                                log_debug("FIT check error %d\n", ret);
1657                                return ret;
1658                        }
1659                }
1660                if (ret) {
1661                        log_debug("FIT check error %d\n", ret);
1662                        return ret;
1663                }
1664        }
1665
1666        /* mandatory / node 'description' property */
1667        if (!fdt_getprop(fit, 0, FIT_DESC_PROP, NULL)) {
1668                log_debug("Wrong FIT format: no description\n");
1669                return -ENOMSG;
1670        }
1671
1672        if (IMAGE_ENABLE_TIMESTAMP) {
1673                /* mandatory / node 'timestamp' property */
1674                if (!fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL)) {
1675                        log_debug("Wrong FIT format: no timestamp\n");
1676                        return -EBADMSG;
1677                }
1678        }
1679
1680        /* mandatory subimages parent '/images' node */
1681        if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) {
1682                log_debug("Wrong FIT format: no images parent node\n");
1683                return -ENOENT;
1684        }
1685
1686        return 0;
1687}
1688
1689/**
1690 * fit_conf_find_compat
1691 * @fit: pointer to the FIT format image header
1692 * @fdt: pointer to the device tree to compare against
1693 *
1694 * fit_conf_find_compat() attempts to find the configuration whose fdt is the
1695 * most compatible with the passed in device tree.
1696 *
1697 * Example:
1698 *
1699 * / o image-tree
1700 *   |-o images
1701 *   | |-o fdt-1
1702 *   | |-o fdt-2
1703 *   |
1704 *   |-o configurations
1705 *     |-o config-1
1706 *     | |-fdt = fdt-1
1707 *     |
1708 *     |-o config-2
1709 *       |-fdt = fdt-2
1710 *
1711 * / o U-Boot fdt
1712 *   |-compatible = "foo,bar", "bim,bam"
1713 *
1714 * / o kernel fdt1
1715 *   |-compatible = "foo,bar",
1716 *
1717 * / o kernel fdt2
1718 *   |-compatible = "bim,bam", "baz,biz"
1719 *
1720 * Configuration 1 would be picked because the first string in U-Boot's
1721 * compatible list, "foo,bar", matches a compatible string in the root of fdt1.
1722 * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1.
1723 *
1724 * As an optimization, the compatible property from the FDT's root node can be
1725 * copied into the configuration node in the FIT image. This is required to
1726 * match configurations with compressed FDTs.
1727 *
1728 * returns:
1729 *     offset to the configuration to use if one was found
1730 *     -1 otherwise
1731 */
1732int fit_conf_find_compat(const void *fit, const void *fdt)
1733{
1734        int ndepth = 0;
1735        int noffset, confs_noffset, images_noffset;
1736        const void *fdt_compat;
1737        int fdt_compat_len;
1738        int best_match_offset = 0;
1739        int best_match_pos = 0;
1740
1741        confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1742        images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH);
1743        if (confs_noffset < 0 || images_noffset < 0) {
1744                debug("Can't find configurations or images nodes.\n");
1745                return -1;
1746        }
1747
1748        fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len);
1749        if (!fdt_compat) {
1750                debug("Fdt for comparison has no \"compatible\" property.\n");
1751                return -1;
1752        }
1753
1754        /*
1755         * Loop over the configurations in the FIT image.
1756         */
1757        for (noffset = fdt_next_node(fit, confs_noffset, &ndepth);
1758                        (noffset >= 0) && (ndepth > 0);
1759                        noffset = fdt_next_node(fit, noffset, &ndepth)) {
1760                const void *fdt;
1761                const char *kfdt_name;
1762                int kfdt_noffset, compat_noffset;
1763                const char *cur_fdt_compat;
1764                int len;
1765                size_t sz;
1766                int i;
1767
1768                if (ndepth > 1)
1769                        continue;
1770
1771                /* If there's a compat property in the config node, use that. */
1772                if (fdt_getprop(fit, noffset, "compatible", NULL)) {
1773                        fdt = fit;                /* search in FIT image */
1774                        compat_noffset = noffset; /* search under config node */
1775                } else {        /* Otherwise extract it from the kernel FDT. */
1776                        kfdt_name = fdt_getprop(fit, noffset, "fdt", &len);
1777                        if (!kfdt_name) {
1778                                debug("No fdt property found.\n");
1779                                continue;
1780                        }
1781                        kfdt_noffset = fdt_subnode_offset(fit, images_noffset,
1782                                                          kfdt_name);
1783                        if (kfdt_noffset < 0) {
1784                                debug("No image node named \"%s\" found.\n",
1785                                      kfdt_name);
1786                                continue;
1787                        }
1788
1789                        if (!fit_image_check_comp(fit, kfdt_noffset,
1790                                                  IH_COMP_NONE)) {
1791                                debug("Can't extract compat from \"%s\" "
1792                                      "(compressed)\n", kfdt_name);
1793                                continue;
1794                        }
1795
1796                        /* search in this config's kernel FDT */
1797                        if (fit_image_get_data_and_size(fit, kfdt_noffset,
1798                                                        &fdt, &sz)) {
1799                                debug("Failed to get fdt \"%s\".\n", kfdt_name);
1800                                continue;
1801                        }
1802
1803                        compat_noffset = 0;  /* search kFDT under root node */
1804                }
1805
1806                len = fdt_compat_len;
1807                cur_fdt_compat = fdt_compat;
1808                /*
1809                 * Look for a match for each U-Boot compatibility string in
1810                 * turn in the compat string property.
1811                 */
1812                for (i = 0; len > 0 &&
1813                     (!best_match_offset || best_match_pos > i); i++) {
1814                        int cur_len = strlen(cur_fdt_compat) + 1;
1815
1816                        if (!fdt_node_check_compatible(fdt, compat_noffset,
1817                                                       cur_fdt_compat)) {
1818                                best_match_offset = noffset;
1819                                best_match_pos = i;
1820                                break;
1821                        }
1822                        len -= cur_len;
1823                        cur_fdt_compat += cur_len;
1824                }
1825        }
1826        if (!best_match_offset) {
1827                debug("No match found.\n");
1828                return -1;
1829        }
1830
1831        return best_match_offset;
1832}
1833
1834int fit_conf_get_node(const void *fit, const char *conf_uname)
1835{
1836        int noffset, confs_noffset;
1837        int len;
1838        const char *s;
1839        char *conf_uname_copy = NULL;
1840
1841        confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH);
1842        if (confs_noffset < 0) {
1843                debug("Can't find configurations parent node '%s' (%s)\n",
1844                      FIT_CONFS_PATH, fdt_strerror(confs_noffset));
1845                return confs_noffset;
1846        }
1847
1848        if (conf_uname == NULL) {
1849                /* get configuration unit name from the default property */
1850                debug("No configuration specified, trying default...\n");
1851                if (!tools_build() && IS_ENABLED(CONFIG_MULTI_DTB_FIT)) {
1852                        noffset = fit_find_config_node(fit);
1853                        if (noffset < 0)
1854                                return noffset;
1855                        conf_uname = fdt_get_name(fit, noffset, NULL);
1856                } else {
1857                        conf_uname = (char *)fdt_getprop(fit, confs_noffset,
1858                                                         FIT_DEFAULT_PROP, &len);
1859                        if (conf_uname == NULL) {
1860                                fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP,
1861                                              len);
1862                                return len;
1863                        }
1864                }
1865                debug("Found default configuration: '%s'\n", conf_uname);
1866        }
1867
1868        s = strchr(conf_uname, '#');
1869        if (s) {
1870                len = s - conf_uname;
1871                conf_uname_copy = malloc(len + 1);
1872                if (!conf_uname_copy) {
1873                        debug("Can't allocate uname copy: '%s'\n",
1874                                        conf_uname);
1875                        return -ENOMEM;
1876                }
1877                memcpy(conf_uname_copy, conf_uname, len);
1878                conf_uname_copy[len] = '\0';
1879                conf_uname = conf_uname_copy;
1880        }
1881
1882        noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname);
1883        if (noffset < 0) {
1884                debug("Can't get node offset for configuration unit name: '%s' (%s)\n",
1885                      conf_uname, fdt_strerror(noffset));
1886        }
1887
1888        if (conf_uname_copy)
1889                free(conf_uname_copy);
1890
1891        return noffset;
1892}
1893
1894int fit_conf_get_prop_node_count(const void *fit, int noffset,
1895                const char *prop_name)
1896{
1897        return fdt_stringlist_count(fit, noffset, prop_name);
1898}
1899
1900int fit_conf_get_prop_node_index(const void *fit, int noffset,
1901                const char *prop_name, int index)
1902{
1903        const char *uname;
1904        int len;
1905
1906        /* get kernel image unit name from configuration kernel property */
1907        uname = fdt_stringlist_get(fit, noffset, prop_name, index, &len);
1908        if (uname == NULL)
1909                return len;
1910
1911        return fit_image_get_node(fit, uname);
1912}
1913
1914int fit_conf_get_prop_node(const void *fit, int noffset,
1915                const char *prop_name)
1916{
1917        return fit_conf_get_prop_node_index(fit, noffset, prop_name, 0);
1918}
1919
1920static int fit_image_select(const void *fit, int rd_noffset, int verify)
1921{
1922        fit_image_print(fit, rd_noffset, "   ");
1923
1924        if (verify) {
1925                puts("   Verifying Hash Integrity ... ");
1926                if (!fit_image_verify(fit, rd_noffset)) {
1927                        puts("Bad Data Hash\n");
1928                        return -EACCES;
1929                }
1930                puts("OK\n");
1931        }
1932
1933        return 0;
1934}
1935
1936int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name,
1937                        ulong addr)
1938{
1939        int cfg_noffset;
1940        void *fit_hdr;
1941        int noffset;
1942
1943        debug("*  %s: using config '%s' from image at 0x%08lx\n",
1944              prop_name, images->fit_uname_cfg, addr);
1945
1946        /* Check whether configuration has this property defined */
1947        fit_hdr = map_sysmem(addr, 0);
1948        cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg);
1949        if (cfg_noffset < 0) {
1950                debug("*  %s: no such config\n", prop_name);
1951                return -EINVAL;
1952        }
1953
1954        noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name);
1955        if (noffset < 0) {
1956                debug("*  %s: no '%s' in config\n", prop_name, prop_name);
1957                return -ENOENT;
1958        }
1959
1960        return noffset;
1961}
1962
1963/**
1964 * fit_get_image_type_property() - get property name for IH_TYPE_...
1965 *
1966 * Return: the properly name where we expect to find the image in the
1967 * config node
1968 */
1969static const char *fit_get_image_type_property(int type)
1970{
1971        /*
1972         * This is sort-of available in the uimage_type[] table in image.c
1973         * but we don't have access to the short name, and "fdt" is different
1974         * anyway. So let's just keep it here.
1975         */
1976        switch (type) {
1977        case IH_TYPE_FLATDT:
1978                return FIT_FDT_PROP;
1979        case IH_TYPE_KERNEL:
1980                return FIT_KERNEL_PROP;
1981        case IH_TYPE_FIRMWARE:
1982                return FIT_FIRMWARE_PROP;
1983        case IH_TYPE_RAMDISK:
1984                return FIT_RAMDISK_PROP;
1985        case IH_TYPE_X86_SETUP:
1986                return FIT_SETUP_PROP;
1987        case IH_TYPE_LOADABLE:
1988                return FIT_LOADABLE_PROP;
1989        case IH_TYPE_FPGA:
1990                return FIT_FPGA_PROP;
1991        case IH_TYPE_STANDALONE:
1992                return FIT_STANDALONE_PROP;
1993        }
1994
1995        return "unknown";
1996}
1997
1998int fit_image_load(bootm_headers_t *images, ulong addr,
1999                   const char **fit_unamep, const char **fit_uname_configp,
2000                   int arch, int image_type, int bootstage_id,
2001                   enum fit_load_op load_op, ulong *datap, ulong *lenp)
2002{
2003        int cfg_noffset, noffset;
2004        const char *fit_uname;
2005        const char *fit_uname_config;
2006        const char *fit_base_uname_config;
2007        const void *fit;
2008        void *buf;
2009        void *loadbuf;
2010        size_t size;
2011        int type_ok, os_ok;
2012        ulong load, load_end, data, len;
2013        uint8_t os, comp;
2014        const char *prop_name;
2015        int ret;
2016
2017        fit = map_sysmem(addr, 0);
2018        fit_uname = fit_unamep ? *fit_unamep : NULL;
2019        fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
2020        fit_base_uname_config = NULL;
2021        prop_name = fit_get_image_type_property(image_type);
2022        printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);
2023
2024        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
2025        ret = fit_check_format(fit, IMAGE_SIZE_INVAL);
2026        if (ret) {
2027                printf("Bad FIT %s image format! (err=%d)\n", prop_name, ret);
2028                if (CONFIG_IS_ENABLED(FIT_SIGNATURE) && ret == -EADDRNOTAVAIL)
2029                        printf("Signature checking prevents use of unit addresses (@) in nodes\n");
2030                bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
2031                return ret;
2032        }
2033        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
2034        if (fit_uname) {
2035                /* get FIT component image node offset */
2036                bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
2037                noffset = fit_image_get_node(fit, fit_uname);
2038        } else {
2039                /*
2040                 * no image node unit name, try to get config
2041                 * node first. If config unit node name is NULL
2042                 * fit_conf_get_node() will try to find default config node
2043                 */
2044                bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
2045                if (IS_ENABLED(CONFIG_FIT_BEST_MATCH) && !fit_uname_config) {
2046                        cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
2047                } else {
2048                        cfg_noffset = fit_conf_get_node(fit,
2049                                                        fit_uname_config);
2050                }
2051                if (cfg_noffset < 0) {
2052                        puts("Could not find configuration node\n");
2053                        bootstage_error(bootstage_id +
2054                                        BOOTSTAGE_SUB_NO_UNIT_NAME);
2055                        return -ENOENT;
2056                }
2057
2058                fit_base_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
2059                printf("   Using '%s' configuration\n", fit_base_uname_config);
2060                /* Remember this config */
2061                if (image_type == IH_TYPE_KERNEL)
2062                        images->fit_uname_cfg = fit_base_uname_config;
2063
2064                if (FIT_IMAGE_ENABLE_VERIFY && images->verify) {
2065                        puts("   Verifying Hash Integrity ... ");
2066                        if (fit_config_verify(fit, cfg_noffset)) {
2067                                puts("Bad Data Hash\n");
2068                                bootstage_error(bootstage_id +
2069                                        BOOTSTAGE_SUB_HASH);
2070                                return -EACCES;
2071                        }
2072                        puts("OK\n");
2073                }
2074
2075                bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
2076
2077                noffset = fit_conf_get_prop_node(fit, cfg_noffset,
2078                                                 prop_name);
2079                fit_uname = fit_get_name(fit, noffset, NULL);
2080        }
2081        if (noffset < 0) {
2082                printf("Could not find subimage node type '%s'\n", prop_name);
2083                bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
2084                return -ENOENT;
2085        }
2086
2087        printf("   Trying '%s' %s subimage\n", fit_uname, prop_name);
2088
2089        ret = fit_image_select(fit, noffset, images->verify);
2090        if (ret) {
2091                bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
2092                return ret;
2093        }
2094
2095        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
2096        if (!tools_build() && IS_ENABLED(CONFIG_SANDBOX)) {
2097                if (!fit_image_check_target_arch(fit, noffset)) {
2098                        puts("Unsupported Architecture\n");
2099                        bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
2100                        return -ENOEXEC;
2101                }
2102        }
2103
2104#ifndef USE_HOSTCC
2105        {
2106        uint8_t os_arch;
2107
2108        fit_image_get_arch(fit, noffset, &os_arch);
2109        images->os.arch = os_arch;
2110        }
2111#endif
2112
2113        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
2114        type_ok = fit_image_check_type(fit, noffset, image_type) ||
2115                  fit_image_check_type(fit, noffset, IH_TYPE_FIRMWARE) ||
2116                  fit_image_check_type(fit, noffset, IH_TYPE_TEE) ||
2117                  (image_type == IH_TYPE_KERNEL &&
2118                   fit_image_check_type(fit, noffset, IH_TYPE_KERNEL_NOLOAD));
2119
2120        os_ok = image_type == IH_TYPE_FLATDT ||
2121                image_type == IH_TYPE_FPGA ||
2122                fit_image_check_os(fit, noffset, IH_OS_LINUX) ||
2123                fit_image_check_os(fit, noffset, IH_OS_U_BOOT) ||
2124                fit_image_check_os(fit, noffset, IH_OS_TEE) ||
2125                fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) ||
2126                fit_image_check_os(fit, noffset, IH_OS_EFI) ||
2127                fit_image_check_os(fit, noffset, IH_OS_VXWORKS);
2128
2129        /*
2130         * If either of the checks fail, we should report an error, but
2131         * if the image type is coming from the "loadables" field, we
2132         * don't care what it is
2133         */
2134        if ((!type_ok || !os_ok) && image_type != IH_TYPE_LOADABLE) {
2135                fit_image_get_os(fit, noffset, &os);
2136                printf("No %s %s %s Image\n",
2137                       genimg_get_os_name(os),
2138                       genimg_get_arch_name(arch),
2139                       genimg_get_type_name(image_type));
2140                bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
2141                return -EIO;
2142        }
2143
2144        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);
2145
2146        /* get image data address and length */
2147        if (fit_image_get_data_and_size(fit, noffset,
2148                                        (const void **)&buf, &size)) {
2149                printf("Could not find %s subimage data!\n", prop_name);
2150                bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
2151                return -ENOENT;
2152        }
2153
2154        /* Decrypt data before uncompress/move */
2155        if (IS_ENABLED(CONFIG_FIT_CIPHER) && IMAGE_ENABLE_DECRYPT) {
2156                puts("   Decrypting Data ... ");
2157                if (fit_image_uncipher(fit, noffset, &buf, &size)) {
2158                        puts("Error\n");
2159                        return -EACCES;
2160                }
2161                puts("OK\n");
2162        }
2163
2164        /* perform any post-processing on the image data */
2165        if (!tools_build() && IS_ENABLED(CONFIG_FIT_IMAGE_POST_PROCESS))
2166                board_fit_image_post_process(fit, noffset, &buf, &size);
2167
2168        len = (ulong)size;
2169
2170        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);
2171
2172        data = map_to_sysmem(buf);
2173        load = data;
2174        if (load_op == FIT_LOAD_IGNORED) {
2175                /* Don't load */
2176        } else if (fit_image_get_load(fit, noffset, &load)) {
2177                if (load_op == FIT_LOAD_REQUIRED) {
2178                        printf("Can't get %s subimage load address!\n",
2179                               prop_name);
2180                        bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
2181                        return -EBADF;
2182                }
2183        } else if (load_op != FIT_LOAD_OPTIONAL_NON_ZERO || load) {
2184                ulong image_start, image_end;
2185
2186                /*
2187                 * move image data to the load address,
2188                 * make sure we don't overwrite initial image
2189                 */
2190                image_start = addr;
2191                image_end = addr + fit_get_size(fit);
2192
2193                load_end = load + len;
2194                if (image_type != IH_TYPE_KERNEL &&
2195                    load < image_end && load_end > image_start) {
2196                        printf("Error: %s overwritten\n", prop_name);
2197                        return -EXDEV;
2198                }
2199
2200                printf("   Loading %s from 0x%08lx to 0x%08lx\n",
2201                       prop_name, data, load);
2202        } else {
2203                load = data;    /* No load address specified */
2204        }
2205
2206        comp = IH_COMP_NONE;
2207        loadbuf = buf;
2208        /* Kernel images get decompressed later in bootm_load_os(). */
2209        if (!fit_image_get_comp(fit, noffset, &comp) &&
2210            comp != IH_COMP_NONE &&
2211            !(image_type == IH_TYPE_KERNEL ||
2212              image_type == IH_TYPE_KERNEL_NOLOAD ||
2213              image_type == IH_TYPE_RAMDISK)) {
2214                ulong max_decomp_len = len * 20;
2215                if (load == data) {
2216                        loadbuf = malloc(max_decomp_len);
2217                        load = map_to_sysmem(loadbuf);
2218                } else {
2219                        loadbuf = map_sysmem(load, max_decomp_len);
2220                }
2221                if (image_decomp(comp, load, data, image_type,
2222                                loadbuf, buf, len, max_decomp_len, &load_end)) {
2223                        printf("Error decompressing %s\n", prop_name);
2224
2225                        return -ENOEXEC;
2226                }
2227                len = load_end - load;
2228        } else if (load != data) {
2229                loadbuf = map_sysmem(load, len);
2230                memcpy(loadbuf, buf, len);
2231        }
2232
2233        if (image_type == IH_TYPE_RAMDISK && comp != IH_COMP_NONE)
2234                puts("WARNING: 'compression' nodes for ramdisks are deprecated,"
2235                     " please fix your .its file!\n");
2236
2237        /* verify that image data is a proper FDT blob */
2238        if (image_type == IH_TYPE_FLATDT && fdt_check_header(loadbuf)) {
2239                puts("Subimage data is not a FDT");
2240                return -ENOEXEC;
2241        }
2242
2243        bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);
2244
2245        *datap = load;
2246        *lenp = len;
2247        if (fit_unamep)
2248                *fit_unamep = (char *)fit_uname;
2249        if (fit_uname_configp)
2250                *fit_uname_configp = (char *)(fit_uname_config ? :
2251                                              fit_base_uname_config);
2252
2253        return noffset;
2254}
2255
2256int boot_get_setup_fit(bootm_headers_t *images, uint8_t arch,
2257                        ulong *setup_start, ulong *setup_len)
2258{
2259        int noffset;
2260        ulong addr;
2261        ulong len;
2262        int ret;
2263
2264        addr = map_to_sysmem(images->fit_hdr_os);
2265        noffset = fit_get_node_from_config(images, FIT_SETUP_PROP, addr);
2266        if (noffset < 0)
2267                return noffset;
2268
2269        ret = fit_image_load(images, addr, NULL, NULL, arch,
2270                             IH_TYPE_X86_SETUP, BOOTSTAGE_ID_FIT_SETUP_START,
2271                             FIT_LOAD_REQUIRED, setup_start, &len);
2272
2273        return ret;
2274}
2275
2276#ifndef USE_HOSTCC
2277int boot_get_fdt_fit(bootm_headers_t *images, ulong addr,
2278                   const char **fit_unamep, const char **fit_uname_configp,
2279                   int arch, ulong *datap, ulong *lenp)
2280{
2281        int fdt_noffset, cfg_noffset, count;
2282        const void *fit;
2283        const char *fit_uname = NULL;
2284        const char *fit_uname_config = NULL;
2285        char *fit_uname_config_copy = NULL;
2286        char *next_config = NULL;
2287        ulong load, len;
2288#ifdef CONFIG_OF_LIBFDT_OVERLAY
2289        ulong image_start, image_end;
2290        ulong ovload, ovlen, ovcopylen;
2291        const char *uconfig;
2292        const char *uname;
2293        void *base, *ov, *ovcopy = NULL;
2294        int i, err, noffset, ov_noffset;
2295#endif
2296
2297        fit_uname = fit_unamep ? *fit_unamep : NULL;
2298
2299        if (fit_uname_configp && *fit_uname_configp) {
2300                fit_uname_config_copy = strdup(*fit_uname_configp);
2301                if (!fit_uname_config_copy)
2302                        return -ENOMEM;
2303
2304                next_config = strchr(fit_uname_config_copy, '#');
2305                if (next_config)
2306                        *next_config++ = '\0';
2307                if (next_config - 1 > fit_uname_config_copy)
2308                        fit_uname_config = fit_uname_config_copy;
2309        }
2310
2311        fdt_noffset = fit_image_load(images,
2312                addr, &fit_uname, &fit_uname_config,
2313                arch, IH_TYPE_FLATDT,
2314                BOOTSTAGE_ID_FIT_FDT_START,
2315                FIT_LOAD_OPTIONAL, &load, &len);
2316
2317        if (fdt_noffset < 0)
2318                goto out;
2319
2320        debug("fit_uname=%s, fit_uname_config=%s\n",
2321                        fit_uname ? fit_uname : "<NULL>",
2322                        fit_uname_config ? fit_uname_config : "<NULL>");
2323
2324        fit = map_sysmem(addr, 0);
2325
2326        cfg_noffset = fit_conf_get_node(fit, fit_uname_config);
2327
2328        /* single blob, or error just return as well */
2329        count = fit_conf_get_prop_node_count(fit, cfg_noffset, FIT_FDT_PROP);
2330        if (count <= 1 && !next_config)
2331                goto out;
2332
2333        /* we need to apply overlays */
2334
2335#ifdef CONFIG_OF_LIBFDT_OVERLAY
2336        image_start = addr;
2337        image_end = addr + fit_get_size(fit);
2338        /* verify that relocation took place by load address not being in fit */
2339        if (load >= image_start && load < image_end) {
2340                /* check is simplified; fit load checks for overlaps */
2341                printf("Overlayed FDT requires relocation\n");
2342                fdt_noffset = -EBADF;
2343                goto out;
2344        }
2345
2346        base = map_sysmem(load, len);
2347
2348        /* apply extra configs in FIT first, followed by args */
2349        for (i = 1; ; i++) {
2350                if (i < count) {
2351                        noffset = fit_conf_get_prop_node_index(fit, cfg_noffset,
2352                                                               FIT_FDT_PROP, i);
2353                        uname = fit_get_name(fit, noffset, NULL);
2354                        uconfig = NULL;
2355                } else {
2356                        if (!next_config)
2357                                break;
2358                        uconfig = next_config;
2359                        next_config = strchr(next_config, '#');
2360                        if (next_config)
2361                                *next_config++ = '\0';
2362                        uname = NULL;
2363
2364                        /*
2365                         * fit_image_load() would load the first FDT from the
2366                         * extra config only when uconfig is specified.
2367                         * Check if the extra config contains multiple FDTs and
2368                         * if so, load them.
2369                         */
2370                        cfg_noffset = fit_conf_get_node(fit, uconfig);
2371
2372                        i = 0;
2373                        count = fit_conf_get_prop_node_count(fit, cfg_noffset,
2374                                                             FIT_FDT_PROP);
2375                }
2376
2377                debug("%d: using uname=%s uconfig=%s\n", i, uname, uconfig);
2378
2379                ov_noffset = fit_image_load(images,
2380                        addr, &uname, &uconfig,
2381                        arch, IH_TYPE_FLATDT,
2382                        BOOTSTAGE_ID_FIT_FDT_START,
2383                        FIT_LOAD_IGNORED, &ovload, &ovlen);
2384                if (ov_noffset < 0) {
2385                        printf("load of %s failed\n", uname);
2386                        continue;
2387                }
2388                debug("%s loaded at 0x%08lx len=0x%08lx\n",
2389                                uname, ovload, ovlen);
2390                ov = map_sysmem(ovload, ovlen);
2391
2392                ovcopylen = ALIGN(fdt_totalsize(ov), SZ_4K);
2393                ovcopy = malloc(ovcopylen);
2394                if (!ovcopy) {
2395                        printf("failed to duplicate DTO before application\n");
2396                        fdt_noffset = -ENOMEM;
2397                        goto out;
2398                }
2399
2400                err = fdt_open_into(ov, ovcopy, ovcopylen);
2401                if (err < 0) {
2402                        printf("failed on fdt_open_into for DTO\n");
2403                        fdt_noffset = err;
2404                        goto out;
2405                }
2406
2407                base = map_sysmem(load, len + ovlen);
2408                err = fdt_open_into(base, base, len + ovlen);
2409                if (err < 0) {
2410                        printf("failed on fdt_open_into\n");
2411                        fdt_noffset = err;
2412                        goto out;
2413                }
2414
2415                /* the verbose method prints out messages on error */
2416                err = fdt_overlay_apply_verbose(base, ovcopy);
2417                if (err < 0) {
2418                        fdt_noffset = err;
2419                        goto out;
2420                }
2421                fdt_pack(base);
2422                len = fdt_totalsize(base);
2423
2424                free(ovcopy);
2425                ovcopy = NULL;
2426        }
2427#else
2428        printf("config with overlays but CONFIG_OF_LIBFDT_OVERLAY not set\n");
2429        fdt_noffset = -EBADF;
2430#endif
2431
2432out:
2433        if (datap)
2434                *datap = load;
2435        if (lenp)
2436                *lenp = len;
2437        if (fit_unamep)
2438                *fit_unamep = fit_uname;
2439        if (fit_uname_configp)
2440                *fit_uname_configp = fit_uname_config;
2441
2442#ifdef CONFIG_OF_LIBFDT_OVERLAY
2443        if (ovcopy)
2444                free(ovcopy);
2445#endif
2446        if (fit_uname_config_copy)
2447                free(fit_uname_config_copy);
2448        return fdt_noffset;
2449}
2450#endif
2451