uboot/board/gdsys/p1022/controlcenterd-id.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2013
   4 * Reinhard Pfau, Guntermann & Drunck GmbH, reinhard.pfau@gdsys.cc
   5 */
   6
   7/* TODO: some more #ifdef's to avoid unneeded code for stage 1 / stage 2 */
   8
   9#ifdef CCDM_ID_DEBUG
  10#define DEBUG
  11#endif
  12
  13#include <common.h>
  14#include <bootstage.h>
  15#include <command.h>
  16#include <dm.h>
  17#include <env.h>
  18#include <hang.h>
  19#include <log.h>
  20#include <malloc.h>
  21#include <fs.h>
  22#include <i2c.h>
  23#include <mmc.h>
  24#include <tpm-v1.h>
  25#include <linux/delay.h>
  26#include <u-boot/crc.h>
  27#include <u-boot/sha1.h>
  28#include <asm/byteorder.h>
  29#include <asm/unaligned.h>
  30#include <pca9698.h>
  31
  32#undef CCDM_FIRST_STAGE
  33#undef CCDM_SECOND_STAGE
  34#undef CCDM_AUTO_FIRST_STAGE
  35
  36#ifdef CONFIG_DEVELOP
  37#define CCDM_DEVELOP
  38#endif
  39
  40#ifdef CONFIG_TRAILBLAZER
  41#define CCDM_FIRST_STAGE
  42#undef CCDM_SECOND_STAGE
  43#else
  44#undef CCDM_FIRST_STAGE
  45#define CCDM_SECOND_STAGE
  46#endif
  47
  48#if defined(CCDM_DEVELOP) && defined(CCDM_SECOND_STAGE) && \
  49        !defined(CCCM_FIRST_STAGE)
  50#define CCDM_AUTO_FIRST_STAGE
  51#endif
  52
  53/* CCDM specific contants */
  54enum {
  55        /* NV indices */
  56        NV_COMMON_DATA_INDEX    = 0x40000001,
  57        /* magics for key blob chains */
  58        MAGIC_KEY_PROGRAM       = 0x68726500,
  59        MAGIC_HMAC              = 0x68616300,
  60        MAGIC_END_OF_CHAIN      = 0x00000000,
  61        /* sizes */
  62        NV_COMMON_DATA_MIN_SIZE = 3 * sizeof(uint64_t) + 2 * sizeof(uint16_t),
  63};
  64
  65/* other constants */
  66enum {
  67        ESDHC_BOOT_IMAGE_SIG_OFS        = 0x40,
  68        ESDHC_BOOT_IMAGE_SIZE_OFS       = 0x48,
  69        ESDHC_BOOT_IMAGE_ADDR_OFS       = 0x50,
  70        ESDHC_BOOT_IMAGE_TARGET_OFS     = 0x58,
  71        ESDHC_BOOT_IMAGE_ENTRY_OFS      = 0x60,
  72};
  73
  74enum {
  75        I2C_SOC_0 = 0,
  76        I2C_SOC_1 = 1,
  77};
  78
  79struct key_program {
  80        uint32_t magic;
  81        uint32_t code_crc;
  82        uint32_t code_size;
  83        uint8_t code[];
  84};
  85
  86struct h_reg {
  87        bool valid;
  88        uint8_t digest[20];
  89};
  90
  91
  92enum access_mode {
  93        HREG_NONE       = 0,
  94        HREG_RD         = 1,
  95        HREG_WR         = 2,
  96        HREG_RDWR       = 3,
  97};
  98
  99/* register constants */
 100enum {
 101        FIX_HREG_DEVICE_ID_HASH = 0,
 102        FIX_HREG_SELF_HASH      = 1,
 103        FIX_HREG_STAGE2_HASH    = 2,
 104        FIX_HREG_VENDOR         = 3,
 105        COUNT_FIX_HREGS
 106};
 107
 108
 109/* hre opcodes */
 110enum {
 111        /* opcodes w/o data */
 112        HRE_NOP         = 0x00,
 113        HRE_SYNC        = HRE_NOP,
 114        HRE_CHECK0      = 0x01,
 115        /* opcodes w/o data, w/ sync dst */
 116        /* opcodes w/ data */
 117        HRE_LOAD        = 0x81,
 118        /* opcodes w/data, w/sync dst */
 119        HRE_XOR         = 0xC1,
 120        HRE_AND         = 0xC2,
 121        HRE_OR          = 0xC3,
 122        HRE_EXTEND      = 0xC4,
 123        HRE_LOADKEY     = 0xC5,
 124};
 125
 126/* hre errors */
 127enum {
 128        HRE_E_OK        = 0,
 129        HRE_E_TPM_FAILURE,
 130        HRE_E_INVALID_HREG,
 131};
 132
 133static uint64_t device_id;
 134static uint64_t device_cl;
 135static uint64_t device_type;
 136
 137static uint32_t platform_key_handle;
 138
 139static void(*bl2_entry)(void);
 140
 141static struct h_reg pcr_hregs[24];
 142static struct h_reg fix_hregs[COUNT_FIX_HREGS];
 143static struct h_reg var_hregs[8];
 144static uint32_t hre_tpm_err;
 145static int hre_err = HRE_E_OK;
 146
 147#define IS_PCR_HREG(spec) ((spec) & 0x20)
 148#define IS_FIX_HREG(spec) (((spec) & 0x38) == 0x08)
 149#define IS_VAR_HREG(spec) (((spec) & 0x38) == 0x10)
 150#define HREG_IDX(spec) ((spec) & (IS_PCR_HREG(spec) ? 0x1f : 0x7))
 151
 152static int get_tpm(struct udevice **devp)
 153{
 154        int rc;
 155
 156        rc = uclass_first_device_err(UCLASS_TPM, devp);
 157        if (rc) {
 158                printf("Could not find TPM (ret=%d)\n", rc);
 159                return CMD_RET_FAILURE;
 160        }
 161
 162        return 0;
 163}
 164
 165static const uint8_t vendor[] = "Guntermann & Drunck";
 166
 167/**
 168 * @brief read a bunch of data from MMC into memory.
 169 *
 170 * @param mmc   pointer to the mmc structure to use.
 171 * @param src   offset where the data starts on MMC/SD device (in bytes).
 172 * @param dst   pointer to the location where the read data should be stored.
 173 * @param size  number of bytes to read from the MMC/SD device.
 174 * @return number of bytes read or -1 on error.
 175 */
 176static int ccdm_mmc_read(struct mmc *mmc, u64 src, u8 *dst, int size)
 177{
 178        int result = 0;
 179        u32 blk_len, ofs;
 180        ulong block_no, n, cnt;
 181        u8 *tmp_buf = NULL;
 182
 183        if (size <= 0)
 184                goto end;
 185
 186        blk_len = mmc->read_bl_len;
 187        tmp_buf = malloc(blk_len);
 188        if (!tmp_buf)
 189                goto failure;
 190        block_no = src / blk_len;
 191        ofs = src % blk_len;
 192
 193        if (ofs) {
 194                n = mmc->block_dev.block_read(&mmc->block_dev, block_no++, 1,
 195                        tmp_buf);
 196                if (!n)
 197                        goto failure;
 198                result = min(size, (int)(blk_len - ofs));
 199                memcpy(dst, tmp_buf + ofs, result);
 200                dst += result;
 201                size -= result;
 202        }
 203        cnt = size / blk_len;
 204        if (cnt) {
 205                n = mmc->block_dev.block_read(&mmc->block_dev, block_no, cnt,
 206                        dst);
 207                if (n != cnt)
 208                        goto failure;
 209                size -= cnt * blk_len;
 210                result += cnt * blk_len;
 211                dst += cnt * blk_len;
 212                block_no += cnt;
 213        }
 214        if (size) {
 215                n = mmc->block_dev.block_read(&mmc->block_dev, block_no++, 1,
 216                        tmp_buf);
 217                if (!n)
 218                        goto failure;
 219                memcpy(dst, tmp_buf, size);
 220                result += size;
 221        }
 222        goto end;
 223failure:
 224        result = -1;
 225end:
 226        if (tmp_buf)
 227                free(tmp_buf);
 228        return result;
 229}
 230
 231/**
 232 * @brief returns a location where the 2nd stage bootloader can be(/ is) placed.
 233 *
 234 * @return pointer to the location for/of the 2nd stage bootloader
 235 */
 236static u8 *get_2nd_stage_bl_location(ulong target_addr)
 237{
 238        ulong addr;
 239#ifdef CCDM_SECOND_STAGE
 240        addr = env_get_ulong("loadaddr", 16, CONFIG_LOADADDR);
 241#else
 242        addr = target_addr;
 243#endif
 244        return (u8 *)(addr);
 245}
 246
 247
 248#ifdef CCDM_SECOND_STAGE
 249/**
 250 * @brief returns a location where the image can be(/ is) placed.
 251 *
 252 * @return pointer to the location for/of the image
 253 */
 254static u8 *get_image_location(void)
 255{
 256        ulong addr;
 257        /* TODO use other area? */
 258        addr = env_get_ulong("loadaddr", 16, CONFIG_LOADADDR);
 259        return (u8 *)(addr);
 260}
 261#endif
 262
 263/**
 264 * @brief get the size of a given (TPM) NV area
 265 * @param index NV index of the area to get size for
 266 * @param size  pointer to the size
 267 * @return 0 on success, != 0 on error
 268 */
 269static int get_tpm_nv_size(struct udevice *tpm, uint32_t index, uint32_t *size)
 270{
 271        uint32_t err;
 272        uint8_t info[72];
 273        uint8_t *ptr;
 274        uint16_t v16;
 275
 276        err = tpm_get_capability(tpm, TPM_CAP_NV_INDEX, index,
 277                                 info, sizeof(info));
 278        if (err) {
 279                printf("tpm_get_capability(CAP_NV_INDEX, %08x) failed: %u\n",
 280                       index, err);
 281                return 1;
 282        }
 283
 284        /* skip tag and nvIndex */
 285        ptr = info + 6;
 286        /* skip 2 pcr info fields */
 287        v16 = get_unaligned_be16(ptr);
 288        ptr += 2 + v16 + 1 + 20;
 289        v16 = get_unaligned_be16(ptr);
 290        ptr += 2 + v16 + 1 + 20;
 291        /* skip permission and flags */
 292        ptr += 6 + 3;
 293
 294        *size = get_unaligned_be32(ptr);
 295        return 0;
 296}
 297
 298/**
 299 * @brief search for a key by usage auth and pub key hash.
 300 * @param auth  usage auth of the key to search for
 301 * @param pubkey_digest (SHA1) hash of the pub key structure of the key
 302 * @param[out] handle   the handle of the key iff found
 303 * @return 0 if key was found in TPM; != 0 if not.
 304 */
 305static int find_key(struct udevice *tpm, const uint8_t auth[20],
 306                    const uint8_t pubkey_digest[20], uint32_t *handle)
 307{
 308        uint16_t key_count;
 309        uint32_t key_handles[10];
 310        uint8_t buf[288];
 311        uint8_t *ptr;
 312        uint32_t err;
 313        uint8_t digest[20];
 314        size_t buf_len;
 315        unsigned int i;
 316
 317        /* fetch list of already loaded keys in the TPM */
 318        err = tpm_get_capability(tpm, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
 319                                 sizeof(buf));
 320        if (err)
 321                return -1;
 322        key_count = get_unaligned_be16(buf);
 323        ptr = buf + 2;
 324        for (i = 0; i < key_count; ++i, ptr += 4)
 325                key_handles[i] = get_unaligned_be32(ptr);
 326
 327        /* now search a(/ the) key which we can access with the given auth */
 328        for (i = 0; i < key_count; ++i) {
 329                buf_len = sizeof(buf);
 330                err = tpm_get_pub_key_oiap(tpm, key_handles[i], auth, buf,
 331                                           &buf_len);
 332                if (err && err != TPM_AUTHFAIL)
 333                        return -1;
 334                if (err)
 335                        continue;
 336                sha1_csum(buf, buf_len, digest);
 337                if (!memcmp(digest, pubkey_digest, 20)) {
 338                        *handle = key_handles[i];
 339                        return 0;
 340                }
 341        }
 342        return 1;
 343}
 344
 345/**
 346 * @brief read CCDM common data from TPM NV
 347 * @return 0 if CCDM common data was found and read, !=0 if something failed.
 348 */
 349static int read_common_data(struct udevice *tpm)
 350{
 351        uint32_t size;
 352        uint32_t err;
 353        uint8_t buf[256];
 354        sha1_context ctx;
 355
 356        if (get_tpm_nv_size(tpm, NV_COMMON_DATA_INDEX, &size) ||
 357            size < NV_COMMON_DATA_MIN_SIZE)
 358                return 1;
 359        err = tpm_nv_read_value(tpm, NV_COMMON_DATA_INDEX,
 360                                buf, min(sizeof(buf), size));
 361        if (err) {
 362                printf("tpm_nv_read_value() failed: %u\n", err);
 363                return 1;
 364        }
 365
 366        device_id = get_unaligned_be64(buf);
 367        device_cl = get_unaligned_be64(buf + 8);
 368        device_type = get_unaligned_be64(buf + 16);
 369
 370        sha1_starts(&ctx);
 371        sha1_update(&ctx, buf, 24);
 372        sha1_finish(&ctx, fix_hregs[FIX_HREG_DEVICE_ID_HASH].digest);
 373        fix_hregs[FIX_HREG_DEVICE_ID_HASH].valid = true;
 374
 375        platform_key_handle = get_unaligned_be32(buf + 24);
 376
 377        return 0;
 378}
 379
 380/**
 381 * @brief compute hash of bootloader itself.
 382 * @param[out] dst      hash register where the hash should be stored
 383 * @return 0 on success, != 0 on failure.
 384 *
 385 * @note MUST be called at a time where the boot loader is accessible at the
 386 * configured location (; so take care when code is reallocated).
 387 */
 388static int compute_self_hash(struct h_reg *dst)
 389{
 390        sha1_csum((const uint8_t *)CONFIG_SYS_MONITOR_BASE,
 391                  CONFIG_SYS_MONITOR_LEN, dst->digest);
 392        dst->valid = true;
 393        return 0;
 394}
 395
 396int ccdm_compute_self_hash(void)
 397{
 398        if (!fix_hregs[FIX_HREG_SELF_HASH].valid)
 399                compute_self_hash(&fix_hregs[FIX_HREG_SELF_HASH]);
 400        return 0;
 401}
 402
 403/**
 404 * @brief compute the hash of the 2nd stage boot loader (on SD card)
 405 * @param[out] dst      hash register to store the computed hash
 406 * @return 0 on success, != 0 on failure
 407 *
 408 * Determines the size and location of the 2nd stage boot loader on SD card,
 409 * loads the 2nd stage boot loader and computes the (SHA1) hash value.
 410 * Within the 1st stage boot loader, the 2nd stage boot loader is loaded at
 411 * the desired memory location and the variable @a bl2_entry is set.
 412 *
 413 * @note This sets the variable @a bl2_entry to the entry point when the
 414 * 2nd stage boot loader is loaded at its configured memory location.
 415 */
 416static int compute_second_stage_hash(struct h_reg *dst)
 417{
 418        int result = 0;
 419        u32 code_len, code_offset, target_addr, exec_entry;
 420        struct mmc *mmc;
 421        u8 *load_addr = NULL;
 422        u8 buf[128];
 423
 424        mmc = find_mmc_device(0);
 425        if (!mmc)
 426                goto failure;
 427        mmc_init(mmc);
 428
 429        if (ccdm_mmc_read(mmc, 0, buf, sizeof(buf)) < 0)
 430                goto failure;
 431
 432        code_offset = *(u32 *)(buf + ESDHC_BOOT_IMAGE_ADDR_OFS);
 433        code_len = *(u32 *)(buf + ESDHC_BOOT_IMAGE_SIZE_OFS);
 434        target_addr = *(u32 *)(buf + ESDHC_BOOT_IMAGE_TARGET_OFS);
 435        exec_entry =  *(u32 *)(buf + ESDHC_BOOT_IMAGE_ENTRY_OFS);
 436
 437        load_addr = get_2nd_stage_bl_location(target_addr);
 438        if (load_addr == (u8 *)target_addr)
 439                bl2_entry = (void(*)(void))exec_entry;
 440
 441        if (ccdm_mmc_read(mmc, code_offset, load_addr, code_len) < 0)
 442                goto failure;
 443
 444        sha1_csum(load_addr, code_len, dst->digest);
 445        dst->valid = true;
 446
 447        goto end;
 448failure:
 449        result = 1;
 450        bl2_entry = NULL;
 451end:
 452        return result;
 453}
 454
 455/**
 456 * @brief get pointer to  hash register by specification
 457 * @param spec  specification of a hash register
 458 * @return pointer to hash register or NULL if @a spec does not qualify a
 459 * valid hash register; NULL else.
 460 */
 461static struct h_reg *get_hreg(uint8_t spec)
 462{
 463        uint8_t idx;
 464
 465        idx = HREG_IDX(spec);
 466        if (IS_FIX_HREG(spec)) {
 467                if (idx < ARRAY_SIZE(fix_hregs))
 468                        return fix_hregs + idx;
 469                hre_err = HRE_E_INVALID_HREG;
 470        } else if (IS_PCR_HREG(spec)) {
 471                if (idx < ARRAY_SIZE(pcr_hregs))
 472                        return pcr_hregs + idx;
 473                hre_err = HRE_E_INVALID_HREG;
 474        } else if (IS_VAR_HREG(spec)) {
 475                if (idx < ARRAY_SIZE(var_hregs))
 476                        return var_hregs + idx;
 477                hre_err = HRE_E_INVALID_HREG;
 478        }
 479        return NULL;
 480}
 481
 482/**
 483 * @brief get pointer of a hash register by specification and usage.
 484 * @param spec  specification of a hash register
 485 * @param mode  access mode (read or write or read/write)
 486 * @return pointer to hash register if found and valid; NULL else.
 487 *
 488 * This func uses @a get_reg() to determine the hash register for a given spec.
 489 * If a register is found it is validated according to the desired access mode.
 490 * The value of automatic registers (PCR register and fixed registers) is
 491 * loaded or computed on read access.
 492 */
 493static struct h_reg *access_hreg(struct udevice *tpm, uint8_t spec,
 494                                 enum access_mode mode)
 495{
 496        struct h_reg *result;
 497
 498        result = get_hreg(spec);
 499        if (!result)
 500                return NULL;
 501
 502        if (mode & HREG_WR) {
 503                if (IS_FIX_HREG(spec)) {
 504                        hre_err = HRE_E_INVALID_HREG;
 505                        return NULL;
 506                }
 507        }
 508        if (mode & HREG_RD) {
 509                if (!result->valid) {
 510                        if (IS_PCR_HREG(spec)) {
 511                                hre_tpm_err = tpm_pcr_read(tpm, HREG_IDX(spec),
 512                                        result->digest, 20);
 513                                result->valid = (hre_tpm_err == TPM_SUCCESS);
 514                        } else if (IS_FIX_HREG(spec)) {
 515                                switch (HREG_IDX(spec)) {
 516                                case FIX_HREG_DEVICE_ID_HASH:
 517                                        read_common_data(tpm);
 518                                        break;
 519                                case FIX_HREG_SELF_HASH:
 520                                        ccdm_compute_self_hash();
 521                                        break;
 522                                case FIX_HREG_STAGE2_HASH:
 523                                        compute_second_stage_hash(result);
 524                                        break;
 525                                case FIX_HREG_VENDOR:
 526                                        memcpy(result->digest, vendor, 20);
 527                                        result->valid = true;
 528                                        break;
 529                                }
 530                        } else {
 531                                result->valid = true;
 532                        }
 533                }
 534                if (!result->valid) {
 535                        hre_err = HRE_E_INVALID_HREG;
 536                        return NULL;
 537                }
 538        }
 539
 540        return result;
 541}
 542
 543static void *compute_and(void *_dst, const void *_src, size_t n)
 544{
 545        uint8_t *dst = _dst;
 546        const uint8_t *src = _src;
 547        size_t i;
 548
 549        for (i = n; i-- > 0; )
 550                *dst++ &= *src++;
 551
 552        return _dst;
 553}
 554
 555static void *compute_or(void *_dst, const void *_src, size_t n)
 556{
 557        uint8_t *dst = _dst;
 558        const uint8_t *src = _src;
 559        size_t i;
 560
 561        for (i = n; i-- > 0; )
 562                *dst++ |= *src++;
 563
 564        return _dst;
 565}
 566
 567static void *compute_xor(void *_dst, const void *_src, size_t n)
 568{
 569        uint8_t *dst = _dst;
 570        const uint8_t *src = _src;
 571        size_t i;
 572
 573        for (i = n; i-- > 0; )
 574                *dst++ ^= *src++;
 575
 576        return _dst;
 577}
 578
 579static void *compute_extend(void *_dst, const void *_src, size_t n)
 580{
 581        uint8_t digest[20];
 582        sha1_context ctx;
 583
 584        sha1_starts(&ctx);
 585        sha1_update(&ctx, _dst, n);
 586        sha1_update(&ctx, _src, n);
 587        sha1_finish(&ctx, digest);
 588        memcpy(_dst, digest, min(n, sizeof(digest)));
 589
 590        return _dst;
 591}
 592
 593static int hre_op_loadkey(struct udevice *tpm, struct h_reg *src_reg,
 594                          struct h_reg *dst_reg, const void *key,
 595                          size_t key_size)
 596{
 597        uint32_t parent_handle;
 598        uint32_t key_handle;
 599
 600        if (!src_reg || !dst_reg || !src_reg->valid || !dst_reg->valid)
 601                return -1;
 602        if (find_key(tpm, src_reg->digest, dst_reg->digest, &parent_handle))
 603                return -1;
 604        hre_tpm_err = tpm_load_key2_oiap(tpm, parent_handle, key, key_size,
 605                                         src_reg->digest, &key_handle);
 606        if (hre_tpm_err) {
 607                hre_err = HRE_E_TPM_FAILURE;
 608                return -1;
 609        }
 610        /* TODO remember key handle somehow? */
 611
 612        return 0;
 613}
 614
 615/**
 616 * @brief executes the next opcode on the hash register engine.
 617 * @param[in,out] ip    pointer to the opcode (instruction pointer)
 618 * @param[in,out] code_size     (remaining) size of the code
 619 * @return new instruction pointer on success, NULL on error.
 620 */
 621static const uint8_t *hre_execute_op(struct udevice *tpm, const uint8_t **ip,
 622                                     size_t *code_size)
 623{
 624        bool dst_modified = false;
 625        uint32_t ins;
 626        uint8_t opcode;
 627        uint8_t src_spec;
 628        uint8_t dst_spec;
 629        uint16_t data_size;
 630        struct h_reg *src_reg, *dst_reg;
 631        uint8_t buf[20];
 632        const uint8_t *src_buf, *data;
 633        uint8_t *ptr;
 634        int i;
 635        void * (*bin_func)(void *, const void *, size_t);
 636
 637        if (*code_size < 4)
 638                return NULL;
 639
 640        ins = get_unaligned_be32(*ip);
 641        opcode = **ip;
 642        data = *ip + 4;
 643        src_spec = (ins >> 18) & 0x3f;
 644        dst_spec = (ins >> 12) & 0x3f;
 645        data_size = (ins & 0x7ff);
 646
 647        debug("HRE: ins=%08x (op=%02x, s=%02x, d=%02x, L=%d)\n", ins,
 648              opcode, src_spec, dst_spec, data_size);
 649
 650        if ((opcode & 0x80) && (data_size + 4) > *code_size)
 651                return NULL;
 652
 653        src_reg = access_hreg(tpm, src_spec, HREG_RD);
 654        if (hre_err || hre_tpm_err)
 655                return NULL;
 656        dst_reg = access_hreg(tpm, dst_spec,
 657                              (opcode & 0x40) ? HREG_RDWR : HREG_WR);
 658        if (hre_err || hre_tpm_err)
 659                return NULL;
 660
 661        switch (opcode) {
 662        case HRE_NOP:
 663                goto end;
 664        case HRE_CHECK0:
 665                if (src_reg) {
 666                        for (i = 0; i < 20; ++i) {
 667                                if (src_reg->digest[i])
 668                                        return NULL;
 669                        }
 670                }
 671                break;
 672        case HRE_LOAD:
 673                bin_func = memcpy;
 674                goto do_bin_func;
 675        case HRE_XOR:
 676                bin_func = compute_xor;
 677                goto do_bin_func;
 678        case HRE_AND:
 679                bin_func = compute_and;
 680                goto do_bin_func;
 681        case HRE_OR:
 682                bin_func = compute_or;
 683                goto do_bin_func;
 684        case HRE_EXTEND:
 685                bin_func = compute_extend;
 686do_bin_func:
 687                if (!dst_reg)
 688                        return NULL;
 689                if (src_reg) {
 690                        src_buf = src_reg->digest;
 691                } else {
 692                        if (!data_size) {
 693                                memset(buf, 0, 20);
 694                                src_buf = buf;
 695                        } else if (data_size == 1) {
 696                                memset(buf, *data, 20);
 697                                src_buf = buf;
 698                        } else if (data_size >= 20) {
 699                                src_buf = data;
 700                        } else {
 701                                src_buf = buf;
 702                                for (ptr = (uint8_t *)src_buf, i = 20; i > 0;
 703                                        i -= data_size, ptr += data_size)
 704                                        memcpy(ptr, data,
 705                                               min_t(size_t, i, data_size));
 706                        }
 707                }
 708                bin_func(dst_reg->digest, src_buf, 20);
 709                dst_reg->valid = true;
 710                dst_modified = true;
 711                break;
 712        case HRE_LOADKEY:
 713                if (hre_op_loadkey(tpm, src_reg, dst_reg, data, data_size))
 714                        return NULL;
 715                break;
 716        default:
 717                return NULL;
 718        }
 719
 720        if (dst_reg && dst_modified && IS_PCR_HREG(dst_spec)) {
 721                hre_tpm_err = tpm_extend(tpm, HREG_IDX(dst_spec),
 722                                         dst_reg->digest, dst_reg->digest);
 723                if (hre_tpm_err) {
 724                        hre_err = HRE_E_TPM_FAILURE;
 725                        return NULL;
 726                }
 727        }
 728end:
 729        *ip += 4;
 730        *code_size -= 4;
 731        if (opcode & 0x80) {
 732                *ip += data_size;
 733                *code_size -= data_size;
 734        }
 735
 736        return *ip;
 737}
 738
 739/**
 740 * @brief runs a program on the hash register engine.
 741 * @param code          pointer to the (HRE) code.
 742 * @param code_size     size of the code (in bytes).
 743 * @return 0 on success, != 0 on failure.
 744 */
 745static int hre_run_program(struct udevice *tpm, const uint8_t *code,
 746                           size_t code_size)
 747{
 748        size_t code_left;
 749        const uint8_t *ip = code;
 750
 751        code_left = code_size;
 752        hre_tpm_err = 0;
 753        hre_err = HRE_E_OK;
 754        while (code_left > 0)
 755                if (!hre_execute_op(tpm, &ip, &code_left))
 756                        return -1;
 757
 758        return hre_err;
 759}
 760
 761static int check_hmac(struct key_program *hmac,
 762        const uint8_t *data, size_t data_size)
 763{
 764        uint8_t key[20], computed_hmac[20];
 765        uint32_t type;
 766
 767        type = get_unaligned_be32(hmac->code);
 768        if (type != 0)
 769                return 1;
 770        memset(key, 0, sizeof(key));
 771        compute_extend(key, pcr_hregs[1].digest, 20);
 772        compute_extend(key, pcr_hregs[2].digest, 20);
 773        compute_extend(key, pcr_hregs[3].digest, 20);
 774        compute_extend(key, pcr_hregs[4].digest, 20);
 775
 776        sha1_hmac(key, sizeof(key), data, data_size, computed_hmac);
 777
 778        return memcmp(computed_hmac, hmac->code + 4, 20);
 779}
 780
 781static int verify_program(struct key_program *prg)
 782{
 783        uint32_t crc;
 784        crc = crc32(0, prg->code, prg->code_size);
 785
 786        if (crc != prg->code_crc) {
 787                printf("HRC crc mismatch: %08x != %08x\n",
 788                       crc, prg->code_crc);
 789                return 1;
 790        }
 791        return 0;
 792}
 793
 794#if defined(CCDM_FIRST_STAGE) || (defined CCDM_AUTO_FIRST_STAGE)
 795static struct key_program *load_sd_key_program(void)
 796{
 797        u32 code_len, code_offset;
 798        struct mmc *mmc;
 799        u8 buf[128];
 800        struct key_program *result = NULL, *hmac = NULL;
 801        struct key_program header;
 802
 803        mmc = find_mmc_device(0);
 804        if (!mmc)
 805                return NULL;
 806        mmc_init(mmc);
 807
 808        if (ccdm_mmc_read(mmc, 0, buf, sizeof(buf)) <= 0)
 809                goto failure;
 810
 811        code_offset = *(u32 *)(buf + ESDHC_BOOT_IMAGE_ADDR_OFS);
 812        code_len = *(u32 *)(buf + ESDHC_BOOT_IMAGE_SIZE_OFS);
 813
 814        code_offset += code_len;
 815        /* TODO: the following needs to be the size of the 2nd stage env */
 816        code_offset += CONFIG_ENV_SIZE;
 817
 818        if (ccdm_mmc_read(mmc, code_offset, buf, 4*3) < 0)
 819                goto failure;
 820
 821        header.magic = get_unaligned_be32(buf);
 822        header.code_crc = get_unaligned_be32(buf + 4);
 823        header.code_size = get_unaligned_be32(buf + 8);
 824
 825        if (header.magic != MAGIC_KEY_PROGRAM)
 826                goto failure;
 827
 828        result = malloc(sizeof(struct key_program) + header.code_size);
 829        if (!result)
 830                goto failure;
 831        *result = header;
 832
 833        printf("load key program chunk from SD card (%u bytes) ",
 834               header.code_size);
 835        code_offset += 12;
 836        if (ccdm_mmc_read(mmc, code_offset, result->code, header.code_size)
 837                < 0)
 838                goto failure;
 839        code_offset += header.code_size;
 840        puts("\n");
 841
 842        if (verify_program(result))
 843                goto failure;
 844
 845        if (ccdm_mmc_read(mmc, code_offset, buf, 4*3) < 0)
 846                goto failure;
 847
 848        header.magic = get_unaligned_be32(buf);
 849        header.code_crc = get_unaligned_be32(buf + 4);
 850        header.code_size = get_unaligned_be32(buf + 8);
 851
 852        if (header.magic == MAGIC_HMAC) {
 853                puts("check integrity\n");
 854                hmac = malloc(sizeof(struct key_program) + header.code_size);
 855                if (!hmac)
 856                        goto failure;
 857                *hmac = header;
 858                code_offset += 12;
 859                if (ccdm_mmc_read(mmc, code_offset, hmac->code,
 860                                  hmac->code_size) < 0)
 861                        goto failure;
 862                if (verify_program(hmac))
 863                        goto failure;
 864                if (check_hmac(hmac, result->code, result->code_size)) {
 865                        puts("key program integrity could not be verified\n");
 866                        goto failure;
 867                }
 868                puts("key program verified\n");
 869        }
 870
 871        goto end;
 872failure:
 873        if (result)
 874                free(result);
 875        result = NULL;
 876end:
 877        if (hmac)
 878                free(hmac);
 879
 880        return result;
 881}
 882#endif
 883
 884#ifdef CCDM_SECOND_STAGE
 885/**
 886 * @brief load a key program from file system.
 887 * @param ifname        interface of the file system
 888 * @param dev_part_str  device part of the file system
 889 * @param fs_type       tyep of the file system
 890 * @param path          path of the file to load.
 891 * @return the loaded structure or NULL on failure.
 892 */
 893static struct key_program *load_key_chunk(const char *ifname,
 894        const char *dev_part_str, int fs_type,
 895        const char *path)
 896{
 897        struct key_program *result = NULL;
 898        struct key_program header;
 899        uint32_t crc;
 900        uint8_t buf[12];
 901        loff_t i;
 902
 903        if (fs_set_blk_dev(ifname, dev_part_str, fs_type))
 904                goto failure;
 905        if (fs_read(path, (ulong)buf, 0, 12, &i) < 0)
 906                goto failure;
 907        if (i < 12)
 908                goto failure;
 909        header.magic = get_unaligned_be32(buf);
 910        header.code_crc = get_unaligned_be32(buf + 4);
 911        header.code_size = get_unaligned_be32(buf + 8);
 912
 913        if (header.magic != MAGIC_HMAC && header.magic != MAGIC_KEY_PROGRAM)
 914                goto failure;
 915
 916        result = malloc(sizeof(struct key_program) + header.code_size);
 917        if (!result)
 918                goto failure;
 919        if (fs_set_blk_dev(ifname, dev_part_str, fs_type))
 920                goto failure;
 921        if (fs_read(path, (ulong)result, 0,
 922                    sizeof(struct key_program) + header.code_size, &i) < 0)
 923                goto failure;
 924        if (i <= 0)
 925                goto failure;
 926        *result = header;
 927
 928        crc = crc32(0, result->code, result->code_size);
 929
 930        if (crc != result->code_crc) {
 931                printf("%s: HRC crc mismatch: %08x != %08x\n",
 932                       path, crc, result->code_crc);
 933                goto failure;
 934        }
 935        goto end;
 936failure:
 937        if (result) {
 938                free(result);
 939                result = NULL;
 940        }
 941end:
 942        return result;
 943}
 944#endif
 945
 946#if defined(CCDM_FIRST_STAGE) || (defined CCDM_AUTO_FIRST_STAGE)
 947static const uint8_t prg_stage1_prepare[] = {
 948        0x00, 0x20, 0x00, 0x00, /* opcode: SYNC f0 */
 949        0x00, 0x24, 0x00, 0x00, /* opcode: SYNC f1 */
 950        0x01, 0x80, 0x00, 0x00, /* opcode: CHECK0 PCR0 */
 951        0x81, 0x22, 0x00, 0x00, /* opcode: LOAD PCR0, f0 */
 952        0x01, 0x84, 0x00, 0x00, /* opcode: CHECK0 PCR1 */
 953        0x81, 0x26, 0x10, 0x00, /* opcode: LOAD PCR1, f1 */
 954        0x01, 0x88, 0x00, 0x00, /* opcode: CHECK0 PCR2 */
 955        0x81, 0x2a, 0x20, 0x00, /* opcode: LOAD PCR2, f2 */
 956        0x01, 0x8c, 0x00, 0x00, /* opcode: CHECK0 PCR3 */
 957        0x81, 0x2e, 0x30, 0x00, /* opcode: LOAD PCR3, f3 */
 958};
 959
 960static int first_stage_actions(struct udevice *tpm)
 961{
 962        int result = 0;
 963        struct key_program *sd_prg = NULL;
 964
 965        puts("CCDM S1: start actions\n");
 966#ifndef CCDM_SECOND_STAGE
 967        if (tpm_continue_self_test(tpm))
 968                goto failure;
 969#else
 970        tpm_continue_self_test(tpm);
 971#endif
 972        mdelay(37);
 973
 974        if (hre_run_program(tpm, prg_stage1_prepare,
 975                            sizeof(prg_stage1_prepare)))
 976                goto failure;
 977
 978        sd_prg = load_sd_key_program();
 979        if (sd_prg) {
 980                if (hre_run_program(tpm, sd_prg->code, sd_prg->code_size))
 981                        goto failure;
 982                puts("SD code run successfully\n");
 983        } else {
 984                puts("no key program found on SD\n");
 985                goto failure;
 986        }
 987        goto end;
 988failure:
 989        result = 1;
 990end:
 991        if (sd_prg)
 992                free(sd_prg);
 993        printf("CCDM S1: actions done (%d)\n", result);
 994        return result;
 995}
 996#endif
 997
 998#ifdef CCDM_FIRST_STAGE
 999static int first_stage_init(void)
