1
0
mirror of https://git.yoctoproject.org/meta-arm synced 2026-07-17 16:17:09 +00:00

Compare commits

...

58 Commits

Author SHA1 Message Date
Ross Burton 23b572c40e meta-arm-systemready/arm-systemready-linux-distros-fedora: remove
Fedora 39 is very obsolete and has been removed from the Fedora mirrors.

If someone needs this then this commit can be reverted and the recipe
upgraded to the latest Fedora release.

Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-06-18 09:46:22 -04:00
Hugo SIMELIERE c4fd56386e optee-os: Fix CVE-2026-33662
Pick patch from [1] as mentioned in OP-TEE os security report in [2].

[1] https://github.com/OP-TEE/optee_os/commit/caeaa2ae551666068894005387cca4113b10873f
[2] https://github.com/OP-TEE/optee_os/security/advisories/GHSA-4cf8-v5g3-73gr

Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
Reviewed-by: Bruno VERNAY <bruno.vernay@se.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-21 06:00:08 -04:00
Hugo SIMELIERE 313a5da55a optee-os: Fix CVE-2026-33317
Pick patches from [1], [2] and [3] as mentioned in Debian report in [4].

[1] https://github.com/OP-TEE/optee_os/commit/e031c4e562023fd9f199e39fd2e85797e4cbdca9
[2] https://github.com/OP-TEE/optee_os/commit/16926d5a46934c46e6656246b4fc18385a246900
[3] https://github.com/OP-TEE/optee_os/commit/149e8d7ecc4ef8bb00ab4a37fd2ccede6d79e1ca
[4] https://security-tracker.debian.org/tracker/CVE-2026-33317

Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
Reviewed-by: Bruno VERNAY <bruno.vernay@se.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2026-05-21 06:00:08 -04:00
Ross Burton a81c19915b CI: only run pending-updates on master
This job takes a few minutes and isn't useful unless it's being ran for
master, or is being actively worked on.

Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-11-05 09:35:03 -05:00
Jon Mason 0f1e7bf92c arm-systemready/ir-acs: Update URL
The github URL where the image was located has gone away on the master
branch.  Update the URL to point to the legacy branch, which should stay
around (according to the documentation).

Fixes: aebe535aa8 ("arm-systemready: Introduce the Arm SystemReady layer")
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-09-08 10:00:15 -04:00
Ross Burton 8e0f8af90f arm/fvp-base-a-aem: remove spurious executable stack from one library
There are some objects in the FVP binary that are assembler source and
fail to declare what permissions the stack needs to have, so GCC falls
back to assuming that the final binary needs an executable stack.

glibc 2.41 (as now used in uninative) introduces changes here[1]: whether
to have an executable stack or not when the binary doesn't specify a
need (defaults to executable, but this is a tunable), and any binaries
that are dlopen()ed that require an executable stack will fail.

Thus, some FVPs on some platforms (notable, fvp-base-a-aem on x86-64)
now fail on startup:

  libarmctmodel.so: cannot enable executable stack as shared object requires: Invalid argument

Luckily the solution here is to simply clear the executable bit, as
an executable stack is not actually needed.  Until a new release of the
FVP is made we can fix the binary in our package using execstack.

[1] https://lists.gnu.org/archive/html/info-gnu/2025-01/msg00014.html

Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-04-29 11:00:13 -04:00
Ross Burton f5f8dfb5a8 arm/execstack-native: add new recipe
Add a recipe for the execstack binary from prelink-cross. This tool is
used to manipulate the GNU_STACK segment in ELF binaries, specifically
to control whether the binary requests an executable stack or not.

Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-04-29 11:00:13 -04:00
Ross Burton f3640941c6 CI: use canonical git.yoctoproject.org URLs
The canonical repository URLs don't use /git/.

Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-04-04 13:55:39 -04:00
Ross Burton b6e214752a arm-system-ready/arm-systemready-ir-acs: add version to download filename
The download filename wasn't versioned so multiple versions would write
to the same file on disk and conflict, causing repeated downloads and
fetch failures.

Add the PV to the filename on disk to resolve this.

Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-04-04 13:00:12 -04:00
Jose Quaresma 3cadb81ffa bsp: optee-client: cleanup old tee-supplicant
The same tee-supplicant is available in the meta-arm layer
along with the recipe.

| meta-arm/recipes-security/optee/optee-client
| meta-arm/recipes-security/optee/optee-client/tee-supplicant.sh
| meta-arm/recipes-security/optee/optee-client/tee-supplicant@.service
| meta-arm/recipes-security/optee/optee-client.inc
| meta-arm/recipes-security/optee/optee-client_4.1.0.bb

Signed-off-by: Jose Quaresma <jose.quaresma@foundries.io>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-02-21 08:00:14 -05:00
Romain Naour a8fe9d22ea external-arm-toolchain: rebuild libmvec.so symlink if any
On some architectures (namely Aarch64), glibc may provide a libmvec
library since glibc 2.22, which programs built with gcc OpenMP
support might get linked to.

In order for these programs to work on the target, we need to copy this
library to the target filesystem.

Make sure that libmvec.so symlink is correct with or without usermerge
enabled otherwise libmvec.so symlink is broken.

For more details on libmvec, see
https://sourceware.org/glibc/wiki/libmvec.

(cherry picked from commit de47f836e2)

Signed-off-by: Romain Naour <romain.naour@smile.fr>
Acked-by: Denys Dmytriyenko <denys@konsulko.com>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-01-06 06:00:11 -05:00
Romain Naour c22b4f89f7 external-arm-toolchain: override dynamic loader path with usrmerge enabled
usrmerge nowaday required by systemd [1] but it broke
external-arm-toolchain in several ways...

When usrmerge is enabled, /lib is no longer part of SYSROOT_DIRS list
while the prebuilt toolchain expect the dynamic loader to be placed in
/lib not /usr/lib.

There is no /lib directory in the per-package sysroot directory
generated to build each package:

  [...]/build/tmp/sysroots-components/<target>/<package>/
  sysroot-providers/ usr/

But the cross-compiler still generate binaries with dynamic loarder
path set to "/lib/ld-linux-<target>.so*"

  strings sanitycheckc_cross.exe | grep ld
  /lib/ld-linux-aarch64.so.1

A symlink /lib -> /usr/lib is crated in the final rootfs image.

But this broke the meson-qemuwrapper used when "qemu-usermode"
(MACHINE_FEATURES) is available:

See [2]:
  do_write_config:append:class-target() {
       # Write out a qemu wrapper that will be used as exe_wrapper so that meson
       # can run target helper binaries through that.
       qemu_binary="${@qemu_wrapper_cmdline(d, '$STAGING_DIR_HOST', ['$STAGING_DIR_HOST/${libdir}','$STAGING_DIR_HOST/${base_libdir}'])}"

It produce a runtime issue while running a meson sanity check:

  meson-qemuwrapper [...]/build/meson-private/sanitycheckc_cross.exe

  qemu-aarch64: Could not open '/lib/ld-linux-aarch64.so.1': No such file or directory

Note: The binaries build by the Yocto internal toolchain seems be "patched" [3]
to look at /usr/lib instead of /lib.

We use -Wl,--dynamic-linker to make sure that the cross-compiler
generate binaries using the dynamic loader path defined by usrmerge
for all packages build by Yocto.

[1] https://git.openembedded.org/openembedded-core/commit/?id=802e853eeddf16d73db1900546cc5f045d1fb7ed
[2] https://git.openembedded.org/openembedded-core/tree/meta/classes-recipe/meson.bbclass?h=2024-04.3-scarthgap#n130
[3] https://github.com/openembedded/openembedded-core/blob/scarthgap/meta/recipes-devtools/gcc/gcc/0007-Define-GLIBC_DYNAMIC_LINKER-and-UCLIBC_DYNAMIC_LINKE.patch

(cherry picked from commit cb4c0c9a93)

Signed-off-by: Romain Naour <romain.naour@smile.fr>
Acked-by: Denys Dmytriyenko <denys@konsulko.com>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-01-06 06:00:11 -05:00
Vasyl Vavrychuk 309d93f9e5 external-arm-toolchain: remove ${base_libdir}/libpthread*.so from FILES:${PN}
When `usrmerge` distro feature is not enabled, then `${base_libdir}`
resolves to `/lib` and `/lib/libpthread*.so` does not match any files.
But, with `usrmerge` distro feature, `${base_libdir}` is `/usr/lib`, so
removed line leads to `/usr/lib/libpthread.so` symlink included in
`${PN}` which causes QA check failure.

(cherry picked from commit 8634bdc2f2)

Signed-off-by: Vasyl Vavrychuk <vvavrychuk@gmail.com>
Acked-by: Denys Dmytriyenko <denys@konsulko.com>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-01-06 06:00:11 -05:00
Vasyl Vavrychuk a6233bf5fd external-arm-toolchain: in libc.so GNU ld script use base_libdir
`base_libdir` gets replaced with `/lib` or `/usr/lib` depending on
`usrmerge` distro feature.

(cherry picked from commit 4b2cef379f)

Signed-off-by: Vasyl Vavrychuk <vvavrychuk@gmail.com>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Acked-by: Denys Dmytriyenko <denys@konsulko.com>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-01-06 06:00:11 -05:00
Romain Naour 415215c074 external-arm-toolchain: wrap symlink handling under usrmerge check
Rework the symlink handling when usermerge is enabled.
Indeed, "ln -sf ../../lib/librt.so.1 ${D}${libdir}/librt.so" create a
dead link with usermerge...

Based on: https://lists.yoctoproject.org/g/meta-arm/message/5765

(cherry picked from commit a6f44bbb80)

Signed-off-by: Romain Naour <romain.naour@smile.fr>
Cc: "Parthiban" <parthiban@linumiz.com>
Acked-by: Denys Dmytriyenko <denys@konsulko.com>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-01-06 06:00:11 -05:00
Vasyl Vavrychuk a7f27d1641 external-arm-toolchain: wrap base_libdir vs libdir manipulations under usrmerge check
With `usrmerge` disto feature `base_libdir` and `libdir` are the same,
so it does not make sense to:

* removing "duplicates" between them
* move files from `base_libdir` to `libdir`

This fixes build error

| mv: '.../tmp/work/cortexa15t2hf-neon-poky-linux-gnueabi/external-arm-toolchain/12.2.Rel1/image/usr/lib/libasan.a' and '.../tmp/work/cortexa15t2hf-neon-poky-linux-gnueabi/external-arm-toolchain/12.2.Rel1/image/usr/lib/libasan.a' are the same file

in case of `usrmerge` feature enabled.

(cherry picked from commit 98eea62962)

Signed-off-by: Vasyl Vavrychuk <vvavrychuk@gmail.com>
Acked-by: Denys Dmytriyenko <denys@konsulko.com>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-01-06 06:00:11 -05:00
Romain Naour acbba48ee5 external-arm-toolchain: remove old sed fixup for libc.so
As reported by Vasyl Vavrychuk [1], /${EAT_LIBDIR}/${EAT_TARGET_SYS}
is not present in libc.so in the latest prebuilt toolchains:

ARM32:
  $ cat ./gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib/libc.so
  OUTPUT_FORMAT(elf32-littlearm)
  GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux-armhf.so.3 ) )

  $ cat ./gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/lib/libc.so
  OUTPUT_FORMAT(elf32-littlearm)
  GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux-armhf.so.3 ) )

  $ cat ./arm-gnu-toolchain-12.3.rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/lib/libc.so
  OUTPUT_FORMAT(elf32-littlearm)
  GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux-armhf.so.3 ) )

  $ cat ./arm-gnu-toolchain-13.3.rel1-x86_64-arm-none-linux-gnueabihf/arm-none-linux-gnueabihf/libc/usr/lib/libc.so
  OUTPUT_FORMAT(elf32-littlearm)
  GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux-armhf.so.3 ) )

