diff --git a/Makefile.work b/Makefile.work index 3f64531ab11c..f7111185ba3c 100644 --- a/Makefile.work +++ b/Makefile.work @@ -400,6 +400,9 @@ SONIC_BUILD_INSTRUCTION := make \ SONIC_ENABLE_IMAGE_SIGNATURE=$(ENABLE_IMAGE_SIGNATURE) \ SONIC_ENABLE_SECUREBOOT_SIGNATURE=$(SONIC_ENABLE_SECUREBOOT_SIGNATURE) \ SONIC_DEFAULT_CONTAINER_REGISTRY=$(DEFAULT_CONTAINER_REGISTRY) \ + 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) \ ENABLE_HOST_SERVICE_ON_START=$(ENABLE_HOST_SERVICE_ON_START) \ SLAVE_DIR=$(SLAVE_DIR) \ ENABLE_AUTO_TECH_SUPPORT=$(ENABLE_AUTO_TECH_SUPPORT) \ diff --git a/build_image.sh b/build_image.sh index ddf134e845ce..6559b89eda6b 100755 --- a/build_image.sh +++ b/build_image.sh @@ -86,7 +86,7 @@ generate_onie_installer_image() ## Note: Don't leave blank between lines. It is single line command. ./onie-mk-demo.sh $CONFIGURED_ARCH $TARGET_MACHINE $TARGET_PLATFORM-$TARGET_MACHINE-$ONIEIMAGE_VERSION \ installer platform/$TARGET_MACHINE/platform.conf $output_file OS $IMAGE_VERSION $ONIE_IMAGE_PART_SIZE \ - $ONIE_INSTALLER_PAYLOAD + $ONIE_INSTALLER_PAYLOAD $SECURE_UPGRADE_DEV_SIGNING_CERT $SECURE_UPGRADE_DEV_SIGNING_KEY } # Generate asic-specific device list diff --git a/files/build_templates/sonic_debian_extension.j2 b/files/build_templates/sonic_debian_extension.j2 index 4b7a77b3151c..bd8a4d3a9152 100644 --- a/files/build_templates/sonic_debian_extension.j2 +++ b/files/build_templates/sonic_debian_extension.j2 @@ -78,6 +78,9 @@ 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 + # 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/sharch_body.sh b/installer/sharch_body.sh index e6289371cd58..d2d46c8b09cd 100644 --- a/installer/sharch_body.sh +++ b/installer/sharch_body.sh @@ -11,7 +11,9 @@ ## echo -n "Verifying image checksum ..." -sha1=$(sed -e '1,/^exit_marker$/d' "$0" | sha1sum | awk '{ print $1 }') +payload_image_size=%%PAYLOAD_IMAGE_SIZE%% + +sha1=$(sed -e '1,/^exit_marker$/d' "$0" | head -c $payload_image_size | sha1sum | awk '{ print $1 }') payload_sha1=%%IMAGE_SHA1%% @@ -45,7 +47,9 @@ if [ "$(id -u)" = "0" ] ; then fi cd $tmp_dir echo -n "Preparing image archive ..." -sed -e '1,/^exit_marker$/d' $archive_path | tar xf - || exit 1 + +sed -e '1,/^exit_marker$/d' $archive_path | head -c $payload_image_size | tar xf - || clean_up 1 + echo " OK." cd $cur_wd if [ -n "$extract" ] ; then diff --git a/onie-mk-demo.sh b/onie-mk-demo.sh index 0905673d42cb..5b91ccc817f8 100755 --- a/onie-mk-demo.sh +++ b/onie-mk-demo.sh @@ -14,6 +14,8 @@ output_file=$6 demo_type=$7 image_version=$8 onie_image_part_size=$9 +cert_file=${11} +key_file=${12} shift 9 @@ -130,7 +132,46 @@ cp $installer_dir/sharch_body.sh $output_file || { # Replace variables in the sharch template sed -i -e "s/%%IMAGE_SHA1%%/$sha1/" $output_file echo -n "." +tar_size="$(wc -c < "${sharch}")" cat $sharch >> $output_file +sed -i -e "s|%%PAYLOAD_IMAGE_SIZE%%|${tar_size}|" ${output_file} +echo "secure upgrade flags: 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" + +if [ "$SECURE_UPGRADE_MODE" = "dev" -o "$SECURE_UPGRADE_MODE" = "prod" ]; then + CMS_SIG="${tmp_dir}/signature.sig" + + echo "$0 Creating CMS signature for ${output_file} with ${key_file}. Output file ${CMS_SIG}" + DIR="$(dirname "$0")" + + scripts_dir="${DIR}/scripts" + if [ "$SECURE_UPGRADE_MODE" = "dev" ]; then + . ${scripts_dir}/sign_image_dev.sh + sign_image_dev ${cert_file} ${key_file} ${output_file} ${CMS_SIG} || { + echo "CMS sign error $?" + sudo rm -rf ${CMS_SIG} + clean_up 1 + } + else # "$SECURE_UPGRADE_MODE" has to be equal to "prod" + . ${scripts_dir}/sign_image_${platform}.sh + sign_image_prod ${output_file} ${CMS_SIG} || { + echo "CMS sign error $?" + sudo rm -rf ${CMS_SIG} + clean_up 1 + } + fi + + [ -f "$CMS_SIG" ] || { + echo "Error: CMS signature not created - exiting without signing" + clean_up 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." diff --git a/rules/config b/rules/config index 380b28bc7cd5..a407c0921df1 100644 --- a/rules/config +++ b/rules/config @@ -208,6 +208,14 @@ SONIC_ENABLE_IMAGE_SIGNATURE ?= n # The absolute path should be provided. SONIC_ENABLE_SECUREBOOT_SIGNATURE ?= n +# folloing flags are used for image secure upgrade verification: +# 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 = +#SECURE_UPGRADE_DEV_SIGNING_CERT = +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/sign_image_dev.sh b/scripts/sign_image_dev.sh new file mode 100755 index 000000000000..1dbc7fa1bbde --- /dev/null +++ b/scripts/sign_image_dev.sh @@ -0,0 +1,14 @@ +sign_image_dev() +{ + cert_file=$1 + key_file=$2 + image_to_sign=$3 + cms_sig_out=$4 + openssl cms -sign -nosmimecap -signer ${cert_file} -inkey ${key_file} -binary -in $image_to_sign -outform pem -out ${cms_sig_out} || { + echo "$?: CMS sign error" + sudo rm -rf ${cms_sig_out} + exit 1 + } + echo "CMS sign OK" + return 0 +} \ No newline at end of file diff --git a/slave.mk b/slave.mk index e1f4a0ef80d9..0cd26d11bdfc 100644 --- a/slave.mk +++ b/slave.mk @@ -348,6 +348,9 @@ $(info "USE_NATIVE_DOCKERD_FOR_BUILD" : "$(SONIC_CONFIG_USE_NATIVE_DOCKERD_FO $(info "SONIC_USE_DOCKER_BUILDKIT" : "$(SONIC_USE_DOCKER_BUILDKIT)") $(info "USERNAME" : "$(USERNAME)") $(info "PASSWORD" : "$(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)") @@ -1174,6 +1177,9 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \ export enable_organization_extensions="$(ENABLE_ORGANIZATION_EXTENSIONS)" export enable_dhcp_graph_service="$(ENABLE_DHCP_GRAPH_SERVICE)" export enable_ztp="$(ENABLE_ZTP)" + 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)" @@ -1373,6 +1379,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)" \