Skip to content

Commit

Permalink
Demo OS: support Secure GRUB
Browse files Browse the repository at this point in the history
This adds the new demo-efi directory to the installer build.
Depending on security settings, it may contain:

shimx64.efi  <- shim signed for secure boot
grubx64.efi  <- GRUB signed for secure boot
grub.cfg     <- a grub.cfg to disable GRUB signature checking
grub.cfg.sig <- signature of ^^ grub.cfg so secure GRUB will
                 not reject it.

These files get installed under /boot/efi/EFI/ONIE-DEMO-OS

Previously the Demo OS was able to install by copying over
the efi binaries installed under /boot/efi/EFI/ONIE, as they
were already signed to be part of the Secure Boot chain
of trust.

This is a bit unrealistic for a real NOS, as it will be
deploying it's own signed shim/GRUB, etc, so requiring
the Demo OS to deploy its own copies of these binaries
will help demonstrate the concept and allow for different
testing configurations.

Copying the contents of the /boot/efi/EFI/ONIE directory
also falls apart with Secure GRUB, where GRUB is compiled
to validate the config files it loads against their detached
signature (*.sig) files. The Demo OS GRUB config was
generated during install, and thus could not be signed.

So, onie/demo/installer/grub-arch/grub.cfg has been added
as the grub.cfg that ends up under /boot/efi/EFI/ONIE-DEMO-OS
It gets signed during demo make, and is added to the
demo-efi directory (along with shim, GRUB, and the
grub.cfg.sig detached signature), to be present when
GRUB goes to boot Demo OS.

Astute developers may note that the first thing this
config does is switch off GRUB's check_signatures so
the rest of the generated GRUB configuration can load.
...but it serves its purpose of demonstrating how
this works.

Also note, once the Demo OS is loaded, the
GRUB login and password will be required to
chain load the ONIE boot menu.
This demonstrates the use of the password to
do any additional configuration.
If this behavior is undesirable, 50_onie_grub
can be edited to have '--unrestricted' in the
ONIE GRUB entry to NOT require a Secure GRUB login.
...and there is a comment there saying as much.

Testing:
---------
 Demo OS builds, boots, and can be logged in to with:
  SECURE_BOOT_ENABLE yes/no (no required alternate kernel config)
  SECURE_BOOT_EXT    yes/no
  SECURE_GRUB        yes/no

Signed-off-by: Alex Doyle <[email protected]>
  • Loading branch information
ehdoyle committed Jul 31, 2021
1 parent 0275da5 commit 1e0eb99
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 19 deletions.
20 changes: 19 additions & 1 deletion build-config/make/demo.make
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ DEMO_UIMAGE = $(IMAGEDIR)/demo-$(PLATFORM).itb
DEMO_OS_BIN = $(IMAGEDIR)/demo-installer-$(PLATFORM).bin
DEMO_DIAG_BIN = $(IMAGEDIR)/demo-diag-installer-$(PLATFORM).bin

# Files for the installer to put under /boot/efi/EFI/ONIE-DEMO-OS
DEMO_EFI_DIR = $(MBUILDDIR)/demo-efi

DEMO_SYSROOT_COMPLETE_STAMP = $(STAMPDIR)/demo-sysroot-complete
DEMO_KERNEL_COMPLETE_STAMP = $(STAMPDIR)/demo-kernel-complete
DEMO_UIMAGE_COMPLETE_STAMP = $(STAMPDIR)/demo-uimage-complete
Expand Down Expand Up @@ -107,11 +110,25 @@ endif

define demo_MKIMAGE
./scripts/onie-mk-demo.sh $(ROOTFS_ARCH) $(MACHINE) $(PLATFORM) \
$(DEMO_INSTALLER_DIR) $(MACHINEDIR)/demo/platform.conf $(1) $(2) $(DEMO_IMAGE_PARTS)
$(DEMO_INSTALLER_DIR) $(MACHINEDIR)/demo/platform.conf $(DEMO_EFI_DIR) \
$(1) $(2) $(DEMO_IMAGE_PARTS)
endef

