From fd737172f1068870fe1ededbe9b2ed4a86663acd Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Wed, 4 Sep 2024 21:37:11 +0200 Subject: T861: add UEFI Secure Boot support This adds support for UEFI Secure Boot. It adds the missing pieces to the Linux Kernel and enforces module signing. This results in an additional security layer where untrusted (unsigned) Kernel modules can no longer be loaded into the live system. NOTE: This commit will not work unless signing keys are present. Arbitrary keys can be generated using instructions found in: data/live-build-config/includes.chroot/var/lib/shim-signed/mok/README.md --- .../hooks/live/92-strip-symbols.chroot | 76 ++++++++++++++++++++++ .../hooks/live/93-sign-kernel.chroot | 18 +++++ .../hooks/live/99-strip-symbols.chroot | 76 ---------------------- .../var/lib/shim-signed/mok/README.md | 22 +++++++ 4 files changed, 116 insertions(+), 76 deletions(-) create mode 100755 data/live-build-config/hooks/live/92-strip-symbols.chroot create mode 100755 data/live-build-config/hooks/live/93-sign-kernel.chroot delete mode 100755 data/live-build-config/hooks/live/99-strip-symbols.chroot create mode 100644 data/live-build-config/includes.chroot/var/lib/shim-signed/mok/README.md (limited to 'data') diff --git a/data/live-build-config/hooks/live/92-strip-symbols.chroot b/data/live-build-config/hooks/live/92-strip-symbols.chroot new file mode 100755 index 00000000..704f9cb3 --- /dev/null +++ b/data/live-build-config/hooks/live/92-strip-symbols.chroot @@ -0,0 +1,76 @@ +#!/bin/sh + +# +# Discard symbols and other data from object files. +# +# Reference: +# https://www.linuxfromscratch.org/lfs/view/systemd/chapter08/stripping.html +# https://www.debian.org/doc/debian-policy/ch-files.html +# + +# Set variables. +STRIPCMD_REGULAR="strip --remove-section=.comment --remove-section=.note --preserve-dates" +STRIPCMD_DEBUG="strip --strip-debug --remove-section=.comment --remove-section=.note --preserve-dates" +STRIPCMD_UNNEEDED="strip --strip-unneeded --remove-section=.comment --remove-section=.note --preserve-dates" +STRIPDIR_REGULAR=" +" +STRIPDIR_DEBUG=" +/usr/lib/modules +" +STRIPDIR_UNNEEDED=" +/etc/hsflowd/modules +/usr/bin +/usr/lib/openvpn +/usr/lib/x86_64-linux-gnu +/usr/lib32 +/usr/lib64 +/usr/libx32 +/usr/sbin +" +STRIP_EXCLUDE=`dpkg-query -L libbinutils | grep '.so'` + +# Perform stuff. +echo "Stripping symbols..." + +# List excluded files. +echo "Exclude files: ${STRIP_EXCLUDE}" + +# CMD: strip +for DIR in ${STRIPDIR_REGULAR}; do + echo "Parse dir (strip): ${DIR}" + find ${DIR} -type f -exec file {} \; | grep 'not stripped' | cut -d ":" -f 1 | while read FILE; do + echo "${STRIP_EXCLUDE}" | grep -F -q -w "${FILE}" + if [ $? -ne 0 ]; then + echo "Strip file (strip): ${FILE}" + ${STRIPCMD_REGULAR} ${FILE} + fi + done +done + +# CMD: strip --strip-debug +for DIR in ${STRIPDIR_DEBUG}; do + echo "Parse dir (strip-debug): ${DIR}" + find ${DIR} -type f -exec file {} \; | grep 'not stripped' | cut -d ":" -f 1 | while read FILE; do + echo "${STRIP_EXCLUDE}" | grep -F -q -w "${FILE}" + if [ $? -ne 0 ]; then + echo "Strip file (strip-debug): ${FILE}" + ${STRIPCMD_DEBUG} ${FILE} + fi + done +done + +# CMD: strip --strip-unneeded +for DIR in ${STRIPDIR_UNNEEDED}; do + echo "Parse dir (strip-unneeded: ${DIR}" + find ${DIR} -type f -exec file {} \; | grep 'not stripped' | cut -d ":" -f 1 | while read FILE; do + echo "${STRIP_EXCLUDE}" | grep -F -q -w "${FILE}" + if [ $? -ne 0 ]; then + echo "Strip file (strip-unneeded): ${FILE}" + ${STRIPCMD_UNNEEDED} ${FILE} + fi + done +done + +# Remove binutils package. +apt-get -y purge --autoremove binutils + diff --git a/data/live-build-config/hooks/live/93-sign-kernel.chroot b/data/live-build-config/hooks/live/93-sign-kernel.chroot new file mode 100755 index 00000000..031db10d --- /dev/null +++ b/data/live-build-config/hooks/live/93-sign-kernel.chroot @@ -0,0 +1,18 @@ +#!/bin/sh +SIGN_FILE=$(find /usr/lib -name sign-file) +MOK_KEY="/var/lib/shim-signed/mok/kernel.key" +MOK_CERT="/var/lib/shim-signed/mok/kernel.pem" +kernel_elf=$(readlink /boot/vmlinuz) + +if [ ! -f ${MOK_KEY} ]; then + echo "I: Signing key for Linux Kernel not found - Secure Boot not possible" +else + echo "I: Signing Linux Kernel for Secure Boot" + + sbsign --key $MOK_KEY --cert $MOK_CERT /boot/${kernel_elf} --output /boot/${kernel_elf} + sbverify --list /boot/${kernel_elf} + + find /lib/modules -type f -name \*.ko -o -name \*.ko.xz | while read module; do + $SIGN_FILE sha512 $MOK_KEY $MOK_CERT $module + done +fi diff --git a/data/live-build-config/hooks/live/99-strip-symbols.chroot b/data/live-build-config/hooks/live/99-strip-symbols.chroot deleted file mode 100755 index 704f9cb3..00000000 --- a/data/live-build-config/hooks/live/99-strip-symbols.chroot +++ /dev/null @@ -1,76 +0,0 @@ -#!/bin/sh - -# -# Discard symbols and other data from object files. -# -# Reference: -# https://www.linuxfromscratch.org/lfs/view/systemd/chapter08/stripping.html -# https://www.debian.org/doc/debian-policy/ch-files.html -# - -# Set variables. -STRIPCMD_REGULAR="strip --remove-section=.comment --remove-section=.note --preserve-dates" -STRIPCMD_DEBUG="strip --strip-debug --remove-section=.comment --remove-section=.note --preserve-dates" -STRIPCMD_UNNEEDED="strip --strip-unneeded --remove-section=.comment --remove-section=.note --preserve-dates" -STRIPDIR_REGULAR=" -" -STRIPDIR_DEBUG=" -/usr/lib/modules -" -STRIPDIR_UNNEEDED=" -/etc/hsflowd/modules -/usr/bin -/usr/lib/openvpn -/usr/lib/x86_64-linux-gnu -/usr/lib32 -/usr/lib64 -/usr/libx32 -/usr/sbin -" -STRIP_EXCLUDE=`dpkg-query -L libbinutils | grep '.so'` - -# Perform stuff. -echo "Stripping symbols..." - -# List excluded files. -echo "Exclude files: ${STRIP_EXCLUDE}" - -# CMD: strip -for DIR in ${STRIPDIR_REGULAR}; do - echo "Parse dir (strip): ${DIR}" - find ${DIR} -type f -exec file {} \; | grep 'not stripped' | cut -d ":" -f 1 | while read FILE; do - echo "${STRIP_EXCLUDE}" | grep -F -q -w "${FILE}" - if [ $? -ne 0 ]; then - echo "Strip file (strip): ${FILE}" - ${STRIPCMD_REGULAR} ${FILE} - fi - done -done - -# CMD: strip --strip-debug -for DIR in ${STRIPDIR_DEBUG}; do - echo "Parse dir (strip-debug): ${DIR}" - find ${DIR} -type f -exec file {} \; | grep 'not stripped' | cut -d ":" -f 1 | while read FILE; do - echo "${STRIP_EXCLUDE}" | grep -F -q -w "${FILE}" - if [ $? -ne 0 ]; then - echo "Strip file (strip-debug): ${FILE}" - ${STRIPCMD_DEBUG} ${FILE} - fi - done -done - -# CMD: strip --strip-unneeded -for DIR in ${STRIPDIR_UNNEEDED}; do - echo "Parse dir (strip-unneeded: ${DIR}" - find ${DIR} -type f -exec file {} \; | grep 'not stripped' | cut -d ":" -f 1 | while read FILE; do - echo "${STRIP_EXCLUDE}" | grep -F -q -w "${FILE}" - if [ $? -ne 0 ]; then - echo "Strip file (strip-unneeded): ${FILE}" - ${STRIPCMD_UNNEEDED} ${FILE} - fi - done -done - -# Remove binutils package. -apt-get -y purge --autoremove binutils - diff --git a/data/live-build-config/includes.chroot/var/lib/shim-signed/mok/README.md b/data/live-build-config/includes.chroot/var/lib/shim-signed/mok/README.md new file mode 100644 index 00000000..5a6edbba --- /dev/null +++ b/data/live-build-config/includes.chroot/var/lib/shim-signed/mok/README.md @@ -0,0 +1,22 @@ +# Secure Boot + +## CA + +Create Certificate Authority used for Kernel signing. CA is loaded into the +Machine Owner Key store on the target system. + +```bash +openssl req -new -x509 -newkey rsa:2048 -keyout MOK.key -outform DER -out MOK.der -days 36500 -subj "/CN=VyOS Secure Boot CA/" -nodes +openssl x509 -inform der -in MOK.der -out MOK.pem +``` + +## Kernel Module Signing Key + +We do not make use of ephemeral keys for Kernel module signing. Instead a key +is generated and signed by the VyOS Secure Boot CA which signs all the Kernel +modules during ISO assembly if present. + +```bash +openssl req -newkey rsa:2048 -keyout kernel.key -out kernel.csr -subj "/CN=VyOS Secure Boot Signer 2024 - linux/" -nodes +openssl x509 -req -in kernel.csr -CA MOK.pem -CAkey MOK.key -CAcreateserial -out kernel.pem -days 730 -sha256 +``` -- cgit v1.2.3