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