sign_official_cos_build: Support signature-based IMA Previously, the script only supported hash-based IMA. This commit replaces the "ima" option with "ima_hash" and "ima_sign" options. To maintain backwards compatibility, "ima" is an aliase for "ima_hash". The "ima_sign" option requires an ima_key.pem in the key dir. BUG=b/465211305 TEST=presubmit RELEASE_NOTE=None Change-Id: I61440922cd1689534fc01c46145e2d080a64c1db Reviewed-on: https://cos-review.googlesource.com/c/third_party/platform/vboot_reference/+/153404 Reviewed-by: Robert Kolchmeyer <rkolchmeyer@google.com> Tested-by: Cusky Presubmit Bot <presubmit@cos-infra-prod.iam.gserviceaccount.com>
diff --git a/scripts/image_signing/sign_official_cos_build.sh b/scripts/image_signing/sign_official_cos_build.sh index 3b22d4e..c98297d 100755 --- a/scripts/image_signing/sign_official_cos_build.sh +++ b/scripts/image_signing/sign_official_cos_build.sh
@@ -32,7 +32,8 @@ key_origin: "local" for local keys, or "kms" for Cloud KMS keys. output_image: File name of the signed output image service_account: Name of GCP service account to use when signing with Cloud KMS -ima: Set to "ima" to sign the root file system for IMA +ima: Set to "ima_hash" for hash-based IMA, or "ima_sign" for signature-based IMA. + ima_sign requires an IMA private key at /path/to/keys/dir/ima_key.pem. version_file: File name of where to read the kernel and firmware versions. If you are signing an image, you must specify an [output_image] and @@ -83,6 +84,26 @@ IMA=$7 VERSION_FILE=$8 +case "${IMA}" in + ima_sign) + [[ -f "${KEY_DIR}/ima_key.pem" ]] || die "ima_sign requires an IMA signing key at ${KEY_DIR}/ima_key.pem" + ;; + + ima_hash | ima_disabled | "") + # Valid options; do nothing + : + ;; + + ima) + warn "The 'ima' option is deprecated, use 'ima_hash' instead." + IMA="ima_hash" + ;; + + *) + die "Invalid IMA option: '${IMA}'. Allowed values: ima_hash, ima_sign, ima_disabled, or empty string." + ;; +esac + FIRMWARE_VERSION=1 KERNEL_VERSION=1 @@ -92,7 +113,7 @@ if [[ "${KEY_ORIGIN}" == "kms" ]]; then prereqs+=(kms_signer) fi -if [[ "${IMA}" == "ima" ]]; then +if [[ "${IMA}" == "ima_hash" || "${IMA}" == "ima_sign" ]]; then prereqs+=(evmctl) fi for prereq in ${prereqs[@]}; do @@ -534,10 +555,11 @@ } # Set security.ima xattr on all files in given file system. -# Currently sets hashes instead of signatures. -# Args: LOOPDEV +# Supports both hash-based IMA (ima_hash) and signature-based IMA (ima_sign). +# Args: LOOPDEV IMA_MODE sign_ima() { local loopdev="$1" + local ima_mode="$2" local rootfs_dir="$(make_temp_dir)" mount_loop_image_partition "${loopdev}" 3 "${rootfs_dir}" # `evmctl sign -r` does more than try to set the security.ima xattr, and spams @@ -548,7 +570,11 @@ sudo find "${rootfs_dir}" -type f | while read -r f; do if ! getfattr -n security.ima "$f" > /dev/null 2>&1 ; then echo "Signing $f" - sudo evmctl ima_hash $f + if [[ "${ima_mode}" == "ima_sign" ]]; then + sudo evmctl ima_sign --hashalgo sha256 --key "${KEY_DIR}/ima_key.pem" "$f" + else + sudo evmctl ima_hash --hashalgo sha256 "$f" + fi echo "Done signing $f" else echo "security.ima xattr already present for $f" @@ -791,8 +817,8 @@ sign_uefi_binaries "${loopdev}" "${service_account}" - if [[ "${ima}" == "ima" ]]; then - sign_ima "${loopdev}" + if [[ "${ima}" == "ima_hash" || "${ima}" == "ima_sign" ]]; then + sign_ima "${loopdev}" "${ima}" fi # We do NOT strip /boot for factory installer, since some devices need it to