Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] MbedTLS integration (MbedTLS as a git submodule) #4

Draft
wants to merge 23 commits into
base: master
Choose a base branch
from

Conversation

raymo200915
Copy link
Owner

@raymo200915 raymo200915 commented Jan 16, 2024

This is the initial PR to integrate MbedTLS into U-Boot.

What are changed with this patch set:

  1. MbedTLS LTS v3.6 (v3.6.0RC1) is introduced into U-Boot as a git submodule. Init and update git submodule are done by makefile automatically when make.
  2. A kbuild makefile and Kconfig are added (CONFIG_MBEDTLS_LIB as a main switch for enabling MbedTLS, CONFIG_MBEDTLS_LIB_CRYPTO, CONFIG_MBEDTLS_LIB_X509 and CONFIG_MBEDTLS_LIB_TLS for enabling the subset libraries Crypto, X509 and TLS respectively).
  3. Allow MBedTLS patches to be applied by makfile automatically.
  4. A hash shim layer is created on top of MbedTLS Crypto library to port the digest functions from common/hash, which is used by boot/image and efi_loader, etc, when CONFIG_MBEDTLS_LIB_CRYPTO is enabled.
  5. Fixed the arm linker script to solve potential gaps in the section table that may result in different checksums that cause a failure when calling function efi_image_verify_digest() .
  6. The traditional hash libraries (lib/md5, lib/shaX) are still in the build system when CONFIG_MBEDTLS_LIB_CRYPTO is enabled, since they are widely being used by arch/platform/driver codes at the moment, but idealy all of them should be replaced eventually when CONFIG_MBEDTLS_LIB_CRYPTO is enabled.
  7. Patched MbedTLS to support parsing MicroSoft Authenticate Code and PKCS9 Authenticate Attributes if they exist in a PKCS7 message. These are required by EFI Secure Boot when verifying a signed PE image.
  8. Patched MbedTLS to support multiple signer's certs in the signed data within a PKCS7 message.
  9. Ported lib/crypto components (public_key, x509, PKCS7, mscode) on top of MbedTLS and removed the dependence on original ASN1 and RSA libraries when CONFIG_MBEDTLS_LIB_X509 is enabled (lib/crypto/rsa_helper, lib/rsa and lib/asn1_decoder are still being built for modules other than the EFI loader).
  10. The initial build with MbedTLS increased size by 18%, after optimize the MbeTLS config by disabling the unused features, it drops to 6%. The duplicated original crypto libraries (lib/rsa, lib/asn1_decoder, lib/rsa_helper, lib/md5, lib/sha1, lib/sha256, lib/sha512) are totally about 3%. So ideally it will only takes 3% if the duplicated crypto libraries are all cut off and replaced by MbedTLS.

Below MbedTLS configs are added into qemu_arm64_defconfig

[...]
CONFIG_MBEDTLS_LIB=y
CONFIG_MBEDTLS_LIB_CRYPTO=y
CONFIG_MBEDTLS_LIB_X509=y
# CONFIG_MBEDTLS_LIB_TLS is not set
[...]
CONFIG_EFI_SECURE_BOOT=y

To build:

make CROSS_COMPILE=aarch64-none-linux-gnu- O=out qemu_arm64_defconfig
make CROSS_COMPILE=aarch64-none-linux-gnu- O=out all