Aarch64:
  $ cat ./gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu/aarch64-linux-gnu/libc/usr/lib/libc.so
  OUTPUT_FORMAT(elf64-littleaarch64)
  GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) )

  $ cat ./gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/lib64/libc.so
  OUTPUT_FORMAT(elf64-littleaarch64)
  GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) )

  $ cat ./arm-gnu-toolchain-12.3.rel1-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/lib64/libc.so
  OUTPUT_FORMAT(elf64-littleaarch64)
  GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) )

  $ cat ./arm-gnu-toolchain-13.3.rel1-x86_64-aarch64-none-linux-gnu/aarch64-none-linux-gnu/libc/usr/lib64/libc.so
  OUTPUT_FORMAT(elf64-littleaarch64)
  GROUP ( /lib64/libc.so.6 /usr/lib64/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux-aarch64.so.1 ) )

We can safely remove old sed fixup for libc.so.

[1] https://lists.yoctoproject.org/g/meta-arm/message/5565

(cherry picked from commit 9a0451a959)

Signed-off-by: Romain Naour <romain.naour@smile.fr>
Acked-by: Denys Dmytriyenko <denys@konsulko.com>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2025-01-06 06:00:11 -05:00
Hugues KAMBA MPIANA 7088279c0a arm-bsp/documentation: corstone1000: Add SystemReady IR v2.0 certification
- Add details on SystemReady IR v2.0 certification achievement
- Document additional patch added
- Update release notes with new milestone tag `CORSTONE1000-2024.06-systemready-ir-v2.0`

Signed-off-by: Hugues KAMBA MPIANA <hugues.kambampiana@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-11-06 07:00:12 -05:00
Ross Burton d67a9b6070 arm-base/linux-yocto: revert interim 6.10 patch for fvp-base
oe-core master now has 6.6.54 which incorporates this patch, so we don't
need to carry it anymore.

This reverts commit 60fd47edd0.

Signed-off-by: Ross Burton <ross.burton@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-11-05 10:42:16 -05:00
Jon Mason 60e31ef2c4 arm/linux-yocto: disable CONFIG_MTD_NAND_FSL_IFC
Linux stable kernel v6.6.44 added commit c22649e217457d732a51112aaa8721a0e79e2c30,
which modifies the depends for the Freescale IFC NAND controller.  See
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?h=linux-6.6.y&id=c22649e217457d732a51112aaa8721a0e79e2c30

Because of this change, do_kernel_configcheck is logging an warning
about values not matching.  To address this issue, disable it manually
in a config fragment, but only for the affected machines in meta-arm.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-10-21 12:00:17 -04:00
Jon Mason 0ce566fb86 arm-bsp/fvp-base: Get 6.10 kernel working
Apply upstream patch to get virtio networking functioning again and
switch to the 6.10 kernel.

Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-10-21 12:00:17 -04:00
Ben 218c3bbfea kas: Include unattended openSUSE test
Add unattended installation class to openSUSE target

Signed-off-by: Ben Cownley <ben.cownley@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-10-15 12:00:13 -04:00
Ben 62a4a0a71a arm-systemready/oeqa: Add unattended installation testcase
Add test for openSUSE unattended installation

Signed-off-by: Ben Cownley <ben.cownley@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-10-15 12:00:13 -04:00
Ben ba9451a818 arm-systemready/linux-distros: Implement unattended openSUSE
Implement unattended installation for openSUSE

Signed-off-by: Ben Cownley <ben.cownley@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-10-15 12:00:13 -04:00
Luca Fancellu 950a4afce4 arm/lib: Handle timeout for spawn object on stop()
The current code is waiting 5 seconds to get an EOF on the
console pexpect spawn object, on a particularly slow machine
this timeout was not enough ending up into a TIMEOUT exception.

To solve this, increase the timeout and handle the TIMEOUT exception
by printing an error on the debug console instead of letting the
exception raise up to the stack, force the spawn object close() call
as well, since at this stage we would like the process to terminate
anyway.

Signed-off-by: Luca Fancellu <luca.fancellu@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-09-23 13:00:14 -04:00
Jon Mason ea21deb5e9 arm-toolchain: remove libmount-mountfd-support when using binary toolchain
util-linux is failing when compiling with:
| configure: error: libmount_mountfd_support selected, but required mount FDs based API not available
Remove this feature when building with the binary toolchain to avoid
this issue.

Acked-by: Denys Dmytriyenko <denys@konsulko.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-09-20 14:36:14 -04:00
Bence Balogh 1947c00029 arm-bsp/trusted-firmware-m: corstone1000: Fix MPU configuration
The Application Root of Trust and the PSA Root of Trust was not
isolated in TF-M Isolation Level 2 beacuse of the misconfiguration of
the MPU. The added patch fixes this issue.

Fixes: a8f47e9 (arm-bsp/trusted-firmware-m: corstone1000: update to 2.0)
Signed-off-by: Bence Balogh <bence.balogh@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-09-17 17:00:19 -04:00
Harsimran Singh Tungal 313ad2a0e6 arm-bsp,kas: corstone1000: enable External System based on new yml file
Create new yml file "corstone1000-extsys.yml" which adds "corstone1000-extsys" as
new MACHINE_FEATURE.
Based on this, external system components can be enabled or disabled from the
Linux Kernel and U-Boot.

Reason for change:
DT-schema test is failing for the SystemReady-IR v2.0 certification because
device tree binding for remoteproc dts node corresponds to external system has
not been upstreamed in the Linux Kernel yet.
So, it has been decided to make enablement of external system configurable in
order to make Corstone1000 FVP SystemReady-IR v2.0 certifiable.

Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-08-30 05:00:25 -04:00
Luca Fancellu 38bce82e42 arm/oeqa: Introduce retry mechanism for fvp_devices run_cmd
Currently the run_cmd, which is a wrapper for self.target.run()
that uses SSH to spawn commands on the target, can fail spuriously
with error 255 and cause the test to fail on slow systems.

In order to address that, introduce a retry mechanism for the call,
that is able to wait some time for the system to settle and retry
the command when the error code from SSH is 255.

Signed-off-by: Luca Fancellu <luca.fancellu@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-08-01 11:33:42 -04:00
Amr Mohamed ecece16871 kas: Add new yml file for Distros unattended installation
Define “DISTRO_UNATTENDED_INST_TESTS” variable in meta-arm-systemready
independently from meta-arm-auto-solutions. This will allow running
the unattended installation without meta-arm-auto-solutions.

Signed-off-by: Amr Mohamed <amr.mohamed@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-07-31 11:00:22 -04:00
Amr Mohamed aa85142b5b arm-systemready/oeqa: Add new test for Fedora unattended installation
The oeqa test responds to the boot loader prompt error message and
waits till the distro installation is finished.

Signed-off-by: Amr Mohamed <amr.mohamed@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-07-31 11:00:22 -04:00
Amr Mohamed 54fa370dde arm-systemready/linux-distros: Add kickstart file for Fedora unattended
Add the Fedora kickstart configuration file and define a function to
modify the unpacked ISO image to add the kickstart file inside and
modify the grub.cfg file.

Signed-off-by: Amr Mohamed <amr.mohamed@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-07-31 11:00:22 -04:00
Amr Mohamed 79c41bb917 arm-systemready/linux-distros: new inc file for unattended installation
Add a new inc file to unpack and repack the distro ISO image after
adding the kickstart configuration file inside.

Signed-off-by: Amr Mohamed <amr.mohamed@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-07-31 11:00:22 -04:00
Amr Mohamed 1b85bbb4ca kas: Update kas configuration for fvp-base.yml file
Change defaults repo refspec in fvp-base.yml file from master to
scarthgap.

Signed-off-by: Amr Mohamed <amr.mohamed@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-07-19 10:00:23 -04:00
Ziad Elhanafy 58268ddccb arm/oeqa: Enable pexpect profiling for testcase debugging
This patch enables logging with timestamps for individual pexpect
assertions to ease the debugging of failed tests and the tuning of
timeouts. It measures the execution time of all pexpect calls and logs
the actual duration for each.

Only "callable" pexpect calls are timed (e.g. expect, sendline, but not
before or after).

Signed-off-by: Divin Raj <divin.raj@arm.com>
Signed-off-by: Ziad Elhanafy <ziad.elhanafy@arm.com>
Signed-off-by: Peter Hoyes <peter.hoyes@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-06-27 10:00:26 -04:00
Ross Burton 29799b787d Revert "CI: temporarily backport the procps fix"
This procps fix has been merged upstream in oe-core aaced482, so we can
remove this patch now.

This reverts commit fef5eafc08.

Signed-off-by: Ross Burton <ross.burton@arm.com>
2024-06-20 14:22:59 +01:00
Amr Mohamed a88dd94883 arm-systemready/linux-distros: Add a third Linux distribution installation
Add Fedora distribution version 39.1.5 installation to fulfill
the SystemReady IR.

