|
23 | 23 | #include <asm/global_data.h>
|
24 | 24 | #include <asm/io.h>
|
25 | 25 | #include <linux/sizes.h>
|
| 26 | +#include <tpm-v2.h> |
26 | 27 | #if defined(CONFIG_CMD_USB)
|
27 | 28 | #include <usb.h>
|
28 | 29 | #endif
|
@@ -673,6 +674,75 @@ int bootm_process_cmdline_env(int flags)
|
673 | 674 | return 0;
|
674 | 675 | }
|
675 | 676 |
|
| 677 | +int bootm_measure(struct bootm_headers *images) |
| 678 | +{ |
| 679 | + int ret = 0; |
| 680 | + |
| 681 | + /* Skip measurement if EFI is going to do it */ |
| 682 | + if (images->os.os == IH_OS_EFI && |
| 683 | + IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL) && |
| 684 | + IS_ENABLED(CONFIG_BOOTM_EFI)) |
| 685 | + return ret; |
| 686 | + |
| 687 | + if (IS_ENABLED(CONFIG_MEASURED_BOOT)) { |
| 688 | + struct tcg2_event_log elog; |
| 689 | + struct udevice *dev; |
| 690 | + void *initrd_buf; |
| 691 | + void *image_buf; |
| 692 | + const char *s; |
| 693 | + u32 rd_len; |
| 694 | + bool ign; |
| 695 | + |
| 696 | + elog.log_size = 0; |
| 697 | + ign = IS_ENABLED(CONFIG_MEASURE_IGNORE_LOG); |
| 698 | + ret = tcg2_measurement_init(&dev, &elog, ign); |
| 699 | + if (ret) |
| 700 | + return ret; |
| 701 | + |
| 702 | + image_buf = map_sysmem(images->os.image_start, |
| 703 | + images->os.image_len); |
| 704 | + ret = tcg2_measure_data(dev, &elog, 8, images->os.image_len, |
| 705 | + image_buf, EV_COMPACT_HASH, |
| 706 | + strlen("linux") + 1, (u8 *)"linux"); |
| 707 | + if (ret) |
| 708 | + goto unmap_image; |
| 709 | + |
| 710 | + rd_len = images->rd_end - images->rd_start; |
| 711 | + initrd_buf = map_sysmem(images->rd_start, rd_len); |
| 712 | + ret = tcg2_measure_data(dev, &elog, 9, rd_len, initrd_buf, |
| 713 | + EV_COMPACT_HASH, strlen("initrd") + 1, |
| 714 | + (u8 *)"initrd"); |
| 715 | + if (ret) |
| 716 | + goto unmap_initrd; |
| 717 | + |
| 718 | + if (IS_ENABLED(CONFIG_MEASURE_DEVICETREE)) { |
| 719 | + ret = tcg2_measure_data(dev, &elog, 0, images->ft_len, |
| 720 | + (u8 *)images->ft_addr, |
| 721 | + EV_TABLE_OF_DEVICES, |
| 722 | + strlen("dts") + 1, |
| 723 | + (u8 *)"dts"); |
| 724 | + if (ret) |
| 725 | + goto unmap_initrd; |
| 726 | + } |
| 727 | + |
| 728 | + s = env_get("bootargs"); |
| 729 | + if (!s) |
| 730 | + s = ""; |
| 731 | + ret = tcg2_measure_data(dev, &elog, 1, strlen(s) + 1, (u8 *)s, |
| 732 | + EV_PLATFORM_CONFIG_FLAGS, |
| 733 | + strlen(s) + 1, (u8 *)s); |
| 734 | + |
| 735 | +unmap_initrd: |
| 736 | + unmap_sysmem(initrd_buf); |
| 737 | + |
| 738 | +unmap_image: |
| 739 | + unmap_sysmem(image_buf); |
| 740 | + tcg2_measurement_term(dev, &elog, ret != 0); |
| 741 | + } |
| 742 | + |
| 743 | + return ret; |
| 744 | +} |
| 745 | + |
676 | 746 | /**
|
677 | 747 | * Execute selected states of the bootm command.
|
678 | 748 | *
|
@@ -724,6 +794,10 @@ int do_bootm_states(struct cmd_tbl *cmdtp, int flag, int argc,
|
724 | 794 | if (!ret && (states & BOOTM_STATE_FINDOTHER))
|
725 | 795 | ret = bootm_find_other(cmdtp, flag, argc, argv);
|
726 | 796 |
|
| 797 | + if (IS_ENABLED(CONFIG_MEASURED_BOOT) && !ret && |
| 798 | + (states & BOOTM_STATE_MEASURE)) |
| 799 | + bootm_measure(images); |
| 800 | + |
727 | 801 | /* Load the OS */
|
728 | 802 | if (!ret && (states & BOOTM_STATE_LOADOS)) {
|
729 | 803 | iflag = bootm_disable_interrupts();
|
|
0 commit comments