1
0
mirror of https://git.yoctoproject.org/meta-arm synced 2026-07-18 04:27:08 +00:00

Compare commits

...

21 Commits

Author SHA1 Message Date
Abdellatif El Khlifi 38e26f52a8 kas: update the layers SHAs
set the tested SHAs

Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-06-13 13:00:29 -04:00
Bence Balogh 81a24f1aac arm-bsp/documentation: corstone1000: improve tests documentation
Improve the documentation in the user guide of the following tests:

- SystemReady-IR tests
- Manual capsule update and ESRT checks
- Linux distros tests
- UEFI Secureboot (SB) test
- PSA API tests

In addition, we moved the tests in one section for better readability.

Signed-off-by: Delane Brandy <delane.brandy@arm.com>
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-06-13 13:00:29 -04:00
Bence Balogh 9f6643c967 arm-bsp/documentation: corstone1000: update the boot chain
The Secure Boot chain section is updated in the architecture document
to reflect the TF-M BL1 design.

Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Signed-off-by: Delane Brandy <delane.brandy@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-06-13 13:00:29 -04:00
Bence Balogh 3922b49529 kas: corstone1000: remove Arm-FVP-EULA flag
This flag should not be set here and the ARM_FVP_EULA_ACCEPT
should be set to True manually before building for the FVP, as it is
mentioned in the Corstone-1000 User guide:
export ARM_FVP_EULA_ACCEPT="True"

Fixes: 6e2a54748 ("kas: Corstone-1000 kas files updated")
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-06-04 05:00:25 -04:00
Jon Mason 189d473fc9 CI: correct BB_HASHSERVE_UPSTREAM
The BB_HASHSERVE_UPSTREAM has issues which cause significantly less of a
match than expected.  Update with the correct values to get the expected
behavior.

Fixes: 6e9525115b ("CI: add Yocto Project SSTATE Mirror")
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-30 08:50:59 -04:00
Bence Balogh 7728407220 arm-bsp/trusted-firmware-m: corstone1000: remove capsule update reset
The reset has to be removed from the TF-M side after capsule update
because it caused data abort exceptions on the host side.

Signed-off-by: Bence Balogh <bence.balogh@arm.com>
2024-05-29 14:08:28 -04:00
Delane Brandy e0f39a0a8b arm-bsp/corstone1000: update the documentation
Update the Corstone-1000 Documentation for the
2024.06 release.

Signed-off-by: Delane Brandy <delane.brandy@arm.com>
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
2024-05-29 14:08:07 -04:00
Bence Balogh b50f5fb37e kas: corstone1000: set branch to scarthgap
The default branch will be scarthgap so the poky and
openembedded will follow this branch.

Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-23 11:00:24 -04:00
Bence Balogh 1200a59db6 arm-bsp/trusted-firmware-m: corstone1000: increase RSE_COMMS buff size
The buffer size has to be increased to fit the EFI variables which got
increased metadata sizes.

Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-22 14:11:57 -04:00
Bence Balogh a9a3c53ea6 arm-bsp/trusted-services: corstone1000: increase comm buffer size
The increased EFI variable metadata need bigger buffer so it can
be transfered to the Secure Enclave without memory overflow
issues. The heap and buffer sizes had to be aligned with the.

Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-22 14:11:57 -04:00
Bence Balogh 7b6e37a4a3 arm-bsp/trusted-firmware-m: corstone1000: increase PS sizes
The private authenticated variable changes increased the variables
metadata. The PS max asset size and related buffer sizes have to be
increased because of this.

Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-22 14:11:57 -04:00
Bence Balogh 28cc4ca37c arm-bsp/trusted-services: corstone1000: add fixes for private auth vars
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-22 14:11:57 -04:00
Bence Balogh 1b782e9313 arm-bsp/trusted-services: corstone1000: add EFI var handling fixes
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-22 14:11:57 -04:00
Jon Mason 36f731e63e arm/oeqa: increase optee and ftpm test timeouts
OPTEE and ftpm tests are failing in CI on slower systems due to timing
out, but actually finish when given enough time to complete.  Increase
the timeout value to be roughly 100 seconds longer than the time it is
currently taking to finish on the slower systems.

Fixes: d450786667 ("oeqa runtime: add optee.py test")
Fixes: ba315f7242 ("oeqa runtime: add ftpm.py test")
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-21 10:24:43 -04:00
Ben Cownley 9781813a88 arm-systemready/linux-distros: Upgrade the openSUSE version to 15.5
Upgrade the openSUSE distribution from version 15.4 to version 15.5
openSUSE Licenses updated to reflect update from 15.4 to 15.5
License now includes: Apache-1.1, BSL-1.0, IPL-1.0, Sleepycat, Zlib

Signed-off-by: Ben Cownley <ben.cownley@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-21 10:23:24 -04:00
Amr Mohamed ba0f913fb1 arm-systemready/linux-distros: Upgrade the Debian license
Debian Licenses updated to reflect update from 11.7 to 12.4
License now includes: AFL-2.0, AFL-2.1,
GPL-2.0-with-autoconf-exception,
GPL-2.0-with-OpenSSL-exception,
GPL-3.0-with-autoconf-exception,
GPL-3-with-bison-exception, SMAIL_GPL,
BSD-2-Clause, BSD-3-Clause-Clear,
BSD-4-Clause-UC, TCP-wrappers, OLDAP-2.8,
PSF-2.0, BSL-1.0, bzip2-1.0.6, CC0-1.0,
Libpng, Latex2e, Unicode-TOU, Unicode-DFS-2016,
CC-BY-3.0, CC-BY-SA-3.0, CC-BY-SA-4.0, curl,
MS-PL, NTP, FSFAP, FSFUL, FSFULLR, FSF-Unlimited,
EDL-1.0, Vim, FTL, TCL, MPL-1.1, MPL-2.0,
GFDL-1.1-or-later, GFDL-1.2-or-later,
GFDL-1.3-no-invariants-or-later,
GFDL-1.3-no-invariants-only, Artistic-1.0,
Artistic-2.0, Apache-2.0,
Apache-2.0-with-LLVM-exception, Spencer-86,
MIT, MIT-CMU, MIT-advertising, Beerware,
Intel, X11, ISC, IPL-1.0, SSH-OpenSSH, SSH-short,
RSA-MD, OPL-1.0, PD

Licenses removed: Apache-1.0, Apache-1.1, Ruby, PHP-3.01,
W3C-20150513

Signed-off-by: Amr Mohamed <amr.mohamed@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-17 11:07:38 -04:00
Harsimran Singh Tungal d6cd18b600 arm-bsp/documentation: corstone1000: Update user guide for secureboot test
This changeset updates the user guide to test the secureboot for both the
FVP and FPGA.

Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-17 09:38:51 -04:00
Bence Balogh 093247cdb0 arm-bsp/trusted-services: corstone1000: fix IAT test
The psa-iat-api-test was failing because the PLATFORM_HAS_ATTEST_PK
flag was added to the build for Corstone1000.

Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-17 09:38:51 -04:00
Ali Can Ozaslan 9e316ecc1d arm-bsp/trusted-firmware-m: corstone1000: fix crypto failure on mps3
Crypto-AEAD-APIs tests fails on mps3. Configures CC312 mps3 model
same as predefined cc312 FVP configuration while keeping debug
ports closed.

Signed-off-by: Ali Can Ozaslan <ali.oezaslan@arm.com>
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Emekcan Aras <emekcan.aras@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-17 09:38:51 -04:00
Emekcan Aras 3ce8043bf8 arm-bsp/trusted-firmware-a: corstone1000: fix reset sequence
Corstone1000 does not properly clean the cache and disable gic interrupts
before the reset. This causes a race condition especially in FVP after reset.
This adds proper sequence before resetting the platform.

Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-16 11:49:31 -04:00
Ross Burton 69f9ef2fe5 arm/boot-wrapper-aarch64: use https to fetch git source
Some networks limit outgoing git: traffic, so use https:.

Fixes: 0cec3e5 ("arm/gem5/boot-wrapper-aarch64: Move main recipe to meta-arm")
Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-05-08 10:45:41 -04:00
33 changed files with 2955 additions and 222 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ header:
local_conf_header:
sstate_mirror: |
BB_HASHSERVE_UPSTREAM = "hashserv.yocto.io:8687"
BB_HASHSERVE_UPSTREAM = "wss://hashserv.yoctoproject.org/ws"
SSTATE_MIRRORS = "file://.* http://cdn.jsdelivr.net/yocto/sstate/all/PATH;downloadfilename=PATH"
BB_HASHSERVE = "auto"
BB_SIGNATURE_HANDLER = "OEEquivHash"
+4 -4
View File
@@ -5,7 +5,7 @@ distro: poky
defaults:
repos:
branch: master
branch: scarthgap
repos:
meta-arm:
@@ -16,14 +16,14 @@ repos:
poky:
url: https://git.yoctoproject.org/git/poky
# commit: 2e9c2a2381105f1306bcbcb54816cbc5d8110eff
commit: c5df9c829a549ca002c36afd6bdf23639831502e
layers:
meta:
meta-poky:
meta-openembedded:
url: https://git.openembedded.org/meta-openembedded
# commit: 1750c66ae8e4268c472c0b2b94748a59d6ef866d
commit: 6de0ab744341ad61b0661aa28d78dc6767ce0786
layers:
meta-oe:
meta-python:
@@ -31,7 +31,7 @@ repos:
meta-secure-core:
url: https://github.com/wind-river/meta-secure-core.git
# commit: e29165a1031dcf601edbed1733cedd64826672a5
commit: 13cb4867fb1245581c80da3b94b72c4b4f15d67e
layers:
meta-secure-core-common:
meta-signing-key:
-1
View File
@@ -13,7 +13,6 @@ env:
local_conf_header:
testimagefvp: |
LICENSE_FLAGS_ACCEPTED += "Arm-FVP-EULA"
IMAGE_CLASSES += "fvpboot"
mass-storage: |
@@ -1,5 +1,5 @@
..
# Copyright (c) 2022-2023, Arm Limited.
# Copyright (c) 2022-2024, Arm Limited.
#
# SPDX-License-Identifier: MIT
@@ -10,6 +10,78 @@ Change Log
This document contains a summary of the new features, changes and
fixes in each release of Corstone-1000 software stack.
***************
Version 2024.06
***************
Changes
=======
- Re-enabling support for the External System using linux remoteproc (only supporting switching on and off the External System)
- UEFI Secure Boot and Authenticated Variable support
- RSE Comms replaces OpenAMP
- The EFI System partition image is now created by the meta-arm build system.
This image is mounted on the second MMC card by default in the FVP.
- The capsule generation script is now part of the meta-arm build system.
Corstone1000-flash-firmware-image recipe generates a capsule binary using the U-Boot capsule generation tool that includes
all the firmware binaries and recovery kernel image.
- SW components upgrades
- Bug fixes
Corstone-1000 components versions
=================================
+-------------------------------------------+-----------------------------------------------------+
| arm-tstee | 2.0.0 |
+-------------------------------------------+-----------------------------------------------------+
| linux-yocto | 6.6.23 |
+-------------------------------------------+-----------------------------------------------------+
| u-boot | 2023.07.02 |
+-------------------------------------------+-----------------------------------------------------+
| external-system | 0.1.0 |
+-------------------------------------------+-----------------------------------------------------+
| optee-client | 4.1.0 |
+-------------------------------------------+-----------------------------------------------------+
| optee-os | 4.1.0 |
+-------------------------------------------+-----------------------------------------------------+
| trusted-firmware-a | 2.10.4 |
+-------------------------------------------+-----------------------------------------------------+
| trusted-firmware-m | 2.0.0 |
+-------------------------------------------+-----------------------------------------------------+
| libts | 602be60719 |
+-------------------------------------------+-----------------------------------------------------+
| ts-newlib | 4.1.0 |
+-------------------------------------------+-----------------------------------------------------+
| ts-psa-{crypto, iat, its. ps}-api-test | 602be60719 |
+-------------------------------------------+-----------------------------------------------------+
| ts-sp-{se-proxy, smm-gateway} | 602be60719 |
+-------------------------------------------+-----------------------------------------------------+
Yocto distribution components versions
======================================
+-------------------------------------------+------------------------------+
| meta-arm | scarthgap |
+-------------------------------------------+------------------------------+
| poky | scarthgap |
+-------------------------------------------+------------------------------+
| meta-openembedded | scarthgap |
+-------------------------------------------+------------------------------+
| meta-secure-core | scarthgap |
+-------------------------------------------+------------------------------+
| busybox | 1.36.1 |
+-------------------------------------------+------------------------------+
| musl | 1.2.4 |
+-------------------------------------------+------------------------------+
| gcc-arm-none-eabi | 13.2.Rel1 |
+-------------------------------------------+------------------------------+
| gcc-cross-aarch64 | 13.2.0 |
+-------------------------------------------+------------------------------+
| openssl | 3.2.1 |
+-------------------------------------------+------------------------------+
***************
Version 2023.11
***************
@@ -298,4 +370,4 @@ Changes
--------------
*Copyright (c) 2022-2023, Arm Limited. All rights reserved.*
*Copyright (c) 2022-2024, Arm Limited. All rights reserved.*
Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 69 KiB