Signed-off-by: Amr Mohamed <amr.mohamed@arm.com>
Signed-off-by: Jon Mason <jon.mason@arm.com>
2024-06-17 14:00:29 -04:00
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
67 changed files with 4555 additions and 431 deletions
+5
View File
@@ -255,6 +255,11 @@ n1sdp:
pending-updates:
extends: .setup
# Only run this job for the default branch (master), or if forced with
# BUILD_FORCE_PENDING_UPDATES.
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $BUILD_FORCE_PENDING_UPDATES != null
artifacts:
paths:
- update-report
@@ -1,79 +0,0 @@
From 42358d889ed652a8c386862f8c65e5fbe7484de2 Mon Sep 17 00:00:00 2001
From: Ross Burton <ross.burton@arm.com>
Date: Fri, 26 Apr 2024 10:38:28 +0000
Subject: [PATCH] procps: fix build with new glibc but old kernel headers
If you're building procps with a newer glibc (with pidfd_open()) but
older kernel headers (say 4.x, before __NR_pidfd_open) then procps will
fail to build because of a typo in configure.ac.
Signed-off-by: Ross Burton <ross.burton@arm.com>
---
.../procps/procps/pidfd.patch | 42 +++++++++++++++++++
meta/recipes-extended/procps/procps_4.0.4.bb | 1 +
2 files changed, 43 insertions(+)
create mode 100644 meta/recipes-extended/procps/procps/pidfd.patch
diff --git a/meta/recipes-extended/procps/procps/pidfd.patch b/meta/recipes-extended/procps/procps/pidfd.patch
new file mode 100644
index 00000000000..f5e8183e547
--- /dev/null
+++ b/meta/recipes-extended/procps/procps/pidfd.patch
@@ -0,0 +1,42 @@
+From c8f625e085b8249cc009e8b19c3a19100217eb35 Mon Sep 17 00:00:00 2001
+From: Ross Burton <ross.burton@arm.com>
+Date: Thu, 25 Apr 2024 13:33:15 +0000
+Subject: [PATCH] Fix pidfd_open detection
+
+This check for pidfd_open uses AC_CHECK_FUNC which just runs the specified code, but
+src/pgrep.c checks HAVE_PIDFD_OPEN which will only be defined by AC_CHECK_FUNCS.
+
+Also pidfd_open is defined in sys/pidfd.h so that needs including.
+
+Upstream-Status: Pending
+Signed-off-by: Ross Burton <ross.burton@arm.com>
+---
+
+diff --git a/configure.ac b/configure.ac
+index fec27e3f..024731c7 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -170,7 +170,7 @@ AC_TRY_COMPILE([#include <errno.h>],
+ AC_MSG_RESULT(yes),
+ AC_MSG_RESULT(no))
+
+-AC_CHECK_FUNC([pidfd_open], [enable_pidwait=yes], [
++AC_CHECK_FUNCS([pidfd_open], [enable_pidwait=yes], [
+ AC_MSG_CHECKING([for __NR_pidfd_open])
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+ #include <sys/syscall.h>
+diff --git a/src/pgrep.c b/src/pgrep.c
+index d8e57dff..c5211aec 100644
+--- a/src/pgrep.c
++++ b/src/pgrep.c
+@@ -44,7 +44,9 @@
+
+ #ifdef ENABLE_PIDWAIT
+ #include <sys/epoll.h>
+-#ifndef HAVE_PIDFD_OPEN
++#ifdef HAVE_PIDFD_OPEN
++#include <sys/pidfd.h>
++#else
+ #include <sys/syscall.h>
+ #endif /* !HAVE_PIDFD_OPEN */
+ #endif
diff --git a/meta/recipes-extended/procps/procps_4.0.4.bb b/meta/recipes-extended/procps/procps_4.0.4.bb
index 800384f22f7..ec8c4b0261b 100644
--- a/meta/recipes-extended/procps/procps_4.0.4.bb
+++ b/meta/recipes-extended/procps/procps_4.0.4.bb
@@ -14,6 +14,7 @@ inherit autotools gettext pkgconfig update-alternatives
SRC_URI = "git://gitlab.com/procps-ng/procps.git;protocol=https;branch=master \
file://sysctl.conf \
+ file://pidfd.patch \
"
SRCREV = "4ddcef2fd843170c8e2d59a83042978f41037a2b"
--
2.34.1
+1 -5
View File
@@ -17,14 +17,10 @@ repos:
meta-arm-toolchain:
poky:
url: https://git.yoctoproject.org/git/poky
url: https://git.yoctoproject.org/poky
layers:
meta:
meta-poky:
patches:
procps:
path: 0001-procps-fix-build-with-new-glibc-but-old-kernel-heade.patch
repo: meta-arm
env:
BB_LOGCONFIG: ""
+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"
+2 -2
View File
@@ -20,9 +20,9 @@ def repo_shortname(url):
.replace('*', '.'))
repositories = (
"https://git.yoctoproject.org/git/poky",
"https://git.yoctoproject.org/poky",
"https://git.openembedded.org/meta-openembedded",
"https://git.yoctoproject.org/git/meta-virtualization",
"https://git.yoctoproject.org/meta-virtualization",
"https://github.com/kraj/meta-clang",
)
@@ -2,6 +2,7 @@ header:
version: 13
includes:
- kas/arm-systemready-firmware.yml
- kas/arm-systemready-linux-distros-unattended-installation.yml
target:
- arm-systemready-linux-distros-opensuse
@@ -0,0 +1,11 @@
header:
version: 16
env:
DISTRO_UNATTENDED_INST_TESTS:
# The full testimage run typically takes around 12-24h on fvp-base.
TEST_OVERALL_TIMEOUT: "${@ 24*60*60}"
local_conf_header:
systemready-unattended-inst: |
TESTIMAGE_AUTO = "${@oe.utils.vartrue("DISTRO_UNATTENDED_INST_TESTS", "1", "", d)}"
+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:
+6
View File
@@ -0,0 +1,6 @@
header:
version: 14
local_conf_header:
extsys: |
MACHINE_FEATURES += "corstone1000-extsys"
-1
View File
@@ -13,7 +13,6 @@ env:
local_conf_header:
testimagefvp: |
LICENSE_FLAGS_ACCEPTED += "Arm-FVP-EULA"
IMAGE_CLASSES += "fvpboot"
mass-storage: |
+1 -1
View File
@@ -14,7 +14,7 @@ machine: fvp-base
defaults:
repos:
refspec: master
refspec: scarthgap
repos:
meta-arm:
@@ -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,35 @@ 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
SystemReady IR v2.0 Certification Milestone
-------------------------------------------
As of this release, Corstone-1000 has achieved `SystemReady IR v2.0 certification <https://www.arm.com/architecture/system-architectures/systemready-certification-program/ve>`__.
This milestone confirms compliance with the SystemReady IR requirements, ensuring broader compatibility and reliability for deployment.
Applied patch `313ad2a0e600 <https://git.yoctoproject.org/meta-arm/commit/?h=scarthgap&id=313ad2a0e600655d9bfbe53646e356372ff02644>`__ to address compatibility requirements for SystemReady IR v2.0.
This update is included in tag `CORSTONE1000-2024.06-systemready-ir-v2.0 <https://git.yoctoproject.org/meta-arm/tag/?h=CORSTONE1000-2024.06-systemready-ir-v2.0>`__ and builds on the `CORSTONE1000-2024.06` release.
***********************
Release notes - 2023.11
***********************
@@ -213,7 +242,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:
@@ -180,6 +180,12 @@ then run:
kas build meta-arm/kas/corstone1000-fvp.yml:meta-arm/ci/debug.yml
By default, the external system is disabled. To build the Corstone-1000 image with external system enabled, run:
::
kas build meta-arm/kas/corstone1000-<fvp,mps3>.yml:meta-arm/ci/debug.yml:meta-arm/kas/corstone1000-extsys.yml
The initial clean build will be lengthy, given that all host utilities are to
be built as well as the target images. This includes host executables (python,
cmake, etc.) and the required toolchain(s).
@@ -364,6 +370,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 +418,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 +434,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 +454,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 +488,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 +514,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 +540,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 +554,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 +574,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 +585,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 +597,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 +685,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 +729,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 +751,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 +770,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 +807,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 +838,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 +857,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 +897,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 +928,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 +964,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 +977,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 +989,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 +1023,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 +1059,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 +1093,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 +1149,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 +1236,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 +1244,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 +1259,217 @@ 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
---------------------------
Before testing the external system, please make sure to build the Corstone-1000 image with external system enabled as mentioned in section `Building the software stack`_.
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
@@ -0,0 +1,88 @@
From 4d3ebb03b89b122af490824ca73287954a35bd07 Mon Sep 17 00:00:00 2001
From: Jamie Fox <jamie.fox@arm.com>
Date: Thu, 22 Aug 2024 16:54:45 +0100
Subject: [PATCH] Platform: corstone1000: Fix isolation L2 memory protection
The whole of the SRAM was configured unprivileged on this platform, so
the memory protection required for isolation level 2 was not present.
This patch changes the S_DATA_START to S_DATA_LIMIT MPU region to be
configured for privileged access only. It also reorders the MPU regions
so that the App RoT sub-region overlapping S_DATA has a higher region
number and so takes priority in the operation of the Armv6-M MPU.
Signed-off-by: Jamie Fox <jamie.fox@arm.com>
Upstream-Status: Submitted [https://review.trustedfirmware.org/c/TF-M/trusted-firmware-m/+/30951]
---
.../arm/corstone1000/tfm_hal_isolation.c | 43 +++++++++----------
1 file changed, 21 insertions(+), 22 deletions(-)
diff --git a/platform/ext/target/arm/corstone1000/tfm_hal_isolation.c b/platform/ext/target/arm/corstone1000/tfm_hal_isolation.c
index 39b19c535..498f14ed2 100644
--- a/platform/ext/target/arm/corstone1000/tfm_hal_isolation.c
+++ b/platform/ext/target/arm/corstone1000/tfm_hal_isolation.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2024, Arm Limited. All rights reserved.
* Copyright (c) 2022 Cypress Semiconductor Corporation (an Infineon
* company) or an affiliate of Cypress Semiconductor Corporation. All rights
* reserved.
@@ -99,6 +99,26 @@ enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(
return ret;
}
+ /* Set the RAM attributes. It is needed because the first region overlaps the whole
+ * SRAM and it has to be overridden.
+ * The RAM_MPU_REGION_BLOCK_1_SIZE and RAM_MPU_REGION_BLOCK_2_SIZE are calculated manually
+ * and added to the platform_region_defs compile definitions.
+ */
+ base = S_DATA_START;
+ limit = S_DATA_START + RAM_MPU_REGION_BLOCK_1_SIZE;
+ ret = configure_mpu(rnr++, base, limit,
+ XN_EXEC_NOT_OK, AP_RW_PRIV_ONLY);
+ if (ret != TFM_HAL_SUCCESS) {
+ return ret;
+ }
+
+ base = S_DATA_START + RAM_MPU_REGION_BLOCK_1_SIZE;
+ limit = S_DATA_START + RAM_MPU_REGION_BLOCK_1_SIZE + RAM_MPU_REGION_BLOCK_2_SIZE;
+ ret = configure_mpu(rnr++, base, limit,
+ XN_EXEC_NOT_OK, AP_RW_PRIV_ONLY);
+ if (ret != TFM_HAL_SUCCESS) {
+ return ret;
+ }
/* RW, ZI and stack as one region */
base = (uint32_t)&REGION_NAME(Image$$, TFM_APP_RW_STACK_START, $$Base);
@@ -133,27 +153,6 @@ enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(
#endif
- /* Set the RAM attributes. It is needed because the first region overlaps the whole
- * SRAM and it has to be overridden.
- * The RAM_MPU_REGION_BLOCK_1_SIZE and RAM_MPU_REGION_BLOCK_2_SIZE are calculated manually
- * and added to the platform_region_defs compile definitions.
- */
- base = S_DATA_START;
- limit = S_DATA_START + RAM_MPU_REGION_BLOCK_1_SIZE;
- ret = configure_mpu(rnr++, base, limit,
- XN_EXEC_NOT_OK, AP_RW_PRIV_UNPRIV);
- if (ret != TFM_HAL_SUCCESS) {
- return ret;
- }
-
- base = S_DATA_START + RAM_MPU_REGION_BLOCK_1_SIZE;
- limit = S_DATA_START + RAM_MPU_REGION_BLOCK_1_SIZE + RAM_MPU_REGION_BLOCK_2_SIZE;
- ret = configure_mpu(rnr++, base, limit,
- XN_EXEC_NOT_OK, AP_RW_PRIV_UNPRIV);
- if (ret != TFM_HAL_SUCCESS) {
- return ret;
- }
-
arm_mpu_enable();
#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
--
2.25.1
@@ -25,7 +25,11 @@ 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 \
file://0013-Platform-corstone1000-Fix-isolation-L2-memory-protection.patch \
"
# TF-M ships patches for external dependencies that needs to be applied
@@ -64,6 +64,8 @@ SRC_URI:append = " \
file://0046-Corstone1000-Change-MMCOMM-buffer-location.patch \
file://0047-corstone1000-dts-add-external-system-node.patch \
file://0048-corstone1000-Enable-UEFI-Secure-boot.patch \
${@bb.utils.contains('MACHINE_FEATURES', 'corstone1000-extsys', \
'', 'file://0049-corstone1000-purge-remoteproc-dts-node.patch' , d)} \
"
do_configure:append() {
@@ -0,0 +1,34 @@
From 4e0ab7af882fcf498fd8beb4024ea024e6464cef Mon Sep 17 00:00:00 2001
From: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
Date: Wed, 14 Aug 2024 14:33:50 +0000
Subject: [PATCH] corstone1000: purge remoteproc DTS node
Purge remoteproc DTS node
This is done to remove the remote proc node from the DTS passed
to Linux from U-Boot because the device tree binding for remoteproc
has not been upstreamed yet. Existence of remoteproc DTS node in Linux
is causing dt-schema test for SystemReady-IR v2.0 certification to fail.
Upstream-Status: Pending
Signed-off-by: Harsimran Singh Tungal <harsimransingh.tungal@arm.com>
---
board/armltd/corstone1000/corstone1000.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/board/armltd/corstone1000/corstone1000.c b/board/armltd/corstone1000/corstone1000.c
index ef74dc9032..d474fce1b2 100644
--- a/board/armltd/corstone1000/corstone1000.c
+++ b/board/armltd/corstone1000/corstone1000.c
@@ -30,8 +30,7 @@ DT_NON_COMPLIANT_PURGE_LIST(foo) = {
{ .node_path = "/soc/mhu@1b010000" },
{ .node_path = "/soc/mhu@1b020000" },
{ .node_path = "/soc/mhu@1b030000" },
- { .node_path = "/soc/client" },
- { .node_path = "/soc/extsys@1A010310" },
+ { .node_path = "/soc/remoteproc@1a010310" },
};
#define CORSTONE1000_KERNEL_PARTS 2
--
2.34.1
@@ -0,0 +1 @@
CONFIG_MTD_NAND_FSL_IFC=n
@@ -36,13 +36,21 @@ SRC_URI:append:corstone1000 = " ${@bb.utils.contains('MACHINE_FEATURES', \
'file://corstone1000_kernel_debug.cfg', \
'', \
d)}"
SRC_URI:append:corstone1000 = " \
file://extsys.cfg \
file://0001-remoteproc-Add-Arm-remoteproc-driver.patch \
file://0002-arm64-dts-Add-corstone1000-external-system-device-no.patch \
file://0003-dt-bindings-remoteproc-Add-Arm-remoteproc.patch \
"
${@bb.utils.contains( \
'MACHINE_FEATURES', \
'corstone1000-extsys', \
' \
file://extsys.cfg \
file://0001-remoteproc-Add-Arm-remoteproc-driver.patch \
file://0002-arm64-dts-Add-corstone1000-external-system-device-no.patch \
file://0003-dt-bindings-remoteproc-Add-Arm-remoteproc.patch \
', \
'', \
d \
) \
} \
"
# Default kernel features not needed for corstone1000
# otherwise the extra kernel modules will increase the rootfs size
@@ -69,6 +77,9 @@ SRC_URI:append:fvp-base = " \
#
COMPATIBLE_MACHINE:juno = "juno"
FILESEXTRAPATHS:prepend:juno := "${ARMBSPFILESPATHS}"
SRC_URI:append:juno = " \
file://no-fsl-ifc-nand.cfg \
"
#
# Musca B1/S2 can't run Linux
@@ -95,6 +106,7 @@ SRC_URI:append:n1sdp = " \
file://enable-realtek-R8169.cfg \
file://enable-usb_conn_gpio.cfg \
file://usb_xhci_pci_renesas.cfg \
file://no-fsl-ifc-nand.cfg \
"
# Since we use the intree defconfig and the preempt-rt turns off some configs
# do_kernel_configcheck will display warnings. So, lets disable it.
@@ -1,46 +0,0 @@
#!/bin/sh
# Source function library
. /etc/init.d/functions
NAME=tee-supplicant
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DESC="OP-TEE Supplicant"
DAEMON=@sbindir@/$NAME
test -f $DAEMON || exit 0
test -f @sysconfdir@/default/$NAME && . @sysconfdir@/default/$NAME
test -f @sysconfdir@/default/rcS && . @sysconfdir@/default/rcS
SSD_OPTIONS="--oknodo --quiet --exec $DAEMON -- -d $OPTARGS"
set -e
case $1 in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start $SSD_OPTIONS
echo "${DAEMON##*/}."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop $SSD_OPTIONS
echo "${DAEMON##*/}."
;;
restart|force-reload)
$0 stop
sleep 1
$0 start
;;
status)
status ${DAEMON} || exit $?
;;
*)
echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2
exit 1
;;
esac
exit 0
@@ -1,10 +0,0 @@
[Unit]
Description=TEE Supplicant on %i
[Service]
User=root
EnvironmentFile=-@sysconfdir@/default/tee-supplicant
ExecStart=@sbindir@/tee-supplicant $OPTARGS
[Install]
WantedBy=basic.target
@@ -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" \
@@ -0,0 +1,42 @@
from oeqa.runtime.case import OERuntimeTestCase
class SystemReadyOpenSUSEUnattendedTest(OERuntimeTestCase):
def setUp(self):
super().setUp()
self.console = self.target.DEFAULT_CONSOLE
def test_opensuse_unattended(self):
# Turn on the FVP.
self.target.transition('on')
# Timeout value = elapsed time * 2; where elapsed time was collected
# from the elapsed time in the log.do_testimage for each function after
# the build is finished on the development machine.
self.target.expect(self.console,
'Booting `Installation\'',
timeout=(2 * 60))
bb.plain('Installation status: Loading the kernel, initrd and basic drivers...')
self.target.expect(self.console,
'Starting hardware detection...',
timeout=(40 * 60))
bb.plain('Installation status: Starting hardware detection...')
self.target.expect(self.console,
'Loading Installation System',
timeout=(60 * 60))
bb.plain('Installation status: Loading Installation System...')
self.target.expect(self.console,
'Starting Installer',
timeout=(40 * 60))
bb.plain('Installation status: Performing Installation...')
self.target.expect(self.console,
'Finishing Configuration',
timeout=(15 * 60 * 60))
bb.plain('Installation status: Finishing Configuration...')
# Waiting till the installation is finished.
self.target.expect(self.console, r'.*login: ', timeout=(6 * 60 * 60))
bb.plain('Installation status: openSUSE installation finished successfully.')
@@ -48,10 +48,10 @@ TEST_SUITES = "arm_systemready_ir_acs"
PV = "2.0.0"
PV_DATE = "23.03"
FULL_PV = "v${PV_DATE}_${PV}"
ARM_SYSTEMREADY_IR_ACS_BRANCH ?= "main"
IMAGE_FILENAME = "ir-acs-live-image-generic-arm64.wic"
ARM_SYSTEMREADY_IR_ACS_BRANCH ?= "legacy_systemready"
IMAGE_FILENAME = "ir-acs-live-image-generic-arm64-${PV}.wic"
SRC_URI = " \
https://github.com/ARM-software/arm-systemready/raw/${ARM_SYSTEMREADY_IR_ACS_BRANCH}/IR/prebuilt_images/${FULL_PV}/${IMAGE_FILENAME}.xz;name=acs-img \
https://github.com/ARM-software/arm-systemready/raw/${ARM_SYSTEMREADY_IR_ACS_BRANCH}/IR/prebuilt_images/${FULL_PV}/ir-acs-live-image-generic-arm64.wic.xz;name=acs-img;downloadfilename=${IMAGE_FILENAME}.xz \
git://git.gitlab.arm.com/systemready/systemready-ir-template.git;protocol=https;nobranch=1;destsuffix=systemready-ir-template;name=sr-ir-template \
"
SRC_URI[acs-img.sha256sum] = "ea52f84dab44bde97de3e2d2224d883acaae35724dd8e2bdfb125de49040f9b3"
@@ -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,32 @@ 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"
TEST_SUITES = "${@oe.utils.vartrue("DISTRO_UNATTENDED_INST_TESTS", "arm_systemready_opensuse_unattended", "", d)}"
ISO_LABEL = "${@oe.utils.vartrue("DISTRO_UNATTENDED_INST_TESTS", "OEMDRV", "", d)}"
BOOT_CATALOG = "${@oe.utils.vartrue("DISTRO_UNATTENDED_INST_TESTS", "boot.catalog", "", d)}"
BOOT_IMAGE = "${@oe.utils.vartrue("DISTRO_UNATTENDED_INST_TESTS", "EFI/BOOT/bootaa64.efi", "", d)}"
EFI_IMAGE = "${@oe.utils.vartrue("DISTRO_UNATTENDED_INST_TESTS", "boot/aarch64/efi", "", d)}"
modifyiso() {
UNATTENDED_CONF_DIR="${THISDIR}/unattended-boot-conf/openSUSE"
#create installation configuration files, remove grub timeout, setup network
cp "${UNATTENDED_CONF_DIR}/autoinst.xml" ${EXTRACTED_ISO_TEMP_DIR}
sed -i 's/timeout=60/timeout=0/g' "${EXTRACTED_ISO_TEMP_DIR}/EFI/BOOT/grub.cfg"
}
@@ -0,0 +1,45 @@
SUMMARY = "Arm SystemReady Linux distros unattended requirements"
DESCRIPTION = "Arm SystemReady Linux distro unattended configurations \
and ISO image modification"
EXTRACTED_ISO_TEMP_DIR = "${WORKDIR}/extracted_iso_temp_dir"
NEW_ISO_TEMP_DIR = "${WORKDIR}/new_iso_temp_dir"
# oeqa test case must be added to TEST_SUITES to acknowledge that the unattended
# installation was successful.
inherit testimage
python () {
unattended_required_vars = ['ISO_LABEL', 'BOOT_CATALOG', 'BOOT_IMAGE', 'EFI_IMAGE']
for var in unattended_required_vars:
if not d.getVar(var):
raise bb.parse.SkipRecipe(f'{var} variable is not set')
}
unpackiso() {
# Unpack the ISO image
bsdtar -xf ${WORKDIR}/${ISO_IMAGE_NAME}.iso -C ${EXTRACTED_ISO_TEMP_DIR}
chmod -R u+rw ${EXTRACTED_ISO_TEMP_DIR}
}
modifyiso() {
}
repackiso() {
# Repack the ISO image
mkisofs -o ${NEW_ISO_TEMP_DIR}/${ISO_IMAGE_NAME}.iso -U -r -v -T -J -joliet-long -V ${ISO_LABEL} \
-volset ${ISO_LABEL} -A ${ISO_LABEL} -b ${BOOT_IMAGE} -c ${BOOT_CATALOG} -no-emul-boot \
-boot-load-size 4 -boot-info-table -J -R -V ${ISO_LABEL} -eltorito-alt-boot \
-eltorito-boot ${EFI_IMAGE} -no-emul-boot ${EXTRACTED_ISO_TEMP_DIR}
mv -f ${NEW_ISO_TEMP_DIR}/${ISO_IMAGE_NAME}.iso ${WORKDIR}
}
# Write the test data in IMAGE_POSTPROCESS_COMMAND
IMAGE_POSTPROCESS_COMMAND += "write_image_test_data; "
do_unpack[depends] += "cdrtools-native:do_populate_sysroot libarchive-native:do_populate_sysroot"
do_unpack[postfuncs] += "unpackiso modifyiso repackiso"
do_unpack[cleandirs] += "${EXTRACTED_ISO_TEMP_DIR} ${NEW_ISO_TEMP_DIR}"
@@ -2,7 +2,12 @@ SUMMARY = "Arm SystemReady Linux distros installation"
DESCRIPTION = "Arm SystemReady Linux distro CD/DVD images and installation \
target disk image"
IMAGE_CLASSES:remove = "license_image testimage"
DISTRO_UNATTENDED_INST_TESTS ?= "0"
require ${@oe.utils.vartrue("DISTRO_UNATTENDED_INST_TESTS", "arm-systemready-linux-distros-unattended.inc", "", d)}
IMAGE_CLASSES:remove = "license_image"
IMAGE_CLASSES:remove = "${@oe.utils.vartrue("DISTRO_UNATTENDED_INST_TESTS", "", "testimage", d)}"
BUILDHISTORY_FEATURES:remove = "image"
INHIBIT_DEFAULT_DEPS = "1"
@@ -15,7 +20,7 @@ do_configure[noexec] = "1"
do_compile[noexec] = "1"
ISO_IMAGE_NAME = "${PN}-${PV}"
IMAGE_LINK_NAME = "${PN}-${PV}-${MACHINE}"
IMAGE_LINK_NAME = "${PN}-${MACHINE}"
ARM_SYSTEMREADY_LINUX_DISTRO_ISO_IMAGE = \
"${DEPLOY_DIR_IMAGE}/${ISO_IMAGE_NAME}.iso"
@@ -44,7 +49,13 @@ python do_image_complete() {
from oe.utils import execute_pre_post_process
post_process_cmds = d.getVar("IMAGE_POSTPROCESS_COMMAND")
execute_pre_post_process(d, post_process_cmds)
if d.getVar('DISTRO_UNATTENDED_INST_TESTS') == "1":
# Ensure an empty rootfs manifest exists (required by testimage)
fname = os.path.join(d.getVar('IMGDEPLOYDIR'), d.getVar('IMAGE_LINK_NAME') + ".manifest")
open(fname, 'w').close()
}
do_image_complete[nostamp] = "1"
addtask image_complete after do_deploy before do_build
@@ -0,0 +1,935 @@
<?xml version="1.0"?>
<!DOCTYPE profile>
<profile xmlns="http://www.suse.com/1.0/yast2ns" xmlns:config="http://www.suse.com/1.0/configns">
<bootloader t="map">
<global t="map">
<append>splash=silent preempt=full mitigations=auto quiet security=apparmor</append>
<cpu_mitigations>auto</cpu_mitigations>
<gfxmode>auto</gfxmode>
<hiddenmenu>false</hiddenmenu>
<os_prober>true</os_prober>
<secure_boot>true</secure_boot>
<terminal>gfxterm</terminal>
<timeout t="integer">8</timeout>
<update_nvram>true</update_nvram>
</global>
<loader_type>grub2-efi</loader_type>
</bootloader>
<firewall t="map">
<default_zone>public</default_zone>
<enable_firewall t="boolean">true</enable_firewall>
<log_denied_packets>off</log_denied_packets>
<start_firewall t="boolean">true</start_firewall>
<zones t="list">
<zone t="map">
<description>Unsolicited incoming network packets are rejected. Incoming packets that are related to outgoing network connections are accepted. Outgoing network connections are allowed.</description>
<interfaces t="list"/>
<masquerade t="boolean">false</masquerade>
<name>block</name>
<ports t="list"/>
<protocols t="list"/>
<services t="list"/>
<short>Block</short>
<target>%%REJECT%%</target>
</zone>
<zone t="map">
<description>For computers in your demilitarized zone that are publicly-accessible with limited access to your internal network. Only selected incoming connections are accepted.</description>
<interfaces t="list"/>
<masquerade t="boolean">false</masquerade>
<name>dmz</name>
<ports t="list"/>
<protocols t="list"/>
<services t="list">
<service>ssh</service>
</services>
<short>DMZ</short>
<target>default</target>
</zone>
<zone t="map">
<description>All network connections are accepted.</description>
<interfaces t="list">
<interface>docker0</interface>
</interfaces>
<masquerade t="boolean">false</masquerade>
<name>docker</name>
<ports t="list"/>
<protocols t="list"/>
<services t="list"/>
<short>docker</short>
<target>ACCEPT</target>
</zone>
<zone t="map">
<description>Unsolicited incoming network packets are dropped. Incoming packets that are related to outgoing network connections are accepted. Outgoing network connections are allowed.</description>
<interfaces t="list"/>
<masquerade t="boolean">false</masquerade>
<name>drop</name>
<ports t="list"/>
<protocols t="list"/>
<services t="list"/>
<short>Drop</short>
<target>DROP</target>
</zone>
<zone t="map">
<description>For use on external networks. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<interfaces t="list"/>
<masquerade t="boolean">true</masquerade>
<name>external</name>
<ports t="list"/>
<protocols t="list"/>
<services t="list">
<service>ssh</service>
</services>
<short>External</short>
<target>default</target>
</zone>
<zone t="map">
<description>For use in home areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<interfaces t="list"/>
<masquerade t="boolean">false</masquerade>
<name>home</name>
<ports t="list"/>
<protocols t="list"/>
<services t="list">
<service>dhcpv6-client</service>
<service>mdns</service>
<service>samba-client</service>
<service>ssh</service>
</services>
<short>Home</short>
<target>default</target>
</zone>
<zone t="map">
<description>For use on internal networks. You mostly trust the other computers on the networks to not harm your computer. Only selected incoming connections are accepted.</description>
<interfaces t="list"/>
<masquerade t="boolean">false</masquerade>
<name>internal</name>
<ports t="list"/>
<protocols t="list"/>
<services t="list">
<service>dhcpv6-client</service>
<service>mdns</service>
<service>samba-client</service>
<service>ssh</service>
</services>
<short>Internal</short>
<target>default</target>
</zone>
<zone t="map">
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<interfaces t="list">
<interface>eth0</interface>
</interfaces>
<masquerade t="boolean">false</masquerade>
<name>public</name>
<ports t="list"/>
<protocols t="list"/>
<services t="list">
<service>dhcpv6-client</service>
<service>ssh</service>
</services>
<short>Public</short>
<target>default</target>
</zone>
<zone t="map">
<description>All network connections are accepted.</description>
<interfaces t="list"/>
<masquerade t="boolean">false</masquerade>
<name>trusted</name>
<ports t="list"/>
<protocols t="list"/>
<services t="list"/>
<short>Trusted</short>
<target>ACCEPT</target>
</zone>
<zone t="map">
<description>For use in work areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<interfaces t="list"/>
<masquerade t="boolean">false</masquerade>
<name>work</name>
<ports t="list"/>
<protocols t="list"/>
<services t="list">
<service>dhcpv6-client</service>
<service>ssh</service>
</services>
<short>Work</short>
<target>default</target>
</zone>
</zones>
</firewall>
<general t="map">
<mode t="map">
<confirm t="boolean">false</confirm>
</mode>
</general>
<groups t="list">
<group t="map">
<gid>100</gid>
<groupname>users</groupname>
<userlist/>
</group>
<group t="map">
<gid>499</gid>
<groupname>messagebus</groupname>
<userlist/>
</group>
<group t="map">
<gid>1</gid>
<groupname>bin</groupname>
<userlist>daemon</userlist>
</group>
<group t="map">
<gid>488</gid>
<groupname>input</groupname>
<userlist/>
</group>
<group t="map">
<gid>495</gid>
<groupname>kmem</groupname>
<userlist/>
</group>
<group t="map">
<gid>493</gid>
<groupname>utmp</groupname>
<userlist/>
</group>
<group t="map">
<gid>62</gid>
<groupname>man</groupname>
<userlist/>
</group>
<group t="map">
<gid>477</gid>
<groupname>polkitd</groupname>
<userlist/>
</group>
<group t="map">
<gid>479</gid>
<groupname>systemd-timesync</groupname>
<userlist/>
</group>
<group t="map">
<gid>2</gid>
<groupname>daemon</groupname>
<userlist/>
</group>
<group t="map">
<gid>480</gid>
<groupname>systemd-network</groupname>
<userlist/>
</group>
<group t="map">
<gid>71</gid>
<groupname>ntadmin</groupname>
<userlist/>
</group>
<group t="map">
<gid>490</gid>
<groupname>dialout</groupname>
<userlist/>
</group>
<group t="map">
<gid>59</gid>
<groupname>maildrop</groupname>
<userlist>postfix</userlist>
</group>
<group t="map">
<gid>478</gid>
<groupname>nscd</groupname>
<userlist/>
</group>
<group t="map">
<gid>51</gid>
<groupname>postfix</groupname>
<userlist/>
</group>
<group t="map">
<gid>485</gid>
<groupname>tape</groupname>
<userlist/>
</group>
<group t="map">
<gid>487</gid>
<groupname>render</groupname>
<userlist/>
</group>
<group t="map">
<gid>476</gid>
<groupname>sshd</groupname>
<userlist/>
</group>
<group t="map">
<gid>491</gid>
<groupname>cdrom</groupname>
<userlist/>
</group>
<group t="map">
<gid>486</gid>
<groupname>sgx</groupname>
<userlist/>
</group>
<group t="map">
<gid>0</gid>
<groupname>root</groupname>
<userlist/>
</group>
<group t="map">
<gid>489</gid>
<groupname>disk</groupname>
<userlist/>
</group>
<group t="map">
<gid>15</gid>
<groupname>shadow</groupname>
<userlist/>
</group>
<group t="map">
<gid>484</gid>
<groupname>video</groupname>
<userlist/>
</group>
<group t="map">
<gid>496</gid>
<groupname>wheel</groupname>
<userlist/>
</group>
<group t="map">
<gid>483</gid>
<groupname>audit</groupname>
<userlist/>
</group>
<group t="map">
<gid>498</gid>
<groupname>mail</groupname>
<userlist>postfix</userlist>
</group>
<group t="map">
<gid>5</gid>
<groupname>tty</groupname>
<userlist/>
</group>
<group t="map">
<gid>65533</gid>
<groupname>nogroup</groupname>
<userlist/>
</group>
<group t="map">
<gid>65534</gid>
<groupname>nobody</groupname>
<userlist/>
</group>
<group t="map">
<gid>497</gid>
<groupname>lp</groupname>
<userlist/>
</group>
<group t="map">
<gid>482</gid>
<groupname>chrony</groupname>
<userlist/>
</group>
<group t="map">
<gid>492</gid>
<groupname>audio</groupname>
<userlist/>
</group>
<group t="map">
<gid>494</gid>
<groupname>lock</groupname>
<userlist/>
</group>
<group t="map">
<gid>36</gid>
<groupname>kvm</groupname>
<userlist/>
</group>
<group t="map">
<gid>42</gid>
<groupname>trusted</groupname>
<userlist/>
</group>
<group t="map">
<gid>481</gid>
<groupname>systemd-journal</groupname>
<userlist/>
</group>
</groups>
<host t="map">
<hosts t="list">
<hosts_entry t="map">
<host_address>127.0.0.1</host_address>
<names t="list">
<name>localhost</name>
</names>
</hosts_entry>
<hosts_entry t="map">
<host_address>::1</host_address>
<names t="list">
<name>localhost ipv6-localhost ipv6-loopback</name>
</names>
</hosts_entry>
<hosts_entry t="map">
<host_address>fe00::0</host_address>
<names t="list">
<name>ipv6-localnet</name>
</names>
</hosts_entry>
<hosts_entry t="map">
<host_address>ff00::0</host_address>
<names t="list">
<name>ipv6-mcastprefix</name>
</names>
</hosts_entry>
<hosts_entry t="map">
<host_address>ff02::1</host_address>
<names t="list">
<name>ipv6-allnodes</name>
</names>
</hosts_entry>
<hosts_entry t="map">
<host_address>ff02::2</host_address>
<names t="list">
<name>ipv6-allrouters</name>
</names>
</hosts_entry>
<hosts_entry t="map">
<host_address>ff02::3</host_address>
<names t="list">
<name>ipv6-allhosts</name>
</names>
</hosts_entry>
</hosts>
</host>
<language t="map">
<language>en_GB</language>
<languages>en_GB</languages>
</language>
<networking t="map">
<dhcp_options t="map">
<dhclient_client_id/>
<dhclient_hostname_option>AUTO</dhclient_hostname_option>
</dhcp_options>
<dns t="map">
<dhcp_hostname t="boolean">true</dhcp_hostname>
<hostname>localhost</hostname>
<resolv_conf_policy>auto</resolv_conf_policy>
</dns>
<interfaces t="list">
<interface t="map">
<bootproto>dhcp</bootproto>
<name>eth0</name>
<startmode>auto</startmode>
<zone>public</zone>
</interface>
</interfaces>
<ipv6 t="boolean">true</ipv6>
<keep_install_network t="boolean">true</keep_install_network>
<managed t="boolean">false</managed>
<routing t="map">
<ipv4_forward t="boolean">false</ipv4_forward>
<ipv6_forward t="boolean">false</ipv6_forward>
</routing>
</networking>
<ntp-client t="map">
<ntp_policy>auto</ntp_policy>
<ntp_servers t="list"/>
<ntp_sync>systemd</ntp_sync>
</ntp-client>
<partitioning t="list">
<drive t="map">
<device>/dev/vda</device>
<disklabel>gpt</disklabel>
<enable_snapshots t="boolean">false</enable_snapshots>
<partitions t="list">
<partition t="map">
<create t="boolean">true</create>
<filesystem t="symbol">vfat</filesystem>
<format t="boolean">true</format>
<fstopt>utf8</fstopt>
<mount>/boot/efi</mount>
<mountby t="symbol">uuid</mountby>
<partition_id t="integer">259</partition_id>
<partition_nr t="integer">1</partition_nr>
<resize t="boolean">false</resize>
<size>134217728</size>
</partition>
<partition t="map">
<create t="boolean">true</create>
<create_subvolumes t="boolean">true</create_subvolumes>
<filesystem t="symbol">btrfs</filesystem>
<format t="boolean">true</format>
<mount>/</mount>
<mountby t="symbol">uuid</mountby>
<partition_id t="integer">131</partition_id>
<partition_nr t="integer">2</partition_nr>
<quotas t="boolean">false</quotas>
<resize t="boolean">false</resize>
<size>6307167744</size>
<subvolumes t="list">
<subvolume t="map">
<copy_on_write t="boolean">false</copy_on_write>
<path>var</path>
</subvolume>
<subvolume t="map">
<copy_on_write t="boolean">true</copy_on_write>
<path>usr/local</path>
</subvolume>
<subvolume t="map">
<copy_on_write t="boolean">true</copy_on_write>
<path>tmp</path>
</subvolume>
<subvolume t="map">
<copy_on_write t="boolean">true</copy_on_write>
<path>srv</path>
</subvolume>
<subvolume t="map">
<copy_on_write t="boolean">true</copy_on_write>
<path>root</path>
</subvolume>
<subvolume t="map">
<copy_on_write t="boolean">true</copy_on_write>
<path>opt</path>
</subvolume>
<subvolume t="map">
<copy_on_write t="boolean">true</copy_on_write>
<path>home</path>
</subvolume>
<subvolume t="map">
<copy_on_write t="boolean">true</copy_on_write>
<path>boot/grub2/arm64-efi</path>
</subvolume>
</subvolumes>
<subvolumes_prefix>@</subvolumes_prefix>
</partition>
</partitions>
<type t="symbol">CT_DISK</type>
<use>all</use>
</drive>
</partitioning>
<proxy t="map">
<enabled t="boolean">false</enabled>
</proxy>
<services-manager t="map">
<default_target>multi-user</default_target>
<services t="map">
<enable t="list">
<service>YaST2-Firstboot</service>
<service>YaST2-Second-Stage</service>
<service>apparmor</service>
<service>auditd</service>
<service>klog</service>
<service>chronyd</service>
<service>cron</service>
<service>cups</service>
<service>firewalld</service>
<service>wickedd-auto4</service>
<service>wickedd-dhcp4</service>
<service>wickedd-dhcp6</service>
<service>wickedd-nanny</service>
<service>irqbalance</service>
<service>issue-generator</service>
<service>kbdsettings</service>
<service>wicked</service>
<service>nscd</service>
<service>postfix</service>
<service>purge-kernels</service>
<service>rsyslog</service>
<service>smartd</service>
<service>sshd</service>
<service>systemd-pstore</service>
<service>systemd-remount-fs</service>
</enable>
</services>
</services-manager>
<software t="map">
<install_recommended t="boolean">true</install_recommended>
<instsource/>
<packages t="list">
<package>wicked</package>
<package>shim</package>
<package>os-prober</package>
<package>openssh</package>
<package>openSUSE-release</package>
<package>mokutil</package>
<package>kexec-tools</package>
<package>grub2-arm64-efi</package>
<package>glibc</package>
<package>firewalld</package>
<package>e2fsprogs</package>
<package>dosfstools</package>
<package>chrony</package>
<package>btrfsprogs</package>
<package>autoyast2</package>
</packages>
<patterns t="list">
<pattern>apparmor</pattern>
<pattern>base</pattern>
<pattern>documentation</pattern>
<pattern>enhanced_base</pattern>
<pattern>minimal_base</pattern>
<pattern>sw_management</pattern>
<pattern>yast2_basis</pattern>
</patterns>
<products t="list">
<product>Leap</product>
</products>
</software>
<ssh_import t="map">
<copy_config t="boolean">false</copy_config>
<import t="boolean">false</import>
</ssh_import>
<user_defaults t="map">
<expire/>
<group>100</group>
<home>/home</home>
<inactive>-1</inactive>
<shell>/bin/bash</shell>
<umask>022</umask>
</user_defaults>
<users t="list">
<user t="map">
<authorized_keys t="list"/>
<encrypted t="boolean">true</encrypted>
<fullname>user</fullname>
<gid>100</gid>
<home>/home/user</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max>99999</max>
<min>0</min>
<warn>7</warn>
</password_settings>
<shell>/bin/bash</shell>
<uid>1000</uid>
<user_password>$6$WV8CB/c6j0zhAi5S$4euhbt4alH7WNfaatS9IJgPiiKDJ48d5Ru1zCZCA0N9GiyOPuefN2PAUWlyYeTgqAInpyvPh1frdp4fFVjvEn0</user_password>
<username>user</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>User for nscd</fullname>
<gid>478</gid>
<home>/run/nscd</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/sbin/nologin</shell>
<uid>478</uid>
<user_password>!</user_password>
<username>nscd</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>systemd Network Management</fullname>
<gid>480</gid>
<home>/</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/sbin/nologin</shell>
<uid>480</uid>
<user_password>!*</user_password>
<username>systemd-network</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>Daemon</fullname>
<gid>2</gid>
<home>/sbin</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/sbin/nologin</shell>
<uid>2</uid>
<user_password>!</user_password>
<username>daemon</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>systemd Time Synchronization</fullname>
<gid>479</gid>
<home>/</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/sbin/nologin</shell>
<uid>479</uid>
<user_password>!*</user_password>
<username>systemd-timesync</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>user for rpcbind</fullname>
<gid>65534</gid>
<home>/var/lib/empty</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/sbin/nologin</shell>
<uid>475</uid>
<user_password>!</user_password>
<username>rpc</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>SSH daemon</fullname>
<gid>476</gid>
<home>/var/lib/sshd</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/sbin/nologin</shell>
<uid>476</uid>
<user_password>!</user_password>
<username>sshd</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>Postfix Daemon</fullname>
<gid>51</gid>
<home>/var/spool/postfix</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/sbin/nologin</shell>
<uid>51</uid>
<user_password>!</user_password>
<username>postfix</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>NFS statd daemon</fullname>
<gid>65533</gid>
<home>/var/lib/nfs</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/sbin/nologin</shell>
<uid>474</uid>
<user_password>!</user_password>
<username>statd</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>bin</fullname>
<gid>1</gid>
<home>/bin</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/sbin/nologin</shell>
<uid>1</uid>
<user_password>!</user_password>
<username>bin</username>
</user>
<user t="map">
<authorized_keys t="list"/>
<encrypted t="boolean">true</encrypted>
<fullname>root</fullname>
<gid>0</gid>
<home>/root</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/bin/bash</shell>
<uid>0</uid>
<user_password>$6$zAe5W7gw/kja9aKy$mM.BWtNyjalXrDNig4CUfN3bgfmehUIs8.zvBwWn1XroK104G.rY3lyup3OH8TujieUmgO4J74Df.LktV4A1K1</user_password>
<username>root</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>User for D-Bus</fullname>
<gid>499</gid>
<home>/run/dbus</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/bin/false</shell>
<uid>499</uid>
<user_password>!</user_password>
<username>messagebus</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>Manual pages viewer</fullname>
<gid>62</gid>
<home>/var/lib/empty</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/sbin/nologin</shell>
<uid>13</uid>
<user_password>!</user_password>
<username>man</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>Printing daemon</fullname>
<gid>497</gid>
<home>/var/spool/lpd</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/sbin/nologin</shell>
<uid>497</uid>
<user_password>!</user_password>
<username>lp</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>User for polkitd</fullname>
<gid>477</gid>
<home>/var/lib/polkit</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/sbin/nologin</shell>
<uid>477</uid>
<user_password>!</user_password>
<username>polkitd</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>Chrony Daemon</fullname>
<gid>482</gid>
<home>/var/lib/chrony</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/sbin/nologin</shell>
<uid>496</uid>
<user_password>!</user_password>
<username>chrony</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>nobody</fullname>
<gid>65534</gid>
<home>/var/lib/nobody</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/bin/bash</shell>
<uid>65534</uid>
<user_password>!</user_password>
<username>nobody</username>
</user>
<user t="map">
<encrypted t="boolean">true</encrypted>
<fullname>Mailer daemon</fullname>
<gid>498</gid>
<home>/var/spool/clientmqueue</home>
<home_btrfs_subvolume t="boolean">false</home_btrfs_subvolume>
<password_settings t="map">
<expire/>
<flag/>
<inact/>
<max/>
<min/>
<warn/>
</password_settings>
<shell>/usr/sbin/nologin</shell>
<uid>498</uid>
<user_password>!</user_password>
<username>mail</username>
</user>
</users>
</profile>
@@ -15,6 +15,11 @@ EAT_TARGET_SYS:aarch64 ?= "${@ 'aarch64-none-linux-gnu' if os.path.exists('${EXT
EAT_TARGET_SYS = "${TARGET_SYS}"
TARGET_PREFIX = "${EAT_TARGET_SYS}-"
EXTERNAL_TOOLCHAIN_LIBDIR = "${@bb.utils.contains('DISTRO_FEATURES', 'usrmerge', '/usr/lib', '/lib', d)}"
EXTERNAL_TOOLCHAIN_DYN_LINKER_PATH:arm ?= " -Wl,--dynamic-linker=${EXTERNAL_TOOLCHAIN_LIBDIR}/ld-linux-armhf.so.3"
EXTERNAL_TOOLCHAIN_DYN_LINKER_PATH:aarch64 ?= " -Wl,--dynamic-linker=${EXTERNAL_TOOLCHAIN_LIBDIR}/ld-linux-aarch64.so.1"
TARGET_LDFLAGS:append:class-target = "${EXTERNAL_TOOLCHAIN_DYN_LINKER_PATH}"
EAT_LIBDIR:arm = "lib"
EAT_LIBDIR:aarch64 = "lib64"
@@ -0,0 +1 @@
PACKAGECONFIG:remove = "${@bb.utils.contains('TCMODE', 'external-arm', 'libmount-mountfd-support', '' , d)}"
@@ -118,54 +118,80 @@ do_install() {
else
cp ${CP_ARGS} ${EXTERNAL_TOOLCHAIN}/${EAT_TARGET_SYS}/libc/lib/${linker_name} ${D}${base_libdir}/
fi
ln -sf ../../lib/librt.so.1 ${D}${libdir}/librt.so
ln -sf ../../lib/libcrypt.so.1 ${D}${libdir}/libcrypt.so
ln -sf ../../lib/libresolv.so.2 ${D}${libdir}/libresolv.so
ln -sf ../../lib/libnss_hesiod.so.2 ${D}${libdir}/libnss_hesiod.so
ln -sf ../../lib/libutil.so.1 ${D}${libdir}/libutil.so
ln -sf ../../lib/libBrokenLocale.so.1 ${D}${libdir}/libBrokenLocale.so
ln -sf ../../lib/libpthread.so.0 ${D}${libdir}/libpthread.so
ln -sf ../../lib/libthread_db.so.1 ${D}${libdir}/libthread_db.so
ln -sf ../../lib/libanl.so.1 ${D}${libdir}/libanl.so
ln -sf ../../lib/libdl.so.2 ${D}${libdir}/libdl.so
ln -sf ../../lib/libnss_db.so.2 ${D}${libdir}/libnss_db.so
ln -sf ../../lib/libnss_dns.so.2 ${D}${libdir}/libnss_dns.so
ln -sf ../../lib/libnss_files.so.2 ${D}${libdir}/libnss_files.so
ln -sf ../../lib/libnss_compat.so.2 ${D}${libdir}/libnss_compat.so
ln -sf ../../lib/libm.so.6 ${D}${libdir}/libm.so
ln -sf ../../lib/libc_malloc_debug.so.0 ${D}${libdir}/libc_malloc_debug.so
# remove potential .so duplicates from base_libdir
# for all symlinks created above in libdir
rm -f ${D}${base_libdir}/librt.so
rm -f ${D}${base_libdir}/libcrypt.so
rm -f ${D}${base_libdir}/libresolv.so
rm -f ${D}${base_libdir}/libnss_hesiod.so
rm -f ${D}${base_libdir}/libutil.so
rm -f ${D}${base_libdir}/libBrokenLocale.so
rm -f ${D}${base_libdir}/libpthread.so
rm -f ${D}${base_libdir}/libthread_db.so
rm -f ${D}${base_libdir}/libanl.so
rm -f ${D}${base_libdir}/libdl.so
rm -f ${D}${base_libdir}/libnss_db.so
rm -f ${D}${base_libdir}/libnss_dns.so
rm -f ${D}${base_libdir}/libnss_files.so
rm -f ${D}${base_libdir}/libnss_compat.so
rm -f ${D}${base_libdir}/libm.so
# Move these completely to ${libdir} and delete duplicates in ${base_libdir}
for lib in asan hwasan atomic gfortran gomp itm lsan sanitizer stdc++ tsan ubsan; do
if [ -e ${D}${base_libdir}/lib${lib}.spec ] ; then
mv ${D}${base_libdir}/lib${lib}.spec ${D}${libdir}
if ${@bb.utils.contains('DISTRO_FEATURES', 'usrmerge', 'false', 'true', d)}; then
ln -sf ../../lib/librt.so.1 ${D}${libdir}/librt.so
ln -sf ../../lib/libcrypt.so.1 ${D}${libdir}/libcrypt.so
ln -sf ../../lib/libresolv.so.2 ${D}${libdir}/libresolv.so
ln -sf ../../lib/libnss_hesiod.so.2 ${D}${libdir}/libnss_hesiod.so
ln -sf ../../lib/libutil.so.1 ${D}${libdir}/libutil.so
ln -sf ../../lib/libBrokenLocale.so.1 ${D}${libdir}/libBrokenLocale.so
ln -sf ../../lib/libpthread.so.0 ${D}${libdir}/libpthread.so
ln -sf ../../lib/libthread_db.so.1 ${D}${libdir}/libthread_db.so
ln -sf ../../lib/libanl.so.1 ${D}${libdir}/libanl.so
ln -sf ../../lib/libdl.so.2 ${D}${libdir}/libdl.so
ln -sf ../../lib/libnss_db.so.2 ${D}${libdir}/libnss_db.so
ln -sf ../../lib/libnss_dns.so.2 ${D}${libdir}/libnss_dns.so
ln -sf ../../lib/libnss_files.so.2 ${D}${libdir}/libnss_files.so
ln -sf ../../lib/libnss_compat.so.2 ${D}${libdir}/libnss_compat.so
ln -sf ../../lib/libm.so.6 ${D}${libdir}/libm.so
ln -sf ../../lib/libc_malloc_debug.so.0 ${D}${libdir}/libc_malloc_debug.so
if [ -f ${D}${base_libdir}/libmvec.so.1 ]; then
ln -sf ../../lib/libmvec.so.1 ${D}${libdir}/libmvec.so
fi
if [ -e ${D}${base_libdir}/lib${lib}.a ] ; then
mv ${D}${base_libdir}/lib${lib}.a ${D}${libdir}
fi
rm -f ${D}${base_libdir}/lib${lib}*
done
# Clean up duplicate libs that are both in base_libdir and libdir
rm -f ${D}${libdir}/libgcc*
# remove potential .so duplicates from base_libdir
# for all symlinks created above in libdir
rm -f ${D}${base_libdir}/librt.so
rm -f ${D}${base_libdir}/libcrypt.so
rm -f ${D}${base_libdir}/libresolv.so
rm -f ${D}${base_libdir}/libnss_hesiod.so
rm -f ${D}${base_libdir}/libutil.so
rm -f ${D}${base_libdir}/libBrokenLocale.so
rm -f ${D}${base_libdir}/libpthread.so
rm -f ${D}${base_libdir}/libthread_db.so
rm -f ${D}${base_libdir}/libanl.so
rm -f ${D}${base_libdir}/libdl.so
rm -f ${D}${base_libdir}/libnss_db.so
rm -f ${D}${base_libdir}/libnss_dns.so
rm -f ${D}${base_libdir}/libnss_files.so
rm -f ${D}${base_libdir}/libnss_compat.so
rm -f ${D}${base_libdir}/libm.so
rm -f ${D}${base_libdir}/libmvec.so
# Move these completely to ${libdir} and delete duplicates in ${base_libdir}
for lib in asan hwasan atomic gfortran gomp itm lsan sanitizer stdc++ tsan ubsan; do
if [ -e ${D}${base_libdir}/lib${lib}.spec ] ; then
mv ${D}${base_libdir}/lib${lib}.spec ${D}${libdir}
fi
if [ -e ${D}${base_libdir}/lib${lib}.a ] ; then
mv ${D}${base_libdir}/lib${lib}.a ${D}${libdir}
fi
rm -f ${D}${base_libdir}/lib${lib}*
done
# Clean up duplicate libs that are both in base_libdir and libdir
rm -f ${D}${libdir}/libgcc*
else
ln -sf libcrypt.so.1 ${D}${libdir}/libcrypt.so
ln -sf libresolv.so.2 ${D}${libdir}/libresolv.so
ln -sf libnss_hesiod.so.2 ${D}${libdir}/libnss_hesiod.so
ln -sf libutil.so.1 ${D}${libdir}/libutil.so
ln -sf libBrokenLocale.so.1 ${D}${libdir}/libBrokenLocale.so
ln -sf libpthread.so.0 ${D}${libdir}/libpthread.so
ln -sf libthread_db.so.1 ${D}${libdir}/libthread_db.so
ln -sf libanl.so.1 ${D}${libdir}/libanl.so
ln -sf libdl.so.2 ${D}${libdir}/libdl.so
ln -sf libnss_db.so.2 ${D}${libdir}/libnss_db.so
ln -sf libnss_dns.so.2 ${D}${libdir}/libnss_dns.so
ln -sf libnss_files.so.2 ${D}${libdir}/libnss_files.so
ln -sf libnss_compat.so.2 ${D}${libdir}/libnss_compat.so
ln -sf libm.so.6 ${D}${libdir}/libm.so
ln -sf libc_malloc_debug.so.0 ${D}${libdir}/libc_malloc_debug.so
if [ -f ${D}${libdir}/libmvec.so.1 ]; then
ln -sf libmvec.so.1 ${D}${libdir}/libmvec.so
fi
fi
# Besides ld-${EAT_VER_LIBC}.so, other libs can have duplicates like lib*-${EAT_VER_LIBC}.so
# Only remove them if both are regular files and are identical
@@ -205,13 +231,13 @@ do_install() {
rm -rf ${D}${includedir}/rpcsvc/rquota.*
if [ -f ${D}${libdir}/libc.so ];then
sed -i -e "s# /${EAT_LIBDIR}/${EAT_TARGET_SYS}# ../../${EAT_LIBDIR}#g" -e "s# /usr/${EAT_LIBDIR}/# /usr/lib/#g" -e "s# /usr/${EAT_LIBDIR}/${EAT_TARGET_SYS}# .#g" -e "s# /${EAT_LIBDIR}/ld-linux# ../../${EAT_LIBDIR}/ld-linux#g" ${D}${libdir}/libc.so
sed -i -e "s# /usr/${EAT_LIBDIR}/# /usr/lib/#g" -e "s# /${EAT_LIBDIR}/ld-linux# ../../${base_libdir}/ld-linux#g" ${D}${libdir}/libc.so
sed -i -e "s# /${EAT_LIBDIR}/libc.so.6# /lib/libc.so.6#g" ${D}${libdir}/libc.so
sed -i -e "s# /lib# ../../lib#g" -e "s# /usr/lib# .#g" ${D}${libdir}/libc.so
sed -i -e "s# /lib# ../../${base_libdir}#g" -e "s# /usr/lib# .#g" ${D}${libdir}/libc.so
fi
if [ -f ${D}${base_libdir}/libc.so ];then
sed -i -e "s# /${EAT_LIBDIR}/${EAT_TARGET_SYS}# ../../lib#g" -e "s# /usr/${EAT_LIBDIR}/${EAT_TARGET_SYS}# .#g" -e "s# /${EAT_LIBDIR}/# /lib/#g" ${D}${base_libdir}/libc.so
sed -i -e "s# /${EAT_LIBDIR}/# /lib/#g" ${D}${base_libdir}/libc.so
if [ -f ${D}${base_libdir}/libc.so.6 ]; then
sed -i -e "s# /usr/${EAT_LIBDIR}/libc.so.6# /lib/libc.so.6#g" -e "s# /${EAT_LIBDIR}/libc.so.6# /lib/libc.so.6#g" ${D}${base_libdir}/libc.so.6
fi
@@ -527,7 +553,6 @@ FILES:${PN} += "\
${base_libdir}/ld*.so.* \
${base_libdir}/ld-*.so \
${base_libdir}/libpthread*.so.* \
${base_libdir}/libpthread*.so \
${base_libdir}/libpthread-*.so \
${base_libdir}/libresolv*.so.* \
${base_libdir}/libresolv-*.so \
+8 -2
View File
@@ -134,8 +134,14 @@ class FVPRunner:
for console in self._pexpects:
import pexpect
# Ensure pexpect logs all remaining output to the logfile
console.expect(pexpect.EOF, timeout=5.0)
console.close()
try:
console.expect(pexpect.EOF, timeout=30.0)
except pexpect.TIMEOUT:
pexpect_logfile = ""
if console.logfile is not None:
pexpect_logfile = f" ({console.logfile})"
self._logger.debug(f"Unable to get EOF on pexpect spawn obj{pexpect_logfile}.")
console.close(force=True)
if self._fvp_process and self._fvp_process.returncode and \
self._fvp_process.returncode > 0:
+13 -2
View File
@@ -3,6 +3,7 @@ import enum
import pathlib
import pexpect
import os
import time
from oeqa.core.target.ssh import OESSHTarget
from fvp import runner
@@ -127,9 +128,19 @@ class OEFVPTarget(OESSHTarget):
def call_pexpect(terminal, *args, **kwargs):
attr = getattr(self.terminals[terminal], name)
if callable(attr):
return attr(*args, **kwargs)
self.logger.debug(f"Calling {name} on {terminal} : with arguments -> {args} : {kwargs}")
start_time = time.monotonic() # Record the start time
attr = getattr(self.terminals[terminal], name)
result = attr(*args, **kwargs)
end_time = time.monotonic() # Record the end time
elapsed_time = end_time - start_time
self.logger.debug(f"Execution time for result: [ {result} ] - elapsed_time: {elapsed_time} seconds")
else:
return attr
result = attr
return result
return call_pexpect
+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
+15 -2
View File
@@ -1,16 +1,29 @@
from oeqa.runtime.case import OERuntimeTestCase
from oeqa.core.decorator.data import skipIfNotInDataVar
from oeqa.core.decorator.depends import OETestDepends
from time import sleep
class FvpDevicesTest(OERuntimeTestCase):
def run_cmd(self, cmd, check=True):
def run_cmd(self, cmd, check=True, retry=3):
"""
A wrapper around self.target.run, which:
* Fails the test on command failure by default
* Allows the "run" behavior to be overridden in sub-classes
* Has a retry mechanism when SSH returns 255
"""
(status, output) = self.target.run(cmd)
status = 255
# The loop is retrying the self.target.run() which uses SSH only when
# the SSH return code is 255, which might be an issue with
# "Connection refused" because the port isn't open yet
while status == 255 and retry > 0:
(status, output) = self.target.run(cmd)
retry -= 1
# In case the status is 255, delay the next retry to give time to
# the system to settle
if status == 255:
sleep(30)
if status and check:
self.fail("Command '%s' returned non-zero exit "
"status %d:\n%s" % (cmd, status, output))
+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
@@ -0,0 +1,21 @@
SUMMARY = "execstack tool"
LICENSE = "GPL-2.0-or-later"
LIC_FILES_CHKSUM = "file://COPYING;md5=c93c0550bd3173f4504b2cbd8991e50b"
DEPENDS = "binutils-native elfutils-native"
SRC_URI = "git://git.yoctoproject.org/prelink-cross;protocol=https;branch=master"
SRCREV = "ff2561c02ade96c5d4d56ddd4e27ff064840a176"
PV = "1.0+git${SRCPV}"
S = "${WORKDIR}/git"
inherit autotools native
do_compile() {
oe_runmake -C ${B}/src execstack
}
do_install() {
oe_runmake -C ${B}/src install-binPROGRAMS DESTDIR="${D}"
}
@@ -14,3 +14,6 @@ UPSTREAM_VERSION_UNKNOWN = "1"
MODEL_CODE = "FVP_Base_RevC-2xAEMvA"
COMPATIBLE_HOST = "(aarch64|x86_64).*-linux"
require remove-execstack.inc
REMOVE_EXECSTACKS:x86-64 = "${FVPDIR}/models/${FVP_ARCH_DIR}*/libarmctmodel.so"
@@ -0,0 +1,26 @@
# Clear the executable stack flag on named shared libraries. This are typically
# not needed, and glibc 2.41 will refuse to dlopen() a library that expects
# an executable stack.
#
# The stack permissions can be checked with readelf -lW <.so> | grep GNU_STACK.
# RW is read/write, RWE is read/write/execute.
DEPENDS += "execstack-native"
REMOVE_EXECSTACKS ?= ""
do_install:append() {
for SO in ${REMOVE_EXECSTACKS}; do
NAME=$(basename $SO)
SO=${D}$SO
test -f $SO || bbfatal remove-execstack: cannot find $SO
if execstack --query $SO | grep -q ^X; then
bbnote "Stripping executable stack bit on $NAME"
execstack --clear-execstack $SO
else
bbwarn "Executable stack stripping no longer required for $NAME, remove"
fi
done
}
@@ -0,0 +1,51 @@
From fcacaa1f80c601907299b8f9de8b57cc35cd5a68 Mon Sep 17 00:00:00 2001
From: Etienne Carriere <etienne.carriere@st.com>
Date: Wed, 21 Jan 2026 13:55:33 +0100
Subject: [PATCH 1/3] ta: pkcs11: check output buffer size on get attribute
value
Check client output buffer input size and update its output
size on PKCS11_CMD_GET_ATTRIBUTE_VALUE command.
CVE: CVE-2026-33317
Upstream-Status: Backport [https://github.com/OP-TEE/optee_os/commit/e031c4e562023fd9f199e39fd2e85797e4cbdca9]
Fixes: 783c1515c2f9 ("ta: pkcs11: Add support for getting object size and attribute value")
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
---
ta/pkcs11/src/object.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/ta/pkcs11/src/object.c b/ta/pkcs11/src/object.c
index c9a95e1b2..ba3be7a71 100644
--- a/ta/pkcs11/src/object.c
+++ b/ta/pkcs11/src/object.c
@@ -800,6 +800,15 @@ enum pkcs11_rc entry_get_attribute_value(struct pkcs11_client *client,
goto out;
}
+ /*
+ * We will update the template with relevant data, without resizing it.
+ * Upon completion, it will be copied to client output buffer.
+ */
+ if (out->memref.size < sizeof(*template) + template->attrs_size) {
+ rc = PKCS11_CKR_ARGUMENTS_BAD;
+ goto out;
+ }
+
/* Iterate over attributes and set their values */
/*
* 1. If the specified attribute (i.e., the attribute specified by the
@@ -912,6 +921,7 @@ enum pkcs11_rc entry_get_attribute_value(struct pkcs11_client *client,
rc = PKCS11_CKR_BUFFER_TOO_SMALL;
/* Move updated template to out buffer */
+ out->memref.size = sizeof(*template) + template->attrs_size;
TEE_MemMove(out->memref.buffer, template, out->memref.size);
DMSG("PKCS11 session %"PRIu32": get attributes %#"PRIx32,
--
2.43.0
@@ -0,0 +1,52 @@
From 7e57efa90820489f123708f8ae5ee13706e8f4ce Mon Sep 17 00:00:00 2001
From: Etienne Carriere <etienne.carriere@st.com>
Date: Wed, 21 Jan 2026 13:58:09 +0100
Subject: [PATCH 2/3] ta: pkcs11: check template consistency on get attribute
value
Check client template holds consistent attribute area sizes
value on PKCS11_CMD_GET_ATTRIBUTE_SIZE.
CVE: CVE-2026-33317
Upstream-Status: Backport [https://github.com/OP-TEE/optee_os/commit/16926d5a46934c46e6656246b4fc18385a246900]
Fixes: 783c1515c2f9 ("ta: pkcs11: Add support for getting object size and attribute value")
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
---
ta/pkcs11/src/object.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/ta/pkcs11/src/object.c b/ta/pkcs11/src/object.c
index ba3be7a71..470eeb247 100644
--- a/ta/pkcs11/src/object.c
+++ b/ta/pkcs11/src/object.c
@@ -840,12 +840,23 @@ enum pkcs11_rc entry_get_attribute_value(struct pkcs11_client *client,
for (; cur < end; cur += len) {
struct pkcs11_attribute_head *cli_ref = (void *)cur;
struct pkcs11_attribute_head cli_head = { };
+ uintptr_t cli_end = 0;
void *data_ptr = NULL;
+ if ((char *)(cli_ref + 1) > end) {
+ rc = PKCS11_CKR_ARGUMENTS_BAD;
+ goto out;
+ }
+
/* Make copy of header so that is aligned properly. */
TEE_MemMove(&cli_head, cli_ref, sizeof(cli_head));
- len = sizeof(*cli_ref) + cli_head.size;
+ if (ADD_OVERFLOW(sizeof(*cli_ref), cli_head.size, &len) ||
+ ADD_OVERFLOW((uintptr_t)cur, len, &cli_end) ||
+ (char *)cli_end > end) {
+ rc = PKCS11_CKR_ARGUMENTS_BAD;
+ goto out;
+ }
/* Treat hidden attributes as missing attributes */
if (attribute_is_hidden(&cli_head)) {
--
2.43.0
@@ -0,0 +1,46 @@
From 75c1a999d6b51520234276b207ceefbd5e18ed02 Mon Sep 17 00:00:00 2001
From: Etienne Carriere <etienne.carriere@st.com>
Date: Wed, 21 Jan 2026 14:03:26 +0100
Subject: [PATCH 3/3] ta: pkcs11: fix attribute output size if too small on get
attribute value
Correct the size field output value for attributes fetched with
PKCS11_CMD_GET_ATTRIBUTE_VALUE where a too short buffer was provided.
As per the PKCS#11 specification, in such case, the related attributes
size field should be filled with CK_UNAVAILABLE_INFORMATION and the
function to return an non-true-error code like CKR_BUFFER_TOO_SMALL.
The implementation complied for the return value but was loading the
required attribute data value size instead in CK_UNAVAILABLE_INFORMATION
in the attribute size field.
CVE: CVE-2026-33317
Upstream-Status: Backport [https://github.com/OP-TEE/optee_os/commit/149e8d7ecc4ef8bb00ab4a37fd2ccede6d79e1ca]
Fixes: 783c1515c2f9 ("ta: pkcs11: Add support for getting object size and attribute value")
Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
---
ta/pkcs11/src/object.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/ta/pkcs11/src/object.c b/ta/pkcs11/src/object.c
index 470eeb247..ed2ce2a95 100644
--- a/ta/pkcs11/src/object.c
+++ b/ta/pkcs11/src/object.c
@@ -900,8 +900,11 @@ enum pkcs11_rc entry_get_attribute_value(struct pkcs11_client *client,
attr_type_invalid = 1;
break;
case PKCS11_CKR_BUFFER_TOO_SMALL:
- if (data_ptr)
+ if (data_ptr) {
+ cli_head.size =
+ PKCS11_CK_UNAVAILABLE_INFORMATION;
buffer_too_small = 1;
+ }
break;
default:
rc = PKCS11_CKR_GENERAL_ERROR;
--
2.43.0
@@ -0,0 +1,40 @@
From 2fdf0aa10bd23c0e4633efa087a27ff07f79015f Mon Sep 17 00:00:00 2001
From: Jens Wiklander <jens.wiklander@linaro.org>
Date: Thu, 22 Jan 2026 14:19:36 +0100
Subject: [PATCH] core: crypto_api: fix underflow in emsa_pkcs1_v1_5_encode()
Guard against an integer underflow in emsa_pkcs1_v1_5_encode() that can
occur when calculating the padding field in the EMA-PKCS1-v1_5 encoding.
CVE: CVE-2026-33662
Upstream-Status: Backport [https://github.com/OP-TEE/optee_os/commit/caeaa2ae551666068894005387cca4113b10873f]
Fixes: f5a70e3efb80 ("drivers: crypto: generic resources for crypto device driver - RSA")
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Jerome Forissier <jerome.forissier@arm.com>
Signed-off-by: Hugo SIMELIERE (Schneider Electric) <hsimeliere.opensource@witekio.com>
---
core/drivers/crypto/crypto_api/acipher/rsassa.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/core/drivers/crypto/crypto_api/acipher/rsassa.c b/core/drivers/crypto/crypto_api/acipher/rsassa.c
index 0f71b84cc..01f8d7dc9 100644
--- a/core/drivers/crypto/crypto_api/acipher/rsassa.c
+++ b/core/drivers/crypto/crypto_api/acipher/rsassa.c
@@ -45,9 +45,10 @@ static TEE_Result emsa_pkcs1_v1_5_encode(struct drvcrypt_rsa_ssa *ssa_data,
* Calculate the PS size
* EM Size (modulus size) - 3 bytes - DigestInfo DER format size
*/
- ps_size = ssa_data->key.n_size - 3;
- ps_size -= ssa_data->digest_size;
- ps_size -= 10 + hash_oid->asn1_length;
+ if (SUB_OVERFLOW(ssa_data->key.n_size, 3, &ps_size) ||
+ SUB_OVERFLOW(ps_size, ssa_data->digest_size, &ps_size) ||
+ SUB_OVERFLOW(ps_size, 10 + hash_oid->asn1_length, &ps_size))
+ return TEE_ERROR_BAD_PARAMETERS;
CRYPTO_TRACE("PS size = %zu (n %zu)", ps_size, ssa_data->key.n_size);
--
2.43.0
@@ -7,4 +7,8 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
SRCREV = "18b424c23aa5a798dfe2e4d20b4bde3919dc4e99"
SRC_URI += " \
file://0003-optee-enable-clang-support.patch \
file://CVE-2026-33317-1.patch \
file://CVE-2026-33317-2.patch \
file://CVE-2026-33317-3.patch \
file://CVE-2026-33662.patch \
"