From 848aae191d964f1c7b9f5131a8107a90df913237 Mon Sep 17 00:00:00 2001 From: Sandrine Bailleux Date: Thu, 31 Oct 2019 09:08:20 +0100 Subject: [PATCH] PoC: Detach BL33 image from the main chain of trust This is a proof-of-concept patch showing how the existing TBBR CoT may be modified in order to detach the BL33 image from it. BL33 is now part of its own independent CoT derived from a new key called NS-ROTPK. A script is provided to build the code and run it on the Base AEM FVP, launch it as follows: BL33= \ MBEDTLS_DIR= \ bash ./test.sh The FVP is expected to be in the PATH. Change-Id: I0936d010db631000f2a47d67ff00ba45712876c9 Signed-off-by: Sandrine Bailleux --- drivers/auth/tbbr/tbbr_cot.c | 8 +- include/tools_share/tbbr_oid.h | 3 + plat/arm/board/common/board_arm_trusted_boot.c | 41 ++++++++++ plat/arm/board/common/ns-rotpk/ns-rot-priv.pem | 28 +++++++ test.sh | 103 +++++++++++++++++++++++++ tools/cert_create/include/tbbr/tbb_ext.h | 3 +- tools/cert_create/include/tbbr/tbb_key.h | 3 +- tools/cert_create/src/tbbr/tbb_cert.c | 7 +- tools/cert_create/src/tbbr/tbb_ext.c | 10 ++- tools/cert_create/src/tbbr/tbb_key.c | 8 +- 10 files changed, 205 insertions(+), 9 deletions(-) create mode 100644 plat/arm/board/common/ns-rotpk/ns-rot-priv.pem create mode 100644 test.sh diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c index 6dd4ae2..f286366 100644 --- a/drivers/auth/tbbr/tbbr_cot.c +++ b/drivers/auth/tbbr/tbbr_cot.c @@ -603,15 +603,19 @@ static const auth_img_desc_t tos_fw_config = { /* * Non-Trusted Firmware */ +static auth_param_type_desc_t ns_rot_pk = AUTH_PARAM_TYPE_DESC( + AUTH_PARAM_PUB_KEY, NS_ROT_KEY_OID); + static const auth_img_desc_t non_trusted_fw_key_cert = { .img_id = NON_TRUSTED_FW_KEY_CERT_ID, .img_type = IMG_CERT, - .parent = &trusted_key_cert, + .parent = NULL, /* Root certificate. */ .img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) { [0] = { + /* Expected to be signed with the NS-ROTPK. */ .type = AUTH_METHOD_SIG, .param.sig = { - .pk = &non_trusted_world_pk, + .pk = &ns_rot_pk, .sig = &sig, .alg = &sig_alg, .data = &raw_data diff --git a/include/tools_share/tbbr_oid.h b/include/tools_share/tbbr_oid.h index 6bccfdd..2a087c9 100644 --- a/include/tools_share/tbbr_oid.h +++ b/include/tools_share/tbbr_oid.h @@ -135,6 +135,9 @@ /* NonTrustedFirmwareContentCertPK */ #define NON_TRUSTED_FW_CONTENT_CERT_PK_OID "1.3.6.1.4.1.4128.2100.1101" +/* Pick the next available OID. Arbitrary value, not defined by TBBR spec. */ +#define NS_ROT_KEY_OID "1.3.6.1.4.1.4128.2100.1102" + /* * Non-Trusted Firmware Content Certificate diff --git a/plat/arm/board/common/board_arm_trusted_boot.c b/plat/arm/board/common/board_arm_trusted_boot.c index c71e932..fd6545b 100644 --- a/plat/arm/board/common/board_arm_trusted_boot.c +++ b/plat/arm/board/common/board_arm_trusted_boot.c @@ -73,6 +73,47 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, assert(key_len != NULL); assert(flags != NULL); + /* + * Return the right root of trust key hash based on the cookie value: + * - NULL means S-ROTPK (as always). + * - Otherwise, interpret cookie as the OID of the certificate + * extension containing the key. + */ + if ((cookie != NULL) && + (strcmp(cookie, NS_ROT_KEY_OID) == 0)) { + VERBOSE("%s: Getting key hash for BL33 certificate.\n", + __func__); + + /* + * SHA-256 hash of the NS-ROT public key. + * + * Was generated on the host machine by hashing the RSA public + * key in DER format: + * openssl rsa \ + * -in plat/arm/board/common/ns-rotpk/ns-rot-priv.pem \ + * -pubout -outform DER | \ + * openssl dgst -sha256 -binary | \ + * hexdump -e '"\x"/1 "%02X "' + * + * Then do a bit of formatting to get the hexadecimal string and + * embed it in the code here. + */ + static unsigned char ns_rotpk_hash[] = \ + /* DER header. */ \ + "\x30\x31\x30\x0D\x06\x09\x60\x86\x48" \ + "\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20" \ + /* Key hash. */ \ + "\xBF\x7C\x46\xF6\xCA\xCE\x99\x18" \ + "\xA0\xA6\x74\x22\x42\x7B\xB5\x53" \ + "\xA7\x29\x6E\x79\x3D\x3B\x9B\xBE" \ + "\x0F\x01\xD0\x5B\xD8\xDE\x1E\xB9"; + + *key_ptr = ns_rotpk_hash; + *key_len = sizeof(ns_rotpk_hash); + *flags = ROTPK_IS_HASH; + return 0; + } + /* Copy the DER header */ memcpy(rotpk_hash_der, rotpk_hash_hdr, rotpk_hash_hdr_len); dst = (uint8_t *)&rotpk_hash_der[rotpk_hash_hdr_len]; diff --git a/plat/arm/board/common/ns-rotpk/ns-rot-priv.pem b/plat/arm/board/common/ns-rotpk/ns-rot-priv.pem new file mode 100644 index 0000000..c13c667 --- /dev/null +++ b/plat/arm/board/common/ns-rotpk/ns-rot-priv.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDG/zQ8yNsGEO0b +W+PuEYI5xEpOZWR4zZ4dxUglLDp1rhT2eTcZkr8grEZjsO9/IOGak9+ajWFvOlHR +pdmQde/07SFLM0FoCK0P1/vJc9otrAXX2xmu13wLZj1Sj+fJWllcqqMYX4BVduly +QaXhHhBEjAxHPQFpctSbgnKMVtZgkSURV7JoxOmbZLrwrhlscpuyAQshSHPP6Nyy +0aAqDLFlBx0lhlDpZvqPACJ4BPuDK0rYN5w1b5u3RyQJKglLxT6uWH4WhVi37tL2 +NUnRZ00F8mZmKCWGeVGOTdNql3Qh9TB/efTmmrfnTskJH+RVkCVCjfqCgHaCPy1U +iLGAQ8pZAgMBAAECggEACu5Z4DzoSx0C6U3S53Duxl2R91x6eGhTFy+PFvum+m/l +luRxsmXtOc48z50YitMzkVouHj9F6uY5OFrz6IuR8tJT0d2u6hgP6Z7jpd1HTtr0 +NzdB4ejUV4v2MmLVSKo93mlBLEWStx8hE7WndwY/voQy6HbhbPlx1FkGEc9zVzqJ +D24EuDJofTQ62hPtU5wOMQ/KW+DZ2SjieXVTEWGzJIZ4pqmFo+2EN6v0RPZrxfe+ +Sq3ofC2/IkHTTUFoINbu/H6F5GttE2aQKYQ6IV9ypx+cWD/JqtZfO98HycuuXq6n +w3N3J7HmUAvumf6K+r1IezU2AXWZrsGqjU0hYQ5mQQKBgQDpH3scquCnYABeb1u/ +i7iUzI4ri9E/BdoMCAAPTS021NLSVMlz9+t5Ij3GR4UIHxP+bAA9h5RD0cACLZG0 +m0Nc+axFMsYzcm0xK1A29kuaRxPGk7v8gKsxUYj7zlkYunPzWeGa2EN5WibArVpO +mYyu5fx0ZRgcnIJR4+HToaAm8wKBgQDahmg8jZkd2cbGcFeDcI6pzbLqIcDBKW/W +MIWU7+BLeMPaYRS8IQtsk250BIEJQ/uwX/iRKW5zM/dggDzs/fFlcbiRbVLzSu++ +OzkCh16KdMDLoukt9LxX1Dd/X7HUaNqqOUbQuqOd/H+81/4evtbcKGUQcw2spTcT +Q7twxZ+0gwKBgQDo7zfIcUWAeIBl28dFIYsRw0LbaB1wZ5x0IRpOL8NZ4lW1LFsO +sU5r/zbShGv8rXEA61FiKbKQAWllw7qvR+SLZj4n9o/soA1S8AB6qqboRNURulQ/ +/SERanMBiDGmb8ekBM9UNXtWKipGo/B0USEtMUiL1Oe+zvO4d4cSO5EW2QKBgQC1 +pLvIebspAPklwgQ8kbdElmN+Ewhyh8sas8KWBr7efUfvonrl1mH0oqhRb90Coqv3 +9A5eO54/zJZ4dKAwLvYVaO4OlF07NrMJ4ZiF7Zg8ZshLfONu+9wC9bgb/KOI+I+q +p2mh30JZ9KUJiFEHpYJcBofboIdhVwPs04RfPSZ/mQKBgQDDysx51wAb2qt28OGM +Wq5NLydX6Zk1WFgGn7AGMthcGHmc2Q9GRhCj5uv/AzpU+0umstQH3+XEat1QL2oq +GQZbFP83LVbeNJxSOUHUsTdvV8ncK8d9uAeTmz/NYnhlJ2SHJy2BR0DHdoa2l+Lq +7Dgn16hGrMGigC55knETj+xqDQ== +-----END PRIVATE KEY----- diff --git a/test.sh b/test.sh new file mode 100644 index 0000000..d203a5f --- /dev/null +++ b/test.sh @@ -0,0 +1,103 @@ +#! /bin/bash +# +# Copyright (c) 2019, Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +set -x +set -e + +rot_key_file=plat/arm/board/common/rotpk/arm_rotprivk_rsa.pem + +# Was generated using: +# openssl genpkey -algorithm rsa -pkeyopt rsa_keygen_bits:2048 > ns-rot-priv.pem +nsrot_key_file=plat/arm/board/common/ns-rotpk/ns-rot-priv.pem + + +# Build firmware images and configuration files. +export MBEDTLS_DIR=${MBEDTLS_DIR:?} + +make -j \ +PLAT=fvp DEBUG=1 \ +TRUSTED_BOARD_BOOT=1 \ +GENERATE_COT=1 \ +ARM_ROTPK_LOCATION=devel_rsa \ +ROT_KEY=${rot_key_file} \ +E=0 LOG_LEVEL=50 \ +all + + +# Build tools. +make fiptool certtool + + +# Create certificates. +BL33=${BL33:?} + +plat_build_dir=build/fvp/debug + +tools/cert_create/cert_create \ +--tb-fw-config ${plat_build_dir}/fdts/fvp_tb_fw_config.dtb \ +--soc-fw-config ${plat_build_dir}/fdts/fvp_soc_fw_config.dtb \ +--nt-fw-config ${plat_build_dir}/fdts/fvp_nt_fw_config.dtb \ +--hw-config ${plat_build_dir}/fdts/fvp-base-gicv3-psci.dtb \ + \ +--tfw-nvctr 31 \ +--ntfw-nvctr 223 \ + \ +--key-alg rsa \ +--key-size 2048 \ +--rot-key ${rot_key_file} \ +--trusted-world-key ${rot_key_file} \ +--non-trusted-world-key ${rot_key_file} \ +--soc-fw-key ${rot_key_file} \ +--nt-fw-key ${rot_key_file} \ +--tos-fw-key ${rot_key_file} \ +--scp-fw-key ${rot_key_file} \ +--ns-rot-key ${nsrot_key_file} \ + \ +--tb-fw ${plat_build_dir}/bl2.bin \ +--soc-fw ${plat_build_dir}/bl31.bin \ +--nt-fw ${BL33} \ + \ +--trusted-key-cert ${plat_build_dir}/trusted_key.crt \ +--tb-fw-cert ${plat_build_dir}/tb_fw.crt \ +--soc-fw-cert ${plat_build_dir}/soc_fw_content.crt \ +--soc-fw-key-cert ${plat_build_dir}/soc_fw_key.crt \ +--nt-fw-cert ${plat_build_dir}/nt_fw_content.crt \ +--nt-fw-key-cert ${plat_build_dir}/nt_fw_key.crt + + +# Build the FIP image. +tools/fiptool/fiptool create \ +--tb-fw-config ${plat_build_dir}/fdts/fvp_tb_fw_config.dtb \ +--soc-fw-config ${plat_build_dir}/fdts/fvp_soc_fw_config.dtb \ +--nt-fw-config ${plat_build_dir}/fdts/fvp_nt_fw_config.dtb \ +--hw-config ${plat_build_dir}/fdts/fvp-base-gicv3-psci.dtb \ + \ +--trusted-key-cert ${plat_build_dir}/trusted_key.crt \ +--tb-fw-cert ${plat_build_dir}/tb_fw.crt \ +--soc-fw-cert ${plat_build_dir}/soc_fw_content.crt \ +--soc-fw-key-cert ${plat_build_dir}/soc_fw_key.crt \ +--nt-fw-cert ${plat_build_dir}/nt_fw_content.crt \ +--nt-fw-key-cert ${plat_build_dir}/nt_fw_key.crt \ + \ +--tb-fw ${plat_build_dir}/bl2.bin \ +--soc-fw ${plat_build_dir}/bl31.bin \ +--nt-fw ${BL33} \ +${plat_build_dir}/fip.bin + + +# Run on the FVP. +FVP_Base_RevC-2xAEMv8A \ + -C bp.vis.disable_visualisation=1 \ + -C bp.terminal_0.start_telnet=0 \ + -C bp.terminal_1.start_telnet=0 \ + -C bp.pl011_uart0.out_file=- \ + -C bp.pl011_uart0.unbuffered_output=1 \ + -C bp.flashloader0.fname=${plat_build_dir}/fip.bin \ + -C bp.secureflashloader.fname=${plat_build_dir}/bl1.bin \ + -C pctl.startup=0.0.0.0 \ + -C bp.ve_sysregs.exit_on_shutdown=1 \ + -C bp.pl011_uart0.shutdown_on_eot=1 diff --git a/tools/cert_create/include/tbbr/tbb_ext.h b/tools/cert_create/include/tbbr/tbb_ext.h index 462aafc..824635c 100644 --- a/tools/cert_create/include/tbbr/tbb_ext.h +++ b/tools/cert_create/include/tbbr/tbb_ext.h @@ -32,7 +32,8 @@ enum { NON_TRUSTED_FW_CONFIG_HASH_EXT, SCP_FWU_CFG_HASH_EXT, AP_FWU_CFG_HASH_EXT, - FWU_HASH_EXT + FWU_HASH_EXT, + NS_ROT_PK_EXT }; #endif /* TBB_EXT_H */ diff --git a/tools/cert_create/include/tbbr/tbb_key.h b/tools/cert_create/include/tbbr/tbb_key.h index 47ad1de..fe67f61 100644 --- a/tools/cert_create/include/tbbr/tbb_key.h +++ b/tools/cert_create/include/tbbr/tbb_key.h @@ -19,7 +19,8 @@ enum { SCP_FW_CONTENT_CERT_KEY, SOC_FW_CONTENT_CERT_KEY, TRUSTED_OS_FW_CONTENT_CERT_KEY, - NON_TRUSTED_FW_CONTENT_CERT_KEY + NON_TRUSTED_FW_CONTENT_CERT_KEY, + NS_ROT_KEY }; #endif /* TBB_KEY_H */ diff --git a/tools/cert_create/src/tbbr/tbb_cert.c b/tools/cert_create/src/tbbr/tbb_cert.c index 7fb32d8..5c1e25c 100644 --- a/tools/cert_create/src/tbbr/tbb_cert.c +++ b/tools/cert_create/src/tbbr/tbb_cert.c @@ -141,13 +141,14 @@ static cert_t tbb_certs[] = { .help_msg = "Non-Trusted Firmware Key Certificate (output file)", .fn = NULL, .cn = "Non-Trusted Firmware Key Certificate", - .key = NON_TRUSTED_WORLD_KEY, + .key = NS_ROT_KEY, .issuer = NON_TRUSTED_FW_KEY_CERT, .ext = { NON_TRUSTED_FW_NVCOUNTER_EXT, - NON_TRUSTED_FW_CONTENT_CERT_PK_EXT + NON_TRUSTED_FW_CONTENT_CERT_PK_EXT, + NS_ROT_PK_EXT }, - .num_ext = 2 + .num_ext = 3 }, [NON_TRUSTED_FW_CONTENT_CERT] = { .id = NON_TRUSTED_FW_CONTENT_CERT, diff --git a/tools/cert_create/src/tbbr/tbb_ext.c b/tools/cert_create/src/tbbr/tbb_ext.c index ee5377f..1a849c9 100644 --- a/tools/cert_create/src/tbbr/tbb_ext.c +++ b/tools/cert_create/src/tbbr/tbb_ext.c @@ -232,7 +232,15 @@ static ext_t tbb_ext[] = { .asn1_type = V_ASN1_OCTET_STRING, .type = EXT_TYPE_HASH, .optional = 1 - } + }, + [NS_ROT_PK_EXT] = { + .oid = NS_ROT_KEY_OID, + .sn = "NonSecureRoTKey", + .ln = "Non-Secure Root of Trust Public Key", + .asn1_type = V_ASN1_OCTET_STRING, + .type = EXT_TYPE_PKEY, + .attr.key = NS_ROT_KEY + }, }; REGISTER_EXTENSIONS(tbb_ext); diff --git a/tools/cert_create/src/tbbr/tbb_key.c b/tools/cert_create/src/tbbr/tbb_key.c index a81f0e4..afc644c 100644 --- a/tools/cert_create/src/tbbr/tbb_key.c +++ b/tools/cert_create/src/tbbr/tbb_key.c @@ -53,7 +53,13 @@ static key_t tbb_keys[] = { .opt = "nt-fw-key", .help_msg = "Non Trusted Firmware Content Certificate key (input/output file)", .desc = "Non Trusted Firmware Content Certificate key" - } + }, + [NS_ROT_KEY] = { + .id = NS_ROT_KEY, + .opt = "ns-rot-key", + .help_msg = "Non-Secure Root of Trust key", + .desc = "Non-Secure Root of Trust key" + }, }; REGISTER_KEYS(tbb_keys); -- 2.7.4