diff --git a/meta-arm/classes/uefi_capsule.bbclass b/meta-arm/classes/uefi_capsule.bbclass index 9d98959d..c353c691 100644 --- a/meta-arm/classes/uefi_capsule.bbclass +++ b/meta-arm/classes/uefi_capsule.bbclass @@ -55,14 +55,39 @@ python() { "UEFI_FIRMWARE_BINARIES", \ "UEFI_CAPSULE_CONFIG_GENERATOR_SCRIPT", \ "CAPSULE_ALL_COMPONENTS", \ - "CAPSULE_SELECTED_COMPONENTS", \ - "PAYLOAD_CERTIFICATE_PATH", \ - "PAYLOAD_PRIVATE_KEY_PATH"]: + "CAPSULE_SELECTED_COMPONENTS"]: if not d.getVar(var): raise bb.parse.SkipRecipe(f"{var} not set") } IMAGE_CMD:uefi_capsule(){ + signing_pem_dir="${WORKDIR}/uefi-capsule-signing-pems" + rm -rf "$signing_pem_dir" + install -d -m 0700 "$signing_pem_dir" + + set -- ${CAPSULE_CERTIFICATE_PATHS} + signing_pem_paths="" + signing_pem_index=0 + for private_key_path in ${CAPSULE_PRIVATE_KEY_PATHS}; do + if [ "$#" -eq 0 ]; then + bbfatal "CAPSULE_PRIVATE_KEY_PATHS has more entries than CAPSULE_CERTIFICATE_PATHS" + fi + + certificate_path="$1" + shift + + signing_pem_path="$signing_pem_dir/$signing_pem_index.pem" + install -m 0600 "$private_key_path" "$signing_pem_path" + cat "$certificate_path" >> "$signing_pem_path" + + signing_pem_paths="$signing_pem_paths $signing_pem_path" + signing_pem_index="$(expr "$signing_pem_index" + 1)" + done + + if [ "$#" -ne 0 ]; then + bbfatal "CAPSULE_CERTIFICATE_PATHS has more entries than CAPSULE_PRIVATE_KEY_PATHS" + fi + # Generates the UEFI capsule payloads JSON ${PYTHON} ${UEFI_CAPSULE_CONFIG_GENERATOR_SCRIPT} \ --selected_components ${CAPSULE_SELECTED_COMPONENTS}\ @@ -74,16 +99,13 @@ IMAGE_CMD:uefi_capsule(){ --monotonic_counts ${CAPSULE_MONOTONIC_COUNTS} \ --payloads ${UEFI_FIRMWARE_BINARIES} \ --update_image_indexes ${CAPSULE_INDEXES} \ - --private_keys ${CAPSULE_PRIVATE_KEY_PATHS} \ + --signing_pems $signing_pem_paths \ --certificates ${CAPSULE_CERTIFICATE_PATHS} \ --output ${CAPSULE_CONFIG_FILE} # Force the GenerateCapsule script to use python3 export PYTHON_COMMAND=${PYTHON} - # Append the certificate to the private key to create a PEM bundle compatible with EDK2 tools - cat ${PAYLOAD_CERTIFICATE_PATH} >> ${PAYLOAD_PRIVATE_KEY_PATH} - # Generate the UEFI capsule image using the EDK2 GenerateCapsule tool ${STAGING_BINDIR_NATIVE}/edk2-BaseTools/BinWrappers/PosixLike/GenerateCapsule \ -e -j ${CAPSULE_CONFIG_FILE} \ diff --git a/meta-arm/scripts/generate_capsule_json_multiple.py b/meta-arm/scripts/generate_capsule_json_multiple.py index 55c4b351..6c9d8798 100644 --- a/meta-arm/scripts/generate_capsule_json_multiple.py +++ b/meta-arm/scripts/generate_capsule_json_multiple.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: Copyright 2025 Arm Limited and/or its +# SPDX-FileCopyrightText: Copyright 2025-2026 Arm Limited and/or its # affiliates # # SPDX-License-Identifier: MIT @@ -19,7 +19,7 @@ Usage: --monotonic_counts 1 1 1 \ --payloads bl2.bin initramfs.bin tfm_s.bin \ --update_image_indexes 1 4 2 \ - --private_keys key.key key.key key.key \ + --signing_pems signing.pem signing.pem signing.pem \ --certificates cert.crt cert.crt cert.crt \ --components bl2 initramfs tfm_s \ --selected_components bl2 \ @@ -50,6 +50,17 @@ def parse_arguments() -> argparse.Namespace: "--output", default="capsule_payloads.json", help="Output JSON file name" ) + parser.add_argument( + "--signing_pems", "--private_keys", + dest="signing_pems", + nargs="+", + required=True, + help=( + "List of signing PEM file paths (private key and certificate). " + "--private_keys is kept as a compatibility alias." + ), + ) + # Required arguments for each payload entry required_args = { "components": "List of components", @@ -60,7 +71,6 @@ def parse_arguments() -> argparse.Namespace: "monotonic_counts": "List of monotonic counts", "payloads": "List of payload file paths", "update_image_indexes": "List of update image indexes", - "private_keys": "List of private key file paths", "certificates": "List of certificate file paths", } @@ -105,7 +115,7 @@ def create_payloads(args: argparse.Namespace) -> List[dict]: "MonotonicCount": args.monotonic_counts[i], "Payload": args.payloads[i], "UpdateImageIndex": args.update_image_indexes[i], - "OpenSslSignerPrivateCertFile": args.private_keys[i], + "OpenSslSignerPrivateCertFile": args.signing_pems[i], "OpenSslTrustedPublicCertFile": args.certificates[i], "OpenSslOtherPublicCertFile": args.certificates[i], }