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 <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
54enum {
55
56 NV_COMMON_DATA_INDEX = 0x40000001,
57
58 MAGIC_KEY_PROGRAM = 0x68726500,
59 MAGIC_HMAC = 0x68616300,
60 MAGIC_END_OF_CHAIN = 0x00000000,
61
62 NV_COMMON_DATA_MIN_SIZE = 3 * sizeof(uint64_t) + 2 * sizeof(uint16_t),
63};
64
65
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
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
110enum {
111
112 HRE_NOP = 0x00,
113 HRE_SYNC = HRE_NOP,
114 HRE_CHECK0 = 0x01,
115
116
117 HRE_LOAD = 0x81,
118
119 HRE_XOR = 0xC1,
120 HRE_AND = 0xC2,
121 HRE_OR = 0xC3,
122 HRE_EXTEND = 0xC4,
123 HRE_LOADKEY = 0xC5,
124};
125
126
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
169
170
171
172
173
174
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
233
234
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
251
252
253
254static u8 *get_image_location(void)
255{
256 ulong addr;
257
258 addr = env_get_ulong("loadaddr", 16, CONFIG_LOADADDR);
259 return (u8 *)(addr);
260}
261#endif
262
263
264
265
266
267
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
285 ptr = info + 6;
286
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
292 ptr += 6 + 3;
293
294 *size = get_unaligned_be32(ptr);
295 return 0;
296}
297
298
299
300
301
302
303
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
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
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
347
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
382
383
384
385
386
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
405
406
407
408
409
410
411
412
413
414
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
457
458
459
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
484
485
486
487
488
489
490
491
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
611
612 return 0;
613}
614
615
616
617
618
619
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
741
742
743
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
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
887
888
889
890
891
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,
949 0x00, 0x24, 0x00, 0x00,
950 0x01, 0x80, 0x00, 0x00,
951 0x81, 0x22, 0x00, 0x00,
952 0x01, 0x84, 0x00, 0x00,
953 0x81, 0x26, 0x10, 0x00,
954 0x01, 0x88, 0x00, 0x00,
955 0x81, 0x2a, 0x20, 0x00,
956 0x01, 0x8c, 0x00, 0x00,
957 0x81, 0x2e, 0x30, 0x00,
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,
1023 0x00, 0x84, 0x00, 0x00,
1024 0x00, 0x88, 0x00, 0x00,
1025 0x00, 0x8c, 0x00, 0x00,
1026 0x00, 0x90, 0x00, 0x00,
1027};
1028
1029static const uint8_t prg_stage2_success[] = {
1030 0x81, 0x02, 0x40, 0x14,
1031 0x48, 0xfd, 0x95, 0x17, 0xe7, 0x54, 0x6b, 0x68,
1032 0x92, 0x31, 0x18, 0x05, 0xf8, 0x58, 0x58, 0x3c,
1033 0xe4, 0xd2, 0x81, 0xe0,
1034};
1035
1036static const uint8_t prg_stage_fail[] = {
1037 0x81, 0x01, 0x00, 0x14,
1038 0xc0, 0x32, 0xad, 0xc1, 0xff, 0x62, 0x9c, 0x9b,
1039 0x66, 0xf2, 0x27, 0x49, 0xad, 0x66, 0x7e, 0x6b,
1040 0xea, 0xdf, 0x14, 0x4b,
1041 0x81, 0x42, 0x30, 0x00,
1042 0x81, 0x42, 0x40, 0x00,
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
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
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
1161
1162
1163
1164
1165
1166
1167
1168
1169static void ccdm_hang(void)
1170{
1171 static const u64 f0 = 0x0ba3bb8ba2e880;
1172 static const u64 s0 = 0x00f0f0f0f0f0f0;
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);
1181 pca9698_direction_output(0x22, 4, 0);
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
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