uboot/board/freescale/common/fsl_validate.c
<<
>>
Prefs
   1/*
   2 * Copyright 2015 Freescale Semiconductor, Inc.
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <fsl_validate.h>
   9#include <fsl_secboot_err.h>
  10#include <fsl_sfp.h>
  11#include <fsl_sec.h>
  12#include <command.h>
  13#include <malloc.h>
  14#include <dm/uclass.h>
  15#include <u-boot/rsa-mod-exp.h>
  16#include <hash.h>
  17#include <fsl_secboot_err.h>
  18#ifdef CONFIG_LS102XA
  19#include <asm/arch/immap_ls102xa.h>
  20#endif
  21
  22#define SHA256_BITS     256
  23#define SHA256_BYTES    (256/8)
  24#define SHA256_NIBBLES  (256/4)
  25#define NUM_HEX_CHARS   (sizeof(ulong) * 2)
  26
  27#define CHECK_KEY_LEN(key_len)  (((key_len) == 2 * KEY_SIZE_BYTES / 4) || \
  28                                 ((key_len) == 2 * KEY_SIZE_BYTES / 2) || \
  29                                 ((key_len) == 2 * KEY_SIZE_BYTES))
  30
  31/* This array contains DER value for SHA-256 */
  32static const u8 hash_identifier[] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60,
  33                0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
  34                0x04, 0x20
  35                };
  36
  37static u8 hash_val[SHA256_BYTES];
  38
  39#ifdef CONFIG_ESBC_HDR_LS
  40/* New Barker Code for LS ESBC Header */
  41static const u8 barker_code[ESBC_BARKER_LEN] = { 0x12, 0x19, 0x20, 0x01 };
  42#else
  43static const u8 barker_code[ESBC_BARKER_LEN] = { 0x68, 0x39, 0x27, 0x81 };
  44#endif
  45
  46void branch_to_self(void) __attribute__ ((noreturn));
  47
  48/*
  49 * This function will put core in infinite loop.
  50 * This will be called when the ESBC can not proceed further due
  51 * to some unknown errors.
  52 */
  53void branch_to_self(void)
  54{
  55        printf("Core is in infinite loop due to errors.\n");
  56self:
  57        goto self;
  58}
  59
  60#if defined(CONFIG_FSL_ISBC_KEY_EXT)
  61static u32 check_ie(struct fsl_secboot_img_priv *img)
  62{
  63        if (img->hdr.ie_flag)
  64                return 1;
  65
  66        return 0;
  67}
  68
  69/* This function returns the CSF Header Address of uboot
  70 * For MPC85xx based platforms, the LAW mapping for NOR
  71 * flash changes in uboot code. Hence the offset needs
  72 * to be calculated and added to the new NOR flash base
  73 * address
  74 */
  75#if defined(CONFIG_MPC85xx)
  76int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
  77{
  78        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
  79        u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
  80        u32 csf_flash_offset = csf_hdr_addr & ~(CONFIG_SYS_PBI_FLASH_BASE);
  81        u32 flash_addr, addr;
  82        int found = 0;
  83        int i = 0;
  84
  85        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
  86                flash_addr = flash_info[i].start[0];
  87                addr = flash_info[i].start[0] + csf_flash_offset;
  88                if (memcmp((u8 *)addr, barker_code, ESBC_BARKER_LEN) == 0) {
  89                        debug("Barker found on addr %x\n", addr);
  90                        found = 1;
  91                        break;
  92                }
  93        }
  94
  95        if (!found)
  96                return -1;
  97
  98        *csf_addr = addr;
  99        *flash_base_addr = flash_addr;
 100
 101        return 0;
 102}
 103#else
 104/* For platforms like LS1020, correct flash address is present in
 105 * the header. So the function reqturns flash base address as 0
 106 */
 107int get_csf_base_addr(u32 *csf_addr, u32 *flash_base_addr)
 108{
 109        struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
 110        u32 csf_hdr_addr = in_be32(&gur->scratchrw[0]);
 111
 112        if (memcmp((u8 *)(uintptr_t)csf_hdr_addr,
 113                   barker_code, ESBC_BARKER_LEN))
 114                return -1;
 115
 116        *csf_addr = csf_hdr_addr;
 117        *flash_base_addr = 0;
 118        return 0;
 119}
 120#endif
 121
 122static int get_ie_info_addr(u32 *ie_addr)
 123{
 124        struct fsl_secboot_img_hdr *hdr;
 125        struct fsl_secboot_sg_table *sg_tbl;
 126        u32 flash_base_addr, csf_addr;
 127
 128        if (get_csf_base_addr(&csf_addr, &flash_base_addr))
 129                return -1;
 130
 131        hdr = (struct fsl_secboot_img_hdr *)(uintptr_t)csf_addr;
 132
 133        /* For SoC's with Trust Architecture v1 with corenet bus
 134         * the sg table field in CSF header has absolute address
 135         * for sg table in memory. In other Trust Architecture,
 136         * this field specifies the offset of sg table from the
 137         * base address of CSF Header
 138         */
 139#if defined(CONFIG_FSL_TRUST_ARCH_v1) && defined(CONFIG_FSL_CORENET)
 140        sg_tbl = (struct fsl_secboot_sg_table *)
 141                 (((u32)hdr->psgtable & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
 142                  flash_base_addr);
 143#else
 144        sg_tbl = (struct fsl_secboot_sg_table *)(uintptr_t)(csf_addr +
 145                                                 (u32)hdr->psgtable);
 146#endif
 147
 148        /* IE Key Table is the first entry in the SG Table */
 149#if defined(CONFIG_MPC85xx)
 150        *ie_addr = (sg_tbl->src_addr & ~(CONFIG_SYS_PBI_FLASH_BASE)) +
 151                   flash_base_addr;
 152#else
 153        *ie_addr = sg_tbl->src_addr;
 154#endif
 155
 156        debug("IE Table address is %x\n", *ie_addr);
 157        return 0;
 158}
 159
 160#endif
 161
 162#ifdef CONFIG_KEY_REVOCATION
 163/* This function checks srk_table_flag in header and set/reset srk_flag.*/
 164static u32 check_srk(struct fsl_secboot_img_priv *img)
 165{
 166#ifdef CONFIG_ESBC_HDR_LS
 167        /* In LS, No SRK Flag as SRK is always present*/
 168        return 1;
 169#else
 170        if (img->hdr.len_kr.srk_table_flag & SRK_FLAG)
 171                return 1;
 172
 173        return 0;
 174#endif
 175}
 176
 177/* This function returns ospr's key_revoc values.*/
 178static u32 get_key_revoc(void)
 179{
 180        struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
 181        return (sfp_in32(&sfp_regs->ospr) & OSPR_KEY_REVOC_MASK) >>
 182                OSPR_KEY_REVOC_SHIFT;
 183}
 184
 185/* This function checks if selected key is revoked or not.*/
 186static u32 is_key_revoked(u32 keynum, u32 rev_flag)
 187{
 188        if (keynum == UNREVOCABLE_KEY)
 189                return 0;
 190
 191        if ((u32)(1 << (ALIGN_REVOC_KEY - keynum)) & rev_flag)
 192                return 1;
 193
 194        return 0;
 195}
 196
 197/* It read validates srk_table key lengths.*/
 198static u32 read_validate_srk_tbl(struct fsl_secboot_img_priv *img)
 199{
 200        int i = 0;
 201        u32 ret, key_num, key_revoc_flag, size;
 202        struct fsl_secboot_img_hdr *hdr = &img->hdr;
 203        void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
 204
 205        if ((hdr->len_kr.num_srk == 0) ||
 206            (hdr->len_kr.num_srk > MAX_KEY_ENTRIES))
 207                return ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY;
 208
 209        key_num = hdr->len_kr.srk_sel;
 210        if (key_num == 0 || key_num > hdr->len_kr.num_srk)
 211                return ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM;
 212
 213        /* Get revoc key from sfp */
 214        key_revoc_flag = get_key_revoc();
 215        ret = is_key_revoked(key_num, key_revoc_flag);
 216        if (ret)
 217                return ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED;
 218
 219        size = hdr->len_kr.num_srk * sizeof(struct srk_table);
 220
 221        memcpy(&img->srk_tbl, esbc + hdr->srk_tbl_off, size);
 222
 223        for (i = 0; i < hdr->len_kr.num_srk; i++) {
 224                if (!CHECK_KEY_LEN(img->srk_tbl[i].key_len))
 225                        return ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN;
 226        }
 227
 228        img->key_len = img->srk_tbl[key_num - 1].key_len;
 229
 230        memcpy(&img->img_key, &(img->srk_tbl[key_num - 1].pkey),
 231               img->key_len);
 232
 233        return 0;
 234}
 235#endif
 236
 237#ifndef CONFIG_ESBC_HDR_LS
 238static u32 read_validate_single_key(struct fsl_secboot_img_priv *img)
 239{
 240        struct fsl_secboot_img_hdr *hdr = &img->hdr;
 241        void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
 242
 243        /* check key length */
 244        if (!CHECK_KEY_LEN(hdr->key_len))
 245                return ERROR_ESBC_CLIENT_HEADER_KEY_LEN;
 246
 247        memcpy(&img->img_key, esbc + hdr->pkey, hdr->key_len);
 248
 249        img->key_len = hdr->key_len;
 250
 251        return 0;
 252}
 253#endif /* CONFIG_ESBC_HDR_LS */
 254
 255#if defined(CONFIG_FSL_ISBC_KEY_EXT)
 256static u32 read_validate_ie_tbl(struct fsl_secboot_img_priv *img)
 257{
 258        struct fsl_secboot_img_hdr *hdr = &img->hdr;
 259        u32 ie_key_len, ie_revoc_flag, ie_num;
 260        struct ie_key_info *ie_info;
 261
 262        if (get_ie_info_addr(&img->ie_addr))
 263                return ERROR_IE_TABLE_NOT_FOUND;
 264        ie_info = (struct ie_key_info *)(uintptr_t)img->ie_addr;
 265        if (ie_info->num_keys == 0 || ie_info->num_keys > 32)
 266                return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY;
 267
 268        ie_num = hdr->ie_key_sel;
 269        if (ie_num == 0 || ie_num > ie_info->num_keys)
 270                return ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM;
 271
 272        ie_revoc_flag = ie_info->key_revok;
 273        if ((u32)(1 << (ie_num - 1)) & ie_revoc_flag)
 274                return ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED;
 275
 276        ie_key_len = ie_info->ie_key_tbl[ie_num - 1].key_len;
 277
 278        if (!CHECK_KEY_LEN(ie_key_len))
 279                return ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN;
 280
 281        memcpy(&img->img_key, &(ie_info->ie_key_tbl[ie_num - 1].pkey),
 282               ie_key_len);
 283
 284        img->key_len = ie_key_len;
 285        return 0;
 286}
 287#endif
 288
 289
 290/* This function return length of public key.*/
 291static inline u32 get_key_len(struct fsl_secboot_img_priv *img)
 292{
 293        return img->key_len;
 294}
 295
 296/*
 297 * Handles the ESBC uboot client header verification failure.
 298 * This  function  handles all the errors which might occur in the
 299 * parsing and checking of ESBC uboot client header. It will also
 300 * set the error bits in the SEC_MON.
 301 */
 302static void fsl_secboot_header_verification_failure(void)
 303{
 304        struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
 305
 306        /* 29th bit of OSPR is ITS */
 307        u32 its = sfp_in32(&sfp_regs->ospr) >> 2;
 308
 309        if (its == 1)
 310                set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL);
 311        else
 312                set_sec_mon_state(HPSR_SSM_ST_NON_SECURE);
 313
 314        printf("Generating reset request\n");
 315        do_reset(NULL, 0, 0, NULL);
 316        /* If reset doesn't coocur, halt execution */
 317        do_esbc_halt(NULL, 0, 0, NULL);
 318}
 319
 320/*
 321 * Handles the ESBC uboot client image verification failure.
 322 * This  function  handles all the errors which might occur in the
 323 * public key hash comparison and signature verification of
 324 * ESBC uboot client image. It will also
 325 * set the error bits in the SEC_MON.
 326 */
 327static void fsl_secboot_image_verification_failure(void)
 328{
 329        struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
 330
 331        u32 its = (sfp_in32(&sfp_regs->ospr) & ITS_MASK) >> ITS_BIT;
 332
 333        if (its == 1) {
 334                set_sec_mon_state(HPSR_SSM_ST_SOFT_FAIL);
 335
 336                printf("Generating reset request\n");
 337                do_reset(NULL, 0, 0, NULL);
 338                /* If reset doesn't coocur, halt execution */
 339                do_esbc_halt(NULL, 0, 0, NULL);
 340
 341        } else {
 342                set_sec_mon_state(HPSR_SSM_ST_NON_SECURE);
 343        }
 344}
 345
 346static void fsl_secboot_bootscript_parse_failure(void)
 347{
 348        fsl_secboot_header_verification_failure();
 349}
 350
 351/*
 352 * Handles the errors in esbc boot.
 353 * This  function  handles all the errors which might occur in the
 354 * esbc boot phase. It will call the appropriate api to log the
 355 * errors and set the error bits in the SEC_MON.
 356 */
 357void fsl_secboot_handle_error(int error)
 358{
 359        const struct fsl_secboot_errcode *e;
 360
 361        for (e = fsl_secboot_errcodes; e->errcode != ERROR_ESBC_CLIENT_MAX;
 362                e++) {
 363                if (e->errcode == error)
 364                        printf("ERROR :: %x :: %s\n", error, e->name);
 365        }
 366
 367        /* If Boot Mode is secure, transition the SNVS state and issue
 368         * reset based on type of failure and ITS setting.
 369         * If Boot mode is non-secure, return from this function.
 370         */
 371        if (fsl_check_boot_mode_secure() == 0)
 372                return;
 373
 374        switch (error) {
 375        case ERROR_ESBC_CLIENT_HEADER_BARKER:
 376        case ERROR_ESBC_CLIENT_HEADER_IMG_SIZE:
 377        case ERROR_ESBC_CLIENT_HEADER_KEY_LEN:
 378        case ERROR_ESBC_CLIENT_HEADER_SIG_LEN:
 379        case ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN:
 380        case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1:
 381        case ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2:
 382        case ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD:
 383        case ERROR_ESBC_CLIENT_HEADER_SG_ESBC_EP:
 384        case ERROR_ESBC_CLIENT_HEADER_SG_ENTIRES_BAD:
 385        case ERROR_KEY_TABLE_NOT_FOUND:
 386#ifdef CONFIG_KEY_REVOCATION
 387        case ERROR_ESBC_CLIENT_HEADER_KEY_REVOKED:
 388        case ERROR_ESBC_CLIENT_HEADER_INVALID_SRK_NUM_ENTRY:
 389        case ERROR_ESBC_CLIENT_HEADER_INVALID_KEY_NUM:
 390        case ERROR_ESBC_CLIENT_HEADER_INV_SRK_ENTRY_KEYLEN:
 391#endif
 392#if defined(CONFIG_FSL_ISBC_KEY_EXT)
 393        /*@fallthrough@*/
 394        case ERROR_ESBC_CLIENT_HEADER_IE_KEY_REVOKED:
 395        case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_NUM_ENTRY:
 396        case ERROR_ESBC_CLIENT_HEADER_INVALID_IE_KEY_NUM:
 397        case ERROR_ESBC_CLIENT_HEADER_INV_IE_ENTRY_KEYLEN:
 398        case ERROR_IE_TABLE_NOT_FOUND:
 399#endif
 400                fsl_secboot_header_verification_failure();
 401                break;
 402        case ERROR_ESBC_SEC_RESET:
 403        case ERROR_ESBC_SEC_DEQ:
 404        case ERROR_ESBC_SEC_ENQ:
 405        case ERROR_ESBC_SEC_DEQ_TO:
 406        case ERROR_ESBC_SEC_JOBQ_STATUS:
 407        case ERROR_ESBC_CLIENT_HASH_COMPARE_KEY:
 408        case ERROR_ESBC_CLIENT_HASH_COMPARE_EM:
 409                fsl_secboot_image_verification_failure();
 410                break;
 411        case ERROR_ESBC_MISSING_BOOTM:
 412                fsl_secboot_bootscript_parse_failure();
 413                break;
 414        case ERROR_ESBC_WRONG_CMD:
 415        default:
 416                branch_to_self();
 417                break;
 418        }
 419}
 420
 421static void fsl_secblk_handle_error(int error)
 422{
 423        switch (error) {
 424        case ERROR_ESBC_SEC_ENQ:
 425                fsl_secboot_handle_error(ERROR_ESBC_SEC_ENQ);
 426                break;
 427        case ERROR_ESBC_SEC_DEQ:
 428                fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ);
 429                break;
 430        case ERROR_ESBC_SEC_DEQ_TO:
 431                fsl_secboot_handle_error(ERROR_ESBC_SEC_DEQ_TO);
 432                break;
 433        default:
 434                printf("Job Queue Output status %x\n", error);
 435                fsl_secboot_handle_error(ERROR_ESBC_SEC_JOBQ_STATUS);
 436                break;
 437        }
 438}
 439
 440/*
 441 * Calculate hash of key obtained via offset present in ESBC uboot
 442 * client hdr. This function calculates the hash of key which is obtained
 443 * through offset present in ESBC uboot client header.
 444 */
 445static int calc_img_key_hash(struct fsl_secboot_img_priv *img)
 446{
 447        struct hash_algo *algo;
 448        void *ctx;
 449        int i, srk = 0;
 450        int ret = 0;
 451        const char *algo_name = "sha256";
 452
 453        /* Calculate hash of the esbc key */
 454        ret = hash_progressive_lookup_algo(algo_name, &algo);
 455        if (ret)
 456                return ret;
 457
 458        ret = algo->hash_init(algo, &ctx);
 459        if (ret)
 460                return ret;
 461
 462        /* Update hash for ESBC key */
 463#ifdef CONFIG_KEY_REVOCATION
 464        if (check_srk(img)) {
 465                ret = algo->hash_update(algo, ctx,
 466                      (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
 467                      img->hdr.len_kr.num_srk * sizeof(struct srk_table), 1);
 468                srk = 1;
 469        }
 470#endif
 471        if (!srk)
 472                ret = algo->hash_update(algo, ctx,
 473                        img->img_key, img->key_len, 1);
 474        if (ret)
 475                return ret;
 476
 477        /* Copy hash at destination buffer */
 478        ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
 479        if (ret)
 480                return ret;
 481
 482        for (i = 0; i < SHA256_BYTES; i++)
 483                img->img_key_hash[i] = hash_val[i];
 484
 485        return 0;
 486}
 487
 488/*
 489 * Calculate hash of ESBC hdr and ESBC. This function calculates the
 490 * single hash of ESBC header and ESBC image. If SG flag is on, all
 491 * SG entries are also hashed alongwith the complete SG table.
 492 */
 493static int calc_esbchdr_esbc_hash(struct fsl_secboot_img_priv *img)
 494{
 495        struct hash_algo *algo;
 496        void *ctx;
 497        int ret = 0;
 498        int key_hash = 0;
 499        const char *algo_name = "sha256";
 500
 501        /* Calculate the hash of the ESBC */
 502        ret = hash_progressive_lookup_algo(algo_name, &algo);
 503        if (ret)
 504                return ret;
 505
 506        ret = algo->hash_init(algo, &ctx);
 507        /* Copy hash at destination buffer */
 508        if (ret)
 509                return ret;
 510
 511        /* Update hash for CSF Header */
 512        ret = algo->hash_update(algo, ctx,
 513                (u8 *)&img->hdr, sizeof(struct fsl_secboot_img_hdr), 0);
 514        if (ret)
 515                return ret;
 516
 517        /* Update the hash with that of srk table if srk flag is 1
 518         * If IE Table is selected, key is not added in the hash
 519         * If neither srk table nor IE key table available, add key
 520         * from header in the hash calculation
 521         */
 522#ifdef CONFIG_KEY_REVOCATION
 523        if (check_srk(img)) {
 524                ret = algo->hash_update(algo, ctx,
 525                      (u8 *)(uintptr_t)(img->ehdrloc + img->hdr.srk_tbl_off),
 526                      img->hdr.len_kr.num_srk * sizeof(struct srk_table), 0);
 527                key_hash = 1;
 528        }
 529#endif
 530#if defined(CONFIG_FSL_ISBC_KEY_EXT)
 531        if (!key_hash && check_ie(img))
 532                key_hash = 1;
 533#endif
 534#ifndef CONFIG_ESBC_HDR_LS
 535/* No single key support in LS ESBC header */
 536        if (!key_hash) {
 537                ret = algo->hash_update(algo, ctx,
 538                        img->img_key, img->hdr.key_len, 0);
 539                key_hash = 1;
 540        }
 541#endif
 542        if (ret)
 543                return ret;
 544        if (!key_hash)
 545                return ERROR_KEY_TABLE_NOT_FOUND;
 546
 547        /* Update hash for actual Image */
 548        ret = algo->hash_update(algo, ctx,
 549                (u8 *)(*(img->img_addr_ptr)), img->img_size, 1);
 550        if (ret)
 551                return ret;
 552
 553        /* Copy hash at destination buffer */
 554        ret = algo->hash_finish(algo, ctx, hash_val, algo->digest_size);
 555        if (ret)
 556                return ret;
 557
 558        return 0;
 559}
 560
 561/*
 562 * Construct encoded hash EM' wrt PKCSv1.5. This function calculates the
 563 * pointers for padding, DER value and hash. And finally, constructs EM'
 564 * which includes hash of complete CSF header and ESBC image. If SG flag
 565 * is on, hash of SG table and entries is also included.
 566 */
 567static void construct_img_encoded_hash_second(struct fsl_secboot_img_priv *img)
 568{
 569        /*
 570         * RSA PKCSv1.5 encoding format for encoded message is below
 571         * EM = 0x0 || 0x1 || PS || 0x0 || DER || Hash
 572         * PS is Padding String
 573         * DER is DER value for SHA-256
 574         * Hash is SHA-256 hash
 575         * *********************************************************
 576         * representative points to first byte of EM initially and is
 577         * filled with 0x0
 578         * representative is incremented by 1 and second byte is filled
 579         * with 0x1
 580         * padding points to third byte of EM
 581         * digest points to full length of EM - 32 bytes
 582         * hash_id (DER value) points to 19 bytes before pDigest
 583         * separator is one byte which separates padding and DER
 584         */
 585
 586        size_t len;
 587        u8 *representative;
 588        u8 *padding, *digest;
 589        u8 *hash_id, *separator;
 590        int i;
 591
 592        len = (get_key_len(img) / 2) - 1;
 593        representative = img->img_encoded_hash_second;
 594        representative[0] = 0;
 595        representative[1] = 1;  /* block type 1 */
 596
 597        padding = &representative[2];
 598        digest = &representative[1] + len - 32;
 599        hash_id = digest - sizeof(hash_identifier);
 600        separator = hash_id - 1;
 601
 602        /* fill padding area pointed by padding with 0xff */
 603        memset(padding, 0xff, separator - padding);
 604
 605        /* fill byte pointed by separator */
 606        *separator = 0;
 607
 608        /* fill SHA-256 DER value  pointed by HashId */
 609        memcpy(hash_id, hash_identifier, sizeof(hash_identifier));
 610
 611        /* fill hash pointed by Digest */
 612        for (i = 0; i < SHA256_BYTES; i++)
 613                digest[i] = hash_val[i];
 614}
 615
 616/*
 617 * Reads and validates the ESBC client header.
 618 * This function reads key and signature from the ESBC client header.
 619 * If Scatter/Gather flag is on, lengths and offsets of images
 620 * present as SG entries are also read. This function also checks
 621 * whether the header is valid or not.
 622 */
 623static int read_validate_esbc_client_header(struct fsl_secboot_img_priv *img)
 624{
 625        struct fsl_secboot_img_hdr *hdr = &img->hdr;
 626        void *esbc = (u8 *)(uintptr_t)img->ehdrloc;
 627        u8 *k, *s;
 628        u32 ret = 0;
 629
 630        int  key_found = 0;
 631
 632        /* check barker code */
 633        if (memcmp(hdr->barker, barker_code, ESBC_BARKER_LEN))
 634                return ERROR_ESBC_CLIENT_HEADER_BARKER;
 635
 636        /* If Image Address is not passed as argument to function,
 637         * then Address and Size must be read from the Header.
 638         */
 639        if (*(img->img_addr_ptr) == 0) {
 640        #ifdef CONFIG_ESBC_ADDR_64BIT
 641                *(img->img_addr_ptr) = hdr->pimg64;
 642        #else
 643                *(img->img_addr_ptr) = hdr->pimg;
 644        #endif
 645        }
 646
 647        if (!hdr->img_size)
 648                return ERROR_ESBC_CLIENT_HEADER_IMG_SIZE;
 649
 650        img->img_size = hdr->img_size;
 651
 652        /* Key checking*/
 653#ifdef CONFIG_KEY_REVOCATION
 654        if (check_srk(img)) {
 655                ret = read_validate_srk_tbl(img);
 656                if (ret != 0)
 657                        return ret;
 658                key_found = 1;
 659        }
 660#endif
 661
 662#if defined(CONFIG_FSL_ISBC_KEY_EXT)
 663        if (!key_found && check_ie(img)) {
 664                ret = read_validate_ie_tbl(img);
 665                if (ret != 0)
 666                        return ret;
 667                key_found = 1;
 668        }
 669#endif
 670#ifndef CONFIG_ESBC_HDR_LS
 671/* Single Key Feature not available in LS ESBC Header */
 672        if (key_found == 0) {
 673                ret = read_validate_single_key(img);
 674                if (ret != 0)
 675                        return ret;
 676                key_found = 1;
 677        }
 678#endif
 679        if (!key_found)
 680                return ERROR_KEY_TABLE_NOT_FOUND;
 681
 682        /* check signaure */
 683        if (get_key_len(img) == 2 * hdr->sign_len) {
 684                /* check signature length */
 685                if (!((hdr->sign_len == KEY_SIZE_BYTES / 4) ||
 686                      (hdr->sign_len == KEY_SIZE_BYTES / 2) ||
 687                      (hdr->sign_len == KEY_SIZE_BYTES)))
 688                        return ERROR_ESBC_CLIENT_HEADER_SIG_LEN;
 689        } else {
 690                return ERROR_ESBC_CLIENT_HEADER_KEY_LEN_NOT_TWICE_SIG_LEN;
 691        }
 692
 693        memcpy(&img->img_sign, esbc + hdr->psign, hdr->sign_len);
 694/* No SG support in LS-CH3 */
 695#ifndef CONFIG_ESBC_HDR_LS
 696        /* No SG support */
 697        if (hdr->sg_flag)
 698                return ERROR_ESBC_CLIENT_HEADER_SG;
 699#endif
 700
 701        /* modulus most significant bit should be set */
 702        k = (u8 *)&img->img_key;
 703
 704        if ((k[0] & 0x80) == 0)
 705                return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_1;
 706
 707        /* modulus value should be odd */
 708        if ((k[get_key_len(img) / 2 - 1] & 0x1) == 0)
 709                return ERROR_ESBC_CLIENT_HEADER_KEY_MOD_2;
 710
 711        /* Check signature value < modulus value */
 712        s = (u8 *)&img->img_sign;
 713
 714        if (!(memcmp(s, k, hdr->sign_len) < 0))
 715                return ERROR_ESBC_CLIENT_HEADER_SIG_KEY_MOD;
 716
 717        return ESBC_VALID_HDR;
 718}
 719
 720static inline int str2longbe(const char *p, ulong *num)
 721{
 722        char *endptr;
 723        ulong tmp;
 724
 725        if (!p) {
 726                return 0;
 727        } else {
 728                tmp = simple_strtoul(p, &endptr, 16);
 729                if (sizeof(ulong) == 4)
 730                        *num = cpu_to_be32(tmp);
 731                else
 732                        *num = cpu_to_be64(tmp);
 733        }
 734
 735        return *p != '\0' && *endptr == '\0';
 736}
 737/* Function to calculate the ESBC Image Hash
 738 * and hash from Digital signature.
 739 * The Two hash's are compared to yield the
 740 * result of signature validation.
 741 */
 742static int calculate_cmp_img_sig(struct fsl_secboot_img_priv *img)
 743{
 744        int ret;
 745        uint32_t key_len;
 746        struct key_prop prop;
 747#if !defined(USE_HOSTCC)
 748        struct udevice *mod_exp_dev;
 749#endif
 750        ret = calc_esbchdr_esbc_hash(img);
 751        if (ret)
 752                return ret;
 753
 754        /* Construct encoded hash EM' wrt PKCSv1.5 */
 755        construct_img_encoded_hash_second(img);
 756
 757        /* Fill prop structure for public key */
 758        memset(&prop, 0, sizeof(struct key_prop));
 759        key_len = get_key_len(img) / 2;
 760        prop.modulus = img->img_key;
 761        prop.public_exponent = img->img_key + key_len;
 762        prop.num_bits = key_len * 8;
 763        prop.exp_len = key_len;
 764
 765        ret = uclass_get_device(UCLASS_MOD_EXP, 0, &mod_exp_dev);
 766        if (ret) {
 767                printf("RSA: Can't find Modular Exp implementation\n");
 768                return -EINVAL;
 769        }
 770
 771        ret = rsa_mod_exp(mod_exp_dev, img->img_sign, img->hdr.sign_len,
 772                          &prop, img->img_encoded_hash);
 773        if (ret)
 774                return ret;
 775
 776        /*
 777         * compare the encoded messages EM' and EM wrt RSA PKCSv1.5
 778         * memcmp returns zero on success
 779         * memcmp returns non-zero on failure
 780         */
 781        ret = memcmp(&img->img_encoded_hash_second, &img->img_encoded_hash,
 782                img->hdr.sign_len);
 783
 784        if (ret)
 785                return ERROR_ESBC_CLIENT_HASH_COMPARE_EM;
 786
 787        return 0;
 788}
 789/* haddr - Address of the header of image to be validated.
 790 * arg_hash_str - Option hash string. If provided, this
 791 * overrides the key hash in the SFP fuses.
 792 * img_addr_ptr - Optional pointer to address of image to be validated.
 793 * If non zero addr, this overrides the addr of image in header,
 794 * otherwise updated to image addr in header.
 795 * Acts as both input and output of function.
 796 * This pointer shouldn't be NULL.
 797 */
 798int fsl_secboot_validate(uintptr_t haddr, char *arg_hash_str,
 799                        uintptr_t *img_addr_ptr)
 800{
 801        struct ccsr_sfp_regs *sfp_regs = (void *)(CONFIG_SYS_SFP_ADDR);
 802        ulong hash[SHA256_BYTES/sizeof(ulong)];
 803        char hash_str[NUM_HEX_CHARS + 1];
 804        struct fsl_secboot_img_priv *img;
 805        struct fsl_secboot_img_hdr *hdr;
 806        void *esbc;
 807        int ret, i, hash_cmd = 0;
 808        u32 srk_hash[8];
 809
 810        if (arg_hash_str != NULL) {
 811                const char *cp = arg_hash_str;
 812                int i = 0;
 813
 814                if (*cp == '0' && *(cp + 1) == 'x')
 815                        cp += 2;
 816
 817                /* The input string expected is in hex, where
 818                 * each 4 bits would be represented by a hex
 819                 * sha256 hash is 256 bits long, which would mean
 820                 * num of characters = 256 / 4
 821                 */
 822                if (strlen(cp) != SHA256_NIBBLES) {
 823                        printf("%s is not a 256 bits hex string as expected\n",
 824                               arg_hash_str);
 825                        return -1;
 826                }
 827
 828                for (i = 0; i < sizeof(hash)/sizeof(ulong); i++) {
 829                        strncpy(hash_str, cp + (i * NUM_HEX_CHARS),
 830                                NUM_HEX_CHARS);
 831                        hash_str[NUM_HEX_CHARS] = '\0';
 832                        if (!str2longbe(hash_str, &hash[i])) {
 833                                printf("%s is not a 256 bits hex string ",
 834                                       arg_hash_str);
 835                                return -1;
 836                        }
 837                }
 838
 839                hash_cmd = 1;
 840        }
 841
 842        img = malloc(sizeof(struct fsl_secboot_img_priv));
 843
 844        if (!img)
 845                return -1;
 846
 847        memset(img, 0, sizeof(struct fsl_secboot_img_priv));
 848
 849        /* Update the information in Private Struct */
 850        hdr = &img->hdr;
 851        img->ehdrloc = haddr;
 852        img->img_addr_ptr = img_addr_ptr;
 853        esbc = (u8 *)img->ehdrloc;
 854
 855        memcpy(hdr, esbc, sizeof(struct fsl_secboot_img_hdr));
 856
 857        /* read and validate esbc header */
 858        ret = read_validate_esbc_client_header(img);
 859
 860        if (ret != ESBC_VALID_HDR) {
 861                fsl_secboot_handle_error(ret);
 862                goto exit;
 863        }
 864
 865        /* SRKH present in SFP */
 866        for (i = 0; i < NUM_SRKH_REGS; i++)
 867                srk_hash[i] = srk_in32(&sfp_regs->srk_hash[i]);
 868
 869        /*
 870         * Calculate hash of key obtained via offset present in
 871         * ESBC uboot client hdr
 872         */
 873        ret = calc_img_key_hash(img);
 874        if (ret) {
 875                fsl_secblk_handle_error(ret);
 876                goto exit;
 877        }
 878
 879        /* Compare hash obtained above with SRK hash present in SFP */
 880        if (hash_cmd)
 881                ret = memcmp(&hash, &img->img_key_hash, SHA256_BYTES);
 882        else
 883                ret = memcmp(srk_hash, img->img_key_hash, SHA256_BYTES);
 884
 885#if defined(CONFIG_FSL_ISBC_KEY_EXT)
 886        if (!hash_cmd && check_ie(img))
 887                ret = 0;
 888#endif
 889
 890        if (ret != 0) {
 891                fsl_secboot_handle_error(ERROR_ESBC_CLIENT_HASH_COMPARE_KEY);
 892                goto exit;
 893        }
 894
 895        ret = calculate_cmp_img_sig(img);
 896        if (ret) {
 897                fsl_secboot_handle_error(ret);
 898                goto exit;
 899        }
 900
 901exit:
 902        return ret;
 903}
 904