From e5a495a9fd6e5150fd0939dda6766b58c473c4c2 Mon Sep 17 00:00:00 2001 From: David Pilnik Date: Sun, 13 Nov 2022 14:48:30 +0200 Subject: [PATCH 01/13] [secure boot]Add Secure Boot Feature --- Makefile.work | 3 + build_debian.sh | 53 +++++- .../build_templates/sonic_debian_extension.j2 | 4 + installer/default_platform.conf | 111 +++++++++++- rules/config | 8 + scripts/efi-sign.sh | 60 +++++++ scripts/secure_boot_signature_verification.sh | 96 +++++++++++ scripts/signing_kernel_modules.sh | 120 +++++++++++++ scripts/signing_secure_boot_dev.sh | 162 ++++++++++++++++++ slave.mk | 9 + 10 files changed, 621 insertions(+), 5 deletions(-) create mode 100755 scripts/efi-sign.sh create mode 100755 scripts/secure_boot_signature_verification.sh create mode 100755 scripts/signing_kernel_modules.sh create mode 100755 scripts/signing_secure_boot_dev.sh diff --git a/Makefile.work b/Makefile.work index e0099429ed2a..8d5a1ff49d31 100644 --- a/Makefile.work +++ b/Makefile.work @@ -525,6 +525,9 @@ SONIC_BUILD_INSTRUCTION := $(MAKE) \ BUILD_LOG_TIMESTAMP=$(BUILD_LOG_TIMESTAMP) \ SONIC_ENABLE_IMAGE_SIGNATURE=$(ENABLE_IMAGE_SIGNATURE) \ SONIC_ENABLE_SECUREBOOT_SIGNATURE=$(SONIC_ENABLE_SECUREBOOT_SIGNATURE) \ + SECURE_UPGRADE_MODE=$(SECURE_UPGRADE_MODE) \ + SECURE_UPGRADE_DEV_SIGNING_KEY=$(SECURE_UPGRADE_DEV_SIGNING_KEY) \ + SECURE_UPGRADE_DEV_SIGNING_CERT=$(SECURE_UPGRADE_DEV_SIGNING_CERT) \ SONIC_DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) \ ENABLE_HOST_SERVICE_ON_START=$(ENABLE_HOST_SERVICE_ON_START) \ SLAVE_DIR=$(SLAVE_DIR) \ diff --git a/build_debian.sh b/build_debian.sh index b599b8c859bb..4e3f2d6f142b 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -167,7 +167,8 @@ if [[ $CONFIGURED_ARCH == amd64 ]]; then fi ## Sign the Linux kernel -if [ "$SONIC_ENABLE_SECUREBOOT_SIGNATURE" = "y" ]; then +# note: when flag SONIC_ENABLE_SECUREBOOT_SIGNATURE is enabled the Secure Upgrade flags should be disabled (no_sign) to avoid conflict between the features. +if [ "$SONIC_ENABLE_SECUREBOOT_SIGNATURE" = "y" ] && [ "$SECURE_UPGRADE_MODE" != 'dev' ] && [ "$SECURE_UPGRADE_MODE" != "prod" ]; then if [ ! -f $SIGNING_KEY ]; then echo "Error: SONiC linux kernel signing key missing" exit 1 @@ -631,6 +632,56 @@ then fi +# ################# +# secure boot +# ################# +if [[ $SECURE_UPGRADE_MODE == 'dev' || $SECURE_UPGRADE_MODE == "prod" && $SONIC_ENABLE_SECUREBOOT_SIGNATURE != 'y' ]]; then + # note: SONIC_ENABLE_SECUREBOOT_SIGNATURE is a feature that signing just kernel, + # SECURE_UPGRADE_MODE is signing all the boot component including kernel. + # its required to do not enable both features together to avoid conflicts. + echo "Secure Boot support build stage: Starting .." + + # debian secure boot dependecies + sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install \ + shim-unsigned \ + grub-efi + + if [ ! -f $SECURE_UPGRADE_DEV_SIGNING_CERT ]; then + echo "Error: SONiC SECURE_UPGRADE_DEV_SIGNING_CERT=$SECURE_UPGRADE_DEV_SIGNING_CERT key missing" + exit 1 + fi + + if [[ $SECURE_UPGRADE_MODE == 'dev' ]]; then + # development signing & verification + + if [ ! -f $SECURE_UPGRADE_DEV_SIGNING_KEY ]; then + echo "Error: SONiC SECURE_UPGRADE_DEV_SIGNING_KEY=$SECURE_UPGRADE_DEV_SIGNING_KEY key missing" + exit 1 + fi + + sudo bash scripts/signing_secure_boot_dev.sh $CONFIGURED_ARCH \ + $FILESYSTEM_ROOT \ + $LINUX_KERNEL_VERSION \ + $SECURE_UPGRADE_DEV_SIGNING_CERT \ + $SECURE_UPGRADE_DEV_SIGNING_KEY + elif [[ $SECURE_UPGRADE_MODE == "prod" ]]; then + # Here Vendor signing should be implemented + OUTPUT_SEC_BOOT_DIR=$FILESYSTEM_ROOT/boot + sudo bash scripts/signing_secure_boot_prod.sh $CONFIGURED_ARCH $FILESYSTEM_ROOT $LINUX_KERNEL_VERSION $OUTPUT_SEC_BOOT_DIR + + # verifying all EFI files and kernel modules in $OUTPUT_SEC_BOOT_DIR + bash scripts/secure_boot_signature_verification.sh -e $OUTPUT_SEC_BOOT_DIR \ + -c $SECURE_UPGRADE_DEV_SIGNING_CERT \ + -k $FILESYSTEM_ROOT + + # verifying vmlinuz file. + bash scripts/secure_boot_signature_verification.sh -e $FILESYSTEM_ROOT/boot/vmlinuz-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH} \ + -c $SECURE_UPGRADE_DEV_SIGNING_CERT \ + -k $FILESYSTEM_ROOT + fi + echo "Secure Boot support build stage: END." +fi + ## Update initramfs sudo chroot $FILESYSTEM_ROOT update-initramfs -u ## Convert initrd image to u-boot format diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 848bf717c33f..88ea2a399565 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -78,6 +78,10 @@ fi # Update apt's snapshot of its repos sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get update +# Install efitools to support secure upgrade +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install efitools +sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install mokutil + # Apply environtment configuration files sudo cp $IMAGE_CONFIGS/environment/environment $FILESYSTEM_ROOT/etc/ sudo cp $IMAGE_CONFIGS/environment/motd $FILESYSTEM_ROOT/etc/ diff --git a/installer/default_platform.conf b/installer/default_platform.conf index c0758b6fb94b..4081dc27dbaf 100755 --- a/installer/default_platform.conf +++ b/installer/default_platform.conf @@ -359,6 +359,78 @@ demo_install_uefi_grub() } +# Install UEFI BIOS SHIM for DEMO OS +demo_install_uefi_shim() +{ + echo "demo_install_uefi_shim(): Installing Secure Boot components" + + 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 + } + + echo "creating demo_volume_label=$demo_volume_label in dir: /boot/efi/EFI/ ." + mkdir -p /boot/efi/EFI/$demo_volume_label + + if [ ! -f $demo_mnt/$image_dir/boot/mmx64.efi ]; then + echo "ERROR: $demo_mnt/$image_dir/boot/mmx64.efi file does not exist" + exit 1 + fi + + if [ ! -f $demo_mnt/$image_dir/boot/shimx64.efi ]; then + echo "ERROR: $demo_mnt/$image_dir/boot/shimx64.efi file does not exist" + exit 1 + fi + + if [ ! -f $demo_mnt/$image_dir/boot/grubx64.efi ]; then + echo "ERROR: $demo_mnt/$image_dir/boot/grubx64.efi file does not exist" + exit 1 + fi + + if [ ! -f $demo_mnt/$image_dir/boot/grub.cfg ]; then + echo "ERROR: cp $demo_mnt/$image_dir/boot/grub.cfg file does not exist" + exit 1 + fi + + echo "copying signed shim, mm, grub, grub.cfg from $demo_mnt/$image_dir/boot/ to /boot/efi/EFI/$demo_volume_label directory" + cp $demo_mnt/$image_dir/boot/mmx64.efi /boot/efi/EFI/$demo_volume_label/mmx64.efi + cp $demo_mnt/$image_dir/boot/shimx64.efi /boot/efi/EFI/$demo_volume_label/shimx64.efi + cp $demo_mnt/$image_dir/boot/grubx64.efi /boot/efi/EFI/$demo_volume_label/grubx64.efi + + # cp first grub.cfg as entrypoint to call real grub.cfg in nvos label + mkdir -p /boot/efi/EFI/debian/ + echo "cp $demo_mnt/$image_dir/boot/grub.cfg /boot/efi/EFI/debian/" + cp $demo_mnt/$image_dir/boot/grub.cfg /boot/efi/EFI/debian/ + + # Configure EFI NVRAM Boot variables. --create also sets the + # new boot number as active. + 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 + } + echo "demo_install_uefi_shim(): Secure Boot components installed successfully" +} bootloader_menu_config() { @@ -370,7 +442,15 @@ 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" + secure_boot_state=$(mokutil --sb-state) + echo secure_boot_state=$secure_boot_state + if [ "$secure_boot_state" = "SecureBoot enabled" ]; then + echo "UEFI Secure Boot is enabled" + demo_install_uefi_shim "$demo_mnt" "$blk_dev" + else + echo "UEFI Secure Boot is disabled" + demo_install_uefi_grub "$demo_mnt" "$blk_dev" + fi else demo_install_grub "$demo_mnt" "$blk_dev" fi @@ -405,7 +485,8 @@ bootloader_menu_config() fi DEFAULT_GRUB_SERIAL_COMMAND="serial --port=${CONSOLE_PORT} --speed=${CONSOLE_SPEED} --word=8 --parity=no --stop=1" - DEFAULT_GRUB_CMDLINE_LINUX="console=tty0 console=ttyS${CONSOLE_DEV},${CONSOLE_SPEED}n8 quiet $CSTATES" + # DEFAULT_GRUB_CMDLINE_LINUX="console=tty0 console=ttyS${CONSOLE_DEV},${CONSOLE_SPEED}n8 quiet $CSTATES" + DEFAULT_GRUB_CMDLINE_LINUX="console=tty0 console=ttyS${CONSOLE_DEV},${CONSOLE_SPEED}n8 loglevel=7 systemd.log_level=debug $CSTATES" GRUB_SERIAL_COMMAND=${GRUB_SERIAL_COMMAND:-"$DEFAULT_GRUB_SERIAL_COMMAND"} GRUB_CMDLINE_LINUX=${GRUB_CMDLINE_LINUX:-"$DEFAULT_GRUB_CMDLINE_LINUX"} export GRUB_SERIAL_COMMAND @@ -472,6 +553,17 @@ EOF # Add extra linux command line echo "EXTRA_CMDLINE_LINUX=$extra_cmdline_linux" GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX $extra_cmdline_linux" +GRUB_CFG_LINUX_CMD="" +GRUB_CFG_INITRD_CMD="" +if [ "$firmware" = "uefi" ] ; then + # grub.cfg when BIOS is UEFI and support Secure Boot + GRUB_CFG_LINUX_CMD="linuxefi" + GRUB_CFG_INITRD_CMD="initrdefi" +else + # grub.cfg when BIOS is Legacy + GRUB_CFG_LINUX_CMD="linux" + GRUB_CFG_INITRD_CMD="initrd" +fi cat <> $grub_cfg menuentry '$demo_grub_entry' { @@ -481,13 +573,13 @@ menuentry '$demo_grub_entry' { if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 - linux /$image_dir/boot/vmlinuz-5.10.0-18-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ + $GRUB_CFG_LINUX_CMD /$image_dir/boot/vmlinuz-5.10.0-18-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ net.ifnames=0 biosdevname=0 \ loop=$image_dir/$FILESYSTEM_SQUASHFS loopfstype=squashfs \ systemd.unified_cgroup_hierarchy=0 \ apparmor=1 security=apparmor varlog_size=$VAR_LOG_SIZE usbcore.autosuspend=-1 $ONIE_PLATFORM_EXTRA_CMDLINE_LINUX echo 'Loading $demo_volume_label $demo_type initial ramdisk ...' - initrd /$image_dir/boot/initrd.img-5.10.0-18-2-amd64 + $GRUB_CFG_INITRD_CMD /$image_dir/boot/initrd.img-5.10.0-18-2-amd64 } EOF @@ -510,6 +602,17 @@ EOF cp $grub_cfg $onie_initrd_tmp/$demo_mnt/grub/grub.cfg fi + if [ "$secure_boot_state" = "SecureBoot enabled" ]; then + # Secure Boot grub.cfg support + # Saving grub_cfg in the same place where is grubx64.efi, + # this grub_cfg file will be called by first grub.cfg file from: /boot/efi/EFI/debian/grub.cfg + if [ -f $NVOS_BOOT_DIR/grub.cfg ]; then + rm $NVOS_BOOT_DIR/grub.cfg + fi + + cp $grub_cfg $NVOS_BOOT_DIR/grub.cfg + fi + cd / echo "Installed SONiC base image $demo_volume_label successfully" diff --git a/rules/config b/rules/config index ec659631e222..b6c06a3ca2fa 100644 --- a/rules/config +++ b/rules/config @@ -220,6 +220,14 @@ SONIC_ENABLE_IMAGE_SIGNATURE ?= n # The absolute path should be provided. SONIC_ENABLE_SECUREBOOT_SIGNATURE ?= n +# Full Secure Boot feature flags. +# SECURE_UPGRADE_DEV_SIGNING_KEY - path to development signing key, used for image signing during build +# SECURE_UPGRADE_DEV_SIGNING_CERT - path to development signing certificate, used for image signing during build +# SECURE_UPGRADE_MODE - enum value for secure upgrade mode, valid options are "dev", "prod" and "no_sign" +SECURE_UPGRADE_DEV_SIGNING_KEY = /sonic/files/nv_onyx_key.pem +SECURE_UPGRADE_DEV_SIGNING_CERT = /sonic/files/nv_onyx_key_certificate.pem +SECURE_UPGRADE_MODE = "no_sign" + # PACKAGE_URL_PREFIX - the package url prefix PACKAGE_URL_PREFIX ?= https://packages.trafficmanager.net/public/packages diff --git a/scripts/efi-sign.sh b/scripts/efi-sign.sh new file mode 100755 index 000000000000..53ebddcaca5d --- /dev/null +++ b/scripts/efi-sign.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +set -e + +# +# Sign efi file with secret key and certificate +# - shim +# - grub +# - vmlinuz +# +usage() { + cat < +Usage example: efi-sign.sh priv-key.pem pub-key.pem shimx64.efi shimx64-signed.efi + +EOF +} + +if [ "$1" = "-h" -o "$1" = "--help" ]; then + usage +fi + +PRIVATE_KEY_PEM="$1" +CERT_PEM="$2" +EFI_FILE="$3" +EFI_FILE_SIGNED="$4" + + +[ -f "$PRIVATE_KEY_PEM" ] || { + echo "Error: PRIVATE_KEY_PEM file does not exist: $PRIVATE_KEY_PEM" + usage + exit 1 +} + +[ -f "$CERT_PEM" ] || { + echo "Error: CERT_PEM file does not exist: $CERT_PEM" + usage + exit 1 +} + +[ -f "$EFI_FILE" ] || { + echo "Error: File for signing does not exist: $EFI_FILE" + usage + exit 1 +} + +if [ -z ${EFI_FILE_SIGNED} ]; then + echo "ERROR: no arg named supplied" + usage + exit 1 +fi + +echo "$0 signing $EFI_FILE with ${PRIVATE_KEY_PEM}, ${CERT_PEM} to create $EFI_FILE_SIGNED" +sbsign --key ${PRIVATE_KEY_PEM} --cert ${CERT_PEM} \ + --output ${EFI_FILE_SIGNED} ${EFI_FILE} || { + echo "EFI sign error" + exit 1 +} diff --git a/scripts/secure_boot_signature_verification.sh b/scripts/secure_boot_signature_verification.sh new file mode 100755 index 000000000000..1a70a74dea98 --- /dev/null +++ b/scripts/secure_boot_signature_verification.sh @@ -0,0 +1,96 @@ +#!/bin/bash +# This Script is verifying the efi file signature by using sbverify. +# In addition, is verifying that kernel modules a directory contained a signature. +# Note: Kernel Module verification is not checking that the signature is correct, but its checking that the Kernel Modules have one. + +EFI_FILE='' +KERNEL_MODULES_DIR='' +CERT_PEM='' +VERBOSE='false' + +usage() { + cat < -c -k +Run Example: secure_boot_signature_verification.sh -e shimx64.efi -c pub-key.pem -k fsroot-mellanox +Run Example: secure_boot_signature_verification.sh -e /boot/efi_dir -c pub-key.pem -k fsroot-mellanox + +EOF +} + +verify_efi(){ + cert_pem=$1 + efi_file=$2 + echo "sbverify --cert $cert_pem $efi_file" + sbverify --cert $cert_pem $efi_file || { + echo "sbverify error with $efi_file" + exit 1 + } + echo "$efi_file signed OK." +} + +while getopts 'e:k:c:hv' flag; do + case "${flag}" in + e) EFI_FILE="${OPTARG}" ;; + k) KERNEL_MODULES_DIR="${OPTARG}" ;; + c) CERT_PEM="${OPTARG}" ;; + v) VERBOSE='true' ;; + h) print_usage + exit 1 ;; + esac +done +if [ $OPTIND -eq 1 ]; then echo "no options were pass"; print_usage; exit 1 ;fi + +if [ -d "$EFI_FILE" ];then + [ -f "$CERT_PEM" ] || { + echo "Error: option '-c' incorrect, file: certificate=$CERT_PEM does not exist" + print_usage + exit 1 + } + + # find all efi files. + efi_file_list=$(sudo find ${EFI_FILE} -name "*.efi") + for efi_file in $efi_file_list + do + echo "verifying efi_file named: ${efi_file} .." + verify_efi $CERT_PEM ${efi_file} + done + echo "$0: All EFI files SIGNED OK." +fi + +if [ -f "$EFI_FILE" ]; then + [ -f "$CERT_PEM" ] || { + echo "Error: option '-c' incorrect, file: certificate=$CERT_PEM does not exist" + print_usage + exit 1 + } + verify_efi $CERT_PEM $EFI_FILE +fi + +if [ -d "$KERNEL_MODULES_DIR" ]; then + # Condition checking that all the kernel modules in the KERNEL_MODULES_DIR contain a signature. + + # find all the kernel modules. + modules_list=$(sudo find ${KERNEL_MODULES_DIR} -name "*.ko") + + # Do sign for each found module + kernel_modules_cnt=0 + for mod in $modules_list + do + # check Kernel module is signed. + if ! grep -q "~Module signature appended~" "${mod}"; then + echo "Error: Kernel module=${mod} have no signature appened." + exit 1 + fi + + if [ $VERBOSE = 'true' ]; then + echo "kernel module named=${mod} have signature appended." + fi + + kernel_modules_cnt=$((kernel_modules_cnt+1)) + done + echo "Num of kernel modules signed: kernel_modules_cnt=$kernel_modules_cnt" + echo "$0: All Kernel Modules SIGNED OK." +fi + diff --git a/scripts/signing_kernel_modules.sh b/scripts/signing_kernel_modules.sh new file mode 100755 index 000000000000..d7b8ebe119ec --- /dev/null +++ b/scripts/signing_kernel_modules.sh @@ -0,0 +1,120 @@ +#!/bin/bash +# This script is signing kernel modules by using sign-file tool + +usage() { + cat < +Sign kernel modules in using private & public keys. + +Parameters description: +LINUX_KERNEL_VERSION +PEM_CERT public key (pem format) +PEM_PRIVATE_KEY private key (pem format) +LOCAL_SIGN_FILE path of the sign-file tool for signing Kernel Modules, if the value is empty it will used the sign-file installed in /usr/lib/linux-kbuild-/scripts +LOCAL_EXTRACT_CERT path of the extract-cert tool for Extract X.509 certificate, if the value is empty it will used the extract-cert installed in /usr/lib/linux-kbuild-/scripts +KERNEL_MODULES_DIR root directory of all the kernel modules to be sign by the script, if the value empty it will use the call script location as root. + +Runs examples: +1. sudo bash scripts/signing_kernel_modules.sh 5.10.0-8-2 cert.pem priv-key.pem +2. sudo bash scripts/signing_kernel_modules.sh 5.10.0-8-2 cert.pem priv-key.pem fsroot-mellanox /usr/lib/linux-kbuild-5.10/scripts/extract-cert /usr/lib/linux-kbuild-5.10/scripts/sign-file +EOF +} + +if [ "$1" = "-h" -o "$1" = "--help" ]; then + usage +fi + +LINUX_KERNEL_VERSION="$1" +PEM_CERT="$2" +PEM_PRIVATE_KEY="$3" +KERNEL_MODULES_DIR="$4" +LOCAL_SIGN_FILE="$5" +LOCAL_EXTRACT_CERT="$6" + +if [ -z ${LINUX_KERNEL_VERSION} ]; then + echo "ERROR: LINUX_KERNEL_VERSION arg1 is empty" + usage + exit 1 +fi + +if [ ! -f ${PEM_CERT} ]; then + echo "ERROR: arg2 PEM_CERT=${PEM_CERT} file does not exist" + usage + exit 1 +fi + +if [ ! -f ${PEM_PRIVATE_KEY} ]; then + echo "ERROR: arg3 PEM_PRIVATE_KEY=${PEM_PRIVATE_KEY} file does not exist" + usage + exit 1 +fi + +kbuild_ver_major="$(cut -d '.' -f 1 <<< "$LINUX_KERNEL_VERSION")"."$(cut -d '.' -f 2 <<< "$LINUX_KERNEL_VERSION")" +if [ -z ${LOCAL_SIGN_FILE} ]; then + LOCAL_SIGN_FILE="/usr/lib/linux-kbuild-${kbuild_ver_major}/scripts/sign-file" +fi + +if [ ! -f ${LOCAL_SIGN_FILE} ]; then + echo "ERROR: LOCAL_SIGN_FILE=${LOCAL_SIGN_FILE} file does not exist" + usage + exit 1 +fi + +if [ -z ${LOCAL_EXTRACT_CERT} ]; then + LOCAL_EXTRACT_CERT="/usr/lib/linux-kbuild-${kbuild_ver_major}/scripts/extract-cert" +fi + +if [ ! -f ${LOCAL_EXTRACT_CERT} ]; then + echo "ERROR: LOCAL_EXTRACT_CERT=${LOCAL_EXTRACT_CERT} file does not exist" + usage + exit 1 +fi + +if [ ! -d "$KERNEL_MODULES_DIR" ]; then + # If the user do not provide a KERNEL_MODULES_DIR, the script is going to search in the script call path for Kernel modules. + KERNEL_MODULES_DIR="./" + echo "KERNEL_MODULES_DIR set to default path: $KERNEL_MODULES_DIR" + +fi + +# find all the kernel modules. +modules_list=$(sudo find ${KERNEL_MODULES_DIR} -name "*.ko") + +dev_certs_tmp_folder="/tmp/dev_kmod_sign" + +# clean env +if [ -d ${dev_certs_tmp_folder} ]; then + rm -r ${dev_certs_tmp_folder} +fi + +mkdir -p ${dev_certs_tmp_folder} +local_sign_key="${dev_certs_tmp_folder}/$(basename $PEM_PRIVATE_KEY)" +local_sign_cert="${dev_certs_tmp_folder}/$(basename $PEM_CERT)" + +# Combine cert for module signing +echo "keys concat: cat ${PEM_PRIVATE_KEY} ${PEM_CERT} > ${local_sign_key}" +cat ${PEM_PRIVATE_KEY} ${PEM_CERT} > ${local_sign_key} + +# Extract x509 cert in corect format +echo "create x509 cert: ${LOCAL_EXTRACT_CERT} ${local_sign_key} ${local_sign_cert}" +${LOCAL_EXTRACT_CERT} ${local_sign_key} ${local_sign_cert} + +# Do sign for each found module +kernel_modules_cnt=0 +for mod in $modules_list +do + echo "signing module named: ${mod} .." + echo "${LOCAL_SIGN_FILE} sha512 ${local_sign_key} ${local_sign_cert} ${mod}" + kernel_modules_cnt=$((kernel_modules_cnt+1)) + sudo ${LOCAL_SIGN_FILE} sha512 ${local_sign_key} ${local_sign_cert} ${mod} + + # check Kernel module is signed. + if ! grep -q "~Module signature appended~" "${mod}"; then + echo "Error: Kernel module=${mod} have no signature appened." + exit 1 + fi +done + +echo "Num of kernel modules signed: kernel_modules_cnt=$kernel_modules_cnt" +echo "$0: All Kernel Modules SIGNED OK." \ No newline at end of file diff --git a/scripts/signing_secure_boot_dev.sh b/scripts/signing_secure_boot_dev.sh new file mode 100755 index 000000000000..061e5af595a3 --- /dev/null +++ b/scripts/signing_secure_boot_dev.sh @@ -0,0 +1,162 @@ +#!/bin/bash +# This script is signing boot components: shim, mmx, grub, kernel and kernel modules in development env. + +## Enable debug output for script & exit code when failing occurs +set -x -e + +usage() { + cat < +Usage example: efi-sign.sh priv-key.pem pub-key.pem shimx64.efi shimx64-signed.efi + +EOF +} + +clean_file() { + if [ -f $1 ]; then + echo "clean old file named: $1" + echo "sudo rm $1" + sudo rm $1 + echo "$?" + exit 1 + fi +} + +echo "$0 signing & verifying EFI files and Kernel Modules start ..." +CONFIGURED_ARCH="$1" +FS_ROOT="$2" +LINUX_KERNEL_VERSION="$3" +PEM_CERT="$4" +PEM_PRIV_KEY="$5" + +if [ -z ${CONFIGURED_ARCH} ]; then + echo "ERROR: CONFIGURED_ARCH=${CONFIGURED_ARCH} is empty" + usage + exit 1 +fi + +if [ -z ${FS_ROOT} ]; then + echo "ERROR: FS_ROOT=${FS_ROOT} is empty" + usage + exit 1 +fi + +if [ -z ${LINUX_KERNEL_VERSION} ]; then + echo "ERROR: LINUX_KERNEL_VERSION=${LINUX_KERNEL_VERSION} is empty" + usage + exit 1 +fi + +if [ ! -f "${PEM_CERT}" ]; then + echo "ERROR: PEM_CERT=${PEM_CERT} file does not exist" + usage + exit 1 +fi + +if [ ! -f "${PEM_PRIV_KEY}" ]; then + echo "ERROR: PEM_PRIV_KEY=${PEM_PRIV_KEY} file does not exist" + usage + exit 1 +fi + +ARCH='' +if [[ $CONFIGURED_ARCH == amd64 ]]; then +ARCH=x86_64 +EFI_ARCH=x64 +fi + +# efi-sign.sh is used to sign: shim, mmx, grub, and kernel (vmlinuz) +EFI_SIGNING=scripts/efi-sign.sh + +###################### +## shim & mmx signing +###################### + +# shim dirs +SHIM_DIR_SRC=$FS_ROOT/usr/lib/shim +MMX_EFI_SRC=$SHIM_DIR_SRC/mm${EFI_ARCH}.efi +SHIMX_EFI_SRC=$SHIM_DIR_SRC/shim${EFI_ARCH}.efi + +# clean old files +clean_file ${SHIMX_EFI_SRC}-signed +clean_file ${MMX_EFI_SRC}-signed +clean_file $FS_ROOT/boot/shim${EFI_ARCH}.efi +clean_file $FS_ROOT/boot/mm${EFI_ARCH}.efi + +# clean old shim & mmx files in the env +sudo rm -f ${SHIMX_EFI_SRC}-signed ${MMX_EFI_SRC}-signed \ + $FS_ROOT/boot/shim${EFI_ARCH}.efi $FS_ROOT/boot/mm${EFI_ARCH}.efi + +echo "signing shim${EFI_ARCH}.efi & mm${EFI_ARCH}.efi from location: ${SHIM_DIR_SRC} .." +sudo ${EFI_SIGNING} $PEM_PRIV_KEY $PEM_CERT ${SHIMX_EFI_SRC} ${SHIMX_EFI_SRC}-signed +sudo ${EFI_SIGNING} $PEM_PRIV_KEY $PEM_CERT ${MMX_EFI_SRC} ${MMX_EFI_SRC}-signed + +# cp shim & mmx signed files to boot directory in the fs. +sudo cp ${SHIMX_EFI_SRC}-signed $FS_ROOT/boot/shim${EFI_ARCH}.efi +sudo cp ${MMX_EFI_SRC}-signed $FS_ROOT/boot/mm${EFI_ARCH}.efi + +# verifying signature of mm & shim efi files. +sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e $FS_ROOT/boot/shim${EFI_ARCH}.efi +sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e $FS_ROOT/boot/mm${EFI_ARCH}.efi + +###################### +## grub signing +###################### + +# Make a config grub file that reads a grub.cfg from the EFI directory +# where the final grub binary is running. +tmp_config=$(mktemp) +cat < $tmp_config +configfile \$cmdpath/grub.cfg +EOF + +# clean old files +clean_file $FS_ROOT/boot/grub.cfg +clean_file ${GRUB_EFI_SRC}-signed +clean_file $FS_ROOT/boot/grub${EFI_ARCH}.efi + +sudo cp $tmp_config $FS_ROOT/boot/grub.cfg + +GRUB_DIR_SRC=$FS_ROOT/usr/lib/grub/x86_64-efi/monolithic/ +GRUB_EFI_SRC=$GRUB_DIR_SRC/grub${EFI_ARCH}.efi + +# clean old grub files in the env +sudo rm -f ${GRUB_EFI_SRC}-signed $FS_ROOT/boot/grub${EFI_ARCH}.efi + +echo "signing grub${EFI_ARCH}.efi from location: ${GRUB_EFI_SRC} .." +sudo ${EFI_SIGNING} $PEM_PRIV_KEY $PEM_CERT ${GRUB_EFI_SRC} ${GRUB_EFI_SRC}-signed + +# cp signed grub to fs boot dir. +sudo cp ${GRUB_EFI_SRC}-signed $FS_ROOT/boot/grub${EFI_ARCH}.efi + +# verifying signature of grub efi file. +sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e $FS_ROOT/boot/grub${EFI_ARCH}.efi + +###################### +## vmlinuz signing +###################### + +CURR_VMLINUZ=$FS_ROOT/boot/vmlinuz-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH} + +# clean old files +clean_file ${CURR_VMLINUZ}-signed + +# clean old grub files in the env +sudo rm -f ${CURR_VMLINUZ}-signed + +echo "signing ${CURR_VMLINUZ} .." +sudo ${EFI_SIGNING} $PEM_PRIV_KEY $PEM_CERT ${CURR_VMLINUZ} ${CURR_VMLINUZ}-signed + +# rename signed vmlinuz with the name vmlinuz without signed suffix +sudo cp ${CURR_VMLINUZ}-signed ${CURR_VMLINUZ} + +sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e ${CURR_VMLINUZ} + +######################### +# Kernel Modules signing +######################### +sudo bash scripts/signing_kernel_modules.sh $LINUX_KERNEL_VERSION ${PEM_CERT} ${PEM_PRIV_KEY} + +echo "$0 signing & verifying EFI files and Kernel Modules DONE" \ No newline at end of file diff --git a/slave.mk b/slave.mk index 5789287f1d43..eefbb7941802 100644 --- a/slave.mk +++ b/slave.mk @@ -377,6 +377,9 @@ $(info "SONIC_USE_DOCKER_BUILDKIT" : "$(SONIC_USE_DOCKER_BUILDKIT)") $(info "USERNAME" : "$(USERNAME)") $(info "PASSWORD" : "$(PASSWORD)") $(info "CHANGE_DEFAULT_PASSWORD" : "$(CHANGE_DEFAULT_PASSWORD)") +$(info "SECURE_UPGRADE_MODE" : "$(SECURE_UPGRADE_MODE)") +$(info "SECURE_UPGRADE_DEV_SIGNING_KEY" : "$(SECURE_UPGRADE_DEV_SIGNING_KEY)") +$(info "SECURE_UPGRADE_DEV_SIGNING_CERT" : "$(SECURE_UPGRADE_DEV_SIGNING_CERT)") $(info "ENABLE_DHCP_GRAPH_SERVICE" : "$(ENABLE_DHCP_GRAPH_SERVICE)") $(info "SHUTDOWN_BGP_ON_START" : "$(SHUTDOWN_BGP_ON_START)") $(info "ENABLE_PFCWD_ON_START" : "$(ENABLE_PFCWD_ON_START)") @@ -1258,6 +1261,9 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_ztp="$(ENABLE_ZTP)" export include_teamd="$(INCLUDE_TEAMD)" export include_router_advertiser="$(INCLUDE_ROUTER_ADVERTISER)" + export sonic_su_dev_signing_key="$(SECURE_UPGRADE_DEV_SIGNING_KEY)" + export sonic_su_dev_signing_cert="$(SECURE_UPGRADE_DEV_SIGNING_CERT)" + export sonic_su_mode="$(SECURE_UPGRADE_MODE)" export include_system_telemetry="$(INCLUDE_SYSTEM_TELEMETRY)" export include_restapi="$(INCLUDE_RESTAPI)" export include_nat="$(INCLUDE_NAT)" @@ -1458,6 +1464,9 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ TARGET_MACHINE=$(dep_machine) \ IMAGE_TYPE=$($*_IMAGE_TYPE) \ SONIC_ENABLE_IMAGE_SIGNATURE="$(SONIC_ENABLE_IMAGE_SIGNATURE)" \ + SECURE_UPGRADE_MODE="$(SECURE_UPGRADE_MODE)" \ + SECURE_UPGRADE_DEV_SIGNING_KEY="$(SECURE_UPGRADE_DEV_SIGNING_KEY)" \ + SECURE_UPGRADE_DEV_SIGNING_CERT="$(SECURE_UPGRADE_DEV_SIGNING_CERT)" \ SIGNING_KEY="$(SIGNING_KEY)" \ SIGNING_CERT="$(SIGNING_CERT)" \ CA_CERT="$(CA_CERT)" \ From 2eb66bcad6b091d746722d643284dc495dc3b963 Mon Sep 17 00:00:00 2001 From: David Pilnik Date: Mon, 21 Nov 2022 15:34:27 +0200 Subject: [PATCH 02/13] [secure boot]Fix first grub.cfg to look for the sonic grub.cfg in the sonic fs (like original grub.cfg)instead in boot directory --- installer/default_platform.conf | 35 ++++++++++++------------------ scripts/signing_secure_boot_dev.sh | 10 --------- 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/installer/default_platform.conf b/installer/default_platform.conf index 4081dc27dbaf..03d941ba97d2 100755 --- a/installer/default_platform.conf +++ b/installer/default_platform.conf @@ -405,21 +405,11 @@ demo_install_uefi_shim() exit 1 fi - if [ ! -f $demo_mnt/$image_dir/boot/grub.cfg ]; then - echo "ERROR: cp $demo_mnt/$image_dir/boot/grub.cfg file does not exist" - exit 1 - fi - echo "copying signed shim, mm, grub, grub.cfg from $demo_mnt/$image_dir/boot/ to /boot/efi/EFI/$demo_volume_label directory" cp $demo_mnt/$image_dir/boot/mmx64.efi /boot/efi/EFI/$demo_volume_label/mmx64.efi cp $demo_mnt/$image_dir/boot/shimx64.efi /boot/efi/EFI/$demo_volume_label/shimx64.efi cp $demo_mnt/$image_dir/boot/grubx64.efi /boot/efi/EFI/$demo_volume_label/grubx64.efi - # cp first grub.cfg as entrypoint to call real grub.cfg in nvos label - mkdir -p /boot/efi/EFI/debian/ - echo "cp $demo_mnt/$image_dir/boot/grub.cfg /boot/efi/EFI/debian/" - cp $demo_mnt/$image_dir/boot/grub.cfg /boot/efi/EFI/debian/ - # Configure EFI NVRAM Boot variables. --create also sets the # new boot number as active. efibootmgr --quiet --create \ @@ -550,6 +540,20 @@ EOF fi fi +# Make a first grub config file that located in default debian path:/boot/efi/EFI/debian/ +# this first grub.cfg will call the complete grub.cfg created below with sonic configuration +tmp_config=$(mktemp) +cat < $tmp_config +search --no-floppy --label --set=root $demo_volume_label +set prefix=(\$root)'/grub' +configfile \$prefix/grub.cfg +EOF + +# Copy first grub.cfg as entrypoint to default debian path where grubx64.efi expected it. +mkdir -p /boot/efi/EFI/debian/ +echo "cp $tmp_config /boot/efi/EFI/debian/grub.cfg" +cp $tmp_config /boot/efi/EFI/debian/grub.cfg + # Add extra linux command line echo "EXTRA_CMDLINE_LINUX=$extra_cmdline_linux" GRUB_CMDLINE_LINUX="$GRUB_CMDLINE_LINUX $extra_cmdline_linux" @@ -602,17 +606,6 @@ EOF cp $grub_cfg $onie_initrd_tmp/$demo_mnt/grub/grub.cfg fi - if [ "$secure_boot_state" = "SecureBoot enabled" ]; then - # Secure Boot grub.cfg support - # Saving grub_cfg in the same place where is grubx64.efi, - # this grub_cfg file will be called by first grub.cfg file from: /boot/efi/EFI/debian/grub.cfg - if [ -f $NVOS_BOOT_DIR/grub.cfg ]; then - rm $NVOS_BOOT_DIR/grub.cfg - fi - - cp $grub_cfg $NVOS_BOOT_DIR/grub.cfg - fi - cd / echo "Installed SONiC base image $demo_volume_label successfully" diff --git a/scripts/signing_secure_boot_dev.sh b/scripts/signing_secure_boot_dev.sh index 061e5af595a3..c8702f79b8b3 100755 --- a/scripts/signing_secure_boot_dev.sh +++ b/scripts/signing_secure_boot_dev.sh @@ -105,20 +105,10 @@ sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e $FS_ROOT ## grub signing ###################### -# Make a config grub file that reads a grub.cfg from the EFI directory -# where the final grub binary is running. -tmp_config=$(mktemp) -cat < $tmp_config -configfile \$cmdpath/grub.cfg -EOF - # clean old files -clean_file $FS_ROOT/boot/grub.cfg clean_file ${GRUB_EFI_SRC}-signed clean_file $FS_ROOT/boot/grub${EFI_ARCH}.efi -sudo cp $tmp_config $FS_ROOT/boot/grub.cfg - GRUB_DIR_SRC=$FS_ROOT/usr/lib/grub/x86_64-efi/monolithic/ GRUB_EFI_SRC=$GRUB_DIR_SRC/grub${EFI_ARCH}.efi From ddde4c73b52c55efcbebfbf335e5d7dbea658688 Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Mon, 14 Nov 2022 16:33:34 -0800 Subject: [PATCH 03/13] Update Linux kernel from 5.10.103 to 5.10.140 (#12660) Signed-off-by: Saikrishna Arcot Signed-off-by: Saikrishna Arcot --- installer/default_platform.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/installer/default_platform.conf b/installer/default_platform.conf index 03d941ba97d2..0c920b5b3c2c 100755 --- a/installer/default_platform.conf +++ b/installer/default_platform.conf @@ -577,13 +577,13 @@ menuentry '$demo_grub_entry' { if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 - $GRUB_CFG_LINUX_CMD /$image_dir/boot/vmlinuz-5.10.0-18-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ + linux /$image_dir/boot/vmlinuz-5.10.0-18-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ net.ifnames=0 biosdevname=0 \ loop=$image_dir/$FILESYSTEM_SQUASHFS loopfstype=squashfs \ systemd.unified_cgroup_hierarchy=0 \ apparmor=1 security=apparmor varlog_size=$VAR_LOG_SIZE usbcore.autosuspend=-1 $ONIE_PLATFORM_EXTRA_CMDLINE_LINUX echo 'Loading $demo_volume_label $demo_type initial ramdisk ...' - $GRUB_CFG_INITRD_CMD /$image_dir/boot/initrd.img-5.10.0-18-2-amd64 + initrd /$image_dir/boot/initrd.img-5.10.0-18-2-amd64 } EOF From 73cda2487839d31f30f00a5a6ef152da5d7afa69 Mon Sep 17 00:00:00 2001 From: David Pilnik Date: Sun, 13 Nov 2022 14:48:30 +0200 Subject: [PATCH 04/13] [secure boot]fix conflict --- installer/default_platform.conf | 15 +++++++++++++-- scripts/signing_secure_boot_dev.sh | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/installer/default_platform.conf b/installer/default_platform.conf index 0c920b5b3c2c..8ff4fd4c5a39 100755 --- a/installer/default_platform.conf +++ b/installer/default_platform.conf @@ -577,13 +577,13 @@ menuentry '$demo_grub_entry' { if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi insmod part_msdos insmod ext2 - linux /$image_dir/boot/vmlinuz-5.10.0-18-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ + $GRUB_CFG_LINUX_CMD /$image_dir/boot/vmlinuz-5.10.0-18-2-amd64 root=$grub_cfg_root rw $GRUB_CMDLINE_LINUX \ net.ifnames=0 biosdevname=0 \ loop=$image_dir/$FILESYSTEM_SQUASHFS loopfstype=squashfs \ systemd.unified_cgroup_hierarchy=0 \ apparmor=1 security=apparmor varlog_size=$VAR_LOG_SIZE usbcore.autosuspend=-1 $ONIE_PLATFORM_EXTRA_CMDLINE_LINUX echo 'Loading $demo_volume_label $demo_type initial ramdisk ...' - initrd /$image_dir/boot/initrd.img-5.10.0-18-2-amd64 + $GRUB_CFG_INITRD_CMD /$image_dir/boot/initrd.img-5.10.0-18-2-amd64 } EOF @@ -606,6 +606,17 @@ EOF cp $grub_cfg $onie_initrd_tmp/$demo_mnt/grub/grub.cfg fi + if [ "$secure_boot_state" = "SecureBoot enabled" ]; then + # Secure Boot grub.cfg support + # Saving grub_cfg in the same place where is grubx64.efi, + # this grub_cfg file will be called by first grub.cfg file from: /boot/efi/EFI/debian/grub.cfg + if [ -f $NVOS_BOOT_DIR/grub.cfg ]; then + rm $NVOS_BOOT_DIR/grub.cfg + fi + + cp $grub_cfg $NVOS_BOOT_DIR/grub.cfg + fi + cd / echo "Installed SONiC base image $demo_volume_label successfully" diff --git a/scripts/signing_secure_boot_dev.sh b/scripts/signing_secure_boot_dev.sh index c8702f79b8b3..b4a95efd84b2 100755 --- a/scripts/signing_secure_boot_dev.sh +++ b/scripts/signing_secure_boot_dev.sh @@ -149,4 +149,4 @@ sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e ${CURR_V ######################### sudo bash scripts/signing_kernel_modules.sh $LINUX_KERNEL_VERSION ${PEM_CERT} ${PEM_PRIV_KEY} -echo "$0 signing & verifying EFI files and Kernel Modules DONE" \ No newline at end of file +echo "$0 signing & verifying EFI files and Kernel Modules DONE" From 78bb260d478b204ecfa1726482f20155b53d651a Mon Sep 17 00:00:00 2001 From: David Pilnik Date: Mon, 28 Nov 2022 16:14:59 +0200 Subject: [PATCH 05/13] [secure boot]Add getopts to signing scripts --- build_debian.sh | 10 ++-- installer/default_platform.conf | 3 +- rules/config | 4 +- scripts/efi-sign.sh | 25 ++++---- scripts/secure_boot_signature_verification.sh | 2 +- scripts/signing_kernel_modules.sh | 26 +++++---- scripts/signing_secure_boot_dev.sh | 58 +++++++++---------- scripts/signing_secure_boot_prod.sh | 1 + 8 files changed, 66 insertions(+), 63 deletions(-) create mode 100644 scripts/signing_secure_boot_prod.sh diff --git a/build_debian.sh b/build_debian.sh index 4e3f2d6f142b..a907d38f03bf 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -659,11 +659,11 @@ if [[ $SECURE_UPGRADE_MODE == 'dev' || $SECURE_UPGRADE_MODE == "prod" && $SONIC_ exit 1 fi - sudo bash scripts/signing_secure_boot_dev.sh $CONFIGURED_ARCH \ - $FILESYSTEM_ROOT \ - $LINUX_KERNEL_VERSION \ - $SECURE_UPGRADE_DEV_SIGNING_CERT \ - $SECURE_UPGRADE_DEV_SIGNING_KEY + sudo bash scripts/signing_secure_boot_dev.sh -a $CONFIGURED_ARCH \ + -r $FILESYSTEM_ROOT \ + -l $LINUX_KERNEL_VERSION \ + -c $SECURE_UPGRADE_DEV_SIGNING_CERT \ + -p $SECURE_UPGRADE_DEV_SIGNING_KEY elif [[ $SECURE_UPGRADE_MODE == "prod" ]]; then # Here Vendor signing should be implemented OUTPUT_SEC_BOOT_DIR=$FILESYSTEM_ROOT/boot diff --git a/installer/default_platform.conf b/installer/default_platform.conf index 8ff4fd4c5a39..0f4f6fef042c 100755 --- a/installer/default_platform.conf +++ b/installer/default_platform.conf @@ -475,8 +475,7 @@ bootloader_menu_config() fi DEFAULT_GRUB_SERIAL_COMMAND="serial --port=${CONSOLE_PORT} --speed=${CONSOLE_SPEED} --word=8 --parity=no --stop=1" - # DEFAULT_GRUB_CMDLINE_LINUX="console=tty0 console=ttyS${CONSOLE_DEV},${CONSOLE_SPEED}n8 quiet $CSTATES" - DEFAULT_GRUB_CMDLINE_LINUX="console=tty0 console=ttyS${CONSOLE_DEV},${CONSOLE_SPEED}n8 loglevel=7 systemd.log_level=debug $CSTATES" + DEFAULT_GRUB_CMDLINE_LINUX="console=tty0 console=ttyS${CONSOLE_DEV},${CONSOLE_SPEED}n8 quiet $CSTATES" GRUB_SERIAL_COMMAND=${GRUB_SERIAL_COMMAND:-"$DEFAULT_GRUB_SERIAL_COMMAND"} GRUB_CMDLINE_LINUX=${GRUB_CMDLINE_LINUX:-"$DEFAULT_GRUB_CMDLINE_LINUX"} export GRUB_SERIAL_COMMAND diff --git a/rules/config b/rules/config index b6c06a3ca2fa..1b39bf166cee 100644 --- a/rules/config +++ b/rules/config @@ -224,8 +224,8 @@ SONIC_ENABLE_SECUREBOOT_SIGNATURE ?= n # SECURE_UPGRADE_DEV_SIGNING_KEY - path to development signing key, used for image signing during build # SECURE_UPGRADE_DEV_SIGNING_CERT - path to development signing certificate, used for image signing during build # SECURE_UPGRADE_MODE - enum value for secure upgrade mode, valid options are "dev", "prod" and "no_sign" -SECURE_UPGRADE_DEV_SIGNING_KEY = /sonic/files/nv_onyx_key.pem -SECURE_UPGRADE_DEV_SIGNING_CERT = /sonic/files/nv_onyx_key_certificate.pem +SECURE_UPGRADE_DEV_SIGNING_KEY = /sonic/your/private/key/path/private_key.pem +SECURE_UPGRADE_DEV_SIGNING_CERT = /sonic/your/certificate/path/cert.pem SECURE_UPGRADE_MODE = "no_sign" # PACKAGE_URL_PREFIX - the package url prefix diff --git a/scripts/efi-sign.sh b/scripts/efi-sign.sh index 53ebddcaca5d..6225880d09b0 100755 --- a/scripts/efi-sign.sh +++ b/scripts/efi-sign.sh @@ -8,25 +8,28 @@ set -e # - grub # - vmlinuz # -usage() { +print_usage() { cat < +$0 -p -c -e -s Usage example: efi-sign.sh priv-key.pem pub-key.pem shimx64.efi shimx64-signed.efi EOF } -if [ "$1" = "-h" -o "$1" = "--help" ]; then - usage -fi - -PRIVATE_KEY_PEM="$1" -CERT_PEM="$2" -EFI_FILE="$3" -EFI_FILE_SIGNED="$4" - +while getopts 'p:c:e:s:hv' flag; do + case "${flag}" in + p) PRIVATE_KEY_PEM="${OPTARG}" ;; + c) CERT_PEM="${OPTARG}" ;; + e) EFI_FILE="${OPTARG}" ;; + s) EFI_FILE_SIGNED="${OPTARG}" ;; + v) VERBOSE='true' ;; + h) print_usage + exit 1 ;; + esac +done +if [ $OPTIND -eq 1 ]; then echo "no options were pass"; print_usage; exit 1 ;fi [ -f "$PRIVATE_KEY_PEM" ] || { echo "Error: PRIVATE_KEY_PEM file does not exist: $PRIVATE_KEY_PEM" diff --git a/scripts/secure_boot_signature_verification.sh b/scripts/secure_boot_signature_verification.sh index 1a70a74dea98..e704d8fabc35 100755 --- a/scripts/secure_boot_signature_verification.sh +++ b/scripts/secure_boot_signature_verification.sh @@ -8,7 +8,7 @@ KERNEL_MODULES_DIR='' CERT_PEM='' VERBOSE='false' -usage() { +print_usage() { cat < +$0 -l -c -p -s -e -k Sign kernel modules in using private & public keys. Parameters description: @@ -21,16 +21,20 @@ Runs examples: EOF } -if [ "$1" = "-h" -o "$1" = "--help" ]; then - usage -fi - -LINUX_KERNEL_VERSION="$1" -PEM_CERT="$2" -PEM_PRIVATE_KEY="$3" -KERNEL_MODULES_DIR="$4" -LOCAL_SIGN_FILE="$5" -LOCAL_EXTRACT_CERT="$6" +while getopts 'l:c:p:k:s:e:hv' flag; do + case "${flag}" in + l) LINUX_KERNEL_VERSION="${OPTARG}" ;; + c) PEM_CERT="${OPTARG}" ;; + p) PEM_PRIVATE_KEY="${OPTARG}" ;; + k) KERNEL_MODULES_DIR="${OPTARG}" ;; + s) LOCAL_SIGN_FILE="${OPTARG}" ;; + e) LOCAL_EXTRACT_CERT="${OPTARG}" ;; + v) VERBOSE='true' ;; + h) print_usage + exit 1 ;; + esac +done +if [ $OPTIND -eq 1 ]; then echo "no options were pass"; print_usage; exit 1 ;fi if [ -z ${LINUX_KERNEL_VERSION} ]; then echo "ERROR: LINUX_KERNEL_VERSION arg1 is empty" diff --git a/scripts/signing_secure_boot_dev.sh b/scripts/signing_secure_boot_dev.sh index b4a95efd84b2..91f7b06693ac 100755 --- a/scripts/signing_secure_boot_dev.sh +++ b/scripts/signing_secure_boot_dev.sh @@ -4,12 +4,11 @@ ## Enable debug output for script & exit code when failing occurs set -x -e -usage() { +print_usage() { cat < -Usage example: efi-sign.sh priv-key.pem pub-key.pem shimx64.efi shimx64-signed.efi +$0 -a -r -l -c -p EOF } @@ -17,19 +16,26 @@ EOF clean_file() { if [ -f $1 ]; then echo "clean old file named: $1" - echo "sudo rm $1" - sudo rm $1 - echo "$?" - exit 1 + echo "sudo rm -f $1" + sudo sudo rm -f $1 fi } +while getopts 'a:r:l:c:p:hv' flag; do + case "${flag}" in + a) CONFIGURED_ARCH="${OPTARG}" ;; + r) FS_ROOT="${OPTARG}" ;; + l) LINUX_KERNEL_VERSION="${OPTARG}" ;; + c) PEM_CERT="${OPTARG}" ;; + p) PEM_PRIV_KEY="${OPTARG}" ;; + v) VERBOSE='true' ;; + h) print_usage + exit 1 ;; + esac +done +if [ $OPTIND -eq 1 ]; then echo "no options were pass"; print_usage; exit 1 ;fi + echo "$0 signing & verifying EFI files and Kernel Modules start ..." -CONFIGURED_ARCH="$1" -FS_ROOT="$2" -LINUX_KERNEL_VERSION="$3" -PEM_CERT="$4" -PEM_PRIV_KEY="$5" if [ -z ${CONFIGURED_ARCH} ]; then echo "ERROR: CONFIGURED_ARCH=${CONFIGURED_ARCH} is empty" @@ -85,13 +91,9 @@ clean_file ${MMX_EFI_SRC}-signed clean_file $FS_ROOT/boot/shim${EFI_ARCH}.efi clean_file $FS_ROOT/boot/mm${EFI_ARCH}.efi -# clean old shim & mmx files in the env -sudo rm -f ${SHIMX_EFI_SRC}-signed ${MMX_EFI_SRC}-signed \ - $FS_ROOT/boot/shim${EFI_ARCH}.efi $FS_ROOT/boot/mm${EFI_ARCH}.efi - echo "signing shim${EFI_ARCH}.efi & mm${EFI_ARCH}.efi from location: ${SHIM_DIR_SRC} .." -sudo ${EFI_SIGNING} $PEM_PRIV_KEY $PEM_CERT ${SHIMX_EFI_SRC} ${SHIMX_EFI_SRC}-signed -sudo ${EFI_SIGNING} $PEM_PRIV_KEY $PEM_CERT ${MMX_EFI_SRC} ${MMX_EFI_SRC}-signed +sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${SHIMX_EFI_SRC} -s ${SHIMX_EFI_SRC}-signed +sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${MMX_EFI_SRC} -s ${MMX_EFI_SRC}-signed # cp shim & mmx signed files to boot directory in the fs. sudo cp ${SHIMX_EFI_SRC}-signed $FS_ROOT/boot/shim${EFI_ARCH}.efi @@ -105,18 +107,15 @@ sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e $FS_ROOT ## grub signing ###################### -# clean old files -clean_file ${GRUB_EFI_SRC}-signed -clean_file $FS_ROOT/boot/grub${EFI_ARCH}.efi - GRUB_DIR_SRC=$FS_ROOT/usr/lib/grub/x86_64-efi/monolithic/ GRUB_EFI_SRC=$GRUB_DIR_SRC/grub${EFI_ARCH}.efi -# clean old grub files in the env -sudo rm -f ${GRUB_EFI_SRC}-signed $FS_ROOT/boot/grub${EFI_ARCH}.efi +# clean old files +clean_file ${GRUB_EFI_SRC}-signed +clean_file $FS_ROOT/boot/grub${EFI_ARCH}.efi echo "signing grub${EFI_ARCH}.efi from location: ${GRUB_EFI_SRC} .." -sudo ${EFI_SIGNING} $PEM_PRIV_KEY $PEM_CERT ${GRUB_EFI_SRC} ${GRUB_EFI_SRC}-signed +sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${GRUB_EFI_SRC} -s ${GRUB_EFI_SRC}-signed # cp signed grub to fs boot dir. sudo cp ${GRUB_EFI_SRC}-signed $FS_ROOT/boot/grub${EFI_ARCH}.efi @@ -133,20 +132,17 @@ CURR_VMLINUZ=$FS_ROOT/boot/vmlinuz-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH} # clean old files clean_file ${CURR_VMLINUZ}-signed -# clean old grub files in the env -sudo rm -f ${CURR_VMLINUZ}-signed - echo "signing ${CURR_VMLINUZ} .." -sudo ${EFI_SIGNING} $PEM_PRIV_KEY $PEM_CERT ${CURR_VMLINUZ} ${CURR_VMLINUZ}-signed +sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${CURR_VMLINUZ} -s ${CURR_VMLINUZ}-signed # rename signed vmlinuz with the name vmlinuz without signed suffix -sudo cp ${CURR_VMLINUZ}-signed ${CURR_VMLINUZ} +sudo mv ${CURR_VMLINUZ}-signed ${CURR_VMLINUZ} sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e ${CURR_VMLINUZ} ######################### # Kernel Modules signing ######################### -sudo bash scripts/signing_kernel_modules.sh $LINUX_KERNEL_VERSION ${PEM_CERT} ${PEM_PRIV_KEY} +sudo bash scripts/signing_kernel_modules.sh -l $LINUX_KERNEL_VERSION -c ${PEM_CERT} -p ${PEM_PRIV_KEY} -k ${FS_ROOT} echo "$0 signing & verifying EFI files and Kernel Modules DONE" diff --git a/scripts/signing_secure_boot_prod.sh b/scripts/signing_secure_boot_prod.sh new file mode 100644 index 000000000000..111283cb8a59 --- /dev/null +++ b/scripts/signing_secure_boot_prod.sh @@ -0,0 +1 @@ +#In this script Vendor should code the logic to build a secure boot image by using vendor flows From 29e619e388e68038ec2a7b76503e7615389a4123 Mon Sep 17 00:00:00 2001 From: David Pilnik Date: Thu, 1 Dec 2022 19:55:20 +0200 Subject: [PATCH 06/13] [secure boot]Support arm platform by signing with reggex instead hard-coded platform --- scripts/efi-sign.sh | 8 +-- scripts/signing_secure_boot_dev.sh | 79 ++++++++++-------------------- 2 files changed, 30 insertions(+), 57 deletions(-) diff --git a/scripts/efi-sign.sh b/scripts/efi-sign.sh index 6225880d09b0..fd890f23c4fc 100755 --- a/scripts/efi-sign.sh +++ b/scripts/efi-sign.sh @@ -33,25 +33,25 @@ if [ $OPTIND -eq 1 ]; then echo "no options were pass"; print_usage; exit 1 ;fi [ -f "$PRIVATE_KEY_PEM" ] || { echo "Error: PRIVATE_KEY_PEM file does not exist: $PRIVATE_KEY_PEM" - usage + print_usage exit 1 } [ -f "$CERT_PEM" ] || { echo "Error: CERT_PEM file does not exist: $CERT_PEM" - usage + print_usage exit 1 } [ -f "$EFI_FILE" ] || { echo "Error: File for signing does not exist: $EFI_FILE" - usage + print_usage exit 1 } if [ -z ${EFI_FILE_SIGNED} ]; then echo "ERROR: no arg named supplied" - usage + print_usage exit 1 fi diff --git a/scripts/signing_secure_boot_dev.sh b/scripts/signing_secure_boot_dev.sh index 91f7b06693ac..134aed2afbf8 100755 --- a/scripts/signing_secure_boot_dev.sh +++ b/scripts/signing_secure_boot_dev.sh @@ -8,7 +8,7 @@ print_usage() { cat < -r -l -c -p +$0 -r -l -c -p EOF } @@ -67,61 +67,34 @@ if [ ! -f "${PEM_PRIV_KEY}" ]; then exit 1 fi -ARCH='' -if [[ $CONFIGURED_ARCH == amd64 ]]; then -ARCH=x86_64 -EFI_ARCH=x64 -fi - # efi-sign.sh is used to sign: shim, mmx, grub, and kernel (vmlinuz) EFI_SIGNING=scripts/efi-sign.sh -###################### -## shim & mmx signing -###################### - -# shim dirs -SHIM_DIR_SRC=$FS_ROOT/usr/lib/shim -MMX_EFI_SRC=$SHIM_DIR_SRC/mm${EFI_ARCH}.efi -SHIMX_EFI_SRC=$SHIM_DIR_SRC/shim${EFI_ARCH}.efi - -# clean old files -clean_file ${SHIMX_EFI_SRC}-signed -clean_file ${MMX_EFI_SRC}-signed -clean_file $FS_ROOT/boot/shim${EFI_ARCH}.efi -clean_file $FS_ROOT/boot/mm${EFI_ARCH}.efi - -echo "signing shim${EFI_ARCH}.efi & mm${EFI_ARCH}.efi from location: ${SHIM_DIR_SRC} .." -sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${SHIMX_EFI_SRC} -s ${SHIMX_EFI_SRC}-signed -sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${MMX_EFI_SRC} -s ${MMX_EFI_SRC}-signed - -# cp shim & mmx signed files to boot directory in the fs. -sudo cp ${SHIMX_EFI_SRC}-signed $FS_ROOT/boot/shim${EFI_ARCH}.efi -sudo cp ${MMX_EFI_SRC}-signed $FS_ROOT/boot/mm${EFI_ARCH}.efi - -# verifying signature of mm & shim efi files. -sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e $FS_ROOT/boot/shim${EFI_ARCH}.efi -sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e $FS_ROOT/boot/mm${EFI_ARCH}.efi - -###################### -## grub signing -###################### - -GRUB_DIR_SRC=$FS_ROOT/usr/lib/grub/x86_64-efi/monolithic/ -GRUB_EFI_SRC=$GRUB_DIR_SRC/grub${EFI_ARCH}.efi - -# clean old files -clean_file ${GRUB_EFI_SRC}-signed -clean_file $FS_ROOT/boot/grub${EFI_ARCH}.efi - -echo "signing grub${EFI_ARCH}.efi from location: ${GRUB_EFI_SRC} .." -sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${GRUB_EFI_SRC} -s ${GRUB_EFI_SRC}-signed - -# cp signed grub to fs boot dir. -sudo cp ${GRUB_EFI_SRC}-signed $FS_ROOT/boot/grub${EFI_ARCH}.efi - -# verifying signature of grub efi file. -sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e $FS_ROOT/boot/grub${EFI_ARCH}.efi +# ###################################### +# Signing EFI files: mm, shim, grub +# ##################################### +efi_file_list=$(sudo find ${KERNEL_MODULES_DIR} -name "*.efi") + +for efi in $efi_file_list +do + # grep filename from full path + efi_filename=$(echo $efi | grep -o '[^/]*$') + + if echo $efi_filename | grep -e "shim" -e "grub" -e "mm"; then + + clean_file ${efi}-signed + + echo "signing efi file - full path: ${efi} filename: ${efi_filename}" + echo "sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${efi} -s ${efi}-signed" + sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${efi} -s ${efi}-signed + + # cp shim & mmx signed files to boot directory in the fs. + sudo cp ${efi}-signed $FS_ROOT/boot/${efi_filename} + + # verifying signature of mm & shim efi files. + sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e $FS_ROOT/boot/${efi_filename} + fi +done ###################### ## vmlinuz signing From 9f184b9124c48c65b0cda429e66068d96d7de519 Mon Sep 17 00:00:00 2001 From: David Pilnik Date: Mon, 5 Dec 2022 08:48:14 +0200 Subject: [PATCH 07/13] [secure boot]Remove sudo redundancy, fix code example comments --- build_debian.sh | 24 ++++++++++++------------ scripts/efi-sign.sh | 2 +- scripts/signing_kernel_modules.sh | 8 ++++---- scripts/signing_secure_boot_dev.sh | 28 ++++++++++++++-------------- scripts/signing_secure_boot_prod.sh | 3 ++- 5 files changed, 33 insertions(+), 32 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index a907d38f03bf..816889321791 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -659,25 +659,25 @@ if [[ $SECURE_UPGRADE_MODE == 'dev' || $SECURE_UPGRADE_MODE == "prod" && $SONIC_ exit 1 fi - sudo bash scripts/signing_secure_boot_dev.sh -a $CONFIGURED_ARCH \ - -r $FILESYSTEM_ROOT \ - -l $LINUX_KERNEL_VERSION \ - -c $SECURE_UPGRADE_DEV_SIGNING_CERT \ - -p $SECURE_UPGRADE_DEV_SIGNING_KEY + sudo ./scripts/signing_secure_boot_dev.sh -a $CONFIGURED_ARCH \ + -r $FILESYSTEM_ROOT \ + -l $LINUX_KERNEL_VERSION \ + -c $SECURE_UPGRADE_DEV_SIGNING_CERT \ + -p $SECURE_UPGRADE_DEV_SIGNING_KEY elif [[ $SECURE_UPGRADE_MODE == "prod" ]]; then # Here Vendor signing should be implemented OUTPUT_SEC_BOOT_DIR=$FILESYSTEM_ROOT/boot - sudo bash scripts/signing_secure_boot_prod.sh $CONFIGURED_ARCH $FILESYSTEM_ROOT $LINUX_KERNEL_VERSION $OUTPUT_SEC_BOOT_DIR + sudo ./scripts/signing_secure_boot_prod.sh $CONFIGURED_ARCH $FILESYSTEM_ROOT $LINUX_KERNEL_VERSION $OUTPUT_SEC_BOOT_DIR # verifying all EFI files and kernel modules in $OUTPUT_SEC_BOOT_DIR - bash scripts/secure_boot_signature_verification.sh -e $OUTPUT_SEC_BOOT_DIR \ - -c $SECURE_UPGRADE_DEV_SIGNING_CERT \ - -k $FILESYSTEM_ROOT + sudo ./scripts/secure_boot_signature_verification.sh -e $OUTPUT_SEC_BOOT_DIR \ + -c $SECURE_UPGRADE_DEV_SIGNING_CERT \ + -k $FILESYSTEM_ROOT # verifying vmlinuz file. - bash scripts/secure_boot_signature_verification.sh -e $FILESYSTEM_ROOT/boot/vmlinuz-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH} \ - -c $SECURE_UPGRADE_DEV_SIGNING_CERT \ - -k $FILESYSTEM_ROOT + sudo ./scripts/secure_boot_signature_verification.sh -e $FILESYSTEM_ROOT/boot/vmlinuz-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH} \ + -c $SECURE_UPGRADE_DEV_SIGNING_CERT \ + -k $FILESYSTEM_ROOT fi echo "Secure Boot support build stage: END." fi diff --git a/scripts/efi-sign.sh b/scripts/efi-sign.sh index fd890f23c4fc..34dca50b067d 100755 --- a/scripts/efi-sign.sh +++ b/scripts/efi-sign.sh @@ -13,7 +13,7 @@ print_usage() { $0: Usage $0 -p -c -e -s -Usage example: efi-sign.sh priv-key.pem pub-key.pem shimx64.efi shimx64-signed.efi +Usage example: efi-sign.sh -p priv-key.pem -c pub-key.pem -e shimx64.efi -s shimx64-signed.efi EOF } diff --git a/scripts/signing_kernel_modules.sh b/scripts/signing_kernel_modules.sh index 654ed2e1badd..5270d23b86f4 100755 --- a/scripts/signing_kernel_modules.sh +++ b/scripts/signing_kernel_modules.sh @@ -16,8 +16,8 @@ LOCAL_EXTRACT_CERT path of the extract-cert tool for Extract X KERNEL_MODULES_DIR root directory of all the kernel modules to be sign by the script, if the value empty it will use the call script location as root. Runs examples: -1. sudo bash scripts/signing_kernel_modules.sh 5.10.0-8-2 cert.pem priv-key.pem -2. sudo bash scripts/signing_kernel_modules.sh 5.10.0-8-2 cert.pem priv-key.pem fsroot-mellanox /usr/lib/linux-kbuild-5.10/scripts/extract-cert /usr/lib/linux-kbuild-5.10/scripts/sign-file +1. ./scripts/signing_kernel_modules.sh -l 5.10.0-8-2 -c cert.pem -p priv-key.pem +2. ./scripts/signing_kernel_modules.sh -l 5.10.0-8-2 -c cert.pem -p priv-key.pem -k fsroot-mellanox -e /usr/lib/linux-kbuild-5.10/scripts/extract-cert -s /usr/lib/linux-kbuild-5.10/scripts/sign-file EOF } @@ -83,7 +83,7 @@ if [ ! -d "$KERNEL_MODULES_DIR" ]; then fi # find all the kernel modules. -modules_list=$(sudo find ${KERNEL_MODULES_DIR} -name "*.ko") +modules_list=$(find ${KERNEL_MODULES_DIR} -name "*.ko") dev_certs_tmp_folder="/tmp/dev_kmod_sign" @@ -111,7 +111,7 @@ do echo "signing module named: ${mod} .." echo "${LOCAL_SIGN_FILE} sha512 ${local_sign_key} ${local_sign_cert} ${mod}" kernel_modules_cnt=$((kernel_modules_cnt+1)) - sudo ${LOCAL_SIGN_FILE} sha512 ${local_sign_key} ${local_sign_cert} ${mod} + ${LOCAL_SIGN_FILE} sha512 ${local_sign_key} ${local_sign_cert} ${mod} # check Kernel module is signed. if ! grep -q "~Module signature appended~" "${mod}"; then diff --git a/scripts/signing_secure_boot_dev.sh b/scripts/signing_secure_boot_dev.sh index 134aed2afbf8..cc937215b9b2 100755 --- a/scripts/signing_secure_boot_dev.sh +++ b/scripts/signing_secure_boot_dev.sh @@ -16,8 +16,8 @@ EOF clean_file() { if [ -f $1 ]; then echo "clean old file named: $1" - echo "sudo rm -f $1" - sudo sudo rm -f $1 + echo "rm -f $1" + rm -f $1 fi } @@ -39,31 +39,31 @@ echo "$0 signing & verifying EFI files and Kernel Modules start ..." if [ -z ${CONFIGURED_ARCH} ]; then echo "ERROR: CONFIGURED_ARCH=${CONFIGURED_ARCH} is empty" - usage + print_usage exit 1 fi if [ -z ${FS_ROOT} ]; then echo "ERROR: FS_ROOT=${FS_ROOT} is empty" - usage + print_usage exit 1 fi if [ -z ${LINUX_KERNEL_VERSION} ]; then echo "ERROR: LINUX_KERNEL_VERSION=${LINUX_KERNEL_VERSION} is empty" - usage + print_usage exit 1 fi if [ ! -f "${PEM_CERT}" ]; then echo "ERROR: PEM_CERT=${PEM_CERT} file does not exist" - usage + print_usage exit 1 fi if [ ! -f "${PEM_PRIV_KEY}" ]; then echo "ERROR: PEM_PRIV_KEY=${PEM_PRIV_KEY} file does not exist" - usage + print_usage exit 1 fi @@ -86,13 +86,13 @@ do echo "signing efi file - full path: ${efi} filename: ${efi_filename}" echo "sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${efi} -s ${efi}-signed" - sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${efi} -s ${efi}-signed + ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${efi} -s ${efi}-signed # cp shim & mmx signed files to boot directory in the fs. - sudo cp ${efi}-signed $FS_ROOT/boot/${efi_filename} + cp ${efi}-signed $FS_ROOT/boot/${efi_filename} # verifying signature of mm & shim efi files. - sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e $FS_ROOT/boot/${efi_filename} + ./scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e $FS_ROOT/boot/${efi_filename} fi done @@ -106,16 +106,16 @@ CURR_VMLINUZ=$FS_ROOT/boot/vmlinuz-${LINUX_KERNEL_VERSION}-${CONFIGURED_ARCH} clean_file ${CURR_VMLINUZ}-signed echo "signing ${CURR_VMLINUZ} .." -sudo ${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${CURR_VMLINUZ} -s ${CURR_VMLINUZ}-signed +${EFI_SIGNING} -p $PEM_PRIV_KEY -c $PEM_CERT -e ${CURR_VMLINUZ} -s ${CURR_VMLINUZ}-signed # rename signed vmlinuz with the name vmlinuz without signed suffix -sudo mv ${CURR_VMLINUZ}-signed ${CURR_VMLINUZ} +mv ${CURR_VMLINUZ}-signed ${CURR_VMLINUZ} -sudo bash scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e ${CURR_VMLINUZ} +./scripts/secure_boot_signature_verification.sh -c $PEM_CERT -e ${CURR_VMLINUZ} ######################### # Kernel Modules signing ######################### -sudo bash scripts/signing_kernel_modules.sh -l $LINUX_KERNEL_VERSION -c ${PEM_CERT} -p ${PEM_PRIV_KEY} -k ${FS_ROOT} +./scripts/signing_kernel_modules.sh -l $LINUX_KERNEL_VERSION -c ${PEM_CERT} -p ${PEM_PRIV_KEY} -k ${FS_ROOT} echo "$0 signing & verifying EFI files and Kernel Modules DONE" diff --git a/scripts/signing_secure_boot_prod.sh b/scripts/signing_secure_boot_prod.sh index 111283cb8a59..a90940ee57e5 100644 --- a/scripts/signing_secure_boot_prod.sh +++ b/scripts/signing_secure_boot_prod.sh @@ -1 +1,2 @@ -#In this script Vendor should code the logic to build a secure boot image by using vendor flows +# In this script Vendor should code the logic to build a secure boot image by using production vendor flows. +# More details can be found in the Secure Boot HLD in https://github.com/sonic-net/SONiC repo From 8758f696c9d63fbda24f31e5aadc62439289ac35 Mon Sep 17 00:00:00 2001 From: "david.zagury" Date: Mon, 19 Dec 2022 13:43:53 +0200 Subject: [PATCH 08/13] Mount the Signing key and Certificate in the slave container --- Makefile.work | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile.work b/Makefile.work index 8d5a1ff49d31..bea0642e64a2 100644 --- a/Makefile.work +++ b/Makefile.work @@ -309,6 +309,14 @@ ifdef SONIC_BUILD_QUIETER DOCKER_RUN += -e "SONIC_BUILD_QUIETER=$(SONIC_BUILD_QUIETER)" endif +# Mount the Signing key and Certificate in the slave container +ifneq ($(SECURE_UPGRADE_DEV_SIGNING_KEY),) + DOCKER_RUN += -v $(SECURE_UPGRADE_DEV_SIGNING_KEY):$(SECURE_UPGRADE_DEV_SIGNING_KEY):ro +endif +ifneq ($(SECURE_UPGRADE_DEV_SIGNING_CERT),) + DOCKER_RUN += -v $(SECURE_UPGRADE_DEV_SIGNING_CERT):$(SECURE_UPGRADE_DEV_SIGNING_CERT):ro +endif + ifneq ($(SONIC_DPKG_CACHE_SOURCE),) DOCKER_RUN += -v "$(SONIC_DPKG_CACHE_SOURCE):/dpkg_cache:rw" endif From 2b409114941d49ffd8484fb0d30cdc6a695b76a5 Mon Sep 17 00:00:00 2001 From: David Pilnik Date: Wed, 25 Jan 2023 15:09:09 +0200 Subject: [PATCH 09/13] [secure boot]Add support to re-build kernel if Secure Boot flag modify. --- rules/linux-kernel.dep | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rules/linux-kernel.dep b/rules/linux-kernel.dep index 4706f56afbaf..7e2dd4741486 100644 --- a/rules/linux-kernel.dep +++ b/rules/linux-kernel.dep @@ -4,11 +4,10 @@ DEP_FILES := rules/linux-kernel.mk rules/linux-kernel.dep SMDEP_FILES := $(addprefix $(SPATH)/,$(shell cd $(SPATH) && git ls-files)) DEP_FLAGS := $(SONIC_COMMON_FLAGS_LIST) \ - $(KERNEL_PROCURE_METHOD) $(KERNEL_CACHE_PATH) + $(KERNEL_PROCURE_METHOD) $(KERNEL_CACHE_PATH) $(SECURE_UPGRADE_MODE) $(SECURE_UPGRADE_DEV_SIGNING_CERT) $(LINUX_HEADERS_COMMON)_CACHE_MODE := GIT_CONTENT_SHA $(LINUX_HEADERS_COMMON)_DEP_FLAGS := $(DEP_FLAGS) $(LINUX_HEADERS_COMMON)_DEP_FILES := $(DEP_FILES) $(LINUX_HEADERS_COMMON)_SMDEP_FILES := $(SMDEP_FILES) $(LINUX_HEADERS_COMMON)_SMDEP_PATHS := $(SPATH) - From 410886000d942798e54816776e50c8a2e9f12f35 Mon Sep 17 00:00:00 2001 From: David Pilnik Date: Thu, 9 Feb 2023 14:46:12 +0200 Subject: [PATCH 10/13] [secure boot]Add new build flag for signing vendor prod script --- Makefile.work | 8 ++++++++ build_debian.sh | 2 +- rules/config | 3 ++- slave.mk | 3 +++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Makefile.work b/Makefile.work index bea0642e64a2..cdaa1184370f 100644 --- a/Makefile.work +++ b/Makefile.work @@ -316,6 +316,13 @@ endif ifneq ($(SECURE_UPGRADE_DEV_SIGNING_CERT),) DOCKER_RUN += -v $(SECURE_UPGRADE_DEV_SIGNING_CERT):$(SECURE_UPGRADE_DEV_SIGNING_CERT):ro endif +# Mount the Signing prod tool in the slave container +$(info "SECURE_UPGRADE_PROD_SIGNING_TOOL": "$(SECURE_UPGRADE_PROD_SIGNING_TOOL)") +ifneq ($(SECURE_UPGRADE_PROD_SIGNING_TOOL),) + SECURE_UPGRADE_PROD_SIGNING_TOOL_DST = /sonic/scripts/$(shell basename -- $(SECURE_UPGRADE_PROD_SIGNING_TOOL)) + DOCKER_RUN += -v $(SECURE_UPGRADE_PROD_SIGNING_TOOL):$(SECURE_UPGRADE_PROD_SIGNING_TOOL_DST):ro + SECURE_UPGRADE_PROD_SIGNING_TOOL := $(SECURE_UPGRADE_PROD_SIGNING_TOOL_SOURCE) +endif ifneq ($(SONIC_DPKG_CACHE_SOURCE),) DOCKER_RUN += -v "$(SONIC_DPKG_CACHE_SOURCE):/dpkg_cache:rw" @@ -536,6 +543,7 @@ SONIC_BUILD_INSTRUCTION := $(MAKE) \ SECURE_UPGRADE_MODE=$(SECURE_UPGRADE_MODE) \ SECURE_UPGRADE_DEV_SIGNING_KEY=$(SECURE_UPGRADE_DEV_SIGNING_KEY) \ SECURE_UPGRADE_DEV_SIGNING_CERT=$(SECURE_UPGRADE_DEV_SIGNING_CERT) \ + SECURE_UPGRADE_PROD_SIGNING_TOOL=$(SECURE_UPGRADE_PROD_SIGNING_TOOL) \ SONIC_DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) \ ENABLE_HOST_SERVICE_ON_START=$(ENABLE_HOST_SERVICE_ON_START) \ SLAVE_DIR=$(SLAVE_DIR) \ diff --git a/build_debian.sh b/build_debian.sh index 816889321791..e5696797b9e9 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -667,7 +667,7 @@ if [[ $SECURE_UPGRADE_MODE == 'dev' || $SECURE_UPGRADE_MODE == "prod" && $SONIC_ elif [[ $SECURE_UPGRADE_MODE == "prod" ]]; then # Here Vendor signing should be implemented OUTPUT_SEC_BOOT_DIR=$FILESYSTEM_ROOT/boot - sudo ./scripts/signing_secure_boot_prod.sh $CONFIGURED_ARCH $FILESYSTEM_ROOT $LINUX_KERNEL_VERSION $OUTPUT_SEC_BOOT_DIR + sudo $SECURE_UPGRADE_PROD_SIGNING_TOOL $CONFIGURED_ARCH $FILESYSTEM_ROOT $LINUX_KERNEL_VERSION $OUTPUT_SEC_BOOT_DIR # verifying all EFI files and kernel modules in $OUTPUT_SEC_BOOT_DIR sudo ./scripts/secure_boot_signature_verification.sh -e $OUTPUT_SEC_BOOT_DIR \ diff --git a/rules/config b/rules/config index 1b39bf166cee..068514172b40 100644 --- a/rules/config +++ b/rules/config @@ -224,10 +224,11 @@ SONIC_ENABLE_SECUREBOOT_SIGNATURE ?= n # SECURE_UPGRADE_DEV_SIGNING_KEY - path to development signing key, used for image signing during build # SECURE_UPGRADE_DEV_SIGNING_CERT - path to development signing certificate, used for image signing during build # SECURE_UPGRADE_MODE - enum value for secure upgrade mode, valid options are "dev", "prod" and "no_sign" +# SECURE_UPGRADE_PROD_SIGNING_TOOL - path to a vendor signing tool for production flow. SECURE_UPGRADE_DEV_SIGNING_KEY = /sonic/your/private/key/path/private_key.pem SECURE_UPGRADE_DEV_SIGNING_CERT = /sonic/your/certificate/path/cert.pem SECURE_UPGRADE_MODE = "no_sign" - +SECURE_UPGRADE_PROD_SIGNING_TOOL ?= none # PACKAGE_URL_PREFIX - the package url prefix PACKAGE_URL_PREFIX ?= https://packages.trafficmanager.net/public/packages diff --git a/slave.mk b/slave.mk index eefbb7941802..1d5c3dde7846 100644 --- a/slave.mk +++ b/slave.mk @@ -380,6 +380,7 @@ $(info "CHANGE_DEFAULT_PASSWORD" : "$(CHANGE_DEFAULT_PASSWORD)") $(info "SECURE_UPGRADE_MODE" : "$(SECURE_UPGRADE_MODE)") $(info "SECURE_UPGRADE_DEV_SIGNING_KEY" : "$(SECURE_UPGRADE_DEV_SIGNING_KEY)") $(info "SECURE_UPGRADE_DEV_SIGNING_CERT" : "$(SECURE_UPGRADE_DEV_SIGNING_CERT)") +$(info "SECURE_UPGRADE_PROD_SIGNING_TOOL": "$(SECURE_UPGRADE_PROD_SIGNING_TOOL)") $(info "ENABLE_DHCP_GRAPH_SERVICE" : "$(ENABLE_DHCP_GRAPH_SERVICE)") $(info "SHUTDOWN_BGP_ON_START" : "$(SHUTDOWN_BGP_ON_START)") $(info "ENABLE_PFCWD_ON_START" : "$(ENABLE_PFCWD_ON_START)") @@ -1264,6 +1265,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export sonic_su_dev_signing_key="$(SECURE_UPGRADE_DEV_SIGNING_KEY)" export sonic_su_dev_signing_cert="$(SECURE_UPGRADE_DEV_SIGNING_CERT)" export sonic_su_mode="$(SECURE_UPGRADE_MODE)" + export sonic_su_prod_signing_tool="$(SECURE_UPGRADE_PROD_SIGNING_TOOL)" export include_system_telemetry="$(INCLUDE_SYSTEM_TELEMETRY)" export include_restapi="$(INCLUDE_RESTAPI)" export include_nat="$(INCLUDE_NAT)" @@ -1467,6 +1469,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ SECURE_UPGRADE_MODE="$(SECURE_UPGRADE_MODE)" \ SECURE_UPGRADE_DEV_SIGNING_KEY="$(SECURE_UPGRADE_DEV_SIGNING_KEY)" \ SECURE_UPGRADE_DEV_SIGNING_CERT="$(SECURE_UPGRADE_DEV_SIGNING_CERT)" \ + SECURE_UPGRADE_PROD_SIGNING_TOOL="$(SECURE_UPGRADE_PROD_SIGNING_TOOL)" \ SIGNING_KEY="$(SIGNING_KEY)" \ SIGNING_CERT="$(SIGNING_CERT)" \ CA_CERT="$(CA_CERT)" \ From 455ea5df297ec322d0675257877a6d46a585bc5c Mon Sep 17 00:00:00 2001 From: David Pilnik Date: Mon, 27 Feb 2023 13:24:09 +0200 Subject: [PATCH 11/13] [secure boot]Removed unused file scripts/signing_secure_boot_prod.sh, fix variable typo SECURE_UPGRADE_PROD_SIGNING_TOOL_DST instead SECURE_UPGRADE_PROD_SIGNING_TOOL_SOURCE --- Makefile.work | 2 +- scripts/signing_secure_boot_prod.sh | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 scripts/signing_secure_boot_prod.sh diff --git a/Makefile.work b/Makefile.work index cdaa1184370f..49aaa6c41375 100644 --- a/Makefile.work +++ b/Makefile.work @@ -321,7 +321,7 @@ $(info "SECURE_UPGRADE_PROD_SIGNING_TOOL": "$(SECURE_UPGRADE_PROD_SIGNING_TOOL)" ifneq ($(SECURE_UPGRADE_PROD_SIGNING_TOOL),) SECURE_UPGRADE_PROD_SIGNING_TOOL_DST = /sonic/scripts/$(shell basename -- $(SECURE_UPGRADE_PROD_SIGNING_TOOL)) DOCKER_RUN += -v $(SECURE_UPGRADE_PROD_SIGNING_TOOL):$(SECURE_UPGRADE_PROD_SIGNING_TOOL_DST):ro - SECURE_UPGRADE_PROD_SIGNING_TOOL := $(SECURE_UPGRADE_PROD_SIGNING_TOOL_SOURCE) + SECURE_UPGRADE_PROD_SIGNING_TOOL := $(SECURE_UPGRADE_PROD_SIGNING_TOOL_DST) endif ifneq ($(SONIC_DPKG_CACHE_SOURCE),) diff --git a/scripts/signing_secure_boot_prod.sh b/scripts/signing_secure_boot_prod.sh deleted file mode 100644 index a90940ee57e5..000000000000 --- a/scripts/signing_secure_boot_prod.sh +++ /dev/null @@ -1,2 +0,0 @@ -# In this script Vendor should code the logic to build a secure boot image by using production vendor flows. -# More details can be found in the Secure Boot HLD in https://github.com/sonic-net/SONiC repo From d54f1e8039d07c97d8b6f5b477ec7eae24264cbd Mon Sep 17 00:00:00 2001 From: David Pilnik Date: Mon, 27 Feb 2023 14:26:20 +0200 Subject: [PATCH 12/13] [secure boot]fix minor issues: help print of secure signing script and remove spaces --- build_debian.sh | 6 ++++++ rules/config | 2 +- scripts/signing_kernel_modules.sh | 11 +++++------ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index e5696797b9e9..5ddfb8dd2a67 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -667,6 +667,12 @@ if [[ $SECURE_UPGRADE_MODE == 'dev' || $SECURE_UPGRADE_MODE == "prod" && $SONIC_ elif [[ $SECURE_UPGRADE_MODE == "prod" ]]; then # Here Vendor signing should be implemented OUTPUT_SEC_BOOT_DIR=$FILESYSTEM_ROOT/boot + + if [ ! -f $SECURE_UPGRADE_PROD_SIGNING_TOOL ]; then + echo "Error: SONiC SECURE_UPGRADE_PROD_SIGNING_TOOL=$SECURE_UPGRADE_PROD_SIGNING_TOOL script missing" + exit 1 + fi + sudo $SECURE_UPGRADE_PROD_SIGNING_TOOL $CONFIGURED_ARCH $FILESYSTEM_ROOT $LINUX_KERNEL_VERSION $OUTPUT_SEC_BOOT_DIR # verifying all EFI files and kernel modules in $OUTPUT_SEC_BOOT_DIR diff --git a/rules/config b/rules/config index 068514172b40..7d74c668e844 100644 --- a/rules/config +++ b/rules/config @@ -228,7 +228,7 @@ SONIC_ENABLE_SECUREBOOT_SIGNATURE ?= n SECURE_UPGRADE_DEV_SIGNING_KEY = /sonic/your/private/key/path/private_key.pem SECURE_UPGRADE_DEV_SIGNING_CERT = /sonic/your/certificate/path/cert.pem SECURE_UPGRADE_MODE = "no_sign" -SECURE_UPGRADE_PROD_SIGNING_TOOL ?= none +SECURE_UPGRADE_PROD_SIGNING_TOOL ?= # PACKAGE_URL_PREFIX - the package url prefix PACKAGE_URL_PREFIX ?= https://packages.trafficmanager.net/public/packages diff --git a/scripts/signing_kernel_modules.sh b/scripts/signing_kernel_modules.sh index 5270d23b86f4..d6db8f8cd39d 100755 --- a/scripts/signing_kernel_modules.sh +++ b/scripts/signing_kernel_modules.sh @@ -30,11 +30,11 @@ while getopts 'l:c:p:k:s:e:hv' flag; do s) LOCAL_SIGN_FILE="${OPTARG}" ;; e) LOCAL_EXTRACT_CERT="${OPTARG}" ;; v) VERBOSE='true' ;; - h) print_usage + h) usage exit 1 ;; esac done -if [ $OPTIND -eq 1 ]; then echo "no options were pass"; print_usage; exit 1 ;fi +if [ $OPTIND -eq 1 ]; then echo "no options were pass"; usage; exit 1 ;fi if [ -z ${LINUX_KERNEL_VERSION} ]; then echo "ERROR: LINUX_KERNEL_VERSION arg1 is empty" @@ -76,10 +76,9 @@ if [ ! -f ${LOCAL_EXTRACT_CERT} ]; then fi if [ ! -d "$KERNEL_MODULES_DIR" ]; then - # If the user do not provide a KERNEL_MODULES_DIR, the script is going to search in the script call path for Kernel modules. - KERNEL_MODULES_DIR="./" - echo "KERNEL_MODULES_DIR set to default path: $KERNEL_MODULES_DIR" - + # If the user do not provide a KERNEL_MODULES_DIR, the script is going to search in the script call path for Kernel modules. + KERNEL_MODULES_DIR="./" + echo "KERNEL_MODULES_DIR set to default path: $KERNEL_MODULES_DIR" fi # find all the kernel modules. From 7509fc5d3f855cba4d35a76248e79efc89e18048 Mon Sep 17 00:00:00 2001 From: David Pilnik Date: Mon, 6 Mar 2023 15:41:23 +0200 Subject: [PATCH 13/13] [secure boot]add return code verification when mounting efi --- installer/default_platform.conf | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/installer/default_platform.conf b/installer/default_platform.conf index 0f4f6fef042c..ddf59baffdc8 100755 --- a/installer/default_platform.conf +++ b/installer/default_platform.conf @@ -369,7 +369,10 @@ demo_install_uefi_shim() # make sure /boot/efi is mounted if ! mount | grep -q "/boot/efi"; then - mount /boot/efi + mount /boot/efi || { + echo "Error: Unable to mount /boot/efi" + exit 1 + } fi # Look for the EFI system partition UUID on the same block device as