diff --git a/build_image.sh b/build_image.sh index 862f584e9c86..133a95db32b7 100755 --- a/build_image.sh +++ b/build_image.sh @@ -221,7 +221,10 @@ elif [ "$IMAGE_TYPE" = "aboot" ]; then fi elif [[ $CONFIGURED_PLATFORM == nvidia-bluefield ]]; then - sudo --preserve-env /sonic/installer/bluefield/create_sonic_image --kernel $KVERSION + if [[ $SECURE_UPGRADE_MODE != "no_sign" ]]; then + secure_upgrade_keys="--signing-key "$SECURE_UPGRADE_DEV_SIGNING_KEY" --signing-cert "$SECURE_UPGRADE_SIGNING_CERT"" + fi + sudo --preserve-env /sonic/installer/bluefield/create_sonic_image --kernel $KVERSION "$secure_upgrade_keys" if [[ $IMAGE_TYPE != bin ]]; then sudo chown $USER ./$OUTPUT_BFB_IMAGE if [[ $IMAGE_TYPE == pxe ]]; then diff --git a/installer/bluefield/create_sonic_image b/installer/bluefield/create_sonic_image index 7679eeb9703b..a201ac0a28e5 100755 --- a/installer/bluefield/create_sonic_image +++ b/installer/bluefield/create_sonic_image @@ -31,6 +31,8 @@ INITRD= VMLINUZ= MODULES_DIR= +SIGNING_CERT= +SIGNING_KEY= CDIR=/sonic/ SDIR=$CDIR/installer/bluefield DDIR=$CDIR @@ -52,11 +54,12 @@ cat << EOF Usage: `basename $0` [ OPTIONS ] OPTIONS: -k, --kernel Kernel version for the SmartNIC. +-sc, --signing-cert Secure upgrade signing certificate. +-sk, --signing-key Secure upgrade signing key. -v, --verbose Run script in verbose mode. Will print out each step of execution. -h, --help Display help EOF } - parse_args() { while [[ $@ != "" ]]; do case $1 in @@ -72,6 +75,16 @@ parse_args() { shift KERNEL_VERSION=$1 ;; + -sc|--signing-cert) + shift + echo "signing cert $1" + SIGNING_CERT="$1" + ;; + -sk|--signing-key) + shift + echo "signing key $1" + SIGNING_KEY="$1" + ;; *) usage exit 1 @@ -147,8 +160,55 @@ generate_s2s_installer_image_bluefield() sed -i -e "s/%%IMAGE_SHA1%%/$sha1/" /sonic/$OUTPUT_ONIE_IMAGE echo -n "." tar_size="$(wc -c < "${sharch}")" - sed -i -e "s|%%PAYLOAD_IMAGE_SIZE%%|${tar_size}|" /sonic/$OUTPUT_ONIE_IMAGE + output_file="/sonic/$OUTPUT_ONIE_IMAGE" + sed -i -e "s|%%PAYLOAD_IMAGE_SIZE%%|${tar_size}|" ${output_file} cat $sharch >> /sonic/$OUTPUT_ONIE_IMAGE + echo "secure upgrade flags: SECURE_UPGRADE_MODE = $SECURE_UPGRADE_MODE, \ + SECURE_UPGRADE_DEV_SIGNING_KEY = $SIGNING_KEY, SECURE_UPGRADE_SIGNING_CERT = $SIGNING_CERT" +key_file=${SIGNING_KEY} +cert_file=${SIGNING_CERT} +if [ "$SECURE_UPGRADE_MODE" = "dev" -o "$SECURE_UPGRADE_MODE" = "prod" -o "$signing_keys_path" = "ok" ]; then + CMS_SIG="${tmp_dir}/signature.sig" + scripts_dir="/sonic/scripts" + + echo "$0 $SECURE_UPGRADE_MODE signing - creating CMS signature for ${output_file}. Output file ${CMS_SIG}" + + if [ "$SECURE_UPGRADE_MODE" = "dev" ]; then + if [[ -z "$key_file" ]] || [[ -z "$cert_file" ]]; then + echo "dev signing key and/or cert not defined. SECURE_UPGRADE_DEV_SIGNING_KEY: $key_file SECURE_UPGRADE_SIGNING_CERT: $cert_file" + clean_dir $tmp_dir 1 + fi + echo "$0 dev keyfile location: ${key_file}." + [ -f ${scripts_dir}/sign_image_dev.sh ] || { + echo "dev sign script ${scripts_dir}/sign_image_dev.sh not found" + rm -rf ${output_file} + } + (${scripts_dir}/sign_image_dev.sh ${cert_file} ${key_file} ${output_file} ${CMS_SIG}) || { + echo "CMS sign error $?" + rm -rf ${CMS_SIG} ${output_file} + } + else # "$SECURE_UPGRADE_MODE" has to be equal to "prod" + [ -f ${scripts_dir}/sign_image_${machine}.sh ] || { + echo "prod sign script ${scripts_dir}/sign_image_${machine}.sh not found" + rm -rf ${output_file} + } + (${scripts_dir}/sign_image_${machine}.sh ${output_file} ${CMS_SIG} ${SECURE_UPGRADE_MODE}) || { + echo "CMS sign error $?" + rm -rf ${CMS_SIG} ${output_file} + } + fi + + [ -f "$CMS_SIG" ] || { + echo "Error: CMS signature not created - exiting without signing" + clean_dir $tmp_dir 1 + } + # append signature to binary + cat ${CMS_SIG} >> ${output_file} + sudo rm -rf ${CMS_SIG} +elif [ "$SECURE_UPGRADE_MODE" -ne "no_sign" ]; then + echo "SECURE_UPGRADE_MODE not defined or defined as $SECURE_UPGRADE_MODE - build without signing" +fi + rm -rf $tmp_dir echo " Done." @@ -237,7 +297,7 @@ add_sonic_to_initramfs() { # Add the logic to put second stage installer into bfb initramfs mkdir -p debian - j2 ${SDIR}/install.sh.j2 -o ./debian/install.sh + j2 ${SDIR}/install.sh.j2 -o ./debian/install.sh -e SECURE_UPGRADE_MODE="$SECURE_UPGRADE_MODE" chmod 0755 ./debian/install.sh # Copy the INSTALLER payload @@ -394,6 +454,8 @@ create_bfb_image() { cp $TMFIFO_DRIVER . cp $SDHCI_OF_DWCMSHC_DRIVER . cp $WATCHDOG . + mkdir -p ./secure-boot + cp -r $CDIR/$FILESYSTEM_ROOT/boot/* ./secure-boot mkdir -p ./lib/firmware/mellanox/boot/ cp /lib/firmware/mellanox/boot/default.bfb ./lib/firmware/mellanox/boot/default.bfb @@ -441,7 +503,11 @@ create_pxe_archive(){ pushd $arxiv_wdir cp /usr/lib/grub/arm64-efi/monolithic/$GRUB_AA64 . - + if [[ "$SECURE_UPGRADE_MODE" == "dev" || "$SECURE_UPGRADE_MODE" == "prod" ]]; then + cp $CDIR/$FILESYSTEM_ROOT/boot/shimaa64.efi . + cp $CDIR/$FILESYSTEM_ROOT/boot/mmaa64.efi . + cp $CDIR/$FILESYSTEM_ROOT/boot/grubaa64.efi . + fi cp $WDIR/vmlinuz Image cp $WDIR/dump-initramfs-v0 initramfs @@ -457,20 +523,16 @@ create_pxe_archive(){ main() { echo $@ parse_args $@ - . $CDIR/onie-image-arm64.conf - # Export ENV Variables for j2cli CHROOT_DIR=$CDIR/$FILESYSTEM_ROOT if [[ ! -d "$CHROOT_DIR" ]]; then echo "[create_sonic_image] Error! Path to CHROOT not found" exit 1 fi - export GRUB_CFG=$(cat /sonic/installer/bluefield/sonic-grub.cfg) export IMAGE_VERSION=$(cat $CHROOT_DIR/etc/sonic/sonic_version.yml | grep "build_version" | sed -e "s/build_version: //g;s/'//g") - export BF2_BOOT_ARGS BF3_BOOT_ARGS BF2_GRUB_CFG BF3_GRUB_CFG ONIE_INSTALLER_PAYLOAD FILESYSTEM_DOCKERFS DOCKERFS_DIR FILESYSTEM_SQUASHFS KERNEL_VERSION - + export BF2_BOOT_ARGS BF3_BOOT_ARGS BF2_GRUB_CFG BF3_GRUB_CFG ONIE_INSTALLER_PAYLOAD FILESYSTEM_DOCKERFS DOCKERFS_DIR FILESYSTEM_SQUASHFS KERNEL_VERSION SECURE_UPGRADE_MODE SIGNING_KEY SIGNING_CERT if [[ $IMAGE_TYPE == bin ]]; then # bluefield Doesn't have ONiE Support yet and this *.bin image generated can only be used for SONiC-SONiC installation echo "Build SONiC to SONiC installer for Bluefield" diff --git a/installer/bluefield/install.sh.j2 b/installer/bluefield/install.sh.j2 index 5c6dffdd496a..1bbc09c928f7 100755 --- a/installer/bluefield/install.sh.j2 +++ b/installer/bluefield/install.sh.j2 @@ -210,9 +210,34 @@ EOF chmod a+r /mnt/machine.conf sync +{% if SECURE_UPGRADE_MODE in ['dev', 'prod'] %} +demo_volume_label="SONiC-OS" +log "creating demo_volume_label=$demo_volume_label dir under EFI partition to include all boot related modules" +mkdir -p /mnt/boot/efi/EFI/$demo_volume_label + +if [ ! -f /secure-boot/mmaa64.efi ]; then + echo "ERROR: /secure-boot/mmaa64.efi file does not exist" + exit 1 +fi -log "Installing GRUB" +if [ ! -f /secure-boot/shimaa64.efi ]; then + echo "ERROR: /secure-boot/shimaa64.efi file does not exist" + exit 1 +fi + +if [ ! -f /secure-boot/grubaa64.efi ]; then + echo "ERROR: /secure-boot/grubaa64.efi file does not exist" + exit 1 +fi +log "copying signed shim, mm, grub, grub.cfg from /secure-boot to /boot/efi/EFI/$demo_volume_label directory" +MNT_DIR="/mnt/boot/efi/EFI/$demo_volume_label" +cp /secure-boot/shimaa64.efi $MNT_DIR +cp /secure-boot/grubaa64.efi $MNT_DIR +cp /secure-boot/mmaa64.efi $MNT_DIR +{% else %} +log "Installing GRUB" +{% endif %} # Create a minimal grub.cfg that allows for: # - configure the serial console # - allows for grub-reboot to work @@ -248,9 +273,13 @@ cat <> $grub_cfg EOF # Copy the grub.cfg onto the boot-directory as specified in the grub-install -ex mkdir -p /mnt/grub +{% if SECURE_UPGRADE_MODE in ['dev', 'prod'] %} +ex cp $grub_cfg /mnt/boot/efi/EFI/$demo_volume_label/grub.cfg +{% else %} +ex mkdir -p /mnt/grub ex cp $grub_cfg /mnt/grub/grub.cfg +{% endif %} sync log "GRUB CFG Updated" @@ -303,7 +332,17 @@ else fi ex efibootmgr -c -d "$device" -p 1 -L $device_label -l "\EFI\\$device_label\grubaa64.efi" fi - +{% if SECURE_UPGRADE_MODE in ['dev', 'prod'] %} +uefi_part=1 +ex efibootmgr --create \ + --label "$demo_volume_label" \ + --disk "$device" --part $uefi_part \ + --loader "\EFI\$demo_volume_label\shimaa64.efi" || { + echo "ERROR: efibootmgr failed to create new boot variable on: $device" + exit 1 +} +echo "uefi_shim: Secure Boot components installed successfully" +{% endif %} BFCFG=`which bfcfg 2> /dev/null` if [ -n "$BFCFG" ]; then # Create PXE boot entries diff --git a/installer/sharch_body.sh b/installer/sharch_body.sh index 9683b4692dca..5451a462c644 100644 --- a/installer/sharch_body.sh +++ b/installer/sharch_body.sh @@ -13,8 +13,8 @@ echo -n "Verifying image checksum ..." payload_image_size=%%PAYLOAD_IMAGE_SIZE%% -sha1=$(sed -e '1,/^exit_marker$/d' "$0" | head -c $payload_image_size | sha1sum | awk '{ print $1 }') +sha1=$(sed -e '1,/^exit_marker$/d' "$0" | head -c $payload_image_size | sha1sum | awk '{ print $1 }') payload_sha1=%%IMAGE_SHA1%% if [ "$sha1" != "$payload_sha1" ] ; then diff --git a/onie-mk-demo.sh b/onie-mk-demo.sh index b466441ca31b..d92e2479e393 100755 --- a/onie-mk-demo.sh +++ b/onie-mk-demo.sh @@ -64,6 +64,13 @@ tmp_dir= clean_up() { rm -rf $tmp_dir + if [ -n "$2" ]; then + rm -rf "$2" + if [ -n "$3" ];then + rm -rf "$3" + fi + echo "Error: CMS signature not created - exiting without signing" + fi exit $1 }