1000{
1001        struct udevice *tpm;
1002        int ret;
1003
1004        puts("CCDM S1\n");
1005        ret = get_tpm(&tpm);
1006        if (ret || tpm_init(tpm) || tpm_startup(tpm, TPM_ST_CLEAR))
1007                return 1;
1008        ret = first_stage_actions(tpm);
1009#ifndef CCDM_SECOND_STAGE
1010        if (!ret) {
1011                if (bl2_entry)
1012                        (*bl2_entry)();
1013                ret = 1;
1014        }
1015#endif
1016        return ret;
1017}
1018#endif
1019
1020#ifdef CCDM_SECOND_STAGE
1021static const uint8_t prg_stage2_prepare[] = {
1022        0x00, 0x80, 0x00, 0x00, /* opcode: SYNC PCR0 */
1023        0x00, 0x84, 0x00, 0x00, /* opcode: SYNC PCR1 */
1024        0x00, 0x88, 0x00, 0x00, /* opcode: SYNC PCR2 */
1025        0x00, 0x8c, 0x00, 0x00, /* opcode: SYNC PCR3 */
1026        0x00, 0x90, 0x00, 0x00, /* opcode: SYNC PCR4 */
1027};
1028
1029static const uint8_t prg_stage2_success[] = {
1030        0x81, 0x02, 0x40, 0x14, /* opcode: LOAD PCR4, #<20B data> */
1031        0x48, 0xfd, 0x95, 0x17, 0xe7, 0x54, 0x6b, 0x68, /* data */
1032        0x92, 0x31, 0x18, 0x05, 0xf8, 0x58, 0x58, 0x3c, /* data */
1033        0xe4, 0xd2, 0x81, 0xe0, /* data */
1034};
1035
1036static const uint8_t prg_stage_fail[] = {
1037        0x81, 0x01, 0x00, 0x14, /* opcode: LOAD v0, #<20B data> */
1038        0xc0, 0x32, 0xad, 0xc1, 0xff, 0x62, 0x9c, 0x9b, /* data */
1039        0x66, 0xf2, 0x27, 0x49, 0xad, 0x66, 0x7e, 0x6b, /* data */
1040        0xea, 0xdf, 0x14, 0x4b, /* data */
1041        0x81, 0x42, 0x30, 0x00, /* opcode: LOAD PCR3, v0 */
1042        0x81, 0x42, 0x40, 0x00, /* opcode: LOAD PCR4, v0 */
1043};
1044
1045static int second_stage_init(void)
1046{
1047        static const char mac_suffix[] = ".mac";
1048        bool did_first_stage_run = true;
1049        int result = 0;
1050        char *cptr, *mmcdev = NULL;
1051        struct key_program *hmac_blob = NULL;
1052        const char *image_path = "/ccdm.itb";
1053        char *mac_path = NULL;
1054        ulong image_addr;
1055        loff_t image_size;
1056        struct udevice *tpm;
1057        uint32_t err;
1058        int ret;
1059
1060        printf("CCDM S2\n");
1061        ret = get_tpm(&tpm);
1062        if (ret || tpm_init(tpm))
1063                return 1;
1064        err = tpm_startup(tpm, TPM_ST_CLEAR);
1065        if (err != TPM_INVALID_POSTINIT)
1066                did_first_stage_run = false;
1067
1068#ifdef CCDM_AUTO_FIRST_STAGE
1069        if (!did_first_stage_run && first_stage_actions(tpm))
1070                goto failure;
1071#else
1072        if (!did_first_stage_run)
1073                goto failure;
1074#endif
1075
1076        if (hre_run_program(tpm, prg_stage2_prepare,
1077                            sizeof(prg_stage2_prepare)))
1078                goto failure;
1079
1080        /* run "prepboot" from env to get "mmcdev" set */
1081        cptr = env_get("prepboot");
1082        if (cptr && !run_command(cptr, 0))
1083                mmcdev = env_get("mmcdev");
1084        if (!mmcdev)
1085                goto failure;
1086
1087        cptr = env_get("ramdiskimage");
1088        if (cptr)
1089                image_path = cptr;
1090
1091        mac_path = malloc(strlen(image_path) + strlen(mac_suffix) + 1);
1092        if (mac_path == NULL)
1093                goto failure;
1094        strcpy(mac_path, image_path);
1095        strcat(mac_path, mac_suffix);
1096
1097        /* read image from mmcdev (ccdm.itb) */
1098        image_addr = (ulong)get_image_location();
1099        if (fs_set_blk_dev("mmc", mmcdev, FS_TYPE_EXT))
1100                goto failure;
1101        if (fs_read(image_path, image_addr, 0, 0, &image_size) < 0)
1102                goto failure;
1103        if (image_size <= 0)
1104                goto failure;
1105        printf("CCDM image found on %s, %lld bytes\n", mmcdev, image_size);
1106
1107        hmac_blob = load_key_chunk("mmc", mmcdev, FS_TYPE_EXT, mac_path);
1108        if (!hmac_blob) {
1109                puts("failed to load mac file\n");
1110                goto failure;
1111        }
1112        if (verify_program(hmac_blob)) {
1113                puts("corrupted mac file\n");
1114                goto failure;
1115        }
1116        if (check_hmac(hmac_blob, (u8 *)image_addr, image_size)) {
1117                puts("image integrity could not be verified\n");
1118                goto failure;
1119        }
1120        puts("CCDM image OK\n");
1121
1122        hre_run_program(tpm, prg_stage2_success, sizeof(prg_stage2_success));
1123
1124        goto end;
1125failure:
1126        result = 1;
1127        hre_run_program(tpm, prg_stage_fail, sizeof(prg_stage_fail));
1128end:
1129        if (hmac_blob)
1130                free(hmac_blob);
1131        if (mac_path)
1132                free(mac_path);
1133
1134        return result;
1135}
1136#endif
1137
1138int show_self_hash(void)
1139{
1140        struct h_reg *hash_ptr;
1141#ifdef CCDM_SECOND_STAGE
1142        struct h_reg hash;
1143
1144        hash_ptr = &hash;
1145        if (compute_self_hash(hash_ptr))
1146                return 1;
1147#else
1148        hash_ptr = &fix_hregs[FIX_HREG_SELF_HASH];
1149#endif
1150        puts("self hash: ");
1151        if (hash_ptr && hash_ptr->valid)
1152                print_buffer(0, hash_ptr->digest, 1, 20, 20);
1153        else
1154                puts("INVALID\n");
1155
1156        return 0;
1157}
1158
1159/**
1160 * @brief let the system hang.
1161 *
1162 * Called on error.
1163 * Will stop the boot process; display a message and signal the error condition
1164 * by blinking the "status" and the "finder" LED of the controller board.
1165 *
1166 * @note the develop version runs the blink cycle 2 times and then returns.
1167 * The release version never returns.
1168 */
1169static void ccdm_hang(void)
1170{
1171        static const u64 f0 = 0x0ba3bb8ba2e880; /* blink code "finder" LED */
1172        static const u64 s0 = 0x00f0f0f0f0f0f0; /* blink code "status" LED */
1173        u64 f, s;
1174        int i;
1175#ifdef CCDM_DEVELOP
1176        int j;
1177#endif
1178
1179        I2C_SET_BUS(I2C_SOC_0);
1180        pca9698_direction_output(0x22, 0, 0); /* Finder */
1181        pca9698_direction_output(0x22, 4, 0); /* Status */
1182
1183        puts("### ERROR ### Please RESET the board ###\n");
1184        bootstage_error(BOOTSTAGE_ID_NEED_RESET);
1185#ifdef CCDM_DEVELOP
1186        puts("*** ERROR ******** THIS WOULD HANG ******** ERROR ***\n");
1187        puts("** but we continue since this is a DEVELOP version **\n");
1188        puts("*** ERROR ******** THIS WOULD HANG ******** ERROR ***\n");
1189        for (j = 2; j-- > 0;) {
1190                putc('#');
1191#else
1192        for (;;) {
1193#endif
1194                f = f0;
1195                s = s0;
1196                for (i = 54; i-- > 0;) {
1197                        pca9698_set_value(0x22, 0, !(f & 1));
1198                        pca9698_set_value(0x22, 4, (s & 1));
1199                        f >>= 1;
1200                        s >>= 1;
1201                        mdelay(120);
1202                }
1203        }
1204        puts("\ncontinue...\n");
1205}
1206
1207int startup_ccdm_id_module(void)
1208{
1209        int result = 0;
1210        unsigned int orig_i2c_bus;
1211
1212        orig_i2c_bus = i2c_get_bus_num();
1213        i2c_set_bus_num(I2C_SOC_1);
1214
1215        /* goto end; */
1216
1217#ifdef CCDM_DEVELOP
1218        show_self_hash();
1219#endif
1220#ifdef CCDM_FIRST_STAGE
1221        result = first_stage_init();
1222        if (result) {
1223                puts("1st stage init failed\n");
1224                goto failure;
1225        }
1226#endif
1227#ifdef CCDM_SECOND_STAGE
1228        result = second_stage_init();
1229        if (result) {
1230                puts("2nd stage init failed\n");
1231                goto failure;
1232        }
1233#endif
1234
1235        goto end;
1236failure:
1237        result = 1;
1238end:
1239        i2c_set_bus_num(orig_i2c_bus);
1240        if (result)
1241                ccdm_hang();
1242
1243        return result;
1244}
1245