Merge changes If9672598,I219c49d3 into integration

* changes:
  feat(cert-create): add pkcs11 engine support
  fix(cert-create): key: Avoid having a temporary value for pkey in key_load
This commit is contained in:
Sandrine Bailleux 2023-09-25 17:00:52 +02:00 committed by TrustedFirmware Code Review
commit 9c44778818
6 changed files with 108 additions and 58 deletions

View file

@ -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.

View file

@ -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

View file

@ -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"
},
};

View file

@ -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"
},
};

View file

@ -9,7 +9,11 @@
#include <stdlib.h>
#include <string.h>
/* Suppress OpenSSL engine deprecation warnings */
#define OPENSSL_SUPPRESS_DEPRECATED
#include <openssl/conf.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
@ -189,30 +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;
EVP_PKEY *k;
if (key->fn) {
/* Load key from file */
fp = fopen(key->fn, "r");
if (fp) {
k = PEM_read_PrivateKey(fp, &key->key, NULL, NULL);
fclose(fp);
if (k) {
*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;
}
@ -224,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,

View file

@ -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"
}
};