Tested through below steps for EFI Secure Boot:

  1. Generate UEFI certs (PK/KEK/db/dbx)
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 -t "2020-04-01" -c PK.crt -k PK.key PK PK.esl PK.auth
touch noPK.esl; sign-efi-sig-list -t "2020-04-02" -c PK.crt -k PK.key PK noPK.esl noPK.auth
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 -t "2020-04-03" -c PK.crt -k PK.key KEK KEK.esl KEK.auth
openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_db/ -keyout db.key -out db.crt -nodes -days 365
cert-to-efi-sig-list -g '11111111-2222-3333-4444-123456789abc' db.crt db.esl; sign-efi-sig-list -t "2020-04-04" -c KEK.crt -k KEK.key db db.esl db.auth
openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=TEST_dbx/ -keyout dbx.key -out dbx.crt -nodes -days 365
cert-to-efi-sig-list -g '11111111-2222-3333-4444-123456789abc' dbx.crt dbx.esl; sign-efi-sig-list -t "2020-04-05" -c KEK.crt -k KEK.key dbx dbx.esl dbx.auth
  1. Sign a test EFI image (helloworld.efi)
    sbsign --key db.key --cert db.crt --output helloworld-signed.efi helloworld.efi
    Verify the signature:
    sbverify --cert db.crt helloworld-signed.efi

  2. Create a GPT image (test_efi_secboot.img) that contains the signed test EFI image (helloworld-signed.efi) and the UEFI certs
    sudo virt-make-fs --partition=gpt --size=+1M --type=vfat <DIR_OF_CERTS_AND_EFI_IMAGE> test_efi_secboot.img

  3. Launch QEMU with the GPT image (test_efi_secboot.img) mounted as a virtio device
    qemu-system-aarch64 -bios u-boot.bin -machine virt -cpu cortex-a57 -smp 1 -m 4G -d unimp -nographic -serial mon:stdio -semihosting -drive if=none,file=test_efi_secboot.img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0

  4. Load PK from virtio device
    load virtio 0:1 90000000 PK.auth && setenv -e -nv -bs -rt -at -i 90000000:$filesize PK

  5. Load KEK/db/dbx from virtio device respectively and each of them should be verified successfully.

load virtio 0:1 90000000 KEK.auth && setenv -e -nv -bs -rt -at -i 90000000:$filesize KEK
load virtio 0:1 90000000 db.auth && setenv -e -nv -bs -rt -at -i 90000000:$filesize db
load virtio 0:1 90000000 dbx.auth && setenv -e -nv -bs -rt -at -i 90000000:$filesize dbx
  1. Load the signed test EFI image (helloworld-signed.efi) into memory and boot it.
load virtio 0:1 ${loadaddr} helloworld-signed.efi
bootefi ${loadaddr} ${fdt_addr}

The signed EFI image should be verified and boot successfully.

  1. Negative testing with tempered KEK and tempered signed test EFI image (tempered by manually altering the last few bytes). Both tempered files failed in verification and were rejected as expectation.

Also tested through EFI Secure Boot sandbox test by:

`./test/py/test.py --bd sandbox --build -k efi_secboot`

@raymo200915 raymo200915 force-pushed the mbedtls_integration branch 2 times, most recently from ed544cf to 2a264df Compare January 18, 2024 18:09
@raymo200915
Copy link
Owner Author

raymo200915 commented Jan 18, 2024

Milestone 1:
MbedTLS is introduced into U-Boot as a git submodule.
Build MbedTLS objects when CONFIG_MBEDTLS_LIB is enabled.
Hash functions in below modules are replaced with MbedTLS crypto library when CONFIG_MBEDTLS_LIB_CRYPTO is enabled.
common/hash
boot/image
lib/crypto
lib/efi_loade
tools/image-sig-host

Add mbedtls as a submodule.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
@raymo200915 raymo200915 force-pushed the mbedtls_integration branch 2 times, most recently from 25b0a46 to 7590093 Compare March 5, 2024 21:20
@raymo200915
Copy link
Owner Author

raymo200915 commented Mar 5, 2024

EFI Secure Boot requires the MicroSoft Authenticate Code and Authenticate Attributes for verifying a signed PE image, while MbedTLS does not support these attributes naturally.
Adding a patch to MbedTLS to enable the populating of MicroSoft Authenticate Code and Authenticate Attributes from a PKCS7 message if they exist, and store them into the decoding context.

@raymo200915 raymo200915 marked this pull request as draft March 6, 2024 00:24
@raymo200915
Copy link
Owner Author

