diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst index 46177d768..fed202ad9 100644 --- a/docs/design/trusted-board-boot.rst +++ b/docs/design/trusted-board-boot.rst @@ -216,10 +216,11 @@ Certificate Generation Tool The ``cert_create`` tool is built and runs on the host machine as part of the TF-A build process when ``GENERATE_COT=1``. It takes the boot loader images -and keys as inputs (keys must be in PEM format) and generates the -certificates (in DER format) required to establish the CoT. New keys can be -generated by the tool in case they are not provided. The certificates are then -passed as inputs to the ``fiptool`` utility for creating the FIP. +and keys as inputs and generates the certificates (in DER format) required to +establish the CoT. The input keys must either be a file in PEM format or a +PKCS11 URI in case a HSM is used. New keys can be generated by the tool in +case they are not provided. The certificates are then passed as inputs to +the ``fiptool`` utility for creating the FIP. The certificates are also stored individually in the output build directory. diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 2c018c394..1da273878 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -80,9 +80,9 @@ Common build options BL31 image for the ``fip`` target. In this case, the BL31 in TF-A will not be built. -- ``BL31_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the - file that contains the BL31 private key in PEM format. If ``SAVE_KEYS=1``, - this file name will be used to save the key. +- ``BL31_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a + file that contains the BL31 private key in PEM format or a PKCS11 URI. If + ``SAVE_KEYS=1``, only a file is accepted and it will be used to save the key. - ``BL32``: This is an optional build option which specifies the path to BL32 image for the ``fip`` target. In this case, the BL32 in TF-A will not @@ -94,16 +94,16 @@ Common build options - ``BL32_EXTRA2``: This is an optional build option which specifies the path to Trusted OS Extra2 image for the ``fip`` target. -- ``BL32_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the - file that contains the BL32 private key in PEM format. If ``SAVE_KEYS=1``, - this file name will be used to save the key. +- ``BL32_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a + file that contains the BL32 private key in PEM format or a PKCS11 URI. If + ``SAVE_KEYS=1``, only a file is accepted and it will be used to save the key. - ``BL33``: Path to BL33 image in the host file system. This is mandatory for ``fip`` target in case TF-A BL2 is used. -- ``BL33_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the - file that contains the BL33 private key in PEM format. If ``SAVE_KEYS=1``, - this file name will be used to save the key. +- ``BL33_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a + file that contains the BL33 private key in PEM format or a PKCS11 URI. If + ``SAVE_KEYS=1``, only a file is accepted and it will be used to save the key. - ``BRANCH_PROTECTION``: Numeric value to enable ARMv8.3 Pointer Authentication and ARMv8.5 Branch Target Identification support for TF-A BL images themselves. @@ -749,8 +749,9 @@ Common build options MARCH_DIRECTIVE := -march=armv8.5-a - ``NON_TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It - specifies the file that contains the Non-Trusted World private key in PEM - format. If ``SAVE_KEYS=1``, this file name will be used to save the key. + specifies a file that contains the Non-Trusted World private key in PEM + format or a PKCS11 URI. If ``SAVE_KEYS=1``, only a file is accepted and it + will be used to save the key. - ``NS_BL2U``: Path to NS_BL2U image in the host file system. This image is optional. It is only needed if the platform makefile specifies that it @@ -827,10 +828,10 @@ Common build options instead of the BL1 entrypoint. It can take the value 0 (CPU reset to BL1 entrypoint) or 1 (CPU reset to SP_MIN entrypoint). The default value is 0. -- ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the - file that contains the ROT private key in PEM format and enforces public key - hash generation. If ``SAVE_KEYS=1``, this - file name will be used to save the key. +- ``ROT_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a + file that contains the ROT private key in PEM format or a PKCS11 URI and + enforces public key hash generation. If ``SAVE_KEYS=1``, only a file is + accepted and it will be used to save the key. - ``SAVE_KEYS``: This option is used when ``GENERATE_COT=1``. It tells the certificate generation tool to save the keys used to establish the Chain of @@ -840,9 +841,9 @@ Common build options If a SCP_BL2 image is present then this option must be passed for the ``fip`` target. -- ``SCP_BL2_KEY``: This option is used when ``GENERATE_COT=1``. It specifies the - file that contains the SCP_BL2 private key in PEM format. If ``SAVE_KEYS=1``, - this file name will be used to save the key. +- ``SCP_BL2_KEY``: This option is used when ``GENERATE_COT=1``. It specifies a + file that contains the SCP_BL2 private key in PEM format or a PKCS11 URI. + If ``SAVE_KEYS=1``, only a file is accepted and it will be used to save the key. - ``SCP_BL2U``: Path to SCP_BL2U image in the host file system. This image is optional. It is only needed if the platform makefile specifies that it @@ -959,8 +960,9 @@ Common build options already exist in disk, they will be overwritten without further notice. - ``TRUSTED_WORLD_KEY``: This option is used when ``GENERATE_COT=1``. It - specifies the file that contains the Trusted World private key in PEM - format. If ``SAVE_KEYS=1``, this file name will be used to save the key. + specifies a file that contains the Trusted World private key in PEM + format or a PKCS11 URI. If ``SAVE_KEYS=1``, only a file is accepted and + it will be used to save the key. - ``TSP_INIT_ASYNC``: Choose BL32 initialization method as asynchronous or synchronous, (see "Initializing a BL32 Image" section in diff --git a/tools/cert_create/src/cca/cot.c b/tools/cert_create/src/cca/cot.c index e39b036e4..372d90876 100644 --- a/tools/cert_create/src/cca/cot.c +++ b/tools/cert_create/src/cca/cot.c @@ -414,35 +414,35 @@ static key_t cot_keys[] = { [ROT_KEY] = { .id = ROT_KEY, .opt = "rot-key", - .help_msg = "Root Of Trust key (input/output file)", + .help_msg = "Root Of Trust key file or PKCS11 URI", .desc = "Root Of Trust key" }, [SWD_ROT_KEY] = { .id = SWD_ROT_KEY, .opt = "swd-rot-key", - .help_msg = "Secure World Root of Trust key", + .help_msg = "Secure World Root of Trust key file or PKCS11 URI", .desc = "Secure World Root of Trust key" }, [CORE_SWD_KEY] = { .id = CORE_SWD_KEY, .opt = "core-swd-key", - .help_msg = "Core Secure World key", + .help_msg = "Core Secure World key file or PKCS11 URI", .desc = "Core Secure World key" }, [PROT_KEY] = { .id = PROT_KEY, .opt = "prot-key", - .help_msg = "Platform Root of Trust key", + .help_msg = "Platform Root of Trust key file or PKCS11 URI", .desc = "Platform Root of Trust key" }, [PLAT_KEY] = { .id = PLAT_KEY, .opt = "plat-key", - .help_msg = "Platform key", + .help_msg = "Platform key file or PKCS11 URI", .desc = "Platform key" }, }; diff --git a/tools/cert_create/src/dualroot/cot.c b/tools/cert_create/src/dualroot/cot.c index 4dd4cf033..81a7d75dc 100644 --- a/tools/cert_create/src/dualroot/cot.c +++ b/tools/cert_create/src/dualroot/cot.c @@ -540,42 +540,42 @@ static key_t cot_keys[] = { [ROT_KEY] = { .id = ROT_KEY, .opt = "rot-key", - .help_msg = "Root Of Trust key (input/output file)", + .help_msg = "Root Of Trust key file or PKCS11 URI", .desc = "Root Of Trust key" }, [TRUSTED_WORLD_KEY] = { .id = TRUSTED_WORLD_KEY, .opt = "trusted-world-key", - .help_msg = "Trusted World key (input/output file)", + .help_msg = "Trusted World key file or PKCS11 URI", .desc = "Trusted World key" }, [SCP_FW_CONTENT_CERT_KEY] = { .id = SCP_FW_CONTENT_CERT_KEY, .opt = "scp-fw-key", - .help_msg = "SCP Firmware Content Certificate key (input/output file)", + .help_msg = "SCP Firmware Content Certificate key file or PKCS11 URI", .desc = "SCP Firmware Content Certificate key" }, [SOC_FW_CONTENT_CERT_KEY] = { .id = SOC_FW_CONTENT_CERT_KEY, .opt = "soc-fw-key", - .help_msg = "SoC Firmware Content Certificate key (input/output file)", + .help_msg = "SoC Firmware Content Certificate key file or PKCS11 URI", .desc = "SoC Firmware Content Certificate key" }, [TRUSTED_OS_FW_CONTENT_CERT_KEY] = { .id = TRUSTED_OS_FW_CONTENT_CERT_KEY, .opt = "tos-fw-key", - .help_msg = "Trusted OS Firmware Content Certificate key (input/output file)", + .help_msg = "Trusted OS Firmware Content Certificate key file or PKCS11 URI", .desc = "Trusted OS Firmware Content Certificate key" }, [PROT_KEY] = { .id = PROT_KEY, .opt = "prot-key", - .help_msg = "Platform Root of Trust key", + .help_msg = "Platform Root of Trust key file or PKCS11 URI", .desc = "Platform Root of Trust key" }, }; diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c index dc953d77a..32229d1e9 100644 --- a/tools/cert_create/src/key.c +++ b/tools/cert_create/src/key.c @@ -9,7 +9,11 @@ #include #include +/* Suppress OpenSSL engine deprecation warnings */ +#define OPENSSL_SUPPRESS_DEPRECATED + #include +#include #include #include @@ -189,29 +193,69 @@ int key_create(key_t *key, int type, int key_bits) return 0; } +static EVP_PKEY *key_load_pkcs11(const char *uri) +{ + char *key_pass; + EVP_PKEY *pkey; + ENGINE *e; + + ENGINE_load_builtin_engines(); + e = ENGINE_by_id("pkcs11"); + if (!e) { + fprintf(stderr, "Cannot Load PKCS#11 ENGINE\n"); + return NULL; + } + + if (!ENGINE_init(e)) { + fprintf(stderr, "Cannot ENGINE_init\n"); + goto err; + } + + key_pass = getenv("PKCS11_PIN"); + if (key_pass) { + if (!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) { + fprintf(stderr, "Cannot Set PKCS#11 PIN\n"); + goto err; + } + } + + pkey = ENGINE_load_private_key(e, uri, NULL, NULL); + if (pkey) + return pkey; +err: + ENGINE_free(e); + return NULL; + +} + int key_load(key_t *key, unsigned int *err_code) { FILE *fp; if (key->fn) { - /* Load key from file */ - fp = fopen(key->fn, "r"); - if (fp) { - key->key = PEM_read_PrivateKey(fp, NULL, NULL, NULL); - fclose(fp); - if (key->key) { - *err_code = KEY_ERR_NONE; - return 1; - } else { - ERROR("Cannot load key from %s\n", key->fn); - *err_code = KEY_ERR_LOAD; - } + if (!strncmp(key->fn, "pkcs11:", 7)) { + /* Load key through pkcs11 */ + key->key = key_load_pkcs11(key->fn); } else { - WARN("Cannot open file %s\n", key->fn); - *err_code = KEY_ERR_OPEN; + /* Load key from file */ + fp = fopen(key->fn, "r"); + if (fp) { + key->key = PEM_read_PrivateKey(fp, NULL, NULL, NULL); + fclose(fp); + } else { + WARN("Cannot open file %s\n", key->fn); + *err_code = KEY_ERR_OPEN; + } + } + if (key->key) { + *err_code = KEY_ERR_NONE; + return 1; + } else { + ERROR("Cannot load key from %s\n", key->fn); + *err_code = KEY_ERR_LOAD; } } else { - VERBOSE("Key filename not specified\n"); + VERBOSE("Key not specified\n"); *err_code = KEY_ERR_FILENAME; } @@ -223,6 +267,10 @@ int key_store(key_t *key) FILE *fp; if (key->fn) { + if (!strncmp(key->fn, "pkcs11:", 7)) { + ERROR("PKCS11 URI provided instead of a file"); + return 0; + } fp = fopen(key->fn, "w"); if (fp) { PEM_write_PrivateKey(fp, key->key, diff --git a/tools/cert_create/src/tbbr/tbb_key.c b/tools/cert_create/src/tbbr/tbb_key.c index a81f0e442..5b84b6e91 100644 --- a/tools/cert_create/src/tbbr/tbb_key.c +++ b/tools/cert_create/src/tbbr/tbb_key.c @@ -15,43 +15,43 @@ static key_t tbb_keys[] = { [ROT_KEY] = { .id = ROT_KEY, .opt = "rot-key", - .help_msg = "Root Of Trust key (input/output file)", + .help_msg = "Root Of Trust key file or PKCS11 URI", .desc = "Root Of Trust key" }, [TRUSTED_WORLD_KEY] = { .id = TRUSTED_WORLD_KEY, .opt = "trusted-world-key", - .help_msg = "Trusted World key (input/output file)", + .help_msg = "Trusted World key file or PKCS11 URI", .desc = "Trusted World key" }, [NON_TRUSTED_WORLD_KEY] = { .id = NON_TRUSTED_WORLD_KEY, .opt = "non-trusted-world-key", - .help_msg = "Non Trusted World key (input/output file)", + .help_msg = "Non Trusted World key file or PKCS11 URI", .desc = "Non Trusted World key" }, [SCP_FW_CONTENT_CERT_KEY] = { .id = SCP_FW_CONTENT_CERT_KEY, .opt = "scp-fw-key", - .help_msg = "SCP Firmware Content Certificate key (input/output file)", + .help_msg = "SCP Firmware Content Certificate key file or PKCS11 URI", .desc = "SCP Firmware Content Certificate key" }, [SOC_FW_CONTENT_CERT_KEY] = { .id = SOC_FW_CONTENT_CERT_KEY, .opt = "soc-fw-key", - .help_msg = "SoC Firmware Content Certificate key (input/output file)", + .help_msg = "SoC Firmware Content Certificate key file or PKCS11 URI", .desc = "SoC Firmware Content Certificate key" }, [TRUSTED_OS_FW_CONTENT_CERT_KEY] = { .id = TRUSTED_OS_FW_CONTENT_CERT_KEY, .opt = "tos-fw-key", - .help_msg = "Trusted OS Firmware Content Certificate key (input/output file)", + .help_msg = "Trusted OS Firmware Content Certificate key file or PKCS11 URI", .desc = "Trusted OS Firmware Content Certificate key" }, [NON_TRUSTED_FW_CONTENT_CERT_KEY] = { .id = NON_TRUSTED_FW_CONTENT_CERT_KEY, .opt = "nt-fw-key", - .help_msg = "Non Trusted Firmware Content Certificate key (input/output file)", + .help_msg = "Non Trusted Firmware Content Certificate key file or PKCS11 URI", .desc = "Non Trusted Firmware Content Certificate key" } };