# Configuration for building a coreboot ROM that works in # the qemu emulator in console mode thanks to Whiptail # This version requires a supported HOTP Security dongle (Nitrokey Pro/Storage or Librem Key) # # TPM can be used with a qemu software TPM (TIS, 2.0). export CONFIG_COREBOOT=y export CONFIG_COREBOOT_VERSION=4.19 export CONFIG_LINUX_VERSION=5.10.5 #Enable only one RESTRICTED/BASIC boot modes below to test them manually (we cannot inject config under QEMU (no internal flashing) #export CONFIG_RESTRICTED_BOOT=y #export CONFIG_BASIC=y #Enable DEBUG output export CONFIG_DEBUG_OUTPUT=y export CONFIG_ENABLE_FUNCTION_TRACING_OUTPUT=y #Enable TPM2 pcap output under /tmp export CONFIG_TPM2_CAPTURE_PCAP=y CONFIG_COREBOOT_CONFIG=config/coreboot-qemu-tpm2.config CONFIG_LINUX_CONFIG=config/linux-qemu.config ifeq "$(CONFIG_UROOT)" "y" CONFIG_BUSYBOX=n else CONFIG_KEXEC=y CONFIG_QRENCODE=y CONFIG_TPMTOTP=y CONFIG_POPT=y CONFIG_FLASHTOOLS=y CONFIG_FLASHROM=y CONFIG_PCIUTILS=y CONFIG_UTIL_LINUX=y CONFIG_CRYPTSETUP2=y CONFIG_GPG2=y CONFIG_LVM2=y CONFIG_MBEDTLS=y CONFIG_DROPBEAR=y CONFIG_MSRTOOLS=y CONFIG_HOTPKEY=y #Uncomment only one of the following block #Required for graphical gui-init (FBWhiptail) #CONFIG_CAIRO=y #CONFIG_FBWHIPTAIL=y # #text-based init (generic-init and gui-init) CONFIG_NEWT=y CONFIG_SLANG=y endif export CONFIG_LINUX_USB_COMPANION_CONTROLLER=y CONFIG_LINUX_USB=y CONFIG_LINUX_E1000=y #Uncomment only one BOOTSCRIPT: #Whiptail-based init (text-based or FBWhiptail) export CONFIG_BOOTSCRIPT=/bin/gui-init # #text-based original init: #export CONFIG_BOOTSCRIPT=/bin/generic-init export CONFIG_BOOT_REQ_HASH=n export CONFIG_BOOT_REQ_ROLLBACK=n export CONFIG_BOOT_RECOVERY_SERIAL="/dev/ttyS0" export CONFIG_BOOT_KERNEL_ADD="console=ttyS0 console=tty systemd.zram=0" export CONFIG_BOOT_KERNEL_REMOVE="quiet rhgb splash" #TPM2 requirements export CONFIG_TPM2_TOOLS=y export CONFIG_PRIMARY_KEY_TYPE=ecc CONFIG_TPM2_TSS=y CONFIG_OPENSSL=y export CONFIG_BOOT_DEV="/dev/vda1" export CONFIG_BOARD_NAME="qemu-coreboot-whiptail-tpm2-hotp" # Use the GPG-injected ROM if a key was given, since we can't reflash a GPG # keyring in QEMU. Otherwise use the plain ROM, some things can still be tested # that way without a GPG key. ifneq "$(PUBKEY_ASC)" "" QEMU_BOOT_ROM := $(build)/$(BOARD)/$(CB_OUTPUT_FILE_GPG_INJ) else QEMU_BOOT_ROM := $(build)/$(BOARD)/$(CB_OUTPUT_FILE) endif #borrowed from https://github.com/orangecms/webboot/blob/boot-via-qemu/run-webboot.sh TPMDIR=$(build)/$(BOARD)/vtpm $(TPMDIR)/.manufacture: mkdir -p "$(TPMDIR)" swtpm_setup --create-config-files skip-if-exist swtpm_setup --tpm-state "$(TPMDIR)" --create-platform-cert --lock-nvram --tpm2 touch "$(TPMDIR)/.manufacture" ROOT_DISK_IMG=$(build)/$(BOARD)/root.qcow2 # Default to 20G disk QEMU_DISK_SIZE?=20G $(ROOT_DISK_IMG): qemu-img create -f qcow2 "$(ROOT_DISK_IMG)" $(QEMU_DISK_SIZE) # Remember the amount of memory so it doesn't have to be specified every time. # Default to 4G, most bootable OSes are not usable with less. QEMU_MEMORY_SIZE?=4G MEMORY_SIZE_FILE=$(build)/$(BOARD)/memory $(MEMORY_SIZE_FILE): @echo "$(QEMU_MEMORY_SIZE)" >"$(MEMORY_SIZE_FILE)" USB_FD_IMG=$(build)/$(BOARD)/usb_fd.raw $(USB_FD_IMG): dd if=/dev/zero bs=1M of="$(USB_FD_IMG)" bs=1M count=128 # Debian obnoxiously does not include /usr/sbin in PATH for non-root, even # though it is meaningful to use mkfs.vfat (etc.) as non-root MKFS_VFAT=mkfs.vfat; \ [ -x /usr/sbin/mkfs.vfat ] && MKFS_VFAT=/usr/sbin/mkfs.vfat; \ "$$MKFS_VFAT" "$(USB_FD_IMG)" # Pass INSTALL_IMG= to attach an installer as a USB flash drive instead # of the temporary flash drive for exporting GPG keys. ifneq "$(INSTALL_IMG)" "" QEMU_USB_FD_IMG := $(INSTALL_IMG) else QEMU_USB_FD_IMG := $(USB_FD_IMG) endif # To forward a USB token, set USB_TOKEN to one of the following: # - NitrokeyPro - forwards a Nitrokey Pro by VID:PID # - LibremKey - forwards a Librem Key by VID:PID # - - Provide the QEMU usb-host parameters, such as # 'hostbus=<#>,hostport=<#>' or 'vendorid=<#>,productid=<#>' ifeq "$(USB_TOKEN)" "NitrokeyPro" QEMU_USB_TOKEN_DEV := -device usb-host,vendorid=8352,productid=16648 else ifeq "$(USB_TOKEN)" "NitrokeyStorage" QEMU_USB_TOKEN_DEV := -device usb-host,vendorid=8352,productid=16649 else ifeq "$(USB_TOKEN)" "Nitrokey3NFC" QEMU_USB_TOKEN_DEV := -device usb-host,vendorid=8352,productid=17074 else ifeq "$(USB_TOKEN)" "LibremKey" QEMU_USB_TOKEN_DEV := -device usb-host,vendorid=12653,productid=19531 else ifneq "$(USB_TOKEN)" "" QEMU_USB_TOKEN_DEV := -device "usb-host,$(USB_TOKEN)" endif run: $(TPMDIR)/.manufacture $(ROOT_DISK_IMG) $(MEMORY_SIZE_FILE) $(USB_FD_IMG) swtpm socket \ --tpm2 \ --tpmstate dir="$(TPMDIR)" \ --flags "startup-clear" \ --terminate \ --ctrl type=unixio,path="$(TPMDIR)/sock" & sleep 0.5 -qemu-system-x86_64 -drive file="$(ROOT_DISK_IMG)",if=virtio \ --machine q35,accel=kvm:tcg \ -rtc base=utc \ -smp "$$(nproc)" \ -vga std \ -m "$$(cat "$(MEMORY_SIZE_FILE)")" \ -serial stdio \ --bios "$(QEMU_BOOT_ROM)" \ -object rng-random,filename=/dev/urandom,id=rng0 \ -device virtio-rng-pci,rng=rng0 \ -netdev user,id=u1 -device e1000,netdev=u1 \ -chardev socket,id=chrtpm,path="$(TPMDIR)/sock" \ -tpmdev emulator,id=tpm0,chardev=chrtpm \ -device tpm-tis,tpmdev=tpm0 \ -device qemu-xhci,id=usb \ -device usb-tablet \ -drive file="$(QEMU_USB_FD_IMG)",if=none,id=usb-fd-drive,format=raw \ -device usb-storage,bus=usb.0,drive=usb-fd-drive \ $(QEMU_USB_TOKEN_DEV) \ stty sane @echo