@@ -1,5 +1,5 @@
..
# Copyright (c) 2022-2023, Arm Limited.
# Copyright (c) 2022-2024, Arm Limited.
#
# SPDX-License-Identifier: MIT
@@ -19,6 +19,25 @@ intended for safety-critical applications. Should Your Software or Your Hardware
prove defective, you assume the entire cost of all necessary servicing, repair
or correction.
***********************
Release notes - 2024.06
***********************
Known Issues or Limitations
---------------------------
- Use Ethernet over VirtIO due to lan91c111 Ethernet driver support dropped from U-Boot.
- Due to the performance uplimit of MPS3 FPGA and FVP, some Linux distros like Fedora Rawhide can not boot on Corstone-1000 (i.e. user may experience timeouts or boot hang).
- Corstone-1000 SoC on FVP doesn't have a secure debug peripheral. It does on the MPS3.
- See previous release notes for the known limitations regarding ACS tests.
Platform Support
-----------------
- This software release is tested on Corstone-1000 FPGA version AN550_v2
https://developer.arm.com/downloads/-/download-fpga-images
- This software release is tested on Corstone-1000 Fast Model platform (FVP) version 11.23_25
https://developer.arm.com/tools-and-software/open-source-software/arm-platforms-software/arm-ecosystem-fvps
***********************
Release notes - 2023.11
***********************
@@ -213,7 +232,7 @@ Support
-------
For technical support email: support-subsystem-iot@arm.com
For all security issues, contact Arm by email at arm-security@arm.com.
For all security issues, contact Arm by email at psirt@arm.com.
--------------
@@ -1,5 +1,5 @@
..
# Copyright (c) 2022-2023, Arm Limited.
# Copyright (c) 2022-2024, Arm Limited.
#
# SPDX-License-Identifier: MIT
@@ -52,7 +52,7 @@ secure flash. Software running on the Secure Enclave is isolated via
hardware for enhanced security. Communication with the Secure Encalve
is achieved using Message Handling Units (MHUs) and shared memory.
On system power on, the Secure Enclave boots first. Its software
comprises of a ROM code (TF-M BL1), Mcuboot BL2, and
comprises of a ROM code (TF-M BL1), MCUboot BL2, and
TrustedFirmware-M(`TF-M`_) as runtime software. The software design on
Secure Enclave follows Firmware Framework for M class
processor (`FF-M`_) specification.
@@ -61,7 +61,7 @@ The Host System is based on ARM Cotex-A35 processor with standardized
peripherals to allow for the booting of a Linux OS. The Cortex-A35 has
the TrustZone technology that allows secure and non-secure security
states in the processor. The software design in the Host System follows
Firmware Framework for A class procseeor (`FF-A`_) specification.
Firmware Framework for A class processor (`FF-A`_) specification.
The boot process follows Trusted Boot Base Requirement (`TBBR`_).
The Host Subsystem is taken out of reset by the Secure Enclave system
during its final stages of the initialization. The Host subsystem runs
@@ -70,12 +70,12 @@ FF-A Secure Partitions(based on `Trusted Services`_) and OPTEE-OS
linux (`linux repo`_) in the non-secure world. The communication between
non-secure and the secure world is performed via FF-A messages.
An external system is intended to implement use-case specific
functionality. The system is based on Cortex-M3 and run RTX RTOS.
Communication between the external system and Host (Cortex-A35) is performed
using MHU as transport mechanism and rpmsg messaging system (the external system
support in Linux is disabled in this release. More info about this change can be found in the
release-notes).
An external system is intended to implement use-case specific functionality.
The system is based on Cortex-M3 and run RTX RTOS. Communication between the
external system and Host (Cortex-A35) can be performed using MHU as transport
mechanism. The current software release supports switching on and off the
external system. Support for OpenAMP-based communication is under
development.
Overall, the Corstone-1000 architecture is designed to cover a range
of Power, Performance, and Area (PPA) applications, and enable extension
@@ -93,30 +93,64 @@ and loads the following software in the chain. For the boot chain
process to work, the start of the chain should be trusted, forming the
Root of Trust (RoT) of the device. The RoT of the device is immutable in
nature and encoded into the device by the device owner before it
is deployed into the field. In Corstone-1000, the BL1 image of the secure
enclave and content of the CC312 OTP (One Time Programmable) memory
forms the RoT. The BL1 image exists in ROM (Read Only Memory).
is deployed into the field. In Corstone-1000, the content of the ROM
and CC312 OTP (One Time Programmable) memory forms the RoT.
Verification of an image can happen either by comparing the computed and
stored hashes, or by checking the signature of the image if the image
is signed.
.. image:: images/SecureBootChain.png
:width: 870
:alt: SecureBootChain
It is a lengthy chain to boot the software on Corstone-1000. On power on,
the secure enclave starts executing BL1 code from the ROM which is the RoT
of the device. Authentication of an image involves the steps listed below:
the Secure Enclave starts executing BL1_1 code from the ROM which is the RoT
of the device. The BL1_1 is the immutable bootloader of the system, it handles
the provisioning on the first boot, hardware initialization and verification
of the next stage.
- Load image from flash to dynamic RAM.
The BL1_2 code, hashes and keys are written into the OTP during the provisioning.
The next bootstage is the BL1_2 which is copied from the OTP into the RAM. The
BL1_1 also compares the BL1_2 hash with the hash saved to the OTP. The BL1_2
verifies and transfers control to the next bootstage which is the BL2. During the
verification, the BL1_2 compares the BL2 image's computed hash with the BL2 hash in
the OTP. The BL2 is MCUBoot in the system. BL2 can provision additional keys on the
first boot and it authenticates the initial bootloader of the host (Host TF-A BL2)
and TF-M by checking the signatures of the images.
The MCUBoot handles the image verification the following way:
- Load image from a non-volatile memory to dynamic RAM.
- The public key present in the image header is validated by comparing with the hash.
Depending on the image, the hash of the public key is either stored in the OTP or part
of the software which is being already verified in the previous stages.
- The image is validated using the public key.
In the secure enclave, BL1 authenticates the BL2 and passes the execution
control. BL2 authenticates the initial boot loader of the host (Host TF-A BL2)
and TF-M. The execution control is now passed to TF-M. TF-M being the run
time executable of secure enclave which initializes itself and, at the end,
brings the host CPU out of rest. The host follows the boot standard defined
in the `TBBR`_ to authenticate the secure and non-secure software.
The execution control is passed to TF-M after the verification. TF-M being
the runtime executable of the Secure Enclave which initializes itself and, at the end,
brings the host CPU out of rest.
The TF-M BL1 design details and reasoning can be found in the `TF-M design documents
<https://tf-m-user-guide.trustedfirmware.org/design_docs/booting/bl1.html>`_.
The Corstone-1000 has some differences compared to this design due to memory (OTP/ROM)
limitations:
- The provisioning bundle that contains the BL1_2 code is located in the ROM.
This means the BL1_2 cannot be updated during provisioning time.
- The BL1_1 handles most of the hardware initialization instead of the BL1_2. This
results in a bigger BL1_1 code size than needed.
- The BL1_2 does not use the post-quantum LMS verification. The BL2 is verified by
comparing the computed hash to the hash which is stored in the OTP. This means the
BL2 is not updatable.
The host follows the boot standard defined in the `TBBR`_ to authenticate the
secure and non-secure software.
For UEFI Secure Boot, authenticated variables can be accessed from the secure flash.
The feature has been integrated in U-Boot, which authenticates the images as per the UEFI
specification before executing them.
***************
Secure Services
@@ -124,11 +158,11 @@ Secure Services
Corstone-1000 is unique in providing a secure environment to run a secure
workload. The platform has TrustZone technology in the Host subsystem but
it also has hardware isolated secure enclave environment to run such secure
it also has hardware isolated Secure Enclave environment to run such secure
workloads. In Corstone-1000, known Secure Services such as Crypto, Protected
Storage, Internal Trusted Storage and Attestation are available via PSA
Functional APIs in TF-M. There is no difference for a user communicating to
these services which are running on a secure enclave instead of the
these services which are running on a Secure Enclave instead of the
secure world of the host subsystem. The below diagram presents the data
flow path for such calls.
@@ -139,7 +173,7 @@ flow path for such calls.
The SE Proxy SP (Secure Enclave Proxy Secure Partition) is a proxy partition
managed by OPTEE which forwards such calls to the secure enclave. The
managed by OPTEE which forwards such calls to the Secure Enclave. The
solution relies on the `RSE communication protocol
<https://tf-m-user-guide.trustedfirmware.org/platform/arm/rse/rse_comms.html>`_
which is a lightweight serialization of the psa_call() API. It can use shared
@@ -150,7 +184,7 @@ Unit) is used to implement isolation level 2.
For a user to define its own secure service, both the options of the host
secure world or secure encalve are available. It's a trade-off between
lower latency vs higher security. Services running on a secure enclave are
lower latency vs higher security. Services running on a Secure Enclave are
secure by real hardware isolation but have a higher latency path. In the
second scenario, the services running on the secure world of the host
subsystem have lower latency but virtual hardware isolation created by
@@ -177,7 +211,7 @@ Image (the initramfs bundle). The new images are accepted in the form of a UEFI
:width: 690
:alt: ExternalFlash
When Firmware update is triggered, u-boot verifies the capsule by checking the
When Firmware update is triggered, U-Boot verifies the capsule by checking the
capsule signature, version number and size. Then it signals the Secure Enclave
that can start writing UEFI capsule into the flash. Once this operation finishes
,Secure Enclave resets the entire system.
@@ -213,7 +247,7 @@ service. The below diagram presents the data flow to store UEFI variables.
The U-Boot implementation of the UEFI subsystem uses the U-Boot FF-A driver to
communicate with the SMM Service in the secure world. The backend of the
SMM service uses the proxy PS from the SE Proxy SP. From there on, the PS
calls are forwarded to the secure enclave as explained above.
calls are forwarded to the Secure Enclave as explained above.
.. image:: images/UEFISupport.png
@@ -3,9 +3,9 @@
#
# SPDX-License-Identifier: MIT
##########
User Guide
##########
#####################################
User Guide: Build & run the software
#####################################
Notice
------
@@ -43,7 +43,7 @@ Targets
Yocto stable branch
-------------------
Corstone-1000 software stack is built on top of Yocto mickledore.
Corstone-1000 software stack is built on top of Yocto scarthgap.
Provided components
-------------------
@@ -71,7 +71,7 @@ Based on `Trusted Firmware-A <https://git.trustedfirmware.org/TF-A/trusted-firmw
+----------+-------------------------------------------------------------------------------------------------+
| bbappend | <_workspace>/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a_%.bbappend |
+----------+-------------------------------------------------------------------------------------------------+
| Recipe | <_workspace>/meta-arm/meta-arm/recipes-bsp/trusted-firmware-a/trusted-firmware-a_2.9.0.bb |
| Recipe | <_workspace>/meta-arm/meta-arm/recipes-bsp/trusted-firmware-a/trusted-firmware-a_2.10.4.bb |
+----------+-------------------------------------------------------------------------------------------------+
OP-TEE
@@ -79,9 +79,9 @@ OP-TEE
Based on `OP-TEE <https://git.trustedfirmware.org/OP-TEE/optee_os.git>`__
+----------+----------------------------------------------------------------------------------------+
| bbappend | <_workspace>/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.22.0.bbappend |
| bbappend | <_workspace>/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_4.%.bbappend |
+----------+----------------------------------------------------------------------------------------+
| Recipe | <_workspace>/meta-arm/meta-arm-bsp/recipes-security/optee/optee-os_3.22.0.bb |
| Recipe |<_workspace>/meta-arm/meta-arm/recipes-security/optee/optee-os_4.1.0.bb |
+----------+----------------------------------------------------------------------------------------+
U-Boot
@@ -107,7 +107,7 @@ recipe responsible for building a tiny version of Linux is listed below.
+-----------+----------------------------------------------------------------------------------------------+
| bbappend | <_workspace>/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-yocto_%.bbappend |
+-----------+----------------------------------------------------------------------------------------------+
| Recipe | <_workspace>/poky/meta/recipes-kernel/linux/linux-yocto_6.5.bb |
| Recipe | <_workspace>/poky/meta/recipes-kernel/linux/linux-yocto_6.6.bb |
+-----------+----------------------------------------------------------------------------------------------+
| defconfig | <_workspace>/meta-arm/meta-arm-bsp/recipes-kernel/linux/files/corstone1000/defconfig |
+-----------+----------------------------------------------------------------------------------------------+
@@ -120,7 +120,7 @@ Based on `Trusted Firmware-M <https://git.trustedfirmware.org/TF-M/trusted-firmw
+----------+-----------------------------------------------------------------------------------------------------+
| bbappend | <_workspace>/meta-arm/meta-arm-bsp/recipes-bsp/trusted-firmware-m/trusted-firmware-m_%.bbappend |
+----------+-----------------------------------------------------------------------------------------------------+
| Recipe | <_workspace>/meta-arm/meta-arm/recipes-bsp/trusted-firmware-m/trusted-firmware-m_1.8.1.bb |
| Recipe | <_workspace>/meta-arm/meta-arm/recipes-bsp/trusted-firmware-m/trusted-firmware-m_2.0.0.bb |
+----------+-----------------------------------------------------------------------------------------------------+
********************************
@@ -158,7 +158,7 @@ In the top directory of the workspace ``<_workspace>``, run:
::
git clone https://git.yoctoproject.org/git/meta-arm -b CORSTONE1000-2023.11
git clone https://git.yoctoproject.org/git/meta-arm -b CORSTONE1000-2024.06
To build a Corstone-1000 image for MPS3 FPGA, run:
@@ -364,6 +364,22 @@ The host will boot trusted-firmware-a, OP-TEE, U-Boot and then Linux, and presen
Login using the username root.
Using FVP on Windows or AArch64 Linux
-------------------------------------
The user should follow the build instructions in this document to build on a Linux host machine.
Then, copy the output binaries to the Windows or Aarch64 Linux machine where the FVP is located.
Then, launch the FVP binary.
Security Issue Reporting
------------------------
To report any security issues identified with Corstone-1000, please send an email to psirt@arm.com.
###########################
User Guide: Provided tests
###########################
SystemReady-IR tests
--------------------
@@ -396,6 +412,7 @@ running the ACS tests.
**Common to FVP and FPGA:**
::
kas build meta-arm/kas/corstone1000-{mps3,fvp}.yml:meta-arm/ci/debug.yml --target corstone1000-esp-image
Once the build is successful ``corstone1000-esp-image-corstone1000-{mps3,fvp}.wic`` will be available in either:
@@ -411,16 +428,15 @@ confirm). Be cautious here and don't confuse your host machine own hard drive wi
USB drive. Run the following commands to prepare the ACS image in USB stick:
::
sudo dd if=corstone1000-esp-image-corstone1000-mps3.wic of=/dev/sdb iflag=direct oflag=direct status=progress bs=512; sync;
Now you can plug this USB stick to the board together with ACS test USB stick.
**Using ESP in FVP:**
The ESP disk image once created will be used automatically in the Corstone-1000 FVP as the 2nd MMC card image.
The ESP disk image once created will be used automatically in the Corstone-1000 FVP as the 2nd MMC card image. It will be used when the SystemReady-IR tests will be performed on the FVP in the later section.
::
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml -c "../meta-arm/scripts/runfvp -- -C board.msd_mmc.p_mmc_file="${<path-to-img>/ir_acs_live_image.img}"
Clean Secure Flash Before Testing (applicable to FPGA only)
===========================================================
@@ -432,8 +448,8 @@ boot. Run following commands to build such image.
::
cd <_workspace>
git clone https://git.yoctoproject.org/git/meta-arm -b CORSTONE1000-2023.11
git clone https://git.gitlab.arm.com/arm-reference-solutions/systemready-patch.git -b CORSTONE1000-2023.11
git clone https://git.yoctoproject.org/git/meta-arm -b CORSTONE1000-2024.06
git clone https://git.gitlab.arm.com/arm-reference-solutions/systemready-patch.git -b CORSTONE1000-2024.06
cp -f systemready-patch/embedded-a/corstone1000/erase_flash/0001-embedded-a-corstone1000-clean-secure-flash.patch meta-arm
cd meta-arm
git apply 0001-embedded-a-corstone1000-clean-secure-flash.patch
@@ -466,7 +482,7 @@ includes a set of examples of the invariant behaviors that are provided by a
set of specifications for enterprise systems (For example: SBSA, SBBR, etc.),
so that implementers can verify if these behaviours have been interpreted correctly.
ACS image contains two partitions. BOOT partition and RESULT partition.
The ACS image contains a BOOT partition.
Following test suites and bootable applications are under BOOT partition:
* SCT
@@ -492,11 +508,14 @@ BOOT partition contains the following:
├── grub
├── grub.cfg
├── Image
── ramdisk-busybox.img
── ramdisk-busybox.img
└── acs_results
RESULT partition is used to store the test results.
**NOTE**: PLEASE MAKE SURE THAT "acs_results" FOLDER UNDER THE RESULT PARTITION IS EMPTY BEFORE YOU START THE TESTING. OTHERWISE THE TEST RESULTS
WILL NOT BE CONSISTENT
The BOOT partition is also used to store the test results. The
results are stored in the `acs_results` folder.
**NOTE**: PLEASE ENSURE THAT the `acs_results` FOLDER UNDER THE BOOT PARTITION IS
EMPTY BEFORE YOU START TESTING. OTHERWISE THE TEST RESULTS WILL NOT BE CONSISTENT.
FPGA instructions for ACS image
===============================
@@ -515,7 +534,7 @@ certifications of SystemReady-IR. To download the repository, run command:
git clone https://github.com/ARM-software/arm-systemready.git
Once the repository is successfully downloaded, the prebuilt ACS live image can be found in:
- ``<_workspace>/arm-systemready/IR/prebuilt_images/v23.03_2.0.0/ir-acs-live-image-generic-arm64.wic.xz``
- ``<_workspace>/arm-systemready/IR/prebuilt_images/v23.09_2.1.0/ir-acs-live-image-generic-arm64.wic.xz``
**NOTE**: This prebuilt ACS image includes v5.13 kernel, which doesn't provide
USB driver support for Corstone-1000. The ACS image with newer kernel version
@@ -529,7 +548,7 @@ USB drive. Run the following commands to prepare the ACS image in USB stick:
::
cd <_workspace>/arm-systemready/IR/prebuilt_images/v23.03_2.0.0
cd <_workspace>/arm-systemready/IR/prebuilt_images/v23.09_2.1.0
unxz ir-acs-live-image-generic-arm64.wic.xz
sudo dd if=ir-acs-live-image-generic-arm64.wic of=/dev/sdb iflag=direct oflag=direct bs=1M status=progress; sync
@@ -549,6 +568,7 @@ FVP instructions for ACS image and run
======================================
The FVP has been integrated in the meta-arm-systemready layer so the running of the ACS tests can be handled automatically as follows
::
kas build meta-arm/ci/corstone1000-fvp.yml:meta-arm/ci/debug.yml:kas/arm-systemready-ir-acs.yml
@@ -559,19 +579,6 @@ The details of how this layer works can be found in : ``<_workspace>/meta-arm-sy
**NOTE:** These test might take up to 1 day to finish
**NOTE:** A rare issue has been noticed (5-6% occurence) during which the FVP hangs during booting the system while running ACS tests.
If this happens, please apply the following patch, rebuild the software stack for FVP and re-run the ACS tests.
::
cd <_workspace>
git clone https://git.gitlab.arm.com/arm-reference-solutions/systemready-patch.git -b CORSTONE1000-2023.11
cp -f systemready-patch/embedded-a/corstone1000/sr_ir_workaround/0001-embedded-a-corstone1000-sr-ir-workaround.patch meta-arm
cd meta-arm
git am 0001-embedded-a-corstone1000-sr-ir-workaround.patch
cd ..
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml -c "bitbake u-boot -c cleanall; bitbake trusted-firmware-a -c cleanall; bitbake corstone1000-flash-firmware-image -c cleanall; bitbake corstone1000-flash-firmware-image"
Common to FVP and FPGA
======================
@@ -584,85 +591,70 @@ automatically in the following sequence:
- UEFI BSA
- FWTS
The results can be fetched from the ``acs_results`` folder in the RESULT partition of the USB stick (FPGA) / SD Card (FVP).
The results can be fetched from the `acs_results` folder in the BOOT partition of the USB stick (FPGA) / SD Card (FVP).
**NOTE:** The FVP uses the ``<_workspace>/build/tmp-glibc/work/corstone1000_fvp-oe-linux/arm-systemready-ir-acs/2.0.0/deploy-arm-systemready-ir-acs/arm-systemready-ir-acs-corstone1000-fvp.wic`` image if the meta-arm-systemready layer is used.
The result can be checked in this image.
#####################################################
Manual capsule update and ESRT checks
-------------------------------------
The following section describes running manual capsule update.
The following section describes running manual capsule updates by going through
a negative and positive test. Two capsules are needed to perform the positive
and negative updates. The steps also show how to use the EFI System Resource Table
(ESRT) to retrieve the installed capsule details.
The steps described in this section perform manual capsule update and show how to use the ESRT feature
to retrieve the installed capsule details.
In the positive test, a valid capsule is used and the platform boots correctly
until the Linux prompt after the update. In the negative test, an outdated
capsule is used that has a smaller version number. This capsule gets rejected
because of being outdated and the previous firmware will be used instead.
For the following tests two capsules are needed to perform 2 capsule updates. A positive update and a negative update.
A positive test case capsule which boots the platform correctly until the Linux prompt, and a negative test case with an
incorrect capsule (corrupted or outdated) which fails to boot to the host software.
Check the "Run SystemReady-IR ACS tests" section above to download and unpack the ACS image file
- ``ir-acs-live-image-generic-arm64.wic.xz``
Download systemready-patch repo under <_workspace>:
::
git clone https://git.gitlab.arm.com/arm-reference-solutions/systemready-patch.git -b CORSTONE1000-2023.11
*******************
Generating Capsules
*******************
A no-partition image is created during the Yocto build. An update capsule is generated using this ``.nopt`` image.
This can be found in ``build/tmp_corstone1000-<fvp/mps3>/deploy/images/corstone1000-<fvp/mps3>/corstone1000-<fvp/mps3>_image.nopt``.
The capsule's default metadata (name, version, etc.) can be found in ``meta-arm/meta-arm-bsp/recipes-bsp/images/corstone1000-flash-firmware-image.bb``
and ``meta-arm/kas/corstone1000-image-configuration.yml``.
A no-partition image is needed for the capsule generation. This image is
created automatically during a clean Yocto build and it can be found in
``build/tmp/deploy/images/corstone1000-<fvp/mps3>/corstone1000-<fvp/mps3>_image.nopt``.
A capsule is also automatically generated with U-Boot's ``mkeficapsule`` tool
during the Yocto build that uses this ``corstone1000-<fvp/mps3>_image.nopt``. The
capsule's default metadata, that is passed to the ``mkeficapsule`` tool,
can be found in the ``meta-arm/meta-arm-bsp/recipes-bsp/images/corstone1000-flash-firmware-image.bb``
and ``meta-arm/kas/corstone1000-image-configuration.yml`` files. These
data can be modified before the Yocto build if it is needed. It is
assumed that the default values are used in the following steps.
FPGA Capsules
=============
The automatically generated capsule can be found in
``build/tmp/deploy/images/corstone1000-<fvp/mps3>/corstone1000-<fvp/mps3>-v6.uefi.capsule``.
This capsule will be used as the positive capsule during the test in the following
steps.
The generated capsule can be found in ``build/tmp_corstone1000-mps3/deploy/images/corstone1000-mps3/corstone1000-mps3-v6.uefi.capsule``.
If a new capsule has to be generated with different metadata, then it can be done by using the ``u-boot-tools`` and the previously
created ``.nopt`` image.
Generating Capsules Manually
============================
If a new capsule has to be generated with different metadata after the build
process, then it can be done manually by using the ``u-boot-tools``'s
``mkeficapsule`` and the previously created ``.nopt`` image. The
``mkeficapsule`` tool is built automatically for the host machine
during the Yocto build.
The negative capsule needs a lower ``fw-version`` than the positive
capsule. For example if the host's architecture is x86_64, this can
be generated by using the following command:
For example a capsule for the negative update test scenario, if the host's architecture is x86_64:
::
cd <_workspace>
./build/tmp/sysroots-components/x86_64/u-boot-tools-native/usr/bin/mkeficapsule --monotonic-count 1 \
--private-key build/tmp/deploy/images/corstone1000-mps3/corstone1000_capsule_key.key \
--certificate build/tmp/deploy/images/corstone1000-mps3/corstone1000_capsule_cert.crt --index 1 --guid df1865d1-90fb-4d59-9c38-c9f2c1bba8cc \
--fw-version 5 build/tmp_corstone1000-mps3/deploy/images/corstone1000-mps3/corstone1000-mps3_image.nopt corstone1000-mps3-v5.uefi.capsule
--private-key build/tmp/deploy/images/corstone1000-<fvp/mps3>/corstone1000_capsule_key.key \
--certificate build/tmp/deploy/images/corstone1000-<fvp/mps3>/corstone1000_capsule_cert.crt --index 1 --guid df1865d1-90fb-4d59-9c38-c9f2c1bba8cc \
--fw-version 5 build/tmp/deploy/images/corstone1000-<fvp/mps3>/corstone1000-<fvp/mps3>_image.nopt corstone1000-<fvp/mps3>-v5.uefi.capsule
This command will put the newly generated capsule to the ``<_workspace>`` directory.
Generating FVP Capsules
=======================
The generated capsule can be found in ``build/tmp_corstone1000-fvp/deploy/images/corstone1000-fvp/corstone1000-fvp-v6.uefi.capsule``.
If a new capsule has to be generated with different metadata, then it can be done by using the ``u-boot-tools`` and the previously
created ``.nopt`` image.
For example a capsule for the negative update test scenario, if the host's architecture is x86_64:
::
cd <_workspace>
./build/tmp/sysroots-components/x86_64/u-boot-tools-native/usr/bin/mkeficapsule --monotonic-count 1 \
--private-key build/tmp/deploy/images/corstone1000-fvp/corstone1000_capsule_key.key \
--certificate build/tmp/deploy/images/corstone1000-fvp/corstone1000_capsule_cert.crt --index 1 --guid 989f3a4e-46e0-4cd0-9877-a25c70c01329 \
--fw-version 5 build/tmp_corstone1000-fvp/deploy/images/corstone1000-fvp/corstone1000-fvp_image.nopt corstone1000-fvp-v5.uefi.capsule
This command will put the newly generated capsule to the ``<_workspace>`` directory.
Common Notes for FVP and FPGA
=============================
The capsule binary size (wic file) should be less than 15 MB.
Based on the user's requirement, the user can change the firmware version
number given to ``--fw-version`` option (the version number needs to be >= 1).
This command will put the negative capsule to the ``<_workspace>`` directory.
****************
@@ -687,19 +679,26 @@ the on disk method.
Copying the FVP capsules
========================
First, Find the 1st partition offset:
The ACS image should be used for the FVP as well. Downloaded and extract the
image the same way as for the FPGA `FPGA instructions for ACS image`_.
Creating an USB stick with the image is not needed for the FVP.
After getting the ACS image, find the 1st partition's offset of the
``ir-acs-live-image-generic-arm64.wic`` image. The partition table can be
listed using the ``fdisk`` tool.
::
fdisk -lu <path-to-img>/ir-acs-live-image-generic-arm64.wic
-> Device Start End Sectors Size Type
<path-to-img>/ir-acs-live-image-generic-arm64.wic1 2048 206847 204800 100M Microsoft basic data
<path-to-img>/ir-acs-live-image-generic-arm64.wic2 206848 1024239 817392 399.1M Linux filesystem
<path-to-img>/ir-acs-live-image-generic-arm64.wic3 1026048 1128447 102400 50M Microsoft basic data
Device Start End Sectors Size Type
<path-to-img>/ir-acs-live-image-generic-arm64.wic1 2048 309247 307200 150M Microsoft basic data
<path-to-img>/ir-acs-live-image-generic-arm64.wic2 309248 1343339 1034092 505M Linux filesystem
-> <offset_3rd_partition> = 2048 * 512 (sector size) = 1048576
Next, mount the IR image:
The first partition starts at the 2048th sector. This has to be multiplied
by the sector size which is 512 so the offset is 2048 * 512 = 1048576.
Next, mount the IR image using the previously calculated offset:
::
@@ -724,13 +723,17 @@ Then, unmount the IR image:
Performing the capsule update
******************************
During this section we will be using the capsule with the higher version (``corstone1000-<fvp/mps3>-v6.uefi.capsule``) for the positive scenario
and the capsule with the lower version (``corstone1000-<fvp/mps3>-v5.uefi.capsule``) for the negative scenario.
During this section we will be using the capsule with the higher version
(``corstone1000-<fvp/mps3>-v6.uefi.capsule``) for the positive scenario
and then the capsule with the lower version (``corstone1000-<fvp/mps3>-v5.uefi.capsule``)
for the negative scenario. The two tests have to be done after each other
in the correct order to make sure that the negative capsule will get rejected.
Running the FPGA with the IR prebuilt image
===========================================
Insert the prepared USB stick then Power cycle the MPS3 board.
Insert the prepared USB stick which has the IR prebuilt image and two capsules,
then Power cycle the MPS3 board.
Running the FVP with the IR prebuilt image
==========================================
@@ -742,11 +745,14 @@ Run the FVP with the IR prebuilt image:
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml -c "../meta-arm/scripts/runfvp --terminals=xterm -- -C board.msd_mmc.p_mmc_file=<path-to-img>/ir-acs-live-image-generic-arm64.wic"
**NOTE:** <path-to-img> must start from the root directory. make sure there are no spaces before or after of "=". board.msd_mmc.p_mmc_file=<path-to-img>/ir-acs-live-image-generic-arm64.wic.
**NOTE:** Do not restart the FVP between the positive and negative test because it will start from a clean state.
Executing capsule update for FVP and FPGA
=========================================
Reach u-boot then interrupt the boot to reach the EFI shell.
Wait until U-boot loads EFI from the ACS image stick and interrupt the EFI
shell by pressing ESC when the following prompt is displayed in the Host
terminal (ttyUSB2).
::
@@ -758,15 +764,26 @@ Then, type FS0: as shown below:
FS0:
In case of the positive scenario run the update with the higher version capsule as shown below:
Then start the CapsuleApp application. Use the positive capsule
(corstone1000-<fvp/mps3>-v6.uefi.capsule) first.
::
EFI/BOOT/app/CapsuleApp.efi corstone1000-<fvp/mps3>-v6.uefi.capsule
After successfully updating the capsule the system will reset.
The capsule update will be started.
In case of the negative scenario run the update with the lower version capsule as shown below:
**NOTE:** On the FVP it takes around 15-30 minutes, on the FPGA it takes less time.
After successfully updating the capsule the system will reset. Make sure the
Corstone-1000's Poky Distro is booted after the reset so the ESRT can be checked.
It is described in the `Select Corstone-1000 Linux kernel boot`_ section how to
boot the Poky distro after the capsule update.
The `Positive scenario`_ sections describes how the result should be inspected.
After the result is checked, the system can be rebooted with the ``reboot`` command in the Host
terminal (ttyUSB2).
Interrupt the EFI shell again and now start the capsule update with the negative capsule:
::
@@ -784,17 +801,14 @@ Then, reboot manually:
Shell> reset
FPGA: Select Corstone-1000 Linux kernel boot
============================================
Make sure the Corstone-1000's Poky Distro is booted again
(`Select Corstone-1000 Linux kernel boot`_) in order to check the results
`Negative scenario`_.
Remove the USB stick before u-boot is reached so the Corstone-1000 kernel will be detected and used for booting.
Select Corstone-1000 Linux kernel boot
======================================
**NOTE:** Otherwise, the execution ends up in the ACS live image.
FVP: Select Corstone-1000 Linux kernel boot
===========================================
Interrupt the u-boot shell.
Interrupt the U-Boot shell.
::
@@ -818,9 +832,12 @@ Capsule update status
Positive scenario
=================
In the positive case scenario, the user should see following log in TF-M log,
indicating the new capsule image is successfully applied, and the board boots
correctly.
In the positive case scenario, the software stack copies the capsule to the
External Flash, which is shared between the Secure Enclave and Host,
then a reboot is triggered. The TF-M accepts the capsule.
The user should see following TF-M log in the Secure Enclave terminal (ttyUSB1)
before the system reboots automatically, indicating the new capsule
image is successfully applied, and the board boots correctly.
::
@@ -834,6 +851,18 @@ correctly.
corstone1000_fwu_flash_image: exit: ret = 0
...
And after the reboot:
::
...
fmp_set_image_info:133 Enter
FMP image update: image id = 0
FMP image update: status = 0version=6 last_attempt_version=6.
fmp_set_image_info:157 Exit.
corstone1000_fwu_host_ack: exit: ret = 0
...
It's possible to check the content of the ESRT table after the system fully boots.
@@ -862,11 +891,14 @@ In the Linux command-line run the following:
lowest_supported_fw_ver: 0
Negative scenario (Applicable to FPGA only)
===========================================
Negative scenario
=================
In the negative case scenario (rollback the capsule version), the user should
see appropriate logs in the secure enclave terminal.
In the negative case scenario (rollback the capsule version),
the TF-M detects that the new capsule's version number is
smaller then the current version. The capsule is rejected because
of this.
The user should see appropriate logs in the Secure Enclave terminal (ttyUSB1) before the system reboots itself.
::
@@ -890,7 +922,7 @@ see appropriate logs in the secure enclave terminal.
If capsule pass initial verification, but fails verifications performed during
boot time, secure enclave will try new images predetermined number of times
boot time, Secure Enclave will try new images predetermined number of times
(defined in the code), before reverting back to the previous good bank.
::
@@ -926,11 +958,6 @@ In the Linux command-line run the following:
last_attempt_version: 5
lowest_supported_fw_ver: 0
**Note**: This test is currently not working properly in Corstone-1000 FVP.
However, it is not part of the System-Ready IR tests, and it won't affect the
SR-IR certification. All the compulsory `capsule update tests for SR-IR
<https://developer.arm.com/documentation/DUI1101/2-1/Test-SystemReady-IR/Test-UpdateCapsule>`__
works on both Corstone-1000 FVP and FPGA.
Linux distros tests
-------------------
@@ -944,7 +971,7 @@ provided with the Debian installer image (see below). This bug causes a fatal
error when attempting to boot media installer for Debian, and it resets the platform before installation starts.
A patch to be applied to the Corstone-1000 stack (only applicable when
installing Debian) is provided to
`Skip the Shim <https://gitlab.arm.com/arm-reference-solutions/systemready-patch/-/blob/CORSTONE1000-2023.11/embedded-a/corstone1000/shim/0001-arm-bsp-u-boot-corstone1000-Skip-the-shim-by-booting.patch>`__.
`Skip the Shim <https://gitlab.arm.com/arm-reference-solutions/systemready-patch/-/blob/CORSTONE1000-2024.06/embedded-a/corstone1000/shim/0001-arm-bsp-u-boot-corstone1000-Skip-the-shim-by-booting.patch>`__.
This patch makes U-Boot automatically bypass the Shim and run grub and allows
the user to proceed with a normal installation. If at the moment of reading this
document the problem is solved in the Shim, the user is encouraged to try the
@@ -956,18 +983,20 @@ documentation.
::
cd <_workspace>
git clone https://git.gitlab.arm.com/arm-reference-solutions/systemready-patch.git -b CORSTONE1000-2023.11
git clone https://git.gitlab.arm.com/arm-reference-solutions/systemready-patch.git -b CORSTONE1000-2024.06
cp -f systemready-patch/embedded-a/corstone1000/shim/0001-arm-bsp-u-boot-corstone1000-Skip-the-shim-by-booting.patch meta-arm
cd meta-arm
git am 0001-arm-bsp-u-boot-corstone1000-Skip-the-shim-by-booting.patch
cd ..
**On FPGA**
::
kas shell meta-arm/kas/corstone1000-mps3.yml:meta-arm/ci/debug.yml -c="bitbake u-boot trusted-firmware-a corstone1000-flash-firmware-image -c cleansstate; bitbake corstone1000-flash-firmware-image"
**On FVP**
::
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml -c="bitbake u-boot trusted-firmware-a corstone1000-flash-firmware-image -c cleansstate; bitbake corstone1000-flash-firmware-image"
@@ -988,8 +1017,8 @@ Preparing the Installation Media
*************************************************
Download one of following Linux distro images:
- `Debian installer image <https://cdimage.debian.org/debian-cd/current/arm64/iso-dvd/>`__ (Tested on: debian-12.2.0-arm64-DVD-1.iso)
- `OpenSUSE Tumbleweed installer image <http://download.opensuse.org/ports/aarch64/tumbleweed/iso/>`__ (Tested on: openSUSE-Tumbleweed-DVD-aarch64-Snapshot20231120-Media.iso)
- `Debian installer image <https://cdimage.debian.org/mirror/cdimage/archive/12.4.0/arm64/iso-dvd/>`__
- `OpenSUSE Tumbleweed installer image <http://download.opensuse.org/ports/aarch64/tumbleweed/iso/>`__ (Tested on: openSUSE-Tumbleweed-DVD-aarch64-Snapshot20240516-Media.iso)
**NOTE:** For OpenSUSE Tumbleweed, the user should look for a DVD Snapshot like
openSUSE-Tumbleweed-DVD-aarch64-Snapshot<date>-Media.iso
@@ -1024,9 +1053,9 @@ With a minimum size of 8GB formatted with gpt.
::
#Generating mmc2
dd if=/dev/zero of=<_workspace>/mmc2_file.img bs=1 count=0 seek=8G; sync;
parted -s mmc2_file.img mklabel gpt
#Generating os_file
dd if=/dev/zero of=<_workspace>/os_file.img bs=1 count=0 seek=10G; sync;
parted -s os_file.img mklabel gpt
*************************************************
@@ -1058,10 +1087,10 @@ FVP
::
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml -c "../meta-arm/scripts/runfvp --terminals=xterm -- -C board.msd_mmc.p_mmc_file="<path-to-iso_file>" -C board.msd_mmc_2.p_mmc_file="<_workspace>/mmc2_file.img"
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml -c "../meta-arm/scripts/runfvp --terminals=xterm -- -C board.msd_mmc.p_mmc_file=<_workspace>/os_file.img -C board.msd_mmc_2.p_mmc_file=<path-to-iso_file>"
The installer should now start.
The os will be installed on the second mmc 'mmc2_file.img'.
The OS will be installed on 'os_file.img'.
*******************************************************
Debian install clarifications
@@ -1114,17 +1143,22 @@ after entering the password for the root user.
FVP
==============
Once the installation is complete, you will need to exit the shell instance
and run this command to boot into the installed OS:
The platform should automatically boot into the installed OS image.
::
To cold boot:
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml -c "../meta-arm/scripts/runfvp --terminals=xterm -- -C board.msd_mmc.p_mmc_file="<path-to-iso_file>" -C board.msd_mmc.p_mmc_file="<_workspace>/mmc2_file.img"
::
Once the FVP begins booting, you will need to quickly change the boot option in grub,
to boot into recovery mode.
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml -c "../meta-arm/scripts/runfvp --terminals=xterm -- -C board.msd_mmc.p_mmc_file=<_workspace>/os_file.img"
**NOTE:** This option will disappear quickly, so it's best to preempt it.
The board will then enter recovery mode, from which the user can access a shell
after entering the password for the root user.
**NOTE:** To manually enter recovery mode, once the FVP begins booting, you can quickly
change the boot option in grub, to boot into recovery mode. This option will disappear
quickly, so it's best to preempt it.
Select 'Advanced Options for '<OS>' and then '<OS> (recovery mode)'.
@@ -1196,7 +1230,7 @@ First, load FF-A TEE kernel module:
::
insmod /lib/modules/6.1.32-yocto-standard/extra/arm-tstee.ko
insmod /lib/modules/*-yocto-standard/updates/arm-tstee.ko
Then, check whether the FF-A TEE driver is loaded correctly by using the following command:
@@ -1204,7 +1238,7 @@ Then, check whether the FF-A TEE driver is loaded correctly by using the followi
cat /proc/modules | grep arm_tstee
The output should be:
The output should be similar to:
::
@@ -1219,22 +1253,216 @@ Now, run the PSA API tests in the following order:
psa-its-api-test
psa-ps-api-test
**NOTE:** The psa-crypto-api-test takes between 30 minutes to 1 hour to run.
UEFI Secureboot (SB) test
-------------------------
Before running the SB test, the user should make sure that the `FVP and FPGA software has been compiled and the ESP image for both the FVP and FPGA has been created` as mentioned in the previous sections and user should use the same workspace directory under which sources have been compiled.
The SB test is applicable on both the FVP and the FPGA and this involves testing both the signed and unsigned kernel images. Successful test results in executing the signed image correctly and not allowing the unsigned image to run at all.
***********************************************************
Below steps are applicable to FVP as well as FPGA
***********************************************************
Firstly, the flash firmware image has to be built for both the FVP and FPGA as follows:
For FVP,
::
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml -c bitbake -c build corstone1000-flash-firmware-image"
For FPGA,
::
kas shell meta-arm/kas/corstone1000-mps3.yml:meta-arm/ci/debug.yml -c bitbake -c build corstone1000-flash-firmware-image"
In order to test SB for FVP and FPGA, a bash script is available in the systemready-patch repo which is responsible in creating the relevant keys, sign the respective kernel images, and copy the same in their corresponding ESP images.
Clone the systemready-patch repo under <_workspace. Then, change directory to where the script `create_keys_and_sign.sh` is and execute the script as follows:
::
git clone https://git.gitlab.arm.com/arm-reference-solutions/systemready-patch.git -b CORSTONE1000-2024.06
cd systemready-patch/embedded-a/corstone1000/secureboot/
**NOTE:** The efitools package is required to execute the script. Install the efitools package on your system, if it doesn't exist.
The script is responsible to create the required UEFI secureboot keys, sign the kernel images and copy the public keys and the kernel images (both signed and unsigned) to the ESP image for both the FVP and FPGA.
::
./create_keys_and_sign.sh -w <Absolute path to <workdir> directory under which sources have been compiled> -v <certification validity in days>
For ex: ./create_keys_and_sign.sh -w "/home/xyz/workspace/meta-arm" -v 365
For help: ./create_keys_and_sign.sh -h
**NOTE:** The above script is interactive and contains some commands that would require sudo password/permissions.
After executing the above script, the relevant keys and the signed/unsigned kernel images will be copied to the ESP images for both the FVP and FGPA. The modified ESP images can be found at the same location i.e.
::
For MPS3 FPGA : _workspace/meta-arm/build/tmp/deploy/images/corstone1000-mps3/corstone1000-esp-image-corstone1000-mps3.wic
For FVP : _workspace/meta-arm/build/tmp/deploy/images/corstone1000-fvp/corstone1000-esp-image-corstone1000-fvp.wic
Now, it is time to test the SB for the Corstone-1000
***********************************************************
Steps to test SB on FVP
***********************************************************
Now, as mentioned in the previous section **Prepare EFI System Partition**, the ESP image will be used automatically in the Corstone-1000 FVP as the 2nd MMC card image. Change directory to your workspace and run the FVP as follows:
::
kas shell meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml -c "../meta-arm/scripts/runfvp --terminals=xterm"
When the script is executed, three terminal instances will be launched, one for the boot processor (aka Secure Enclave) processing element and two for the Host processing element. On the host side, stop the execution at the U-Boot prompt which looks like `corstone1000#`. There is a timeout of 3 seconds to stop the execution at the U-Boot prompt. At the U-Boot prompt, run the following commands:
Set the current mmc device
::
corstone1000# mmc dev 1
Enroll the four UEFI Secureboot authenticated variables
::
corstone1000# load mmc 1:1 ${loadaddr} corstone1000_secureboot_keys/PK.auth && setenv -e -nv -bs -rt -at -i ${loadaddr}:$filesize PK
corstone1000# load mmc 1:1 ${loadaddr} corstone1000_secureboot_keys/KEK.auth && setenv -e -nv -bs -rt -at -i ${loadaddr}:$filesize KEK
corstone1000# load mmc 1:1 ${loadaddr} corstone1000_secureboot_keys/db.auth && setenv -e -nv -bs -rt -at -i ${loadaddr}:$filesize db
corstone1000# load mmc 1:1 ${loadaddr} corstone1000_secureboot_keys/dbx.auth && setenv -e -nv -bs -rt -at -i ${loadaddr}:$filesize dbx
Now, load the unsigned FVP kernel image and execute it. This unsigned kernel image should not boot and result as follows
::
corstone1000# load mmc 1:1 ${loadaddr} corstone1000_secureboot_fvp_images/Image_fvp
corstone1000# loadm $loadaddr $kernel_addr_r $filesize
corstone1000# bootefi $kernel_addr_r $fdtcontroladdr
Booting /MemoryMapped(0x0,0x88200000,0x236aa00)
Image not authenticated
Loading image failed
The next step is to verify the signed linux kernel image. Load the signed kernel image and execute it as follows:
::
corstone1000# load mmc 1:1 ${loadaddr} corstone1000_secureboot_fvp_images/Image_fvp.signed
corstone1000# loadm $loadaddr $kernel_addr_r $filesize
corstone1000# bootefi $kernel_addr_r $fdtcontroladdr
The above set of commands should result in booting of signed linux kernel image successfully.
***********************************************************
Steps to test SB on MPS3 FPGA
***********************************************************
Now, as mentioned in the previous section **Prepare EFI System Partition**, the ESP image for MPS3 FPGA needs to be copied to the USB drive.
Follow the steps mentioned in the same section for MPS3 FPGA to prepare the USB drive with the ESP image. The modified ESP image corresponds to MPS3 FPGA can be found at the location as mentioned before i.e. `_workspace/meta-arm/build/tmp/deploy/images/corstone1000-mps3/corstone1000-esp-image-corstone1000-mps3.wic`.
Insert this USB drive to the MPS3 FPGA and boot, and stop the execution at the U-Boot prompt similar to the FVP. At the U-Boot prompt, run the following commands:
Reset the USB
::
corstone1000# usb reset
resetting USB...
Bus usb@40200000: isp1763 bus width: 16, oc: not available
USB ISP 1763 HW rev. 32 started
scanning bus usb@40200000 for devices... port 1 high speed
3 USB Device(s) found
scanning usb for storage devices... 1 Storage Device(s) found
**NOTE:** Sometimes, the usb reset doesn't recognize the USB device. It is recomended to rerun the usb reset command.
Set the current USB device
::
corstone1000# usb dev 0
Enroll the four UEFI Secureboot authenticated variables
::
corstone1000# load usb 0 $loadaddr corstone1000_secureboot_keys/PK.auth && setenv -e -nv -bs -rt -at -i $loadaddr:$filesize PK
corstone1000# load usb 0 $loadaddr corstone1000_secureboot_keys/KEK.auth && setenv -e -nv -bs -rt -at -i $loadaddr:$filesize KEK
corstone1000# load usb 0 $loadaddr corstone1000_secureboot_keys/db.auth && setenv -e -nv -bs -rt -at -i $loadaddr:$filesize db
corstone1000# load usb 0 $loadaddr corstone1000_secureboot_keys/dbx.auth && setenv -e -nv -bs -rt -at -i $loadaddr:$filesize dbx
Now, load the unsigned MPS3 FPGA linux kernel image and execute it. This unsigned kernel image should not boot and result as follows
::
corstone1000# load usb 0 $loadaddr corstone1000_secureboot_mps3_images/Image_mps3
corstone1000# loadm $loadaddr $kernel_addr_r $filesize
corstone1000# bootefi $kernel_addr_r $fdtcontroladdr
Booting /MemoryMapped(0x0,0x88200000,0x236aa00)
Image not authenticated
Loading image failed
The next step is to verify the signed linux kernel image. Load the signed kernel image and execute it as follows:
::
corstone1000# load usb 0 $loadaddr corstone1000_secureboot_mps3_images/Image_mps3.signed
corstone1000# loadm $loadaddr $kernel_addr_r $filesize
corstone1000# bootefi $kernel_addr_r $fdtcontroladdr
The above set of commands should result in booting of signed linux kernel image successfully.
***********************************************************
Steps to disable Secureboot on both FVP and MPS3 FPGA
***********************************************************
Now, after testing the SB, UEFI authenticated variables get stored in the secure flash. When you try to reboot, the U-Boot will automatically read the UEFI authenticated variables and authenticates the images before executing them. In normal booting scenario, the linux kernel images will not be signed and hence this will not allow the system to boot, as image authentication will fail. We need to delete the Platform Key (one of the UEFI authenticated variable for SB) in order to disable the SB. At the U-Boot prompt, run the following commands.
On the FVP
::
corstone1000# mmc dev 1
corstone1000# load mmc 1:1 $loadaddr corstone1000_secureboot_keys/PK_delete.auth && setenv -e -nv -bs -rt -at -i $loadaddr:$filesize PK
corstone1000# boot
On the MPS3 FPGA
::
corstone1000# usb reset
corstone1000# usb dev 0
corstone1000# load usb 0 $loadaddr corstone1000_secureboot_keys/PK_delete.auth && setenv -e -nv -bs -rt -at -i $loadaddr:$filesize PK
corstone1000# boot
The above commands will delete the Platform key (PK) and allow the normal system boot flow without SB.
Testing the External System
---------------------------
During Linux boot the remoteproc subsystem automatically starts
the external system.
The external system can be switched on/off on demand with the following commands:
::
echo stop > /sys/class/remoteproc/remoteproc0/state
::
echo start > /sys/class/remoteproc/remoteproc0/state
Tests results
-------------
As a reference for the end user, reports for various tests for `Corstone-1000 software (CORSTONE1000-2023.11) <https://git.yoctoproject.org/meta-arm/tag/?h=CORSTONE1000-2023.11>`__
can be found `here <https://gitlab.arm.com/arm-reference-solutions/arm-reference-solutions-test-report/-/tree/master/embedded-a/corstone1000>`__.
Running the software on FVP on Windows or AArch64 Linux
------------------------------------------------------------
The user should follow the build instructions in this document to build on a Linux host machine. Then, copy the output binaries to the Windows or Aarch64 Linux machine where the FVP is located. Then, launch the FVP binary.
Security Issue Reporting
------------------------
To report any security issues identified with Corstone-1000, please send an email to arm-security@arm.com.
As a reference for the end user, reports for various tests for `Corstone-1000 software (CORSTONE1000-2024.06) <https://git.yoctoproject.org/meta-arm/tag/?h=CORSTONE1000-2024.06>`__
can be found `here <https://gitlab.arm.com/arm-reference-solutions/arm-reference-solutions-test-report/-/tree/CORSTONE1000-2024.06/embedded-a/corstone1000/CORSTONE1000-2024.06?ref_type=tags>`__.
--------------
@@ -0,0 +1,46 @@
From 37f92eeb4361626072e690adb3b0bb20db7c2fca Mon Sep 17 00:00:00 2001
From: Emekcan Aras <Emekcan.Aras@arm.com>
Date: Wed, 15 May 2024 13:54:51 +0100
Subject: [PATCH] fix(corstone1000): clean the cache and disable interrupt
before system reset
Corstone1000 does not properly clean the cache and disable gic interrupts
before the reset. This causes a race condition especially in FVP after reset.
This adds proper sequence before resetting the platform.
Signed-off-by: Emekcan Aras <Emekcan.Aras@arm.com>
Upstream-Status: Pending
---
plat/arm/board/corstone1000/common/corstone1000_pm.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/plat/arm/board/corstone1000/common/corstone1000_pm.c b/plat/arm/board/corstone1000/common/corstone1000_pm.c
index 4b0a791e7..a52e945bf 100644
--- a/plat/arm/board/corstone1000/common/corstone1000_pm.c
+++ b/plat/arm/board/corstone1000/common/corstone1000_pm.c
@@ -7,6 +7,7 @@
#include <lib/psci/psci.h>
#include <plat/arm/common/plat_arm.h>
#include <platform_def.h>
+#include <drivers/arm/gicv2.h>
/*******************************************************************************
* Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
* platform layer will take care of registering the handlers with PSCI.
@@ -18,6 +19,14 @@ static void __dead2 corstone1000_system_reset(void)
uint32_t volatile * const watchdog_ctrl_reg = (uint32_t *) SECURE_WATCHDOG_ADDR_CTRL_REG;
uint32_t volatile * const watchdog_val_reg = (uint32_t *) SECURE_WATCHDOG_ADDR_VAL_REG;
+ /* Flush and invalidate data cache */
+ dcsw_op_all(DCCISW);
+ /*
+ * Disable GIC CPU interface to prevent pending interrupt
+ * from waking up the AP from WFI.
+ */
+ gicv2_cpuif_disable();
+
*(watchdog_val_reg) = SECURE_WATCHDOG_COUNTDOWN_VAL;
*watchdog_ctrl_reg = SECURE_WATCHDOG_MASK_ENABLE;
while (1) {
--
2.25.1
@@ -8,6 +8,7 @@ SRC_URI:append = " \
file://0002-fix-corstone1000-pass-spsr-value-explicitly.patch \
file://0003-fix-spmd-remove-EL3-interrupt-registration.patch \
file://0004-fix-corstone1000-remove-unused-NS_SHARED_RAM-region.patch \
file://0005-fix-corstone1000-clean-the-cache-and-disable-interru.patch \
"
TFA_DEBUG = "1"
@@ -1,7 +1,7 @@
From 21b0c9f028b6b04fa2f027510ec90969735f4dd1 Mon Sep 17 00:00:00 2001
From: Bence Balogh <bence.balogh@arm.com>
Date: Wed, 17 Apr 2024 19:31:03 +0200
Subject: [PATCH] platform: CS1000: Increase RSE_COMMS buffer size
Subject: [PATCH] platform: corstone1000: Increase RSE_COMMS buffer size
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Upstream-Status: Pending
@@ -18,7 +18,7 @@ index 6d79dd3bf..f079f6504 100644
/* size suits to fit the largest message too (EFI variables) */
-#define RSE_COMMS_PAYLOAD_MAX_SIZE (0x2100)
+#define RSE_COMMS_PAYLOAD_MAX_SIZE (0x3B00)
+#define RSE_COMMS_PAYLOAD_MAX_SIZE (0x43C0)
/*
* Allocated for each client request.
@@ -0,0 +1,31 @@
From a8aeaafd6c26d6bc3066164d12aabc5cb754fe1c Mon Sep 17 00:00:00 2001
From: Ali Can Ozaslan <ali.oezaslan@arm.com>
Date: Wed, 15 May 2024 12:12:15 +0000
Subject: [PATCH] CC312: alignment of cc312 differences between fvp and mps3
corstone1000 platforms
Configures CC312 mps3 model same as predefined cc312 FVP
configuration while keeping debug ports closed.
Signed-off-by: Ali Can Ozaslan <ali.oezaslan@arm.com>
Upstream-Status: Inappropriate [Requires an aligment cc3xx with mps3 hw and fvp sw models]
---
lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c
index 31e4332be..4d7e6fa61 100644
--- a/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c
+++ b/lib/ext/cryptocell-312-runtime/host/src/cc3x_lib/cc_lib.c
@@ -207,6 +207,9 @@ CClibRetCode_t CC_LibInit(CCRndContext_t *rndContext_ptr, CCRndWorkBuff_t *rndW
goto InitErr2;
}
+ /* configuring secure debug to align cc312 with corstone 1000 */
+ CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(HOST_RGF,HOST_DCU_EN0), 0xffffe7fc);
+
/* turn off the DFA since Cerberus doen't support it */
reg = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_AO_LOCK_BITS));
CC_REG_FLD_SET(0, HOST_AO_LOCK_BITS, HOST_FORCE_DFA_ENABLE, reg, 0x0);
@@ -0,0 +1,45 @@
From d7725e629c9ba93523589cc9d8af3186db19d4e8 Mon Sep 17 00:00:00 2001
From: Bence Balogh <bence.balogh@arm.com>
Date: Wed, 15 May 2024 22:37:51 +0200
Subject: [PATCH] Platform: corstone1000: Increase buffers for EFI vars
The UEFI variables are stored in the Protected Storage. The size of
the variables metadata have been increased so the related buffer sizes
have to be increased.
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Upstream-Status: Pending
---
.../ext/target/arm/corstone1000/config_tfm_target.h | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/platform/ext/target/arm/corstone1000/config_tfm_target.h b/platform/ext/target/arm/corstone1000/config_tfm_target.h
index 2eb0924770..6ee823a7dc 100644
--- a/platform/ext/target/arm/corstone1000/config_tfm_target.h
+++ b/platform/ext/target/arm/corstone1000/config_tfm_target.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -24,4 +24,15 @@
#undef ITS_MAX_ASSET_SIZE
#define ITS_MAX_ASSET_SIZE 2048
+/* The maximum asset size to be stored in the Protected Storage */
+#undef PS_MAX_ASSET_SIZE
+#define PS_MAX_ASSET_SIZE 2592
+
+/* This is needed to be able to process the EFI variables during PS writes. */
+#undef CRYPTO_ENGINE_BUF_SIZE
+#define CRYPTO_ENGINE_BUF_SIZE 0x5000
+
+/* This is also has to be increased to fit the EFI variables into the iovecs. */
+#undef CRYPTO_IOVEC_BUFFER_SIZE
+#define CRYPTO_IOVEC_BUFFER_SIZE 6000
#endif /* __CONFIG_TFM_TARGET_H__ */
--
2.25.1
@@ -0,0 +1,28 @@
From 78db43f80676f8038b35edd6674d22fb5ff85c12 Mon Sep 17 00:00:00 2001
From: Bence Balogh <bence.balogh@arm.com>
Date: Mon, 27 May 2024 17:11:31 +0200
Subject: [PATCH] corstone1000: Remove reset after capsule update
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/29065]
---
.../target/arm/corstone1000/services/src/tfm_platform_system.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/platform/ext/target/arm/corstone1000/services/src/tfm_platform_system.c b/platform/ext/target/arm/corstone1000/services/src/tfm_platform_system.c
index 41305ed966..1e837ce3b5 100644
--- a/platform/ext/target/arm/corstone1000/services/src/tfm_platform_system.c
+++ b/platform/ext/target/arm/corstone1000/services/src/tfm_platform_system.c
@@ -28,9 +28,6 @@ enum tfm_platform_err_t tfm_platform_hal_ioctl(tfm_platform_ioctl_req_t request,
case IOCTL_CORSTONE1000_FWU_FLASH_IMAGES:
result = corstone1000_fwu_flash_image();
- if (!result) {
- NVIC_SystemReset();
- }
break;
case IOCTL_CORSTONE1000_FWU_HOST_ACK:
--
2.25.1
@@ -25,7 +25,10 @@ SRC_URI:append:corstone1000 = " \
file://0006-Platform-Corstone1000-Enable-host-firewall-in-FVP.patch \
file://0007-platform-corstone1000-Increase-ITS-max-asset-size.patch \
file://0008-Platform-CS1000-Replace-OpenAMP-with-RSE_COMMS.patch \
file://0009-platform-CS1000-Increase-RSE_COMMS-buffer-size.patch \
file://0009-platform-corstone1000-Increase-RSE_COMMS-buffer-size.patch \
file://0010-CC312-alignment-of-cc312-differences-between-fvp-and.patch \
file://0011-Platform-corstone1000-Increase-buffers-for-EFI-vars.patch \
file://0012-corstone1000-Remove-reset-after-capsule-update.patch \
"
# TF-M ships patches for external dependencies that needs to be applied
@@ -0,0 +1,27 @@
From a94bcd8af80c42adf99a7114174afea4000e6647 Mon Sep 17 00:00:00 2001
From: Bence Balogh <bence.balogh@arm.com>
Date: Tue, 14 May 2024 15:58:15 +0200
Subject: [PATCH] Remove PLATFORM_HAS_ATTEST_PK define from IAT test
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Upstream-Status: Inappropriate [Should remove the flag only for CS1000]
---
deployments/psa-api-test/initial_attestation/iat-api-test.cmake | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/deployments/psa-api-test/initial_attestation/iat-api-test.cmake b/deployments/psa-api-test/initial_attestation/iat-api-test.cmake
index 4d1d2b1a9..eb4db223c 100644
--- a/deployments/psa-api-test/initial_attestation/iat-api-test.cmake
+++ b/deployments/psa-api-test/initial_attestation/iat-api-test.cmake
@@ -15,7 +15,7 @@ set(TS_ARCH_TEST_SUITE INITIAL_ATTESTATION CACHE STRING "Arch test suite")
# Set additional defines needed for build.
#-------------------------------------------------------------------------------
list(APPEND PSA_ARCH_TEST_EXTERNAL_DEFS
- -DPSA_ALG_MD4=0x02000002 -DPLATFORM_HAS_ATTEST_PK)
+ -DPSA_ALG_MD4=0x02000002)
#-------------------------------------------------------------------------------
# The arch test build system puts its build output under a test suite specific
--
2.25.1
@@ -0,0 +1,28 @@
From c7f2861e5c5ee209373a8dba15a608f78a97078b Mon Sep 17 00:00:00 2001
From: Gabor Toth <gabor.toth2@arm.com>
Date: Wed, 10 Apr 2024 11:17:50 +0200
Subject: [PATCH 1/3] Fix: Avoid redefinition of variables
Remove variable redefinition which shadows the original one.
Signed-off-by: Gabor Toth <gabor.toth2@arm.com>
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TS/trusted-services/+/27954]
---
.../service/uefi/smm_variable/client/cpp/smm_variable_client.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/components/service/uefi/smm_variable/client/cpp/smm_variable_client.cpp b/components/service/uefi/smm_variable/client/cpp/smm_variable_client.cpp
index f71d0c864..d39448900 100644
--- a/components/service/uefi/smm_variable/client/cpp/smm_variable_client.cpp
+++ b/components/service/uefi/smm_variable/client/cpp/smm_variable_client.cpp
@@ -166,7 +166,6 @@ efi_status_t smm_variable_client::get_variable(const EFI_GUID &guid, const std::
if (call_handle) {
uint8_t *resp_buf;
- size_t resp_len;
service_status_t service_status;
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *access_var =
--
2.25.1
@@ -0,0 +1,495 @@
From cc4cc9f3f5f02f713cf4da1854f3085bf31e71cf Mon Sep 17 00:00:00 2001
From: Gabor Toth <gabor.toth2@arm.com>
Date: Sat, 13 Apr 2024 14:52:23 +0200
Subject: [PATCH 2/3] Fix GetNextVariableName NameSize input
Based on the specification the NameSize shall be set to the available
buffer size at the first call instead of the NameSize of the
provided variable.
Change smm-gateway and the tests according this. Also remove
sanitize_get_next_var_name_param utility function, which is not
compilant with this solution.
Signed-off-by: Gabor Toth <gabor.toth2@arm.com>
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TS/trusted-services/+/28022]
---
.../backend/test/variable_store_tests.cpp | 48 +++++++--------
.../backend/uefi_variable_store.c | 60 ++++++++++++-------
.../backend/uefi_variable_store.h | 5 +-
.../smm_variable/backend/variable_index.c | 3 +
.../provider/smm_variable_provider.c | 59 +++++-------------
.../service/smm_variable_attack_tests.cpp | 29 ++++-----
.../service/smm_variable_service_tests.cpp | 7 ++-
7 files changed, 98 insertions(+), 113 deletions(-)
diff --git a/components/service/uefi/smm_variable/backend/test/variable_store_tests.cpp b/components/service/uefi/smm_variable/backend/test/variable_store_tests.cpp
index fd48f13fb..72772821c 100644
--- a/components/service/uefi/smm_variable/backend/test/variable_store_tests.cpp
+++ b/components/service/uefi/smm_variable/backend/test/variable_store_tests.cpp
@@ -501,15 +501,13 @@ TEST(UefiVariableStoreTests, bootServiceAccess)
std::vector<uint8_t> msg_buffer(VARIABLE_BUFFER_SIZE);
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *next_name =
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) msg_buffer.data();
- size_t max_name_len =
- VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
size_t total_len = 0;
- next_name->NameSize = sizeof(int16_t);
+ next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
next_name->Name[0] = 0;
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- max_name_len, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
}
@@ -574,47 +572,48 @@ TEST(UefiVariableStoreTests, enumerateStoreContents)
std::vector<uint8_t> msg_buffer(VARIABLE_BUFFER_SIZE);
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *next_name =
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) msg_buffer.data();
- size_t max_name_len =
- VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
/* First check handling of invalid variable name */
std::u16string bogus_name = to_variable_name(u"bogus_variable");
size_t bogus_name_size = string_get_size_in_bytes(bogus_name);
next_name->Guid = m_common_guid;
- next_name->NameSize = bogus_name_size;
+ next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
memcpy(next_name->Name, bogus_name.data(), bogus_name_size);
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- max_name_len, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_INVALID_PARAMETER, status);
/* Enumerate store contents */
next_name->NameSize = sizeof(int16_t);
next_name->Name[0] = 0;
- /* Check if the correct NameSize is returned if max_name_len is too small */
+ /* Check if the correct NameSize is returned if namesize is too small */
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- 0, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_BUFFER_TOO_SMALL, status);
UNSIGNED_LONGLONGS_EQUAL(sizeof(var_name_1), next_name->NameSize);
- /* And then used the previously received next_name->NameSize as max_name_len */
+ next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- next_name->NameSize, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
CHECK_TRUE(compare_variable_name(var_name_1, next_name->Name, next_name->NameSize));
+ next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- max_name_len, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
CHECK_TRUE(compare_variable_name(var_name_2, next_name->Name, next_name->NameSize));
+ next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- max_name_len, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
CHECK_TRUE(compare_variable_name(var_name_3, next_name->Name, next_name->NameSize));
+ next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- max_name_len, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
power_cycle();
@@ -622,21 +621,23 @@ TEST(UefiVariableStoreTests, enumerateStoreContents)
/* Enumerate again - should be left with just NV variables.
* Use a different but equally valid null name.
*/
- next_name->NameSize = 10 * sizeof(int16_t);
+ next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
memset(next_name->Name, 0, next_name->NameSize);
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- max_name_len, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
CHECK_TRUE(compare_variable_name(var_name_1, next_name->Name, next_name->NameSize));
+ next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- max_name_len, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
CHECK_TRUE(compare_variable_name(var_name_3, next_name->Name, next_name->NameSize));
+ next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- max_name_len, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
}
@@ -672,21 +673,20 @@ TEST(UefiVariableStoreTests, failedNvSet)
std::vector<uint8_t> msg_buffer(VARIABLE_BUFFER_SIZE);
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *next_name =
(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) msg_buffer.data();
- size_t max_name_len =
- VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
/* Enumerate store contents */
size_t total_len = 0;
- next_name->NameSize = sizeof(int16_t);
+ next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
next_name->Name[0] = 0;
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- max_name_len, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
CHECK_TRUE(compare_variable_name(var_name_1, next_name->Name, next_name->NameSize));
+ next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
- max_name_len, &total_len);
+ &total_len);
UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
}
diff --git a/components/service/uefi/smm_variable/backend/uefi_variable_store.c b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
index 5b46c1371..caf6698aa 100644
--- a/components/service/uefi/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
@@ -404,9 +404,27 @@ efi_status_t uefi_variable_store_get_variable(const struct uefi_variable_store *
efi_status_t
uefi_variable_store_get_next_variable_name(const struct uefi_variable_store *context,
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *cur,
- size_t max_name_len, size_t *total_length)
+ size_t *total_length)
{
- efi_status_t status = check_name_terminator(cur->Name, cur->NameSize);
+ efi_status_t status = EFI_SUCCESS;
+ size_t buffer_size = 0;
+
+ if (!cur)
+ return EFI_INVALID_PARAMETER;
+ /*
+ * NameSize is set to the buffer size to store the names,
+ * let's calculate the size actually being used.
+ */
+ buffer_size = cur->NameSize;
+ for (int i = 0; i < buffer_size / sizeof(int16_t); i++) {
+ if (cur->Name[i] == 0) {
+ /* With null terminator */
+ cur->NameSize = 2*(i+1);
+ break;
+ }
+ }
+
+ status = check_name_terminator(cur->Name, cur->NameSize);
if (status != EFI_SUCCESS)
return status;
@@ -418,21 +436,11 @@ uefi_variable_store_get_next_variable_name(const struct uefi_variable_store *con
&context->variable_index, &cur->Guid, cur->NameSize, cur->Name, &status);
if (info && (status == EFI_SUCCESS)) {
- /* The NameSize has to be set in every case according to the UEFI specs.
- * In case of EFI_BUFFER_TOO_SMALL it has to reflect the size of buffer
- * needed.
- */
- cur->NameSize = info->metadata.name_size;
- *total_length = sizeof(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME);
-
- if (info->metadata.name_size <= max_name_len) {
+ if (info->metadata.name_size <= buffer_size) {
cur->Guid = info->metadata.guid;
+ cur->NameSize = info->metadata.name_size;
memcpy(cur->Name, info->metadata.name, info->metadata.name_size);
- *total_length =
- SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_TOTAL_SIZE(
- cur);
-
/*
* Check if variable is accessible (e.g boot variable is not
* accessible at runtime)
@@ -442,6 +450,10 @@ uefi_variable_store_get_next_variable_name(const struct uefi_variable_store *con
if (status == EFI_SUCCESS)
break;
} else {
+ /* The VariableNameSize is updated to reflect the size of buffer needed */
+ cur->NameSize = info->metadata.name_size;
+ memset(cur->Name, 0, buffer_size);
+ memset(&cur->Guid, 0, sizeof(EFI_GUID));
status = EFI_BUFFER_TOO_SMALL;
break;
}
@@ -450,18 +462,24 @@ uefi_variable_store_get_next_variable_name(const struct uefi_variable_store *con
/* Do not hide original error if there is any */
if (status == EFI_SUCCESS)
status = EFI_NOT_FOUND;
+
+ memset(cur->Name, 0, buffer_size);
+ memset(&cur->Guid, 0, sizeof(EFI_GUID));
+ cur->NameSize = 0;
break;
}
}
- /* If we found no accessible variable clear the fields for security */
- if (status != EFI_SUCCESS) {
- memset(cur->Name, 0, max_name_len);
- memset(&cur->Guid, 0, sizeof(EFI_GUID));
- if (status != EFI_BUFFER_TOO_SMALL)
- cur->NameSize = 0;
+ if (status == EFI_SUCCESS) {
+ /* Store everything including the name */
+ *total_length =
+ SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_TOTAL_SIZE(
+ cur);
+ } else {
+ /* Do not store the name, only the size */
+ *total_length =
+ SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_NAME_OFFSET;
}
-
return status;
}
diff --git a/components/service/uefi/smm_variable/backend/uefi_variable_store.h b/components/service/uefi/smm_variable/backend/uefi_variable_store.h
index 8be5f36e6..2493ff6b4 100644
--- a/components/service/uefi/smm_variable/backend/uefi_variable_store.h
+++ b/components/service/uefi/smm_variable/backend/uefi_variable_store.h
@@ -134,8 +134,7 @@ efi_status_t uefi_variable_store_get_variable(const struct uefi_variable_store *
* Used for enumerating the store contents
*
* @param[in] context uefi_variable_store instance
- * @param[out] cur Current variable name
- * @param[in] max_name_len The maximum variable name length
+ * @param[inout] cur The size of the VariableName buffer
* @param[out] total_len The total length of the output
*
* @return EFI_SUCCESS if successful
@@ -143,7 +142,7 @@ efi_status_t uefi_variable_store_get_variable(const struct uefi_variable_store *
efi_status_t
uefi_variable_store_get_next_variable_name(const struct uefi_variable_store *context,
SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *cur,
- size_t max_name_len, size_t *total_length);
+ size_t *total_length);
/**
* @brief Query for variable info
diff --git a/components/service/uefi/smm_variable/backend/variable_index.c b/components/service/uefi/smm_variable/backend/variable_index.c
index d850dbe18..e2fe6dd38 100644
--- a/components/service/uefi/smm_variable/backend/variable_index.c
+++ b/components/service/uefi/smm_variable/backend/variable_index.c
@@ -27,6 +27,9 @@ static uint64_t name_hash(const EFI_GUID *guid, size_t name_size, const int16_t
/* Extend to cover name up to but not including null terminator */
for (size_t i = 0; i < (name_size - sizeof(int16_t)) / sizeof(int16_t); ++i) {
+ /* Only hash till the first null terminator */
+ if (name[i] == 0)
+ break;
hash = ((hash << 5) + hash) + name[i];
}
diff --git a/components/service/uefi/smm_variable/provider/smm_variable_provider.c b/components/service/uefi/smm_variable/provider/smm_variable_provider.c
index ca3f7e5e5..1a5269338 100644
--- a/components/service/uefi/smm_variable/provider/smm_variable_provider.c
+++ b/components/service/uefi/smm_variable/provider/smm_variable_provider.c
@@ -81,30 +81,6 @@ static efi_status_t sanitize_access_variable_param(struct rpc_request *req, size
return efi_status;
}
-static efi_status_t sanitize_get_next_var_name_param(struct rpc_request *req, size_t *param_len)
-{
- efi_status_t efi_status = EFI_INVALID_PARAMETER;
- *param_len = 0;
- const struct rpc_buffer *req_buf = &req->request;
-
- if (req_buf->data_length >= SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_NAME_OFFSET) {
- const SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *param =
- (const SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *)req_buf->data;
-
- size_t max_space_for_name =
- req_buf->data_length -
- SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_NAME_OFFSET;
-
- if (param->NameSize <= max_space_for_name) {
- *param_len =
- SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_TOTAL_SIZE(param);
- efi_status = EFI_SUCCESS;
- }
- }
-
- return efi_status;
-}
-
static efi_status_t sanitize_var_check_property_param(struct rpc_request *req, size_t *param_len)
{
efi_status_t efi_status = EFI_INVALID_PARAMETER;
@@ -146,7 +122,7 @@ static rpc_status_t get_variable_handler(void *context, struct rpc_request *req)
struct rpc_buffer *req_buf = &req->request;
size_t max_data_len = resp_buf->size - param_len;
- memmove(resp_buf->data, req_buf->data, param_len);
+ memcpy(resp_buf->data, req_buf->data, param_len);
efi_status = uefi_variable_store_get_variable(
&this_instance->variable_store,
@@ -167,28 +143,21 @@ static rpc_status_t get_next_variable_name_handler(void *context, struct rpc_req
{
struct smm_variable_provider *this_instance = (struct smm_variable_provider *)context;
- size_t param_len = 0;
- efi_status_t efi_status = sanitize_get_next_var_name_param(req, &param_len);
+ efi_status_t efi_status = EFI_SUCCESS;
+ size_t variable_size = 0;
- if (efi_status == EFI_SUCCESS) {
- /* Valid get next variable name header */
- struct rpc_buffer *resp_buf = &req->response;
+ /* Valid get next variable name header */
+ struct rpc_buffer *resp_buf = &req->response;
+ struct rpc_buffer *req_buf = &req->request;
- if (resp_buf->size >= param_len) {
- struct rpc_buffer *req_buf = &req->request;
+ memcpy(resp_buf->data, req_buf->data, req_buf->data_length);
- memmove(resp_buf->data, req_buf->data, param_len);
+ efi_status = uefi_variable_store_get_next_variable_name(
+ &this_instance->variable_store,
+ (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *)resp_buf->data,
+ &variable_size);
- efi_status = uefi_variable_store_get_next_variable_name(
- &this_instance->variable_store,
- (SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *)resp_buf->data,
- ((SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME*)resp_buf->data)->NameSize,
- &resp_buf->data_length);
- } else {
- /* Reponse buffer not big enough */
- efi_status = EFI_BAD_BUFFER_SIZE;
- }
- }
+ resp_buf->data_length = variable_size;
req->service_status = efi_status;
@@ -240,7 +209,7 @@ static rpc_status_t query_variable_info_handler(void *context, struct rpc_reques
struct rpc_buffer *resp_buf = &req->response;
if (resp_buf->size >= req_buf->data_length) {
- memmove(resp_buf->data, req_buf->data, req_buf->data_length);
+ memcpy(resp_buf->data, req_buf->data, req_buf->data_length);
efi_status = uefi_variable_store_query_variable_info(
&this_instance->variable_store,
@@ -308,7 +277,7 @@ static rpc_status_t get_var_check_property_handler(void *context, struct rpc_req
if (resp_buf->size >= param_len) {
struct rpc_buffer *req_buf = &req->request;
- memmove(resp_buf->data, req_buf->data, param_len);
+ memcpy(resp_buf->data, req_buf->data, param_len);
resp_buf->data_length = param_len;
efi_status = uefi_variable_store_get_var_check_property(
diff --git a/components/service/uefi/smm_variable/test/service/smm_variable_attack_tests.cpp b/components/service/uefi/smm_variable/test/service/smm_variable_attack_tests.cpp
index 76b62fd35..98e61fec0 100644
--- a/components/service/uefi/smm_variable/test/service/smm_variable_attack_tests.cpp
+++ b/components/service/uefi/smm_variable/test/service/smm_variable_attack_tests.cpp
@@ -176,19 +176,6 @@ TEST(SmmVariableAttackTests, setAndGetWithSizeMaxNameSize)
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
}
-TEST(SmmVariableAttackTests, enumerateWithOversizeName)
-{
- efi_status_t efi_status = EFI_SUCCESS;
- std::u16string var_name = null_name;
- EFI_GUID guid;
- memset(&guid, 0, sizeof(guid));
-
- efi_status = m_client->get_next_variable_name(guid, var_name,
- (var_name.size() + 1) * sizeof(int16_t) + 1);
-
- UNSIGNED_LONGLONGS_EQUAL(EFI_INVALID_PARAMETER, efi_status);
-}
-
TEST(SmmVariableAttackTests, enumerateWithSizeMaxNameSize)
{
efi_status_t efi_status = EFI_SUCCESS;
@@ -202,17 +189,23 @@ TEST(SmmVariableAttackTests, enumerateWithSizeMaxNameSize)
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
- /* Initial iteration uses good name length */
- efi_status = m_client->get_next_variable_name(guid, var_name);
+ /* Initial iteration uses good name length for next variable */
+ efi_status = m_client->get_next_variable_name(guid, var_name, std::numeric_limits<size_t>::max());
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
- /* Next iteration uses invalid name length */
- efi_status = m_client->get_next_variable_name(guid, var_name,
- std::numeric_limits<size_t>::max());
+ /* Next iteration uses invalid name length, so a null terminator can not fit */
+ var_name = null_name;
+ efi_status = m_client->get_next_variable_name(guid, var_name, 1);
UNSIGNED_LONGLONGS_EQUAL(EFI_INVALID_PARAMETER, efi_status);
+ /* Next iteration uses invalid name length, so a null terminator can not fit */
+ var_name = null_name;
+ efi_status = m_client->get_next_variable_name(guid, var_name, 2);
+
+ UNSIGNED_LONGLONGS_EQUAL(EFI_BUFFER_TOO_SMALL, efi_status);
+
/* Expect to be able to remove the variable */
efi_status = m_client->remove_variable(m_common_guid, var_name_1);
UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
diff --git a/components/service/uefi/smm_variable/test/service/smm_variable_service_tests.cpp b/components/service/uefi/smm_variable/test/service/smm_variable_service_tests.cpp
index e82a90c37..8fa4f8077 100644
--- a/components/service/uefi/smm_variable/test/service/smm_variable_service_tests.cpp
+++ b/components/service/uefi/smm_variable/test/service/smm_variable_service_tests.cpp
@@ -9,6 +9,7 @@
#include <cstring>
#include <locale>
#include <sstream>
+#include <limits>
#include "util.h"
@@ -154,7 +155,7 @@ TEST_GROUP(SmmVariableServiceTests)
#endif
do {
- status = m_client->get_next_variable_name(guid, var_name);
+ status = m_client->get_next_variable_name(guid, var_name, max_variable_size);
/* There are no more variables in the persistent store */
if (status == EFI_NOT_FOUND) {
@@ -223,6 +224,8 @@ TEST_GROUP(SmmVariableServiceTests)
std::u16string m_ro_variable = to_variable_name(u"ro_variable");
std::u16string m_boot_finished_var_name = to_variable_name(u"finished");
+ uint32_t max_variable_size = 4096;
+
/* Cleanup skips these variables */
std::vector<std::u16string *> m_non_rm_vars{ &m_ro_variable, &m_boot_finished_var_name };
@@ -654,7 +657,7 @@ TEST(SmmVariableServiceTests, enumerateStoreContents)
std::u16string *expected_variables[] = { &var_name_1, &var_name_2, &var_name_3 };
do {
- efi_status = m_client->get_next_variable_name(guid, var_name);
+ efi_status = m_client->get_next_variable_name(guid, var_name, max_variable_size);
if (efi_status != EFI_SUCCESS)
break;
--
2.25.1
@@ -0,0 +1,82 @@
From c62e728bb86981219984c8b39819fb8926a41e10 Mon Sep 17 00:00:00 2001
From: Gabor Toth <gabor.toth2@arm.com>
Date: Fri, 19 Apr 2024 18:25:23 +0200
Subject: [PATCH 3/3] Fix error handling of variable index loading
If loading of the variable index from Protected Storage fails, SmmGW
will silently continue with empty variable store. This is a serious
fault and a potential security risk.
Change the code to produce a log output when this happens and stop
loading the SP.
Signed-off-by: Gabor Toth <gabor.toth2@arm.com>
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TS/trusted-services/+/28300]
---
.../backend/uefi_variable_store.c | 28 ++++++++++++++-----
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/components/service/uefi/smm_variable/backend/uefi_variable_store.c b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
index caf6698aa..c1691dc8f 100644
--- a/components/service/uefi/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
@@ -27,7 +27,7 @@
#include "service/crypto/client/psa/crypto_client.h"
#endif
-static void load_variable_index(struct uefi_variable_store *context);
+static efi_status_t load_variable_index(struct uefi_variable_store *context);
static efi_status_t sync_variable_index(const struct uefi_variable_store *context);
@@ -165,8 +165,10 @@ efi_status_t uefi_variable_store_init(struct uefi_variable_store *context, uint3
/* Load the variable index with NV variable info from the persistent store */
if (context->index_sync_buffer) {
- load_variable_index(context);
- purge_orphan_index_entries(context);
+ status = load_variable_index(context);
+
+ if (status == EFI_SUCCESS)
+ purge_orphan_index_entries(context);
}
}
@@ -571,7 +573,7 @@ efi_status_t uefi_variable_store_get_var_check_property(
return status;
}
-static void load_variable_index(struct uefi_variable_store *context)
+static efi_status_t load_variable_index(struct uefi_variable_store *context)
{
struct storage_backend *persistent_store = context->persistent_store.storage_backend;
@@ -583,11 +585,23 @@ static void load_variable_index(struct uefi_variable_store *context)
SMM_VARIABLE_INDEX_STORAGE_UID, 0, context->index_sync_buffer_size,
context->index_sync_buffer, &data_len);
- if (psa_status == PSA_SUCCESS) {
- variable_index_restore(&context->variable_index, data_len,
- context->index_sync_buffer);
+ switch(psa_status) {
+ case PSA_SUCCESS:
+ (void) variable_index_restore(&context->variable_index, data_len,
+ context->index_sync_buffer);
+ break;
+
+ case PSA_ERROR_DOES_NOT_EXIST:
+ IMSG("Index variable does not exist in NV store, continuing with empty index");
+ break;
+
+ default:
+ EMSG("Loading variable index failed: %d", psa_status);
+ return EFI_LOAD_ERROR;
}
}
+
+ return EFI_SUCCESS;
}
static efi_status_t sync_variable_index(const struct uefi_variable_store *context)
--
2.25.1
@@ -0,0 +1,758 @@
From 370811420cfa1c14146f45de308bbccf70408eb8 Mon Sep 17 00:00:00 2001
From: Gabor Toth <gabor.toth2@arm.com>
Date: Fri, 5 Apr 2024 11:19:37 +0200
Subject: [PATCH] Provide crypto api to create uefi priv var fingerprint
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add new call to the crypto backend to calculate a hash of the common
name of the signing certificates Subject and the tbsCertificate
of the top-level issuer certificate.
Signed-off-by: Gabor Toth <gabor.toth2@arm.com>
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TS/trusted-services/+/27953]
---
.../client/caller/packed-c/crypto_caller.h | 1 +
...aller_get_uefi_priv_auth_var_fingerprint.h | 90 ++++++++
.../packed-c/packedc_crypto_client.cpp | 8 +
.../protocol/packed-c/packedc_crypto_client.h | 4 +
.../service/crypto/client/psa/component.cmake | 1 +
.../service/crypto/client/psa/crypto_client.h | 5 +
.../psa/get_uefi_priv_auth_var_fingerprint.c | 21 ++
.../service/crypto/provider/crypto_provider.c | 212 +++++++++++++++---
.../serializer/crypto_provider_serializer.h | 8 +
.../packedc_crypto_provider_serializer.c | 54 +++++
.../backend/direct/uefi_direct_backend.c | 90 ++++++++
deployments/smm-gateway/smm-gateway.cmake | 5 +
.../get_uefi_priv_auth_var_fingerprint.h | 21 ++
protocols/service/crypto/packed-c/opcodes.h | 1 +
14 files changed, 488 insertions(+), 33 deletions(-)
create mode 100644 components/service/crypto/client/caller/packed-c/crypto_caller_get_uefi_priv_auth_var_fingerprint.h
create mode 100644 components/service/crypto/client/psa/get_uefi_priv_auth_var_fingerprint.c
create mode 100644 protocols/service/crypto/packed-c/get_uefi_priv_auth_var_fingerprint.h
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller.h b/components/service/crypto/client/caller/packed-c/crypto_caller.h
index d834bc207..d5dd0f70d 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller.h
@@ -31,5 +31,6 @@
#include "crypto_caller_sign_hash.h"
#include "crypto_caller_verify_hash.h"
#include "crypto_caller_verify_pkcs7_signature.h"
+#include "crypto_caller_get_uefi_priv_auth_var_fingerprint.h"
#endif /* PACKEDC_CRYPTO_CALLER_H */
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_get_uefi_priv_auth_var_fingerprint.h b/components/service/crypto/client/caller/packed-c/crypto_caller_get_uefi_priv_auth_var_fingerprint.h
new file mode 100644
index 000000000..d3446e445
--- /dev/null
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_get_uefi_priv_auth_var_fingerprint.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PACKEDC_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+#define PACKEDC_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+
+#include <common/tlv/tlv.h>
+#include <protocols/common/efi/efi_status.h>
+#include <protocols/rpc/common/packed-c/status.h>
+#include <protocols/service/crypto/packed-c/opcodes.h>
+#include <protocols/service/crypto/packed-c/get_uefi_priv_auth_var_fingerprint.h>
+#include <service/common/client/service_client.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline int crypto_caller_get_uefi_priv_auth_var_fingerprint(struct service_client *context,
+ const uint8_t *signature_cert,
+ uint64_t signature_cert_len,
+ uint8_t *output)
+{
+ efi_status_t efi_status = EFI_SUCCESS;
+ size_t req_len = 0;
+
+ if (signature_cert_len > UINT16_MAX)
+ return RPC_ERROR_INVALID_VALUE;
+
+ struct tlv_record signature_record = {
+ .tag = TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_IN_TAG_SIGNATURE,
+ .length = (uint16_t)signature_cert_len,
+ .value = signature_cert
+ };
+
+ req_len += tlv_required_space(signature_record.length);
+
+ rpc_call_handle call_handle;
+ uint8_t *req_buf;
+
+ call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
+
+ if (call_handle) {
+ uint8_t *resp_buf;
+ size_t resp_len;
+ service_status_t service_status;
+ struct tlv_iterator req_iter;
+
+ tlv_iterator_begin(&req_iter, req_buf, req_len);
+ tlv_encode(&req_iter, &signature_record);
+
+ context->rpc_status = rpc_caller_session_invoke(
+ call_handle, TS_CRYPTO_OPCODE_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT, &resp_buf, &resp_len,
+ &service_status);
+
+ if (context->rpc_status == RPC_SUCCESS) {
+
+ if (service_status == EFI_SUCCESS) {
+
+ struct tlv_const_iterator resp_iter;
+ struct tlv_record decoded_record;
+ tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
+
+ if (tlv_find_decode(&resp_iter,
+ TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_OUT_TAG_IDENTIFIER, &decoded_record)) {
+
+ memcpy(output, decoded_record.value, PSA_HASH_MAX_SIZE);
+ }
+ else {
+ /* Mandatory response parameter missing */
+ efi_status = EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ rpc_caller_session_end(call_handle);
+ }
+
+ return efi_status;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PACKEDC_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H */
diff --git a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
index aaa71f0c8..e0f6a15a8 100644
--- a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
+++ b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
@@ -428,3 +428,11 @@ int packedc_crypto_client::verify_pkcs7_signature(const uint8_t *signature_cert,
hash, hash_len, public_key_cert,
public_key_cert_len);
}
+
+int packedc_crypto_client::get_uefi_priv_auth_var_fingerprint(const uint8_t *signature_cert,
+ uint64_t signature_cert_len,
+ uint8_t *output)
+{
+ return crypto_caller_get_uefi_priv_auth_var_fingerprint(&m_client, signature_cert, signature_cert_len,
+ output);
+}
diff --git a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
index 8d4f60cf9..ec6c51c7f 100644
--- a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
+++ b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
@@ -236,6 +236,10 @@ public:
int verify_pkcs7_signature(const uint8_t *signature_cert, uint64_t signature_cert_len,
const uint8_t *hash, uint64_t hash_len,
const uint8_t *public_key_cert, uint64_t public_key_cert_len);
+
+ int get_uefi_priv_auth_var_fingerprint(const uint8_t *signature_cert,
+ uint64_t signature_cert_len,
+ uint8_t *output);
};
#endif /* PACKEDC_CRYPTO_CLIENT_H */
diff --git a/components/service/crypto/client/psa/component.cmake b/components/service/crypto/client/psa/component.cmake
index 359db3b4a..5bee0c652 100644
--- a/components/service/crypto/client/psa/component.cmake
+++ b/components/service/crypto/client/psa/component.cmake
@@ -32,4 +32,5 @@ target_sources(${TGT} PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/psa_sign_message.c"
"${CMAKE_CURRENT_LIST_DIR}/psa_verify_message.c"
"${CMAKE_CURRENT_LIST_DIR}/verify_pkcs7_signature.c"
+ "${CMAKE_CURRENT_LIST_DIR}/get_uefi_priv_auth_var_fingerprint.c"
)
diff --git a/components/service/crypto/client/psa/crypto_client.h b/components/service/crypto/client/psa/crypto_client.h
index 4b59bbe32..af04df11e 100644
--- a/components/service/crypto/client/psa/crypto_client.h
+++ b/components/service/crypto/client/psa/crypto_client.h
@@ -7,10 +7,15 @@
#ifndef CRYPTO_CLIENT_H
#define CRYPTO_CLIENT_H
+#include <stddef.h>
#include <stdint.h>
int verify_pkcs7_signature(const uint8_t *signature_cert, uint64_t signature_cert_len,
const uint8_t *hash, uint64_t hash_len, const uint8_t *public_key_cert,
uint64_t public_key_cert_len);
+int get_uefi_priv_auth_var_fingerprint_handler(const uint8_t *signature_cert,
+ uint64_t signature_cert_len,
+ uint8_t *output);
+
#endif /* CRYPTO_CLIENT_H */
diff --git a/components/service/crypto/client/psa/get_uefi_priv_auth_var_fingerprint.c b/components/service/crypto/client/psa/get_uefi_priv_auth_var_fingerprint.c
new file mode 100644
index 000000000..702aaa0c4
--- /dev/null
+++ b/components/service/crypto/client/psa/get_uefi_priv_auth_var_fingerprint.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "crypto_caller_selector.h"
+#include "crypto_client.h"
+#include "psa_crypto_client.h"
+
+int get_uefi_priv_auth_var_fingerprint_handler(const uint8_t *signature_cert,
+ uint64_t signature_cert_len,
+ uint8_t *output)
+{
+ if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
+ return psa_crypto_client_instance.init_status;
+
+ return crypto_caller_get_uefi_priv_auth_var_fingerprint(&psa_crypto_client_instance.base,
+ signature_cert, signature_cert_len,
+ output);
+}
diff --git a/components/service/crypto/provider/crypto_provider.c b/components/service/crypto/provider/crypto_provider.c
index 9cd520859..4535d6dbe 100644
--- a/components/service/crypto/provider/crypto_provider.c
+++ b/components/service/crypto/provider/crypto_provider.c
@@ -3,12 +3,15 @@
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <protocols/common/efi/efi_status.h>
#include <protocols/rpc/common/packed-c/status.h>
#include <protocols/service/crypto/packed-c/opcodes.h>
#include <service/crypto/backend/crypto_backend.h>
#include <service/crypto/provider/crypto_provider.h>
+#include <compiler.h>
#include <stdint.h>
#include <stdlib.h>
+#include <string.h>
#include "crypto_partition.h"
#include "crypto_uuid.h"
@@ -28,25 +31,27 @@ static rpc_status_t copy_key_handler(void *context, struct rpc_request *req);
static rpc_status_t purge_key_handler(void *context, struct rpc_request *req);
static rpc_status_t get_key_attributes_handler(void *context, struct rpc_request *req);
static rpc_status_t verify_pkcs7_signature_handler(void *context, struct rpc_request *req);
+static rpc_status_t get_uefi_priv_auth_var_fingerprint_handler(void *context, struct rpc_request *req);
/* Handler mapping table for service */
static const struct service_handler handler_table[] = {
- { TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler },
- { TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler },
- { TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler },
- { TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler },
- { TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler },
- { TS_CRYPTO_OPCODE_SIGN_HASH, asymmetric_sign_handler },
- { TS_CRYPTO_OPCODE_VERIFY_HASH, asymmetric_verify_handler },
- { TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler },
- { TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler },
- { TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler },
- { TS_CRYPTO_OPCODE_COPY_KEY, copy_key_handler },
- { TS_CRYPTO_OPCODE_PURGE_KEY, purge_key_handler },
- { TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES, get_key_attributes_handler },
- { TS_CRYPTO_OPCODE_SIGN_MESSAGE, asymmetric_sign_handler },
- { TS_CRYPTO_OPCODE_VERIFY_MESSAGE, asymmetric_verify_handler },
- { TS_CRYPTO_OPCODE_VERIFY_PKCS7_SIGNATURE, verify_pkcs7_signature_handler },
+ { TS_CRYPTO_OPCODE_GENERATE_KEY, generate_key_handler },
+ { TS_CRYPTO_OPCODE_DESTROY_KEY, destroy_key_handler },
+ { TS_CRYPTO_OPCODE_EXPORT_KEY, export_key_handler },
+ { TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY, export_public_key_handler },
+ { TS_CRYPTO_OPCODE_IMPORT_KEY, import_key_handler },
+ { TS_CRYPTO_OPCODE_SIGN_HASH, asymmetric_sign_handler },
+ { TS_CRYPTO_OPCODE_VERIFY_HASH, asymmetric_verify_handler },
+ { TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT, asymmetric_decrypt_handler },
+ { TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT, asymmetric_encrypt_handler },
+ { TS_CRYPTO_OPCODE_GENERATE_RANDOM, generate_random_handler },
+ { TS_CRYPTO_OPCODE_COPY_KEY, copy_key_handler },
+ { TS_CRYPTO_OPCODE_PURGE_KEY, purge_key_handler },
+ { TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES, get_key_attributes_handler },
+ { TS_CRYPTO_OPCODE_SIGN_MESSAGE, asymmetric_sign_handler },
+ { TS_CRYPTO_OPCODE_VERIFY_MESSAGE, asymmetric_verify_handler },
+ { TS_CRYPTO_OPCODE_VERIFY_PKCS7_SIGNATURE, verify_pkcs7_signature_handler },
+ { TS_CRYPTO_OPCODE_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT, get_uefi_priv_auth_var_fingerprint_handler },
};
struct rpc_service_interface *
@@ -664,33 +669,44 @@ static rpc_status_t verify_pkcs7_signature_handler(void *context, struct rpc_req
}
if (rpc_status == RPC_SUCCESS) {
- /* Parse the public key certificate */
- mbedtls_x509_crt signer_certificate;
+ /* Parse the PKCS#7 DER encoded signature block */
+ mbedtls_pkcs7 pkcs7_structure;
- mbedtls_x509_crt_init(&signer_certificate);
+ mbedtls_pkcs7_init(&pkcs7_structure);
- mbedtls_status = mbedtls_x509_crt_parse_der(&signer_certificate, public_key_cert,
- public_key_cert_len);
+ mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
+ signature_cert_len);
- if (mbedtls_status == 0) {
- /* Parse the PKCS#7 DER encoded signature block */
- mbedtls_pkcs7 pkcs7_structure;
+ if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
- mbedtls_pkcs7_init(&pkcs7_structure);
+ /*
+ * If a separate public key is provided, verify the signature with it,
+ * else use the key from the pkcs7 signature structure, because it is
+ * a self-signed certificate.
+ */
+ if(public_key_cert_len) {
+ /* Parse the public key certificate */
+ mbedtls_x509_crt signer_certificate;
- mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
- signature_cert_len);
+ mbedtls_x509_crt_init(&signer_certificate);
- if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
- /* Verify hash against signed hash */
+ mbedtls_status = mbedtls_x509_crt_parse_der(&signer_certificate, public_key_cert,
+ public_key_cert_len);
+
+ if (mbedtls_status == 0) {
+ /* Verify hash against signed hash */
+ mbedtls_status = mbedtls_pkcs7_signed_hash_verify(
+ &pkcs7_structure, &signer_certificate, hash, hash_len);
+ }
+
+ mbedtls_x509_crt_free(&signer_certificate);
+ } else {
mbedtls_status = mbedtls_pkcs7_signed_hash_verify(
- &pkcs7_structure, &signer_certificate, hash, hash_len);
+ &pkcs7_structure, &pkcs7_structure.private_signed_data.private_certs, hash, hash_len);
}
-
- mbedtls_pkcs7_free(&pkcs7_structure);
}
- mbedtls_x509_crt_free(&signer_certificate);
+ mbedtls_pkcs7_free(&pkcs7_structure);
}
free(signature_cert);
@@ -702,6 +718,128 @@ static rpc_status_t verify_pkcs7_signature_handler(void *context, struct rpc_req
return rpc_status;
}
+
+/*
+ * Official value: http://www.oid-info.com/get/2.5.4.3
+ * Hex converter: https://misc.daniel-marschall.de/asn.1/oid-converter/online.php
+ */
+static const mbedtls_asn1_buf* findCommonName(const mbedtls_x509_name *name)
+{
+ uint8_t CN_oid_tag = 0x06;
+ uint8_t CN_oid_len = 0x03;
+ uint8_t CN_oid_val[3] = {0x55, 0x04, 0x03};
+
+ while (name)
+ {
+ if (name->oid.tag == CN_oid_tag && name->oid.len == CN_oid_len) {
+ if (name->oid.p != NULL) {
+ if (!memcmp(name->oid.p, CN_oid_val, CN_oid_len))
+ return &name->val;
+ }
+ }
+
+ name = name->next;
+ }
+
+ return NULL;
+}
+
+static rpc_status_t get_uefi_priv_auth_var_fingerprint_handler(void *context, struct rpc_request *req)
+{
+ rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+ struct rpc_buffer *req_buf = &req->request;
+ const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+
+ int mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+
+ uint8_t *signature_cert = NULL;
+ uint64_t signature_cert_len = 0;
+
+ if (serializer) {
+ /* First collect the lengths of the field */
+ rpc_status = serializer->deserialize_get_uefi_priv_auth_var_fingerprint_req(
+ req_buf, NULL, &signature_cert_len);
+
+ if (rpc_status == RPC_SUCCESS) {
+ /* Allocate the needed space and get the data */
+ signature_cert = (uint8_t *)malloc(signature_cert_len);
+
+ if (signature_cert) {
+ rpc_status = serializer->deserialize_get_uefi_priv_auth_var_fingerprint_req(
+ req_buf, signature_cert, &signature_cert_len);
+ } else {
+ rpc_status = RPC_ERROR_RESOURCE_FAILURE;
+ }
+ }
+ }
+
+ if (rpc_status == RPC_SUCCESS) {
+ /* Parse the PKCS#7 DER encoded signature block */
+ mbedtls_pkcs7 pkcs7_structure;
+
+ mbedtls_pkcs7_init(&pkcs7_structure);
+
+ mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
+ signature_cert_len);
+
+ if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
+
+ uint8_t output_buffer[PSA_HASH_MAX_SIZE] = { 0 };
+ size_t __maybe_unused output_size = 0;
+ const mbedtls_asn1_buf *signerCertCN = NULL;
+ const mbedtls_x509_crt *topLevelCert = &pkcs7_structure.private_signed_data.private_certs;
+ const mbedtls_x509_buf *toplevelCertTbs = NULL;
+ struct rpc_buffer *resp_buf = &req->response;;
+ psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
+
+ /* Find common name field of the signing certificate, which is the first in the chain */
+ signerCertCN = findCommonName(&topLevelCert->subject);
+ if (!signerCertCN)
+ mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+
+ /* Get the TopLevel certificate which is the last in the chain */
+ while(topLevelCert->next)
+ topLevelCert = topLevelCert->next;
+ toplevelCertTbs = &topLevelCert->tbs;
+
+ /* Hash the data to create the fingerprint */
+ op = psa_hash_operation_init();
+
+ if (psa_hash_setup(&op, PSA_ALG_SHA_256) != PSA_SUCCESS)
+ mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+
+ if (psa_hash_update(&op, signerCertCN->p, signerCertCN->len)) {
+ psa_hash_abort(&op);
+ mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+ }
+
+ if (psa_hash_update(&op, toplevelCertTbs->p, toplevelCertTbs->len)) {
+ psa_hash_abort(&op);
+ mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+ }
+
+ if (psa_hash_finish(&op, (uint8_t*)&output_buffer, PSA_HASH_MAX_SIZE, &output_size)) {
+ psa_hash_abort(&op);
+ mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+ }
+
+ /* Clear the remaining part of the buffer for consistency */
+ memset(&output_buffer[output_size], 0, PSA_HASH_MAX_SIZE - output_size);
+
+ rpc_status = serializer->serialize_get_uefi_priv_auth_var_fingerprint_resp(
+ resp_buf, (uint8_t*)&output_buffer);
+ }
+
+ mbedtls_pkcs7_free(&pkcs7_structure);
+ }
+
+ free(signature_cert);
+
+ /* Provide the result of the verification */
+ req->service_status = (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) ? EFI_SUCCESS : EFI_COMPROMISED_DATA;
+
+ return rpc_status;
+}
#else
static rpc_status_t verify_pkcs7_signature_handler(void *context, struct rpc_request *req)
{
@@ -710,4 +848,12 @@ static rpc_status_t verify_pkcs7_signature_handler(void *context, struct rpc_req
return RPC_ERROR_INTERNAL;
}
+
+static rpc_status_t get_uefi_priv_auth_var_fingerprint_handler(void *context, struct rpc_request *req)
+{
+ (void)context;
+ (void)req;
+
+ return RPC_ERROR_INTERNAL;
+}
#endif
diff --git a/components/service/crypto/provider/serializer/crypto_provider_serializer.h b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
index bd5336c3d..2b965afdb 100644
--- a/components/service/crypto/provider/serializer/crypto_provider_serializer.h
+++ b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
@@ -126,6 +126,14 @@ struct crypto_provider_serializer {
uint8_t *hash, uint64_t *hash_len,
uint8_t *public_key_cert,
uint64_t *public_key_cert_len);
+
+ /* Operation: get_uefi_priv_auth_var_fingerprintentifier */
+ rpc_status_t (*deserialize_get_uefi_priv_auth_var_fingerprint_req)(const struct rpc_buffer *req_buf,
+ uint8_t *signed_data,
+ uint64_t *signed_data_len);
+
+ rpc_status_t (*serialize_get_uefi_priv_auth_var_fingerprint_resp)(struct rpc_buffer *resp_buf,
+ const uint8_t *output);
};
#endif /* CRYPTO_PROVIDER_SERIALIZER_H */
diff --git a/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
index 050ef2f7d..89e07e2c8 100644
--- a/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
+++ b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
@@ -22,6 +22,7 @@
#include <protocols/service/crypto/packed-c/sign_hash.h>
#include <protocols/service/crypto/packed-c/verify_hash.h>
#include <protocols/service/crypto/packed-c/verify_pkcs7_signature.h>
+#include <protocols/service/crypto/packed-c/get_uefi_priv_auth_var_fingerprint.h>
#include <service/crypto/backend/crypto_backend.h>
#include <stdlib.h>
#include <string.h>
@@ -675,6 +676,57 @@ static rpc_status_t deserialize_verify_pkcs7_signature_req(
return rpc_status;
}
+/* Operation: get_uefi_priv_auth_var_fingerprintentifier */
+static rpc_status_t deserialize_get_uefi_priv_auth_var_fingerprint_req(const struct rpc_buffer *req_buf,
+ uint8_t *signed_data,
+ uint64_t *signed_data_len)
+{
+ rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+
+ if (req_buf->data_length) {
+ struct tlv_const_iterator req_iter;
+ struct tlv_record decoded_record;
+
+ rpc_status = RPC_SUCCESS;
+
+ tlv_const_iterator_begin(&req_iter, (uint8_t *)req_buf->data, req_buf->data_length);
+
+ if (tlv_find_decode(&req_iter, TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_IN_TAG_SIGNATURE,
+ &decoded_record)) {
+ *signed_data_len = decoded_record.length;
+
+ if (signed_data)
+ memcpy(signed_data, decoded_record.value, decoded_record.length);
+ } else {
+ /* Default to a zero length */
+ *signed_data_len = 0;
+ }
+ }
+
+ return rpc_status;
+}
+
+static rpc_status_t serialize_get_uefi_priv_auth_var_fingerprint_resp(struct rpc_buffer *resp_buf,
+ const uint8_t *output)
+{
+ rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+ struct tlv_iterator resp_iter;
+ struct tlv_record out_record;
+
+ out_record.tag = TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_OUT_TAG_IDENTIFIER;
+ out_record.length = PSA_HASH_MAX_SIZE;
+ out_record.value = output;
+
+ tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+
+ if (tlv_encode(&resp_iter, &out_record)) {
+ resp_buf->data_length = tlv_required_space(PSA_HASH_MAX_SIZE);
+ rpc_status = RPC_SUCCESS;
+ }
+
+ return rpc_status;
+}
+
/* Singleton method to provide access to the serializer instance */
const struct crypto_provider_serializer *packedc_crypto_provider_serializer_instance(void)
{
@@ -704,6 +756,8 @@ const struct crypto_provider_serializer *packedc_crypto_provider_serializer_inst
deserialize_generate_random_req,
serialize_generate_random_resp,
deserialize_verify_pkcs7_signature_req,
+ deserialize_get_uefi_priv_auth_var_fingerprint_req,
+ serialize_get_uefi_priv_auth_var_fingerprint_resp
};
return &instance;
diff --git a/components/service/uefi/smm_variable/backend/direct/uefi_direct_backend.c b/components/service/uefi/smm_variable/backend/direct/uefi_direct_backend.c
index bf978c5dd..c7ca07254 100644
--- a/components/service/uefi/smm_variable/backend/direct/uefi_direct_backend.c
+++ b/components/service/uefi/smm_variable/backend/direct/uefi_direct_backend.c
@@ -9,6 +9,8 @@
#include <mbedtls/pkcs7.h>
#include <mbedtls/x509_crt.h>
#include <stdint.h>
+#include <string.h>
+#include <compiler.h>
int verify_pkcs7_signature(const uint8_t *signature_cert, uint64_t signature_cert_len,
const uint8_t *hash, uint64_t hash_len, const uint8_t *public_key_cert,
@@ -46,3 +48,91 @@ int verify_pkcs7_signature(const uint8_t *signature_cert, uint64_t signature_cer
return mbedtls_status;
}
+
+/*
+ * Official value: http://www.oid-info.com/get/2.5.4.3
+ * Hex converter: https://misc.daniel-marschall.de/asn.1/oid-converter/online.php
+ */
+static const mbedtls_asn1_buf* findCommonName(const mbedtls_x509_name *name)
+{
+ uint8_t CN_oid_tag = 0x06;
+ uint8_t CN_oid_len = 0x03;
+ uint8_t CN_oid_val[3] = {0x55, 0x04, 0x03};
+
+ while (name)
+ {
+ if (name->oid.tag == CN_oid_tag && name->oid.len == CN_oid_len) {
+ if (name->oid.p != NULL) {
+ if (!memcmp(name->oid.p, CN_oid_val, CN_oid_len))
+ return &name->val;
+ }
+ }
+
+ name = name->next;
+ }
+
+ return NULL;
+}
+
+int get_uefi_priv_auth_var_fingerprint_handler(const uint8_t *signature_cert,
+ uint64_t signature_cert_len,
+ uint8_t *output)
+{
+ int mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+
+ /* Parse the PKCS#7 DER encoded signature block */
+ mbedtls_pkcs7 pkcs7_structure;
+
+ mbedtls_pkcs7_init(&pkcs7_structure);
+
+ mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
+ signature_cert_len);
+
+ if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
+
+ uint8_t output_buffer[PSA_HASH_MAX_SIZE] = { 0 };
+ size_t __maybe_unused output_size = 0;
+ const mbedtls_asn1_buf *signerCertCN = NULL;
+ const mbedtls_x509_crt *topLevelCert = &pkcs7_structure.private_signed_data.private_certs;
+ const mbedtls_x509_buf *toplevelCertTbs = NULL;
+ psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
+
+ /* Find common name field of the signing certificate, which is the first in the chain */
+ signerCertCN = findCommonName(&topLevelCert->subject);
+ if (!signerCertCN)
+ mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+
+ /* Get the TopLevel certificate which is the last in the chain */
+ while(topLevelCert->next)
+ topLevelCert = topLevelCert->next;
+ toplevelCertTbs = &topLevelCert->tbs;
+
+ /* Hash the data to create the fingerprint */
+ op = psa_hash_operation_init();
+
+ if (psa_hash_setup(&op, PSA_ALG_SHA_256) != PSA_SUCCESS)
+ mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+
+ if (psa_hash_update(&op, signerCertCN->p, signerCertCN->len)) {
+ psa_hash_abort(&op);
+ mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+ }
+
+ if (psa_hash_update(&op, toplevelCertTbs->p, toplevelCertTbs->len)) {
+ psa_hash_abort(&op);
+ mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+ }
+
+ if (psa_hash_finish(&op, (uint8_t*)&output_buffer, PSA_HASH_MAX_SIZE, &output_size)) {
+ psa_hash_abort(&op);
+ mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+ }
+
+ /* Clear the remaining part of the buffer for consistency */
+ memset(&output_buffer[output_size], 0, PSA_HASH_MAX_SIZE - output_size);
+ }
+
+ mbedtls_pkcs7_free(&pkcs7_structure);
+
+ return mbedtls_status;
+}
diff --git a/deployments/smm-gateway/smm-gateway.cmake b/deployments/smm-gateway/smm-gateway.cmake
index e5ee03b60..de519892d 100644
--- a/deployments/smm-gateway/smm-gateway.cmake
+++ b/deployments/smm-gateway/smm-gateway.cmake
@@ -17,6 +17,11 @@ include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
target_link_libraries(smm-gateway PRIVATE MbedTLS::mbedcrypto)
target_link_libraries(smm-gateway PRIVATE MbedTLS::mbedx509)
+# Pass the location of the mbedtls config file to C preprocessor.
+target_compile_definitions(smm-gateway PRIVATE
+ MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}"
+)
+
target_compile_definitions(smm-gateway PRIVATE
-DUEFI_INTERNAL_CRYPTO
)
diff --git a/protocols/service/crypto/packed-c/get_uefi_priv_auth_var_fingerprint.h b/protocols/service/crypto/packed-c/get_uefi_priv_auth_var_fingerprint.h
new file mode 100644
index 000000000..29964b33c
--- /dev/null
+++ b/protocols/service/crypto/packed-c/get_uefi_priv_auth_var_fingerprint.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+#define TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+
+#include <stdint.h>
+
+/* Variable length output parameter tags */
+enum {
+ TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_OUT_TAG_IDENTIFIER = 1,
+};
+
+/* Variable length input parameter tags */
+enum {
+ TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_IN_TAG_SIGNATURE = 1,
+};
+
+#endif /* TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H */
diff --git a/protocols/service/crypto/packed-c/opcodes.h b/protocols/service/crypto/packed-c/opcodes.h
index 35b81599b..8bc2b49b0 100644
--- a/protocols/service/crypto/packed-c/opcodes.h
+++ b/protocols/service/crypto/packed-c/opcodes.h
@@ -28,6 +28,7 @@
#define TS_CRYPTO_OPCODE_SIGN_MESSAGE (TS_CRYPTO_OPCODE_BASE + 16)
#define TS_CRYPTO_OPCODE_VERIFY_MESSAGE (TS_CRYPTO_OPCODE_BASE + 17)
#define TS_CRYPTO_OPCODE_VERIFY_PKCS7_SIGNATURE (TS_CRYPTO_OPCODE_BASE + 18)
+#define TS_CRYPTO_OPCODE_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT (TS_CRYPTO_OPCODE_BASE + 19)
/* Hash operations */
#define TS_CRYPTO_OPCODE_HASH_BASE (0x0200)
--
2.25.1
@@ -0,0 +1,146 @@
From 5b418e141aadcb6604406f75e156317bd143d898 Mon Sep 17 00:00:00 2001
From: Gabor Toth <gabor.toth2@arm.com>
Date: Fri, 5 Apr 2024 11:27:15 +0200
Subject: [PATCH 1/3] Add timestamp validation for uefi variables
Return failure if uefi variable creation or update is not
requested with newer timestamp.
Signed-off-by: Gabor Toth <gabor.toth2@arm.com>
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TS/trusted-services/+/27955]
---
.../backend/uefi_variable_store.c | 35 +++++++++++++++----
.../smm_variable/backend/variable_index.c | 1 +
.../smm_variable/backend/variable_index.h | 1 +
3 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/components/service/uefi/smm_variable/backend/uefi_variable_store.c b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
index c1691dc8f..1b624f0c9 100644
--- a/components/service/uefi/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
@@ -76,6 +76,7 @@ static efi_status_t verify_var_by_key_var(const efi_data_map *new_var,
const uint8_t *hash_buffer, size_t hash_len);
static efi_status_t authenticate_variable(const struct uefi_variable_store *context,
+ EFI_TIME *timestamp,
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var);
#endif
@@ -197,6 +198,7 @@ efi_status_t uefi_variable_store_set_variable(const struct uefi_variable_store *
const SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var)
{
bool should_sync_index = false;
+ EFI_TIME timestamp = { 0 };
/* Validate incoming request */
efi_status_t status = check_name_terminator(var->Name, var->NameSize);
@@ -225,6 +227,9 @@ efi_status_t uefi_variable_store_set_variable(const struct uefi_variable_store *
return EFI_OUT_OF_RESOURCES;
}
+ /* Save the timestamp into a buffer, which can be overwritten by the authentication function */
+ memcpy(&timestamp, &info->metadata.timestamp, sizeof(EFI_TIME));
+
/* Control access */
status = check_access_permitted_on_set(context, info, var);
@@ -240,7 +245,7 @@ efi_status_t uefi_variable_store_set_variable(const struct uefi_variable_store *
if (info->metadata.attributes &
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
status = authenticate_variable(
- context, (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
+ context, &timestamp, (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
if (status != EFI_SUCCESS)
return status;
@@ -326,7 +331,7 @@ efi_status_t uefi_variable_store_set_variable(const struct uefi_variable_store *
*/
if (var->Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
status = authenticate_variable(
- context, (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
+ context, &timestamp, (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
if (status != EFI_SUCCESS)
return status;
@@ -358,9 +363,11 @@ efi_status_t uefi_variable_store_set_variable(const struct uefi_variable_store *
if (should_sync_index)
status = sync_variable_index(context);
- /* Store any variable data to the storage backend */
- if (info->is_variable_set && (status == EFI_SUCCESS))
+ /* Store any variable data to the storage backend with the updated metadata */
+ if (info->is_variable_set && (status == EFI_SUCCESS)) {
+ memcpy(&info->metadata.timestamp, &timestamp, sizeof(EFI_TIME));
status = store_variable_data(context, info, var);
+ }
}
variable_index_remove_unused_entry(&context->variable_index, info);
@@ -1106,6 +1113,7 @@ static efi_status_t verify_var_by_key_var(const efi_data_map *new_var,
* then verifies it.
*/
static efi_status_t authenticate_variable(const struct uefi_variable_store *context,
+ EFI_TIME *timestamp,
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var)
{
efi_status_t status = EFI_SUCCESS;
@@ -1223,9 +1231,7 @@ static efi_status_t authenticate_variable(const struct uefi_variable_store *cont
*
* UEFI: Page 253
* 2. Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components
- * of the TimeStamp value are set to zero. Unless the EFI_VARIABLE_APPEND_WRITE
- * attribute is set, verify that the TimeStamp value is later than the current
- * timestamp value associated with the variable
+ * of the TimeStamp value are set to zero.
*/
if ((var_map.efi_auth_descriptor->TimeStamp.Pad1 != 0) ||
(var_map.efi_auth_descriptor->TimeStamp.Pad2 != 0) ||
@@ -1235,6 +1241,21 @@ static efi_status_t authenticate_variable(const struct uefi_variable_store *cont
return EFI_SECURITY_VIOLATION;
}
+ /**
+ * UEFI: Page 253
+ * Unless the EFI_VARIABLE_APPEND_WRITE attribute is set, verify
+ * that the TimeStamp value is later than the current
+ * timestamp value associated with the variable
+ */
+ if (!(var->Attributes & EFI_VARIABLE_APPEND_WRITE)) {
+ if (memcmp(&var_map.efi_auth_descriptor->TimeStamp, timestamp, sizeof(EFI_GUID)) <= 0) {
+ EMSG("Timestamp violation");
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ /* Save new timestamp */
+ memcpy(timestamp, &var_map.efi_auth_descriptor->TimeStamp, sizeof(EFI_TIME));
+ }
/* Calculate hash for the variable only once */
hash_result = calc_variable_hash(&var_map, (uint8_t *)&hash_buffer, sizeof(hash_buffer),
&hash_len);
diff --git a/components/service/uefi/smm_variable/backend/variable_index.c b/components/service/uefi/smm_variable/backend/variable_index.c
index e2fe6dd38..f4194d2d3 100644
--- a/components/service/uefi/smm_variable/backend/variable_index.c
+++ b/components/service/uefi/smm_variable/backend/variable_index.c
@@ -198,6 +198,7 @@ static struct variable_entry *add_entry(const struct variable_index *context, co
/* Initialize metadata */
info->metadata.uid = generate_uid(context, guid, name_size, name);
info->metadata.guid = *guid;
+ memset(&info->metadata.timestamp, 0, sizeof(EFI_TIME));
info->metadata.attributes = 0;
info->metadata.name_size = name_size;
memcpy(info->metadata.name, name, name_size);
diff --git a/components/service/uefi/smm_variable/backend/variable_index.h b/components/service/uefi/smm_variable/backend/variable_index.h
index 5d3b7a7c6..7eef7b86b 100644
--- a/components/service/uefi/smm_variable/backend/variable_index.h
+++ b/components/service/uefi/smm_variable/backend/variable_index.h
@@ -32,6 +32,7 @@ extern "C" {
*/
struct variable_metadata {
EFI_GUID guid;
+ EFI_TIME timestamp;
size_t name_size;
int16_t name[VARIABLE_INDEX_MAX_NAME_SIZE];
uint32_t attributes;
--
2.25.1
@@ -0,0 +1,282 @@
From 19e79008e0fa3193b54bf6499516dc75cb10f6ec Mon Sep 17 00:00:00 2001
From: Gabor Toth <gabor.toth2@arm.com>
Date: Thu, 11 Apr 2024 13:42:03 +0200
Subject: [PATCH 2/3] Isolate common uefi variable authentication steps
Currently all auth variables are authenticated with the secure boot
keys. To introduce corrent check for Private Authenticated Variables
first separate the common steps from the secure boot related steps.
Signed-off-by: Gabor Toth <gabor.toth2@arm.com>
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TS/trusted-services/+/27956]
---
.../backend/uefi_variable_store.c | 191 ++++++++++--------
1 file changed, 103 insertions(+), 88 deletions(-)
diff --git a/components/service/uefi/smm_variable/backend/uefi_variable_store.c b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
index 1b624f0c9..1384d0def 100644
--- a/components/service/uefi/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
@@ -78,6 +78,12 @@ static efi_status_t verify_var_by_key_var(const efi_data_map *new_var,
static efi_status_t authenticate_variable(const struct uefi_variable_store *context,
EFI_TIME *timestamp,
SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var);
+
+static efi_status_t authenticate_secure_boot_variable(const struct uefi_variable_store *context,
+ efi_data_map* var_map,
+ uint8_t* hash_buffer,
+ size_t hash_len,
+ uint64_t max_variable_size);
#endif
static efi_status_t store_variable_data(const struct uefi_variable_store *context,
@@ -1118,30 +1124,109 @@ static efi_status_t authenticate_variable(const struct uefi_variable_store *cont
{
efi_status_t status = EFI_SUCCESS;
EFI_GUID pkcs7_guid = EFI_CERT_TYPE_PKCS7_GUID;
- EFI_GUID global_variable_guid = EFI_GLOBAL_VARIABLE;
- EFI_GUID security_database_guid = EFI_IMAGE_SECURITY_DATABASE_GUID;
SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO variable_info = { 0, 0, 0, 0 };
- SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *pk_variable = NULL;
- size_t pk_payload_size = 0;
efi_data_map var_map = { NULL, NULL, NULL, 0, 0, NULL, 0, NULL };
uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
size_t hash_len = 0;
- bool hash_result = false;
/* Create a map of the fields of the new variable including the auth header */
if (!init_efi_data_map(var, true, &var_map))
return EFI_SECURITY_VIOLATION;
- /* database variables can be verified by either PK or KEK while images
- * should be checked by db and dbx so the length of two will be enough.
- */
- SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *allowed_key_store_variables[] = { NULL, NULL };
-
/* Find the maximal size of variables for the GetVariable operation */
status = uefi_variable_store_query_variable_info(context, &variable_info);
if (status != EFI_SUCCESS)
return EFI_SECURITY_VIOLATION;
+ /**
+ * UEFI: Page 246
+ * If the EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set in a
+ * SetVariable() call, and firmware does not support signature type of the certificate
+ * included in the EFI_VARIABLE_AUTHENTICATION_2 descriptor, then the SetVariable() call
+ * shall return EFI_INVALID_PARAMETER. The list of signature types supported by the
+ * firmware is defined by the SignatureSupport variable. Signature type of the certificate
+ * is defined by its digest and encryption algorithms.
+ */
+ /* TODO: Should support WIN_CERT_TYPE_PKCS_SIGNED_DATA and WIN_CERT_TYPE_EFI_PKCS115 */
+ if (var_map.efi_auth_descriptor->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID)
+ return EFI_INVALID_PARAMETER;
+
+ /* Only a CertType of EFI_CERT_TYPE_PKCS7_GUID is accepted */
+ if (!compare_guid(&var_map.efi_auth_descriptor->AuthInfo.CertType, &pkcs7_guid))
+ return EFI_SECURITY_VIOLATION;
+
+ /**
+ * Time associated with the authentication descriptor. For the TimeStamp value,
+ * components Pad1, Nanosecond, TimeZone, Daylight and Pad2 shall be set to 0.
+ * This means that the time shall always be expressed in GMT.
+ *
+ * UEFI: Page 253
+ * 2. Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components
+ * of the TimeStamp value are set to zero.
+ */
+ if ((var_map.efi_auth_descriptor->TimeStamp.Pad1 != 0) ||
+ (var_map.efi_auth_descriptor->TimeStamp.Pad2 != 0) ||
+ (var_map.efi_auth_descriptor->TimeStamp.Nanosecond != 0) ||
+ (var_map.efi_auth_descriptor->TimeStamp.TimeZone != 0) ||
+ (var_map.efi_auth_descriptor->TimeStamp.Daylight != 0)) {
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ /**
+ * UEFI: Page 253
+ * Unless the EFI_VARIABLE_APPEND_WRITE attribute is set, verify
+ * that the TimeStamp value is later than the current
+ * timestamp value associated with the variable
+ */
+ if (!(var->Attributes & EFI_VARIABLE_APPEND_WRITE)) {
+ if (memcmp(&var_map.efi_auth_descriptor->TimeStamp, timestamp, sizeof(EFI_GUID)) <= 0) {
+ EMSG("Timestamp violation");
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ /* Save new timestamp */
+ memcpy(timestamp, &var_map.efi_auth_descriptor->TimeStamp, sizeof(EFI_TIME));
+ }
+ /* Calculate hash for the variable only once */
+ if (calc_variable_hash(&var_map, (uint8_t *)&hash_buffer, sizeof(hash_buffer), &hash_len) == 0) {
+ status = EFI_SECURITY_VIOLATION;
+ }
+
+ /* Run Secure Boot related authentication steps */
+ status = authenticate_secure_boot_variable(context, &var_map, (uint8_t*) &hash_buffer, hash_len, variable_info.MaximumVariableSize);
+
+ /* Remove the authentication header from the variable if the authentication is successful */
+ if (status == EFI_SUCCESS) {
+ uint8_t *smm_payload =
+ (uint8_t *)var + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(var);
+
+ memmove(smm_payload, var_map.payload, var_map.payload_len);
+ memset((uint8_t *)smm_payload + var_map.payload_len, 0,
+ var_map.efi_auth_descriptor_len);
+
+ var->DataSize -= var_map.efi_auth_descriptor_len;
+ }
+
+ return status;
+}
+
+static efi_status_t authenticate_secure_boot_variable(const struct uefi_variable_store *context,
+ efi_data_map* var_map,
+ uint8_t* hash_buffer,
+ size_t hash_len,
+ uint64_t max_variable_size)
+{
+ efi_status_t status = EFI_SUCCESS;
+ EFI_GUID global_variable_guid = EFI_GLOBAL_VARIABLE;
+ EFI_GUID security_database_guid = EFI_IMAGE_SECURITY_DATABASE_GUID;
+ SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *pk_variable = NULL;
+ size_t pk_payload_size = 0;
+
+ /* database variables can be verified by either PK or KEK while images
+ * should be checked by db and dbx so the length of two will be enough.
+ */
+ SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *allowed_key_store_variables[] = { NULL, NULL };
+
/**
* UEFI: Page 253
* 3. If the variable SetupMode==1, and the variable is a secure
@@ -1166,14 +1251,14 @@ static efi_status_t authenticate_variable(const struct uefi_variable_store *cont
* Platform Key is checked to enable or disable authentication.
*/
create_smm_variable(&pk_variable, sizeof(EFI_PLATFORM_KEY_NAME),
- variable_info.MaximumVariableSize, (uint8_t *)EFI_PLATFORM_KEY_NAME,
+ max_variable_size, (uint8_t *)EFI_PLATFORM_KEY_NAME,
&global_variable_guid);
if (!pk_variable)
return EFI_OUT_OF_RESOURCES;
status = uefi_variable_store_get_variable(
- context, pk_variable, variable_info.MaximumVariableSize, &pk_payload_size);
+ context, pk_variable, max_variable_size, &pk_payload_size);
/* If PK does not exist authentication is disabled */
if (status != EFI_SUCCESS) {
@@ -1207,66 +1292,8 @@ static efi_status_t authenticate_variable(const struct uefi_variable_store *cont
goto end;
}
- /**
- * UEFI: Page 246
- * If the EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set in a
- * SetVariable() call, and firmware does not support signature type of the certificate
- * included in the EFI_VARIABLE_AUTHENTICATION_2 descriptor, then the SetVariable() call
- * shall return EFI_INVALID_PARAMETER. The list of signature types supported by the
- * firmware is defined by the SignatureSupport variable. Signature type of the certificate
- * is defined by its digest and encryption algorithms.
- */
- /* TODO: Should support WIN_CERT_TYPE_PKCS_SIGNED_DATA and WIN_CERT_TYPE_EFI_PKCS115 */
- if (var_map.efi_auth_descriptor->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID)
- return EFI_INVALID_PARAMETER;
-
- /* Only a CertType of EFI_CERT_TYPE_PKCS7_GUID is accepted */
- if (!compare_guid(&var_map.efi_auth_descriptor->AuthInfo.CertType, &pkcs7_guid))
- return EFI_SECURITY_VIOLATION;
-
- /**
- * Time associated with the authentication descriptor. For the TimeStamp value,
- * components Pad1, Nanosecond, TimeZone, Daylight and Pad2 shall be set to 0.
- * This means that the time shall always be expressed in GMT.
- *
- * UEFI: Page 253
- * 2. Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components
- * of the TimeStamp value are set to zero.
- */
- if ((var_map.efi_auth_descriptor->TimeStamp.Pad1 != 0) ||
- (var_map.efi_auth_descriptor->TimeStamp.Pad2 != 0) ||
- (var_map.efi_auth_descriptor->TimeStamp.Nanosecond != 0) ||
- (var_map.efi_auth_descriptor->TimeStamp.TimeZone != 0) ||
- (var_map.efi_auth_descriptor->TimeStamp.Daylight != 0)) {
- return EFI_SECURITY_VIOLATION;
- }
-
- /**
- * UEFI: Page 253
- * Unless the EFI_VARIABLE_APPEND_WRITE attribute is set, verify
- * that the TimeStamp value is later than the current
- * timestamp value associated with the variable
- */
- if (!(var->Attributes & EFI_VARIABLE_APPEND_WRITE)) {
- if (memcmp(&var_map.efi_auth_descriptor->TimeStamp, timestamp, sizeof(EFI_GUID)) <= 0) {
- EMSG("Timestamp violation");
- return EFI_SECURITY_VIOLATION;
- }
-
- /* Save new timestamp */
- memcpy(timestamp, &var_map.efi_auth_descriptor->TimeStamp, sizeof(EFI_TIME));
- }
- /* Calculate hash for the variable only once */
- hash_result = calc_variable_hash(&var_map, (uint8_t *)&hash_buffer, sizeof(hash_buffer),
- &hash_len);
-
- if (!hash_result) {
- status = EFI_SECURITY_VIOLATION;
- goto end;
- }
-
- status = select_verification_keys(var_map, global_variable_guid, security_database_guid,
- variable_info.MaximumVariableSize,
+ status = select_verification_keys(*var_map, global_variable_guid, security_database_guid,
+ max_variable_size,
&allowed_key_store_variables[0]);
if (status != EFI_SUCCESS)
@@ -1280,8 +1307,8 @@ static efi_status_t authenticate_variable(const struct uefi_variable_store *cont
continue;
status = uefi_variable_store_get_variable(context, allowed_key_store_variables[i],
- variable_info.MaximumVariableSize,
- &actual_variable_length);
+ max_variable_size,
+ &actual_variable_length);
if (status) {
/* When the parent does not exist it is considered verification failure */
@@ -1297,8 +1324,8 @@ static efi_status_t authenticate_variable(const struct uefi_variable_store *cont
goto end;
}
- status = verify_var_by_key_var(&var_map, &allowed_key_store_var_map,
- (uint8_t *)&hash_buffer, hash_len);
+ status = verify_var_by_key_var(var_map, &allowed_key_store_var_map,
+ hash_buffer, hash_len);
if (status == EFI_SUCCESS)
goto end;
@@ -1311,18 +1338,6 @@ end:
free(allowed_key_store_variables[i]);
}
- /* Remove the authentication header from the variable if the authentication is successful */
- if (status == EFI_SUCCESS) {
- uint8_t *smm_payload =
- (uint8_t *)var + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(var);
-
- memmove(smm_payload, var_map.payload, var_map.payload_len);
- memset((uint8_t *)smm_payload + var_map.payload_len, 0,
- var_map.efi_auth_descriptor_len);
-
- var->DataSize -= var_map.efi_auth_descriptor_len;
- }
-
return status;
}
#endif
--
2.25.1
@@ -0,0 +1,292 @@
From a172c6e8269915db1b25e2749bae06dc0220cfb8 Mon Sep 17 00:00:00 2001
From: Gabor Toth <gabor.toth2@arm.com>
Date: Thu, 11 Apr 2024 13:48:14 +0200
Subject: [PATCH 3/3] Implement Private Authenticated Variable verification
Refactor the implementation to only use the PK, KEK, DB authentication
chain for boot variables, and implement the self authentication for
private authenticated variables.
Signed-off-by: Gabor Toth <gabor.toth2@arm.com>
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TS/trusted-services/+/27957]
---
.../backend/uefi_variable_store.c | 126 +++++++++++++++---
.../smm_variable/backend/variable_index.c | 1 +
.../smm_variable/backend/variable_index.h | 2 +
.../config/default-opteesp/CMakeLists.txt | 2 +-
.../config/default-sp/CMakeLists.txt | 2 +-
5 files changed, 112 insertions(+), 21 deletions(-)
diff --git a/components/service/uefi/smm_variable/backend/uefi_variable_store.c b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
index 1384d0def..97c43dc74 100644
--- a/components/service/uefi/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
@@ -75,15 +75,25 @@ static efi_status_t verify_var_by_key_var(const efi_data_map *new_var,
const efi_data_map *key_store_var,
const uint8_t *hash_buffer, size_t hash_len);
+static bool isPrivateAuthVar(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var);
+
static efi_status_t authenticate_variable(const struct uefi_variable_store *context,
- EFI_TIME *timestamp,
- SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var);
+ EFI_TIME *timestamp, uint8_t (*fingerprint)[FINGERPRINT_SIZE],
+ bool new_variable, SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var);
static efi_status_t authenticate_secure_boot_variable(const struct uefi_variable_store *context,
efi_data_map* var_map,
uint8_t* hash_buffer,
size_t hash_len,
uint64_t max_variable_size);
+
+static efi_status_t authenticate_private_variable(const struct uefi_variable_store *context,
+ efi_data_map* var_map,
+ uint8_t* hash_buffer,
+ size_t hash_len,
+ uint64_t max_variable_size,
+ bool new_variable,
+ uint8_t (*fingerprint)[FINGERPRINT_SIZE]);
#endif
static efi_status_t store_variable_data(const struct uefi_variable_store *context,
@@ -205,6 +215,7 @@ efi_status_t uefi_variable_store_set_variable(const struct uefi_variable_store *
{
bool should_sync_index = false;
EFI_TIME timestamp = { 0 };
+ uint8_t fingerprint[FINGERPRINT_SIZE] = { 0 };
/* Validate incoming request */
efi_status_t status = check_name_terminator(var->Name, var->NameSize);
@@ -233,8 +244,9 @@ efi_status_t uefi_variable_store_set_variable(const struct uefi_variable_store *
return EFI_OUT_OF_RESOURCES;
}
- /* Save the timestamp into a buffer, which can be overwritten by the authentication function */
+ /* Save the timestamp and fingerprints into a buffer, which can be overwritten by the authentication function */
memcpy(&timestamp, &info->metadata.timestamp, sizeof(EFI_TIME));
+ memcpy(&fingerprint, &info->metadata.fingerprint, FINGERPRINT_SIZE);
/* Control access */
status = check_access_permitted_on_set(context, info, var);
@@ -251,7 +263,8 @@ efi_status_t uefi_variable_store_set_variable(const struct uefi_variable_store *
if (info->metadata.attributes &
EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
status = authenticate_variable(
- context, &timestamp, (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
+ context, &timestamp, &fingerprint, false,
+ (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
if (status != EFI_SUCCESS)
return status;
@@ -337,7 +350,8 @@ efi_status_t uefi_variable_store_set_variable(const struct uefi_variable_store *
*/
if (var->Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
status = authenticate_variable(
- context, &timestamp, (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
+ context, &timestamp, &fingerprint, true,
+ (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
if (status != EFI_SUCCESS)
return status;
@@ -372,6 +386,7 @@ efi_status_t uefi_variable_store_set_variable(const struct uefi_variable_store *
/* Store any variable data to the storage backend with the updated metadata */
if (info->is_variable_set && (status == EFI_SUCCESS)) {
memcpy(&info->metadata.timestamp, &timestamp, sizeof(EFI_TIME));
+ memcpy(&info->metadata.fingerprint, &fingerprint, FINGERPRINT_SIZE);
status = store_variable_data(context, info, var);
}
}
@@ -1030,15 +1045,6 @@ select_verification_keys(const efi_data_map new_var, EFI_GUID global_variable_gu
create_smm_variable(&(allowed_key_store_variables[1]),
sizeof(EFI_KEY_EXCHANGE_KEY_NAME), maximum_variable_size,
(uint8_t *)EFI_KEY_EXCHANGE_KEY_NAME, &global_variable_guid);
- } else {
- /*
- * Any other variable is considered Private Authenticated Variable.
- * These are verified by db
- */
- create_smm_variable(&(allowed_key_store_variables[0]),
- sizeof(EFI_IMAGE_SECURITY_DATABASE), maximum_variable_size,
- (uint8_t *)EFI_IMAGE_SECURITY_DATABASE,
- &security_database_guid);
}
return EFI_SUCCESS;
@@ -1114,13 +1120,39 @@ static efi_status_t verify_var_by_key_var(const efi_data_map *new_var,
return EFI_SECURITY_VIOLATION;
}
-/* Basic verification of the authentication header of the new variable.
+static bool isPrivateAuthVar(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var)
+{
+ if (compare_name_to_key_store_name(var->Name,
+ var->NameSize, EFI_PLATFORM_KEY_NAME,
+ sizeof(EFI_PLATFORM_KEY_NAME)) ||
+ compare_name_to_key_store_name(
+ var->Name, var->NameSize,
+ EFI_KEY_EXCHANGE_KEY_NAME, sizeof(EFI_KEY_EXCHANGE_KEY_NAME)) ||
+ compare_name_to_key_store_name(
+ var->Name, var->NameSize,
+ EFI_IMAGE_SECURITY_DATABASE, sizeof(EFI_IMAGE_SECURITY_DATABASE)) ||
+ compare_name_to_key_store_name(
+ var->Name, var->NameSize,
+ EFI_IMAGE_SECURITY_DATABASE1, sizeof(EFI_IMAGE_SECURITY_DATABASE1)) ||
+ compare_name_to_key_store_name(
+ var->Name, var->NameSize,
+ EFI_IMAGE_SECURITY_DATABASE2, sizeof(EFI_IMAGE_SECURITY_DATABASE2)) ||
+ compare_name_to_key_store_name(
+ var->Name, var->NameSize,
+ EFI_IMAGE_SECURITY_DATABASE3, sizeof(EFI_IMAGE_SECURITY_DATABASE3)))
+ return false;
+
+ return true;
+}
+
+/*
+ * Basic verification of the authentication header of the new variable.
* First finds the key variable responsible for the authentication of the new variable,
* then verifies it.
*/
static efi_status_t authenticate_variable(const struct uefi_variable_store *context,
- EFI_TIME *timestamp,
- SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var)
+ EFI_TIME *timestamp, uint8_t (*fingerprint)[FINGERPRINT_SIZE],
+ bool new_variable, SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var)
{
efi_status_t status = EFI_SUCCESS;
EFI_GUID pkcs7_guid = EFI_CERT_TYPE_PKCS7_GUID;
@@ -1192,8 +1224,13 @@ static efi_status_t authenticate_variable(const struct uefi_variable_store *cont
status = EFI_SECURITY_VIOLATION;
}
- /* Run Secure Boot related authentication steps */
- status = authenticate_secure_boot_variable(context, &var_map, (uint8_t*) &hash_buffer, hash_len, variable_info.MaximumVariableSize);
+ if (isPrivateAuthVar(var)) {
+ /* Run Private Authenticated Variable related authentication steps */
+ status = authenticate_private_variable(context, &var_map, (uint8_t*) &hash_buffer, hash_len, variable_info.MaximumVariableSize, new_variable, fingerprint);
+ } else {
+ /* Run Secure Boot related authentication steps */
+ status = authenticate_secure_boot_variable(context, &var_map, (uint8_t*) &hash_buffer, hash_len, variable_info.MaximumVariableSize);
+ }
/* Remove the authentication header from the variable if the authentication is successful */
if (status == EFI_SUCCESS) {
@@ -1340,6 +1377,57 @@ end:
return status;
}
+
+static efi_status_t authenticate_private_variable(const struct uefi_variable_store *context,
+ efi_data_map* var_map,
+ uint8_t* hash_buffer,
+ size_t hash_len,
+ uint64_t max_variable_size,
+ bool new_variable,
+ uint8_t (*fingerprint)[FINGERPRINT_SIZE])
+{
+ efi_status_t status = EFI_SUCCESS;
+ uint8_t new_fingerprint[PSA_HASH_MAX_SIZE] = { 0 };
+
+ /* Verify the signature of the variable */
+ if (verify_pkcs7_signature(
+ var_map->efi_auth_descriptor->AuthInfo.CertData,
+ var_map->efi_auth_descriptor_certdata_len, hash_buffer,
+ hash_len, NULL, 0) == 0)
+ status = EFI_SUCCESS;
+ else
+ return EFI_SECURITY_VIOLATION;
+
+ /**
+ * UEFI: Page 254
+ * CN of the signing certificates Subject and the hash of the tbsCertificate of the top-level issuer certificate
+ * (or the signing certificate itself if no other certificates are present or the certificate chain is of length 1)
+ * in SignedData.certificates is registered for use in subsequent verifications of this variable. Implementations
+ * may store just a single hash of these two elements to reduce storage requirements.
+ */
+ if (get_uefi_priv_auth_var_fingerprint_handler(var_map->efi_auth_descriptor->AuthInfo.CertData,
+ var_map->efi_auth_descriptor_certdata_len,
+ (uint8_t*)&new_fingerprint)) {
+ EMSG("Failed to querry variable fingerprint input");
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ /*
+ * The hash is SHA256 so only 32 bytes contain non zero values.
+ * Use only that part to decrease metadata size.
+ */
+ if (!new_variable) {
+ if (memcmp(&new_fingerprint, fingerprint, FINGERPRINT_SIZE)) {
+ EMSG("Fingerprint verification failed");
+ return EFI_SECURITY_VIOLATION;
+ }
+ } else {
+ /* Save fingerprint */
+ memcpy(fingerprint, &new_fingerprint, FINGERPRINT_SIZE);
+ }
+
+ return status;
+}
#endif
static efi_status_t store_variable_data(const struct uefi_variable_store *context,
diff --git a/components/service/uefi/smm_variable/backend/variable_index.c b/components/service/uefi/smm_variable/backend/variable_index.c
index f4194d2d3..7f2fbe0ba 100644
--- a/components/service/uefi/smm_variable/backend/variable_index.c
+++ b/components/service/uefi/smm_variable/backend/variable_index.c
@@ -199,6 +199,7 @@ static struct variable_entry *add_entry(const struct variable_index *context, co
info->metadata.uid = generate_uid(context, guid, name_size, name);
info->metadata.guid = *guid;
memset(&info->metadata.timestamp, 0, sizeof(EFI_TIME));
+ memset(&info->metadata.fingerprint, 0, sizeof(FINGERPRINT_SIZE));
info->metadata.attributes = 0;
info->metadata.name_size = name_size;
memcpy(info->metadata.name, name, name_size);
diff --git a/components/service/uefi/smm_variable/backend/variable_index.h b/components/service/uefi/smm_variable/backend/variable_index.h
index 7eef7b86b..726bc985a 100644
--- a/components/service/uefi/smm_variable/backend/variable_index.h
+++ b/components/service/uefi/smm_variable/backend/variable_index.h
@@ -24,6 +24,7 @@ extern "C" {
* Implementation limits
*/
#define VARIABLE_INDEX_MAX_NAME_SIZE (64)
+#define FINGERPRINT_SIZE (32)
/**
* \brief variable_metadata structure definition
@@ -33,6 +34,7 @@ extern "C" {
struct variable_metadata {
EFI_GUID guid;
EFI_TIME timestamp;
+ uint8_t fingerprint[FINGERPRINT_SIZE];
size_t name_size;
int16_t name[VARIABLE_INDEX_MAX_NAME_SIZE];
uint32_t attributes;
diff --git a/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt b/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt
index 0e281a377..d3df61ded 100644
--- a/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt
+++ b/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt
@@ -42,7 +42,7 @@ set(SP_BOOT_ORDER "8" CACHE STRING "Boot order of the SP")
add_platform(TARGET "smm-gateway")
# SMM variable and RPC caller settings
-set(SMM_GATEWAY_MAX_UEFI_VARIABLES 40 CACHE STRING "Maximum UEFI variable count")
+set(SMM_GATEWAY_MAX_UEFI_VARIABLES 35 CACHE STRING "Maximum UEFI variable count")
set(SMM_RPC_CALLER_SESSION_SHARED_MEMORY_SIZE 2*4096 CACHE STRING "RPC caller buffer size in SMMGW")
if (UEFI_AUTH_VAR)
set(SMM_SP_HEAP_SIZE 64*1024 CACHE STRING "SMM gateway SP heap size")
diff --git a/deployments/smm-gateway/config/default-sp/CMakeLists.txt b/deployments/smm-gateway/config/default-sp/CMakeLists.txt
index 8df9256e4..bb97cf8e3 100644
--- a/deployments/smm-gateway/config/default-sp/CMakeLists.txt
+++ b/deployments/smm-gateway/config/default-sp/CMakeLists.txt
@@ -47,7 +47,7 @@ set(SP_BOOT_ORDER "8" CACHE STRING "Boot order of the SP")
add_platform(TARGET "smm-gateway")
# SMM variable and RPC caller settings
-set(SMM_GATEWAY_MAX_UEFI_VARIABLES 40 CACHE STRING "Maximum UEFI variable count")
+set(SMM_GATEWAY_MAX_UEFI_VARIABLES 35 CACHE STRING "Maximum UEFI variable count")
set(SMM_RPC_CALLER_SESSION_SHARED_MEMORY_SIZE 2*4096 CACHE STRING "RPC caller buffer size in SMMGW")
if (UEFI_AUTH_VAR)
set(SMM_SP_HEAP_SIZE 64*1024 CACHE STRING "SMM gateway SP heap size")
--
2.25.1
@@ -0,0 +1,37 @@
From e8b577d02d1d4ed2492bb0b6c3a5bb7d2656f13a Mon Sep 17 00:00:00 2001
From: Bence Balogh <bence.balogh@arm.com>
Date: Fri, 17 May 2024 13:21:07 +0200
Subject: [PATCH] Change RSS_COMMS cmake variables to cahce vars
This way they can be set externally as well for the corstone1000
platform.
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Upstream-Status: Pending
---
platform/providers/arm/corstone1000/platform.cmake | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/platform/providers/arm/corstone1000/platform.cmake b/platform/providers/arm/corstone1000/platform.cmake
index 16139c80e..82ac14f0b 100644
--- a/platform/providers/arm/corstone1000/platform.cmake
+++ b/platform/providers/arm/corstone1000/platform.cmake
@@ -9,11 +9,13 @@
set(SMM_GATEWAY_MAX_UEFI_VARIABLES 80 CACHE STRING "Maximum UEFI variable count")
set(SMM_RPC_CALLER_SESSION_SHARED_MEMORY_SIZE 4*4096 CACHE STRING "RPC caller buffer size in SMMGW")
set(SMM_SP_HEAP_SIZE 80*1024 CACHE STRING "SMM gateway SP heap size")
+set(PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE 0x43C0 CACHE STRING "Size of the RSS_COMMS_PAYLOAD buffer")
+set(COMMS_MHU_MSG_SIZE 0x4500 CACHE STRING "Max message size that can be transfered via MHU")
target_compile_definitions(${TGT} PRIVATE
SMM_VARIABLE_INDEX_STORAGE_UID=0x787
- PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE=0x2080
- COMMS_MHU_MSG_SIZE=0x3500
+ PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE=${PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE}
+ COMMS_MHU_MSG_SIZE=${COMMS_MHU_MSG_SIZE}
)
get_property(_platform_driver_dependencies TARGET ${TGT}
--
2.25.1
@@ -11,6 +11,15 @@ SRC_URI:append:corstone1000 = " \
file://0007-plat-corstone1000-Initialize-capsule-update-provider.patch \
file://0008-plat-corstone1000-add-client_id-for-FMP-service.patch \
file://0009-Remove-Werror-flag.patch \
file://0010-Remove-PLATFORM_HAS_ATTEST_PK-define-from-IAT-test.patch \
file://0011-Fix-Avoid-redefinition-of-variables.patch \
file://0012-Fix-GetNextVariableName-NameSize-input.patch \
file://0013-Fix-error-handling-of-variable-index-loading.patch \
file://0014-Provide-crypto-api-to-create-uefi-priv-var-fingerpri.patch \
file://0015-Add-timestamp-validation-for-uefi-variables.patch \
file://0016-Isolate-common-uefi-variable-authentication-steps.patch \
file://0017-Implement-Private-Authenticated-Variable-verificatio.patch \
file://0018-Change-RSS_COMMS-cmake-variables-to-cahce-vars.patch \
"
@@ -2,6 +2,7 @@ require ts-arm-platforms.inc
EXTRA_OECMAKE:append:corstone1000 = " -DMM_COMM_BUFFER_ADDRESS="0x00000000 0x81FFF000" \
-DMM_COMM_BUFFER_PAGE_COUNT="1" \
-DSP_HEAP_SIZE=70*1024 \
"
# Proxy is pointless on fvp-base as there is no dedicated security subsystem. It could be
@@ -4,6 +4,7 @@ EXTRA_OECMAKE:append:corstone1000 = " -DMM_COMM_BUFFER_ADDRESS="0x00000000 0x81F
-DMM_COMM_BUFFER_PAGE_COUNT="1" \
-DUEFI_AUTH_VAR=ON \
-DUEFI_INTERNAL_CRYPTO=ON \
-DSMM_GATEWAY_MAX_UEFI_VARIABLES=60 \
"
EXTRA_OECMAKE:append:fvp-base = " -DMM_COMM_BUFFER_ADDRESS="0x00000000 0x81000000" \
@@ -1,37 +1,101 @@
require arm-systemready-linux-distros.inc
LICENSE = "GPL-1.0-only & GPL-1.0-or-later & GPL-2.0-only & GPL-2.0-or-later \
& GPL-3.0-only & GPL-3.0-or-later & LGPL-2.0-only \
& LGPL-2.0-or-later & LGPL-2.1-only & LGPL-2.1-or-later \
& LGPL-3.0-only & LGPL-3.0-or-later & BSD-3-Clause & BSD-4-Clause \
& Artistic-1.0-Perl & Apache-1.0 & Apache-1.1 & Apache-2.0 & Zlib \
& Python-2.0 & Ruby & PHP-3.01 & W3C-20150513 & OpenSSL & Sleepycat"
# The Debian project does not provide a license manifest for the distributed ISO images.
# The following list only contains the SPDX license identifiers found on the deb
# packages from the ISO image and is not exhaustive.
# For more information about Debian licenses, including the non-free ones, refer to
# https://www.debian.org/legal/licenses/.
LICENSE = "AFL-2.0 & AFL-2.1 \
& GPL-1.0-only & GPL-1.0-or-later & GPL-2.0-only & GPL-2.0-or-later & GPL-2.0-with-autoconf-exception \
& GPL-2.0-with-OpenSSL-exception & GPL-3.0-only & GPL-3.0-or-later & GPL-3.0-with-autoconf-exception \
& GPL-3-with-bison-exception & SMAIL_GPL & LGPL-2.0-only & LGPL-2.0-or-later & LGPL-2.1-only \
& LGPL-2.1-or-later & LGPL-3.0-only & LGPL-3.0-or-later & BSD-2-Clause & BSD-3-Clause \
& BSD-3-Clause-Clear & BSD-4-Clause & BSD-4-Clause-UC & TCP-wrappers & OLDAP-2.8 & PSF-2.0 & BSL-1.0 \
& bzip2-1.0.6 & CC0-1.0 & Libpng & Latex2e & Unicode-TOU & Unicode-DFS-2016 & CC-BY-3.0 & CC-BY-SA-3.0 \
& CC-BY-SA-4.0 & curl & MS-PL & NTP & FSFAP & FSFUL & FSFULLR & FSF-Unlimited & EDL-1.0 & Vim & FTL \
& TCL & MPL-1.1 & MPL-2.0 & GFDL-1.1-or-later & GFDL-1.2-or-later & GFDL-1.3-no-invariants-or-later \
& GFDL-1.3-no-invariants-only & Artistic-1.0 & Artistic-2.0 & Artistic-1.0-Perl & Apache-2.0 \
& Apache-2.0-with-LLVM-exception & Zlib & Python-2.0 & OpenSSL & Sleepycat & Spencer-86 & MIT & MIT-CMU \
& MIT-advertising & Beerware & Intel & X11 & ISC & IPL-1.0 & SSH-OpenSSH & SSH-short & RSA-MD & OPL-1.0 & PD"
LIC_FILES_CHKSUM = "\
file://${COMMON_LICENSE_DIR}/AFL-2.0;md5=f01c02e5eac69cff6b8c2cc474b8d468 \
file://${COMMON_LICENSE_DIR}/AFL-2.1;md5=e40039b90e182a056bcd9ad3e47ddd71 \
file://${COMMON_LICENSE_DIR}/GPL-1.0-only;md5=e9e36a9de734199567a4d769498f743d \
file://${COMMON_LICENSE_DIR}/GPL-1.0-or-later;md5=30c0b8a5048cc2f4be5ff15ef0d8cf61 \
file://${COMMON_LICENSE_DIR}/GPL-2.0-only;md5=801f80980d171dd6425610833a22dbe6 \
file://${COMMON_LICENSE_DIR}/GPL-2.0-or-later;md5=fed54355545ffd980b814dab4a3b312c \
file://${COMMON_LICENSE_DIR}/GPL-2.0-with-autoconf-exception;md5=966c02a95037a9c7ad75a7597aea9c5f \
file://${COMMON_LICENSE_DIR}/GPL-2.0-with-OpenSSL-exception;md5=d9e4412f125e3e6f14efba8ce7b4604f \
file://${COMMON_LICENSE_DIR}/GPL-3.0-only;md5=c79ff39f19dfec6d293b95dea7b07891 \
file://${COMMON_LICENSE_DIR}/GPL-3.0-or-later;md5=1c76c4cc354acaac30ed4d5eefea7245 \
file://${COMMON_LICENSE_DIR}/GPL-3.0-with-autoconf-exception;md5=da26b415cb0faf9bfe6829f0ffa409ec \
file://${COMMON_LICENSE_DIR}/GPL-3-with-bison-exception;md5=6e1bac3dc21fcc4fa049cf5c407eb7a2 \
file://${COMMON_LICENSE_DIR}/SMAIL_GPL;md5=b948675029f79c64840e78881e91e1d4 \
file://${COMMON_LICENSE_DIR}/LGPL-2.0-only;md5=9427b8ccf5cf3df47c29110424c9641a \
file://${COMMON_LICENSE_DIR}/LGPL-2.0-or-later;md5=6d2d9952d88b50a51a5c73dc431d06c7 \
file://${COMMON_LICENSE_DIR}/LGPL-2.1-only;md5=1a6d268fd218675ffea8be556788b780 \
file://${COMMON_LICENSE_DIR}/LGPL-2.1-or-later;md5=2a4f4fd2128ea2f65047ee63fbca9f68 \
file://${COMMON_LICENSE_DIR}/LGPL-3.0-only;md5=bfccfe952269fff2b407dd11f2f3083b \
file://${COMMON_LICENSE_DIR}/LGPL-3.0-or-later;md5=c51d3eef3be114124d11349ca0d7e117 \
file://${COMMON_LICENSE_DIR}/BSD-2-Clause;md5=cb641bc04cda31daea161b1bc15da69f \
file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9 \
file://${COMMON_LICENSE_DIR}/BSD-3-Clause-Clear;md5=7a434440b651f4a472ca93716d01033a \
file://${COMMON_LICENSE_DIR}/BSD-4-Clause;md5=624d9e67e8ac41a78f6b6c2c55a83a2b \
file://${COMMON_LICENSE_DIR}/BSD-4-Clause-UC;md5=1da3cf8ad50cd8d5d1de3cfc53196d01 \
file://${COMMON_LICENSE_DIR}/TCP-wrappers;md5=83b1f59c3c52689f5652193e0cd5b1cf \
file://${COMMON_LICENSE_DIR}/OLDAP-2.8;md5=bb28ada4fbb5c3f52c233899b2e410a5 \
file://${COMMON_LICENSE_DIR}/PSF-2.0;md5=76c1502273262a5ebefb50dfb20d7c4f \
file://${COMMON_LICENSE_DIR}/BSL-1.0;md5=65a7df9ad57aacf825fd252c4c33288c \
file://${COMMON_LICENSE_DIR}/bzip2-1.0.6;md5=841c5495611ae95b13e80fa4a0627333 \
file://${COMMON_LICENSE_DIR}/CC0-1.0;md5=0ceb3372c9595f0a8067e55da801e4a1 \
file://${COMMON_LICENSE_DIR}/Libpng;md5=12b4ec50384c800bc568f519671b120c \
file://${COMMON_LICENSE_DIR}/Latex2e;md5=ef91d258f6a8d4d7f4db4d30adf38598 \
file://${COMMON_LICENSE_DIR}/Unicode-TOU;md5=666362dc5dba74f477af0f44fb85bd22 \
file://${COMMON_LICENSE_DIR}/Unicode-DFS-2016;md5=907371994d651afe53e98adc27824669 \
file://${COMMON_LICENSE_DIR}/CC-BY-3.0;md5=dfa02b5755629022e267f10b9c0a2ab7 \
file://${COMMON_LICENSE_DIR}/CC-BY-SA-3.0;md5=3248afbd148270ac7337a6f3e2558be5 \
file://${COMMON_LICENSE_DIR}/CC-BY-SA-4.0;md5=4084714af41157e38872e798eb3fe1b1 \
file://${COMMON_LICENSE_DIR}/curl;md5=f7adb1397db248527ffed14d947e445c \
file://${COMMON_LICENSE_DIR}/MS-PL;md5=b9cbca4f1a399b0c17b3521736e67848 \
file://${COMMON_LICENSE_DIR}/NTP;md5=0926fd147301b2a65e45e21adb3a6f14 \
file://${COMMON_LICENSE_DIR}/FSFAP;md5=232368338ef6dc99de71c2e05ff12176 \
file://${COMMON_LICENSE_DIR}/FSFUL;md5=dc74327e8d4dca295527a090d2af4ba4 \
file://${COMMON_LICENSE_DIR}/FSFULLR;md5=f0aa4b452548cc5d53a7772a9a90b3c0 \
file://${COMMON_LICENSE_DIR}/FSF-Unlimited;md5=06fadd9ae6adbcd5d8d545dac90b15f6 \
file://${COMMON_LICENSE_DIR}/EDL-1.0;md5=e06be17b8577bf6e2277a5c3c71b2d05 \
file://${COMMON_LICENSE_DIR}/Vim;md5=676d28582e2dca824e7e309a9865eeb1 \
file://${COMMON_LICENSE_DIR}/FTL;md5=f0bf6b09ee8b02121ed10709d9e49d8b \
file://${COMMON_LICENSE_DIR}/TCL;md5=5f7b23ac10d8f7cde16737bc896bb6fb \
file://${COMMON_LICENSE_DIR}/MPL-1.1;md5=1d38e87ed8d522c49f04e1efe0fab3ab \
file://${COMMON_LICENSE_DIR}/MPL-2.0;md5=815ca599c9df247a0c7f619bab123dad \
file://${COMMON_LICENSE_DIR}/GFDL-1.1-or-later;md5=03322744a1a73f36ebf29f98cced39a4 \
file://${COMMON_LICENSE_DIR}/GFDL-1.2-or-later;md5=9f58808219e9a42ff1228309d6f83dc6 \
file://${COMMON_LICENSE_DIR}/GFDL-1.3-no-invariants-or-later;md5=e0771ae6a62dc8a2e50b1d450fea66b7 \
file://${COMMON_LICENSE_DIR}/GFDL-1.3-no-invariants-only;md5=e0771ae6a62dc8a2e50b1d450fea66b7 \
file://${COMMON_LICENSE_DIR}/Artistic-1.0;md5=cda03bbdc3c1951996392b872397b798 \
file://${COMMON_LICENSE_DIR}/Artistic-2.0;md5=8bbc66f0ba93cec26ef526117e280266 \
file://${COMMON_LICENSE_DIR}/Artistic-1.0-Perl;md5=8feedd169dbd5738981843bd7d931f9f \
file://${COMMON_LICENSE_DIR}/Apache-1.0;md5=9f7a9503b805de9158a2a31a2cef4b70 \
file://${COMMON_LICENSE_DIR}/Apache-1.1;md5=61cc638ff95ff4f38f243855bcec4317 \
file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10 \
file://${COMMON_LICENSE_DIR}/Apache-2.0-with-LLVM-exception;md5=0bcd48c3bdfef0c9d9fd17726e4b7dab \
file://${COMMON_LICENSE_DIR}/Zlib;md5=87f239f408daca8a157858e192597633 \
file://${COMMON_LICENSE_DIR}/Python-2.0;md5=a5c8025e305fb49e6d405769358851f6 \
file://${COMMON_LICENSE_DIR}/Ruby;md5=105fc57d3f4d3122db32912f3e6107d0 \
file://${COMMON_LICENSE_DIR}/PHP-3.01;md5=3363e286b5882ec667a6ebd86e0d9d91 \
file://${COMMON_LICENSE_DIR}/W3C-20150513;md5=9ff23a699fca546a380855dd40d12d4f \
file://${COMMON_LICENSE_DIR}/OpenSSL;md5=4eb1764f3e65fafa1a25057f9082f2ae \
file://${COMMON_LICENSE_DIR}/Sleepycat;md5=1cbb64231c94198653282f3ccab88ffb \
file://${COMMON_LICENSE_DIR}/Spencer-86;md5=97ba797de74f88a17676473fab224843 \
file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302 \
file://${COMMON_LICENSE_DIR}/MIT-CMU;md5=91b70218e0db8e063ed88cd532cb801d \
file://${COMMON_LICENSE_DIR}/MIT-advertising;md5=0f358dd6677661d482934070c7eeaeec \
file://${COMMON_LICENSE_DIR}/Beerware;md5=8db32780d0d8bbbdce0fa415e514cb89 \
file://${COMMON_LICENSE_DIR}/Intel;md5=ced5efc26449ecac834b4b71625a3410 \
file://${COMMON_LICENSE_DIR}/X11;md5=87f08485cf6ba3c63a00eda8ecba7f1d \
file://${COMMON_LICENSE_DIR}/ISC;md5=f3b90e78ea0cffb20bf5cca7947a896d \
file://${COMMON_LICENSE_DIR}/IPL-1.0;md5=be739b8845e6e98f99e206221fe9293b \
file://${COMMON_LICENSE_DIR}/SSH-OpenSSH;md5=3af632aae8cf01feb6ce2ed44bb7ed2e \
file://${COMMON_LICENSE_DIR}/SSH-short;md5=b73783010a430cadaabdc8ec0c0748f8 \
file://${COMMON_LICENSE_DIR}/RSA-MD;md5=9342e66a3fb8ddeebe449a85366f4acc \
file://${COMMON_LICENSE_DIR}/OPL-1.0;md5=acdf1e4398bd93dc137e271c50316324 \
file://${COMMON_LICENSE_DIR}/PD;md5=b3597d12946881e13cb3b548d1173851 \
"
PV = "12.4.0"
@@ -1,19 +1,20 @@
require arm-systemready-linux-distros.inc
LICENSE = "AGPL-3.0-only & Apache-2.0 & Artistic-1.0 & Artistic-2.0 \
LICENSE = "AGPL-3.0-only & Apache-1.1 & Apache-2.0 & Artistic-1.0 & Artistic-2.0 \
& BSD-2-Clause-Patent & BSD-2-Clause & BSD-3-Clause & BSD-4-Clause \
& CC-BY-3.0 & CC-BY-4.0 & CC-BY-SA-1.0 & CC-BY-SA-3.0 \
& BSL-1.0 & CC-BY-3.0 & CC-BY-4.0 & CC-BY-SA-1.0 & CC-BY-SA-3.0 \
& CC-BY-SA-4.0 & CC0-1.0 & CDDL-1.0 & GFDL-1.1-only \
& GFDL-1.2-only & GFDL-1.3-only & GFDL-1.3-or-later \
& GPL-1.0-or-later & GPL-2.0-only & GPL-2.0-or-later \
& GPL-3.0-only & GPL-3.0-or-later & HPND & ICU & IPA \
& GPL-3.0-only & GPL-3.0-or-later & HPND & ICU & IPL-1.0 & IPA \
& ISC & LGPL-2.0-only & LGPL-2.0-or-later & LGPL-2.1-only \
& LGPL-2.1-or-later & LGPL-3.0-only & LGPL-3.0-or-later \
& LPPL-1.3c & MIT & MPL-1.1 & MPL-2.0 & OFL-1.1 & OLDAP-2.8 \
& OpenSSL & Python-2.0 & Vim & W3C"
& OpenSSL & Python-2.0 & Sleepycat & Vim & W3C & Zlib"
LIC_FILES_CHKSUM = "\
file://${COMMON_LICENSE_DIR}/AGPL-3.0-only;md5=73f1eb20517c55bf9493b7dd6e480788 \
file://${COMMON_LICENSE_DIR}/Apache-1.1;md5=61cc638ff95ff4f38f243855bcec4317 \
file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10 \
file://${COMMON_LICENSE_DIR}/Artistic-1.0;md5=cda03bbdc3c1951996392b872397b798 \
file://${COMMON_LICENSE_DIR}/Artistic-2.0;md5=8bbc66f0ba93cec26ef526117e280266 \
@@ -21,6 +22,7 @@ file://${COMMON_LICENSE_DIR}/BSD-2-Clause-Patent;md5=0518d409dae93098cca8dfa932f
file://${COMMON_LICENSE_DIR}/BSD-2-Clause;md5=cb641bc04cda31daea161b1bc15da69f \
file://${COMMON_LICENSE_DIR}/BSD-3-Clause;md5=550794465ba0ec5312d6919e203a55f9 \
file://${COMMON_LICENSE_DIR}/BSD-4-Clause;md5=624d9e67e8ac41a78f6b6c2c55a83a2b \
file://${COMMON_LICENSE_DIR}/BSL-1.0;md5=65a7df9ad57aacf825fd252c4c33288c \
file://${COMMON_LICENSE_DIR}/CC-BY-3.0;md5=dfa02b5755629022e267f10b9c0a2ab7 \
file://${COMMON_LICENSE_DIR}/CC-BY-4.0;md5=9b33bbd06fb58995fb0e299cd38d1838 \
file://${COMMON_LICENSE_DIR}/CC-BY-SA-1.0;md5=681ffad43a0addd90f1bebf45675104e \
@@ -40,6 +42,7 @@ file://${COMMON_LICENSE_DIR}/GPL-3.0-or-later;md5=1c76c4cc354acaac30ed4d5eefea72
file://${COMMON_LICENSE_DIR}/HPND;md5=faa364b3e3c6db0f74cc0e704ddf6b9c \
file://${COMMON_LICENSE_DIR}/ICU;md5=4d85ad1f393add71dc66bcf78e3ee584 \
file://${COMMON_LICENSE_DIR}/IPA;md5=17b18da2d8b2c43c598aa7583229ef1b \
file://${COMMON_LICENSE_DIR}/IPL-1.0;md5=be739b8845e6e98f99e206221fe9293b \
file://${COMMON_LICENSE_DIR}/ISC;md5=f3b90e78ea0cffb20bf5cca7947a896d \
file://${COMMON_LICENSE_DIR}/LGPL-2.0-only;md5=9427b8ccf5cf3df47c29110424c9641a \
file://${COMMON_LICENSE_DIR}/LGPL-2.0-or-later;md5=6d2d9952d88b50a51a5c73dc431d06c7 \
@@ -55,15 +58,17 @@ file://${COMMON_LICENSE_DIR}/OFL-1.1;md5=fac3a519e5e9eb96316656e0ca4f2b90 \
file://${COMMON_LICENSE_DIR}/OLDAP-2.8;md5=bb28ada4fbb5c3f52c233899b2e410a5 \
file://${COMMON_LICENSE_DIR}/OpenSSL;md5=4eb1764f3e65fafa1a25057f9082f2ae \
file://${COMMON_LICENSE_DIR}/Python-2.0;md5=a5c8025e305fb49e6d405769358851f6 \
file://${COMMON_LICENSE_DIR}/Sleepycat;md5=1cbb64231c94198653282f3ccab88ffb \
file://${COMMON_LICENSE_DIR}/Vim;md5=676d28582e2dca824e7e309a9865eeb1 \
file://${COMMON_LICENSE_DIR}/W3C;md5=4b1d0384b406508a63e51f7c69687700 \
file://${COMMON_LICENSE_DIR}/Zlib;md5=87f239f408daca8a157858e192597633 \
"
ARM_SYSTEMREADY_LINUX_DISTRO_INSTALL_SIZE = "6144"
PV = "15.4"
PV = "15.5"
# possible value of ISO_TYPE: NET, DVD
ISO_TYPE = "DVD"
BUILD_NO = "243.2"
BUILD_NO = "491.1"
SRC_URI = "https://download.opensuse.org/distribution/leap/${PV}/iso/openSUSE-Leap-${PV}-${ISO_TYPE}-aarch64-Build${BUILD_NO}-Media.iso;unpack=0;downloadfilename=${ISO_IMAGE_NAME}.iso"
SRC_URI[sha256sum] = "d87f79b2b723f9baaeedd9e2be0365c04081e51a4f7f7f08c7ab3eee0c3e0fae"
SRC_URI[sha256sum] = "456cc4f99b044429d8a89bd302c06e9e382d6ac4dc590139a7096ebb54f5357b"
+3 -3
View File
@@ -11,12 +11,12 @@ class FtpmTestSuite(OERuntimeTestCase):
"""
Minimal test for optee-ftpm and ftpm kernel driver interfaces
"""
@OETimeout(200)
@OETimeout(360)
def test_ftpm(self):
# device files, need tee-supplicant fully initialized which takes some time
# and tests seem to run before boot is complete
cmd = "ls -l /dev/tpm0 /dev/tpmrm0 || ( runlevel; sleep 10; ls -l /dev/tpm0 /dev/tpmrm0 )"
status, output = self.target.run(cmd, timeout=60)
cmd = "ls -l /dev/tpm0 /dev/tpmrm0 || ( runlevel; sleep 60; ls -l /dev/tpm0 /dev/tpmrm0 )"
status, output = self.target.run(cmd, timeout=90)
self.assertEqual(status, 0, msg='\n'.join([cmd, output]))
# tpm version
+2 -2
View File
@@ -12,7 +12,7 @@ class OpteeTestSuite(OERuntimeTestCase):
"""
Run OP-TEE tests (xtest).
"""
@OETimeout(800)
@OETimeout(1300)
@OEHasPackage(['optee-test'])
def test_opteetest_xtest(self):
# clear storage before executing tests
@@ -20,5 +20,5 @@ class OpteeTestSuite(OERuntimeTestCase):
status, output = self.target.run(cmd, timeout=60)
self.assertEqual(status, 0, msg='\n'.join([cmd, output]))
cmd = "xtest"
status, output = self.target.run(cmd, timeout=600)
status, output = self.target.run(cmd, timeout=1200)
self.assertEqual(status, 0, msg='\n'.join([cmd, output]))
@@ -3,7 +3,7 @@ LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://LICENSE.txt;md5=bb63326febfb5fb909226c8e7ebcef5c"
SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git;branch=master"
SRC_URI = "git://git.kernel.org/pub/scm/linux/kernel/git/mark/boot-wrapper-aarch64.git;branch=master;protocol=https"
SRCREV = "d3b1a15d18542b2086e72bfdc3fc43f454772a3b"
# boot-wrapper doesn't make releases