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