v86 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +17 -6
- package/bios/seabios/.config +113 -0
- package/bios/seabios/.config.old +114 -0
- package/bios/seabios/.gitignore +4 -0
- package/bios/seabios/COPYING +674 -0
- package/bios/seabios/COPYING.LESSER +165 -0
- package/bios/seabios/Makefile +286 -0
- package/bios/seabios/README +17 -0
- package/bios/seabios/docs/Build_overview.md +104 -0
- package/bios/seabios/docs/Contributing.md +20 -0
- package/bios/seabios/docs/Debugging.md +111 -0
- package/bios/seabios/docs/Developer_Documentation.md +25 -0
- package/bios/seabios/docs/Developer_links.md +86 -0
- package/bios/seabios/docs/Download.md +27 -0
- package/bios/seabios/docs/Execution_and_code_flow.md +178 -0
- package/bios/seabios/docs/Linking_overview.md +160 -0
- package/bios/seabios/docs/Mailinglist.md +8 -0
- package/bios/seabios/docs/Memory_Model.md +253 -0
- package/bios/seabios/docs/README +5 -0
- package/bios/seabios/docs/Releases.md +482 -0
- package/bios/seabios/docs/Runtime_config.md +193 -0
- package/bios/seabios/docs/SeaBIOS.md +17 -0
- package/bios/seabios/docs/SeaVGABIOS.md +39 -0
- package/bios/seabios/out/autoconf.h +117 -0
- package/bios/seabios/out/include/config/acpi/dsdt.h +0 -0
- package/bios/seabios/out/include/config/acpi.h +0 -0
- package/bios/seabios/out/include/config/ahci.h +0 -0
- package/bios/seabios/out/include/config/apmbios.h +0 -0
- package/bios/seabios/out/include/config/ata/dma.h +0 -0
- package/bios/seabios/out/include/config/ata/pio32.h +0 -0
- package/bios/seabios/out/include/config/ata.h +0 -0
- package/bios/seabios/out/include/config/auto.conf +69 -0
- package/bios/seabios/out/include/config/auto.conf.cmd +9 -0
- package/bios/seabios/out/include/config/boot.h +0 -0
- package/bios/seabios/out/include/config/bootorder.h +0 -0
- package/bios/seabios/out/include/config/build/vgabios.h +0 -0
- package/bios/seabios/out/include/config/call32/smm.h +0 -0
- package/bios/seabios/out/include/config/cdrom/boot.h +0 -0
- package/bios/seabios/out/include/config/cdrom/emu.h +0 -0
- package/bios/seabios/out/include/config/debug/level.h +0 -0
- package/bios/seabios/out/include/config/drives.h +0 -0
- package/bios/seabios/out/include/config/entry/extrastack.h +0 -0
- package/bios/seabios/out/include/config/esp/scsi.h +0 -0
- package/bios/seabios/out/include/config/flash/floppy.h +0 -0
- package/bios/seabios/out/include/config/floppy.h +0 -0
- package/bios/seabios/out/include/config/fw/romfile/load.h +0 -0
- package/bios/seabios/out/include/config/hardware/irq.h +0 -0
- package/bios/seabios/out/include/config/kbd/call/int15/4f.h +0 -0
- package/bios/seabios/out/include/config/keyboard.h +0 -0
- package/bios/seabios/out/include/config/lpt.h +0 -0
- package/bios/seabios/out/include/config/lsi/scsi.h +0 -0
- package/bios/seabios/out/include/config/malloc/uppermemory.h +0 -0
- package/bios/seabios/out/include/config/megasas.h +0 -0
- package/bios/seabios/out/include/config/mouse.h +0 -0
- package/bios/seabios/out/include/config/mpt/scsi.h +0 -0
- package/bios/seabios/out/include/config/mptable.h +0 -0
- package/bios/seabios/out/include/config/mtrr/init.h +0 -0
- package/bios/seabios/out/include/config/optionroms.h +0 -0
- package/bios/seabios/out/include/config/override/pci/id.h +0 -0
- package/bios/seabios/out/include/config/pcibios.h +0 -0
- package/bios/seabios/out/include/config/pirtable.h +0 -0
- package/bios/seabios/out/include/config/pmm.h +0 -0
- package/bios/seabios/out/include/config/pmtimer.h +0 -0
- package/bios/seabios/out/include/config/pnpbios.h +0 -0
- package/bios/seabios/out/include/config/ps2port.h +0 -0
- package/bios/seabios/out/include/config/pvscsi.h +0 -0
- package/bios/seabios/out/include/config/qemu/hardware.h +0 -0
- package/bios/seabios/out/include/config/qemu.h +0 -0
- package/bios/seabios/out/include/config/rom/size.h +0 -0
- package/bios/seabios/out/include/config/rtc/timer.h +0 -0
- package/bios/seabios/out/include/config/s3/resume.h +0 -0
- package/bios/seabios/out/include/config/sdcard.h +0 -0
- package/bios/seabios/out/include/config/serial.h +0 -0
- package/bios/seabios/out/include/config/tcgbios.h +0 -0
- package/bios/seabios/out/include/config/threads.h +0 -0
- package/bios/seabios/out/include/config/tristate.conf +4 -0
- package/bios/seabios/out/include/config/tsc/timer.h +0 -0
- package/bios/seabios/out/include/config/use/smm.h +0 -0
- package/bios/seabios/out/include/config/vga/allocate/extra/stack.h +0 -0
- package/bios/seabios/out/include/config/vga/bochs/stdvga.h +0 -0
- package/bios/seabios/out/include/config/vga/bochs.h +0 -0
- package/bios/seabios/out/include/config/vga/did.h +0 -0
- package/bios/seabios/out/include/config/vga/extra/stack/size.h +0 -0
- package/bios/seabios/out/include/config/vga/fixup/asm.h +0 -0
- package/bios/seabios/out/include/config/vga/pci.h +0 -0
- package/bios/seabios/out/include/config/vga/stdvga/ports.h +0 -0
- package/bios/seabios/out/include/config/vga/vbe.h +0 -0
- package/bios/seabios/out/include/config/vga/vid.h +0 -0
- package/bios/seabios/out/include/config/vgahooks.h +0 -0
- package/bios/seabios/out/include/config/virtio/blk.h +0 -0
- package/bios/seabios/out/include/config/virtio/scsi.h +0 -0
- package/bios/seabios/out/include/config/xen.h +0 -0
- package/bios/seabios/out/scripts/kconfig/conf +0 -0
- package/bios/seabios/out/scripts/kconfig/conf.o +0 -0
- package/bios/seabios/out/scripts/kconfig/zconf.hash.c +289 -0
- package/bios/seabios/out/scripts/kconfig/zconf.lex.c +2420 -0
- package/bios/seabios/out/scripts/kconfig/zconf.tab.c +2538 -0
- package/bios/seabios/out/scripts/kconfig/zconf.tab.o +0 -0
- package/bios/seabios/scripts/acpi_extract.py +366 -0
- package/bios/seabios/scripts/acpi_extract_preprocess.py +41 -0
- package/bios/seabios/scripts/buildrom.py +56 -0
- package/bios/seabios/scripts/buildversion.py +134 -0
- package/bios/seabios/scripts/checkrom.py +95 -0
- package/bios/seabios/scripts/checkstack.py +226 -0
- package/bios/seabios/scripts/checksum.py +16 -0
- package/bios/seabios/scripts/encodeint.py +21 -0
- package/bios/seabios/scripts/gen-offsets.sh +17 -0
- package/bios/seabios/scripts/kconfig/.gitignore +22 -0
- package/bios/seabios/scripts/kconfig/Makefile +331 -0
- package/bios/seabios/scripts/kconfig/POTFILES.in +12 -0
- package/bios/seabios/scripts/kconfig/check.sh +13 -0
- package/bios/seabios/scripts/kconfig/conf.c +718 -0
- package/bios/seabios/scripts/kconfig/confdata.c +1250 -0
- package/bios/seabios/scripts/kconfig/expr.c +1168 -0
- package/bios/seabios/scripts/kconfig/expr.h +241 -0
- package/bios/seabios/scripts/kconfig/gconf.c +1542 -0
- package/bios/seabios/scripts/kconfig/gconf.glade +661 -0
- package/bios/seabios/scripts/kconfig/images.c +326 -0
- package/bios/seabios/scripts/kconfig/kxgettext.c +235 -0
- package/bios/seabios/scripts/kconfig/lex.zconf.c +2430 -0
- package/bios/seabios/scripts/kconfig/list.h +131 -0
- package/bios/seabios/scripts/kconfig/lkc.h +200 -0
- package/bios/seabios/scripts/kconfig/lkc_proto.h +57 -0
- package/bios/seabios/scripts/kconfig/lxdialog/.gitignore +4 -0
- package/bios/seabios/scripts/kconfig/lxdialog/BIG.FAT.WARNING +4 -0
- package/bios/seabios/scripts/kconfig/lxdialog/check-lxdialog.sh +87 -0
- package/bios/seabios/scripts/kconfig/lxdialog/checklist.c +332 -0
- package/bios/seabios/scripts/kconfig/lxdialog/dialog.h +257 -0
- package/bios/seabios/scripts/kconfig/lxdialog/inputbox.c +301 -0
- package/bios/seabios/scripts/kconfig/lxdialog/menubox.c +437 -0
- package/bios/seabios/scripts/kconfig/lxdialog/textbox.c +408 -0
- package/bios/seabios/scripts/kconfig/lxdialog/util.c +713 -0
- package/bios/seabios/scripts/kconfig/lxdialog/yesno.c +114 -0
- package/bios/seabios/scripts/kconfig/mconf.c +1036 -0
- package/bios/seabios/scripts/kconfig/menu.c +697 -0
- package/bios/seabios/scripts/kconfig/merge_config.sh +150 -0
- package/bios/seabios/scripts/kconfig/nconf.c +1556 -0
- package/bios/seabios/scripts/kconfig/nconf.gui.c +656 -0
- package/bios/seabios/scripts/kconfig/nconf.h +96 -0
- package/bios/seabios/scripts/kconfig/qconf.cc +1795 -0
- package/bios/seabios/scripts/kconfig/qconf.h +338 -0
- package/bios/seabios/scripts/kconfig/streamline_config.pl +647 -0
- package/bios/seabios/scripts/kconfig/symbol.c +1373 -0
- package/bios/seabios/scripts/kconfig/util.c +157 -0
- package/bios/seabios/scripts/kconfig/zconf.gperf +48 -0
- package/bios/seabios/scripts/kconfig/zconf.hash.c_shipped +289 -0
- package/bios/seabios/scripts/kconfig/zconf.l +363 -0
- package/bios/seabios/scripts/kconfig/zconf.lex.c_shipped +2420 -0
- package/bios/seabios/scripts/kconfig/zconf.tab.c_shipped +2538 -0
- package/bios/seabios/scripts/kconfig/zconf.y +733 -0
- package/bios/seabios/scripts/layoutrom.py +705 -0
- package/bios/seabios/scripts/python23compat.py +14 -0
- package/bios/seabios/scripts/readserial.py +190 -0
- package/bios/seabios/scripts/tarball.sh +36 -0
- package/bios/seabios/scripts/test-build.sh +90 -0
- package/bios/seabios/scripts/transdump.py +53 -0
- package/bios/seabios/scripts/vgafixup.py +96 -0
- package/bios/seabios/src/Kconfig +579 -0
- package/bios/seabios/src/apm.c +215 -0
- package/bios/seabios/src/asm-offsets.c +23 -0
- package/bios/seabios/src/biosvar.h +130 -0
- package/bios/seabios/src/block.c +623 -0
- package/bios/seabios/src/block.h +121 -0
- package/bios/seabios/src/bmp.c +117 -0
- package/bios/seabios/src/boot.c +793 -0
- package/bios/seabios/src/bootsplash.c +255 -0
- package/bios/seabios/src/bregs.h +80 -0
- package/bios/seabios/src/byteorder.h +71 -0
- package/bios/seabios/src/cdrom.c +322 -0
- package/bios/seabios/src/clock.c +506 -0
- package/bios/seabios/src/code16gcc.s +1 -0
- package/bios/seabios/src/config.h +108 -0
- package/bios/seabios/src/cp437.c +275 -0
- package/bios/seabios/src/cp437.h +1 -0
- package/bios/seabios/src/disk.c +779 -0
- package/bios/seabios/src/e820map.c +152 -0
- package/bios/seabios/src/e820map.h +26 -0
- package/bios/seabios/src/entryfuncs.S +165 -0
- package/bios/seabios/src/farptr.h +208 -0
- package/bios/seabios/src/font.c +139 -0
- package/bios/seabios/src/fw/acpi-dsdt-cpu-hotplug.dsl +78 -0
- package/bios/seabios/src/fw/acpi-dsdt-dbug.dsl +26 -0
- package/bios/seabios/src/fw/acpi-dsdt-hpet.dsl +36 -0
- package/bios/seabios/src/fw/acpi-dsdt-isa.dsl +102 -0
- package/bios/seabios/src/fw/acpi-dsdt-pci-crs.dsl +90 -0
- package/bios/seabios/src/fw/acpi-dsdt.dsl +342 -0
- package/bios/seabios/src/fw/acpi-dsdt.hex +554 -0
- package/bios/seabios/src/fw/acpi.c +685 -0
- package/bios/seabios/src/fw/biostables.c +491 -0
- package/bios/seabios/src/fw/coreboot.c +569 -0
- package/bios/seabios/src/fw/csm.c +347 -0
- package/bios/seabios/src/fw/dev-pci.h +52 -0
- package/bios/seabios/src/fw/dev-piix.h +29 -0
- package/bios/seabios/src/fw/dev-q35.h +52 -0
- package/bios/seabios/src/fw/lzmadecode.c +398 -0
- package/bios/seabios/src/fw/lzmadecode.h +67 -0
- package/bios/seabios/src/fw/mptable.c +197 -0
- package/bios/seabios/src/fw/mtrr.c +105 -0
- package/bios/seabios/src/fw/multiboot.c +111 -0
- package/bios/seabios/src/fw/paravirt.c +624 -0
- package/bios/seabios/src/fw/paravirt.h +63 -0
- package/bios/seabios/src/fw/pciinit.c +1187 -0
- package/bios/seabios/src/fw/pirtable.c +103 -0
- package/bios/seabios/src/fw/q35-acpi-dsdt.dsl +450 -0
- package/bios/seabios/src/fw/romfile_loader.c +259 -0
- package/bios/seabios/src/fw/romfile_loader.h +91 -0
- package/bios/seabios/src/fw/shadow.c +208 -0
- package/bios/seabios/src/fw/smbios.c +585 -0
- package/bios/seabios/src/fw/smm.c +269 -0
- package/bios/seabios/src/fw/smp.c +194 -0
- package/bios/seabios/src/fw/ssdt-misc.dsl +104 -0
- package/bios/seabios/src/fw/ssdt-misc.hex +88 -0
- package/bios/seabios/src/fw/ssdt-pcihp.dsl +36 -0
- package/bios/seabios/src/fw/ssdt-pcihp.hex +38 -0
- package/bios/seabios/src/fw/ssdt-proc.dsl +48 -0
- package/bios/seabios/src/fw/ssdt-proc.hex +35 -0
- package/bios/seabios/src/fw/xen.c +149 -0
- package/bios/seabios/src/fw/xen.h +125 -0
- package/bios/seabios/src/gen-defs.h +19 -0
- package/bios/seabios/src/hw/ahci.c +697 -0
- package/bios/seabios/src/hw/ahci.h +201 -0
- package/bios/seabios/src/hw/ata.c +1046 -0
- package/bios/seabios/src/hw/ata.h +163 -0
- package/bios/seabios/src/hw/blockcmd.c +372 -0
- package/bios/seabios/src/hw/blockcmd.h +114 -0
- package/bios/seabios/src/hw/dma.c +67 -0
- package/bios/seabios/src/hw/esp-scsi.c +241 -0
- package/bios/seabios/src/hw/esp-scsi.h +8 -0
- package/bios/seabios/src/hw/floppy.c +741 -0
- package/bios/seabios/src/hw/lsi-scsi.c +221 -0
- package/bios/seabios/src/hw/lsi-scsi.h +8 -0
- package/bios/seabios/src/hw/megasas.c +405 -0
- package/bios/seabios/src/hw/megasas.h +8 -0
- package/bios/seabios/src/hw/mpt-scsi.c +319 -0
- package/bios/seabios/src/hw/mpt-scsi.h +8 -0
- package/bios/seabios/src/hw/nvme-int.h +199 -0
- package/bios/seabios/src/hw/nvme.c +708 -0
- package/bios/seabios/src/hw/nvme.h +17 -0
- package/bios/seabios/src/hw/pci.c +133 -0
- package/bios/seabios/src/hw/pci.h +47 -0
- package/bios/seabios/src/hw/pci_ids.h +2632 -0
- package/bios/seabios/src/hw/pci_regs.h +556 -0
- package/bios/seabios/src/hw/pcidevice.c +192 -0
- package/bios/seabios/src/hw/pcidevice.h +76 -0
- package/bios/seabios/src/hw/pic.c +115 -0
- package/bios/seabios/src/hw/pic.h +60 -0
- package/bios/seabios/src/hw/ps2port.c +543 -0
- package/bios/seabios/src/hw/ps2port.h +67 -0
- package/bios/seabios/src/hw/pvscsi.c +333 -0
- package/bios/seabios/src/hw/pvscsi.h +8 -0
- package/bios/seabios/src/hw/ramdisk.c +108 -0
- package/bios/seabios/src/hw/rtc.c +100 -0
- package/bios/seabios/src/hw/rtc.h +75 -0
- package/bios/seabios/src/hw/sdcard.c +572 -0
- package/bios/seabios/src/hw/serialio.c +113 -0
- package/bios/seabios/src/hw/serialio.h +29 -0
- package/bios/seabios/src/hw/timer.c +259 -0
- package/bios/seabios/src/hw/tpm_drivers.c +636 -0
- package/bios/seabios/src/hw/tpm_drivers.h +127 -0
- package/bios/seabios/src/hw/usb-ehci.c +650 -0
- package/bios/seabios/src/hw/usb-ehci.h +177 -0
- package/bios/seabios/src/hw/usb-hid.c +442 -0
- package/bios/seabios/src/hw/usb-hid.h +29 -0
- package/bios/seabios/src/hw/usb-hub.c +205 -0
- package/bios/seabios/src/hw/usb-hub.h +64 -0
- package/bios/seabios/src/hw/usb-msc.c +222 -0
- package/bios/seabios/src/hw/usb-msc.h +10 -0
- package/bios/seabios/src/hw/usb-ohci.c +568 -0
- package/bios/seabios/src/hw/usb-ohci.h +144 -0
- package/bios/seabios/src/hw/usb-uas.c +289 -0
- package/bios/seabios/src/hw/usb-uas.h +9 -0
- package/bios/seabios/src/hw/usb-uhci.c +571 -0
- package/bios/seabios/src/hw/usb-uhci.h +128 -0
- package/bios/seabios/src/hw/usb-xhci.c +1161 -0
- package/bios/seabios/src/hw/usb-xhci.h +133 -0
- package/bios/seabios/src/hw/usb.c +499 -0
- package/bios/seabios/src/hw/usb.h +254 -0
- package/bios/seabios/src/hw/virtio-blk.c +211 -0
- package/bios/seabios/src/hw/virtio-blk.h +43 -0
- package/bios/seabios/src/hw/virtio-pci.c +501 -0
- package/bios/seabios/src/hw/virtio-pci.h +151 -0
- package/bios/seabios/src/hw/virtio-ring.c +147 -0
- package/bios/seabios/src/hw/virtio-ring.h +121 -0
- package/bios/seabios/src/hw/virtio-scsi.c +220 -0
- package/bios/seabios/src/hw/virtio-scsi.h +47 -0
- package/bios/seabios/src/jpeg.c +1055 -0
- package/bios/seabios/src/kbd.c +599 -0
- package/bios/seabios/src/list.h +91 -0
- package/bios/seabios/src/malloc.c +561 -0
- package/bios/seabios/src/malloc.h +70 -0
- package/bios/seabios/src/memmap.h +21 -0
- package/bios/seabios/src/misc.c +195 -0
- package/bios/seabios/src/mouse.c +342 -0
- package/bios/seabios/src/optionroms.c +475 -0
- package/bios/seabios/src/output.c +584 -0
- package/bios/seabios/src/output.h +68 -0
- package/bios/seabios/src/pcibios.c +241 -0
- package/bios/seabios/src/pmm.c +176 -0
- package/bios/seabios/src/pnpbios.c +88 -0
- package/bios/seabios/src/post.c +337 -0
- package/bios/seabios/src/resume.c +157 -0
- package/bios/seabios/src/romfile.c +146 -0
- package/bios/seabios/src/romfile.h +21 -0
- package/bios/seabios/src/romlayout.S +698 -0
- package/bios/seabios/src/sercon.c +677 -0
- package/bios/seabios/src/serial.c +317 -0
- package/bios/seabios/src/sha1.c +147 -0
- package/bios/seabios/src/sha1.h +8 -0
- package/bios/seabios/src/stacks.c +771 -0
- package/bios/seabios/src/stacks.h +68 -0
- package/bios/seabios/src/std/LegacyBios.h +985 -0
- package/bios/seabios/src/std/acpi.h +323 -0
- package/bios/seabios/src/std/bda.h +174 -0
- package/bios/seabios/src/std/disk.h +175 -0
- package/bios/seabios/src/std/mptable.h +77 -0
- package/bios/seabios/src/std/multiboot.h +260 -0
- package/bios/seabios/src/std/optionrom.h +59 -0
- package/bios/seabios/src/std/pirtable.h +35 -0
- package/bios/seabios/src/std/pmm.h +19 -0
- package/bios/seabios/src/std/pnpbios.h +24 -0
- package/bios/seabios/src/std/smbios.h +167 -0
- package/bios/seabios/src/std/tcg.h +554 -0
- package/bios/seabios/src/std/vbe.h +156 -0
- package/bios/seabios/src/std/vga.h +63 -0
- package/bios/seabios/src/string.c +251 -0
- package/bios/seabios/src/string.h +31 -0
- package/bios/seabios/src/system.c +357 -0
- package/bios/seabios/src/tcgbios.c +2014 -0
- package/bios/seabios/src/tcgbios.h +19 -0
- package/bios/seabios/src/types.h +156 -0
- package/bios/seabios/src/util.h +251 -0
- package/bios/seabios/src/version.c +5 -0
- package/bios/seabios/src/vgahooks.c +355 -0
- package/bios/seabios/src/x86.c +23 -0
- package/bios/seabios/src/x86.h +277 -0
- package/bios/seabios/vgasrc/Kconfig +211 -0
- package/bios/seabios/vgasrc/bochsdisplay.c +59 -0
- package/bios/seabios/vgasrc/bochsvga.c +447 -0
- package/bios/seabios/vgasrc/bochsvga.h +57 -0
- package/bios/seabios/vgasrc/cbvga.c +337 -0
- package/bios/seabios/vgasrc/clext.c +627 -0
- package/bios/seabios/vgasrc/geodevga.c +434 -0
- package/bios/seabios/vgasrc/geodevga.h +89 -0
- package/bios/seabios/vgasrc/ramfb.c +163 -0
- package/bios/seabios/vgasrc/stdvga.c +485 -0
- package/bios/seabios/vgasrc/stdvga.h +81 -0
- package/bios/seabios/vgasrc/stdvgaio.c +186 -0
- package/bios/seabios/vgasrc/stdvgamodes.c +534 -0
- package/bios/seabios/vgasrc/swcursor.c +96 -0
- package/bios/seabios/vgasrc/vbe.c +432 -0
- package/bios/seabios/vgasrc/vgabios.c +1131 -0
- package/bios/seabios/vgasrc/vgabios.h +88 -0
- package/bios/seabios/vgasrc/vgaentry.S +161 -0
- package/bios/seabios/vgasrc/vgafb.c +661 -0
- package/bios/seabios/vgasrc/vgafb.h +42 -0
- package/bios/seabios/vgasrc/vgafonts.c +785 -0
- package/bios/seabios/vgasrc/vgahw.h +152 -0
- package/bios/seabios/vgasrc/vgainit.c +202 -0
- package/bios/seabios/vgasrc/vgalayout.lds.S +23 -0
- package/bios/seabios/vgasrc/vgautil.h +103 -0
- package/bios/seabios/vgasrc/vgaversion.c +6 -0
- package/build/binaries.js +1 -1
- package/build/index-debug.cjs +1 -1
- package/build/index-debug.js +1 -1
- package/build/index.cjs +1 -1
- package/build/index.js +1 -1
- package/build/v86-debug.wasm +0 -0
- package/build/v86.wasm +0 -0
- package/package.json +1 -1
|
@@ -0,0 +1,2014 @@
|
|
|
1
|
+
// Implementation of the TCG BIOS extension according to the specification
|
|
2
|
+
// described in specs found at
|
|
3
|
+
// http://www.trustedcomputinggroup.org/resources/pc_client_work_group_specific_implementation_specification_for_conventional_bios
|
|
4
|
+
//
|
|
5
|
+
// Copyright (C) 2006-2011, 2014, 2015 IBM Corporation
|
|
6
|
+
//
|
|
7
|
+
// Authors:
|
|
8
|
+
// Stefan Berger <stefanb@linux.vnet.ibm.com>
|
|
9
|
+
//
|
|
10
|
+
// This file may be distributed under the terms of the GNU LGPLv3 license.
|
|
11
|
+
|
|
12
|
+
#include "bregs.h" // struct bregs
|
|
13
|
+
#include "byteorder.h" // cpu_to_*
|
|
14
|
+
#include "config.h" // CONFIG_TCGBIOS
|
|
15
|
+
#include "farptr.h" // MAKE_FLATPTR
|
|
16
|
+
#include "fw/paravirt.h" // runningOnXen
|
|
17
|
+
#include "hw/tpm_drivers.h" // tpm_drivers[]
|
|
18
|
+
#include "output.h" // dprintf
|
|
19
|
+
#include "sha1.h" // sha1
|
|
20
|
+
#include "std/acpi.h" // RSDP_SIGNATURE, rsdt_descriptor
|
|
21
|
+
#include "std/smbios.h" // struct smbios_entry_point
|
|
22
|
+
#include "std/tcg.h" // TCG_PC_LOGOVERFLOW
|
|
23
|
+
#include "string.h" // checksum
|
|
24
|
+
#include "tcgbios.h"// tpm_*, prototypes
|
|
25
|
+
#include "util.h" // printf, get_keystroke
|
|
26
|
+
#include "stacks.h" // wait_threads, reset
|
|
27
|
+
#include "malloc.h" // malloc_high
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
/****************************************************************
|
|
31
|
+
* ACPI TCPA table interface
|
|
32
|
+
****************************************************************/
|
|
33
|
+
|
|
34
|
+
struct {
|
|
35
|
+
/* length of the TCPA log buffer */
|
|
36
|
+
u32 log_area_minimum_length;
|
|
37
|
+
|
|
38
|
+
/* start address of TCPA log buffer */
|
|
39
|
+
u8 * log_area_start_address;
|
|
40
|
+
|
|
41
|
+
/* number of log entries written */
|
|
42
|
+
u32 entry_count;
|
|
43
|
+
|
|
44
|
+
/* address to write next log entry to */
|
|
45
|
+
u8 * log_area_next_entry;
|
|
46
|
+
|
|
47
|
+
/* address of last entry written (need for TCG_StatusCheck) */
|
|
48
|
+
u8 * log_area_last_entry;
|
|
49
|
+
} tpm_state VARLOW;
|
|
50
|
+
|
|
51
|
+
static int tpm_set_log_area(u8 *log_area_start_address,
|
|
52
|
+
u32 log_area_minimum_length)
|
|
53
|
+
{
|
|
54
|
+
if (!log_area_start_address || !log_area_minimum_length)
|
|
55
|
+
return -1;
|
|
56
|
+
|
|
57
|
+
memset(log_area_start_address, 0, log_area_minimum_length);
|
|
58
|
+
tpm_state.log_area_start_address = log_area_start_address;
|
|
59
|
+
tpm_state.log_area_minimum_length = log_area_minimum_length;
|
|
60
|
+
tpm_state.log_area_next_entry = log_area_start_address;
|
|
61
|
+
tpm_state.log_area_last_entry = NULL;
|
|
62
|
+
tpm_state.entry_count = 0;
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static int
|
|
67
|
+
tpm_tcpa_probe(void)
|
|
68
|
+
{
|
|
69
|
+
struct tcpa_descriptor_rev2 *tcpa = find_acpi_table(TCPA_SIGNATURE);
|
|
70
|
+
if (!tcpa)
|
|
71
|
+
return -1;
|
|
72
|
+
|
|
73
|
+
dprintf(DEBUG_tcg, "TCGBIOS: TCPA: LASA = %p, LAML = %u\n",
|
|
74
|
+
(u8 *)(long)tcpa->log_area_start_address,
|
|
75
|
+
tcpa->log_area_minimum_length);
|
|
76
|
+
|
|
77
|
+
return tpm_set_log_area((u8*)(long)tcpa->log_area_start_address,
|
|
78
|
+
tcpa->log_area_minimum_length);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static int
|
|
82
|
+
tpm_tpm2_probe(void)
|
|
83
|
+
{
|
|
84
|
+
struct tpm2_descriptor_rev2 *tpm2 = find_acpi_table(TPM2_SIGNATURE);
|
|
85
|
+
if (!tpm2)
|
|
86
|
+
return -1;
|
|
87
|
+
|
|
88
|
+
if (tpm2->length < 76)
|
|
89
|
+
return -1;
|
|
90
|
+
|
|
91
|
+
dprintf(DEBUG_tcg, "TCGBIOS: TPM2: LASA = %p, LAML = %u\n",
|
|
92
|
+
(u8 *)(long)tpm2->log_area_start_address,
|
|
93
|
+
tpm2->log_area_minimum_length);
|
|
94
|
+
|
|
95
|
+
return tpm_set_log_area((u8*)(long)tpm2->log_area_start_address,
|
|
96
|
+
tpm2->log_area_minimum_length);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/*
|
|
100
|
+
* Extend the ACPI log with the given entry by copying the
|
|
101
|
+
* entry data into the log.
|
|
102
|
+
* Input
|
|
103
|
+
* entry : The header data to use (including the variable length digest)
|
|
104
|
+
* digest_len : Length of the digest in 'entry'
|
|
105
|
+
* event : Pointer to the event body to be copied into the log
|
|
106
|
+
* event_len : Length of 'event'
|
|
107
|
+
*
|
|
108
|
+
* Output:
|
|
109
|
+
* Returns an error code in case of faiure, 0 in case of success
|
|
110
|
+
*/
|
|
111
|
+
static int
|
|
112
|
+
tpm_log_event(struct tpm_log_header *entry, int digest_len
|
|
113
|
+
, const void *event, int event_len)
|
|
114
|
+
{
|
|
115
|
+
dprintf(DEBUG_tcg, "TCGBIOS: LASA = %p, next entry = %p\n",
|
|
116
|
+
tpm_state.log_area_start_address, tpm_state.log_area_next_entry);
|
|
117
|
+
|
|
118
|
+
if (tpm_state.log_area_next_entry == NULL)
|
|
119
|
+
return -1;
|
|
120
|
+
|
|
121
|
+
u32 size = (sizeof(*entry) + digest_len
|
|
122
|
+
+ sizeof(struct tpm_log_trailer) + event_len);
|
|
123
|
+
u32 logsize = (tpm_state.log_area_next_entry + size
|
|
124
|
+
- tpm_state.log_area_start_address);
|
|
125
|
+
if (logsize > tpm_state.log_area_minimum_length) {
|
|
126
|
+
dprintf(DEBUG_tcg, "TCGBIOS: LOG OVERFLOW: size = %d\n", size);
|
|
127
|
+
return -1;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
void *dest = tpm_state.log_area_next_entry;
|
|
131
|
+
memcpy(dest, entry, sizeof(*entry) + digest_len);
|
|
132
|
+
struct tpm_log_trailer *t = dest + sizeof(*entry) + digest_len;
|
|
133
|
+
t->eventdatasize = event_len;
|
|
134
|
+
memcpy(t->event, event, event_len);
|
|
135
|
+
|
|
136
|
+
tpm_state.log_area_last_entry = tpm_state.log_area_next_entry;
|
|
137
|
+
tpm_state.log_area_next_entry += size;
|
|
138
|
+
tpm_state.entry_count++;
|
|
139
|
+
|
|
140
|
+
return 0;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
/****************************************************************
|
|
145
|
+
* Digest formatting
|
|
146
|
+
****************************************************************/
|
|
147
|
+
|
|
148
|
+
static TPMVersion TPM_version;
|
|
149
|
+
static u32 tpm20_pcr_selection_size;
|
|
150
|
+
static struct tpml_pcr_selection *tpm20_pcr_selection;
|
|
151
|
+
|
|
152
|
+
// A 'struct tpm_log_entry' is a local data structure containing a
|
|
153
|
+
// 'tpm_log_header' followed by space for the maximum supported
|
|
154
|
+
// digest. (The digest is a sha1 hash on tpm1.2 or a series of
|
|
155
|
+
// tpm2_digest_value structs on tpm2.0)
|
|
156
|
+
struct tpm_log_entry {
|
|
157
|
+
struct tpm_log_header hdr;
|
|
158
|
+
u8 pad[sizeof(struct tpm2_digest_values)
|
|
159
|
+
+ 5 * sizeof(struct tpm2_digest_value)
|
|
160
|
+
+ SHA1_BUFSIZE + SHA256_BUFSIZE + SHA384_BUFSIZE
|
|
161
|
+
+ SHA512_BUFSIZE + SM3_256_BUFSIZE];
|
|
162
|
+
} PACKED;
|
|
163
|
+
|
|
164
|
+
static int
|
|
165
|
+
tpm20_get_hash_buffersize(u16 hashAlg)
|
|
166
|
+
{
|
|
167
|
+
switch (hashAlg) {
|
|
168
|
+
case TPM2_ALG_SHA1:
|
|
169
|
+
return SHA1_BUFSIZE;
|
|
170
|
+
case TPM2_ALG_SHA256:
|
|
171
|
+
return SHA256_BUFSIZE;
|
|
172
|
+
case TPM2_ALG_SHA384:
|
|
173
|
+
return SHA384_BUFSIZE;
|
|
174
|
+
case TPM2_ALG_SHA512:
|
|
175
|
+
return SHA512_BUFSIZE;
|
|
176
|
+
case TPM2_ALG_SM3_256:
|
|
177
|
+
return SM3_256_BUFSIZE;
|
|
178
|
+
default:
|
|
179
|
+
return -1;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Add an entry at the start of the log describing digest formats
|
|
184
|
+
static int
|
|
185
|
+
tpm20_write_EfiSpecIdEventStruct(void)
|
|
186
|
+
{
|
|
187
|
+
if (!tpm20_pcr_selection)
|
|
188
|
+
return -1;
|
|
189
|
+
|
|
190
|
+
struct {
|
|
191
|
+
struct TCG_EfiSpecIdEventStruct hdr;
|
|
192
|
+
u8 pad[256];
|
|
193
|
+
} event = {
|
|
194
|
+
.hdr.signature = "Spec ID Event03",
|
|
195
|
+
.hdr.platformClass = TPM_TCPA_ACPI_CLASS_CLIENT,
|
|
196
|
+
.hdr.specVersionMinor = 0,
|
|
197
|
+
.hdr.specVersionMajor = 2,
|
|
198
|
+
.hdr.specErrata = 0,
|
|
199
|
+
.hdr.uintnSize = 2,
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
struct tpms_pcr_selection *sel = tpm20_pcr_selection->selections;
|
|
203
|
+
void *nsel, *end = (void*)tpm20_pcr_selection + tpm20_pcr_selection_size;
|
|
204
|
+
|
|
205
|
+
u32 count;
|
|
206
|
+
for (count = 0; count < be32_to_cpu(tpm20_pcr_selection->count); count++) {
|
|
207
|
+
u8 sizeOfSelect = sel->sizeOfSelect;
|
|
208
|
+
|
|
209
|
+
nsel = (void*)sel + sizeof(*sel) + sizeOfSelect;
|
|
210
|
+
if (nsel > end)
|
|
211
|
+
break;
|
|
212
|
+
|
|
213
|
+
int hsize = tpm20_get_hash_buffersize(be16_to_cpu(sel->hashAlg));
|
|
214
|
+
if (hsize < 0) {
|
|
215
|
+
dprintf(DEBUG_tcg, "TPM is using an unsupported hash: %d\n",
|
|
216
|
+
be16_to_cpu(sel->hashAlg));
|
|
217
|
+
return -1;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
int event_size = offsetof(struct TCG_EfiSpecIdEventStruct
|
|
221
|
+
, digestSizes[count+1]);
|
|
222
|
+
if (event_size > sizeof(event) - sizeof(u32)) {
|
|
223
|
+
dprintf(DEBUG_tcg, "EfiSpecIdEventStruct pad too small\n");
|
|
224
|
+
return -1;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
event.hdr.digestSizes[count].algorithmId = be16_to_cpu(sel->hashAlg);
|
|
228
|
+
event.hdr.digestSizes[count].digestSize = hsize;
|
|
229
|
+
|
|
230
|
+
sel = nsel;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (sel != end) {
|
|
234
|
+
dprintf(DEBUG_tcg, "Malformed pcr selection structure fron TPM\n");
|
|
235
|
+
return -1;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
event.hdr.numberOfAlgorithms = count;
|
|
239
|
+
int event_size = offsetof(struct TCG_EfiSpecIdEventStruct
|
|
240
|
+
, digestSizes[count]);
|
|
241
|
+
u32 *vendorInfoSize = (void*)&event + event_size;
|
|
242
|
+
*vendorInfoSize = 0;
|
|
243
|
+
event_size += sizeof(*vendorInfoSize);
|
|
244
|
+
|
|
245
|
+
struct tpm_log_entry le = {
|
|
246
|
+
.hdr.eventtype = EV_NO_ACTION,
|
|
247
|
+
};
|
|
248
|
+
return tpm_log_event(&le.hdr, SHA1_BUFSIZE, &event, event_size);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/*
|
|
252
|
+
* Build the TPM2 tpm2_digest_values data structure from the given hash.
|
|
253
|
+
* Follow the PCR bank configuration of the TPM and write the same hash
|
|
254
|
+
* in either truncated or zero-padded form in the areas of all the other
|
|
255
|
+
* hashes. For example, write the sha1 hash in the area of the sha256
|
|
256
|
+
* hash and fill the remaining bytes with zeros. Or truncate the sha256
|
|
257
|
+
* hash when writing it in the area of the sha1 hash.
|
|
258
|
+
*
|
|
259
|
+
* le: the log entry to build the digest in
|
|
260
|
+
* sha1: the sha1 hash value to use
|
|
261
|
+
* bigEndian: whether to build in big endian format for the TPM or
|
|
262
|
+
* little endian for the log
|
|
263
|
+
*
|
|
264
|
+
* Returns the digest size; -1 on fatal error
|
|
265
|
+
*/
|
|
266
|
+
static int
|
|
267
|
+
tpm20_build_digest(struct tpm_log_entry *le, const u8 *sha1, int bigEndian)
|
|
268
|
+
{
|
|
269
|
+
if (!tpm20_pcr_selection)
|
|
270
|
+
return -1;
|
|
271
|
+
|
|
272
|
+
struct tpms_pcr_selection *sel = tpm20_pcr_selection->selections;
|
|
273
|
+
void *nsel, *end = (void*)tpm20_pcr_selection + tpm20_pcr_selection_size;
|
|
274
|
+
void *dest = le->hdr.digest + sizeof(struct tpm2_digest_values);
|
|
275
|
+
|
|
276
|
+
u32 count;
|
|
277
|
+
for (count = 0; count < be32_to_cpu(tpm20_pcr_selection->count); count++) {
|
|
278
|
+
u8 sizeOfSelect = sel->sizeOfSelect;
|
|
279
|
+
|
|
280
|
+
nsel = (void*)sel + sizeof(*sel) + sizeOfSelect;
|
|
281
|
+
if (nsel > end)
|
|
282
|
+
break;
|
|
283
|
+
|
|
284
|
+
int hsize = tpm20_get_hash_buffersize(be16_to_cpu(sel->hashAlg));
|
|
285
|
+
if (hsize < 0) {
|
|
286
|
+
dprintf(DEBUG_tcg, "TPM is using an unsupported hash: %d\n",
|
|
287
|
+
be16_to_cpu(sel->hashAlg));
|
|
288
|
+
return -1;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* buffer size sanity check before writing */
|
|
292
|
+
struct tpm2_digest_value *v = dest;
|
|
293
|
+
if (dest + sizeof(*v) + hsize > (void*)le + sizeof(*le)) {
|
|
294
|
+
dprintf(DEBUG_tcg, "tpm_log_entry is too small\n");
|
|
295
|
+
return -1;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (bigEndian)
|
|
299
|
+
v->hashAlg = sel->hashAlg;
|
|
300
|
+
else
|
|
301
|
+
v->hashAlg = be16_to_cpu(sel->hashAlg);
|
|
302
|
+
|
|
303
|
+
memset(v->hash, 0, hsize);
|
|
304
|
+
memcpy(v->hash, sha1, hsize > SHA1_BUFSIZE ? SHA1_BUFSIZE : hsize);
|
|
305
|
+
|
|
306
|
+
dest += sizeof(*v) + hsize;
|
|
307
|
+
sel = nsel;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (sel != end) {
|
|
311
|
+
dprintf(DEBUG_tcg, "Malformed pcr selection structure fron TPM\n");
|
|
312
|
+
return -1;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
struct tpm2_digest_values *v = (void*)le->hdr.digest;
|
|
316
|
+
if (bigEndian)
|
|
317
|
+
v->count = cpu_to_be32(count);
|
|
318
|
+
else
|
|
319
|
+
v->count = count;
|
|
320
|
+
|
|
321
|
+
return dest - (void*)le->hdr.digest;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
static int
|
|
325
|
+
tpm12_build_digest(struct tpm_log_entry *le, const u8 *sha1)
|
|
326
|
+
{
|
|
327
|
+
// On TPM 1.2 the digest contains just the SHA1 hash
|
|
328
|
+
memcpy(le->hdr.digest, sha1, SHA1_BUFSIZE);
|
|
329
|
+
return SHA1_BUFSIZE;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
static int
|
|
333
|
+
tpm_build_digest(struct tpm_log_entry *le, const u8 *sha1, int bigEndian)
|
|
334
|
+
{
|
|
335
|
+
switch (TPM_version) {
|
|
336
|
+
case TPM_VERSION_1_2:
|
|
337
|
+
return tpm12_build_digest(le, sha1);
|
|
338
|
+
case TPM_VERSION_2:
|
|
339
|
+
return tpm20_build_digest(le, sha1, bigEndian);
|
|
340
|
+
}
|
|
341
|
+
return -1;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
/****************************************************************
|
|
346
|
+
* TPM hardware command wrappers
|
|
347
|
+
****************************************************************/
|
|
348
|
+
|
|
349
|
+
// Helper function for sending tpm commands that take a single
|
|
350
|
+
// optional parameter (0, 1, or 2 bytes) and have no special response.
|
|
351
|
+
static int
|
|
352
|
+
tpm_simple_cmd(u8 locty, u32 ordinal
|
|
353
|
+
, int param_size, u16 param, enum tpmDurationType to_t)
|
|
354
|
+
{
|
|
355
|
+
struct {
|
|
356
|
+
struct tpm_req_header trqh;
|
|
357
|
+
u16 param;
|
|
358
|
+
} PACKED req = {
|
|
359
|
+
.trqh.totlen = cpu_to_be32(sizeof(req.trqh) + param_size),
|
|
360
|
+
.trqh.ordinal = cpu_to_be32(ordinal),
|
|
361
|
+
.param = param_size == 2 ? cpu_to_be16(param) : param,
|
|
362
|
+
};
|
|
363
|
+
switch (TPM_version) {
|
|
364
|
+
case TPM_VERSION_1_2:
|
|
365
|
+
req.trqh.tag = cpu_to_be16(TPM_TAG_RQU_CMD);
|
|
366
|
+
break;
|
|
367
|
+
case TPM_VERSION_2:
|
|
368
|
+
req.trqh.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS);
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
u8 obuffer[64];
|
|
373
|
+
struct tpm_rsp_header *trsh = (void*)obuffer;
|
|
374
|
+
u32 obuffer_len = sizeof(obuffer);
|
|
375
|
+
memset(obuffer, 0x0, sizeof(obuffer));
|
|
376
|
+
|
|
377
|
+
int ret = tpmhw_transmit(locty, &req.trqh, obuffer, &obuffer_len, to_t);
|
|
378
|
+
ret = ret ? -1 : be32_to_cpu(trsh->errcode);
|
|
379
|
+
dprintf(DEBUG_tcg, "Return from tpm_simple_cmd(%x, %x) = %x\n",
|
|
380
|
+
ordinal, param, ret);
|
|
381
|
+
return ret;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
static int
|
|
385
|
+
tpm20_getcapability(u32 capability, u32 property, u32 count,
|
|
386
|
+
struct tpm_rsp_header *rsp, u32 rsize)
|
|
387
|
+
{
|
|
388
|
+
struct tpm2_req_getcapability trg = {
|
|
389
|
+
.hdr.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
|
|
390
|
+
.hdr.totlen = cpu_to_be32(sizeof(trg)),
|
|
391
|
+
.hdr.ordinal = cpu_to_be32(TPM2_CC_GetCapability),
|
|
392
|
+
.capability = cpu_to_be32(capability),
|
|
393
|
+
.property = cpu_to_be32(property),
|
|
394
|
+
.propertycount = cpu_to_be32(count),
|
|
395
|
+
};
|
|
396
|
+
|
|
397
|
+
u32 resp_size = rsize;
|
|
398
|
+
int ret = tpmhw_transmit(0, &trg.hdr, rsp, &resp_size,
|
|
399
|
+
TPM_DURATION_TYPE_SHORT);
|
|
400
|
+
ret = (ret ||
|
|
401
|
+
rsize < be32_to_cpu(rsp->totlen)) ? -1 : be32_to_cpu(rsp->errcode);
|
|
402
|
+
|
|
403
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_GetCapability = 0x%08x\n",
|
|
404
|
+
ret);
|
|
405
|
+
|
|
406
|
+
return ret;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
static int
|
|
410
|
+
tpm20_get_pcrbanks(void)
|
|
411
|
+
{
|
|
412
|
+
u8 buffer[128];
|
|
413
|
+
struct tpm2_res_getcapability *trg =
|
|
414
|
+
(struct tpm2_res_getcapability *)&buffer;
|
|
415
|
+
|
|
416
|
+
int ret = tpm20_getcapability(TPM2_CAP_PCRS, 0, 8, &trg->hdr,
|
|
417
|
+
sizeof(buffer));
|
|
418
|
+
if (ret)
|
|
419
|
+
return ret;
|
|
420
|
+
|
|
421
|
+
u32 size = be32_to_cpu(trg->hdr.totlen) -
|
|
422
|
+
offsetof(struct tpm2_res_getcapability, data);
|
|
423
|
+
tpm20_pcr_selection = malloc_high(size);
|
|
424
|
+
if (tpm20_pcr_selection) {
|
|
425
|
+
memcpy(tpm20_pcr_selection, &trg->data, size);
|
|
426
|
+
tpm20_pcr_selection_size = size;
|
|
427
|
+
} else {
|
|
428
|
+
warn_noalloc();
|
|
429
|
+
ret = -1;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return ret;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
static int
|
|
436
|
+
tpm12_get_capability(u32 cap, u32 subcap, struct tpm_rsp_header *rsp, u32 rsize)
|
|
437
|
+
{
|
|
438
|
+
struct tpm_req_getcap trgc = {
|
|
439
|
+
.hdr.tag = cpu_to_be16(TPM_TAG_RQU_CMD),
|
|
440
|
+
.hdr.totlen = cpu_to_be32(sizeof(trgc)),
|
|
441
|
+
.hdr.ordinal = cpu_to_be32(TPM_ORD_GetCapability),
|
|
442
|
+
.capArea = cpu_to_be32(cap),
|
|
443
|
+
.subCapSize = cpu_to_be32(sizeof(trgc.subCap)),
|
|
444
|
+
.subCap = cpu_to_be32(subcap)
|
|
445
|
+
};
|
|
446
|
+
u32 resp_size = rsize;
|
|
447
|
+
int ret = tpmhw_transmit(0, &trgc.hdr, rsp, &resp_size,
|
|
448
|
+
TPM_DURATION_TYPE_SHORT);
|
|
449
|
+
ret = (ret || resp_size != rsize) ? -1 : be32_to_cpu(rsp->errcode);
|
|
450
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return code from TPM_GetCapability(%d, %d)"
|
|
451
|
+
" = %x\n", cap, subcap, ret);
|
|
452
|
+
return ret;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
static int
|
|
456
|
+
tpm12_read_permanent_flags(char *buf, int buf_len)
|
|
457
|
+
{
|
|
458
|
+
memset(buf, 0, buf_len);
|
|
459
|
+
|
|
460
|
+
struct tpm_res_getcap_perm_flags pf;
|
|
461
|
+
int ret = tpm12_get_capability(TPM_CAP_FLAG, TPM_CAP_FLAG_PERMANENT
|
|
462
|
+
, &pf.hdr, sizeof(pf));
|
|
463
|
+
if (ret)
|
|
464
|
+
return -1;
|
|
465
|
+
|
|
466
|
+
memcpy(buf, &pf.perm_flags, buf_len);
|
|
467
|
+
|
|
468
|
+
return 0;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
static int
|
|
472
|
+
tpm12_determine_timeouts(void)
|
|
473
|
+
{
|
|
474
|
+
struct tpm_res_getcap_timeouts timeouts;
|
|
475
|
+
int ret = tpm12_get_capability(TPM_CAP_PROPERTY, TPM_CAP_PROP_TIS_TIMEOUT
|
|
476
|
+
, &timeouts.hdr, sizeof(timeouts));
|
|
477
|
+
if (ret)
|
|
478
|
+
return ret;
|
|
479
|
+
|
|
480
|
+
struct tpm_res_getcap_durations durations;
|
|
481
|
+
ret = tpm12_get_capability(TPM_CAP_PROPERTY, TPM_CAP_PROP_DURATION
|
|
482
|
+
, &durations.hdr, sizeof(durations));
|
|
483
|
+
if (ret)
|
|
484
|
+
return ret;
|
|
485
|
+
|
|
486
|
+
int i;
|
|
487
|
+
for (i = 0; i < 3; i++)
|
|
488
|
+
durations.durations[i] = be32_to_cpu(durations.durations[i]);
|
|
489
|
+
|
|
490
|
+
for (i = 0; i < 4; i++)
|
|
491
|
+
timeouts.timeouts[i] = be32_to_cpu(timeouts.timeouts[i]);
|
|
492
|
+
|
|
493
|
+
dprintf(DEBUG_tcg, "TCGBIOS: timeouts: %u %u %u %u\n",
|
|
494
|
+
timeouts.timeouts[0],
|
|
495
|
+
timeouts.timeouts[1],
|
|
496
|
+
timeouts.timeouts[2],
|
|
497
|
+
timeouts.timeouts[3]);
|
|
498
|
+
|
|
499
|
+
dprintf(DEBUG_tcg, "TCGBIOS: durations: %u %u %u\n",
|
|
500
|
+
durations.durations[0],
|
|
501
|
+
durations.durations[1],
|
|
502
|
+
durations.durations[2]);
|
|
503
|
+
|
|
504
|
+
tpmhw_set_timeouts(timeouts.timeouts, durations.durations);
|
|
505
|
+
|
|
506
|
+
return 0;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
static void
|
|
510
|
+
tpm20_set_timeouts(void)
|
|
511
|
+
{
|
|
512
|
+
u32 durations[3] = {
|
|
513
|
+
TPM2_DEFAULT_DURATION_SHORT,
|
|
514
|
+
TPM2_DEFAULT_DURATION_MEDIUM,
|
|
515
|
+
TPM2_DEFAULT_DURATION_LONG,
|
|
516
|
+
};
|
|
517
|
+
u32 timeouts[4] = {
|
|
518
|
+
TIS2_DEFAULT_TIMEOUT_A,
|
|
519
|
+
TIS2_DEFAULT_TIMEOUT_B,
|
|
520
|
+
TIS2_DEFAULT_TIMEOUT_C,
|
|
521
|
+
TIS2_DEFAULT_TIMEOUT_D,
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
tpmhw_set_timeouts(timeouts, durations);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
static int
|
|
528
|
+
tpm12_extend(struct tpm_log_entry *le, int digest_len)
|
|
529
|
+
{
|
|
530
|
+
struct tpm_req_extend tre = {
|
|
531
|
+
.hdr.tag = cpu_to_be16(TPM_TAG_RQU_CMD),
|
|
532
|
+
.hdr.totlen = cpu_to_be32(sizeof(tre)),
|
|
533
|
+
.hdr.ordinal = cpu_to_be32(TPM_ORD_Extend),
|
|
534
|
+
.pcrindex = cpu_to_be32(le->hdr.pcrindex),
|
|
535
|
+
};
|
|
536
|
+
memcpy(tre.digest, le->hdr.digest, sizeof(tre.digest));
|
|
537
|
+
|
|
538
|
+
struct tpm_rsp_extend rsp;
|
|
539
|
+
u32 resp_length = sizeof(rsp);
|
|
540
|
+
int ret = tpmhw_transmit(0, &tre.hdr, &rsp, &resp_length,
|
|
541
|
+
TPM_DURATION_TYPE_SHORT);
|
|
542
|
+
if (ret || resp_length != sizeof(rsp) || rsp.hdr.errcode)
|
|
543
|
+
return -1;
|
|
544
|
+
|
|
545
|
+
return 0;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
static int tpm20_extend(struct tpm_log_entry *le, int digest_len)
|
|
549
|
+
{
|
|
550
|
+
struct tpm2_req_extend tmp_tre = {
|
|
551
|
+
.hdr.tag = cpu_to_be16(TPM2_ST_SESSIONS),
|
|
552
|
+
.hdr.totlen = cpu_to_be32(0),
|
|
553
|
+
.hdr.ordinal = cpu_to_be32(TPM2_CC_PCR_Extend),
|
|
554
|
+
.pcrindex = cpu_to_be32(le->hdr.pcrindex),
|
|
555
|
+
.authblocksize = cpu_to_be32(sizeof(tmp_tre.authblock)),
|
|
556
|
+
.authblock = {
|
|
557
|
+
.handle = cpu_to_be32(TPM2_RS_PW),
|
|
558
|
+
.noncesize = cpu_to_be16(0),
|
|
559
|
+
.contsession = TPM2_YES,
|
|
560
|
+
.pwdsize = cpu_to_be16(0),
|
|
561
|
+
},
|
|
562
|
+
};
|
|
563
|
+
u8 buffer[sizeof(tmp_tre) + sizeof(le->pad)];
|
|
564
|
+
struct tpm2_req_extend *tre = (struct tpm2_req_extend *)buffer;
|
|
565
|
+
|
|
566
|
+
memcpy(tre, &tmp_tre, sizeof(tmp_tre));
|
|
567
|
+
memcpy(&tre->digest[0], le->hdr.digest, digest_len);
|
|
568
|
+
|
|
569
|
+
tre->hdr.totlen = cpu_to_be32(sizeof(tmp_tre) + digest_len);
|
|
570
|
+
|
|
571
|
+
struct tpm_rsp_header rsp;
|
|
572
|
+
u32 resp_length = sizeof(rsp);
|
|
573
|
+
int ret = tpmhw_transmit(0, &tre->hdr, &rsp, &resp_length,
|
|
574
|
+
TPM_DURATION_TYPE_SHORT);
|
|
575
|
+
if (ret || resp_length != sizeof(rsp) || rsp.errcode)
|
|
576
|
+
return -1;
|
|
577
|
+
|
|
578
|
+
return 0;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
static int
|
|
582
|
+
tpm_extend(struct tpm_log_entry *le, int digest_len)
|
|
583
|
+
{
|
|
584
|
+
switch (TPM_version) {
|
|
585
|
+
case TPM_VERSION_1_2:
|
|
586
|
+
return tpm12_extend(le, digest_len);
|
|
587
|
+
case TPM_VERSION_2:
|
|
588
|
+
return tpm20_extend(le, digest_len);
|
|
589
|
+
}
|
|
590
|
+
return -1;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
static int
|
|
594
|
+
tpm20_stirrandom(void)
|
|
595
|
+
{
|
|
596
|
+
struct tpm2_req_stirrandom stir = {
|
|
597
|
+
.hdr.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
|
|
598
|
+
.hdr.totlen = cpu_to_be32(sizeof(stir)),
|
|
599
|
+
.hdr.ordinal = cpu_to_be32(TPM2_CC_StirRandom),
|
|
600
|
+
.size = cpu_to_be16(sizeof(stir.stir)),
|
|
601
|
+
.stir = rdtscll(),
|
|
602
|
+
};
|
|
603
|
+
/* set more bits to stir with */
|
|
604
|
+
stir.stir += swab64(rdtscll());
|
|
605
|
+
|
|
606
|
+
struct tpm_rsp_header rsp;
|
|
607
|
+
u32 resp_length = sizeof(rsp);
|
|
608
|
+
int ret = tpmhw_transmit(0, &stir.hdr, &rsp, &resp_length,
|
|
609
|
+
TPM_DURATION_TYPE_SHORT);
|
|
610
|
+
if (ret || resp_length != sizeof(rsp) || rsp.errcode)
|
|
611
|
+
ret = -1;
|
|
612
|
+
|
|
613
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_StirRandom = 0x%08x\n",
|
|
614
|
+
ret);
|
|
615
|
+
|
|
616
|
+
return ret;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
static int
|
|
620
|
+
tpm20_getrandom(u8 *buf, u16 buf_len)
|
|
621
|
+
{
|
|
622
|
+
struct tpm2_res_getrandom rsp;
|
|
623
|
+
|
|
624
|
+
if (buf_len > sizeof(rsp.rnd.buffer))
|
|
625
|
+
return -1;
|
|
626
|
+
|
|
627
|
+
struct tpm2_req_getrandom trgr = {
|
|
628
|
+
.hdr.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
|
|
629
|
+
.hdr.totlen = cpu_to_be32(sizeof(trgr)),
|
|
630
|
+
.hdr.ordinal = cpu_to_be32(TPM2_CC_GetRandom),
|
|
631
|
+
.bytesRequested = cpu_to_be16(buf_len),
|
|
632
|
+
};
|
|
633
|
+
u32 resp_length = sizeof(rsp);
|
|
634
|
+
|
|
635
|
+
int ret = tpmhw_transmit(0, &trgr.hdr, &rsp, &resp_length,
|
|
636
|
+
TPM_DURATION_TYPE_MEDIUM);
|
|
637
|
+
if (ret || resp_length != sizeof(rsp) || rsp.hdr.errcode)
|
|
638
|
+
ret = -1;
|
|
639
|
+
else
|
|
640
|
+
memcpy(buf, rsp.rnd.buffer, buf_len);
|
|
641
|
+
|
|
642
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_GetRandom = 0x%08x\n",
|
|
643
|
+
ret);
|
|
644
|
+
|
|
645
|
+
return ret;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
static int
|
|
649
|
+
tpm20_hierarchycontrol(u32 hierarchy, u8 state)
|
|
650
|
+
{
|
|
651
|
+
/* we will try to deactivate the TPM now - ignoring all errors */
|
|
652
|
+
struct tpm2_req_hierarchycontrol trh = {
|
|
653
|
+
.hdr.tag = cpu_to_be16(TPM2_ST_SESSIONS),
|
|
654
|
+
.hdr.totlen = cpu_to_be32(sizeof(trh)),
|
|
655
|
+
.hdr.ordinal = cpu_to_be32(TPM2_CC_HierarchyControl),
|
|
656
|
+
.authhandle = cpu_to_be32(TPM2_RH_PLATFORM),
|
|
657
|
+
.authblocksize = cpu_to_be32(sizeof(trh.authblock)),
|
|
658
|
+
.authblock = {
|
|
659
|
+
.handle = cpu_to_be32(TPM2_RS_PW),
|
|
660
|
+
.noncesize = cpu_to_be16(0),
|
|
661
|
+
.contsession = TPM2_YES,
|
|
662
|
+
.pwdsize = cpu_to_be16(0),
|
|
663
|
+
},
|
|
664
|
+
.enable = cpu_to_be32(hierarchy),
|
|
665
|
+
.state = state,
|
|
666
|
+
};
|
|
667
|
+
struct tpm_rsp_header rsp;
|
|
668
|
+
u32 resp_length = sizeof(rsp);
|
|
669
|
+
int ret = tpmhw_transmit(0, &trh.hdr, &rsp, &resp_length,
|
|
670
|
+
TPM_DURATION_TYPE_MEDIUM);
|
|
671
|
+
if (ret || resp_length != sizeof(rsp) || rsp.errcode)
|
|
672
|
+
ret = -1;
|
|
673
|
+
|
|
674
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_HierarchyControl = 0x%08x\n",
|
|
675
|
+
ret);
|
|
676
|
+
|
|
677
|
+
return ret;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
static int
|
|
681
|
+
tpm20_hierarchychangeauth(u8 auth[20])
|
|
682
|
+
{
|
|
683
|
+
struct tpm2_req_hierarchychangeauth trhca = {
|
|
684
|
+
.hdr.tag = cpu_to_be16(TPM2_ST_SESSIONS),
|
|
685
|
+
.hdr.totlen = cpu_to_be32(sizeof(trhca)),
|
|
686
|
+
.hdr.ordinal = cpu_to_be32(TPM2_CC_HierarchyChangeAuth),
|
|
687
|
+
.authhandle = cpu_to_be32(TPM2_RH_PLATFORM),
|
|
688
|
+
.authblocksize = cpu_to_be32(sizeof(trhca.authblock)),
|
|
689
|
+
.authblock = {
|
|
690
|
+
.handle = cpu_to_be32(TPM2_RS_PW),
|
|
691
|
+
.noncesize = cpu_to_be16(0),
|
|
692
|
+
.contsession = TPM2_YES,
|
|
693
|
+
.pwdsize = cpu_to_be16(0),
|
|
694
|
+
},
|
|
695
|
+
.newAuth = {
|
|
696
|
+
.size = cpu_to_be16(sizeof(trhca.newAuth.buffer)),
|
|
697
|
+
},
|
|
698
|
+
};
|
|
699
|
+
memcpy(trhca.newAuth.buffer, auth, sizeof(trhca.newAuth.buffer));
|
|
700
|
+
|
|
701
|
+
struct tpm_rsp_header rsp;
|
|
702
|
+
u32 resp_length = sizeof(rsp);
|
|
703
|
+
int ret = tpmhw_transmit(0, &trhca.hdr, &rsp, &resp_length,
|
|
704
|
+
TPM_DURATION_TYPE_MEDIUM);
|
|
705
|
+
if (ret || resp_length != sizeof(rsp) || rsp.errcode)
|
|
706
|
+
ret = -1;
|
|
707
|
+
|
|
708
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_HierarchyChangeAuth = 0x%08x\n",
|
|
709
|
+
ret);
|
|
710
|
+
|
|
711
|
+
return ret;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
/****************************************************************
|
|
716
|
+
* Setup and Measurements
|
|
717
|
+
****************************************************************/
|
|
718
|
+
|
|
719
|
+
static int TPM_has_physical_presence;
|
|
720
|
+
u8 TPM_working VARLOW;
|
|
721
|
+
|
|
722
|
+
static int
|
|
723
|
+
tpm_is_working(void)
|
|
724
|
+
{
|
|
725
|
+
return CONFIG_TCGBIOS && TPM_working;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
static void
|
|
729
|
+
tpm_set_failure(void)
|
|
730
|
+
{
|
|
731
|
+
switch (TPM_version) {
|
|
732
|
+
case TPM_VERSION_1_2:
|
|
733
|
+
/*
|
|
734
|
+
* We will try to deactivate the TPM now - ignoring all errors
|
|
735
|
+
* Physical presence is asserted.
|
|
736
|
+
*/
|
|
737
|
+
|
|
738
|
+
tpm_simple_cmd(0, TPM_ORD_SetTempDeactivated,
|
|
739
|
+
0, 0, TPM_DURATION_TYPE_SHORT);
|
|
740
|
+
break;
|
|
741
|
+
case TPM_VERSION_2:
|
|
742
|
+
tpm20_hierarchycontrol(TPM2_RH_ENDORSEMENT, TPM2_NO);
|
|
743
|
+
tpm20_hierarchycontrol(TPM2_RH_OWNER, TPM2_NO);
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
TPM_working = 0;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
/*
|
|
751
|
+
* Add a measurement to the log; the data at data_seg:data/length are
|
|
752
|
+
* appended to the TCG_PCClientPCREventStruct
|
|
753
|
+
*
|
|
754
|
+
* Input parameters:
|
|
755
|
+
* pcrindex : which PCR to extend
|
|
756
|
+
* event_type : type of event; specs section on 'Event Types'
|
|
757
|
+
* event : pointer to info (e.g., string) to be added to log as-is
|
|
758
|
+
* event_length: length of the event
|
|
759
|
+
* hashdata : pointer to the data to be hashed
|
|
760
|
+
* hashdata_length: length of the data to be hashed
|
|
761
|
+
*/
|
|
762
|
+
static void
|
|
763
|
+
tpm_add_measurement_to_log(u32 pcrindex, u32 event_type,
|
|
764
|
+
const char *event, u32 event_length,
|
|
765
|
+
const u8 *hashdata, u32 hashdata_length)
|
|
766
|
+
{
|
|
767
|
+
if (!tpm_is_working())
|
|
768
|
+
return;
|
|
769
|
+
|
|
770
|
+
u8 hash[SHA1_BUFSIZE];
|
|
771
|
+
sha1(hashdata, hashdata_length, hash);
|
|
772
|
+
|
|
773
|
+
struct tpm_log_entry le = {
|
|
774
|
+
.hdr.pcrindex = pcrindex,
|
|
775
|
+
.hdr.eventtype = event_type,
|
|
776
|
+
};
|
|
777
|
+
int digest_len = tpm_build_digest(&le, hash, 1);
|
|
778
|
+
if (digest_len < 0)
|
|
779
|
+
return;
|
|
780
|
+
int ret = tpm_extend(&le, digest_len);
|
|
781
|
+
if (ret) {
|
|
782
|
+
tpm_set_failure();
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
tpm_build_digest(&le, hash, 0);
|
|
786
|
+
tpm_log_event(&le.hdr, digest_len, event, event_length);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
// Add an EV_ACTION measurement to the list of measurements
|
|
790
|
+
static void
|
|
791
|
+
tpm_add_action(u32 pcrIndex, const char *string)
|
|
792
|
+
{
|
|
793
|
+
u32 len = strlen(string);
|
|
794
|
+
tpm_add_measurement_to_log(pcrIndex, EV_ACTION,
|
|
795
|
+
string, len, (u8 *)string, len);
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
/*
|
|
799
|
+
* Add event separators for PCRs 0 to 7; specs on 'Measuring Boot Events'
|
|
800
|
+
*/
|
|
801
|
+
static void
|
|
802
|
+
tpm_add_event_separators(void)
|
|
803
|
+
{
|
|
804
|
+
static const u8 evt_separator[] = {0xff,0xff,0xff,0xff};
|
|
805
|
+
u32 pcrIndex;
|
|
806
|
+
for (pcrIndex = 0; pcrIndex <= 7; pcrIndex++)
|
|
807
|
+
tpm_add_measurement_to_log(pcrIndex, EV_SEPARATOR,
|
|
808
|
+
NULL, 0,
|
|
809
|
+
evt_separator,
|
|
810
|
+
sizeof(evt_separator));
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
static void
|
|
814
|
+
tpm_smbios_measure(void)
|
|
815
|
+
{
|
|
816
|
+
struct pcctes pcctes = {
|
|
817
|
+
.eventid = 1,
|
|
818
|
+
.eventdatasize = SHA1_BUFSIZE,
|
|
819
|
+
};
|
|
820
|
+
struct smbios_entry_point *sep = SMBiosAddr;
|
|
821
|
+
|
|
822
|
+
dprintf(DEBUG_tcg, "TCGBIOS: SMBIOS at %p\n", sep);
|
|
823
|
+
|
|
824
|
+
if (!sep)
|
|
825
|
+
return;
|
|
826
|
+
|
|
827
|
+
sha1((const u8 *)sep->structure_table_address,
|
|
828
|
+
sep->structure_table_length, pcctes.digest);
|
|
829
|
+
tpm_add_measurement_to_log(1,
|
|
830
|
+
EV_EVENT_TAG,
|
|
831
|
+
(const char *)&pcctes, sizeof(pcctes),
|
|
832
|
+
(u8 *)&pcctes, sizeof(pcctes));
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
static int
|
|
836
|
+
tpm12_assert_physical_presence(void)
|
|
837
|
+
{
|
|
838
|
+
int ret = tpm_simple_cmd(0, TPM_ORD_PhysicalPresence,
|
|
839
|
+
2, TPM_PP_PRESENT, TPM_DURATION_TYPE_SHORT);
|
|
840
|
+
if (!ret)
|
|
841
|
+
return 0;
|
|
842
|
+
|
|
843
|
+
struct tpm_permanent_flags pf;
|
|
844
|
+
ret = tpm12_read_permanent_flags((char *)&pf, sizeof(pf));
|
|
845
|
+
if (ret)
|
|
846
|
+
return -1;
|
|
847
|
+
|
|
848
|
+
/* check if hardware physical presence is supported */
|
|
849
|
+
if (pf.flags[PERM_FLAG_IDX_PHYSICAL_PRESENCE_HW_ENABLE]) {
|
|
850
|
+
/* HW phys. presence may not be asserted... */
|
|
851
|
+
return 0;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
if (!pf.flags[PERM_FLAG_IDX_PHYSICAL_PRESENCE_LIFETIME_LOCK]
|
|
855
|
+
&& !pf.flags[PERM_FLAG_IDX_PHYSICAL_PRESENCE_CMD_ENABLE]) {
|
|
856
|
+
tpm_simple_cmd(0, TPM_ORD_PhysicalPresence,
|
|
857
|
+
2, TPM_PP_CMD_ENABLE, TPM_DURATION_TYPE_SHORT);
|
|
858
|
+
|
|
859
|
+
return tpm_simple_cmd(0, TPM_ORD_PhysicalPresence,
|
|
860
|
+
2, TPM_PP_PRESENT, TPM_DURATION_TYPE_SHORT);
|
|
861
|
+
}
|
|
862
|
+
return -1;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
static int
|
|
866
|
+
tpm12_startup(void)
|
|
867
|
+
{
|
|
868
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Starting with TPM_Startup(ST_CLEAR)\n");
|
|
869
|
+
int ret = tpm_simple_cmd(0, TPM_ORD_Startup,
|
|
870
|
+
2, TPM_ST_CLEAR, TPM_DURATION_TYPE_SHORT);
|
|
871
|
+
if (CONFIG_COREBOOT && ret == TPM_INVALID_POSTINIT)
|
|
872
|
+
/* with other firmware on the system the TPM may already have been
|
|
873
|
+
* initialized
|
|
874
|
+
*/
|
|
875
|
+
ret = 0;
|
|
876
|
+
if (ret)
|
|
877
|
+
goto err_exit;
|
|
878
|
+
|
|
879
|
+
/* assertion of physical presence is only possible after startup */
|
|
880
|
+
ret = tpm12_assert_physical_presence();
|
|
881
|
+
if (!ret)
|
|
882
|
+
TPM_has_physical_presence = 1;
|
|
883
|
+
|
|
884
|
+
ret = tpm12_determine_timeouts();
|
|
885
|
+
if (ret)
|
|
886
|
+
goto err_exit;
|
|
887
|
+
|
|
888
|
+
ret = tpm_simple_cmd(0, TPM_ORD_SelfTestFull,
|
|
889
|
+
0, 0, TPM_DURATION_TYPE_LONG);
|
|
890
|
+
if (ret)
|
|
891
|
+
goto err_exit;
|
|
892
|
+
|
|
893
|
+
ret = tpm_simple_cmd(3, TSC_ORD_ResetEstablishmentBit,
|
|
894
|
+
0, 0, TPM_DURATION_TYPE_SHORT);
|
|
895
|
+
if (ret && ret != TPM_BAD_LOCALITY)
|
|
896
|
+
goto err_exit;
|
|
897
|
+
|
|
898
|
+
return 0;
|
|
899
|
+
|
|
900
|
+
err_exit:
|
|
901
|
+
dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
|
|
902
|
+
|
|
903
|
+
tpm_set_failure();
|
|
904
|
+
return -1;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
static int
|
|
908
|
+
tpm20_startup(void)
|
|
909
|
+
{
|
|
910
|
+
tpm20_set_timeouts();
|
|
911
|
+
|
|
912
|
+
int ret = tpm_simple_cmd(0, TPM2_CC_Startup,
|
|
913
|
+
2, TPM2_SU_CLEAR, TPM_DURATION_TYPE_SHORT);
|
|
914
|
+
|
|
915
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_Startup(SU_CLEAR) = 0x%08x\n",
|
|
916
|
+
ret);
|
|
917
|
+
|
|
918
|
+
if (CONFIG_COREBOOT && ret == TPM2_RC_INITIALIZE)
|
|
919
|
+
/* with other firmware on the system the TPM may already have been
|
|
920
|
+
* initialized
|
|
921
|
+
*/
|
|
922
|
+
ret = 0;
|
|
923
|
+
|
|
924
|
+
if (ret)
|
|
925
|
+
goto err_exit;
|
|
926
|
+
|
|
927
|
+
ret = tpm_simple_cmd(0, TPM2_CC_SelfTest,
|
|
928
|
+
1, TPM2_YES, TPM_DURATION_TYPE_LONG);
|
|
929
|
+
|
|
930
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_SelfTest = 0x%08x\n",
|
|
931
|
+
ret);
|
|
932
|
+
|
|
933
|
+
if (ret)
|
|
934
|
+
goto err_exit;
|
|
935
|
+
|
|
936
|
+
ret = tpm20_get_pcrbanks();
|
|
937
|
+
if (ret)
|
|
938
|
+
goto err_exit;
|
|
939
|
+
|
|
940
|
+
ret = tpm20_write_EfiSpecIdEventStruct();
|
|
941
|
+
if (ret)
|
|
942
|
+
goto err_exit;
|
|
943
|
+
|
|
944
|
+
return 0;
|
|
945
|
+
|
|
946
|
+
err_exit:
|
|
947
|
+
dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
|
|
948
|
+
|
|
949
|
+
tpm_set_failure();
|
|
950
|
+
return -1;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
static int
|
|
954
|
+
tpm_startup(void)
|
|
955
|
+
{
|
|
956
|
+
switch (TPM_version) {
|
|
957
|
+
case TPM_VERSION_1_2:
|
|
958
|
+
return tpm12_startup();
|
|
959
|
+
case TPM_VERSION_2:
|
|
960
|
+
return tpm20_startup();
|
|
961
|
+
}
|
|
962
|
+
return -1;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
void
|
|
966
|
+
tpm_setup(void)
|
|
967
|
+
{
|
|
968
|
+
if (!CONFIG_TCGBIOS)
|
|
969
|
+
return;
|
|
970
|
+
|
|
971
|
+
int ret = tpm_tpm2_probe();
|
|
972
|
+
if (ret) {
|
|
973
|
+
ret = tpm_tcpa_probe();
|
|
974
|
+
if (ret)
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
TPM_version = tpmhw_probe();
|
|
979
|
+
if (TPM_version == TPM_VERSION_NONE)
|
|
980
|
+
return;
|
|
981
|
+
|
|
982
|
+
dprintf(DEBUG_tcg,
|
|
983
|
+
"TCGBIOS: Detected a TPM %s.\n",
|
|
984
|
+
(TPM_version == TPM_VERSION_1_2) ? "1.2" : "2");
|
|
985
|
+
|
|
986
|
+
TPM_working = 1;
|
|
987
|
+
|
|
988
|
+
if (runningOnXen())
|
|
989
|
+
return;
|
|
990
|
+
|
|
991
|
+
ret = tpm_startup();
|
|
992
|
+
if (ret)
|
|
993
|
+
return;
|
|
994
|
+
|
|
995
|
+
tpm_smbios_measure();
|
|
996
|
+
tpm_add_action(2, "Start Option ROM Scan");
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
static void
|
|
1000
|
+
tpm20_prepboot(void)
|
|
1001
|
+
{
|
|
1002
|
+
int ret = tpm20_stirrandom();
|
|
1003
|
+
if (ret)
|
|
1004
|
+
goto err_exit;
|
|
1005
|
+
|
|
1006
|
+
u8 auth[20];
|
|
1007
|
+
ret = tpm20_getrandom(&auth[0], sizeof(auth));
|
|
1008
|
+
if (ret)
|
|
1009
|
+
goto err_exit;
|
|
1010
|
+
|
|
1011
|
+
ret = tpm20_hierarchychangeauth(auth);
|
|
1012
|
+
if (ret)
|
|
1013
|
+
goto err_exit;
|
|
1014
|
+
|
|
1015
|
+
return;
|
|
1016
|
+
|
|
1017
|
+
err_exit:
|
|
1018
|
+
dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
|
|
1019
|
+
|
|
1020
|
+
tpm_set_failure();
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
void
|
|
1024
|
+
tpm_prepboot(void)
|
|
1025
|
+
{
|
|
1026
|
+
if (!CONFIG_TCGBIOS)
|
|
1027
|
+
return;
|
|
1028
|
+
|
|
1029
|
+
switch (TPM_version) {
|
|
1030
|
+
case TPM_VERSION_1_2:
|
|
1031
|
+
if (TPM_has_physical_presence)
|
|
1032
|
+
tpm_simple_cmd(0, TPM_ORD_PhysicalPresence,
|
|
1033
|
+
2, TPM_PP_NOT_PRESENT_LOCK, TPM_DURATION_TYPE_SHORT);
|
|
1034
|
+
break;
|
|
1035
|
+
case TPM_VERSION_2:
|
|
1036
|
+
tpm20_prepboot();
|
|
1037
|
+
break;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
tpm_add_action(4, "Calling INT 19h");
|
|
1041
|
+
tpm_add_event_separators();
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
/*
|
|
1045
|
+
* Add measurement to the log about an option rom
|
|
1046
|
+
*/
|
|
1047
|
+
void
|
|
1048
|
+
tpm_option_rom(const void *addr, u32 len)
|
|
1049
|
+
{
|
|
1050
|
+
if (!tpm_is_working())
|
|
1051
|
+
return;
|
|
1052
|
+
|
|
1053
|
+
struct pcctes_romex pcctes = {
|
|
1054
|
+
.eventid = 7,
|
|
1055
|
+
.eventdatasize = sizeof(u16) + sizeof(u16) + SHA1_BUFSIZE,
|
|
1056
|
+
};
|
|
1057
|
+
sha1((const u8 *)addr, len, pcctes.digest);
|
|
1058
|
+
tpm_add_measurement_to_log(2,
|
|
1059
|
+
EV_EVENT_TAG,
|
|
1060
|
+
(const char *)&pcctes, sizeof(pcctes),
|
|
1061
|
+
(u8 *)&pcctes, sizeof(pcctes));
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
void
|
|
1065
|
+
tpm_add_bcv(u32 bootdrv, const u8 *addr, u32 length)
|
|
1066
|
+
{
|
|
1067
|
+
if (!tpm_is_working())
|
|
1068
|
+
return;
|
|
1069
|
+
|
|
1070
|
+
if (length < 0x200)
|
|
1071
|
+
return;
|
|
1072
|
+
|
|
1073
|
+
const char *string = "Booting BCV device 00h (Floppy)";
|
|
1074
|
+
if (bootdrv == 0x80)
|
|
1075
|
+
string = "Booting BCV device 80h (HDD)";
|
|
1076
|
+
tpm_add_action(4, string);
|
|
1077
|
+
|
|
1078
|
+
/* specs: see section 'Hard Disk Device or Hard Disk-Like Devices' */
|
|
1079
|
+
/* equivalent to: dd if=/dev/hda ibs=1 count=440 | sha1sum */
|
|
1080
|
+
string = "MBR";
|
|
1081
|
+
tpm_add_measurement_to_log(4, EV_IPL,
|
|
1082
|
+
string, strlen(string),
|
|
1083
|
+
addr, 0x1b8);
|
|
1084
|
+
|
|
1085
|
+
/* equivalent to: dd if=/dev/hda ibs=1 count=72 skip=440 | sha1sum */
|
|
1086
|
+
string = "MBR PARTITION_TABLE";
|
|
1087
|
+
tpm_add_measurement_to_log(5, EV_IPL_PARTITION_DATA,
|
|
1088
|
+
string, strlen(string),
|
|
1089
|
+
addr + 0x1b8, 0x48);
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
void
|
|
1093
|
+
tpm_add_cdrom(u32 bootdrv, const u8 *addr, u32 length)
|
|
1094
|
+
{
|
|
1095
|
+
if (!tpm_is_working())
|
|
1096
|
+
return;
|
|
1097
|
+
|
|
1098
|
+
tpm_add_action(4, "Booting from CD ROM device");
|
|
1099
|
+
|
|
1100
|
+
/* specs: see section 'El Torito' */
|
|
1101
|
+
const char *string = "EL TORITO IPL";
|
|
1102
|
+
tpm_add_measurement_to_log(4, EV_IPL,
|
|
1103
|
+
string, strlen(string),
|
|
1104
|
+
addr, length);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
void
|
|
1108
|
+
tpm_add_cdrom_catalog(const u8 *addr, u32 length)
|
|
1109
|
+
{
|
|
1110
|
+
if (!tpm_is_working())
|
|
1111
|
+
return;
|
|
1112
|
+
|
|
1113
|
+
tpm_add_action(4, "Booting from CD ROM device");
|
|
1114
|
+
|
|
1115
|
+
/* specs: see section 'El Torito' */
|
|
1116
|
+
const char *string = "BOOT CATALOG";
|
|
1117
|
+
tpm_add_measurement_to_log(5, EV_IPL_PARTITION_DATA,
|
|
1118
|
+
string, strlen(string),
|
|
1119
|
+
addr, length);
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1122
|
+
void
|
|
1123
|
+
tpm_s3_resume(void)
|
|
1124
|
+
{
|
|
1125
|
+
if (!tpm_is_working())
|
|
1126
|
+
return;
|
|
1127
|
+
|
|
1128
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Resuming with TPM_Startup(ST_STATE)\n");
|
|
1129
|
+
|
|
1130
|
+
int ret = -1;
|
|
1131
|
+
|
|
1132
|
+
switch (TPM_version) {
|
|
1133
|
+
case TPM_VERSION_1_2:
|
|
1134
|
+
ret = tpm_simple_cmd(0, TPM_ORD_Startup,
|
|
1135
|
+
2, TPM_ST_STATE, TPM_DURATION_TYPE_SHORT);
|
|
1136
|
+
break;
|
|
1137
|
+
case TPM_VERSION_2:
|
|
1138
|
+
ret = tpm_simple_cmd(0, TPM2_CC_Startup,
|
|
1139
|
+
2, TPM2_SU_STATE, TPM_DURATION_TYPE_SHORT);
|
|
1140
|
+
|
|
1141
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_Startup(SU_STATE) = 0x%08x\n",
|
|
1142
|
+
ret);
|
|
1143
|
+
|
|
1144
|
+
if (ret)
|
|
1145
|
+
goto err_exit;
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
ret = tpm_simple_cmd(0, TPM2_CC_SelfTest,
|
|
1149
|
+
1, TPM2_YES, TPM_DURATION_TYPE_LONG);
|
|
1150
|
+
|
|
1151
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_SelfTest() = 0x%08x\n",
|
|
1152
|
+
ret);
|
|
1153
|
+
|
|
1154
|
+
break;
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
if (ret)
|
|
1158
|
+
goto err_exit;
|
|
1159
|
+
|
|
1160
|
+
return;
|
|
1161
|
+
|
|
1162
|
+
err_exit:
|
|
1163
|
+
dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
|
|
1164
|
+
|
|
1165
|
+
tpm_set_failure();
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
|
|
1169
|
+
/****************************************************************
|
|
1170
|
+
* BIOS interface
|
|
1171
|
+
****************************************************************/
|
|
1172
|
+
|
|
1173
|
+
u8 TPM_interface_shutdown VARLOW;
|
|
1174
|
+
|
|
1175
|
+
static inline void *input_buf32(struct bregs *regs)
|
|
1176
|
+
{
|
|
1177
|
+
return MAKE_FLATPTR(regs->es, regs->di);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
static inline void *output_buf32(struct bregs *regs)
|
|
1181
|
+
{
|
|
1182
|
+
return MAKE_FLATPTR(regs->ds, regs->si);
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
static u32
|
|
1186
|
+
hash_log_extend(struct pcpes *pcpes, const void *hashdata, u32 hashdata_length
|
|
1187
|
+
, void *event, int extend)
|
|
1188
|
+
{
|
|
1189
|
+
if (pcpes->pcrindex >= 24)
|
|
1190
|
+
return TCG_INVALID_INPUT_PARA;
|
|
1191
|
+
if (hashdata)
|
|
1192
|
+
sha1(hashdata, hashdata_length, pcpes->digest);
|
|
1193
|
+
|
|
1194
|
+
struct tpm_log_entry le = {
|
|
1195
|
+
.hdr.pcrindex = pcpes->pcrindex,
|
|
1196
|
+
.hdr.eventtype = pcpes->eventtype,
|
|
1197
|
+
};
|
|
1198
|
+
int digest_len = tpm_build_digest(&le, pcpes->digest, 1);
|
|
1199
|
+
if (digest_len < 0)
|
|
1200
|
+
return TCG_GENERAL_ERROR;
|
|
1201
|
+
if (extend) {
|
|
1202
|
+
int ret = tpm_extend(&le, digest_len);
|
|
1203
|
+
if (ret)
|
|
1204
|
+
return TCG_TCG_COMMAND_ERROR;
|
|
1205
|
+
}
|
|
1206
|
+
tpm_build_digest(&le, pcpes->digest, 0);
|
|
1207
|
+
int ret = tpm_log_event(&le.hdr, digest_len
|
|
1208
|
+
, pcpes->event, pcpes->eventdatasize);
|
|
1209
|
+
if (ret)
|
|
1210
|
+
return TCG_PC_LOGOVERFLOW;
|
|
1211
|
+
return 0;
|
|
1212
|
+
}
|
|
1213
|
+
|
|
1214
|
+
static u32
|
|
1215
|
+
hash_log_extend_event_int(const struct hleei_short *hleei_s,
|
|
1216
|
+
struct hleeo *hleeo)
|
|
1217
|
+
{
|
|
1218
|
+
u32 rc = 0;
|
|
1219
|
+
struct hleei_long *hleei_l = (struct hleei_long *)hleei_s;
|
|
1220
|
+
const void *logdataptr;
|
|
1221
|
+
u32 logdatalen;
|
|
1222
|
+
struct pcpes *pcpes;
|
|
1223
|
+
u32 pcrindex;
|
|
1224
|
+
|
|
1225
|
+
/* short or long version? */
|
|
1226
|
+
switch (hleei_s->ipblength) {
|
|
1227
|
+
case sizeof(struct hleei_short):
|
|
1228
|
+
/* short */
|
|
1229
|
+
logdataptr = hleei_s->logdataptr;
|
|
1230
|
+
logdatalen = hleei_s->logdatalen;
|
|
1231
|
+
pcrindex = hleei_s->pcrindex;
|
|
1232
|
+
break;
|
|
1233
|
+
|
|
1234
|
+
case sizeof(struct hleei_long):
|
|
1235
|
+
/* long */
|
|
1236
|
+
logdataptr = hleei_l->logdataptr;
|
|
1237
|
+
logdatalen = hleei_l->logdatalen;
|
|
1238
|
+
pcrindex = hleei_l->pcrindex;
|
|
1239
|
+
break;
|
|
1240
|
+
|
|
1241
|
+
default:
|
|
1242
|
+
/* bad input block */
|
|
1243
|
+
rc = TCG_INVALID_INPUT_PARA;
|
|
1244
|
+
goto err_exit;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
pcpes = (struct pcpes *)logdataptr;
|
|
1248
|
+
|
|
1249
|
+
if (pcpes->pcrindex != pcrindex
|
|
1250
|
+
|| logdatalen != sizeof(*pcpes) + pcpes->eventdatasize) {
|
|
1251
|
+
rc = TCG_INVALID_INPUT_PARA;
|
|
1252
|
+
goto err_exit;
|
|
1253
|
+
}
|
|
1254
|
+
rc = hash_log_extend(pcpes, hleei_s->hashdataptr, hleei_s->hashdatalen
|
|
1255
|
+
, pcpes->event, 1);
|
|
1256
|
+
if (rc)
|
|
1257
|
+
goto err_exit;
|
|
1258
|
+
|
|
1259
|
+
hleeo->opblength = sizeof(struct hleeo);
|
|
1260
|
+
hleeo->reserved = 0;
|
|
1261
|
+
hleeo->eventnumber = tpm_state.entry_count;
|
|
1262
|
+
memcpy(hleeo->digest, pcpes->digest, sizeof(hleeo->digest));
|
|
1263
|
+
|
|
1264
|
+
err_exit:
|
|
1265
|
+
if (rc != 0) {
|
|
1266
|
+
hleeo->opblength = 4;
|
|
1267
|
+
hleeo->reserved = 0;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
return rc;
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
static u32
|
|
1274
|
+
pass_through_to_tpm_int(struct pttti *pttti, struct pttto *pttto)
|
|
1275
|
+
{
|
|
1276
|
+
u32 rc = 0;
|
|
1277
|
+
struct tpm_req_header *trh = (void*)pttti->tpmopin;
|
|
1278
|
+
|
|
1279
|
+
if (pttti->ipblength < sizeof(struct pttti) + sizeof(*trh)
|
|
1280
|
+
|| pttti->ipblength != sizeof(struct pttti) + be32_to_cpu(trh->totlen)
|
|
1281
|
+
|| pttti->opblength < sizeof(struct pttto)) {
|
|
1282
|
+
rc = TCG_INVALID_INPUT_PARA;
|
|
1283
|
+
goto err_exit;
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
u16 tag = be16_to_cpu(trh->tag);
|
|
1287
|
+
|
|
1288
|
+
switch (TPM_version) {
|
|
1289
|
+
case TPM_VERSION_1_2:
|
|
1290
|
+
if (tag != TPM_TAG_RQU_CMD && tag != TPM_TAG_RQU_AUTH1_CMD
|
|
1291
|
+
&& tag != TPM_TAG_RQU_AUTH2_CMD) {
|
|
1292
|
+
rc = TCG_INVALID_INPUT_PARA;
|
|
1293
|
+
goto err_exit;
|
|
1294
|
+
}
|
|
1295
|
+
break;
|
|
1296
|
+
case TPM_VERSION_2:
|
|
1297
|
+
if (tag != TPM2_ST_NO_SESSIONS && tag != TPM2_ST_SESSIONS) {
|
|
1298
|
+
rc = TCG_INVALID_INPUT_PARA;
|
|
1299
|
+
goto err_exit;
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
u32 resbuflen = pttti->opblength - offsetof(struct pttto, tpmopout);
|
|
1304
|
+
int ret = tpmhw_transmit(0, trh, pttto->tpmopout, &resbuflen,
|
|
1305
|
+
TPM_DURATION_TYPE_LONG /* worst case */);
|
|
1306
|
+
if (ret) {
|
|
1307
|
+
rc = TCG_FATAL_COM_ERROR;
|
|
1308
|
+
goto err_exit;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
pttto->opblength = offsetof(struct pttto, tpmopout) + resbuflen;
|
|
1312
|
+
pttto->reserved = 0;
|
|
1313
|
+
|
|
1314
|
+
err_exit:
|
|
1315
|
+
if (rc != 0) {
|
|
1316
|
+
pttto->opblength = 4;
|
|
1317
|
+
pttto->reserved = 0;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
return rc;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
static u32
|
|
1324
|
+
shutdown_preboot_interface(void)
|
|
1325
|
+
{
|
|
1326
|
+
TPM_interface_shutdown = 1;
|
|
1327
|
+
return 0;
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
static u32
|
|
1331
|
+
hash_log_event_int(const struct hlei *hlei, struct hleo *hleo)
|
|
1332
|
+
{
|
|
1333
|
+
u32 rc = 0;
|
|
1334
|
+
u16 size;
|
|
1335
|
+
struct pcpes *pcpes;
|
|
1336
|
+
|
|
1337
|
+
size = hlei->ipblength;
|
|
1338
|
+
if (size != sizeof(*hlei)) {
|
|
1339
|
+
rc = TCG_INVALID_INPUT_PARA;
|
|
1340
|
+
goto err_exit;
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
pcpes = (struct pcpes *)hlei->logdataptr;
|
|
1344
|
+
|
|
1345
|
+
if (pcpes->pcrindex != hlei->pcrindex
|
|
1346
|
+
|| pcpes->eventtype != hlei->logeventtype
|
|
1347
|
+
|| hlei->logdatalen != sizeof(*pcpes) + pcpes->eventdatasize) {
|
|
1348
|
+
rc = TCG_INVALID_INPUT_PARA;
|
|
1349
|
+
goto err_exit;
|
|
1350
|
+
}
|
|
1351
|
+
rc = hash_log_extend(pcpes, hlei->hashdataptr, hlei->hashdatalen
|
|
1352
|
+
, pcpes->event, 0);
|
|
1353
|
+
if (rc)
|
|
1354
|
+
goto err_exit;
|
|
1355
|
+
|
|
1356
|
+
/* updating the log was fine */
|
|
1357
|
+
hleo->opblength = sizeof(struct hleo);
|
|
1358
|
+
hleo->reserved = 0;
|
|
1359
|
+
hleo->eventnumber = tpm_state.entry_count;
|
|
1360
|
+
|
|
1361
|
+
err_exit:
|
|
1362
|
+
if (rc != 0) {
|
|
1363
|
+
hleo->opblength = 2;
|
|
1364
|
+
hleo->reserved = 0;
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
return rc;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
static u32
|
|
1371
|
+
hash_all_int(const struct hai *hai, u8 *hash)
|
|
1372
|
+
{
|
|
1373
|
+
if (hai->ipblength != sizeof(struct hai) ||
|
|
1374
|
+
hai->hashdataptr == 0 ||
|
|
1375
|
+
hai->hashdatalen == 0 ||
|
|
1376
|
+
hai->algorithmid != TPM_ALG_SHA)
|
|
1377
|
+
return TCG_INVALID_INPUT_PARA;
|
|
1378
|
+
|
|
1379
|
+
sha1((const u8 *)hai->hashdataptr, hai->hashdatalen, hash);
|
|
1380
|
+
return 0;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
static u32
|
|
1384
|
+
tss_int(struct ti *ti, struct to *to)
|
|
1385
|
+
{
|
|
1386
|
+
to->opblength = sizeof(struct to);
|
|
1387
|
+
to->reserved = 0;
|
|
1388
|
+
|
|
1389
|
+
return TCG_PC_UNSUPPORTED;
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
static u32
|
|
1393
|
+
compact_hash_log_extend_event_int(u8 *buffer,
|
|
1394
|
+
u32 info,
|
|
1395
|
+
u32 length,
|
|
1396
|
+
u32 pcrindex,
|
|
1397
|
+
u32 *edx_ptr)
|
|
1398
|
+
{
|
|
1399
|
+
struct pcpes pcpes = {
|
|
1400
|
+
.pcrindex = pcrindex,
|
|
1401
|
+
.eventtype = EV_COMPACT_HASH,
|
|
1402
|
+
.eventdatasize = sizeof(info),
|
|
1403
|
+
};
|
|
1404
|
+
u32 rc = hash_log_extend(&pcpes, buffer, length, &info, 1);
|
|
1405
|
+
if (rc)
|
|
1406
|
+
return rc;
|
|
1407
|
+
|
|
1408
|
+
*edx_ptr = tpm_state.entry_count;
|
|
1409
|
+
return 0;
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
void VISIBLE32FLAT
|
|
1413
|
+
tpm_interrupt_handler32(struct bregs *regs)
|
|
1414
|
+
{
|
|
1415
|
+
if (!CONFIG_TCGBIOS)
|
|
1416
|
+
return;
|
|
1417
|
+
|
|
1418
|
+
set_cf(regs, 0);
|
|
1419
|
+
|
|
1420
|
+
if (TPM_interface_shutdown && regs->al) {
|
|
1421
|
+
regs->eax = TCG_INTERFACE_SHUTDOWN;
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
switch ((enum irq_ids)regs->al) {
|
|
1426
|
+
case TCG_StatusCheck:
|
|
1427
|
+
if (!tpmhw_is_present()) {
|
|
1428
|
+
/* no TPM available */
|
|
1429
|
+
regs->eax = TCG_PC_TPM_NOT_PRESENT;
|
|
1430
|
+
} else {
|
|
1431
|
+
regs->eax = 0;
|
|
1432
|
+
regs->ebx = TCG_MAGIC;
|
|
1433
|
+
regs->ch = TCG_VERSION_MAJOR;
|
|
1434
|
+
regs->cl = TCG_VERSION_MINOR;
|
|
1435
|
+
regs->edx = 0x0;
|
|
1436
|
+
regs->esi = (u32)tpm_state.log_area_start_address;
|
|
1437
|
+
regs->edi = (u32)tpm_state.log_area_last_entry;
|
|
1438
|
+
}
|
|
1439
|
+
break;
|
|
1440
|
+
|
|
1441
|
+
case TCG_HashLogExtendEvent:
|
|
1442
|
+
regs->eax =
|
|
1443
|
+
hash_log_extend_event_int(
|
|
1444
|
+
(struct hleei_short *)input_buf32(regs),
|
|
1445
|
+
(struct hleeo *)output_buf32(regs));
|
|
1446
|
+
break;
|
|
1447
|
+
|
|
1448
|
+
case TCG_PassThroughToTPM:
|
|
1449
|
+
regs->eax =
|
|
1450
|
+
pass_through_to_tpm_int((struct pttti *)input_buf32(regs),
|
|
1451
|
+
(struct pttto *)output_buf32(regs));
|
|
1452
|
+
break;
|
|
1453
|
+
|
|
1454
|
+
case TCG_ShutdownPreBootInterface:
|
|
1455
|
+
regs->eax = shutdown_preboot_interface();
|
|
1456
|
+
break;
|
|
1457
|
+
|
|
1458
|
+
case TCG_HashLogEvent:
|
|
1459
|
+
regs->eax = hash_log_event_int((struct hlei*)input_buf32(regs),
|
|
1460
|
+
(struct hleo*)output_buf32(regs));
|
|
1461
|
+
break;
|
|
1462
|
+
|
|
1463
|
+
case TCG_HashAll:
|
|
1464
|
+
regs->eax =
|
|
1465
|
+
hash_all_int((struct hai*)input_buf32(regs),
|
|
1466
|
+
(u8 *)output_buf32(regs));
|
|
1467
|
+
break;
|
|
1468
|
+
|
|
1469
|
+
case TCG_TSS:
|
|
1470
|
+
regs->eax = tss_int((struct ti*)input_buf32(regs),
|
|
1471
|
+
(struct to*)output_buf32(regs));
|
|
1472
|
+
break;
|
|
1473
|
+
|
|
1474
|
+
case TCG_CompactHashLogExtendEvent:
|
|
1475
|
+
regs->eax =
|
|
1476
|
+
compact_hash_log_extend_event_int((u8 *)input_buf32(regs),
|
|
1477
|
+
regs->esi,
|
|
1478
|
+
regs->ecx,
|
|
1479
|
+
regs->edx,
|
|
1480
|
+
®s->edx);
|
|
1481
|
+
break;
|
|
1482
|
+
|
|
1483
|
+
default:
|
|
1484
|
+
set_cf(regs, 1);
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
return;
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
|
|
1491
|
+
/****************************************************************
|
|
1492
|
+
* TPM Configuration Menu
|
|
1493
|
+
****************************************************************/
|
|
1494
|
+
|
|
1495
|
+
typedef u8 tpm_ppi_code;
|
|
1496
|
+
|
|
1497
|
+
static int
|
|
1498
|
+
tpm12_read_has_owner(int *has_owner)
|
|
1499
|
+
{
|
|
1500
|
+
struct tpm_res_getcap_ownerauth oauth;
|
|
1501
|
+
int ret = tpm12_get_capability(TPM_CAP_PROPERTY, TPM_CAP_PROP_OWNER
|
|
1502
|
+
, &oauth.hdr, sizeof(oauth));
|
|
1503
|
+
if (ret)
|
|
1504
|
+
return -1;
|
|
1505
|
+
|
|
1506
|
+
*has_owner = oauth.flag;
|
|
1507
|
+
|
|
1508
|
+
return 0;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
static int
|
|
1512
|
+
tpm12_enable_tpm(int enable, int verbose)
|
|
1513
|
+
{
|
|
1514
|
+
struct tpm_permanent_flags pf;
|
|
1515
|
+
int ret = tpm12_read_permanent_flags((char *)&pf, sizeof(pf));
|
|
1516
|
+
if (ret)
|
|
1517
|
+
return -1;
|
|
1518
|
+
|
|
1519
|
+
if (pf.flags[PERM_FLAG_IDX_DISABLE] && !enable)
|
|
1520
|
+
return 0;
|
|
1521
|
+
|
|
1522
|
+
ret = tpm_simple_cmd(0, enable ? TPM_ORD_PhysicalEnable
|
|
1523
|
+
: TPM_ORD_PhysicalDisable,
|
|
1524
|
+
0, 0, TPM_DURATION_TYPE_SHORT);
|
|
1525
|
+
if (ret) {
|
|
1526
|
+
if (enable)
|
|
1527
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Enabling the TPM failed.\n");
|
|
1528
|
+
else
|
|
1529
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Disabling the TPM failed.\n");
|
|
1530
|
+
}
|
|
1531
|
+
return ret;
|
|
1532
|
+
}
|
|
1533
|
+
|
|
1534
|
+
static int
|
|
1535
|
+
tpm12_activate_tpm(int activate, int allow_reset, int verbose)
|
|
1536
|
+
{
|
|
1537
|
+
struct tpm_permanent_flags pf;
|
|
1538
|
+
int ret = tpm12_read_permanent_flags((char *)&pf, sizeof(pf));
|
|
1539
|
+
if (ret)
|
|
1540
|
+
return -1;
|
|
1541
|
+
|
|
1542
|
+
if (pf.flags[PERM_FLAG_IDX_DEACTIVATED] && !activate)
|
|
1543
|
+
return 0;
|
|
1544
|
+
|
|
1545
|
+
if (pf.flags[PERM_FLAG_IDX_DISABLE])
|
|
1546
|
+
return 0;
|
|
1547
|
+
|
|
1548
|
+
ret = tpm_simple_cmd(0, TPM_ORD_PhysicalSetDeactivated,
|
|
1549
|
+
1, activate ? 0x00 : 0x01, TPM_DURATION_TYPE_SHORT);
|
|
1550
|
+
if (ret)
|
|
1551
|
+
return ret;
|
|
1552
|
+
|
|
1553
|
+
if (activate && allow_reset) {
|
|
1554
|
+
if (verbose) {
|
|
1555
|
+
printf("Requiring a reboot to activate the TPM.\n");
|
|
1556
|
+
|
|
1557
|
+
msleep(2000);
|
|
1558
|
+
}
|
|
1559
|
+
reset();
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
return 0;
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
static int
|
|
1566
|
+
tpm12_enable_activate(int allow_reset, int verbose)
|
|
1567
|
+
{
|
|
1568
|
+
int ret = tpm12_enable_tpm(1, verbose);
|
|
1569
|
+
if (ret)
|
|
1570
|
+
return ret;
|
|
1571
|
+
|
|
1572
|
+
return tpm12_activate_tpm(1, allow_reset, verbose);
|
|
1573
|
+
}
|
|
1574
|
+
|
|
1575
|
+
static int
|
|
1576
|
+
tpm12_force_clear(int enable_activate_before, int enable_activate_after,
|
|
1577
|
+
int verbose)
|
|
1578
|
+
{
|
|
1579
|
+
int has_owner;
|
|
1580
|
+
int ret = tpm12_read_has_owner(&has_owner);
|
|
1581
|
+
if (ret)
|
|
1582
|
+
return -1;
|
|
1583
|
+
if (!has_owner) {
|
|
1584
|
+
if (verbose)
|
|
1585
|
+
printf("TPM does not have an owner.\n");
|
|
1586
|
+
return 0;
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
if (enable_activate_before) {
|
|
1590
|
+
ret = tpm12_enable_activate(0, verbose);
|
|
1591
|
+
if (ret) {
|
|
1592
|
+
dprintf(DEBUG_tcg,
|
|
1593
|
+
"TCGBIOS: Enabling/activating the TPM failed.\n");
|
|
1594
|
+
return ret;
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
ret = tpm_simple_cmd(0, TPM_ORD_ForceClear,
|
|
1599
|
+
0, 0, TPM_DURATION_TYPE_SHORT);
|
|
1600
|
+
if (ret)
|
|
1601
|
+
return ret;
|
|
1602
|
+
|
|
1603
|
+
if (!enable_activate_after) {
|
|
1604
|
+
if (verbose)
|
|
1605
|
+
printf("Owner successfully cleared.\n"
|
|
1606
|
+
"You will need to enable/activate the TPM again.\n\n");
|
|
1607
|
+
return 0;
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
return tpm12_enable_activate(1, verbose);
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
static int
|
|
1614
|
+
tpm12_set_owner_install(int allow, int verbose)
|
|
1615
|
+
{
|
|
1616
|
+
int has_owner;
|
|
1617
|
+
int ret = tpm12_read_has_owner(&has_owner);
|
|
1618
|
+
if (ret)
|
|
1619
|
+
return -1;
|
|
1620
|
+
if (has_owner) {
|
|
1621
|
+
if (verbose)
|
|
1622
|
+
printf("Must first remove owner.\n");
|
|
1623
|
+
return 0;
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
struct tpm_permanent_flags pf;
|
|
1627
|
+
ret = tpm12_read_permanent_flags((char *)&pf, sizeof(pf));
|
|
1628
|
+
if (ret)
|
|
1629
|
+
return -1;
|
|
1630
|
+
|
|
1631
|
+
if (pf.flags[PERM_FLAG_IDX_DISABLE]) {
|
|
1632
|
+
if (verbose)
|
|
1633
|
+
printf("TPM must first be enable.\n");
|
|
1634
|
+
return 0;
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1637
|
+
ret = tpm_simple_cmd(0, TPM_ORD_SetOwnerInstall,
|
|
1638
|
+
1, allow ? 0x01 : 0x00, TPM_DURATION_TYPE_SHORT);
|
|
1639
|
+
if (ret)
|
|
1640
|
+
return ret;
|
|
1641
|
+
|
|
1642
|
+
if (verbose)
|
|
1643
|
+
printf("Installation of owner %s.\n", allow ? "enabled" : "disabled");
|
|
1644
|
+
|
|
1645
|
+
return 0;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
static int
|
|
1649
|
+
tpm12_process_cfg(tpm_ppi_code msgCode, int verbose)
|
|
1650
|
+
{
|
|
1651
|
+
int ret = 0;
|
|
1652
|
+
|
|
1653
|
+
switch (msgCode) {
|
|
1654
|
+
case TPM_PPI_OP_NOOP: /* no-op */
|
|
1655
|
+
break;
|
|
1656
|
+
|
|
1657
|
+
case TPM_PPI_OP_ENABLE:
|
|
1658
|
+
ret = tpm12_enable_tpm(1, verbose);
|
|
1659
|
+
break;
|
|
1660
|
+
|
|
1661
|
+
case TPM_PPI_OP_DISABLE:
|
|
1662
|
+
ret = tpm12_enable_tpm(0, verbose);
|
|
1663
|
+
break;
|
|
1664
|
+
|
|
1665
|
+
case TPM_PPI_OP_ACTIVATE:
|
|
1666
|
+
ret = tpm12_activate_tpm(1, 1, verbose);
|
|
1667
|
+
break;
|
|
1668
|
+
|
|
1669
|
+
case TPM_PPI_OP_DEACTIVATE:
|
|
1670
|
+
ret = tpm12_activate_tpm(0, 1, verbose);
|
|
1671
|
+
break;
|
|
1672
|
+
|
|
1673
|
+
case TPM_PPI_OP_CLEAR:
|
|
1674
|
+
ret = tpm12_force_clear(1, 0, verbose);
|
|
1675
|
+
break;
|
|
1676
|
+
|
|
1677
|
+
case TPM_PPI_OP_SET_OWNERINSTALL_TRUE:
|
|
1678
|
+
ret = tpm12_set_owner_install(1, verbose);
|
|
1679
|
+
break;
|
|
1680
|
+
|
|
1681
|
+
case TPM_PPI_OP_SET_OWNERINSTALL_FALSE:
|
|
1682
|
+
ret = tpm12_set_owner_install(0, verbose);
|
|
1683
|
+
break;
|
|
1684
|
+
|
|
1685
|
+
default:
|
|
1686
|
+
break;
|
|
1687
|
+
}
|
|
1688
|
+
|
|
1689
|
+
if (ret)
|
|
1690
|
+
printf("Op %d: An error occurred: 0x%x\n", msgCode, ret);
|
|
1691
|
+
|
|
1692
|
+
return ret;
|
|
1693
|
+
}
|
|
1694
|
+
|
|
1695
|
+
static int
|
|
1696
|
+
tpm20_clearcontrol(u8 disable, int verbose)
|
|
1697
|
+
{
|
|
1698
|
+
struct tpm2_req_clearcontrol trc = {
|
|
1699
|
+
.hdr.tag = cpu_to_be16(TPM2_ST_SESSIONS),
|
|
1700
|
+
.hdr.totlen = cpu_to_be32(sizeof(trc)),
|
|
1701
|
+
.hdr.ordinal = cpu_to_be32(TPM2_CC_ClearControl),
|
|
1702
|
+
.authhandle = cpu_to_be32(TPM2_RH_PLATFORM),
|
|
1703
|
+
.authblocksize = cpu_to_be32(sizeof(trc.authblock)),
|
|
1704
|
+
.authblock = {
|
|
1705
|
+
.handle = cpu_to_be32(TPM2_RS_PW),
|
|
1706
|
+
.noncesize = cpu_to_be16(0),
|
|
1707
|
+
.contsession = TPM2_YES,
|
|
1708
|
+
.pwdsize = cpu_to_be16(0),
|
|
1709
|
+
},
|
|
1710
|
+
.disable = disable,
|
|
1711
|
+
};
|
|
1712
|
+
struct tpm_rsp_header rsp;
|
|
1713
|
+
u32 resp_length = sizeof(rsp);
|
|
1714
|
+
int ret = tpmhw_transmit(0, &trc.hdr, &rsp, &resp_length,
|
|
1715
|
+
TPM_DURATION_TYPE_SHORT);
|
|
1716
|
+
if (ret || resp_length != sizeof(rsp) || rsp.errcode)
|
|
1717
|
+
ret = -1;
|
|
1718
|
+
|
|
1719
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_ClearControl = 0x%08x\n",
|
|
1720
|
+
ret);
|
|
1721
|
+
|
|
1722
|
+
return ret;
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
static int
|
|
1726
|
+
tpm20_clear(void)
|
|
1727
|
+
{
|
|
1728
|
+
struct tpm2_req_clear trq = {
|
|
1729
|
+
.hdr.tag = cpu_to_be16(TPM2_ST_SESSIONS),
|
|
1730
|
+
.hdr.totlen = cpu_to_be32(sizeof(trq)),
|
|
1731
|
+
.hdr.ordinal = cpu_to_be32(TPM2_CC_Clear),
|
|
1732
|
+
.authhandle = cpu_to_be32(TPM2_RH_PLATFORM),
|
|
1733
|
+
.authblocksize = cpu_to_be32(sizeof(trq.authblock)),
|
|
1734
|
+
.authblock = {
|
|
1735
|
+
.handle = cpu_to_be32(TPM2_RS_PW),
|
|
1736
|
+
.noncesize = cpu_to_be16(0),
|
|
1737
|
+
.contsession = TPM2_YES,
|
|
1738
|
+
.pwdsize = cpu_to_be16(0),
|
|
1739
|
+
},
|
|
1740
|
+
};
|
|
1741
|
+
struct tpm_rsp_header rsp;
|
|
1742
|
+
u32 resp_length = sizeof(rsp);
|
|
1743
|
+
int ret = tpmhw_transmit(0, &trq.hdr, &rsp, &resp_length,
|
|
1744
|
+
TPM_DURATION_TYPE_MEDIUM);
|
|
1745
|
+
if (ret || resp_length != sizeof(rsp) || rsp.errcode)
|
|
1746
|
+
ret = -1;
|
|
1747
|
+
|
|
1748
|
+
dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_Clear = 0x%08x\n",
|
|
1749
|
+
ret);
|
|
1750
|
+
|
|
1751
|
+
return ret;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
static int
|
|
1755
|
+
tpm20_process_cfg(tpm_ppi_code msgCode, int verbose)
|
|
1756
|
+
{
|
|
1757
|
+
int ret = 0;
|
|
1758
|
+
|
|
1759
|
+
switch (msgCode) {
|
|
1760
|
+
case TPM_PPI_OP_NOOP: /* no-op */
|
|
1761
|
+
break;
|
|
1762
|
+
|
|
1763
|
+
case TPM_PPI_OP_CLEAR:
|
|
1764
|
+
ret = tpm20_clearcontrol(0, verbose);
|
|
1765
|
+
if (!ret)
|
|
1766
|
+
ret = tpm20_clear();
|
|
1767
|
+
break;
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
if (ret)
|
|
1771
|
+
printf("Op %d: An error occurred: 0x%x\n", msgCode, ret);
|
|
1772
|
+
|
|
1773
|
+
return ret;
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1776
|
+
static int
|
|
1777
|
+
tpm12_get_tpm_state(void)
|
|
1778
|
+
{
|
|
1779
|
+
int state = 0;
|
|
1780
|
+
struct tpm_permanent_flags pf;
|
|
1781
|
+
int has_owner;
|
|
1782
|
+
|
|
1783
|
+
if (tpm12_read_permanent_flags((char *)&pf, sizeof(pf)) ||
|
|
1784
|
+
tpm12_read_has_owner(&has_owner))
|
|
1785
|
+
return ~0;
|
|
1786
|
+
|
|
1787
|
+
if (!pf.flags[PERM_FLAG_IDX_DISABLE])
|
|
1788
|
+
state |= TPM_STATE_ENABLED;
|
|
1789
|
+
|
|
1790
|
+
if (!pf.flags[PERM_FLAG_IDX_DEACTIVATED])
|
|
1791
|
+
state |= TPM_STATE_ACTIVE;
|
|
1792
|
+
|
|
1793
|
+
if (has_owner) {
|
|
1794
|
+
state |= TPM_STATE_OWNED;
|
|
1795
|
+
} else {
|
|
1796
|
+
if (pf.flags[PERM_FLAG_IDX_OWNERSHIP])
|
|
1797
|
+
state |= TPM_STATE_OWNERINSTALL;
|
|
1798
|
+
}
|
|
1799
|
+
|
|
1800
|
+
return state;
|
|
1801
|
+
}
|
|
1802
|
+
|
|
1803
|
+
static void
|
|
1804
|
+
tpm12_show_tpm_menu(int state, int next_scancodes[7])
|
|
1805
|
+
{
|
|
1806
|
+
int i = 0;
|
|
1807
|
+
|
|
1808
|
+
printf("\nThe current state of the TPM is:\n");
|
|
1809
|
+
|
|
1810
|
+
if (state & TPM_STATE_ENABLED)
|
|
1811
|
+
printf(" Enabled");
|
|
1812
|
+
else
|
|
1813
|
+
printf(" Disabled");
|
|
1814
|
+
|
|
1815
|
+
if (state & TPM_STATE_ACTIVE)
|
|
1816
|
+
printf(" and active\n");
|
|
1817
|
+
else
|
|
1818
|
+
printf(" and deactivated\n");
|
|
1819
|
+
|
|
1820
|
+
if (state & TPM_STATE_OWNED)
|
|
1821
|
+
printf(" Ownership has been taken\n");
|
|
1822
|
+
else {
|
|
1823
|
+
printf(" Ownership has not been taken\n");
|
|
1824
|
+
if (state & TPM_STATE_OWNERINSTALL)
|
|
1825
|
+
printf(" A user can take ownership of the TPM\n");
|
|
1826
|
+
else
|
|
1827
|
+
printf(" Taking ownership of the TPM has been disabled\n");
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
if ((state & (TPM_STATE_ENABLED | TPM_STATE_ACTIVE)) !=
|
|
1831
|
+
(TPM_STATE_ENABLED | TPM_STATE_ACTIVE)) {
|
|
1832
|
+
printf("\nNote: To make use of all functionality, the TPM must be "
|
|
1833
|
+
"enabled and active.\n");
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
printf("\nAvailable options are:\n");
|
|
1837
|
+
if (state & TPM_STATE_ENABLED) {
|
|
1838
|
+
printf(" d. Disable the TPM\n");
|
|
1839
|
+
next_scancodes[i++] = 32;
|
|
1840
|
+
|
|
1841
|
+
if (state & TPM_STATE_ACTIVE) {
|
|
1842
|
+
printf(" v. Deactivate the TPM\n");
|
|
1843
|
+
next_scancodes[i++] = 47;
|
|
1844
|
+
|
|
1845
|
+
if (state & TPM_STATE_OWNERINSTALL) {
|
|
1846
|
+
printf(" p. Prevent installation of an owner\n");
|
|
1847
|
+
next_scancodes[i++] = 25;
|
|
1848
|
+
} else {
|
|
1849
|
+
printf(" s. Allow installation of an owner\n");
|
|
1850
|
+
next_scancodes[i++] = 31;
|
|
1851
|
+
}
|
|
1852
|
+
} else {
|
|
1853
|
+
printf(" a. Activate the TPM\n");
|
|
1854
|
+
next_scancodes[i++] = 30;
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1857
|
+
} else {
|
|
1858
|
+
printf(" e. Enable the TPM\n");
|
|
1859
|
+
next_scancodes[i++] = 18;
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
if (state & TPM_STATE_OWNED) {
|
|
1863
|
+
printf(" c. Clear ownership\n");
|
|
1864
|
+
next_scancodes[i++] = 46;
|
|
1865
|
+
}
|
|
1866
|
+
|
|
1867
|
+
next_scancodes[i++] = 0;
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
static void
|
|
1871
|
+
tpm12_menu(void)
|
|
1872
|
+
{
|
|
1873
|
+
int scancode, next_scancodes[7];
|
|
1874
|
+
tpm_ppi_code msgCode;
|
|
1875
|
+
int state = 0, i;
|
|
1876
|
+
int waitkey;
|
|
1877
|
+
|
|
1878
|
+
printf("The Trusted Platform Module (TPM) is a hardware device in "
|
|
1879
|
+
"this machine.\n"
|
|
1880
|
+
"It can help verify the integrity of system software.\n\n");
|
|
1881
|
+
|
|
1882
|
+
for (;;) {
|
|
1883
|
+
if ((state = tpm12_get_tpm_state()) != ~0) {
|
|
1884
|
+
tpm12_show_tpm_menu(state, next_scancodes);
|
|
1885
|
+
} else {
|
|
1886
|
+
printf("TPM is not working correctly.\n");
|
|
1887
|
+
return;
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
printf("\nIf no change is desired or if this menu was reached by "
|
|
1891
|
+
"mistake, press ESC to\n"
|
|
1892
|
+
"reboot the machine.\n");
|
|
1893
|
+
|
|
1894
|
+
msgCode = TPM_PPI_OP_NOOP;
|
|
1895
|
+
|
|
1896
|
+
waitkey = 1;
|
|
1897
|
+
|
|
1898
|
+
while (waitkey) {
|
|
1899
|
+
while ((scancode = get_keystroke(1000)) == ~0)
|
|
1900
|
+
;
|
|
1901
|
+
|
|
1902
|
+
switch (scancode) {
|
|
1903
|
+
case 1:
|
|
1904
|
+
// ESC
|
|
1905
|
+
reset();
|
|
1906
|
+
break;
|
|
1907
|
+
case 18: /* e. enable */
|
|
1908
|
+
msgCode = TPM_PPI_OP_ENABLE;
|
|
1909
|
+
break;
|
|
1910
|
+
case 32: /* d. disable */
|
|
1911
|
+
msgCode = TPM_PPI_OP_DISABLE;
|
|
1912
|
+
break;
|
|
1913
|
+
case 30: /* a. activate */
|
|
1914
|
+
msgCode = TPM_PPI_OP_ACTIVATE;
|
|
1915
|
+
break;
|
|
1916
|
+
case 47: /* v. deactivate */
|
|
1917
|
+
msgCode = TPM_PPI_OP_DEACTIVATE;
|
|
1918
|
+
break;
|
|
1919
|
+
case 46: /* c. clear owner */
|
|
1920
|
+
msgCode = TPM_PPI_OP_CLEAR;
|
|
1921
|
+
break;
|
|
1922
|
+
case 25: /* p. prevent ownerinstall */
|
|
1923
|
+
msgCode = TPM_PPI_OP_SET_OWNERINSTALL_FALSE;
|
|
1924
|
+
break;
|
|
1925
|
+
case 31: /* s. allow ownerinstall */
|
|
1926
|
+
msgCode = TPM_PPI_OP_SET_OWNERINSTALL_TRUE;
|
|
1927
|
+
break;
|
|
1928
|
+
default:
|
|
1929
|
+
continue;
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
/*
|
|
1933
|
+
* Using the next_scancodes array, check whether the
|
|
1934
|
+
* pressed key is currently a valid option.
|
|
1935
|
+
*/
|
|
1936
|
+
for (i = 0; i < sizeof(next_scancodes); i++) {
|
|
1937
|
+
if (next_scancodes[i] == 0)
|
|
1938
|
+
break;
|
|
1939
|
+
|
|
1940
|
+
if (next_scancodes[i] == scancode) {
|
|
1941
|
+
tpm12_process_cfg(msgCode, 1);
|
|
1942
|
+
waitkey = 0;
|
|
1943
|
+
break;
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
static void
|
|
1951
|
+
tpm20_menu(void)
|
|
1952
|
+
{
|
|
1953
|
+
int scan_code;
|
|
1954
|
+
tpm_ppi_code msgCode;
|
|
1955
|
+
|
|
1956
|
+
for (;;) {
|
|
1957
|
+
printf("1. Clear TPM\n");
|
|
1958
|
+
|
|
1959
|
+
printf("\nIf no change is desired or if this menu was reached by "
|
|
1960
|
+
"mistake, press ESC to\n"
|
|
1961
|
+
"reboot the machine.\n");
|
|
1962
|
+
|
|
1963
|
+
msgCode = TPM_PPI_OP_NOOP;
|
|
1964
|
+
|
|
1965
|
+
while ((scan_code = get_keystroke(1000)) == ~0)
|
|
1966
|
+
;
|
|
1967
|
+
|
|
1968
|
+
switch (scan_code) {
|
|
1969
|
+
case 1:
|
|
1970
|
+
// ESC
|
|
1971
|
+
reset();
|
|
1972
|
+
break;
|
|
1973
|
+
case 2:
|
|
1974
|
+
msgCode = TPM_PPI_OP_CLEAR;
|
|
1975
|
+
break;
|
|
1976
|
+
default:
|
|
1977
|
+
continue;
|
|
1978
|
+
}
|
|
1979
|
+
|
|
1980
|
+
tpm20_process_cfg(msgCode, 0);
|
|
1981
|
+
}
|
|
1982
|
+
}
|
|
1983
|
+
|
|
1984
|
+
void
|
|
1985
|
+
tpm_menu(void)
|
|
1986
|
+
{
|
|
1987
|
+
if (!CONFIG_TCGBIOS)
|
|
1988
|
+
return;
|
|
1989
|
+
|
|
1990
|
+
while (get_keystroke(0) >= 0)
|
|
1991
|
+
;
|
|
1992
|
+
wait_threads();
|
|
1993
|
+
|
|
1994
|
+
switch (TPM_version) {
|
|
1995
|
+
case TPM_VERSION_1_2:
|
|
1996
|
+
tpm12_menu();
|
|
1997
|
+
break;
|
|
1998
|
+
case TPM_VERSION_2:
|
|
1999
|
+
tpm20_menu();
|
|
2000
|
+
break;
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
int
|
|
2005
|
+
tpm_can_show_menu(void)
|
|
2006
|
+
{
|
|
2007
|
+
switch (TPM_version) {
|
|
2008
|
+
case TPM_VERSION_1_2:
|
|
2009
|
+
return tpm_is_working() && TPM_has_physical_presence;
|
|
2010
|
+
case TPM_VERSION_2:
|
|
2011
|
+
return tpm_is_working();
|
|
2012
|
+
}
|
|
2013
|
+
return 0;
|
|
2014
|
+
}
|