$(DEMO_OS_BIN) : $(DEMO_IMAGE_PARTS_COMPLETE) $(MACHINE_DEMO_DIR)/*
$(Q) echo "==== Create demo OS $(PLATFORM) self-extracting archive ===="
$(Q) mkdir -p $(DEMO_EFI_DIR)
ifeq ($(SECURE_BOOT_ENABLE),yes)
$(Q) echo "==== Copying in signed efi binaries. ===="
$(Q) cp $(MBUILDDIR)/grubx64.efi $(DEMO_EFI_DIR)
$(Q) cp $(MBUILDDIR)/shim/install/shimx64.efi $(DEMO_EFI_DIR)
$(Q) cp $(DEMO_INSTALLER_DIR)/grub-arch/grub.cfg $(DEMO_EFI_DIR)
# Sign the Demo OS grub config file
ifeq ($(SECURE_GRUB),yes)
# Use the Demo OS grub.cfg that disables further GRUB detached signature checking
# Naturally, this has to have a detached signature to be used by GRUB
$(SCRIPTDIR)/gpg-sign.sh $(GPG_SIGN_SECRING) $(DEMO_EFI_DIR)/grub.cfg
endif
endif
$(Q) $(call demo_MKIMAGE, $@, OS)

$(DEMO_DIAG_BIN) : $(DEMO_OS_BIN)
Expand All @@ -126,6 +143,7 @@ $(DEMO_IMAGE_COMPLETE_STAMP): $(DEMO_ARCH_BINS)
MACHINE_CLEAN += demo-clean
demo-clean:
$(Q) rm -rf $(DEMO_SYSROOTDIR)
$(Q) rm -rf $(DEMO_EFI_DIR)
$(Q) rm -f $(MBUILDDIR)/demo-* $(DEMO_IMAGE_PARTS) $(DEMO_OS_BIN) $(DEMO_DIAG_BIN)
$(Q) rm -f $(DEMO_SYSROOT_COMPLETE_STAMP) $(DEMO_IMAGE_COMPLETE_STAMP)
$(Q) rm -f $(DEMO_IMAGE_PARTS_COMPLETE)
Expand Down
20 changes: 17 additions & 3 deletions build-config/scripts/onie-mk-demo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@ machine=$2
platform=$3
installer_dir=$4
platform_conf=$5
output_file=$6
demo_type=$7
efi_binary_dir=$6
output_file=$7
demo_type=$8

shift 7
shift 8

if [ ! -d $installer_dir ] || \
[ ! -r $installer_dir/sharch_body.sh ] ; then
Expand Down Expand Up @@ -68,6 +69,19 @@ tmp_installdir="$tmp_dir/installer"
mkdir $tmp_installdir || clean_up 1

cp $installer_dir/$arch_dir/install.sh $tmp_installdir || clean_up 1
if [ -e "$efi_binary_dir" ];then
# If Secure Boot is active, then the Demo OS will need it's own
# signed efi binaries to install in /boot/efi/EFI/ONIE-DEMO-OS.
# If Secure Grub is active, a detached signature for the cfg file
# will be needed as well.
# This directory may contain:
# grubx64.efi
# shmx64.efi
# grub.cfg
# grub.cfg.sig
cp -r "${efi_binary_dir}" "$tmp_installdir"/ || clean_up 1

fi

# Tailor the demo installer for OS mode or DIAG mode
sed -i -e "s/%%DEMO_TYPE%%/$demo_type/g" \
Expand Down
15 changes: 15 additions & 0 deletions demo/installer/grub-arch/grub.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Set configuration to use in /mnt/onie-boot/grub
# For demo OS
# If Secure Grub is in use, this file will require
# a detached signature to be deployed with it, so
# that grub will use it.
# Note that the first step here is disabling
# signatures so that the Demo OS' dynamically
# created GRUB config can be used.
# Further signing is left as an exercise for the developer
set check_signatures=no
export check_signatures
search --no-floppy --label --set=root ONIE-DEMO-OS
set prefix=($root)'/grub'
configfile $prefix/grub.cfg

33 changes: 18 additions & 15 deletions demo/installer/grub-arch/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -266,26 +266,23 @@ demo_install_uefi_grub()
echo "ERROR: Unable to create directory: $loader_dir"
exit 1
}
# Use ONIE's .efi binaries
cp -a /boot/efi/EFI/onie/*${onie_uefi_arch}.efi "$loader_dir" || {
echo "ERROR: Unable to copy ONIE .efi binaries to: $loader_dir"
exit 1
}
# Copy installer specific shim/grub to efi destination.
# This would be files required for Secure Boot, like:
# shimx64.efi
# grubx64.efi
# grub.cfg
# grub.cfg.sig
cp "${demo_mnt}"/demo-efi/* "$loader_dir" || {
echo "ERROR: failed to find ${demo_mnt}/demo-efi directory with demo efi binaries."
return 1
}
local demo_boot_uuid=$(grub-probe --target=fs_uuid $demo_mnt) || {
echo "ERROR: Unable to determine UUID of GRUB boot directory: $demo_mnt"
return 1
}
# Generate tiny grub config for monolithic image
cat<< EOF > "${loader_dir}/grub.cfg"
search.fs_uuid $demo_boot_uuid root
echo "Search for uuid $demo_boot_uuid"
echo "Found root: \$root"
set prefix=(\$root)'/grub'
configfile \$prefix/grub.cfg
EOF
# Install primary grub config in $demo_mnt
grub_dir="${demo_mnt}/grub"
mkdir -p "${grub_dir}/fonts" "${grub_dir}/locale"
Expand Down Expand Up @@ -363,6 +360,10 @@ mount -t ext4 -o defaults,rw $demo_dev $demo_mnt || {
# Copy kernel and initramfs to demo file system
cp demo.vmlinuz demo.initrd $demo_mnt
# Copy any signed files required for Secure Boot
if [ -d demo-efi ];then
cp -r demo-efi $demo_mnt/
fi
# store installation log in demo file system
onie-support $demo_mnt
Expand Down Expand Up @@ -447,9 +448,11 @@ fi
EOF
# Add a menu entry for the DEMO OS
# Use --unrestricted so it does not ask the user for
# Grub login/password to execute.
demo_grub_entry="Demo $demo_type"
cat <<EOF >> $grub_cfg
menuentry '$demo_grub_entry' {
menuentry '$demo_grub_entry' --unrestricted {
search --no-floppy --label --set=root $demo_volume_label
echo 'Loading ONIE Demo $demo_type kernel ...'
linux /demo.vmlinuz $GRUB_CMDLINE_LINUX \$ONIE_EXTRA_CMDLINE_LINUX DEMO_TYPE=$demo_type
Expand Down
1 change: 1 addition & 0 deletions installer/grub-arch/grub.d/50_onie_grub
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ if [ -d "/sys/firmware/efi/efivars" ] && [ -r "${uefi_root}/${onie_uefi_loader}"
}
cat <<EOF
# Menu entry to chainload ONIE UEFI
# Insert --unrestricted to NOT require a Secure Grub login.
menuentry ONIE {
set root='(hd0,gpt1)'
search --no-floppy --fs-uuid --set=root ${uefi_uuid}
Expand Down

0 comments on commit 1e0eb99

Please sign in to comment.