Build time configuration for startup scripts and modules.

This addresses multiple issues:

* Issue #63: initrd is build fresh each time, so tracked files do not matter.
* Issue #144: build time configuration
* Issue #123: allows us to customize the startup experience
* Issue #122: manual start-xen will go away
* Issue #25: tpmtotp PCRs are updated after reading the secret
* Issue #16: insmod now meaures modules
This commit is contained in:
Trammell Hudson 2017-03-31 11:18:46 -04:00
parent 581602e5b4
commit c40748aa25
No known key found for this signature in database
GPG Key ID: C7CFA251FF608213
26 changed files with 221 additions and 89 deletions

View File

@ -1,12 +1,10 @@
modules :=
modules-y :=
pwd := $(shell pwd)
packages := $(pwd)/packages
build := $(pwd)/build
config := $(pwd)/build
INSTALL := $(pwd)/install
log_dir := $(build)/log
initrd_lib_dir := initrd/lib
initrd_bin_dir := initrd/bin
# Controls how many parallel jobs are invoked in subshells
MAKE_JOBS ?= -j8 --max-load 24
@ -37,6 +35,17 @@ LOCAL_MAKE_VERSION := $(shell $(MAKE) --version | head -1 | cut -d' ' -f3)
include modules/make
ifeq "$(LOCAL_MAKE_VERSION)" "$(make_version)"
# Create a temporary directory for the initrd
initrd_dir := $(shell mktemp -d)
initrd_lib_dir := $(initrd_dir)/lib
initrd_bin_dir := $(initrd_dir)/bin
$(shell mkdir -p "$(initrd_lib_dir)" "$(initrd_bin_dir)")
$(shell echo "Initrd: $initrd_dir")
include $(CONFIG)
# We are running our own version of make,
# proceed with the build.
@ -81,7 +90,7 @@ include modules/*
# These will be built via their intermediate targets
# This increases the build time, so it is commented out for now
#all: $(foreach m,$(modules),$m.intermediate)
#all: $(foreach m,$(modules-y),$m.intermediate)
define bins =
$(foreach m,$1,$(call prefix,$(build)/$($m_dir)/,$($m_output)))
@ -197,7 +206,7 @@ define define_module =
endef
$(call map, define_module, $(modules))
$(call map, define_module, $(modules-y))
#
@ -223,7 +232,6 @@ endef
define initrd_lib_add =
$(initrd_lib_dir)/$(notdir $1): $1
@-mkdir -p "$(dir $$@)"
$(call do,INSTALL-LIB,$$@,$(CROSS)strip -o "$$@" "$$<")
initrd_libs += $(initrd_lib_dir)/$(notdir $1)
endef
@ -242,7 +250,7 @@ $(foreach m, $(bin_modules), \
)
# Install the libraries for every module that we have built
$(foreach m, $(modules), \
$(foreach m, $(modules-y), \
$(call map,initrd_lib_add,$(call libs,$m)) \
)
@ -289,7 +297,7 @@ $(initrd_lib_dir)/modules/$(notdir $1): $(build)/$(linux_dir)/$1
@-mkdir -p "$(initrd_lib_dir)/modules"
$(call do,INSTALL-MODULE,$$@,$(CROSS)strip --strip-debug -o "$$@" "$$<")
endef
$(call map,linux_module,$(linux_modules))
$(call map,linux_module,$(linux_modules-y))
#
@ -307,13 +315,18 @@ $(call map,linux_module,$(linux_modules))
#
#
initrd.cpio: $(initrd_bins) $(initrd_libs) dev.cpio FORCE
$(call do,OVERLAY,initrd,\
tar -C ./initrd -cf - . | tar -C "$(initrd_dir)" -xf - \
)
$(call do,INSTALL,$(CONFIG),cp "$(CONFIG)" "$(initrd_dir)/config")
$(call do,CPIO,$@, \
cd ./initrd ; \
cd "$(initrd_dir)"; \
find . \
| cpio --quiet -H newc -o \
| ../cpio-clean ../dev.cpio - \
> "../$@" \
| $(pwd)/cpio-clean $(pwd)/dev.cpio - \
> "$(pwd)/$@" \
)
echo should $(RM) -rf "$(initrd_dir)"
initrd.intermediate: initrd.cpio

18
config/qemu-moc.config Normal file
View File

@ -0,0 +1,18 @@
# Configuration for building the MOC "server" build on the x230
# thinkpad prototypes.
BOARD=qemu
CONFIG_CRYPTSETUP=y
CONFIG_FLASHROM=y
CONFIG_GPG=y
CONFIG_KEXEC=y
CONFIG_LIBUUID=y
CONFIG_LVM2=y
CONFIG_MBEDTLS=y
CONFIG_PCIUTILS=y
CONFIG_POPT=y
CONFIG_QRENCODE=y
CONFIG_TPMTOTP=y
CONFIG_XEN=n
CONFIG_LINUX_USB=y
CONFIG_LINUX_E1000=y

20
config/x230-moc.config Normal file
View File

@ -0,0 +1,20 @@
# Configuration for building the MOC "server" build on the x230
# thinkpad prototypes.
BOARD=x230
CONFIG_CRYPTSETUP=y
CONFIG_FLASHROM=y
CONFIG_GPG=y
CONFIG_KEXEC=y
CONFIG_LIBUUID=y
CONFIG_LVM2=y
CONFIG_MBEDTLS=y
CONFIG_PCIUTILS=y
CONFIG_POPT=y
CONFIG_QRENCODE=y
CONFIG_TPMTOTP=y
CONFIG_XEN=n
CONFIG_LINUX_USB=y
CONFIG_LINUX_E1000E=y
CONFIG_BOOTSCRIPT=/etc/keylime-init

17
config/x230-qubes.config Normal file
View File

@ -0,0 +1,17 @@
# Configuration for a x230 running Qubes OS
BOARD=x230
CONFIG_CRYPTSETUP=y
CONFIG_FLASHROM=y
CONFIG_GPG=y
CONFIG_KEXEC=y
CONFIG_LIBUUID=y
CONFIG_LVM2=y
CONFIG_MBEDTLS=y
CONFIG_PCIUTILS=y
CONFIG_POPT=y
CONFIG_QRENCODE=y
CONFIG_TPMTOTP=y
CONFIG_XEN=y
CONFIG_LINUX_USB=y
CONFIG_LINUX_E1000E=y

17
initrd/etc/keylime-init Executable file
View File

@ -0,0 +1,17 @@
#!/bin/sh
# Bring up the x230's NIC, get a DHCP address and invoke keylime
insmod /lib/modules/e1000e.ko
udhcpc -n
cd /
wget-measure.sh 6 http://192.168.1.5/keylime.tar.gz
tar xf keylime.tar.gz
if [ ! -x /keylime-node ]; then
echo '!!!! Keylime overlay not found?'
tpm extend -ix 4 -ic "recovery"
exec /bin/ash
fi
exec /keylime-node

8
initrd/etc/motd Normal file
View File

@ -0,0 +1,8 @@
=====================================================
_ _ _ ____ ___ __ __
| | | | ___ __ _ __| |___ _ | _ \ / _ \| \/ |
| |_| |/ _ \/ _` |/ _` / __| (_) | |_) | | | | |\/| |
| _ | __/ (_| | (_| \__ \ _ | _ <| |_| | | | |
|_| |_|\___|\__,_|\__,_|___/ (_) |_| \_\\___/|_| |_|
=====================================================

View File

@ -5,29 +5,61 @@ mount -t devtmpfs none /dev
mount -t proc none /proc
mount -t sysfs none /sys
# Setup our path
export PATH=/sbin:/bin
# Now it is safe to print a banner
echo '====================================================='
echo ' _ _ _ ____ ___ __ __ '
echo '| | | | ___ __ _ __| |___ _ | _ \ / _ \| \/ |'
echo '| |_| |/ _ \/ _` |/ _` / __| (_) | |_) | | | | |\/| |'
echo '| _ | __/ (_| | (_| \__ \ _ | _ <| |_| | | | |'
echo '|_| |_|\___|\__,_|\__,_|___/ (_) |_| \_\\___/|_| |_|'
echo ''
echo '====================================================='
if [ -r /etc/motd ]; then
cat /etc/motd
fi
# Load the date from the hardware clock, setting it in local time
hwclock -l -s
# Verify the user's TPM secret
echo "TPM TOTP:"
if ! unsealtotp.sh ; then
echo '!!!!!'
echo '!!!!! TPM TOTP secret not found.'
echo '!!!!! This firmware can not be trusted.'
echo '!!!!!'
fi
echo
# Read the system configuration parameters
. /config
# Start an interactive shell
export PATH=/sbin:/usr/sbin:/bin:/usr/bin
exec /bin/ash
if [ -z "$CONFIG_TIMEOUT" ]; then
CONFIG_TIMEOUT=10
fi
while true; do
# Verify the user's TPM secret
echo "TPM TOTP:"
if ! unsealtotp.sh ; then
echo '!!!!!'
echo '!!!!! TPM TOTP secret not found.'
echo '!!!!! This firmware can not be trusted.'
echo '!!!!! Entering recovery shell'
echo '!!!!!'
tpm extend -ix 4 -ic "tpm-failure"
exec /bin/ash
fi
# Secret decrypted ok, so prompt for a next step
read \
-t "$CONFIG_TIMEOUT" \
-p "Enter for normal boot or 'r' for recovery shell: " \
-n 1 \
boot_option
if [ "$boot_option" = "r" ]; then
# Start an interactive shell
echo '***** Starting recovery shell'
tpm extend -ix 4 -ic "recovery"
exec /bin/ash
fi
if [ "$boot_option" = "" ]; then
if [ ! -x "$CONFIG_BOOTSCRIPT" ]; then
echo '!!!!! Boot script missing? Entering recovery shell'
tpm extend -ix 4 -ic "boot-failure"
exec /bin/ash
fi
echo '***** Normal boot'
tpm extend -ix 4 -ic "normal-boot"
exec "$CONFIG_BOOTSCRIPT"
fi
done

37
initrd/sbin/insmod Executable file
View File

@ -0,0 +1,37 @@
#!/bin/sh
# extend a TPM PCR with a module and then load it
# any arguments will also be measured.
# The default PCR to be extended is 5, but can be
# overridden with the MODULE_PCR environment variable
die() {
echo >&2 "$@"
exit 1
}
MODULE="$1"; shift
if [ -z "$MODULE_PCR" ]; then
MODULE_PCR=5
fi
if [ -z "$MODULE" ]; then
die "Usage: $0 module [args...]"
fi
if [ ! -r "$MODULE" ]; then
die "$MODULE: not found?"
fi
tpm extend -ix "$MODULE_PCR" -if "$MODULE" || die "$MODULE: tpm extend failed"
if [ ! -z "$@" ]; then
TMPFILE=/tmp/insmod.$$
echo "$@" > $TMPFILE
tpm extend -ix "$MODULE_PCR" -if $TMPFILE || die "$MODULE: tpm extend on arguments failed"
fi
# Since we have replaced the real insmod, we must invoke
# the busybox insmod via the original executable
busybox insmod "$MODULE" "$@" || die "$MODULE: insmod failed"

View File

@ -1,29 +0,0 @@
#!/bin/sh
# extend a TPM PCR with a module and then load it
# any arguments will also be measured
die() {
echo >&2 "$@"
exit 1
}
INDEX="$1"; shift
MODULE="$1"; shift
if [ -z "$INDEX" -o -z "$MODULE" ]; then
die "Usage: $0 pcr-index module [args...]"
fi
if [ ! -r "$MODULE" ]; then
die "$MODULE: not found?"
fi
tpm extend -ix "$INDEX" -if "$MODULE" || die "$MODULE: tpm extend failed"
if [ ! -z "$@" ]; then
TMPFILE=/tmp/insmod.$$
echo "$@" > $TMPFILE
tpm extend -ix "$INDEX" -if $TMPFILE || die "$MODULE: tpm extend on arguments failed"
fi
insmod "$MODULE" "$@" || die "$MODULE: insmod failed"

View File

@ -1,4 +1,4 @@
modules += busybox
modules-y += busybox
busybox_version := 1.25.0
busybox_dir := busybox-$(busybox_version)
@ -11,7 +11,7 @@ busybox_config := busybox.config
busybox_output := busybox
busybox_target := \
CC="$(heads_cc)" \
CONFIG_PREFIX="../../initrd/" \
CONFIG_PREFIX="$(initrd_dir)" \
$(MAKE_JOBS) \
install

View File

@ -1,4 +1,4 @@
modules += coreboot
modules-y += coreboot
#coreboot_version := git
#coreboot_repo := https://github.com/osresearch/coreboot
@ -52,7 +52,7 @@ ifneq "$(coreboot_version)" "git"
# if we are not building from a git checkout,
# we must also download the coreboot-blobs tree
coreboot_depends += coreboot-blobs
modules += coreboot-blobs
modules-y += coreboot-blobs
coreboot-blobs_version := $(coreboot_version)
coreboot-blobs_tar := coreboot-blobs-$(coreboot-blobs_version).tar.xz

View File

@ -1,4 +1,4 @@
modules += cryptsetup
modules-$(CONFIG_CRYPTSETUP) += cryptsetup
cryptsetup_depends := libuuid popt lvm2 $(musl_dep)

View File

@ -1,4 +1,4 @@
modules += flashrom
modules-$(CONFIG_FLASHROM) += flashrom
flashrom_depends := pciutils $(musl_dep)

View File

@ -1,4 +1,4 @@
modules += gpg
modules-$(CONFIG_GPG) += gpg
# we install gpgv 1.4, which is an older version that has fewer
# dependencies. This may need to be revisted later.

View File

@ -1,4 +1,4 @@
modules += kernel-headers
modules-y += kernel-headers
# we install kernel-headers from sabotage linux, a musl-libc based
# distribution, that works well with busybox and other tools.

View File

@ -1,4 +1,4 @@
modules += libuuid
modules-$(CONFIG_LIBUUID) += libuuid
libuuid_version := 1.0.3
libuuid_dir := libuuid-$(libuuid_version)

View File

@ -1,4 +1,4 @@
modules += linux
modules-y += linux
linux_version := 4.9.7
linux_dir := linux-$(linux_version)
@ -17,15 +17,14 @@ linux_configure := \
linux_output := arch/x86/boot/bzImage
linux_config := linux.config
linux_modules := \
drivers/net/ethernet/intel/e1000/e1000.ko \
drivers/net/ethernet/intel/e1000e/e1000e.ko \
drivers/usb/host/xhci-hcd.ko \
drivers/usb/host/ehci-platform.ko \
drivers/usb/host/ehci-hcd.ko \
drivers/usb/host/xhci-plat-hcd.ko \
drivers/usb/host/xhci-pci.ko \
drivers/usb/host/ehci-pci.ko \
linux_modules-$(CONFIG_LINUX_E1000) += drivers/net/ethernet/intel/e1000/e1000.ko
linux_modules-$(CONFIG_LINUX_E1000E) += drivers/net/ethernet/intel/e1000e/e1000e.ko
#linux_modules-$(CONFIG_LINUX_USB) += drivers/usb/host/ehci-platform.ko
linux_modules-$(CONFIG_LINUX_USB) += drivers/usb/host/ehci-hcd.ko
linux_modules-$(CONFIG_LINUX_USB) += drivers/usb/host/ehci-pci.ko
linux_modules-$(CONFIG_LINUX_USB) += drivers/usb/host/xhci-hcd.ko
#linux_modules-$(CONFIG_LINUX_USB) += drivers/usb/host/xhci-plat-hcd.ko
linux_modules-$(CONFIG_LINUX_USB) += drivers/usb/host/xhci-pci.ko
EXTRA_FLAGS := -fdebug-prefix-map=$(pwd)=heads -gno-record-gcc-switches

View File

@ -1,4 +1,4 @@
modules += lvm2
modules-$(CONFIG_LVM2) += lvm2
lvm2_version := 2.02.168
lvm2_dir := LVM2.$(lvm2_version)

View File

@ -1,4 +1,4 @@
modules += mbedtls
modules-$(CONFIG_MBEDTLS) += mbedtls
mbedtls_version := 2.4.2
mbedtls_dir := mbedtls-$(mbedtls_version)

View File

@ -1,4 +1,4 @@
modules += musl
modules-y += musl
musl_version := 1.1.15
musl_dir := musl-$(musl_version)

View File

@ -1,4 +1,4 @@
modules += musl-cross
modules-y += musl-cross
musl-cross_version := git
musl-cross_dir := musl-cross-$(musl-cross_version)

View File

@ -1,4 +1,4 @@
modules += pciutils
modules-$(CONFIG_PCIUTILS) += pciutils
pciutils_depends := $(musl_dep)

View File

@ -1,4 +1,4 @@
modules += popt
modules-$(CONFIG_POPT) += popt
popt_version := 1.16
popt_dir := popt-$(popt_version)

View File

@ -1,4 +1,4 @@
modules += qrencode
modules-$(CONFIG_QRENCODE) += qrencode
qrencode_version := 3.4.4
qrencode_dir := qrencode-$(qrencode_version)

View File

@ -1,4 +1,4 @@
modules += tpmtotp
modules-$(CONFIG_TPMTOTP) += tpmtotp
tpmtotp_depends := mbedtls qrencode $(musl_dep)

View File

@ -1,4 +1,4 @@
modules += xen
modules-$(CONFIG_XEN) += xen
# We extract the entire Xen tree, but only use the xen/xen hypervisor
# portion since Qubes provides the rest of it.
@ -8,6 +8,6 @@ xen_tar := xen-$(xen_version).tar.gz
xen_url := http://bits.xensource.com/oss-xen/release/4.6.3/xen-4.6.3.tar.gz
xen_hash := 02badfce9a037bd1bd4a94210c1f6b85467746216c71795805102b514bcf1fc4
xen_output := xen.gz
xen_output :=
xen_configure :=
xen_target := $(MAKE_JOBS)