Add tool for generating bios image tarball
Adding a gen-bios-tar tool for generating a bios image tarball from given bios
image file as input along with version, machine name parameter. It creates a
MANIFEST for image verification and recreation. It also packages the image and
MANIFEST together in a tarball.
Currently machine name is optional but it will become mandatory in future.
This tarball is required for bios upgrade through image updater
Tested: Verified this with actual image.
Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
Change-Id: I6e9ec57d2b38c9e144bd725026c64106d16c6a6f
diff --git a/gen-bios-tar b/gen-bios-tar
new file mode 100755
index 0000000..d0ddd8e
--- /dev/null
+++ b/gen-bios-tar
@@ -0,0 +1,170 @@
+#!/bin/bash
+set -eo pipefail
+
+help=$'Generate Tarball with Bios image and MANIFEST Script
+
+Generates a Bios image tarball from given file as input.
+Creates a MANIFEST for image verification and recreation
+Packages the image and MANIFEST together in a tarball
+
+usage: gen-bios-tar [OPTION] <Bios FILE>...
+
+Options:
+ -o, --out <file> Specify destination file. Defaults to
+ `pwd`/obmc-bios.tar.gz if unspecified.
+ -s, --sign <path> Sign the image. The optional path argument specifies
+ the private key file. Defaults to the bash variable
+ PRIVATE_KEY_PATH if available, or else uses the
+ open-source private key in this script.
+ -m, --machine <name> Optionally specify the target machine name of this
+ image.
+ -v, --version <name> Specify the version of bios image file
+ -h, --help Display this help text and exit.
+'
+
+#################################################################
+# It's the OpenBMC "public" private key (currently under
+# meta-phosphor/recipes-phosphor/flash/files/OpenBMC.priv):
+# https://gerrit.openbmc-project.xyz/c/openbmc/openbmc/+/8949/15/
+# meta-phosphor/common/recipes-phosphor/flash/files/OpenBMC.priv
+#
+#################################################################
+private_key=$'-----BEGIN PRIVATE KEY-----
+MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAPvSDLu6slkP1gri
+PaeQXL9ysD69J/HjbBCIQ0RPfeWBb75US1tRTjPP0Ub8CtH8ExVf8iF1ulsZA78B
+zIjBYZVp9pyD6LbpZ/hjV7rIH6dTNhoVpdA+F8LzmQ7cyhHG8l2JMvdunwF2uX5k
+D4WDcZt/ITKZNQNavPtmIyD5HprdAgMBAAECgYEAuQkTSi5ZNpAoWz76xtGRFSwU
+zUT4wQi3Mz6tDtjKTYXasiQGa0dHC1M9F8fDu6BZ9W7W4Dc9hArRcdzEighuxoI/
+nZI/0uL89iUEywnDEIHuS6D5JlZaj86/nx9YvQnO8F/seM+MX0EAWVrd5wC7aAF1
+h6Fu7ykZB4ggUjQAWwECQQD+AUiDOEO+8btLJ135dQfSGc5VFcZiequnKWVm6uXt
+rX771hEYjYMjLqWGFg9G4gE3GuABM5chMINuQQUivy8tAkEA/cxfy19XkjtqcMgE
+x/UDt6Nr+Ky/tk+4Y65WxPRDas0uxFOPk/vEjgVmz1k/TAy9G4giisluTvtmltr5
+DCLocQJBAJnRHx9PiD7uVhRJz6/L/iNuOzPtTsi+Loq5F83+O6T15qsM1CeBMsOw
+cM5FN5UeMcwz+yjfHAsePMkcmMaU7jUCQHlg9+N8upXuIo7Dqj2zOU7nMmkgvSNE
+5yuNImRZabC3ZolwaTdd7nf5r1y1Eyec5Ag5yENV6JKPe1Xkbb1XKJECQDngA0h4
+6ATvfP1Vrx4CbP11eKXbCsZ9OGPHSgyvVjn68oY5ZP3uPsIattoN7dE2BRfuJm7m
+F0nIdUAhR0yTfKM=
+-----END PRIVATE KEY-----
+'
+
+do_sign=false
+private_key_path="${PRIVATE_KEY_PATH}"
+outfile=""
+machine=""
+version=""
+
+while [[ $# -gt 0 ]]; do
+ key="$1"
+ case $key in
+ -o|--out)
+ outfile="$2"
+ shift 2
+ ;;
+ -s|--sign)
+ do_sign=true
+ if [[ ! -z "${2}" && "${2}" != -* ]]; then
+ private_key_path="$2"
+ shift 2
+ else
+ shift 1
+ fi
+ ;;
+ -m|--machine)
+ machine="$2"
+ shift 2
+ ;;
+ -v|--version)
+ version="$2"
+ shift 2
+ ;;
+ -h|--help)
+ echo "$help"
+ exit
+ ;;
+ -*)
+ echo "Unrecognised option $1"
+ echo "$help"
+ exit
+ ;;
+ *)
+ file="$1"
+ shift 1
+ ;;
+ esac
+done
+
+if [ ! -f "${file}" ]; then
+ echo "${file} not found, Please enter a valid Bios image file"
+ echo "$help"
+ exit 1
+fi
+
+if [[ -z $version ]]; then
+ echo "Please provide version of image with -v option"
+ exit 1
+fi
+
+if [[ -z $outfile ]]; then
+ outfile=`pwd`/obmc-bios.tar.gz
+else
+ if [[ $outfile != /* ]]; then
+ outfile=`pwd`/$outfile
+ fi
+fi
+
+scratch_dir=`mktemp -d`
+# Remove the temp directory on exit.
+# The files in the temp directory may contain read-only files, so add
+# --interactive=never to skip the prompt.
+trap "{ rm -r --interactive=never ${scratch_dir}; }" EXIT
+
+if [[ "${do_sign}" == true ]]; then
+ if [[ -z "${private_key_path}" ]]; then
+ private_key_path=${scratch_dir}/OpenBMC.priv
+ echo "${private_key}" > "${private_key_path}"
+ echo "Image is NOT secure!! Signing with the open private key!"
+ else
+ if [[ ! -f "${private_key_path}" ]]; then
+ echo "Couldn't find private key ${private_key_path}."
+ exit 1
+ fi
+
+ echo "Signing with ${private_key_path}."
+ fi
+
+ public_key_file=publickey
+ public_key_path=${scratch_dir}/$public_key_file
+ openssl pkey -in "${private_key_path}" -pubout -out ${public_key_path}
+fi
+
+manifest_location="MANIFEST"
+files_to_sign="$manifest_location $public_key_file"
+
+# Go to scratch_dir
+cp ${file} ${scratch_dir}
+cd "${scratch_dir}"
+files_to_sign+=" $(basename ${file})"
+
+echo "Creating MANIFEST for the image"
+echo -e "purpose=xyz.openbmc_project.Software.Version.VersionPurpose.Host\n\
+version=$version" > $manifest_location
+
+if [[ ! -z "${machine}" ]]; then
+ echo -e "MachineName=${machine}" >> $manifest_location
+fi
+
+if [[ "${do_sign}" == true ]]; then
+ private_key_name=$(basename "${private_key_path}")
+ key_type="${private_key_name%.*}"
+ echo KeyType="${key_type}" >> $manifest_location
+ echo HashType="RSA-SHA256" >> $manifest_location
+
+ for file in $files_to_sign; do
+ openssl dgst -sha256 -sign ${private_key_path} -out "${file}.sig" $file
+ done
+
+ additional_files="*.sig"
+fi
+
+tar -czvf $outfile $files_to_sign $additional_files
+echo "Bios image tarball is at $outfile"