Message ID | 20210715170030.97758-3-ilias.apalodimas@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | [1/3] efi_capsule: Move signature from DTB to .rodata | expand |
On 7/15/21 7:00 PM, Ilias Apalodimas wrote: > Since we removed embeddingg the capsule key into a .dtb and fixed > authenticated capsule updates for all boards, move the relevant > documentation in the efi file and update it accordingly > > Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> > --- > doc/board/emulation/qemu_capsule_update.rst | 203 -------------------- > doc/develop/uefi/uefi.rst | 125 ++++++++++++ > 2 files changed, 125 insertions(+), 203 deletions(-) > delete mode 100644 doc/board/emulation/qemu_capsule_update.rst > > diff --git a/doc/board/emulation/qemu_capsule_update.rst b/doc/board/emulation/qemu_capsule_update.rst > deleted file mode 100644 > index 0a2286d039d9..000000000000 > --- a/doc/board/emulation/qemu_capsule_update.rst > +++ /dev/null > @@ -1,203 +0,0 @@ > -.. SPDX-License-Identifier: GPL-2.0+ > -.. Copyright (C) 2020, Linaro Limited > - > -Enabling UEFI Capsule Update feature > ------------------------------------- > - > -Support has been added for the UEFI capsule update feature which > -enables updating the U-Boot image using the UEFI firmware management > -protocol (fmp). The capsules are not passed to the firmware through > -the UpdateCapsule runtime service. Instead, capsule-on-disk > -functionality is used for fetching the capsule from the EFI System > -Partition (ESP) by placing the capsule file under the > -\EFI\UpdateCapsule directory. > - > -Currently, support has been added on the QEMU ARM64 virt platform for > -updating the U-Boot binary as a raw image when the platform is booted > -in non-secure mode, i.e. with CONFIG_TFABOOT disabled. For this > -configuration, the QEMU platform needs to be booted with > -'secure=off'. The U-Boot binary placed on the first bank of the NOR > -flash at offset 0x0. The U-Boot environment is placed on the second > -NOR flash bank at offset 0x4000000. > - > -The capsule update feature is enabled with the following configuration > -settings:: > - > - CONFIG_MTD=y > - CONFIG_FLASH_CFI_MTD=y > - CONFIG_CMD_MTDPARTS=y > - CONFIG_CMD_DFU=y > - CONFIG_DFU_MTD=y > - CONFIG_PCI_INIT_R=y > - CONFIG_EFI_CAPSULE_ON_DISK=y > - CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y > - CONFIG_EFI_CAPSULE_FIRMWARE=y > - CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y > - CONFIG_EFI_CAPSULE_FMP_HEADER=y > - > -In addition, the following config needs to be disabled(QEMU ARM specific):: > - > - CONFIG_TFABOOT > - > -The capsule file can be generated by using the tools/mkeficapsule:: > - > - $ mkeficapsule --raw <u-boot.bin> --index 1 <capsule_file_name> > - > -As per the UEFI specification, the capsule file needs to be placed on > -the EFI System Partition, under the \EFI\UpdateCapsule directory. The > -EFI System Partition can be a virtio-blk-device. > - > -Before initiating the firmware update, the efi variables BootNext, > -BootXXXX and OsIndications need to be set. The BootXXXX variable needs > -to be pointing to the EFI System Partition which contains the capsule > -file. The BootNext, BootXXXX and OsIndications variables can be set > -using the following commands:: > - > - => efidebug boot add -b 0 Boot0000 virtio 0:1 <capsule_file_name> > - => efidebug boot next 0 > - => setenv -e -nv -bs -rt -v OsIndications =0x04 > - => saveenv > - > -Finally, the capsule update can be initiated with the following > -command:: > - > - => efidebug capsule disk-update > - > -The updated U-Boot image will be booted on subsequent boot. > - > -Enabling Capsule Authentication > -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > - > -The UEFI specification defines a way of authenticating the capsule to > -be updated by verifying the capsule signature. The capsule signature > -is computed and prepended to the capsule payload at the time of > -capsule generation. This signature is then verified by using the > -public key stored as part of the X509 certificate. This certificate is > -in the form of an efi signature list (esl) file, which is embedded as > -part of the platform's device tree blob using the mkeficapsule > -utility. > - > -On the QEMU virt platforms, the device-tree is generated on the fly > -based on the devices configured. This device tree is then passed on to > -the various software components booting on the platform, including > -U-Boot. Therefore, on the QEMU virt platform, the signatute is > -embedded on an overlay. This overlay is then applied at runtime to the > -base platform device-tree. Steps needed for embedding the esl file in > -the overlay are highlighted below. > - > -The capsule authentication feature can be enabled through the > -following config, in addition to the configs listed above for capsule > -update:: > - > - CONFIG_EFI_CAPSULE_AUTHENTICATE=y > - > -The public and private keys used for the signing process are generated > -and used by the steps highlighted below:: > - > - 1. Install utility commands on your host > - * OPENSSL > - * efitools > - > - 2. Create signing keys and certificate files on your host > - > - $ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=CRT/ \ > - -keyout CRT.key -out CRT.crt -nodes -days 365 > - $ cert-to-efi-sig-list CRT.crt CRT.esl > - > - $ openssl x509 -in CRT.crt -out CRT.cer -outform DER > - $ openssl x509 -inform DER -in CRT.cer -outform PEM -out CRT.pub.pem > - > - $ openssl pkcs12 -export -out CRT.pfx -inkey CRT.key -in CRT.crt > - $ openssl pkcs12 -in CRT.pfx -nodes -out CRT.pem > - > -The capsule file can be generated by using the GenerateCapsule.py > -script in EDKII:: > - > - $ ./BaseTools/BinWrappers/PosixLike/GenerateCapsule -e -o \ > - <capsule_file_name> --monotonic-count <val> --fw-version \ > - <val> --lsv <val> --guid \ > - e2bb9c06-70e9-4b14-97a3-5a7913176e3f --verbose \ > - --update-image-index <val> --signer-private-cert \ > - /path/to/CRT.pem --trusted-public-cert \ > - /path/to/CRT.pub.pem --other-public-cert /path/to/CRT.pub.pem \ > - <u-boot.bin> > - > -Place the capsule generated in the above step on the EFI System > -Partition under the EFI/UpdateCapsule directory > - > -For embedding the public key certificate, the following steps need to > -be followed:: > - > - 1. Generate a skeleton overlay dts file, with a single fragment > - node and an empty __overlay__ node > - > - A typical skeleton overlay file will look like this > - > - /dts-v1/; > - /plugin/; > - > - / { > - fragment@0 { > - target-path = "/"; > - __overlay__ { > - }; > - }; > - }; > - > - > - 2. Convert the dts to a corresponding dtb with the following > - command > - ./scripts/dtc/dtc -@ -I dts -O dtb -o <ov_dtb_file_name> \ > - <dts_file> > - > - 3. Run the dtb file generated above through the mkeficapsule tool > - in U-Boot > - ./tools/mkeficapsule -O <pub_key.esl> -D <ov_dtb> > - > -Running the above command results in the creation of a 'signature' > -node in the dtb, under which the public key is stored as a > -'capsule-key' property. The '-O' option is to be used since the > -public key certificate(esl) file is being embedded in an overlay. > - > -The dtb file embedded with the certificate is now to be placed on an > -EFI System Partition. This would then be loaded and "merged" with the > -base platform flattened device-tree(dtb) at runtime. > - > -Build U-Boot with the following steps(QEMU ARM64):: > - > - $ make qemu_arm64_defconfig > - $ make menuconfig > - Disable CONFIG_TFABOOT > - Enable CONFIG_EFI_CAPSULE_AUTHENTICATE > - Enable all configs needed for capsule update(listed above) > - $ make all > - > -Boot the platform and perform the following steps on the U-Boot > -command line:: > - > - 1. Enable capsule authentication by setting the following env > - variable > - > - => setenv capsule_authentication_enabled 1 > - => saveenv > - > - 2. Load the overlay dtb to memory and merge it with the base fdt > - > - => fatload virtio 0:1 <$fdtovaddr> EFI/<ov_dtb_file> > - => fdt addr $fdtcontroladdr > - => fdt resize <size_of_ov_dtb_file> > - => fdt apply <$fdtovaddr> > - > - 3. Set the following environment and UEFI boot variables > - > - => setenv -e -nv -bs -rt -v OsIndications =0x04 > - => efidebug boot add -b 0 Boot0000 virtio 0:1 <capsule_file_name> > - => efidebug boot next 0 > - => saveenv > - > - 4. Finally, the capsule update can be initiated with the following > - command > - > - => efidebug capsule disk-update > - > -On subsequent reboot, the platform should boot the updated U-Boot binary. > diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst > index 4f2b8b036db8..3d04228e8188 100644 > --- a/doc/develop/uefi/uefi.rst > +++ b/doc/develop/uefi/uefi.rst > @@ -277,6 +277,131 @@ Enable ``CONFIG_OPTEE``, ``CONFIG_CMD_OPTEE_RPMB`` and ``CONFIG_EFI_MM_COMM_TEE` > > [1] https://optee.readthedocs.io/en/latest/building/efi_vars/stmm.html > > +Enabling UEFI Capsule Update feature > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ > + > +Support has been added for the UEFI capsule update feature which > +enables updating the U-Boot image using the UEFI firmware management > +protocol (FMP). The capsules are not passed to the firmware through > +the UpdateCapsule runtime service. Instead, capsule-on-disk > +functionality is used for fetching the capsule from the EFI System > +Partition (ESP) by placing the capsule file under the > +\EFI\UpdateCapsule directory. > + > +The directory \EFI\UpdateCapsule is checked for capsules only within the > +EFI system partition on the device specified in the active boot option > +determine by reference to BootNext variable or BootOrder variable processing. %s/determine/determined/ > +The active Boot Variable is the variable with highest priority BootNext or Does only the device have to be present or also the file? Should we check only the binary or also the initrd? Best regards Heinrich > +within BootOrder that refers to a device found to be present. Boot variables > +in BootOrder but referring to devices not present are ignored when determining > +active boot variable. > +Before starting a capsule update make sure your capsules are installed in the > +correct ESP partition or set BootNext. > + > +Performing the update > +********************* > + > +Since U-boot doesn't currently support SetVariable at runtime there's a Kconfig > +option (CONFIG_EFI_IGNORE_OSINDICATIONS) to disable the OsIndications variable > +check. If that option is enabled just copy your capsule to \EFI\UpdateCapsule. > + > +If that option is disabled, you'll need to set the OsIndications variable with:: > + > + => setenv -e -nv -bs -rt -v OsIndications =0x04 > + > +Finally, the capsule update can be initiated either by rebooting the board, > +which is the preferred method, or by issuing the following command:: > + > + => efidebug capsule disk-update > + > +**The efidebug command is should only be used during debugging/development.** > + > +Enabling Capsule Authentication > +******************************* > + > +The UEFI specification defines a way of authenticating the capsule to > +be updated by verifying the capsule signature. The capsule signature > +is computed and prepended to the capsule payload at the time of > +capsule generation. This signature is then verified by using the > +public key stored as part of the X509 certificate. This certificate is > +in the form of an efi signature list (esl) file, which is embedded as > +part of U-Boot. > + > +The capsule authentication feature can be enabled through the > +following config, in addition to the configs listed above for capsule > +update:: > + > + CONFIG_EFI_CAPSULE_AUTHENTICATE=y > + CONFIG_EFI_CAPSULE_KEY_PATH=<path to .esl cert> > + > +The public and private keys used for the signing process are generated > +and used by the steps highlighted below:: > + > + 1. Install utility commands on your host > + * OPENSSL > + * efitools > + > + 2. Create signing keys and certificate files on your host > + > + $ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=CRT/ \ > + -keyout CRT.key -out CRT.crt -nodes -days 365 > + $ cert-to-efi-sig-list CRT.crt CRT.esl > + > + $ openssl x509 -in CRT.crt -out CRT.cer -outform DER > + $ openssl x509 -inform DER -in CRT.cer -outform PEM -out CRT.pub.pem > + > + $ openssl pkcs12 -export -out CRT.pfx -inkey CRT.key -in CRT.crt > + $ openssl pkcs12 -in CRT.pfx -nodes -out CRT.pem > + > +The capsule file can be generated by using the GenerateCapsule.py > +script in EDKII:: > + > + $ ./BaseTools/BinWrappers/PosixLike/GenerateCapsule -e -o \ > + <capsule_file_name> --monotonic-count <val> --fw-version \ > + <val> --lsv <val> --guid \ > + e2bb9c06-70e9-4b14-97a3-5a7913176e3f --verbose \ > + --update-image-index <val> --signer-private-cert \ > + /path/to/CRT.pem --trusted-public-cert \ > + /path/to/CRT.pub.pem --other-public-cert /path/to/CRT.pub.pem \ > + <u-boot.bin> > + > +Place the capsule generated in the above step on the EFI System > +Partition under the EFI/UpdateCapsule directory > + > +Testing on QEMU > +*************** > + > +Currently, support has been added on the QEMU ARM64 virt platform for > +updating the U-Boot binary as a raw image when the platform is booted > +in non-secure mode, i.e. with CONFIG_TFABOOT disabled. For this > +configuration, the QEMU platform needs to be booted with > +'secure=off'. The U-Boot binary placed on the first bank of the NOR > +flash at offset 0x0. The U-Boot environment is placed on the second > +NOR flash bank at offset 0x4000000. > + > +The capsule update feature is enabled with the following configuration > +settings:: > + > + CONFIG_MTD=y > + CONFIG_FLASH_CFI_MTD=y > + CONFIG_CMD_MTDPARTS=y > + CONFIG_CMD_DFU=y > + CONFIG_DFU_MTD=y > + CONFIG_PCI_INIT_R=y > + CONFIG_EFI_CAPSULE_ON_DISK=y > + CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y > + CONFIG_EFI_CAPSULE_FIRMWARE=y > + CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y > + CONFIG_EFI_CAPSULE_FMP_HEADER=y > + > +In addition, the following config needs to be disabled(QEMU ARM specific):: > + > + CONFIG_TFABOOT > + > +The capsule file can be generated by using the tools/mkeficapsule:: > + > + $ mkeficapsule --raw <u-boot.bin> --index 1 <capsule_file_name> > + > Executing the boot manager > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > >
> > + > > +The directory \EFI\UpdateCapsule is checked for capsules only within the > > +EFI system partition on the device specified in the active boot option > > +determine by reference to BootNext variable or BootOrder variable processing. > > %s/determine/determined/ > sure > > +The active Boot Variable is the variable with highest priority BootNext or > > Does only the device have to be present or also the file? > Should we check only the binary or also the initrd? I don't follow on the initrd. The whole paragraph is copied verbatim from the EFI spec. Basically you need a valid boot option (with priority) that points to the ESP partition your capsule is. Akashi's code is also doing the right thing following the spec. Regards /Ilias > > Best regards > > Heinrich > > > +within BootOrder that refers to a device found to be present. Boot variables > > +in BootOrder but referring to devices not present are ignored when determining > > +active boot variable. > > +Before starting a capsule update make sure your capsules are installed in the > > +correct ESP partition or set BootNext. > > + > > +Performing the update > > +********************* > > + > > +Since U-boot doesn't currently support SetVariable at runtime there's a Kconfig > > +option (CONFIG_EFI_IGNORE_OSINDICATIONS) to disable the OsIndications variable > > +check. If that option is enabled just copy your capsule to \EFI\UpdateCapsule. > > + > > +If that option is disabled, you'll need to set the OsIndications variable with:: > > + > > + => setenv -e -nv -bs -rt -v OsIndications =0x04 > > + > > +Finally, the capsule update can be initiated either by rebooting the board, > > +which is the preferred method, or by issuing the following command:: > > + > > + => efidebug capsule disk-update > > + > > +**The efidebug command is should only be used during debugging/development.** > > + > > +Enabling Capsule Authentication > > +******************************* > > + > > +The UEFI specification defines a way of authenticating the capsule to > > +be updated by verifying the capsule signature. The capsule signature > > +is computed and prepended to the capsule payload at the time of > > +capsule generation. This signature is then verified by using the > > +public key stored as part of the X509 certificate. This certificate is > > +in the form of an efi signature list (esl) file, which is embedded as > > +part of U-Boot. > > + > > +The capsule authentication feature can be enabled through the > > +following config, in addition to the configs listed above for capsule > > +update:: > > + > > + CONFIG_EFI_CAPSULE_AUTHENTICATE=y > > + CONFIG_EFI_CAPSULE_KEY_PATH=<path to .esl cert> > > + > > +The public and private keys used for the signing process are generated > > +and used by the steps highlighted below:: > > + > > + 1. Install utility commands on your host > > + * OPENSSL > > + * efitools > > + > > + 2. Create signing keys and certificate files on your host > > + > > + $ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=CRT/ \ > > + -keyout CRT.key -out CRT.crt -nodes -days 365 > > + $ cert-to-efi-sig-list CRT.crt CRT.esl > > + > > + $ openssl x509 -in CRT.crt -out CRT.cer -outform DER > > + $ openssl x509 -inform DER -in CRT.cer -outform PEM -out CRT.pub.pem > > + > > + $ openssl pkcs12 -export -out CRT.pfx -inkey CRT.key -in CRT.crt > > + $ openssl pkcs12 -in CRT.pfx -nodes -out CRT.pem > > + > > +The capsule file can be generated by using the GenerateCapsule.py > > +script in EDKII:: > > + > > + $ ./BaseTools/BinWrappers/PosixLike/GenerateCapsule -e -o \ > > + <capsule_file_name> --monotonic-count <val> --fw-version \ > > + <val> --lsv <val> --guid \ > > + e2bb9c06-70e9-4b14-97a3-5a7913176e3f --verbose \ > > + --update-image-index <val> --signer-private-cert \ > > + /path/to/CRT.pem --trusted-public-cert \ > > + /path/to/CRT.pub.pem --other-public-cert /path/to/CRT.pub.pem \ > > + <u-boot.bin> > > + > > +Place the capsule generated in the above step on the EFI System > > +Partition under the EFI/UpdateCapsule directory > > + > > +Testing on QEMU > > +*************** > > + > > +Currently, support has been added on the QEMU ARM64 virt platform for > > +updating the U-Boot binary as a raw image when the platform is booted > > +in non-secure mode, i.e. with CONFIG_TFABOOT disabled. For this > > +configuration, the QEMU platform needs to be booted with > > +'secure=off'. The U-Boot binary placed on the first bank of the NOR > > +flash at offset 0x0. The U-Boot environment is placed on the second > > +NOR flash bank at offset 0x4000000. > > + > > +The capsule update feature is enabled with the following configuration > > +settings:: > > + > > + CONFIG_MTD=y > > + CONFIG_FLASH_CFI_MTD=y > > + CONFIG_CMD_MTDPARTS=y > > + CONFIG_CMD_DFU=y > > + CONFIG_DFU_MTD=y > > + CONFIG_PCI_INIT_R=y > > + CONFIG_EFI_CAPSULE_ON_DISK=y > > + CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y > > + CONFIG_EFI_CAPSULE_FIRMWARE=y > > + CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y > > + CONFIG_EFI_CAPSULE_FMP_HEADER=y > > + > > +In addition, the following config needs to be disabled(QEMU ARM specific):: > > + > > + CONFIG_TFABOOT > > + > > +The capsule file can be generated by using the tools/mkeficapsule:: > > + > > + $ mkeficapsule --raw <u-boot.bin> --index 1 <capsule_file_name> > > + > > Executing the boot manager > > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > >
On Fri, Jul 16, 2021 at 10:09:40AM +0300, Ilias Apalodimas wrote: > > > + > > > +The directory \EFI\UpdateCapsule is checked for capsules only within the > > > +EFI system partition on the device specified in the active boot option > > > +determine by reference to BootNext variable or BootOrder variable processing. > > > > %s/determine/determined/ > > > > sure > > > > +The active Boot Variable is the variable with highest priority BootNext or > > > > Does only the device have to be present or also the file? > > Should we check only the binary or also the initrd? > > I don't follow on the initrd. > The whole paragraph is copied verbatim from the EFI spec. Basically you > need a valid boot option (with priority) that points to the ESP partition > your capsule is. Akashi's code is also doing the right thing following the > spec. I *guess* that Heinrich thinks of all the device paths contained in an boot option, including "initrd" that you added a support for. IIRC, all the paths in one option must point to the same device. (So no for Heinrich's concern?) -Takahiro Akashi > Regards > /Ilias > > > > Best regards > > > > Heinrich > > > > > +within BootOrder that refers to a device found to be present. Boot variables > > > +in BootOrder but referring to devices not present are ignored when determining > > > +active boot variable. > > > +Before starting a capsule update make sure your capsules are installed in the > > > +correct ESP partition or set BootNext. > > > + > > > +Performing the update > > > +********************* > > > + > > > +Since U-boot doesn't currently support SetVariable at runtime there's a Kconfig > > > +option (CONFIG_EFI_IGNORE_OSINDICATIONS) to disable the OsIndications variable > > > +check. If that option is enabled just copy your capsule to \EFI\UpdateCapsule. > > > + > > > +If that option is disabled, you'll need to set the OsIndications variable with:: > > > + > > > + => setenv -e -nv -bs -rt -v OsIndications =0x04 > > > + > > > +Finally, the capsule update can be initiated either by rebooting the board, > > > +which is the preferred method, or by issuing the following command:: > > > + > > > + => efidebug capsule disk-update > > > + > > > +**The efidebug command is should only be used during debugging/development.** > > > + > > > +Enabling Capsule Authentication > > > +******************************* > > > + > > > +The UEFI specification defines a way of authenticating the capsule to > > > +be updated by verifying the capsule signature. The capsule signature > > > +is computed and prepended to the capsule payload at the time of > > > +capsule generation. This signature is then verified by using the > > > +public key stored as part of the X509 certificate. This certificate is > > > +in the form of an efi signature list (esl) file, which is embedded as > > > +part of U-Boot. > > > + > > > +The capsule authentication feature can be enabled through the > > > +following config, in addition to the configs listed above for capsule > > > +update:: > > > + > > > + CONFIG_EFI_CAPSULE_AUTHENTICATE=y > > > + CONFIG_EFI_CAPSULE_KEY_PATH=<path to .esl cert> > > > + > > > +The public and private keys used for the signing process are generated > > > +and used by the steps highlighted below:: > > > + > > > + 1. Install utility commands on your host > > > + * OPENSSL > > > + * efitools > > > + > > > + 2. Create signing keys and certificate files on your host > > > + > > > + $ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=CRT/ \ > > > + -keyout CRT.key -out CRT.crt -nodes -days 365 > > > + $ cert-to-efi-sig-list CRT.crt CRT.esl > > > + > > > + $ openssl x509 -in CRT.crt -out CRT.cer -outform DER > > > + $ openssl x509 -inform DER -in CRT.cer -outform PEM -out CRT.pub.pem > > > + > > > + $ openssl pkcs12 -export -out CRT.pfx -inkey CRT.key -in CRT.crt > > > + $ openssl pkcs12 -in CRT.pfx -nodes -out CRT.pem > > > + > > > +The capsule file can be generated by using the GenerateCapsule.py > > > +script in EDKII:: > > > + > > > + $ ./BaseTools/BinWrappers/PosixLike/GenerateCapsule -e -o \ > > > + <capsule_file_name> --monotonic-count <val> --fw-version \ > > > + <val> --lsv <val> --guid \ > > > + e2bb9c06-70e9-4b14-97a3-5a7913176e3f --verbose \ > > > + --update-image-index <val> --signer-private-cert \ > > > + /path/to/CRT.pem --trusted-public-cert \ > > > + /path/to/CRT.pub.pem --other-public-cert /path/to/CRT.pub.pem \ > > > + <u-boot.bin> > > > + > > > +Place the capsule generated in the above step on the EFI System > > > +Partition under the EFI/UpdateCapsule directory > > > + > > > +Testing on QEMU > > > +*************** > > > + > > > +Currently, support has been added on the QEMU ARM64 virt platform for > > > +updating the U-Boot binary as a raw image when the platform is booted > > > +in non-secure mode, i.e. with CONFIG_TFABOOT disabled. For this > > > +configuration, the QEMU platform needs to be booted with > > > +'secure=off'. The U-Boot binary placed on the first bank of the NOR > > > +flash at offset 0x0. The U-Boot environment is placed on the second > > > +NOR flash bank at offset 0x4000000. > > > + > > > +The capsule update feature is enabled with the following configuration > > > +settings:: > > > + > > > + CONFIG_MTD=y > > > + CONFIG_FLASH_CFI_MTD=y > > > + CONFIG_CMD_MTDPARTS=y > > > + CONFIG_CMD_DFU=y > > > + CONFIG_DFU_MTD=y > > > + CONFIG_PCI_INIT_R=y > > > + CONFIG_EFI_CAPSULE_ON_DISK=y > > > + CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y > > > + CONFIG_EFI_CAPSULE_FIRMWARE=y > > > + CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y > > > + CONFIG_EFI_CAPSULE_FMP_HEADER=y > > > + > > > +In addition, the following config needs to be disabled(QEMU ARM specific):: > > > + > > > + CONFIG_TFABOOT > > > + > > > +The capsule file can be generated by using the tools/mkeficapsule:: > > > + > > > + $ mkeficapsule --raw <u-boot.bin> --index 1 <capsule_file_name> > > > + > > > Executing the boot manager > > > ~~~~~~~~~~~~~~~~~~~~~~~~~~ > > > > > > > >
diff --git a/doc/board/emulation/qemu_capsule_update.rst b/doc/board/emulation/qemu_capsule_update.rst deleted file mode 100644 index 0a2286d039d9..000000000000 --- a/doc/board/emulation/qemu_capsule_update.rst +++ /dev/null @@ -1,203 +0,0 @@ -.. SPDX-License-Identifier: GPL-2.0+ -.. Copyright (C) 2020, Linaro Limited - -Enabling UEFI Capsule Update feature ------------------------------------- - -Support has been added for the UEFI capsule update feature which -enables updating the U-Boot image using the UEFI firmware management -protocol (fmp). The capsules are not passed to the firmware through -the UpdateCapsule runtime service. Instead, capsule-on-disk -functionality is used for fetching the capsule from the EFI System -Partition (ESP) by placing the capsule file under the -\EFI\UpdateCapsule directory. - -Currently, support has been added on the QEMU ARM64 virt platform for -updating the U-Boot binary as a raw image when the platform is booted -in non-secure mode, i.e. with CONFIG_TFABOOT disabled. For this -configuration, the QEMU platform needs to be booted with -'secure=off'. The U-Boot binary placed on the first bank of the NOR -flash at offset 0x0. The U-Boot environment is placed on the second -NOR flash bank at offset 0x4000000. - -The capsule update feature is enabled with the following configuration -settings:: - - CONFIG_MTD=y - CONFIG_FLASH_CFI_MTD=y - CONFIG_CMD_MTDPARTS=y - CONFIG_CMD_DFU=y - CONFIG_DFU_MTD=y - CONFIG_PCI_INIT_R=y - CONFIG_EFI_CAPSULE_ON_DISK=y - CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y - CONFIG_EFI_CAPSULE_FIRMWARE=y - CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y - CONFIG_EFI_CAPSULE_FMP_HEADER=y - -In addition, the following config needs to be disabled(QEMU ARM specific):: - - CONFIG_TFABOOT - -The capsule file can be generated by using the tools/mkeficapsule:: - - $ mkeficapsule --raw <u-boot.bin> --index 1 <capsule_file_name> - -As per the UEFI specification, the capsule file needs to be placed on -the EFI System Partition, under the \EFI\UpdateCapsule directory. The -EFI System Partition can be a virtio-blk-device. - -Before initiating the firmware update, the efi variables BootNext, -BootXXXX and OsIndications need to be set. The BootXXXX variable needs -to be pointing to the EFI System Partition which contains the capsule -file. The BootNext, BootXXXX and OsIndications variables can be set -using the following commands:: - - => efidebug boot add -b 0 Boot0000 virtio 0:1 <capsule_file_name> - => efidebug boot next 0 - => setenv -e -nv -bs -rt -v OsIndications =0x04 - => saveenv - -Finally, the capsule update can be initiated with the following -command:: - - => efidebug capsule disk-update - -The updated U-Boot image will be booted on subsequent boot. - -Enabling Capsule Authentication -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The UEFI specification defines a way of authenticating the capsule to -be updated by verifying the capsule signature. The capsule signature -is computed and prepended to the capsule payload at the time of -capsule generation. This signature is then verified by using the -public key stored as part of the X509 certificate. This certificate is -in the form of an efi signature list (esl) file, which is embedded as -part of the platform's device tree blob using the mkeficapsule -utility. - -On the QEMU virt platforms, the device-tree is generated on the fly -based on the devices configured. This device tree is then passed on to -the various software components booting on the platform, including -U-Boot. Therefore, on the QEMU virt platform, the signatute is -embedded on an overlay. This overlay is then applied at runtime to the -base platform device-tree. Steps needed for embedding the esl file in -the overlay are highlighted below. - -The capsule authentication feature can be enabled through the -following config, in addition to the configs listed above for capsule -update:: - - CONFIG_EFI_CAPSULE_AUTHENTICATE=y - -The public and private keys used for the signing process are generated -and used by the steps highlighted below:: - - 1. Install utility commands on your host - * OPENSSL - * efitools - - 2. Create signing keys and certificate files on your host - - $ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=CRT/ \ - -keyout CRT.key -out CRT.crt -nodes -days 365 - $ cert-to-efi-sig-list CRT.crt CRT.esl - - $ openssl x509 -in CRT.crt -out CRT.cer -outform DER - $ openssl x509 -inform DER -in CRT.cer -outform PEM -out CRT.pub.pem - - $ openssl pkcs12 -export -out CRT.pfx -inkey CRT.key -in CRT.crt - $ openssl pkcs12 -in CRT.pfx -nodes -out CRT.pem - -The capsule file can be generated by using the GenerateCapsule.py -script in EDKII:: - - $ ./BaseTools/BinWrappers/PosixLike/GenerateCapsule -e -o \ - <capsule_file_name> --monotonic-count <val> --fw-version \ - <val> --lsv <val> --guid \ - e2bb9c06-70e9-4b14-97a3-5a7913176e3f --verbose \ - --update-image-index <val> --signer-private-cert \ - /path/to/CRT.pem --trusted-public-cert \ - /path/to/CRT.pub.pem --other-public-cert /path/to/CRT.pub.pem \ - <u-boot.bin> - -Place the capsule generated in the above step on the EFI System -Partition under the EFI/UpdateCapsule directory - -For embedding the public key certificate, the following steps need to -be followed:: - - 1. Generate a skeleton overlay dts file, with a single fragment - node and an empty __overlay__ node - - A typical skeleton overlay file will look like this - - /dts-v1/; - /plugin/; - - / { - fragment@0 { - target-path = "/"; - __overlay__ { - }; - }; - }; - - - 2. Convert the dts to a corresponding dtb with the following - command - ./scripts/dtc/dtc -@ -I dts -O dtb -o <ov_dtb_file_name> \ - <dts_file> - - 3. Run the dtb file generated above through the mkeficapsule tool - in U-Boot - ./tools/mkeficapsule -O <pub_key.esl> -D <ov_dtb> - -Running the above command results in the creation of a 'signature' -node in the dtb, under which the public key is stored as a -'capsule-key' property. The '-O' option is to be used since the -public key certificate(esl) file is being embedded in an overlay. - -The dtb file embedded with the certificate is now to be placed on an -EFI System Partition. This would then be loaded and "merged" with the -base platform flattened device-tree(dtb) at runtime. - -Build U-Boot with the following steps(QEMU ARM64):: - - $ make qemu_arm64_defconfig - $ make menuconfig - Disable CONFIG_TFABOOT - Enable CONFIG_EFI_CAPSULE_AUTHENTICATE - Enable all configs needed for capsule update(listed above) - $ make all - -Boot the platform and perform the following steps on the U-Boot -command line:: - - 1. Enable capsule authentication by setting the following env - variable - - => setenv capsule_authentication_enabled 1 - => saveenv - - 2. Load the overlay dtb to memory and merge it with the base fdt - - => fatload virtio 0:1 <$fdtovaddr> EFI/<ov_dtb_file> - => fdt addr $fdtcontroladdr - => fdt resize <size_of_ov_dtb_file> - => fdt apply <$fdtovaddr> - - 3. Set the following environment and UEFI boot variables - - => setenv -e -nv -bs -rt -v OsIndications =0x04 - => efidebug boot add -b 0 Boot0000 virtio 0:1 <capsule_file_name> - => efidebug boot next 0 - => saveenv - - 4. Finally, the capsule update can be initiated with the following - command - - => efidebug capsule disk-update - -On subsequent reboot, the platform should boot the updated U-Boot binary. diff --git a/doc/develop/uefi/uefi.rst b/doc/develop/uefi/uefi.rst index 4f2b8b036db8..3d04228e8188 100644 --- a/doc/develop/uefi/uefi.rst +++ b/doc/develop/uefi/uefi.rst @@ -277,6 +277,131 @@ Enable ``CONFIG_OPTEE``, ``CONFIG_CMD_OPTEE_RPMB`` and ``CONFIG_EFI_MM_COMM_TEE` [1] https://optee.readthedocs.io/en/latest/building/efi_vars/stmm.html +Enabling UEFI Capsule Update feature +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Support has been added for the UEFI capsule update feature which +enables updating the U-Boot image using the UEFI firmware management +protocol (FMP). The capsules are not passed to the firmware through +the UpdateCapsule runtime service. Instead, capsule-on-disk +functionality is used for fetching the capsule from the EFI System +Partition (ESP) by placing the capsule file under the +\EFI\UpdateCapsule directory. + +The directory \EFI\UpdateCapsule is checked for capsules only within the +EFI system partition on the device specified in the active boot option +determine by reference to BootNext variable or BootOrder variable processing. +The active Boot Variable is the variable with highest priority BootNext or +within BootOrder that refers to a device found to be present. Boot variables +in BootOrder but referring to devices not present are ignored when determining +active boot variable. +Before starting a capsule update make sure your capsules are installed in the +correct ESP partition or set BootNext. + +Performing the update +********************* + +Since U-boot doesn't currently support SetVariable at runtime there's a Kconfig +option (CONFIG_EFI_IGNORE_OSINDICATIONS) to disable the OsIndications variable +check. If that option is enabled just copy your capsule to \EFI\UpdateCapsule. + +If that option is disabled, you'll need to set the OsIndications variable with:: + + => setenv -e -nv -bs -rt -v OsIndications =0x04 + +Finally, the capsule update can be initiated either by rebooting the board, +which is the preferred method, or by issuing the following command:: + + => efidebug capsule disk-update + +**The efidebug command is should only be used during debugging/development.** + +Enabling Capsule Authentication +******************************* + +The UEFI specification defines a way of authenticating the capsule to +be updated by verifying the capsule signature. The capsule signature +is computed and prepended to the capsule payload at the time of +capsule generation. This signature is then verified by using the +public key stored as part of the X509 certificate. This certificate is +in the form of an efi signature list (esl) file, which is embedded as +part of U-Boot. + +The capsule authentication feature can be enabled through the +following config, in addition to the configs listed above for capsule +update:: + + CONFIG_EFI_CAPSULE_AUTHENTICATE=y + CONFIG_EFI_CAPSULE_KEY_PATH=<path to .esl cert> + +The public and private keys used for the signing process are generated +and used by the steps highlighted below:: + + 1. Install utility commands on your host + * OPENSSL + * efitools + + 2. Create signing keys and certificate files on your host + + $ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=CRT/ \ + -keyout CRT.key -out CRT.crt -nodes -days 365 + $ cert-to-efi-sig-list CRT.crt CRT.esl + + $ openssl x509 -in CRT.crt -out CRT.cer -outform DER + $ openssl x509 -inform DER -in CRT.cer -outform PEM -out CRT.pub.pem + + $ openssl pkcs12 -export -out CRT.pfx -inkey CRT.key -in CRT.crt + $ openssl pkcs12 -in CRT.pfx -nodes -out CRT.pem + +The capsule file can be generated by using the GenerateCapsule.py +script in EDKII:: + + $ ./BaseTools/BinWrappers/PosixLike/GenerateCapsule -e -o \ + <capsule_file_name> --monotonic-count <val> --fw-version \ + <val> --lsv <val> --guid \ + e2bb9c06-70e9-4b14-97a3-5a7913176e3f --verbose \ + --update-image-index <val> --signer-private-cert \ + /path/to/CRT.pem --trusted-public-cert \ + /path/to/CRT.pub.pem --other-public-cert /path/to/CRT.pub.pem \ + <u-boot.bin> + +Place the capsule generated in the above step on the EFI System +Partition under the EFI/UpdateCapsule directory + +Testing on QEMU +*************** + +Currently, support has been added on the QEMU ARM64 virt platform for +updating the U-Boot binary as a raw image when the platform is booted +in non-secure mode, i.e. with CONFIG_TFABOOT disabled. For this +configuration, the QEMU platform needs to be booted with +'secure=off'. The U-Boot binary placed on the first bank of the NOR +flash at offset 0x0. The U-Boot environment is placed on the second +NOR flash bank at offset 0x4000000. + +The capsule update feature is enabled with the following configuration +settings:: + + CONFIG_MTD=y + CONFIG_FLASH_CFI_MTD=y + CONFIG_CMD_MTDPARTS=y + CONFIG_CMD_DFU=y + CONFIG_DFU_MTD=y + CONFIG_PCI_INIT_R=y + CONFIG_EFI_CAPSULE_ON_DISK=y + CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y + CONFIG_EFI_CAPSULE_FIRMWARE=y + CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y + CONFIG_EFI_CAPSULE_FMP_HEADER=y + +In addition, the following config needs to be disabled(QEMU ARM specific):: + + CONFIG_TFABOOT + +The capsule file can be generated by using the tools/mkeficapsule:: + + $ mkeficapsule --raw <u-boot.bin> --index 1 <capsule_file_name> + Executing the boot manager ~~~~~~~~~~~~~~~~~~~~~~~~~~
Since we removed embeddingg the capsule key into a .dtb and fixed authenticated capsule updates for all boards, move the relevant documentation in the efi file and update it accordingly Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> --- doc/board/emulation/qemu_capsule_update.rst | 203 -------------------- doc/develop/uefi/uefi.rst | 125 ++++++++++++ 2 files changed, 125 insertions(+), 203 deletions(-) delete mode 100644 doc/board/emulation/qemu_capsule_update.rst -- 2.32.0.rc0