raymo200915 commented Mar 6, 2024

Milestone 2:
Ported public_key, x509. pkcs7 and mscode on top of MbedTLS and removed the original ASN1 decoder.
Teseted via EFI Secure boot when CONFIG_MBEDTLS_LIB_X509 is enabled.

@raymo200915 raymo200915 force-pushed the mbedtls_integration branch 2 times, most recently from 7efa4ac to 4d9a05d Compare March 12, 2024 14:16
@raymo200915
Copy link
Owner Author

Optimized target size by disabling unused features in MbedTLS config.

@raymo200915
Copy link
Owner Author

raymo200915 commented Mar 22, 2024

Fixed Makefile minor issue.
Added MbedTLS patch to support multiple signer's cert in the signed data within a PKCS7 message.
Fixed auth_id (AuthorityKeyIdentifier) decoding issue which causes failure during verifying the signature chain in pkcs7_verify_sig_chain().
Sandbox UT efi_secboot test intca1/2/3 are all passed with these changes.

@raymo200915 raymo200915 changed the title [RFC] MbedTLS integration [RFC] MbedTLS integration (MbedTLS as a git submodule) Mar 22, 2024
@raymo200915
Copy link
Owner Author

Fixed MbedTLS PKCS7 test suites failures: We are only supporting the Context Data format that is expected by EFI Loader. Other than that (e.g. "Inlined Content Info" that represented by OCTETSTRING) are treated as MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE.

Updated MbedTLS test suites to support PKCS7 with multiple certs.

Take mbedtls LTS release from tag v3.6.0

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Retrieve all git submodules before building

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Port mbedtls with dummy libc header files.
Add mbedtls default config header file.
Add mbedtls kbuild makefile.
Add Kconfig and mbedtls config submenu.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Apply MbedTLS patch if any exist before building.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Add text section alignment to fix sbsign signing warning
'gaps in the section table may result in different checksums'
which causes a failure of efi_image_verify_diges()

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Fix a permission issue when running virt-make-fs

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Remove the redundant includes of u-boot/md5.h, u-boot/sha1.h,
u-boot/sha256.h and u-boot/sha512.h

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Remove the redundant includes of u-boot/sha1.h, u-boot/sha256.h
and u-boot/sha512.h

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Create a hash shim layer on top of mbedtls crypto library.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Integrate common/hash.c on the hash shim layer so that hash APIs
from mbedtls can be leveraged by boot/image and efi_loader.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Add the mbedtls include directories into the build system.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
When MBEDTLS_LIB_CRYPTO is enabled, use the APIs of sha256 from
hash shim layer instead.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
When MBEDTLS_LIB_CRYPTO is enabled, use the APIs of sha256 from
hash shim layer instead.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Added patches for MBedTLS PKCS7 parser to support MicroSoft
Authenticate Code with Authenticate Attributes.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Add mbedtls patch to support multiple signer's certs in the signed
data within a PKCS7 message.
Update the related MbedTLS test suites.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Integrate function public_key_verify_signature on top of MbedTLS
pk library.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Integrate x509_cert_parser on top of MbedTLS x509 library.
Add API x509_populate_cert and x509_populate_pubkey for code
reusability between x509 and pkcs7 parsers.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Integrate PKCS7 parser on top of MbedTLS PKCS7 library.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Integrate MicroSoft Authenticate Code parser on top of MbedTLS
ASN.1 decoder.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
When building with MbedTLS,  we are using MbedTLS to decode ASN1 data
for x509, pkcs7 and mscode. So we can remove the dependence on ASN1
decoder when MBEDTLS_LIB_X509 is enabled.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Disable the unused features of MbedTLS to reduce the target size.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
Enable MbedTLS as default setting for qemu arm64

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
@raymo200915
Copy link
Owner Author

Rebased all patches on top of MbedTLS v3.6.0 LTS.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant