From patchwork Wed May 6 19:12:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilias Apalodimas X-Patchwork-Id: 245214 List-Id: U-Boot discussion From: ilias.apalodimas at linaro.org (Ilias Apalodimas) Date: Wed, 6 May 2020 22:12:40 +0300 Subject: [PATCH 0/6] EFI variable support via OP-TEE Message-ID: <20200506191246.237790-1-ilias.apalodimas@linaro.org> With new OP-TEE and EDK2 patches (not yet upstreamed [1][2]) we can run a secure world application which manages UEFI variables. Leveraging the U-Boot's OP-TEE supplicant we can then store those values in an RPMB device. The Secure World application responsible for doing that is coming from EDK2 (StandAloneMM). The StandAloneMM application is compiled from EDK2 and then appended in the OP-TEE binary which executes that in Secure World. There are various advantages in using StandAloneMM directly. Apart from the obvious ones, such as running the whole code in Secure World, we are using the EDK2 Fault Tolerant Write protocol to protect the variables against corruption. We also avoid adding complicated code to U-Boot for the variable management. The only code U-Boot needs is a set OP-TEE APIs to access the new application. >From a user's perspective this changes nothing to the usual way UEFI variables are treated. The user will still use 'setenv/printenv -e' to perform the variable operations. An 'efidebug query' command is added to retrieve information about the container used to store UEFI variables. Since patches for the rest of the projects are not yet upstreamed I've tried to provide a QEMU emulation for anyone interested in testing the patchset. 1. Download precompiled TF-A, OP-TEE binaries and a DTB from https://people.linaro.org/~ilias.apalodimas/secure_boot/ bl33.bin is a precompiled U-Boot binary. If you use that skip (2) 2. git clone --single-branch --branch rpmb_hack \ https://git.linaro.org/people/ilias.apalodimas/u-boot.git I've included a defconfig to make your life easier export CROSS_COMPILE=aarch64-linux-gnu- export ARCH=arm64 make qemu_tfa_mm_defconfig && make -j4 Safely ignore the warnings, they are a result of the RPMB emulation monstrosity ... The branch contains an extra patch which adds RPMB emulation into OP-TEE supplicant but breaks proper RPMB hardware. The patch is a gross hack (but can be upstreamed later for Gitlab testing if needed). Since QEMU has no RPMB emulation providing one through the OP-TEE supplicant was the easiest way to test the patchset. 3. Create PK, KEK etc - PK: openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_PK/ -keyout \ PK.key -out PK.crt -nodes -days 365 cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc PK.crt \ PK.esl; sign-efi-sig-list -c PK.crt -k PK.key PK PK.esl PK.auth - KEK: openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_KEK/ -keyout \ KEK.key -out KEK.crt -nodes -days 365 cert-to-efi-sig-list -g 11111111-2222-3333-4444-123456789abc KEK.crt \ KEK.esl; sign-efi-sig-list -c PK.crt -k PK.key KEK KEK.esl KEK.auth - put them in a file and create an image mkdir tmp && cp PK.auth KEK.auth tmp/ virt-make-fs -s 1M -t ext4 tmp certs.img 4. Launch QEMU (note tested on QEMU 3.1 and 5.0) qemu-system-aarch64 -m 1024 -smp 2 -show-cursor -serial stdio \ -monitor null -nographic \ -cpu cortex-a57 -bios bl1.bin -machine virt,secure=on -d unimp \ -semihosting-config enable,target=native -dtb ledge-qemuarm64.dtb \ -drive if=none,file=certs.img,id=mydisk \ -device nvme,drive=mydisk,serial=foo You can now load and test the certificates nvme scan load nvme 0 0x70000000 PK.auth setenv -e -nv -bs -rt -at -i 0x70000000,$filesize PK; load nvme 0 0x70000000 KEK.auth setenv -e -nv -bs -rt -at -i 0x70000000,$filesize KEK; efidebug query printenv -e -all This has been tested against U-Boot efi_sefltest but since StandAloneMM will write a non-existent variable if APPEND_WRITE is specified, this test will fail. It has also been tested for the runtime variable support (or rather absence of it) with FWTS (https://wiki.ubuntu.com/FirmwareTestSuite). This patchset adds the needed APIs between U-Boot and OP-TEE and StandAloneMM to perform the variable storage. [1] https://github.com/apalos/optee_os/tree/stmm_upstream_03_clean [2] https://git.linaro.org/people/ilias.apalodimas/edk2-platforms.git/log/?h=patch_pcd Ilias Apalodimas (4): efi_loader: Implement EFI variable handling via OP-TEE cmd: efidebug: Add support for querying UEFI variable storage MAINTAINERS: Add maintainer for EFI variables via OP-TEE doc: uefi.rst: Add OP-TEE variable storage config options Sughosh Ganu (2): charset: Add support for calculating bytes occupied by a u16 string efi_loader: Add headers for EDK2 StandAloneMM communication MAINTAINERS | 7 + cmd/efidebug.c | 45 ++- doc/uefi/uefi.rst | 10 + include/charset.h | 11 + include/mm_communication.h | 28 ++ include/mm_variable.h | 78 ++++ lib/charset.c | 5 + lib/efi_loader/Kconfig | 9 + lib/efi_loader/Makefile | 4 + lib/efi_loader/efi_variable_tee.c | 645 ++++++++++++++++++++++++++++++ 10 files changed, 841 insertions(+), 1 deletion(-) create mode 100644 include/mm_communication.h create mode 100644 include/mm_variable.h create mode 100644 lib/efi_loader/efi_variable_tee.c