From 6fe8599216afb1c302e77c52235c4849be6042b2 Mon Sep 17 00:00:00 2001 From: ycoheNvidia <99744138+ycoheNvidia@users.noreply.github.com> Date: Mon, 30 Jan 2023 23:28:15 +0200 Subject: [PATCH] Secure upgrade (#2337) #### What I did Added support for secure upgrade #### How I did it It includes image signing during build (in sonic buildimage repo) and verification during image install (in sonic-utilities). HLD can be found in the following PR: https://github.com/sonic-net/SONiC/pull/1024 #### How to verify it Feature is used to allow image was not modified since built from vendor. During installation, image can be verified with a signature attached to it. In order for image verification - image must be signed - need to provide signing key and certificate (paths in SECURE_UPGRADE_DEV_SIGNING_KEY and SECURE_UPGRADE_DEV_SIGNING_CERT in rules/config) during build , and during image install, need to enable secure boot flag in bios, and signing_certificate should be available in bios. #### Feature dependencies In order for this feature to work smoothly, need to have secure boot feature implemented as well. The Secure boot feature will be merged in the near future. sonic-buildimage PR: https://github.com/sonic-net/sonic-buildimage/pull/11862 --- scripts/verify_image_sign.sh | 75 +++++++++++++++ scripts/verify_image_sign_common.sh | 34 +++++++ setup.py | 2 + sonic_installer/bootloader/grub.py | 11 +++ sonic_installer/main.py | 12 ++- tests/installer_bootloader_grub_test.py | 8 ++ tests/scripts/create_mock_image.sh | 40 ++++++++ .../create_sign_and_verify_test_files.sh | 91 +++++++++++++++++++ tests/scripts/verify_image_sign_test.sh | 29 ++++++ tests/sign_and_verify_test.py | 70 ++++++++++++++ tests/test_sonic_installer.py | 9 +- tests/verify_image_sign_test.sh | 29 ++++++ 12 files changed, 408 insertions(+), 2 deletions(-) create mode 100644 scripts/verify_image_sign.sh create mode 100755 scripts/verify_image_sign_common.sh create mode 100755 tests/scripts/create_mock_image.sh create mode 100755 tests/scripts/create_sign_and_verify_test_files.sh create mode 100755 tests/scripts/verify_image_sign_test.sh create mode 100644 tests/sign_and_verify_test.py create mode 100755 tests/verify_image_sign_test.sh diff --git a/scripts/verify_image_sign.sh b/scripts/verify_image_sign.sh new file mode 100644 index 0000000000..d66148d597 --- /dev/null +++ b/scripts/verify_image_sign.sh @@ -0,0 +1,75 @@ +#!/bin/sh +image_file="${1}" +cms_sig_file="sig.cms" +lines_for_lookup=50 +SECURE_UPGRADE_ENABLED=0 +DIR="$(dirname "$0")" +if [ -d "/sys/firmware/efi/efivars" ]; then + if ! [ -n "$(ls -A /sys/firmware/efi/efivars 2>/dev/null)" ]; then + mount -t efivarfs none /sys/firmware/efi/efivars 2>/dev/null + fi + SECURE_UPGRADE_ENABLED=$(bootctl status 2>/dev/null | grep -c "Secure Boot: enabled") +else + echo "efi not supported - exiting without verification" + exit 0 +fi + +. /usr/local/bin/verify_image_sign_common.sh + +if [ ${SECURE_UPGRADE_ENABLED} -eq 0 ]; then + echo "secure boot not enabled - exiting without image verification" + exit 0 +fi + +clean_up () +{ + if [ -d ${EFI_CERTS_DIR} ]; then rm -rf ${EFI_CERTS_DIR}; fi + if [ -d "${TMP_DIR}" ]; then rm -rf ${TMP_DIR}; fi + exit $1 +} + +TMP_DIR=$(mktemp -d) +DATA_FILE="${TMP_DIR}/data.bin" +CMS_SIG_FILE="${TMP_DIR}/${cms_sig_file}" +TAR_SIZE=$(head -n $lines_for_lookup $image_file | grep "payload_image_size=" | cut -d"=" -f2- ) +SHARCH_SIZE=$(sed '/^exit_marker$/q' $image_file | wc -c) +SIG_PAYLOAD_SIZE=$(($TAR_SIZE + $SHARCH_SIZE )) +# Extract cms signature from signed file +# Add extra byte for payload +sed -e '1,/^exit_marker$/d' $image_file | tail -c +$(( $TAR_SIZE + 1 )) > $CMS_SIG_FILE +# Extract image from signed file +head -c $SIG_PAYLOAD_SIZE $image_file > $DATA_FILE +# verify signature with certificate fetched with efi tools +EFI_CERTS_DIR=/tmp/efi_certs +[ -d $EFI_CERTS_DIR ] && rm -rf $EFI_CERTS_DIR +mkdir $EFI_CERTS_DIR +efi-readvar -v db -o $EFI_CERTS_DIR/db_efi >/dev/null || +{ + echo "Error: unable to read certs from efi db: $?" + clean_up 1 +} +# Convert one file to der certificates +sig-list-to-certs $EFI_CERTS_DIR/db_efi $EFI_CERTS_DIR/db >/dev/null|| +{ + echo "Error: convert sig list to certs: $?" + clean_up 1 +} +for file in $(ls $EFI_CERTS_DIR | grep "db-"); do + LOG=$(openssl x509 -in $EFI_CERTS_DIR/$file -inform der -out $EFI_CERTS_DIR/cert.pem 2>&1) + if [ $? -ne 0 ]; then + logger "cms_validation: $LOG" + fi + # Verify detached signature + LOG=$(verify_image_sign_common $image_file $DATA_FILE $CMS_SIG_FILE) + VALIDATION_RES=$? + if [ $VALIDATION_RES -eq 0 ]; then + RESULT="CMS Verified OK using efi keys" + echo "verification ok:$RESULT" + # No need to continue. + # Exit without error if any success signature verification. + clean_up 0 + fi +done +echo "Failure: CMS signature Verification Failed: $LOG" + +clean_up 1 \ No newline at end of file diff --git a/scripts/verify_image_sign_common.sh b/scripts/verify_image_sign_common.sh new file mode 100755 index 0000000000..ec6511bc6d --- /dev/null +++ b/scripts/verify_image_sign_common.sh @@ -0,0 +1,34 @@ +#!/bin/bash +verify_image_sign_common() { + image_file="${1}" + cms_sig_file="sig.cms" + TMP_DIR=$(mktemp -d) + DATA_FILE="${2}" + CMS_SIG_FILE="${3}" + + openssl version | awk '$2 ~ /(^0\.)|(^1\.(0\.|1\.0))/ { exit 1 }' + if [ $? -eq 0 ]; then + # for version 1.1.1 and later + no_check_time="-no_check_time" + else + # for version older than 1.1.1 use noattr + no_check_time="-noattr" + fi + + # making sure image verification is supported + EFI_CERTS_DIR=/tmp/efi_certs + RESULT="CMS Verification Failure" + LOG=$(openssl cms -verify $no_check_time -noout -CAfile $EFI_CERTS_DIR/cert.pem -binary -in ${CMS_SIG_FILE} -content ${DATA_FILE} -inform pem 2>&1 > /dev/null ) + VALIDATION_RES=$? + if [ $VALIDATION_RES -eq 0 ]; then + RESULT="CMS Verified OK" + if [ -d "${TMP_DIR}" ]; then rm -rf ${TMP_DIR}; fi + echo "verification ok:$RESULT" + # No need to continue. + # Exit without error if any success signature verification. + return 0 + fi + + if [ -d "${TMP_DIR}" ]; then rm -rf ${TMP_DIR}; fi + return 1 +} diff --git a/setup.py b/setup.py index 70d7473bd7..231b80c8ed 100644 --- a/setup.py +++ b/setup.py @@ -154,6 +154,8 @@ 'scripts/memory_threshold_check_handler.py', 'scripts/techsupport_cleanup.py', 'scripts/storm_control.py', + 'scripts/verify_image_sign.sh', + 'scripts/verify_image_sign_common.sh', 'scripts/check_db_integrity.py', 'scripts/sysreadyshow' ], diff --git a/sonic_installer/bootloader/grub.py b/sonic_installer/bootloader/grub.py index 7ab5c6c0bc..dcafc3f840 100644 --- a/sonic_installer/bootloader/grub.py +++ b/sonic_installer/bootloader/grub.py @@ -153,6 +153,17 @@ def verify_image_platform(self, image_path): # Check if platform is inside image's target platforms return self.platform_in_platforms_asic(platform, image_path) + def verify_image_sign(self, image_path): + click.echo('Verifying image signature') + verification_script_name = 'verify_image_sign.sh' + script_path = os.path.join('/usr', 'local', 'bin', verification_script_name) + if not os.path.exists(script_path): + click.echo("Unable to find verification script in path " + script_path) + return False + verification_result = subprocess.run([script_path, image_path], capture_output=True) + click.echo(str(verification_result.stdout) + " " + str(verification_result.stderr)) + return verification_result.returncode == 0 + @classmethod def detect(cls): return os.path.isfile(os.path.join(HOST_PATH, 'grub/grub.cfg')) diff --git a/sonic_installer/main.py b/sonic_installer/main.py index ce1c15866d..d78259317e 100644 --- a/sonic_installer/main.py +++ b/sonic_installer/main.py @@ -511,7 +511,8 @@ def sonic_installer(): @click.option('-y', '--yes', is_flag=True, callback=abort_if_false, expose_value=False, prompt='New image will be installed, continue?') @click.option('-f', '--force', '--skip-secure-check', is_flag=True, - help="Force installation of an image of a non-secure type than secure running image") + help="Force installation of an image of a non-secure type than secure running " + + " image, this flag does not affect secure upgrade image verification") @click.option('--skip-platform-check', is_flag=True, help="Force installation of an image of a type which is not of the same platform") @click.option('--skip_migration', is_flag=True, @@ -576,6 +577,14 @@ def install(url, force, skip_platform_check=False, skip_migration=False, skip_pa "Aborting...", LOG_ERR) raise click.Abort() + # Calling verification script by default - signature will be checked if enabled in bios + echo_and_log("Verifing image {} signature...".format(binary_image_version)) + if not bootloader.verify_image_sign(image_path): + echo_and_log('Error: Failed verify image signature', LOG_ERR) + raise click.Abort() + else: + echo_and_log('Verification successful') + echo_and_log("Installing image {} and setting it as default...".format(binary_image_version)) with SWAPAllocator(not skip_setup_swap, swap_mem_size, total_mem_threshold, available_mem_threshold): bootloader.install_image(image_path) @@ -958,5 +967,6 @@ def verify_next_image(): sys.exit(1) click.echo('Image successfully verified') + if __name__ == '__main__': sonic_installer() diff --git a/tests/installer_bootloader_grub_test.py b/tests/installer_bootloader_grub_test.py index ff35e13b37..10c9dc5ba7 100644 --- a/tests/installer_bootloader_grub_test.py +++ b/tests/installer_bootloader_grub_test.py @@ -53,3 +53,11 @@ def test_set_fips_grub(): # Cleanup the _tmp_host folder shutil.rmtree(tmp_host_path) + +def test_verify_image(): + + bootloader = grub.GrubBootloader() + image = f'{grub.IMAGE_PREFIX}expeliarmus-{grub.IMAGE_PREFIX}abcde' + + # command should fail + assert not bootloader.verify_image_sign(image) diff --git a/tests/scripts/create_mock_image.sh b/tests/scripts/create_mock_image.sh new file mode 100755 index 0000000000..f23032af0d --- /dev/null +++ b/tests/scripts/create_mock_image.sh @@ -0,0 +1,40 @@ +repo_dir=$1 +input_image=$2 +output_file=$3 +cert_file=$4 +key_file=$5 +tmp_dir= +clean_up() +{ + sudo rm -rf $tmp_dir + sudo rm -rf $output_file + exit $1 +} + +DIR="$(dirname "$0")" + +tmp_dir=$(mktemp -d) +sha1=$(cat $input_image | sha1sum | awk '{print $1}') +echo -n "." +cp $repo_dir/installer/sharch_body.sh $output_file || { + echo "Error: Problems copying sharch_body.sh" + clean_up 1 +} +# Replace variables in the sharch template +sed -i -e "s/%%IMAGE_SHA1%%/$sha1/" $output_file +echo -n "." +tar_size="$(wc -c < "${input_image}")" +cat $input_image >> $output_file +sed -i -e "s|%%PAYLOAD_IMAGE_SIZE%%|${tar_size}|" ${output_file} +CMS_SIG="${tmp_dir}/signature.sig" + +echo "$0 CMS signing ${input_image} with ${key_file}. Output file ${output_file}" +. $repo_dir/scripts/sign_image_dev.sh +sign_image_dev ${cert_file} ${key_file} $output_file ${CMS_SIG} || clean_up 1 + +cat ${CMS_SIG} >> ${output_file} +echo "Signature done." +# append signature to binary +sudo rm -rf ${CMS_SIG} +sudo rm -rf $tmp_dir +exit 0 diff --git a/tests/scripts/create_sign_and_verify_test_files.sh b/tests/scripts/create_sign_and_verify_test_files.sh new file mode 100755 index 0000000000..0040c04a7a --- /dev/null +++ b/tests/scripts/create_sign_and_verify_test_files.sh @@ -0,0 +1,91 @@ +repo_dir=$1 +out_dir=$2 +mock_image="mock_img.bin" +output_file=$out_dir/output_file.bin +cert_file=$3 +other_cert_file=$4 +tmp_dir= +clean_up() +{ + sudo rm -rf $tmp_dir + sudo rm -rf $mock_image + exit $1 +} +DIR="$(dirname "$0")" +[ -d $out_dir ] || rm -rf $out_dir +mkdir $out_dir +tmp_dir=$(mktemp -d) +#generate self signed keys and certificate +key_file=$tmp_dir/private-key.pem +pub_key_file=$tmp_dir/public-key.pem +openssl ecparam -name secp256r1 -genkey -noout -out $key_file +openssl ec -in $key_file -pubout -out $pub_key_file +openssl req -new -x509 -key $key_file -out $cert_file -days 360 -subj "/C=US/ST=Test/L=Test/O=Test/CN=Test" +alt_key_file=$tmp_dir/alt-private-key.pem +alt_pub_key_file=$tmp_dir/alt-public-key.pem +openssl ecparam -name secp256r1 -genkey -noout -out $alt_key_file +openssl ec -in $alt_key_file -pubout -out $alt_pub_key_file +openssl req -new -x509 -key $alt_key_file -out $other_cert_file -days 360 -subj "/C=US/ST=Test/L=Test/O=Test/CN=Test" + +echo "this is a mock image\nThis is another line !2#4%6\n" > $mock_image +echo "Created a mock image with following text:" +cat $mock_image +# create signed mock image + +sh $DIR/create_mock_image.sh $repo_dir $mock_image $output_file $cert_file $key_file || { + echo "Error: unable to create mock image" + clean_up 1 +} + +[ -f "$output_file" ] || { + echo "signed mock image not created - exiting without testing" + clean_up 1 +} + +test_image_1=$out_dir/test_image_1.bin +cp -v $output_file $test_image_1 || { + echo "Error: Problems copying image" + clean_up 1 +} + +# test_image_1 = modified image size to something else - should fail on signature verification +image_size=$(sed -n 's/^payload_image_size=\(.*\)/\1/p' < $test_image_1) +sed -i "/payload_image_size=/c\payload_image_size=$(($image_size - 5))" $test_image_1 + +test_image_2=$out_dir/test_image_2.bin +cp -v $output_file $test_image_2 || { + echo "Error: Problems copying image" + clean_up 1 +} + +# test_image_2 = modified image sha1 to other sha1 value - should fail on signature verification +im_sha=$(sed -n 's/^payload_sha1=\(.*\)/\1/p' < $test_image_2) +sed -i "/payload_sha1=/c\payload_sha1=2f1bbd5a0d411253103e688e4e66c00c94bedd40" $test_image_2 + +tmp_image=$tmp_dir/"tmp_image.bin" +echo "this is a different image now" >> $mock_image +sh $DIR/create_mock_image.sh $repo_dir $mock_image $tmp_image $cert_file $key_file || { + echo "Error: unable to create mock image" + clean_up 1 +} +# test_image_3 = original mock image with wrong signature +# Extract cms signature from signed file +test_image_3=$out_dir/"test_image_3.bin" +tmp_sig="${tmp_dir}/tmp_sig.sig" +TMP_TAR_SIZE=$(head -n 50 $tmp_image | grep "payload_image_size=" | cut -d"=" -f2- ) +sed -e '1,/^exit_marker$/d' $tmp_image | tail -c +$(( $TMP_TAR_SIZE + 1 )) > $tmp_sig + +TAR_SIZE=$(head -n 50 $output_file | grep "payload_image_size=" | cut -d"=" -f2- ) +SHARCH_SIZE=$(sed '/^exit_marker$/q' $output_file | wc -c) +SIG_PAYLOAD_SIZE=$(($TAR_SIZE + $SHARCH_SIZE )) +head -c $SIG_PAYLOAD_SIZE $output_file > $test_image_3 +sudo rm -rf $tmp_image + +cat ${tmp_sig} >> ${test_image_3} + +# test_image_4 = modified image with original mock image signature +test_image_4=$out_dir/"test_image_4.bin" +head -c $SIG_PAYLOAD_SIZE $output_file > $test_image_4 +echo "this is additional line" >> $test_image_4 +cat ${tmp_sig} >> ${test_image_4} +clean_up 0 \ No newline at end of file diff --git a/tests/scripts/verify_image_sign_test.sh b/tests/scripts/verify_image_sign_test.sh new file mode 100755 index 0000000000..f4abd2584f --- /dev/null +++ b/tests/scripts/verify_image_sign_test.sh @@ -0,0 +1,29 @@ +#!/bin/bash +image_file="${1}" +cert_path="${2}" +cms_sig_file="sig.cms" +TMP_DIR=$(mktemp -d) +DATA_FILE="${TMP_DIR}/data.bin" +CMS_SIG_FILE="${TMP_DIR}/${cms_sig_file}" +lines_for_lookup=50 + +TAR_SIZE=$(head -n $lines_for_lookup $image_file | grep "payload_image_size=" | cut -d"=" -f2- ) +SHARCH_SIZE=$(sed '/^exit_marker$/q' $image_file | wc -c) +SIG_PAYLOAD_SIZE=$(($TAR_SIZE + $SHARCH_SIZE )) +# Extract cms signature from signed file - exit marker marks last sharch prefix + number of image lines + 1 for next linel +# Add extra byte for payload - extracting image signature from line after data file +sed -e '1,/^exit_marker$/d' $image_file | tail -c +$(( $TAR_SIZE + 1 )) > $CMS_SIG_FILE +# Extract image from signed file +head -c $SIG_PAYLOAD_SIZE $image_file > $DATA_FILE +EFI_CERTS_DIR=/tmp/efi_certs +[ -d $EFI_CERTS_DIR ] && rm -rf $EFI_CERTS_DIR +mkdir $EFI_CERTS_DIR +cp $cert_path $EFI_CERTS_DIR/cert.pem + +DIR="$(dirname "$0")" +. $DIR/verify_image_sign_common.sh +verify_image_sign_common $image_file $DATA_FILE $CMS_SIG_FILE +VERIFICATION_RES=$? +if [ -d "${TMP_DIR}" ]; then rm -rf ${TMP_DIR}; fi +[ -d $EFI_CERTS_DIR ] && rm -rf $EFI_CERTS_DIR +exit $VERIFICATION_RES \ No newline at end of file diff --git a/tests/sign_and_verify_test.py b/tests/sign_and_verify_test.py new file mode 100644 index 0000000000..77d58a4ac9 --- /dev/null +++ b/tests/sign_and_verify_test.py @@ -0,0 +1,70 @@ + +import subprocess +import os +import sys +import shutil + + +class TestSignVerify(object): + def _run_verification_script_and_check(self, image, cert_file_path, success_str, expected_value=0): + res = subprocess.run(['sh', self._verification_script, image, cert_file_path]) + assert res.returncode == expected_value + print(success_str) + + def test_basic_signature_verification(self): + self._run_verification_script_and_check(os.path.join(self._out_dir_path, 'output_file.bin'), + self._cert_file_path, "test case 1 - basic verify signature - SUCCESS") + + # change image size to something else - should fail on signature verification + def test_modified_image_size(self): + self._run_verification_script_and_check(os.path.join(self._out_dir_path, 'test_image_1.bin'), + self._cert_file_path, "test case 2 - modified image size - SUCCESS", 1) + + def test_modified_image_sha1(self): + self._run_verification_script_and_check(os.path.join(self._out_dir_path, 'test_image_2.bin'), + self._cert_file_path, "test case 3 - modified image sha1 - SUCCESS", 1) + + def test_modified_image_data(self): + self._run_verification_script_and_check(os.path.join(self._out_dir_path, 'test_image_3.bin'), + self._cert_file_path, "test case 4 - modified image data - SUCCESS", 1) + + def test_modified_image_signature(self): + self._run_verification_script_and_check(os.path.join(self._out_dir_path, 'test_image_4.bin'), + self._cert_file_path, "test case 5 - modified image data - SUCCESS", 1) + + def test_verify_image_with_wrong_certificate(self): + self._run_verification_script_and_check(os.path.join(self._out_dir_path, 'output_file.bin'), + self._alt_cert_path, "test case 6 - verify with wrong signature - SUCCESS", 1) + + def __init__(self): + self._test_path = os.path.dirname(os.path.abspath(__file__)) + self._modules_path = os.path.dirname(self._test_path) + self._repo_path = os.path.join(self._modules_path, '../..') + self._test_scripts_path = os.path.join(self._test_path, "scripts") + sys.path.insert(0, self._test_path) + sys.path.insert(0, self._modules_path) + sys.path.insert(0, self._test_scripts_path) + script_path = os.path.join(self._test_scripts_path, 'create_sign_and_verify_test_files.sh') + self._verification_script = os.path.join(self._test_scripts_path, 'verify_image_sign_test.sh') + self._out_dir_path = '/tmp/sign_verify_test' + self._cert_file_path = os.path.join(self._out_dir_path, 'self_certificate.pem') + self._alt_cert_path = os.path.join(self._out_dir_path, 'alt_self_certificate.pem') + create_files_result = subprocess.run(['sh', script_path, self._repo_path, self._out_dir_path, + self._cert_file_path, + self._alt_cert_path]) + print(create_files_result) + assert create_files_result.returncode == 0 + + def __del__(self): + shutil.rmtree(self._out_dir_path) + + +if __name__ == '__main__': + t = TestSignVerify() + t.test_basic_signature_verification() + subprocess.run(['ls', '/tmp/sign_verify_test']) + t.test_modified_image_data() + t.test_modified_image_sha1() + t.test_modified_image_signature() + t.test_modified_image_size() + t.test_verify_image_with_wrong_certificate() diff --git a/tests/test_sonic_installer.py b/tests/test_sonic_installer.py index c445dfb6e3..0f8fcdb8ca 100644 --- a/tests/test_sonic_installer.py +++ b/tests/test_sonic_installer.py @@ -3,6 +3,7 @@ from sonic_installer.main import sonic_installer from click.testing import CliRunner from unittest.mock import patch, Mock, call +from sonic_installer.bootloader import GrubBootloader @patch("sonic_installer.main.SWAPAllocator") @patch("sonic_installer.main.get_bootloader") @@ -31,7 +32,7 @@ def test_install(run_command, run_command_or_raise, get_bootloader, swap, fs): mock_bootloader.get_binary_image_version = Mock(return_value=new_image_version) mock_bootloader.get_installed_images = Mock(return_value=[current_image_version]) mock_bootloader.get_image_path = Mock(return_value=new_image_folder) - + mock_bootloader.verify_image_sign = Mock(return_value=True) @contextmanager def rootfs_path_mock(path): yield mounted_image_folder @@ -45,7 +46,13 @@ def rootfs_path_mock(path): print(result.output) assert result.exit_code == 0 + mock_bootloader_verify_image_sign_fail = mock_bootloader + mock_bootloader_verify_image_sign_fail.verify_image_sign = Mock(return_value=False) + get_bootloader.return_value=mock_bootloader_verify_image_sign_fail + result = runner.invoke(sonic_installer.commands["install"], [sonic_image_filename, "-y"]) + print(result.output) + assert result.exit_code != 0 # Assert bootloader install API was called mock_bootloader.install_image.assert_called_with(f"./{sonic_image_filename}") # Assert all below commands were called, so we ensure that diff --git a/tests/verify_image_sign_test.sh b/tests/verify_image_sign_test.sh new file mode 100755 index 0000000000..f4abd2584f --- /dev/null +++ b/tests/verify_image_sign_test.sh @@ -0,0 +1,29 @@ +#!/bin/bash +image_file="${1}" +cert_path="${2}" +cms_sig_file="sig.cms" +TMP_DIR=$(mktemp -d) +DATA_FILE="${TMP_DIR}/data.bin" +CMS_SIG_FILE="${TMP_DIR}/${cms_sig_file}" +lines_for_lookup=50 + +TAR_SIZE=$(head -n $lines_for_lookup $image_file | grep "payload_image_size=" | cut -d"=" -f2- ) +SHARCH_SIZE=$(sed '/^exit_marker$/q' $image_file | wc -c) +SIG_PAYLOAD_SIZE=$(($TAR_SIZE + $SHARCH_SIZE )) +# Extract cms signature from signed file - exit marker marks last sharch prefix + number of image lines + 1 for next linel +# Add extra byte for payload - extracting image signature from line after data file +sed -e '1,/^exit_marker$/d' $image_file | tail -c +$(( $TAR_SIZE + 1 )) > $CMS_SIG_FILE +# Extract image from signed file +head -c $SIG_PAYLOAD_SIZE $image_file > $DATA_FILE +EFI_CERTS_DIR=/tmp/efi_certs +[ -d $EFI_CERTS_DIR ] && rm -rf $EFI_CERTS_DIR +mkdir $EFI_CERTS_DIR +cp $cert_path $EFI_CERTS_DIR/cert.pem + +DIR="$(dirname "$0")" +. $DIR/verify_image_sign_common.sh +verify_image_sign_common $image_file $DATA_FILE $CMS_SIG_FILE +VERIFICATION_RES=$? +if [ -d "${TMP_DIR}" ]; then rm -rf ${TMP_DIR}; fi +[ -d $EFI_CERTS_DIR ] && rm -rf $EFI_CERTS_DIR +exit $VERIFICATION_RES \ No newline at end of file