diff --git a/build_debian.sh b/build_debian.sh index 1486be65c0f..cf12859260c 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -35,6 +35,10 @@ DOCKER_VERSION=5:20.10.14~3-0~debian-$IMAGE_DISTRO CONTAINERD_IO_VERSION=1.5.11-1 LINUX_KERNEL_VERSION=5.10.0-18-2 +## EFI bootloader for UEFI secureboot +GRUB2_EFI_VERSION=2.06-3~deb11u1 +SHIM_EFI_VERSION=15.6-1~deb11u1 + ## Working directory to prepare the file system FILESYSTEM_ROOT=./fsroot PLATFORM_DIR=platform @@ -154,8 +158,35 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in if [[ $CONFIGURED_ARCH == amd64 ]]; then sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install dmidecode hdparm fi +#Secure boot grub-efi +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/grub-efi-${CONFIGURED_ARCH}-bin_${GRUB2_EFI_VERSION}_${CONFIGURED_ARCH}.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f +#Secure shim +sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/shim-unsigned_${SHIM_EFI_VERSION}_${CONFIGURED_ARCH}.deb || \ + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f + +## Sign EFI images +sign_efi_image(){ + image_path=$1 + file_name=$(basename $image_path) + + if [ ! -f $image_path ]; then + echo "Error: image to sign not found: ${image_path}" + exit 1 + fi + + #Check if vendor using vendor specific signing + if [ -n "$SONIC_VENDOR_SIGNING_TOOL" ]; then + echo '[INFO] Vendor Specific Signing: ${file_name}' + /bin/bash -c "$SONIC_VENDOR_SIGNING_TOOL --output /tmp/${file_name} ${image_path}" + else + echo '[INFO] sbsign: ${file_name}' + sbsign --key $SIGNING_KEY --cert $SIGNING_CERT --output /tmp/${file_name} ${image_path} + fi + + sudo cp -f /tmp/${file_name} ${image_path} +} -## Sign the Linux kernel if [ "$SONIC_ENABLE_SECUREBOOT_SIGNATURE" = "y" ]; then if [ ! -f $SIGNING_KEY ]; then echo "Error: SONiC linux kernel signing key missing" @@ -166,10 +197,17 @@ if [ "$SONIC_ENABLE_SECUREBOOT_SIGNATURE" = "y" ]; then exit 1 fi - echo '[INFO] Signing SONiC linux kernel image' - K=$FILESYSTEM_ROOT/boot/vmlinuz-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH} - sbsign --key $SIGNING_KEY --cert $SIGNING_CERT --output /tmp/${K##*/} ${K} - sudo cp -f /tmp/${K##*/} ${K} + sign_efi_image $FILESYSTEM_ROOT/boot/vmlinuz-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH} + + #Grub2 + sign_efi_image $FILESYSTEM_ROOT/usr/lib/grub/x86_64-efi/monolithic/grubx64.efi + + #Shim artifacts + for efi_image in fbx64.efi mmx64.efi shimx64.efi + do + sign_efi_image $FILESYSTEM_ROOT/usr/lib/shim/$efi_image + done + fi ## Update initramfs for booting with squashfs+overlay diff --git a/installer/default_platform.conf b/installer/default_platform.conf index c0758b6fb94..4b0a92cf581 100755 --- a/installer/default_platform.conf +++ b/installer/default_platform.conf @@ -306,6 +306,67 @@ demo_install_grub() } +demo_install_uefi_sb_artifacts() +{ + local demo_mnt="$1" + local blk_dev="$2" + + # make sure /boot/efi is mounted + if ! mount | grep -q "/boot/efi"; then + mount /boot/efi + fi + + # Look for the EFI system partition UUID on the same block device as + # the ONIE-BOOT partition. + local uefi_part=0 + for p in $(seq 8) ; do + if sgdisk -i $p $blk_dev | grep -q C12A7328-F81F-11D2-BA4B-00A0C93EC93B ; then + uefi_part=$p + break + fi + done + + [ $uefi_part -eq 0 ] && { + echo "ERROR: Unable to determine UEFI system partition" + exit 1 + } + + local loader_dir="/boot/efi/EFI/$demo_volume_label" + mkdir -p "$loader_dir" || { + echo "ERROR: Unable to create directory: $loader_dir" + exit 1 + } + uefi_loader=$demo_mnt/$image_dir/boot + + # copy shim efi binaries into loader directory + for f in shim mm fb grub ; do + local loader="${f}${onie_uefi_arch}.efi" + cp "$uefi_loader/$loader" $loader_dir || { + echo "ERROR: Unable to copy loader file: $loader to loader_dir: $loader_dir" + return 1 + } + done + + # Generate tiny grub config for monolithic image + mkdir -p /boot/efi/EFI/debian + cat<< EOF > "/boot/efi/EFI/debian/grub.cfg" +search.fs_uuid $demo_boot_uuid 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" + + efibootmgr --quiet --create \ + --label "$demo_volume_label" \ + --disk $blk_dev --part $uefi_part \ + --loader "/EFI/$demo_volume_label/shimx64.efi" || { + echo "ERROR: efibootmgr failed to create new boot variable on: $blk_dev" + exit 1 + } +} + # Install UEFI BIOS GRUB for DEMO OS demo_install_uefi_grub() { @@ -370,9 +431,12 @@ bootloader_menu_config() mv $onie_initrd_tmp/tmp/onie-support*.tar.bz2 $demo_mnt/$image_dir/ if [ "$firmware" = "uefi" ] ; then - demo_install_uefi_grub "$demo_mnt" "$blk_dev" + if [ "$onie_secure_boot" = "yes" ] ; then + demo_install_uefi_sb_artifacts "$demo_mnt" "$blk_dev" + else + demo_install_uefi_grub "$demo_mnt" "$blk_dev" else - demo_install_grub "$demo_mnt" "$blk_dev" + demo_install_grub "$demo_mnt" "$blk_dev" fi fi diff --git a/rules/config b/rules/config index 9bb3326faa2..16f1f33c303 100644 --- a/rules/config +++ b/rules/config @@ -205,10 +205,11 @@ MASTER_CRI_DOCKERD = 0.2.5 # The relative path is build root folder. SONIC_ENABLE_IMAGE_SIGNATURE ?= n -# SONIC_ENABLE_SECUREBOOT_SIGNATURE - enable SONiC kernel signing to support UEFI secureboot +# SONIC_ENABLE_SECUREBOOT_SIGNATURE - enable SONiC kernel and Grub signing for UEFI secureboot # To support UEFI secureboot chain of trust requires EFI kernel to be signed as a PE binary # SIGNING_KEY = # SIGNING_CERT = +# SONIC_VENDOR_SIGNING_TOOL = # The absolute path should be provided. SONIC_ENABLE_SECUREBOOT_SIGNATURE ?= n diff --git a/rules/grub2.dep b/rules/grub2.dep new file mode 100644 index 00000000000..4c9c7e7f3bf --- /dev/null +++ b/rules/grub2.dep @@ -0,0 +1,10 @@ + +SPATH := $($(GRUB2)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/grub2.mk rules/grub2.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(GRUB2)_CACHE_MODE := GIT_CONTENT_SHA +$(GRUB2)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(GRUB2)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/grub2.mk b/rules/grub2.mk new file mode 100644 index 00000000000..e6b0b377346 --- /dev/null +++ b/rules/grub2.mk @@ -0,0 +1,11 @@ +# Grub2 package + +GRUB2_VERSION = 2.06 +GRUB2_FULL_VERSION = $(GRUB2_VERSION)-3~deb11u1 + +export GRUB2_VERSION +export GRUB2_FULL_VERSION + +GRUB2 = grub-efi-$(CONFIGURED_ARCH)-bin_$(GRUB2_FULL_VERSION)_$(CONFIGURED_ARCH).deb +$(GRUB2)_SRC_PATH = $(SRC_PATH)/grub2 +SONIC_MAKE_DEBS += $(GRUB2) diff --git a/rules/shim.dep b/rules/shim.dep new file mode 100644 index 00000000000..c34807f0faf --- /dev/null +++ b/rules/shim.dep @@ -0,0 +1,10 @@ + +SPATH := $($(SHIM)_SRC_PATH) +DEP_FILES := $(SONIC_COMMON_FILES_LIST) rules/shim.mk rules/shim.dep +DEP_FILES += $(SONIC_COMMON_BASE_FILES_LIST) +DEP_FILES += $(shell git ls-files $(SPATH)) + +$(SHIM)_CACHE_MODE := GIT_CONTENT_SHA +$(SHIM)_DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) +$(SHIM)_DEP_FILES := $(DEP_FILES) + diff --git a/rules/shim.mk b/rules/shim.mk new file mode 100644 index 00000000000..b4d2c1eb88e --- /dev/null +++ b/rules/shim.mk @@ -0,0 +1,11 @@ +# Shim package + +SHIM_VERSION = 15.6 +SHIM_FULL_VERSION = $(SHIM_VERSION)-1~deb11u1 + +export SHIM_VERSION +export SHIM_FULL_VERSION + +SHIM = shim-unsigned_$(SHIM_FULL_VERSION)_$(CONFIGURED_ARCH).deb +$(SHIM)_SRC_PATH = $(SRC_PATH)/shim +SONIC_MAKE_DEBS += $(SHIM) diff --git a/slave.mk b/slave.mk index ae3c6b4dcc3..b6683253896 100644 --- a/slave.mk +++ b/slave.mk @@ -403,6 +403,10 @@ $(info "MULTIARCH_QEMU_ENVIRON" : "$(MULTIARCH_QEMU_ENVIRON)") $(info "SONIC_VERSION_CONTROL_COMPONENTS": "$(SONIC_VERSION_CONTROL_COMPONENTS)") $(info "ENABLE_ASAN" : "$(ENABLE_ASAN)") $(info "DEFAULT_CONTAINER_REGISTRY" : "$(SONIC_DEFAULT_CONTAINER_REGISTRY)") +$(info "SONIC_ENABLE_SECUREBOOT_SIGNATURE" : "$(SONIC_ENABLE_SECUREBOOT_SIGNATURE)") +$(info "SIGNING_KEY" : "$(SIGNING_KEY)") +$(info "SIGNING_CERT" : "$(SIGNING_CERT)") +$(info "SONIC_VENDOR_SIGNING_TOOL" : "$(SONIC_VENDOR_SIGNING_TOOL)") ifeq ($(CONFIGURED_PLATFORM),vs) $(info "BUILD_MULTIASIC_KVM" : "$(BUILD_MULTIASIC_KVM)") endif @@ -1148,6 +1152,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ $(LIBPAM_TACPLUS) \ $(LIBNSS_TACPLUS) \ $(MONIT) \ + $(GRUB2) \ + $(SHIM) \ $(OPENSSH_SERVER) \ $(PYTHON_SWSSCOMMON) \ $(PYTHON3_SWSSCOMMON) \ @@ -1379,6 +1385,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ SONIC_ENABLE_SECUREBOOT_SIGNATURE="$(SONIC_ENABLE_SECUREBOOT_SIGNATURE)" \ SIGNING_KEY="$(SIGNING_KEY)" \ SIGNING_CERT="$(SIGNING_CERT)" \ + SONIC_VENDOR_SIGNING_TOOL="$(SONIC_VENDOR_SIGNING_TOOL)" \ PACKAGE_URL_PREFIX=$(PACKAGE_URL_PREFIX) \ MULTIARCH_QEMU_ENVIRON=$(MULTIARCH_QEMU_ENVIRON) \ CROSS_BUILD_ENVIRON=$(CROSS_BUILD_ENVIRON) \ diff --git a/sonic-slave-bullseye/Dockerfile.j2 b/sonic-slave-bullseye/Dockerfile.j2 index f4f24d847e8..89cf74b24d4 100644 --- a/sonic-slave-bullseye/Dockerfile.j2 +++ b/sonic-slave-bullseye/Dockerfile.j2 @@ -403,6 +403,23 @@ RUN apt-get update && apt-get install -y \ # For audisp-tacplus libauparse-dev \ auditd +# For grub2 + grub-common \ + help2man \ + xfonts-unifont \ + libdevmapper-dev \ + libsdl1.2-dev \ + xorriso \ + qemu-system parted \ + libfuse-dev \ + mtools \ + wamerican \ + libefiboot-dev \ + libefivar-dev \ +# For shim + gnu-efi \ + dos2unix \ + pesign {%- if CROSS_BUILD_ENVIRON == "y" %} # Arm vs. amd64 versions conflict - remove amd64 packages diff --git a/src/grub2/Makefile b/src/grub2/Makefile new file mode 100644 index 00000000000..f856174abd4 --- /dev/null +++ b/src/grub2/Makefile @@ -0,0 +1,22 @@ +SHELL = /bin/bash +.ONESHELL: +.SHELLFLAGS += -e + +MAIN_TARGET = grub-efi-$(CONFIGURED_ARCH)-bin_$(GRUB2_FULL_VERSION)_$(CONFIGURED_ARCH).deb + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + rm -rf grub2-$(GRUB2_VERSION) + wget -O grub2_$(GRUB2_VERSION).orig.tar.xz http://deb.debian.org/debian/pool/main/g/grub2/grub2_$(GRUB2_VERSION).orig.tar.xz + wget -O grub2_$(GRUB2_FULL_VERSION).dsc http://deb.debian.org/debian/pool/main/g/grub2/grub2_$(GRUB2_FULL_VERSION).dsc + wget -O grub2_$(GRUB2_FULL_VERSION).debian.tar.xz http://deb.debian.org/debian/pool/main/g/grub2/grub2_$(GRUB2_FULL_VERSION).debian.tar.xz + # wget -O grub2_$(GRUB2_VERSION).orig.tar.xz.asc http://deb.debian.org/debian/pool/main/g/grub2/grub2_$(GRUB2_VERSION).orig.tar.xz.asc + + dpkg-source -x grub2_$(GRUB2_FULL_VERSION).dsc + + pushd grub2-$(GRUB2_VERSION) + + DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b -a$(CONFIGURED_ARCH) -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) + popd + + # Copy monolithic efi binary for secureboot + mv $* $(DEST)/ diff --git a/src/shim/Makefile b/src/shim/Makefile new file mode 100644 index 00000000000..ce8379a39f0 --- /dev/null +++ b/src/shim/Makefile @@ -0,0 +1,21 @@ +SHELL = /bin/bash +.ONESHELL: +.SHELLFLAGS += -e + +MAIN_TARGET = shim-unsigned_$(SHIM_FULL_VERSION)_$(CONFIGURED_ARCH).deb + +$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : + #rm -rf shim-$(SHIM_VERSION) + #wget -O shim_$(SHIM_VERSION).orig.tar.bz2 http://deb.debian.org/debian/pool/main/s/shim/shim_$(SHIM_VERSION).orig.tar.bz2 + #wget -O shim_$(SHIM_FULL_VERSION).dsc http://deb.debian.org/debian/pool/main/s/shim/shim_$(SHIM_FULL_VERSION).dsc + #wget -O shim_$(SHIM_FULL_VERSION).debian.tar.xz http://deb.debian.org/debian/pool/main/s/shim/shim_$(SHIM_FULL_VERSION).debian.tar.xz + + #dpkg-source -x shim_$(SHIM_FULL_VERSION).dsc + + pushd shim-$(SHIM_VERSION) + + DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -us -uc -b -a$(CONFIGURED_ARCH) -j$(SONIC_CONFIG_MAKE_JOBS) --admindir $(SONIC_DPKG_ADMINDIR) + popd + + # Copy monolithic efi binary for secureboot + mv $* $(DEST)/