GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <common/tbbr/cot_def.h>
|
||||
#include <drivers/auth/auth_common.h>
|
||||
#include <drivers/auth/auth_mod.h>
|
||||
#include <drivers/auth/crypto_mod.h>
|
||||
#include <drivers/auth/img_parser_mod.h>
|
||||
#include <drivers/fwu/fwu.h>
|
||||
#include <lib/fconf/fconf_tbbr_getter.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
/* ASN.1 tags */
|
||||
#define ASN1_INTEGER 0x02
|
||||
|
||||
#define return_if_error(rc) \
|
||||
do { \
|
||||
if (rc != 0) { \
|
||||
return rc; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#pragma weak plat_set_nv_ctr2
|
||||
#pragma weak plat_convert_pk
|
||||
|
||||
|
||||
static int cmp_auth_param_type_desc(const auth_param_type_desc_t *a,
|
||||
const auth_param_type_desc_t *b)
|
||||
{
|
||||
if ((a->type == b->type) && (a->cookie == b->cookie)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function obtains the requested authentication parameter data from the
|
||||
* information extracted from the parent image after its authentication.
|
||||
*/
|
||||
static int auth_get_param(const auth_param_type_desc_t *param_type_desc,
|
||||
const auth_img_desc_t *img_desc,
|
||||
void **param, unsigned int *len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (img_desc->authenticated_data == NULL)
|
||||
return 1;
|
||||
|
||||
for (i = 0 ; i < COT_MAX_VERIFIED_PARAMS ; i++) {
|
||||
if (0 == cmp_auth_param_type_desc(param_type_desc,
|
||||
img_desc->authenticated_data[i].type_desc)) {
|
||||
*param = img_desc->authenticated_data[i].data.ptr;
|
||||
*len = img_desc->authenticated_data[i].data.len;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticate an image by matching the data hash
|
||||
*
|
||||
* This function implements 'AUTH_METHOD_HASH'. To authenticate an image using
|
||||
* this method, the image must contain:
|
||||
*
|
||||
* - The data to calculate the hash from
|
||||
*
|
||||
* The parent image must contain:
|
||||
*
|
||||
* - The hash to be matched with (including hash algorithm)
|
||||
*
|
||||
* For a successful authentication, both hashes must match. The function calls
|
||||
* the crypto-module to check this matching.
|
||||
*
|
||||
* Parameters:
|
||||
* param: parameters to perform the hash authentication
|
||||
* img_desc: pointer to image descriptor so we can know the image type
|
||||
* and parent image
|
||||
* img: pointer to image in memory
|
||||
* img_len: length of image (in bytes)
|
||||
*
|
||||
* Return:
|
||||
* 0 = success, Otherwise = error
|
||||
*/
|
||||
static int auth_hash(const auth_method_param_hash_t *param,
|
||||
const auth_img_desc_t *img_desc,
|
||||
void *img, unsigned int img_len)
|
||||
{
|
||||
void *data_ptr, *hash_der_ptr;
|
||||
unsigned int data_len, hash_der_len;
|
||||
int rc = 0;
|
||||
|
||||
/* Get the hash from the parent image. This hash will be DER encoded
|
||||
* and contain the hash algorithm */
|
||||
rc = auth_get_param(param->hash, img_desc->parent,
|
||||
&hash_der_ptr, &hash_der_len);
|
||||
return_if_error(rc);
|
||||
|
||||
/* Get the data to be hashed from the current image */
|
||||
rc = img_parser_get_auth_param(img_desc->img_type, param->data,
|
||||
img, img_len, &data_ptr, &data_len);
|
||||
return_if_error(rc);
|
||||
|
||||
/* Ask the crypto module to verify this hash */
|
||||
rc = crypto_mod_verify_hash(data_ptr, data_len,
|
||||
hash_der_ptr, hash_der_len);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticate by digital signature
|
||||
*
|
||||
* This function implements 'AUTH_METHOD_SIG'. To authenticate an image using
|
||||
* this method, the image must contain:
|
||||
*
|
||||
* - Data to be signed
|
||||
* - Signature
|
||||
* - Signature algorithm
|
||||
*
|
||||
* We rely on the image parser module to extract this data from the image.
|
||||
* The parent image must contain:
|
||||
*
|
||||
* - Public key (or a hash of it)
|
||||
*
|
||||
* If the parent image contains only a hash of the key, we will try to obtain
|
||||
* the public key from the image itself (i.e. self-signed certificates). In that
|
||||
* case, the signature verification is considered just an integrity check and
|
||||
* the authentication is established by calculating the hash of the key and
|
||||
* comparing it with the hash obtained from the parent.
|
||||
*
|
||||
* If the image has no parent (NULL), it means it has to be authenticated using
|
||||
* the ROTPK stored in the platform. Again, this ROTPK could be the key itself
|
||||
* or a hash of it.
|
||||
*
|
||||
* Return: 0 = success, Otherwise = error
|
||||
*/
|
||||
static int auth_signature(const auth_method_param_sig_t *param,
|
||||
const auth_img_desc_t *img_desc,
|
||||
void *img, unsigned int img_len)
|
||||
{
|
||||
void *data_ptr, *pk_ptr, *pk_hash_ptr, *sig_ptr, *sig_alg_ptr;
|
||||
unsigned int data_len, pk_len, pk_hash_len, sig_len, sig_alg_len;
|
||||
unsigned int flags = 0;
|
||||
int rc = 0;
|
||||
|
||||
/* Get the data to be signed from current image */
|
||||
rc = img_parser_get_auth_param(img_desc->img_type, param->data,
|
||||
img, img_len, &data_ptr, &data_len);
|
||||
return_if_error(rc);
|
||||
|
||||
/* Get the signature from current image */
|
||||
rc = img_parser_get_auth_param(img_desc->img_type, param->sig,
|
||||
img, img_len, &sig_ptr, &sig_len);
|
||||
return_if_error(rc);
|
||||
|
||||
/* Get the signature algorithm from current image */
|
||||
rc = img_parser_get_auth_param(img_desc->img_type, param->alg,
|
||||
img, img_len, &sig_alg_ptr, &sig_alg_len);
|
||||
return_if_error(rc);
|
||||
|
||||
/* Get the public key from the parent. If there is no parent (NULL),
|
||||
* the certificate has been signed with the ROTPK, so we have to get
|
||||
* the PK from the platform */
|
||||
if (img_desc->parent) {
|
||||
rc = auth_get_param(param->pk, img_desc->parent,
|
||||
&pk_ptr, &pk_len);
|
||||
} else {
|
||||
rc = plat_get_rotpk_info(param->pk->cookie, &pk_ptr, &pk_len,
|
||||
&flags);
|
||||
}
|
||||
return_if_error(rc);
|
||||
|
||||
if (flags & (ROTPK_IS_HASH | ROTPK_NOT_DEPLOYED)) {
|
||||
/* If the PK is a hash of the key or if the ROTPK is not
|
||||
deployed on the platform, retrieve the key from the image */
|
||||
pk_hash_ptr = pk_ptr;
|
||||
pk_hash_len = pk_len;
|
||||
rc = img_parser_get_auth_param(img_desc->img_type,
|
||||
param->pk, img, img_len,
|
||||
&pk_ptr, &pk_len);
|
||||
return_if_error(rc);
|
||||
|
||||
/* Ask the crypto module to verify the signature */
|
||||
rc = crypto_mod_verify_signature(data_ptr, data_len,
|
||||
sig_ptr, sig_len,
|
||||
sig_alg_ptr, sig_alg_len,
|
||||
pk_ptr, pk_len);
|
||||
return_if_error(rc);
|
||||
|
||||
if (flags & ROTPK_NOT_DEPLOYED) {
|
||||
NOTICE("ROTPK is not deployed on platform. "
|
||||
"Skipping ROTPK verification.\n");
|
||||
} else {
|
||||
/* platform may store the hash of a prefixed, suffixed or modified pk */
|
||||
rc = plat_convert_pk(pk_ptr, pk_len, &pk_ptr, &pk_len);
|
||||
return_if_error(rc);
|
||||
|
||||
/* Ask the crypto-module to verify the key hash */
|
||||
rc = crypto_mod_verify_hash(pk_ptr, pk_len,
|
||||
pk_hash_ptr, pk_hash_len);
|
||||
}
|
||||
} else {
|
||||
/* Ask the crypto module to verify the signature */
|
||||
rc = crypto_mod_verify_signature(data_ptr, data_len,
|
||||
sig_ptr, sig_len,
|
||||
sig_alg_ptr, sig_alg_len,
|
||||
pk_ptr, pk_len);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticate by Non-Volatile counter
|
||||
*
|
||||
* To protect the system against rollback, the platform includes a non-volatile
|
||||
* counter whose value can only be increased. All certificates include a counter
|
||||
* value that should not be lower than the value stored in the platform. If the
|
||||
* value is larger, the counter in the platform must be updated to the new value
|
||||
* (provided it has been authenticated).
|
||||
*
|
||||
* Return: 0 = success, Otherwise = error
|
||||
* Returns additionally,
|
||||
* cert_nv_ctr -> NV counter value present in the certificate
|
||||
* need_nv_ctr_upgrade = 0 -> platform NV counter upgrade is not needed
|
||||
* need_nv_ctr_upgrade = 1 -> platform NV counter upgrade is needed
|
||||
*/
|
||||
static int auth_nvctr(const auth_method_param_nv_ctr_t *param,
|
||||
const auth_img_desc_t *img_desc,
|
||||
void *img, unsigned int img_len,
|
||||
unsigned int *cert_nv_ctr,
|
||||
bool *need_nv_ctr_upgrade)
|
||||
{
|
||||
unsigned char *p;
|
||||
void *data_ptr = NULL;
|
||||
unsigned int data_len, len, i;
|
||||
unsigned int plat_nv_ctr;
|
||||
int rc = 0;
|
||||
bool is_trial_run = false;
|
||||
|
||||
/* Get the counter value from current image. The AM expects the IPM
|
||||
* to return the counter value as a DER encoded integer */
|
||||
rc = img_parser_get_auth_param(img_desc->img_type, param->cert_nv_ctr,
|
||||
img, img_len, &data_ptr, &data_len);
|
||||
return_if_error(rc);
|
||||
|
||||
/* Parse the DER encoded integer */
|
||||
assert(data_ptr);
|
||||
p = (unsigned char *)data_ptr;
|
||||
|
||||
/*
|
||||
* Integers must be at least 3 bytes: 1 for tag, 1 for length, and 1
|
||||
* for value. The first byte (tag) must be ASN1_INTEGER.
|
||||
*/
|
||||
if ((data_len < 3) || (*p != ASN1_INTEGER)) {
|
||||
/* Invalid ASN.1 integer */
|
||||
return 1;
|
||||
}
|
||||
p++;
|
||||
|
||||
/*
|
||||
* NV-counters are unsigned integers up to 31 bits. Trailing
|
||||
* padding is not allowed.
|
||||
*/
|
||||
len = (unsigned int)*p;
|
||||
if ((len > 4) || (data_len - 2 != len)) {
|
||||
return 1;
|
||||
}
|
||||
p++;
|
||||
|
||||
/* Check the number is not negative */
|
||||
if (*p & 0x80) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Convert to unsigned int. This code is for a little-endian CPU */
|
||||
*cert_nv_ctr = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
*cert_nv_ctr = (*cert_nv_ctr << 8) | *p++;
|
||||
}
|
||||
|
||||
/* Get the counter from the platform */
|
||||
rc = plat_get_nv_ctr(param->plat_nv_ctr->cookie, &plat_nv_ctr);
|
||||
return_if_error(rc);
|
||||
|
||||
if (*cert_nv_ctr < plat_nv_ctr) {
|
||||
/* Invalid NV-counter */
|
||||
return 1;
|
||||
} else if (*cert_nv_ctr > plat_nv_ctr) {
|
||||
#if PSA_FWU_SUPPORT && IMAGE_BL2
|
||||
is_trial_run = fwu_is_trial_run_state();
|
||||
#endif /* PSA_FWU_SUPPORT && IMAGE_BL2 */
|
||||
*need_nv_ctr_upgrade = !is_trial_run;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int plat_set_nv_ctr2(void *cookie, const auth_img_desc_t *img_desc __unused,
|
||||
unsigned int nv_ctr)
|
||||
{
|
||||
return plat_set_nv_ctr(cookie, nv_ctr);
|
||||
}
|
||||
|
||||
int plat_convert_pk(void *full_pk_ptr, unsigned int full_pk_len,
|
||||
void **hashed_pk_ptr, unsigned int *hashed_pk_len)
|
||||
{
|
||||
*hashed_pk_ptr = full_pk_ptr;
|
||||
*hashed_pk_len = full_pk_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the parent id in the output parameter '*parent_id'
|
||||
*
|
||||
* Return value:
|
||||
* 0 = Image has parent, 1 = Image has no parent or parent is authenticated
|
||||
*/
|
||||
int auth_mod_get_parent_id(unsigned int img_id, unsigned int *parent_id)
|
||||
{
|
||||
const auth_img_desc_t *img_desc = NULL;
|
||||
|
||||
assert(parent_id != NULL);
|
||||
/* Get the image descriptor */
|
||||
img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id);
|
||||
|
||||
/* Check if the image has no parent (ROT) */
|
||||
if (img_desc->parent == NULL) {
|
||||
*parent_id = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Check if the parent has already been authenticated */
|
||||
if (auth_img_flags[img_desc->parent->img_id] & IMG_FLAG_AUTHENTICATED) {
|
||||
*parent_id = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
*parent_id = img_desc->parent->img_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the different modules in the authentication framework
|
||||
*/
|
||||
void auth_mod_init(void)
|
||||
{
|
||||
/* Check we have a valid CoT registered */
|
||||
assert(cot_desc_ptr != NULL);
|
||||
|
||||
/* Image parser module */
|
||||
img_parser_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticate a certificate/image
|
||||
*
|
||||
* Return: 0 = success, Otherwise = error
|
||||
*/
|
||||
int auth_mod_verify_img(unsigned int img_id,
|
||||
void *img_ptr,
|
||||
unsigned int img_len)
|
||||
{
|
||||
const auth_img_desc_t *img_desc = NULL;
|
||||
const auth_method_desc_t *auth_method = NULL;
|
||||
void *param_ptr;
|
||||
unsigned int param_len;
|
||||
int rc, i;
|
||||
unsigned int cert_nv_ctr = 0;
|
||||
bool need_nv_ctr_upgrade = false;
|
||||
bool sig_auth_done = false;
|
||||
const auth_method_param_nv_ctr_t *nv_ctr_param = NULL;
|
||||
|
||||
/* Get the image descriptor from the chain of trust */
|
||||
img_desc = FCONF_GET_PROPERTY(tbbr, cot, img_id);
|
||||
|
||||
/* Ask the parser to check the image integrity */
|
||||
rc = img_parser_check_integrity(img_desc->img_type, img_ptr, img_len);
|
||||
return_if_error(rc);
|
||||
|
||||
/* Authenticate the image using the methods indicated in the image
|
||||
* descriptor. */
|
||||
if (img_desc->img_auth_methods == NULL)
|
||||
return 1;
|
||||
for (i = 0 ; i < AUTH_METHOD_NUM ; i++) {
|
||||
auth_method = &img_desc->img_auth_methods[i];
|
||||
switch (auth_method->type) {
|
||||
case AUTH_METHOD_NONE:
|
||||
rc = 0;
|
||||
break;
|
||||
case AUTH_METHOD_HASH:
|
||||
rc = auth_hash(&auth_method->param.hash,
|
||||
img_desc, img_ptr, img_len);
|
||||
break;
|
||||
case AUTH_METHOD_SIG:
|
||||
rc = auth_signature(&auth_method->param.sig,
|
||||
img_desc, img_ptr, img_len);
|
||||
sig_auth_done = true;
|
||||
break;
|
||||
case AUTH_METHOD_NV_CTR:
|
||||
nv_ctr_param = &auth_method->param.nv_ctr;
|
||||
rc = auth_nvctr(nv_ctr_param,
|
||||
img_desc, img_ptr, img_len,
|
||||
&cert_nv_ctr, &need_nv_ctr_upgrade);
|
||||
break;
|
||||
default:
|
||||
/* Unknown authentication method */
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
return_if_error(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do platform NV counter upgrade only if the certificate gets
|
||||
* authenticated, and platform NV-counter upgrade is needed.
|
||||
*/
|
||||
if (need_nv_ctr_upgrade && sig_auth_done) {
|
||||
rc = plat_set_nv_ctr2(nv_ctr_param->plat_nv_ctr->cookie,
|
||||
img_desc, cert_nv_ctr);
|
||||
return_if_error(rc);
|
||||
}
|
||||
|
||||
/* Extract the parameters indicated in the image descriptor to
|
||||
* authenticate the children images. */
|
||||
if (img_desc->authenticated_data != NULL) {
|
||||
for (i = 0 ; i < COT_MAX_VERIFIED_PARAMS ; i++) {
|
||||
if (img_desc->authenticated_data[i].type_desc == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the parameter from the image parser module */
|
||||
rc = img_parser_get_auth_param(img_desc->img_type,
|
||||
img_desc->authenticated_data[i].type_desc,
|
||||
img_ptr, img_len, ¶m_ptr, ¶m_len);
|
||||
return_if_error(rc);
|
||||
|
||||
/* Check parameter size */
|
||||
if (param_len > img_desc->authenticated_data[i].data.len) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Copy the parameter for later use */
|
||||
memcpy((void *)img_desc->authenticated_data[i].data.ptr,
|
||||
(void *)param_ptr, param_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark image as authenticated */
|
||||
auth_img_flags[img_desc->img_id] |= IMG_FLAG_AUTHENTICATED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,675 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <drivers/auth/auth_mod.h>
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#include <tools_share/cca_oid.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
/*
|
||||
* Allocate static buffers to store the authentication parameters extracted from
|
||||
* the certificates.
|
||||
*/
|
||||
static unsigned char fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char hw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char rmm_hash_buf[HASH_DER_LEN];
|
||||
|
||||
#ifdef IMAGE_BL2
|
||||
static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
|
||||
#if defined(SPD_spmd)
|
||||
static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
|
||||
#endif /* SPD_spmd */
|
||||
|
||||
static unsigned char core_swd_pk_buf[PK_DER_LEN];
|
||||
static unsigned char plat_pk_buf[PK_DER_LEN];
|
||||
#endif /* IMAGE_BL2 */
|
||||
|
||||
/*
|
||||
* Parameter type descriptors.
|
||||
*/
|
||||
static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
|
||||
static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, 0);
|
||||
static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_SIG, 0);
|
||||
static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_SIG_ALG, 0);
|
||||
static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_RAW_DATA, 0);
|
||||
|
||||
static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
|
||||
static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID);
|
||||
static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t rmm_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, RMM_HASH_OID);
|
||||
|
||||
#ifdef IMAGE_BL2
|
||||
static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
|
||||
|
||||
static auth_param_type_desc_t prot_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, PROT_PK_OID);
|
||||
static auth_param_type_desc_t swd_rot_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, SWD_ROT_PK_OID);
|
||||
static auth_param_type_desc_t core_swd_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, CORE_SWD_PK_OID);
|
||||
static auth_param_type_desc_t plat_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, PLAT_PK_OID);
|
||||
|
||||
static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID);
|
||||
static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
|
||||
static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
|
||||
#if defined(SPD_spmd)
|
||||
static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
|
||||
#endif /* SPD_spmd */
|
||||
#endif /* IMAGE_BL2 */
|
||||
|
||||
/* CCA Content Certificate */
|
||||
static const auth_img_desc_t cca_content_cert = {
|
||||
.img_id = CCA_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &subject_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &tb_fw_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tb_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &tb_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tb_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[3] = {
|
||||
.type_desc = &hw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)hw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[4] = {
|
||||
.type_desc = &soc_fw_hash,
|
||||
.data = {
|
||||
.ptr = (void *)soc_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[5] = {
|
||||
.type_desc = &soc_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)soc_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[6] = {
|
||||
.type_desc = &rmm_hash,
|
||||
.data = {
|
||||
.ptr = (void *)rmm_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef IMAGE_BL1
|
||||
static const auth_img_desc_t bl2_image = {
|
||||
.img_id = BL2_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &cca_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tb_fw_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t tb_fw_config = {
|
||||
.img_id = TB_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &cca_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tb_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t fw_config = {
|
||||
.img_id = FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &cca_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif /* IMAGE_BL1 */
|
||||
|
||||
#ifdef IMAGE_BL2
|
||||
/* HW Config */
|
||||
static const auth_img_desc_t hw_config = {
|
||||
.img_id = HW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &cca_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &hw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* BL31 */
|
||||
static const auth_img_desc_t bl31_image = {
|
||||
.img_id = BL31_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &cca_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &soc_fw_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* BL31 Config */
|
||||
static const auth_img_desc_t soc_fw_config = {
|
||||
.img_id = SOC_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &cca_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &soc_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* RMM */
|
||||
static const auth_img_desc_t rmm_image = {
|
||||
.img_id = RMM_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &cca_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &rmm_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Core SWD Key Certificate */
|
||||
static const auth_img_desc_t core_swd_key_cert = {
|
||||
.img_id = CORE_SWD_KEY_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL, /* SWD ROOT CERT */
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &swd_rot_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &core_swd_pk,
|
||||
.data = {
|
||||
.ptr = (void *)core_swd_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* SPMC Content Certificate */
|
||||
static const auth_img_desc_t trusted_os_fw_content_cert = {
|
||||
.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &core_swd_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &core_swd_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &tos_fw_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tos_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &tos_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tos_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* SPMC */
|
||||
static const auth_img_desc_t bl32_image = {
|
||||
.img_id = BL32_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_os_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tos_fw_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* SPM Config */
|
||||
static const auth_img_desc_t tos_fw_config = {
|
||||
.img_id = TOS_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_os_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tos_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Platform Key Certificate */
|
||||
static const auth_img_desc_t plat_key_cert = {
|
||||
.img_id = PLAT_KEY_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL, /* PLATFORM ROOT CERT */
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &prot_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &non_trusted_nv_ctr,
|
||||
.plat_nv_ctr = &non_trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &plat_pk,
|
||||
.data = {
|
||||
.ptr = (void *)plat_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Non-Trusted Firmware */
|
||||
static const auth_img_desc_t non_trusted_fw_content_cert = {
|
||||
.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &plat_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &plat_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &non_trusted_nv_ctr,
|
||||
.plat_nv_ctr = &non_trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &nt_world_bl_hash,
|
||||
.data = {
|
||||
.ptr = (void *)nt_world_bl_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &nt_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)nt_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t bl33_image = {
|
||||
.img_id = BL33_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &non_trusted_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &nt_world_bl_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* NT FW Config */
|
||||
static const auth_img_desc_t nt_fw_config = {
|
||||
.img_id = NT_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &non_trusted_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &nt_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Secure Partitions
|
||||
*/
|
||||
#if defined(SPD_spmd)
|
||||
static const auth_img_desc_t sip_sp_content_cert = {
|
||||
.img_id = SIP_SP_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &core_swd_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &core_swd_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &sp_pkg1_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[0],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &sp_pkg2_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[1],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &sp_pkg3_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[2],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[3] = {
|
||||
.type_desc = &sp_pkg4_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[3],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DEFINE_SIP_SP_PKG(1);
|
||||
DEFINE_SIP_SP_PKG(2);
|
||||
DEFINE_SIP_SP_PKG(3);
|
||||
DEFINE_SIP_SP_PKG(4);
|
||||
|
||||
static const auth_img_desc_t plat_sp_content_cert = {
|
||||
.img_id = PLAT_SP_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &plat_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &plat_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &non_trusted_nv_ctr,
|
||||
.plat_nv_ctr = &non_trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &sp_pkg5_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[4],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &sp_pkg6_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[5],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &sp_pkg7_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[6],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[3] = {
|
||||
.type_desc = &sp_pkg8_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[7],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DEFINE_PLAT_SP_PKG(5);
|
||||
DEFINE_PLAT_SP_PKG(6);
|
||||
DEFINE_PLAT_SP_PKG(7);
|
||||
DEFINE_PLAT_SP_PKG(8);
|
||||
#endif /* SPD_spmd */
|
||||
#endif /* IMAGE_BL2 */
|
||||
/*
|
||||
* Chain of trust definition
|
||||
*/
|
||||
#ifdef IMAGE_BL1
|
||||
static const auth_img_desc_t * const cot_desc[] = {
|
||||
[CCA_CONTENT_CERT_ID] = &cca_content_cert,
|
||||
[BL2_IMAGE_ID] = &bl2_image,
|
||||
[TB_FW_CONFIG_ID] = &tb_fw_config,
|
||||
[FW_CONFIG_ID] = &fw_config,
|
||||
};
|
||||
#else /* IMAGE_BL2 */
|
||||
static const auth_img_desc_t * const cot_desc[] = {
|
||||
[CCA_CONTENT_CERT_ID] = &cca_content_cert,
|
||||
[HW_CONFIG_ID] = &hw_config,
|
||||
[BL31_IMAGE_ID] = &bl31_image,
|
||||
[SOC_FW_CONFIG_ID] = &soc_fw_config,
|
||||
[RMM_IMAGE_ID] = &rmm_image,
|
||||
[CORE_SWD_KEY_CERT_ID] = &core_swd_key_cert,
|
||||
[TRUSTED_OS_FW_CONTENT_CERT_ID] = &trusted_os_fw_content_cert,
|
||||
[BL32_IMAGE_ID] = &bl32_image,
|
||||
[TOS_FW_CONFIG_ID] = &tos_fw_config,
|
||||
[PLAT_KEY_CERT_ID] = &plat_key_cert,
|
||||
[NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert,
|
||||
[BL33_IMAGE_ID] = &bl33_image,
|
||||
[NT_FW_CONFIG_ID] = &nt_fw_config,
|
||||
#if defined(SPD_spmd)
|
||||
[SIP_SP_CONTENT_CERT_ID] = &sip_sp_content_cert,
|
||||
[PLAT_SP_CONTENT_CERT_ID] = &plat_sp_content_cert,
|
||||
[SP_PKG1_ID] = &sp_pkg1,
|
||||
[SP_PKG2_ID] = &sp_pkg2,
|
||||
[SP_PKG3_ID] = &sp_pkg3,
|
||||
[SP_PKG4_ID] = &sp_pkg4,
|
||||
[SP_PKG5_ID] = &sp_pkg5,
|
||||
[SP_PKG6_ID] = &sp_pkg6,
|
||||
[SP_PKG7_ID] = &sp_pkg7,
|
||||
[SP_PKG8_ID] = &sp_pkg8,
|
||||
#endif
|
||||
};
|
||||
#endif /* IMAGE_BL1 */
|
||||
|
||||
/* Register the CoT in the authentication module */
|
||||
REGISTER_COT(cot_desc);
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/auth/crypto_mod.h>
|
||||
|
||||
/* Variable exported by the crypto library through REGISTER_CRYPTO_LIB() */
|
||||
|
||||
/*
|
||||
* The crypto module is responsible for verifying digital signatures and hashes.
|
||||
* It relies on a crypto library to perform the cryptographic operations.
|
||||
*
|
||||
* The crypto module itself does not impose any specific format on signatures,
|
||||
* signature algorithm, keys or hashes, but most cryptographic libraries will
|
||||
* take the parameters as the following DER encoded ASN.1 structures:
|
||||
*
|
||||
* AlgorithmIdentifier ::= SEQUENCE {
|
||||
* algorithm OBJECT IDENTIFIER,
|
||||
* parameters ANY DEFINED BY algorithm OPTIONAL
|
||||
* }
|
||||
*
|
||||
* DigestInfo ::= SEQUENCE {
|
||||
* digestAlgorithm AlgorithmIdentifier,
|
||||
* digest OCTET STRING
|
||||
* }
|
||||
*
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING
|
||||
* }
|
||||
*
|
||||
* SignatureAlgorithm ::= AlgorithmIdentifier
|
||||
*
|
||||
* SignatureValue ::= BIT STRING
|
||||
*/
|
||||
|
||||
/*
|
||||
* Perform some static checking and call the library initialization function
|
||||
*/
|
||||
void crypto_mod_init(void)
|
||||
{
|
||||
assert(crypto_lib_desc.name != NULL);
|
||||
assert(crypto_lib_desc.init != NULL);
|
||||
#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
|
||||
assert(crypto_lib_desc.verify_signature != NULL);
|
||||
assert(crypto_lib_desc.verify_hash != NULL);
|
||||
#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
|
||||
|
||||
#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
|
||||
assert(crypto_lib_desc.calc_hash != NULL);
|
||||
#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
|
||||
|
||||
/* Initialize the cryptographic library */
|
||||
crypto_lib_desc.init();
|
||||
INFO("Using crypto library '%s'\n", crypto_lib_desc.name);
|
||||
}
|
||||
|
||||
#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
|
||||
/*
|
||||
* Function to verify a digital signature
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data_ptr, data_len: signed data
|
||||
* sig_ptr, sig_len: the digital signature
|
||||
* sig_alg_ptr, sig_alg_len: the digital signature algorithm
|
||||
* pk_ptr, pk_len: the public key
|
||||
*/
|
||||
int crypto_mod_verify_signature(void *data_ptr, unsigned int data_len,
|
||||
void *sig_ptr, unsigned int sig_len,
|
||||
void *sig_alg_ptr, unsigned int sig_alg_len,
|
||||
void *pk_ptr, unsigned int pk_len)
|
||||
{
|
||||
assert(data_ptr != NULL);
|
||||
assert(data_len != 0);
|
||||
assert(sig_ptr != NULL);
|
||||
assert(sig_len != 0);
|
||||
assert(sig_alg_ptr != NULL);
|
||||
assert(sig_alg_len != 0);
|
||||
assert(pk_ptr != NULL);
|
||||
assert(pk_len != 0);
|
||||
|
||||
return crypto_lib_desc.verify_signature(data_ptr, data_len,
|
||||
sig_ptr, sig_len,
|
||||
sig_alg_ptr, sig_alg_len,
|
||||
pk_ptr, pk_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify a hash by comparison
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* data_ptr, data_len: data to be hashed
|
||||
* digest_info_ptr, digest_info_len: hash to be compared
|
||||
*/
|
||||
int crypto_mod_verify_hash(void *data_ptr, unsigned int data_len,
|
||||
void *digest_info_ptr, unsigned int digest_info_len)
|
||||
{
|
||||
assert(data_ptr != NULL);
|
||||
assert(data_len != 0);
|
||||
assert(digest_info_ptr != NULL);
|
||||
assert(digest_info_len != 0);
|
||||
|
||||
return crypto_lib_desc.verify_hash(data_ptr, data_len,
|
||||
digest_info_ptr, digest_info_len);
|
||||
}
|
||||
#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
|
||||
|
||||
#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
|
||||
/*
|
||||
* Calculate a hash
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* alg: message digest algorithm
|
||||
* data_ptr, data_len: data to be hashed
|
||||
* output: resulting hash
|
||||
*/
|
||||
int crypto_mod_calc_hash(enum crypto_md_algo alg, void *data_ptr,
|
||||
unsigned int data_len,
|
||||
unsigned char output[CRYPTO_MD_MAX_SIZE])
|
||||
{
|
||||
assert(data_ptr != NULL);
|
||||
assert(data_len != 0);
|
||||
assert(output != NULL);
|
||||
|
||||
return crypto_lib_desc.calc_hash(alg, data_ptr, data_len, output);
|
||||
}
|
||||
#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
|
||||
|
||||
/*
|
||||
* Authenticated decryption of data
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
* dec_algo: authenticated decryption algorithm
|
||||
* data_ptr, len: data to be decrypted (inout param)
|
||||
* key, key_len, key_flags: symmetric decryption key
|
||||
* iv, iv_len: initialization vector
|
||||
* tag, tag_len: authentication tag
|
||||
*/
|
||||
int crypto_mod_auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
|
||||
size_t len, const void *key, unsigned int key_len,
|
||||
unsigned int key_flags, const void *iv,
|
||||
unsigned int iv_len, const void *tag,
|
||||
unsigned int tag_len)
|
||||
{
|
||||
assert(crypto_lib_desc.auth_decrypt != NULL);
|
||||
assert(data_ptr != NULL);
|
||||
assert(len != 0U);
|
||||
assert(key != NULL);
|
||||
assert(key_len != 0U);
|
||||
assert(iv != NULL);
|
||||
assert((iv_len != 0U) && (iv_len <= CRYPTO_MAX_IV_SIZE));
|
||||
assert(tag != NULL);
|
||||
assert((tag_len != 0U) && (tag_len <= CRYPTO_MAX_TAG_SIZE));
|
||||
|
||||
return crypto_lib_desc.auth_decrypt(dec_algo, data_ptr, len, key,
|
||||
key_len, key_flags, iv, iv_len, tag,
|
||||
tag_len);
|
||||
}
|
||||
+306
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <common/debug.h>
|
||||
#include <drivers/arm/cryptocell/712/crypto_driver.h>
|
||||
#include <drivers/arm/cryptocell/712/rsa.h>
|
||||
#include <drivers/arm/cryptocell/712/sbrom_bsv_api.h>
|
||||
#include <drivers/arm/cryptocell/712/secureboot_base_func.h>
|
||||
#include <drivers/arm/cryptocell/712/secureboot_gen_defs.h>
|
||||
#include <drivers/arm/cryptocell/712/util.h>
|
||||
#include <drivers/auth/crypto_mod.h>
|
||||
#include <drivers/auth/mbedtls/mbedtls_common.h>
|
||||
#include <lib/utils.h>
|
||||
|
||||
#include <mbedtls/oid.h>
|
||||
#include <mbedtls/x509.h>
|
||||
|
||||
#define LIB_NAME "CryptoCell 712 SBROM"
|
||||
#define RSA_SALT_LEN 32
|
||||
#define RSA_EXPONENT 65537
|
||||
|
||||
/*
|
||||
* AlgorithmIdentifier ::= SEQUENCE {
|
||||
* algorithm OBJECT IDENTIFIER,
|
||||
* parameters ANY DEFINED BY algorithm OPTIONAL
|
||||
* }
|
||||
*
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING
|
||||
* }
|
||||
*
|
||||
* DigestInfo ::= SEQUENCE {
|
||||
* digestAlgorithm AlgorithmIdentifier,
|
||||
* digest OCTET STRING
|
||||
* }
|
||||
*
|
||||
* RSASSA-PSS-params ::= SEQUENCE {
|
||||
* hashAlgorithm [0] HashAlgorithm,
|
||||
* maskGenAlgorithm [1] MaskGenAlgorithm,
|
||||
* saltLength [2] INTEGER,
|
||||
* trailerField [3] TrailerField DEFAULT trailerFieldBC
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialize the library and export the descriptor
|
||||
*/
|
||||
static void init(void)
|
||||
{
|
||||
CCError_t ret;
|
||||
uint32_t lcs;
|
||||
|
||||
/* Initialize CC SBROM */
|
||||
ret = CC_BsvSbromInit((uintptr_t)PLAT_CRYPTOCELL_BASE);
|
||||
if (ret != CC_OK) {
|
||||
ERROR("CryptoCell CC_BsvSbromInit() error %x\n", ret);
|
||||
panic();
|
||||
}
|
||||
|
||||
/* Initialize lifecycle state */
|
||||
ret = CC_BsvLcsGetAndInit((uintptr_t)PLAT_CRYPTOCELL_BASE, &lcs);
|
||||
if (ret != CC_OK) {
|
||||
ERROR("CryptoCell CC_BsvLcsGetAndInit() error %x\n", ret);
|
||||
panic();
|
||||
}
|
||||
|
||||
/* If the lifecyclestate is `SD`, then stop further execution */
|
||||
if (lcs == CC_BSV_SECURITY_DISABLED_LCS) {
|
||||
ERROR("CryptoCell LCS is security-disabled\n");
|
||||
panic();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify a signature.
|
||||
*
|
||||
* Parameters are passed using the DER encoding format following the ASN.1
|
||||
* structures detailed above.
|
||||
*/
|
||||
static int verify_signature(void *data_ptr, unsigned int data_len,
|
||||
void *sig_ptr, unsigned int sig_len,
|
||||
void *sig_alg, unsigned int sig_alg_len,
|
||||
void *pk_ptr, unsigned int pk_len)
|
||||
{
|
||||
CCError_t error;
|
||||
CCSbNParams_t pk;
|
||||
CCSbSignature_t signature;
|
||||
int rc, exp;
|
||||
mbedtls_asn1_buf sig_oid, alg_oid, params;
|
||||
mbedtls_md_type_t md_alg;
|
||||
mbedtls_pk_type_t pk_alg;
|
||||
mbedtls_pk_rsassa_pss_options pss_opts;
|
||||
size_t len;
|
||||
uint8_t *p, *end;
|
||||
/* Temp buf to store the public key modulo (N) in LE format */
|
||||
uint32_t RevN[SB_RSA_MOD_SIZE_IN_WORDS];
|
||||
|
||||
/* Verify the signature algorithm */
|
||||
/* Get pointers to signature OID and parameters */
|
||||
p = sig_alg;
|
||||
end = p + sig_alg_len;
|
||||
rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, ¶ms);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* Get the actual signature algorithm (MD + PK) */
|
||||
rc = mbedtls_oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* The CryptoCell only supports RSASSA-PSS signature */
|
||||
if (pk_alg != MBEDTLS_PK_RSASSA_PSS || md_alg != MBEDTLS_MD_NONE)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* Verify the RSASSA-PSS params */
|
||||
/* The trailer field is verified to be 0xBC internally by this API */
|
||||
rc = mbedtls_x509_get_rsassa_pss_params(¶ms, &md_alg,
|
||||
&pss_opts.mgf1_hash_id,
|
||||
&pss_opts.expected_salt_len);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* The CryptoCell only supports SHA256 as hash algorithm */
|
||||
if (md_alg != MBEDTLS_MD_SHA256 || pss_opts.mgf1_hash_id != MBEDTLS_MD_SHA256)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (pss_opts.expected_salt_len != RSA_SALT_LEN)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* Parse the public key */
|
||||
p = pk_ptr;
|
||||
end = p + pk_len;
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
end = p + len;
|
||||
rc = mbedtls_asn1_get_alg_null(&p, end, &alg_oid);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (pk_alg != MBEDTLS_PK_RSA)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
rc = mbedtls_asn1_get_bitstring_null(&p, end, &len);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (*p == 0) {
|
||||
p++; len--;
|
||||
}
|
||||
if (len != RSA_MOD_SIZE_IN_BYTES || ((p + len) > end))
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/*
|
||||
* The CCSbVerifySignature() API expects N and Np in BE format and
|
||||
* the signature in LE format. Copy N from certificate.
|
||||
*/
|
||||
memcpy(pk.N, p, RSA_MOD_SIZE_IN_BYTES);
|
||||
|
||||
/* Verify the RSA exponent */
|
||||
p += len;
|
||||
rc = mbedtls_asn1_get_int(&p, end, &exp);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (exp != RSA_EXPONENT)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/*
|
||||
* Calculate the Np (Barrett n' value). The RSA_CalcNp() API expects
|
||||
* N in LE format. Hence reverse N into a temporary buffer `RevN`.
|
||||
*/
|
||||
UTIL_ReverseMemCopy((uint8_t *)RevN, (uint8_t *)pk.N, sizeof(RevN));
|
||||
|
||||
RSA_CalcNp((uintptr_t)PLAT_CRYPTOCELL_BASE, RevN, pk.Np);
|
||||
|
||||
/* Np is in LE format. Reverse it to BE */
|
||||
UTIL_ReverseBuff((uint8_t *)pk.Np, sizeof(pk.Np));
|
||||
|
||||
/* Get the signature (bitstring) */
|
||||
p = sig_ptr;
|
||||
end = p + sig_len;
|
||||
rc = mbedtls_asn1_get_bitstring_null(&p, end, &len);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (len != RSA_MOD_SIZE_IN_BYTES || ((p + len) > end))
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/*
|
||||
* The signature is BE format. Convert it to LE before calling
|
||||
* CCSbVerifySignature().
|
||||
*/
|
||||
UTIL_ReverseMemCopy((uint8_t *)signature.sig, p, RSA_MOD_SIZE_IN_BYTES);
|
||||
|
||||
/*
|
||||
* CryptoCell utilises DMA internally to transfer data. Flush the data
|
||||
* from caches.
|
||||
*/
|
||||
flush_dcache_range((uintptr_t)data_ptr, data_len);
|
||||
|
||||
/* Verify the signature */
|
||||
error = CCSbVerifySignature((uintptr_t)PLAT_CRYPTOCELL_BASE,
|
||||
(uint32_t *)data_ptr, &pk, &signature,
|
||||
data_len, RSA_PSS);
|
||||
if (error != CC_OK)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* Signature verification success */
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Match a hash
|
||||
*
|
||||
* Digest info is passed in DER format following the ASN.1 structure detailed
|
||||
* above.
|
||||
*/
|
||||
static int verify_hash(void *data_ptr, unsigned int data_len,
|
||||
void *digest_info_ptr, unsigned int digest_info_len)
|
||||
{
|
||||
mbedtls_asn1_buf hash_oid, params;
|
||||
mbedtls_md_type_t md_alg;
|
||||
uint8_t *p, *end, *hash;
|
||||
CCHashResult_t pubKeyHash;
|
||||
size_t len;
|
||||
int rc;
|
||||
CCError_t error;
|
||||
|
||||
/* Digest info should be an MBEDTLS_ASN1_SEQUENCE */
|
||||
p = digest_info_ptr;
|
||||
end = p + digest_info_len;
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
/* Get the hash algorithm */
|
||||
rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_HASH;
|
||||
/* Verify that hash algorithm is SHA256 */
|
||||
if (md_alg != MBEDTLS_MD_SHA256)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
/* Hash should be octet string type */
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
/* Length of hash must match the algorithm's size */
|
||||
if (len != HASH_RESULT_SIZE_IN_BYTES)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
/*
|
||||
* CryptoCell utilises DMA internally to transfer data. Flush the data
|
||||
* from caches.
|
||||
*/
|
||||
flush_dcache_range((uintptr_t)data_ptr, data_len);
|
||||
|
||||
hash = p;
|
||||
error = SBROM_CryptoHash((uintptr_t)PLAT_CRYPTOCELL_BASE,
|
||||
(uintptr_t)data_ptr, data_len, pubKeyHash);
|
||||
if (error != CC_OK)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
rc = memcmp(pubKeyHash, hash, HASH_RESULT_SIZE_IN_BYTES);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register crypto library descriptor
|
||||
*/
|
||||
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
|
||||
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <plat/common/platform.h>
|
||||
#include <tools_share/tbbr_oid.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/arm/cryptocell/712/sbrom_bsv_api.h>
|
||||
#include <drivers/arm/cryptocell/712/nvm.h>
|
||||
#include <drivers/arm/cryptocell/712/nvm_otp.h>
|
||||
|
||||
/*
|
||||
* Return the ROTPK hash
|
||||
*
|
||||
* dst: buffer into which the ROTPK hash will be copied into
|
||||
* len: length of the provided buffer, which must be at least enough for a
|
||||
* SHA256 hash
|
||||
* flags: a pointer to integer that will be set to indicate the ROTPK status
|
||||
*
|
||||
* Return: 0 = success, Otherwise = error
|
||||
*/
|
||||
int cc_get_rotpk_hash(unsigned char *dst, unsigned int len, unsigned int *flags)
|
||||
{
|
||||
CCError_t error;
|
||||
uint32_t lcs;
|
||||
|
||||
assert(dst != NULL);
|
||||
assert(len >= HASH_RESULT_SIZE_IN_WORDS);
|
||||
assert(flags != NULL);
|
||||
|
||||
error = NVM_GetLCS(PLAT_CRYPTOCELL_BASE, &lcs);
|
||||
if (error != CC_OK)
|
||||
return 1;
|
||||
|
||||
/* If the lifecycle state is `SD`, return failure */
|
||||
if (lcs == CC_BSV_SECURITY_DISABLED_LCS)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* If the lifecycle state is `CM` or `DM`, ROTPK shouldn't be verified.
|
||||
* Return success after setting ROTPK_NOT_DEPLOYED flag
|
||||
*/
|
||||
if ((lcs == CC_BSV_CHIP_MANUFACTURE_LCS) ||
|
||||
(lcs == CC_BSV_DEVICE_MANUFACTURE_LCS)) {
|
||||
*flags = ROTPK_NOT_DEPLOYED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Copy the DER header */
|
||||
error = NVM_ReadHASHPubKey(PLAT_CRYPTOCELL_BASE,
|
||||
CC_SB_HASH_BOOT_KEY_256B,
|
||||
(uint32_t *)dst, HASH_RESULT_SIZE_IN_WORDS);
|
||||
if (error != CC_OK)
|
||||
return 1;
|
||||
|
||||
*flags = ROTPK_IS_HASH;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the non-volatile counter value stored in the platform. The cookie
|
||||
* specifies the OID of the counter in the certificate.
|
||||
*
|
||||
* Return: 0 = success, Otherwise = error
|
||||
*/
|
||||
int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
|
||||
{
|
||||
CCError_t error = CC_FAIL;
|
||||
|
||||
if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
|
||||
error = NVM_GetSwVersion(PLAT_CRYPTOCELL_BASE,
|
||||
CC_SW_VERSION_COUNTER1, nv_ctr);
|
||||
} else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
|
||||
error = NVM_GetSwVersion(PLAT_CRYPTOCELL_BASE,
|
||||
CC_SW_VERSION_COUNTER2, nv_ctr);
|
||||
}
|
||||
|
||||
return (error != CC_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Store a new non-volatile counter value in the counter specified by the OID
|
||||
* in the cookie. This function is not expected to be called if the Lifecycle
|
||||
* state is RMA as the values in the certificate are expected to always match
|
||||
* the nvcounter values. But if called when the LCS is RMA, the underlying
|
||||
* helper functions will return success but without updating the counter.
|
||||
*
|
||||
* Return: 0 = success, Otherwise = error
|
||||
*/
|
||||
int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
|
||||
{
|
||||
CCError_t error = CC_FAIL;
|
||||
|
||||
if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
|
||||
error = NVM_SetSwVersion(PLAT_CRYPTOCELL_BASE,
|
||||
CC_SW_VERSION_COUNTER1, nv_ctr);
|
||||
} else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
|
||||
error = NVM_SetSwVersion(PLAT_CRYPTOCELL_BASE,
|
||||
CC_SW_VERSION_COUNTER2, nv_ctr);
|
||||
}
|
||||
|
||||
return (error != CC_OK);
|
||||
}
|
||||
|
||||
+276
@@ -0,0 +1,276 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <drivers/arm/cryptocell/713/bsv_api.h>
|
||||
#include <drivers/arm/cryptocell/713/bsv_crypto_asym_api.h>
|
||||
#include <drivers/auth/crypto_mod.h>
|
||||
|
||||
#include <mbedtls/oid.h>
|
||||
#include <mbedtls/x509.h>
|
||||
|
||||
#define LIB_NAME "CryptoCell 713 SBROM"
|
||||
#define RSA_SALT_LEN 32
|
||||
#define RSA_EXPONENT 65537
|
||||
|
||||
/*
|
||||
* AlgorithmIdentifier ::= SEQUENCE {
|
||||
* algorithm OBJECT IDENTIFIER,
|
||||
* parameters ANY DEFINED BY algorithm OPTIONAL
|
||||
* }
|
||||
*
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING
|
||||
* }
|
||||
*
|
||||
* DigestInfo ::= SEQUENCE {
|
||||
* digestAlgorithm AlgorithmIdentifier,
|
||||
* digest OCTET STRING
|
||||
* }
|
||||
*
|
||||
* RSASSA-PSS-params ::= SEQUENCE {
|
||||
* hashAlgorithm [0] HashAlgorithm,
|
||||
* maskGenAlgorithm [1] MaskGenAlgorithm,
|
||||
* saltLength [2] INTEGER,
|
||||
* trailerField [3] TrailerField DEFAULT trailerFieldBC
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialize the library and export the descriptor
|
||||
*/
|
||||
static void init(void)
|
||||
{
|
||||
CCError_t ret;
|
||||
uint32_t lcs;
|
||||
|
||||
/* Initialize CC SBROM */
|
||||
ret = CC_BsvInit((uintptr_t)PLAT_CRYPTOCELL_BASE);
|
||||
if (ret != CC_OK) {
|
||||
ERROR("CryptoCell CC_BsvInit() error %x\n", ret);
|
||||
panic();
|
||||
}
|
||||
|
||||
/* Initialize lifecycle state */
|
||||
ret = CC_BsvGetAndInitLcs((uintptr_t)PLAT_CRYPTOCELL_BASE, &lcs);
|
||||
if (ret != CC_OK) {
|
||||
ERROR("CryptoCell CC_BsvGetAndInitLcs() error %x\n", ret);
|
||||
panic();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify a signature.
|
||||
*
|
||||
* Parameters are passed using the DER encoding format following the ASN.1
|
||||
* structures detailed above.
|
||||
*/
|
||||
static int verify_signature(void *data_ptr, unsigned int data_len,
|
||||
void *sig_ptr, unsigned int sig_len,
|
||||
void *sig_alg, unsigned int sig_alg_len,
|
||||
void *pk_ptr, unsigned int pk_len)
|
||||
{
|
||||
CCError_t error;
|
||||
CCBsvNBuff_t NBuff;
|
||||
CCBsvSignature_t signature;
|
||||
int rc, exp;
|
||||
mbedtls_asn1_buf sig_oid, alg_oid, params;
|
||||
mbedtls_md_type_t md_alg;
|
||||
mbedtls_pk_type_t pk_alg;
|
||||
mbedtls_pk_rsassa_pss_options pss_opts;
|
||||
size_t len;
|
||||
uint8_t *p, *end;
|
||||
CCHashResult_t digest;
|
||||
CCBool_t is_verified;
|
||||
/* This is a rather large array, we don't want it on stack */
|
||||
static uint32_t workspace[BSV_RSA_WORKSPACE_MIN_SIZE];
|
||||
|
||||
/* Verify the signature algorithm */
|
||||
/* Get pointers to signature OID and parameters */
|
||||
p = sig_alg;
|
||||
end = p + sig_alg_len;
|
||||
rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, ¶ms);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* Get the actual signature algorithm (MD + PK) */
|
||||
rc = mbedtls_oid_get_sig_alg(&sig_oid, &md_alg, &pk_alg);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* The CryptoCell only supports RSASSA-PSS signature */
|
||||
if (pk_alg != MBEDTLS_PK_RSASSA_PSS || md_alg != MBEDTLS_MD_NONE)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* Verify the RSASSA-PSS params */
|
||||
/* The trailer field is verified to be 0xBC internally by this API */
|
||||
rc = mbedtls_x509_get_rsassa_pss_params(¶ms, &md_alg,
|
||||
&pss_opts.mgf1_hash_id,
|
||||
&pss_opts.expected_salt_len);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* The CryptoCell only supports SHA256 as hash algorithm */
|
||||
if (md_alg != MBEDTLS_MD_SHA256 ||
|
||||
pss_opts.mgf1_hash_id != MBEDTLS_MD_SHA256)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (pss_opts.expected_salt_len != RSA_SALT_LEN)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* Parse the public key */
|
||||
p = pk_ptr;
|
||||
end = p + pk_len;
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
end = p + len;
|
||||
rc = mbedtls_asn1_get_alg_null(&p, end, &alg_oid);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (mbedtls_oid_get_pk_alg(&alg_oid, &pk_alg) != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (pk_alg != MBEDTLS_PK_RSA)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
rc = mbedtls_asn1_get_bitstring_null(&p, end, &len);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (*p == 0) {
|
||||
p++; len--;
|
||||
}
|
||||
if (len != BSV_CERT_RSA_KEY_SIZE_IN_BYTES || ((p + len) > end))
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/*
|
||||
* Copy N from certificate.
|
||||
*/
|
||||
memcpy(NBuff, p, BSV_CERT_RSA_KEY_SIZE_IN_BYTES);
|
||||
|
||||
/* Verify the RSA exponent */
|
||||
p += len;
|
||||
rc = mbedtls_asn1_get_int(&p, end, &exp);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (exp != RSA_EXPONENT)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* Get the signature (bitstring) */
|
||||
p = sig_ptr;
|
||||
end = p + sig_len;
|
||||
rc = mbedtls_asn1_get_bitstring_null(&p, end, &len);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
if (len != BSV_CERT_RSA_KEY_SIZE_IN_BYTES || ((p + len) > end))
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/*
|
||||
* Copy the signature (in BE format)
|
||||
*/
|
||||
memcpy((uint8_t *)signature, p, BSV_CERT_RSA_KEY_SIZE_IN_BYTES);
|
||||
|
||||
error = CC_BsvSha256((uintptr_t)PLAT_CRYPTOCELL_BASE,
|
||||
data_ptr, data_len, digest);
|
||||
if (error != CC_OK)
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* Verify the signature */
|
||||
error = CC_BsvRsaPssVerify((uintptr_t)PLAT_CRYPTOCELL_BASE, NBuff,
|
||||
NULL, signature, digest, workspace,
|
||||
BSV_RSA_WORKSPACE_MIN_SIZE, &is_verified);
|
||||
if ((error != CC_OK) || (is_verified != CC_TRUE))
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
|
||||
/* Signature verification success */
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Match a hash
|
||||
*
|
||||
* Digest info is passed in DER format following the ASN.1 structure detailed
|
||||
* above.
|
||||
*/
|
||||
static int verify_hash(void *data_ptr, unsigned int data_len,
|
||||
void *digest_info_ptr, unsigned int digest_info_len)
|
||||
{
|
||||
mbedtls_asn1_buf hash_oid, params;
|
||||
mbedtls_md_type_t md_alg;
|
||||
uint8_t *p, *end, *hash;
|
||||
CCHashResult_t pubKeyHash;
|
||||
size_t len;
|
||||
int rc;
|
||||
CCError_t error;
|
||||
|
||||
/* Digest info should be an MBEDTLS_ASN1_SEQUENCE */
|
||||
p = digest_info_ptr;
|
||||
end = p + digest_info_len;
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
/* Get the hash algorithm */
|
||||
rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_HASH;
|
||||
/* Verify that hash algorithm is SHA256 */
|
||||
if (md_alg != MBEDTLS_MD_SHA256)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
/* Hash should be octet string type */
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
/* Length of hash must match the algorithm's size */
|
||||
if (len != HASH_RESULT_SIZE_IN_BYTES)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
hash = p;
|
||||
error = CC_BsvSha256((uintptr_t)PLAT_CRYPTOCELL_BASE, data_ptr,
|
||||
data_len, pubKeyHash);
|
||||
if (error != CC_OK)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
rc = memcmp(pubKeyHash, hash, HASH_RESULT_SIZE_IN_BYTES);
|
||||
if (rc != 0)
|
||||
return CRYPTO_ERR_HASH;
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register crypto library descriptor
|
||||
*/
|
||||
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020 ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <plat/common/platform.h>
|
||||
#include <tools_share/tbbr_oid.h>
|
||||
|
||||
#include <lib/libc/endian.h>
|
||||
#include <drivers/arm/cryptocell/713/bsv_api.h>
|
||||
#include <drivers/arm/cryptocell/713/bsv_error.h>
|
||||
|
||||
/*
|
||||
* Return the ROTPK hash
|
||||
*
|
||||
* Return: 0 = success, Otherwise = error
|
||||
*/
|
||||
int cc_get_rotpk_hash(unsigned char *dst, unsigned int len, unsigned int *flags)
|
||||
{
|
||||
CCError_t error;
|
||||
uint32_t lcs;
|
||||
int i;
|
||||
uint32_t *key = (uint32_t *)dst;
|
||||
|
||||
assert(dst != NULL);
|
||||
assert(len >= HASH_RESULT_SIZE_IN_WORDS);
|
||||
assert(flags != NULL);
|
||||
|
||||
error = CC_BsvLcsGet(PLAT_CRYPTOCELL_BASE, &lcs);
|
||||
if (error != CC_OK)
|
||||
return 1;
|
||||
|
||||
if ((lcs == CC_BSV_CHIP_MANUFACTURE_LCS) || (lcs == CC_BSV_RMA_LCS)) {
|
||||
*flags = ROTPK_NOT_DEPLOYED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
error = CC_BsvPubKeyHashGet(PLAT_CRYPTOCELL_BASE,
|
||||
CC_SB_HASH_BOOT_KEY_256B,
|
||||
key, HASH_RESULT_SIZE_IN_WORDS);
|
||||
|
||||
if (error == CC_BSV_HASH_NOT_PROGRAMMED_ERR) {
|
||||
*flags = ROTPK_NOT_DEPLOYED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (error == CC_OK) {
|
||||
|
||||
/* Keys are stored in OTP in little-endian format */
|
||||
for (i = 0; i < HASH_RESULT_SIZE_IN_WORDS; i++)
|
||||
key[i] = le32toh(key[i]);
|
||||
|
||||
*flags = ROTPK_IS_HASH;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the non-volatile counter value stored in the platform. The cookie
|
||||
* specifies the OID of the counter in the certificate.
|
||||
*
|
||||
* Return: 0 = success, Otherwise = error
|
||||
*/
|
||||
int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
|
||||
{
|
||||
CCError_t error = CC_FAIL;
|
||||
|
||||
if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
|
||||
error = CC_BsvSwVersionGet(PLAT_CRYPTOCELL_BASE,
|
||||
CC_SW_VERSION_TRUSTED, nv_ctr);
|
||||
} else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
|
||||
error = CC_BsvSwVersionGet(PLAT_CRYPTOCELL_BASE,
|
||||
CC_SW_VERSION_NON_TRUSTED, nv_ctr);
|
||||
}
|
||||
|
||||
return (error != CC_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Store a new non-volatile counter value in the counter specified by the OID
|
||||
* in the cookie. This function is not expected to be called if the Lifecycle
|
||||
* state is RMA as the values in the certificate are expected to always match
|
||||
* the nvcounter values. But if called when the LCS is RMA, the underlying
|
||||
* helper functions will return success but without updating the counter.
|
||||
*
|
||||
* Return: 0 = success, Otherwise = error
|
||||
*/
|
||||
int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
|
||||
{
|
||||
CCError_t error = CC_FAIL;
|
||||
|
||||
if (strcmp(cookie, TRUSTED_FW_NVCOUNTER_OID) == 0) {
|
||||
error = CC_BsvSwVersionSet(PLAT_CRYPTOCELL_BASE,
|
||||
CC_SW_VERSION_TRUSTED, nv_ctr);
|
||||
} else if (strcmp(cookie, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
|
||||
error = CC_BsvSwVersionSet(PLAT_CRYPTOCELL_BASE,
|
||||
CC_SW_VERSION_NON_TRUSTED, nv_ctr);
|
||||
}
|
||||
|
||||
return (error != CC_OK);
|
||||
}
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
#
|
||||
# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
include drivers/auth/mbedtls/mbedtls_common.mk
|
||||
|
||||
# The algorithm is RSA when using Cryptocell crypto driver
|
||||
TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_RSA
|
||||
|
||||
# Needs to be set to drive mbed TLS configuration correctly
|
||||
$(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID))
|
||||
|
||||
$(eval $(call add_define,KEY_SIZE))
|
||||
|
||||
# CCSBROM_LIB_PATH must be set to the Cryptocell SBROM library path
|
||||
ifeq (${CCSBROM_LIB_PATH},)
|
||||
$(error Error: CCSBROM_LIB_PATH not set)
|
||||
endif
|
||||
|
||||
CRYPTOCELL_VERSION ?= 712
|
||||
ifeq (${CRYPTOCELL_VERSION},712)
|
||||
CCSBROM_LIB_FILENAME := cc_712sbromx509
|
||||
else ifeq (${CRYPTOCELL_VERSION},713)
|
||||
CCSBROM_LIB_FILENAME := cc_713bsv
|
||||
else
|
||||
$(error Error: CRYPTOCELL_VERSION set to invalid version)
|
||||
endif
|
||||
|
||||
CRYPTOCELL_SRC_DIR := drivers/auth/cryptocell/${CRYPTOCELL_VERSION}/
|
||||
|
||||
CRYPTOCELL_SOURCES := ${CRYPTOCELL_SRC_DIR}/cryptocell_crypto.c \
|
||||
${CRYPTOCELL_SRC_DIR}/cryptocell_plat_helpers.c
|
||||
|
||||
TF_LDFLAGS += -L$(CCSBROM_LIB_PATH)
|
||||
LDLIBS += -l$(CCSBROM_LIB_FILENAME)
|
||||
|
||||
BL1_SOURCES += ${CRYPTOCELL_SOURCES}
|
||||
BL2_SOURCES += ${CRYPTOCELL_SOURCES}
|
||||
@@ -0,0 +1,959 @@
|
||||
/*
|
||||
* Copyright (c) 2020-2022, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#include <drivers/auth/auth_mod.h>
|
||||
#include <tools_share/dualroot_oid.h>
|
||||
|
||||
/*
|
||||
* Allocate static buffers to store the authentication parameters extracted from
|
||||
* the certificates.
|
||||
*/
|
||||
static unsigned char fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tb_fw_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char hw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char scp_fw_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
|
||||
|
||||
#ifdef IMAGE_BL2
|
||||
static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
|
||||
#if defined(SPD_spmd)
|
||||
static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
|
||||
#endif /* SPD_spmd */
|
||||
|
||||
static unsigned char trusted_world_pk_buf[PK_DER_LEN];
|
||||
static unsigned char content_pk_buf[PK_DER_LEN];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Parameter type descriptors.
|
||||
*/
|
||||
static auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
|
||||
static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, 0);
|
||||
static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_SIG, 0);
|
||||
static auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_SIG_ALG, 0);
|
||||
static auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_RAW_DATA, 0);
|
||||
|
||||
static auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
|
||||
static auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
|
||||
#ifdef IMAGE_BL1
|
||||
static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
|
||||
static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
|
||||
static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, FWU_HASH_OID);
|
||||
#endif /* IMAGE_BL1 */
|
||||
|
||||
#ifdef IMAGE_BL2
|
||||
static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
|
||||
|
||||
static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID);
|
||||
static auth_param_type_desc_t scp_fw_content_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID);
|
||||
static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID);
|
||||
static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID);
|
||||
static auth_param_type_desc_t prot_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, PROT_PK_OID);
|
||||
|
||||
static auth_param_type_desc_t scp_fw_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SCP_FW_HASH_OID);
|
||||
static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID);
|
||||
static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID);
|
||||
static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t tos_fw_extra1_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA1_HASH_OID);
|
||||
static auth_param_type_desc_t tos_fw_extra2_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA2_HASH_OID);
|
||||
static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
|
||||
static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
|
||||
#if defined(SPD_spmd)
|
||||
static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
|
||||
#endif /* SPD_spmd */
|
||||
#endif /* IMAGE_BL2 */
|
||||
|
||||
|
||||
/* BL2 */
|
||||
static const auth_img_desc_t trusted_boot_fw_cert = {
|
||||
.img_id = TRUSTED_BOOT_FW_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &subject_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &tb_fw_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tb_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &tb_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tb_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &hw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)hw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[3] = {
|
||||
.type_desc = &fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef IMAGE_BL1
|
||||
static const auth_img_desc_t bl2_image = {
|
||||
.img_id = BL2_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_boot_fw_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tb_fw_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif /* IMAGE_BL1 */
|
||||
|
||||
/* HW Config */
|
||||
static const auth_img_desc_t hw_config = {
|
||||
.img_id = HW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_boot_fw_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &hw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* TB FW Config */
|
||||
#ifdef IMAGE_BL1
|
||||
static const auth_img_desc_t tb_fw_config = {
|
||||
.img_id = TB_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_boot_fw_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tb_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t fw_config = {
|
||||
.img_id = FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_boot_fw_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* IMAGE_BL1 */
|
||||
|
||||
#ifdef IMAGE_BL2
|
||||
/* Trusted key certificate */
|
||||
static const auth_img_desc_t trusted_key_cert = {
|
||||
.img_id = TRUSTED_KEY_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &subject_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &trusted_world_pk,
|
||||
.data = {
|
||||
.ptr = (void *)trusted_world_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
/* SCP Firmware */
|
||||
static const auth_img_desc_t scp_fw_key_cert = {
|
||||
.img_id = SCP_FW_KEY_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &trusted_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &trusted_world_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &scp_fw_content_pk,
|
||||
.data = {
|
||||
.ptr = (void *)content_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t scp_fw_content_cert = {
|
||||
.img_id = SCP_FW_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &scp_fw_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &scp_fw_content_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &scp_fw_hash,
|
||||
.data = {
|
||||
.ptr = (void *)scp_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t scp_bl2_image = {
|
||||
.img_id = SCP_BL2_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &scp_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &scp_fw_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* SoC Firmware */
|
||||
static const auth_img_desc_t soc_fw_key_cert = {
|
||||
.img_id = SOC_FW_KEY_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &trusted_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &trusted_world_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &soc_fw_content_pk,
|
||||
.data = {
|
||||
.ptr = (void *)content_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t soc_fw_content_cert = {
|
||||
.img_id = SOC_FW_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &soc_fw_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &soc_fw_content_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &soc_fw_hash,
|
||||
.data = {
|
||||
.ptr = (void *)soc_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &soc_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)soc_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t bl31_image = {
|
||||
.img_id = BL31_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &soc_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &soc_fw_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* SOC FW Config */
|
||||
static const auth_img_desc_t soc_fw_config = {
|
||||
.img_id = SOC_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &soc_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &soc_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Trusted OS Firmware */
|
||||
static const auth_img_desc_t trusted_os_fw_key_cert = {
|
||||
.img_id = TRUSTED_OS_FW_KEY_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &trusted_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &trusted_world_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &tos_fw_content_pk,
|
||||
.data = {
|
||||
.ptr = (void *)content_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t trusted_os_fw_content_cert = {
|
||||
.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &trusted_os_fw_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &tos_fw_content_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &tos_fw_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tos_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &tos_fw_extra1_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tos_fw_extra1_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &tos_fw_extra2_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tos_fw_extra2_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[3] = {
|
||||
.type_desc = &tos_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tos_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t bl32_image = {
|
||||
.img_id = BL32_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_os_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tos_fw_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t bl32_extra1_image = {
|
||||
.img_id = BL32_EXTRA1_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_os_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tos_fw_extra1_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t bl32_extra2_image = {
|
||||
.img_id = BL32_EXTRA2_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_os_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tos_fw_extra2_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* TOS FW Config */
|
||||
static const auth_img_desc_t tos_fw_config = {
|
||||
.img_id = TOS_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_os_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tos_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* Non-Trusted Firmware */
|
||||
static const auth_img_desc_t non_trusted_fw_content_cert = {
|
||||
.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL, /* Root certificate. */
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &prot_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &non_trusted_nv_ctr,
|
||||
.plat_nv_ctr = &non_trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &nt_world_bl_hash,
|
||||
.data = {
|
||||
.ptr = (void *)nt_world_bl_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &nt_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)nt_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t bl33_image = {
|
||||
.img_id = BL33_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &non_trusted_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &nt_world_bl_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* NT FW Config */
|
||||
static const auth_img_desc_t nt_fw_config = {
|
||||
.img_id = NT_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &non_trusted_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &nt_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Secure Partitions
|
||||
*/
|
||||
#if defined(SPD_spmd)
|
||||
static const auth_img_desc_t sip_sp_content_cert = {
|
||||
.img_id = SIP_SP_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &trusted_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &trusted_world_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &sp_pkg1_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[0],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &sp_pkg2_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[1],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &sp_pkg3_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[2],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[3] = {
|
||||
.type_desc = &sp_pkg4_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[3],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DEFINE_SIP_SP_PKG(1);
|
||||
DEFINE_SIP_SP_PKG(2);
|
||||
DEFINE_SIP_SP_PKG(3);
|
||||
DEFINE_SIP_SP_PKG(4);
|
||||
|
||||
static const auth_img_desc_t plat_sp_content_cert = {
|
||||
.img_id = PLAT_SP_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &prot_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &non_trusted_nv_ctr,
|
||||
.plat_nv_ctr = &non_trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &sp_pkg5_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[4],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &sp_pkg6_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[5],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &sp_pkg7_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[6],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[3] = {
|
||||
.type_desc = &sp_pkg8_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[7],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DEFINE_PLAT_SP_PKG(5);
|
||||
DEFINE_PLAT_SP_PKG(6);
|
||||
DEFINE_PLAT_SP_PKG(7);
|
||||
DEFINE_PLAT_SP_PKG(8);
|
||||
#endif /* SPD_spmd */
|
||||
|
||||
#else /* IMAGE_BL2 */
|
||||
|
||||
/* FWU auth descriptor */
|
||||
static const auth_img_desc_t fwu_cert = {
|
||||
.img_id = FWU_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &subject_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &scp_bl2u_hash,
|
||||
.data = {
|
||||
.ptr = (void *)scp_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &bl2u_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tb_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &ns_bl2u_hash,
|
||||
.data = {
|
||||
.ptr = (void *)nt_world_bl_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* SCP_BL2U */
|
||||
static const auth_img_desc_t scp_bl2u_image = {
|
||||
.img_id = SCP_BL2U_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &fwu_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &scp_bl2u_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* BL2U */
|
||||
static const auth_img_desc_t bl2u_image = {
|
||||
.img_id = BL2U_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &fwu_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &bl2u_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* NS_BL2U */
|
||||
static const auth_img_desc_t ns_bl2u_image = {
|
||||
.img_id = NS_BL2U_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &fwu_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &ns_bl2u_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif /* IMAGE_BL2 */
|
||||
|
||||
/*
|
||||
* Chain of trust definition
|
||||
*/
|
||||
#ifdef IMAGE_BL1
|
||||
static const auth_img_desc_t * const cot_desc[] = {
|
||||
[TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert,
|
||||
[BL2_IMAGE_ID] = &bl2_image,
|
||||
[HW_CONFIG_ID] = &hw_config,
|
||||
[TB_FW_CONFIG_ID] = &tb_fw_config,
|
||||
[FW_CONFIG_ID] = &fw_config,
|
||||
[FWU_CERT_ID] = &fwu_cert,
|
||||
[SCP_BL2U_IMAGE_ID] = &scp_bl2u_image,
|
||||
[BL2U_IMAGE_ID] = &bl2u_image,
|
||||
[NS_BL2U_IMAGE_ID] = &ns_bl2u_image
|
||||
};
|
||||
#else /* IMAGE_BL2 */
|
||||
static const auth_img_desc_t * const cot_desc[] = {
|
||||
[TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert,
|
||||
[HW_CONFIG_ID] = &hw_config,
|
||||
[TRUSTED_KEY_CERT_ID] = &trusted_key_cert,
|
||||
[SCP_FW_KEY_CERT_ID] = &scp_fw_key_cert,
|
||||
[SCP_FW_CONTENT_CERT_ID] = &scp_fw_content_cert,
|
||||
[SCP_BL2_IMAGE_ID] = &scp_bl2_image,
|
||||
[SOC_FW_KEY_CERT_ID] = &soc_fw_key_cert,
|
||||
[SOC_FW_CONTENT_CERT_ID] = &soc_fw_content_cert,
|
||||
[BL31_IMAGE_ID] = &bl31_image,
|
||||
[SOC_FW_CONFIG_ID] = &soc_fw_config,
|
||||
[TRUSTED_OS_FW_KEY_CERT_ID] = &trusted_os_fw_key_cert,
|
||||
[TRUSTED_OS_FW_CONTENT_CERT_ID] = &trusted_os_fw_content_cert,
|
||||
[BL32_IMAGE_ID] = &bl32_image,
|
||||
[BL32_EXTRA1_IMAGE_ID] = &bl32_extra1_image,
|
||||
[BL32_EXTRA2_IMAGE_ID] = &bl32_extra2_image,
|
||||
[TOS_FW_CONFIG_ID] = &tos_fw_config,
|
||||
[NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert,
|
||||
[BL33_IMAGE_ID] = &bl33_image,
|
||||
[NT_FW_CONFIG_ID] = &nt_fw_config,
|
||||
#if defined(SPD_spmd)
|
||||
[SIP_SP_CONTENT_CERT_ID] = &sip_sp_content_cert,
|
||||
[PLAT_SP_CONTENT_CERT_ID] = &plat_sp_content_cert,
|
||||
[SP_PKG1_ID] = &sp_pkg1,
|
||||
[SP_PKG2_ID] = &sp_pkg2,
|
||||
[SP_PKG3_ID] = &sp_pkg3,
|
||||
[SP_PKG4_ID] = &sp_pkg4,
|
||||
[SP_PKG5_ID] = &sp_pkg5,
|
||||
[SP_PKG6_ID] = &sp_pkg6,
|
||||
[SP_PKG7_ID] = &sp_pkg7,
|
||||
[SP_PKG8_ID] = &sp_pkg8,
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
||||
/* Register the CoT in the authentication module */
|
||||
REGISTER_COT(cot_desc);
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/auth/auth_common.h>
|
||||
#include <drivers/auth/img_parser_mod.h>
|
||||
#include <lib/utils_def.h>
|
||||
|
||||
IMPORT_SYM(uintptr_t, __PARSER_LIB_DESCS_START__, PARSER_LIB_DESCS_START);
|
||||
IMPORT_SYM(uintptr_t, __PARSER_LIB_DESCS_END__, PARSER_LIB_DESCS_END);
|
||||
static unsigned int parser_lib_indices[IMG_MAX_TYPES];
|
||||
static img_parser_lib_desc_t *parser_lib_descs;
|
||||
|
||||
#define INVALID_IDX UINT_MAX
|
||||
|
||||
static void validate_desc(img_parser_lib_desc_t *desc)
|
||||
{
|
||||
assert(desc != NULL);
|
||||
assert(desc->init != NULL);
|
||||
assert(desc->name != NULL);
|
||||
assert(desc->check_integrity != NULL);
|
||||
assert(desc->get_auth_param != NULL);
|
||||
}
|
||||
|
||||
void img_parser_init(void)
|
||||
{
|
||||
unsigned int index, mod_num;
|
||||
|
||||
/* Initialise internal variables to invalid state */
|
||||
for (index = 0; index < IMG_MAX_TYPES; index++) {
|
||||
parser_lib_indices[index] = INVALID_IDX;
|
||||
}
|
||||
|
||||
/* Calculate how many image parsers are registered. At least one parser
|
||||
* must be present */
|
||||
mod_num = PARSER_LIB_DESCS_END - PARSER_LIB_DESCS_START;
|
||||
mod_num /= sizeof(img_parser_lib_desc_t);
|
||||
assert(mod_num > 0);
|
||||
|
||||
parser_lib_descs = (img_parser_lib_desc_t *) PARSER_LIB_DESCS_START;
|
||||
for (index = 0; index < mod_num; index++) {
|
||||
|
||||
/* Check that the image parser library descriptor is valid */
|
||||
validate_desc(&parser_lib_descs[index]);
|
||||
|
||||
/* Initialize image parser */
|
||||
parser_lib_descs[index].init();
|
||||
|
||||
/* Ensure only one parser is registered for each image type */
|
||||
assert(parser_lib_indices[parser_lib_descs[index].img_type] ==
|
||||
INVALID_IDX);
|
||||
|
||||
/* Keep the index of this hash calculator */
|
||||
parser_lib_indices[parser_lib_descs[index].img_type] = index;
|
||||
}
|
||||
}
|
||||
|
||||
int img_parser_check_integrity(img_type_t img_type,
|
||||
void *img_ptr, unsigned int img_len)
|
||||
{
|
||||
unsigned int idx;
|
||||
|
||||
assert(img_ptr != NULL);
|
||||
assert(img_len != 0);
|
||||
|
||||
/* No integrity checks on raw images */
|
||||
if (img_type == IMG_RAW) {
|
||||
return IMG_PARSER_OK;
|
||||
}
|
||||
|
||||
/* Find the index of the required image parser */
|
||||
idx = parser_lib_indices[img_type];
|
||||
assert(idx != INVALID_IDX);
|
||||
|
||||
/* Call the function to check the image integrity */
|
||||
return parser_lib_descs[idx].check_integrity(img_ptr, img_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract an authentication parameter from an image
|
||||
*
|
||||
* Parameters:
|
||||
* img_type: image type (certificate, raw image, etc)
|
||||
* type_desc: provides info to obtain the parameter
|
||||
* img_ptr: pointer to image data
|
||||
* img_len: image length
|
||||
* param_ptr: [out] stores a pointer to the parameter
|
||||
* param_len: [out] stores the length of the parameter
|
||||
*/
|
||||
int img_parser_get_auth_param(img_type_t img_type,
|
||||
const auth_param_type_desc_t *type_desc,
|
||||
void *img_ptr, unsigned int img_len,
|
||||
void **param_ptr, unsigned int *param_len)
|
||||
{
|
||||
unsigned int idx;
|
||||
|
||||
assert(type_desc != NULL);
|
||||
assert(img_ptr != NULL);
|
||||
assert(img_len != 0);
|
||||
assert(param_ptr != NULL);
|
||||
assert(param_len != NULL);
|
||||
|
||||
/* In a raw image we can only get the data itself */
|
||||
if (img_type == IMG_RAW) {
|
||||
assert(type_desc->type == AUTH_PARAM_RAW_DATA);
|
||||
*param_ptr = img_ptr;
|
||||
*param_len = img_len;
|
||||
return IMG_PARSER_OK;
|
||||
}
|
||||
|
||||
/* Find the index of the required image parser library */
|
||||
idx = parser_lib_indices[img_type];
|
||||
assert(idx != INVALID_IDX);
|
||||
|
||||
/* Call the function to obtain the parameter */
|
||||
return parser_lib_descs[idx].get_auth_param(type_desc, img_ptr, img_len,
|
||||
param_ptr, param_len);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* mbed TLS headers */
|
||||
#include <mbedtls/memory_buffer_alloc.h>
|
||||
#include <mbedtls/platform.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/auth/mbedtls/mbedtls_common.h>
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
static void cleanup(void)
|
||||
{
|
||||
ERROR("EXIT from BL2\n");
|
||||
panic();
|
||||
}
|
||||
|
||||
/*
|
||||
* mbed TLS initialization function
|
||||
*/
|
||||
void mbedtls_init(void)
|
||||
{
|
||||
static int ready;
|
||||
void *heap_addr;
|
||||
size_t heap_size = 0;
|
||||
int err;
|
||||
|
||||
if (!ready) {
|
||||
if (atexit(cleanup))
|
||||
panic();
|
||||
|
||||
err = plat_get_mbedtls_heap(&heap_addr, &heap_size);
|
||||
|
||||
/* Ensure heap setup is proper */
|
||||
if (err < 0) {
|
||||
ERROR("Mbed TLS failed to get a heap\n");
|
||||
panic();
|
||||
}
|
||||
assert(heap_size >= TF_MBEDTLS_HEAP_SIZE);
|
||||
|
||||
/* Initialize the mbed TLS heap */
|
||||
mbedtls_memory_buffer_alloc_init(heap_addr, heap_size);
|
||||
|
||||
#ifdef MBEDTLS_PLATFORM_SNPRINTF_ALT
|
||||
mbedtls_platform_set_snprintf(snprintf);
|
||||
#endif
|
||||
ready = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The following helper function simply returns the default allocated heap.
|
||||
* It can be used by platforms for their plat_get_mbedtls_heap() implementation.
|
||||
*/
|
||||
int get_mbedtls_heap_helper(void **heap_addr, size_t *heap_size)
|
||||
{
|
||||
static unsigned char heap[TF_MBEDTLS_HEAP_SIZE];
|
||||
|
||||
assert(heap_addr != NULL);
|
||||
assert(heap_size != NULL);
|
||||
|
||||
*heap_addr = heap;
|
||||
*heap_size = sizeof(heap);
|
||||
return 0;
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
#
|
||||
# Copyright (c) 2015-2022, Arm Limited. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
ifneq (${MBEDTLS_COMMON_MK},1)
|
||||
MBEDTLS_COMMON_MK := 1
|
||||
|
||||
# MBEDTLS_DIR must be set to the mbed TLS main directory (it must contain
|
||||
# the 'include' and 'library' subdirectories).
|
||||
ifeq (${MBEDTLS_DIR},)
|
||||
$(error Error: MBEDTLS_DIR not set)
|
||||
endif
|
||||
|
||||
MBEDTLS_INC = -I${MBEDTLS_DIR}/include
|
||||
|
||||
# Specify mbed TLS configuration file
|
||||
MBEDTLS_CONFIG_FILE ?= "<drivers/auth/mbedtls/mbedtls_config.h>"
|
||||
$(eval $(call add_define,MBEDTLS_CONFIG_FILE))
|
||||
|
||||
MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_common.c
|
||||
|
||||
|
||||
LIBMBEDTLS_SRCS := $(addprefix ${MBEDTLS_DIR}/library/, \
|
||||
aes.c \
|
||||
asn1parse.c \
|
||||
asn1write.c \
|
||||
cipher.c \
|
||||
cipher_wrap.c \
|
||||
memory_buffer_alloc.c \
|
||||
oid.c \
|
||||
platform.c \
|
||||
platform_util.c \
|
||||
bignum.c \
|
||||
gcm.c \
|
||||
md.c \
|
||||
pk.c \
|
||||
pk_wrap.c \
|
||||
pkparse.c \
|
||||
pkwrite.c \
|
||||
sha256.c \
|
||||
sha512.c \
|
||||
ecdsa.c \
|
||||
ecp_curves.c \
|
||||
ecp.c \
|
||||
rsa.c \
|
||||
rsa_internal.c \
|
||||
x509.c \
|
||||
x509_crt.c \
|
||||
constant_time.c \
|
||||
)
|
||||
|
||||
# The platform may define the variable 'TF_MBEDTLS_KEY_ALG' to select the key
|
||||
# algorithm to use. If the variable is not defined, select it based on
|
||||
# algorithm used for key generation `KEY_ALG`. If `KEY_ALG` is not defined,
|
||||
# then it is set to `rsa`.
|
||||
ifeq (${TF_MBEDTLS_KEY_ALG},)
|
||||
ifeq (${KEY_ALG}, ecdsa)
|
||||
TF_MBEDTLS_KEY_ALG := ecdsa
|
||||
else
|
||||
TF_MBEDTLS_KEY_ALG := rsa
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (${TF_MBEDTLS_KEY_SIZE},)
|
||||
ifneq ($(findstring rsa,${TF_MBEDTLS_KEY_ALG}),)
|
||||
ifeq (${KEY_SIZE},)
|
||||
TF_MBEDTLS_KEY_SIZE := 2048
|
||||
else
|
||||
TF_MBEDTLS_KEY_SIZE := ${KEY_SIZE}
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (${HASH_ALG}, sha384)
|
||||
TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA384
|
||||
else ifeq (${HASH_ALG}, sha512)
|
||||
TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512
|
||||
else
|
||||
TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA256
|
||||
endif
|
||||
|
||||
ifeq (${TF_MBEDTLS_KEY_ALG},ecdsa)
|
||||
TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_ECDSA
|
||||
else ifeq (${TF_MBEDTLS_KEY_ALG},rsa)
|
||||
TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_RSA
|
||||
else ifeq (${TF_MBEDTLS_KEY_ALG},rsa+ecdsa)
|
||||
TF_MBEDTLS_KEY_ALG_ID := TF_MBEDTLS_RSA_AND_ECDSA
|
||||
else
|
||||
$(error "TF_MBEDTLS_KEY_ALG=${TF_MBEDTLS_KEY_ALG} not supported on mbed TLS")
|
||||
endif
|
||||
|
||||
ifeq (${DECRYPTION_SUPPORT}, aes_gcm)
|
||||
TF_MBEDTLS_USE_AES_GCM := 1
|
||||
else
|
||||
TF_MBEDTLS_USE_AES_GCM := 0
|
||||
endif
|
||||
|
||||
# Needs to be set to drive mbed TLS configuration correctly
|
||||
$(eval $(call add_defines,\
|
||||
$(sort \
|
||||
TF_MBEDTLS_KEY_ALG_ID \
|
||||
TF_MBEDTLS_KEY_SIZE \
|
||||
TF_MBEDTLS_HASH_ALG_ID \
|
||||
TF_MBEDTLS_USE_AES_GCM \
|
||||
)))
|
||||
|
||||
$(eval $(call MAKE_LIB,mbedtls))
|
||||
|
||||
endif
|
||||
@@ -0,0 +1,394 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
/* mbed TLS headers */
|
||||
#include <mbedtls/gcm.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/memory_buffer_alloc.h>
|
||||
#include <mbedtls/oid.h>
|
||||
#include <mbedtls/platform.h>
|
||||
#include <mbedtls/x509.h>
|
||||
|
||||
#include <common/debug.h>
|
||||
#include <drivers/auth/crypto_mod.h>
|
||||
#include <drivers/auth/mbedtls/mbedtls_common.h>
|
||||
#include <drivers/auth/mbedtls/mbedtls_config.h>
|
||||
#include <plat/common/platform.h>
|
||||
|
||||
#define LIB_NAME "mbed TLS"
|
||||
|
||||
#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
|
||||
/*
|
||||
* CRYPTO_MD_MAX_SIZE value is as per current stronger algorithm available
|
||||
* so make sure that mbed TLS MD maximum size must be lesser than this.
|
||||
*/
|
||||
CASSERT(CRYPTO_MD_MAX_SIZE >= MBEDTLS_MD_MAX_SIZE,
|
||||
assert_mbedtls_md_size_overflow);
|
||||
|
||||
#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
|
||||
|
||||
/*
|
||||
* AlgorithmIdentifier ::= SEQUENCE {
|
||||
* algorithm OBJECT IDENTIFIER,
|
||||
* parameters ANY DEFINED BY algorithm OPTIONAL
|
||||
* }
|
||||
*
|
||||
* SubjectPublicKeyInfo ::= SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING
|
||||
* }
|
||||
*
|
||||
* DigestInfo ::= SEQUENCE {
|
||||
* digestAlgorithm AlgorithmIdentifier,
|
||||
* digest OCTET STRING
|
||||
* }
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialize the library and export the descriptor
|
||||
*/
|
||||
static void init(void)
|
||||
{
|
||||
/* Initialize mbed TLS */
|
||||
mbedtls_init();
|
||||
}
|
||||
|
||||
#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
|
||||
/*
|
||||
* Verify a signature.
|
||||
*
|
||||
* Parameters are passed using the DER encoding format following the ASN.1
|
||||
* structures detailed above.
|
||||
*/
|
||||
static int verify_signature(void *data_ptr, unsigned int data_len,
|
||||
void *sig_ptr, unsigned int sig_len,
|
||||
void *sig_alg, unsigned int sig_alg_len,
|
||||
void *pk_ptr, unsigned int pk_len)
|
||||
{
|
||||
mbedtls_asn1_buf sig_oid, sig_params;
|
||||
mbedtls_asn1_buf signature;
|
||||
mbedtls_md_type_t md_alg;
|
||||
mbedtls_pk_type_t pk_alg;
|
||||
mbedtls_pk_context pk = {0};
|
||||
int rc;
|
||||
void *sig_opts = NULL;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
unsigned char *p, *end;
|
||||
unsigned char hash[MBEDTLS_MD_MAX_SIZE];
|
||||
|
||||
/* Get pointers to signature OID and parameters */
|
||||
p = (unsigned char *)sig_alg;
|
||||
end = (unsigned char *)(p + sig_alg_len);
|
||||
rc = mbedtls_asn1_get_alg(&p, end, &sig_oid, &sig_params);
|
||||
if (rc != 0) {
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
}
|
||||
|
||||
/* Get the actual signature algorithm (MD + PK) */
|
||||
rc = mbedtls_x509_get_sig_alg(&sig_oid, &sig_params, &md_alg, &pk_alg, &sig_opts);
|
||||
if (rc != 0) {
|
||||
return CRYPTO_ERR_SIGNATURE;
|
||||
}
|
||||
|
||||
/* Parse the public key */
|
||||
mbedtls_pk_init(&pk);
|
||||
p = (unsigned char *)pk_ptr;
|
||||
end = (unsigned char *)(p + pk_len);
|
||||
rc = mbedtls_pk_parse_subpubkey(&p, end, &pk);
|
||||
if (rc != 0) {
|
||||
rc = CRYPTO_ERR_SIGNATURE;
|
||||
goto end2;
|
||||
}
|
||||
|
||||
/* Get the signature (bitstring) */
|
||||
p = (unsigned char *)sig_ptr;
|
||||
end = (unsigned char *)(p + sig_len);
|
||||
signature.tag = *p;
|
||||
rc = mbedtls_asn1_get_bitstring_null(&p, end, &signature.len);
|
||||
if (rc != 0) {
|
||||
rc = CRYPTO_ERR_SIGNATURE;
|
||||
goto end1;
|
||||
}
|
||||
signature.p = p;
|
||||
|
||||
/* Calculate the hash of the data */
|
||||
md_info = mbedtls_md_info_from_type(md_alg);
|
||||
if (md_info == NULL) {
|
||||
rc = CRYPTO_ERR_SIGNATURE;
|
||||
goto end1;
|
||||
}
|
||||
p = (unsigned char *)data_ptr;
|
||||
rc = mbedtls_md(md_info, p, data_len, hash);
|
||||
if (rc != 0) {
|
||||
rc = CRYPTO_ERR_SIGNATURE;
|
||||
goto end1;
|
||||
}
|
||||
|
||||
/* Verify the signature */
|
||||
rc = mbedtls_pk_verify_ext(pk_alg, sig_opts, &pk, md_alg, hash,
|
||||
mbedtls_md_get_size(md_info),
|
||||
signature.p, signature.len);
|
||||
if (rc != 0) {
|
||||
rc = CRYPTO_ERR_SIGNATURE;
|
||||
goto end1;
|
||||
}
|
||||
|
||||
/* Signature verification success */
|
||||
rc = CRYPTO_SUCCESS;
|
||||
|
||||
end1:
|
||||
mbedtls_pk_free(&pk);
|
||||
end2:
|
||||
mbedtls_free(sig_opts);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Match a hash
|
||||
*
|
||||
* Digest info is passed in DER format following the ASN.1 structure detailed
|
||||
* above.
|
||||
*/
|
||||
static int verify_hash(void *data_ptr, unsigned int data_len,
|
||||
void *digest_info_ptr, unsigned int digest_info_len)
|
||||
{
|
||||
mbedtls_asn1_buf hash_oid, params;
|
||||
mbedtls_md_type_t md_alg;
|
||||
const mbedtls_md_info_t *md_info;
|
||||
unsigned char *p, *end, *hash;
|
||||
unsigned char data_hash[MBEDTLS_MD_MAX_SIZE];
|
||||
size_t len;
|
||||
int rc;
|
||||
|
||||
/* Digest info should be an MBEDTLS_ASN1_SEQUENCE */
|
||||
p = (unsigned char *)digest_info_ptr;
|
||||
end = p + digest_info_len;
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (rc != 0) {
|
||||
return CRYPTO_ERR_HASH;
|
||||
}
|
||||
|
||||
/* Get the hash algorithm */
|
||||
rc = mbedtls_asn1_get_alg(&p, end, &hash_oid, ¶ms);
|
||||
if (rc != 0) {
|
||||
return CRYPTO_ERR_HASH;
|
||||
}
|
||||
|
||||
rc = mbedtls_oid_get_md_alg(&hash_oid, &md_alg);
|
||||
if (rc != 0) {
|
||||
return CRYPTO_ERR_HASH;
|
||||
}
|
||||
|
||||
md_info = mbedtls_md_info_from_type(md_alg);
|
||||
if (md_info == NULL) {
|
||||
return CRYPTO_ERR_HASH;
|
||||
}
|
||||
|
||||
/* Hash should be octet string type */
|
||||
rc = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_OCTET_STRING);
|
||||
if (rc != 0) {
|
||||
return CRYPTO_ERR_HASH;
|
||||
}
|
||||
|
||||
/* Length of hash must match the algorithm's size */
|
||||
if (len != mbedtls_md_get_size(md_info)) {
|
||||
return CRYPTO_ERR_HASH;
|
||||
}
|
||||
hash = p;
|
||||
|
||||
/* Calculate the hash of the data */
|
||||
p = (unsigned char *)data_ptr;
|
||||
rc = mbedtls_md(md_info, p, data_len, data_hash);
|
||||
if (rc != 0) {
|
||||
return CRYPTO_ERR_HASH;
|
||||
}
|
||||
|
||||
/* Compare values */
|
||||
rc = memcmp(data_hash, hash, mbedtls_md_get_size(md_info));
|
||||
if (rc != 0) {
|
||||
return CRYPTO_ERR_HASH;
|
||||
}
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
|
||||
|
||||
#if CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
|
||||
/*
|
||||
* Map a generic crypto message digest algorithm to the corresponding macro used
|
||||
* by Mbed TLS.
|
||||
*/
|
||||
static inline mbedtls_md_type_t md_type(enum crypto_md_algo algo)
|
||||
{
|
||||
switch (algo) {
|
||||
case CRYPTO_MD_SHA512:
|
||||
return MBEDTLS_MD_SHA512;
|
||||
case CRYPTO_MD_SHA384:
|
||||
return MBEDTLS_MD_SHA384;
|
||||
case CRYPTO_MD_SHA256:
|
||||
return MBEDTLS_MD_SHA256;
|
||||
default:
|
||||
/* Invalid hash algorithm. */
|
||||
return MBEDTLS_MD_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate a hash
|
||||
*
|
||||
* output points to the computed hash
|
||||
*/
|
||||
static int calc_hash(enum crypto_md_algo md_algo, void *data_ptr,
|
||||
unsigned int data_len,
|
||||
unsigned char output[CRYPTO_MD_MAX_SIZE])
|
||||
{
|
||||
const mbedtls_md_info_t *md_info;
|
||||
|
||||
md_info = mbedtls_md_info_from_type(md_type(md_algo));
|
||||
if (md_info == NULL) {
|
||||
return CRYPTO_ERR_HASH;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the hash of the data, it is safe to pass the
|
||||
* 'output' hash buffer pointer considering its size is always
|
||||
* bigger than or equal to MBEDTLS_MD_MAX_SIZE.
|
||||
*/
|
||||
return mbedtls_md(md_info, data_ptr, data_len, output);
|
||||
}
|
||||
#endif /* CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY || \
|
||||
CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
|
||||
|
||||
#if TF_MBEDTLS_USE_AES_GCM
|
||||
/*
|
||||
* Stack based buffer allocation for decryption operation. It could
|
||||
* be configured to balance stack usage vs execution speed.
|
||||
*/
|
||||
#define DEC_OP_BUF_SIZE 128
|
||||
|
||||
static int aes_gcm_decrypt(void *data_ptr, size_t len, const void *key,
|
||||
unsigned int key_len, const void *iv,
|
||||
unsigned int iv_len, const void *tag,
|
||||
unsigned int tag_len)
|
||||
{
|
||||
mbedtls_gcm_context ctx;
|
||||
mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES;
|
||||
unsigned char buf[DEC_OP_BUF_SIZE];
|
||||
unsigned char tag_buf[CRYPTO_MAX_TAG_SIZE];
|
||||
unsigned char *pt = data_ptr;
|
||||
size_t dec_len;
|
||||
int diff, i, rc;
|
||||
|
||||
mbedtls_gcm_init(&ctx);
|
||||
|
||||
rc = mbedtls_gcm_setkey(&ctx, cipher, key, key_len * 8);
|
||||
if (rc != 0) {
|
||||
rc = CRYPTO_ERR_DECRYPTION;
|
||||
goto exit_gcm;
|
||||
}
|
||||
|
||||
rc = mbedtls_gcm_starts(&ctx, MBEDTLS_GCM_DECRYPT, iv, iv_len, NULL, 0);
|
||||
if (rc != 0) {
|
||||
rc = CRYPTO_ERR_DECRYPTION;
|
||||
goto exit_gcm;
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
dec_len = MIN(sizeof(buf), len);
|
||||
|
||||
rc = mbedtls_gcm_update(&ctx, dec_len, pt, buf);
|
||||
if (rc != 0) {
|
||||
rc = CRYPTO_ERR_DECRYPTION;
|
||||
goto exit_gcm;
|
||||
}
|
||||
|
||||
memcpy(pt, buf, dec_len);
|
||||
pt += dec_len;
|
||||
len -= dec_len;
|
||||
}
|
||||
|
||||
rc = mbedtls_gcm_finish(&ctx, tag_buf, sizeof(tag_buf));
|
||||
if (rc != 0) {
|
||||
rc = CRYPTO_ERR_DECRYPTION;
|
||||
goto exit_gcm;
|
||||
}
|
||||
|
||||
/* Check tag in "constant-time" */
|
||||
for (diff = 0, i = 0; i < tag_len; i++)
|
||||
diff |= ((const unsigned char *)tag)[i] ^ tag_buf[i];
|
||||
|
||||
if (diff != 0) {
|
||||
rc = CRYPTO_ERR_DECRYPTION;
|
||||
goto exit_gcm;
|
||||
}
|
||||
|
||||
/* GCM decryption success */
|
||||
rc = CRYPTO_SUCCESS;
|
||||
|
||||
exit_gcm:
|
||||
mbedtls_gcm_free(&ctx);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Authenticated decryption of an image
|
||||
*/
|
||||
static int auth_decrypt(enum crypto_dec_algo dec_algo, void *data_ptr,
|
||||
size_t len, const void *key, unsigned int key_len,
|
||||
unsigned int key_flags, const void *iv,
|
||||
unsigned int iv_len, const void *tag,
|
||||
unsigned int tag_len)
|
||||
{
|
||||
int rc;
|
||||
|
||||
assert((key_flags & ENC_KEY_IS_IDENTIFIER) == 0);
|
||||
|
||||
switch (dec_algo) {
|
||||
case CRYPTO_GCM_DECRYPT:
|
||||
rc = aes_gcm_decrypt(data_ptr, len, key, key_len, iv, iv_len,
|
||||
tag, tag_len);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
break;
|
||||
default:
|
||||
return CRYPTO_ERR_DECRYPTION;
|
||||
}
|
||||
|
||||
return CRYPTO_SUCCESS;
|
||||
}
|
||||
#endif /* TF_MBEDTLS_USE_AES_GCM */
|
||||
|
||||
/*
|
||||
* Register crypto library descriptor
|
||||
*/
|
||||
#if CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC
|
||||
#if TF_MBEDTLS_USE_AES_GCM
|
||||
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
|
||||
auth_decrypt);
|
||||
#else
|
||||
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, calc_hash,
|
||||
NULL);
|
||||
#endif
|
||||
#elif CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_ONLY
|
||||
#if TF_MBEDTLS_USE_AES_GCM
|
||||
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash,
|
||||
auth_decrypt);
|
||||
#else
|
||||
REGISTER_CRYPTO_LIB(LIB_NAME, init, verify_signature, verify_hash, NULL);
|
||||
#endif
|
||||
#elif CRYPTO_SUPPORT == CRYPTO_HASH_CALC_ONLY
|
||||
REGISTER_CRYPTO_LIB(LIB_NAME, init, calc_hash);
|
||||
#endif /* CRYPTO_SUPPORT == CRYPTO_AUTH_VERIFY_AND_HASH_CALC */
|
||||
@@ -0,0 +1,11 @@
|
||||
#
|
||||
# Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
include drivers/auth/mbedtls/mbedtls_common.mk
|
||||
|
||||
MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_crypto.c
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
#
|
||||
|
||||
include drivers/auth/mbedtls/mbedtls_common.mk
|
||||
|
||||
MBEDTLS_SOURCES += drivers/auth/mbedtls/mbedtls_x509_parser.c
|
||||
+500
@@ -0,0 +1,500 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/*
|
||||
* X509 parser based on mbed TLS
|
||||
*
|
||||
* This module implements functions to check the integrity of a X509v3
|
||||
* certificate ASN.1 structure and extract authentication parameters from the
|
||||
* extensions field, such as an image hash or a public key.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* mbed TLS headers */
|
||||
#include <mbedtls/asn1.h>
|
||||
#include <mbedtls/oid.h>
|
||||
#include <mbedtls/platform.h>
|
||||
|
||||
#include <arch_helpers.h>
|
||||
#include <drivers/auth/img_parser_mod.h>
|
||||
#include <drivers/auth/mbedtls/mbedtls_common.h>
|
||||
#include <lib/utils.h>
|
||||
|
||||
/* Maximum OID string length ("a.b.c.d.e.f ...") */
|
||||
#define MAX_OID_STR_LEN 64
|
||||
|
||||
#define LIB_NAME "mbed TLS X509v3"
|
||||
|
||||
/* Temporary variables to speed up the authentication parameters search. These
|
||||
* variables are assigned once during the integrity check and used any time an
|
||||
* authentication parameter is requested, so we do not have to parse the image
|
||||
* again */
|
||||
static mbedtls_asn1_buf tbs;
|
||||
static mbedtls_asn1_buf v3_ext;
|
||||
static mbedtls_asn1_buf pk;
|
||||
static mbedtls_asn1_buf sig_alg;
|
||||
static mbedtls_asn1_buf signature;
|
||||
|
||||
/*
|
||||
* Clear all static temporary variables.
|
||||
*/
|
||||
static void clear_temp_vars(void)
|
||||
{
|
||||
#define ZERO_AND_CLEAN(x) \
|
||||
do { \
|
||||
zeromem(&x, sizeof(x)); \
|
||||
clean_dcache_range((uintptr_t)&x, sizeof(x)); \
|
||||
} while (0);
|
||||
|
||||
ZERO_AND_CLEAN(tbs)
|
||||
ZERO_AND_CLEAN(v3_ext);
|
||||
ZERO_AND_CLEAN(pk);
|
||||
ZERO_AND_CLEAN(sig_alg);
|
||||
ZERO_AND_CLEAN(signature);
|
||||
|
||||
#undef ZERO_AND_CLEAN
|
||||
}
|
||||
|
||||
/*
|
||||
* Get X509v3 extension
|
||||
*
|
||||
* Global variable 'v3_ext' must point to the extensions region
|
||||
* in the certificate. No need to check for errors since the image has passed
|
||||
* the integrity check.
|
||||
*/
|
||||
static int get_ext(const char *oid, void **ext, unsigned int *ext_len)
|
||||
{
|
||||
int oid_len;
|
||||
size_t len;
|
||||
unsigned char *end_ext_data, *end_ext_octet;
|
||||
unsigned char *p;
|
||||
const unsigned char *end;
|
||||
char oid_str[MAX_OID_STR_LEN];
|
||||
mbedtls_asn1_buf extn_oid;
|
||||
int is_critical;
|
||||
|
||||
assert(oid != NULL);
|
||||
|
||||
p = v3_ext.p;
|
||||
end = v3_ext.p + v3_ext.len;
|
||||
|
||||
mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
|
||||
while (p < end) {
|
||||
zeromem(&extn_oid, sizeof(extn_oid));
|
||||
is_critical = 0; /* DEFAULT FALSE */
|
||||
|
||||
mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
end_ext_data = p + len;
|
||||
|
||||
/* Get extension ID */
|
||||
extn_oid.tag = *p;
|
||||
mbedtls_asn1_get_tag(&p, end, &extn_oid.len, MBEDTLS_ASN1_OID);
|
||||
extn_oid.p = p;
|
||||
p += extn_oid.len;
|
||||
|
||||
/* Get optional critical */
|
||||
mbedtls_asn1_get_bool(&p, end_ext_data, &is_critical);
|
||||
|
||||
/* Extension data */
|
||||
mbedtls_asn1_get_tag(&p, end_ext_data, &len,
|
||||
MBEDTLS_ASN1_OCTET_STRING);
|
||||
end_ext_octet = p + len;
|
||||
|
||||
/* Detect requested extension */
|
||||
oid_len = mbedtls_oid_get_numeric_string(oid_str,
|
||||
MAX_OID_STR_LEN,
|
||||
&extn_oid);
|
||||
if ((oid_len == MBEDTLS_ERR_OID_BUF_TOO_SMALL) || (oid_len < 0)) {
|
||||
return IMG_PARSER_ERR;
|
||||
}
|
||||
if (((size_t)oid_len == strlen(oid_str)) && !strcmp(oid, oid_str)) {
|
||||
*ext = (void *)p;
|
||||
*ext_len = (unsigned int)len;
|
||||
return IMG_PARSER_OK;
|
||||
}
|
||||
|
||||
/* Next */
|
||||
p = end_ext_octet;
|
||||
}
|
||||
|
||||
return IMG_PARSER_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check the integrity of the certificate ASN.1 structure.
|
||||
*
|
||||
* Extract the relevant data that will be used later during authentication.
|
||||
*
|
||||
* This function doesn't clear the static variables located on the top of this
|
||||
* file in case of an error. It is only called from check_integrity(), which
|
||||
* performs the cleanup if necessary.
|
||||
*/
|
||||
static int cert_parse(void *img, unsigned int img_len)
|
||||
{
|
||||
int ret, is_critical;
|
||||
size_t len;
|
||||
unsigned char *p, *end, *crt_end;
|
||||
mbedtls_asn1_buf sig_alg1, sig_alg2;
|
||||
|
||||
p = (unsigned char *)img;
|
||||
len = img_len;
|
||||
end = p + len;
|
||||
|
||||
/*
|
||||
* Certificate ::= SEQUENCE {
|
||||
* tbsCertificate TBSCertificate,
|
||||
* signatureAlgorithm AlgorithmIdentifier,
|
||||
* signatureValue BIT STRING }
|
||||
*/
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
|
||||
if (len > (size_t)(end - p)) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
crt_end = p + len;
|
||||
|
||||
/*
|
||||
* TBSCertificate ::= SEQUENCE {
|
||||
*/
|
||||
tbs.p = p;
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
end = p + len;
|
||||
tbs.len = end - tbs.p;
|
||||
|
||||
/*
|
||||
* Version ::= INTEGER { v1(0), v2(1), v3(2) }
|
||||
*/
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
|
||||
MBEDTLS_ASN1_CONSTRUCTED | 0);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
p += len;
|
||||
|
||||
/*
|
||||
* CertificateSerialNumber ::= INTEGER
|
||||
*/
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_INTEGER);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
p += len;
|
||||
|
||||
/*
|
||||
* signature AlgorithmIdentifier
|
||||
*/
|
||||
sig_alg1.p = p;
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
if ((end - p) < 1) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
sig_alg1.len = (p + len) - sig_alg1.p;
|
||||
p += len;
|
||||
|
||||
/*
|
||||
* issuer Name
|
||||
*/
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
p += len;
|
||||
|
||||
/*
|
||||
* Validity ::= SEQUENCE {
|
||||
* notBefore Time,
|
||||
* notAfter Time }
|
||||
*
|
||||
*/
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
p += len;
|
||||
|
||||
/*
|
||||
* subject Name
|
||||
*/
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
p += len;
|
||||
|
||||
/*
|
||||
* SubjectPublicKeyInfo
|
||||
*/
|
||||
pk.p = p;
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
pk.len = (p + len) - pk.p;
|
||||
p += len;
|
||||
|
||||
/*
|
||||
* issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
|
||||
*/
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
|
||||
MBEDTLS_ASN1_CONSTRUCTED | 1);
|
||||
if (ret != 0) {
|
||||
if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
} else {
|
||||
p += len;
|
||||
}
|
||||
|
||||
/*
|
||||
* subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
|
||||
*/
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
|
||||
MBEDTLS_ASN1_CONSTRUCTED | 2);
|
||||
if (ret != 0) {
|
||||
if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
} else {
|
||||
p += len;
|
||||
}
|
||||
|
||||
/*
|
||||
* extensions [3] EXPLICIT Extensions OPTIONAL
|
||||
* }
|
||||
*
|
||||
* X.509 and RFC5280 allow omitting the extensions entirely.
|
||||
* However, in TF-A, a certificate with no extensions would
|
||||
* always fail later on, as the extensions contain the
|
||||
* information needed to authenticate the next stage in the
|
||||
* boot chain. Furthermore, get_ext() assumes that the
|
||||
* extensions have been parsed into v3_ext, and allowing
|
||||
* there to be no extensions would pointlessly complicate
|
||||
* the code. Therefore, just reject certificates without
|
||||
* extensions. This is also why version 1 and 2 certificates
|
||||
* are rejected above.
|
||||
*/
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONTEXT_SPECIFIC |
|
||||
MBEDTLS_ASN1_CONSTRUCTED | 3);
|
||||
if ((ret != 0) || (len != (size_t)(end - p))) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
|
||||
* -- must use all remaining bytes in TBSCertificate
|
||||
*/
|
||||
v3_ext.p = p;
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if ((ret != 0) || (len != (size_t)(end - p))) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
v3_ext.len = end - v3_ext.p;
|
||||
|
||||
/*
|
||||
* Check extensions integrity. At least one extension is
|
||||
* required: the ASN.1 specifies a minimum size of 1, and at
|
||||
* least one extension is needed to authenticate the next stage
|
||||
* in the boot chain.
|
||||
*/
|
||||
do {
|
||||
unsigned char *end_ext_data;
|
||||
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len,
|
||||
MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
end_ext_data = p + len;
|
||||
|
||||
/* Get extension ID */
|
||||
ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len, MBEDTLS_ASN1_OID);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
p += len;
|
||||
|
||||
/* Get optional critical */
|
||||
ret = mbedtls_asn1_get_bool(&p, end_ext_data, &is_critical);
|
||||
if ((ret != 0) && (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG)) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Data should be octet string type and must use all bytes in
|
||||
* the Extension.
|
||||
*/
|
||||
ret = mbedtls_asn1_get_tag(&p, end_ext_data, &len,
|
||||
MBEDTLS_ASN1_OCTET_STRING);
|
||||
if ((ret != 0) || ((p + len) != end_ext_data)) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
p = end_ext_data;
|
||||
} while (p < end);
|
||||
|
||||
if (p != end) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
|
||||
end = crt_end;
|
||||
|
||||
/*
|
||||
* }
|
||||
* -- end of TBSCertificate
|
||||
*
|
||||
* signatureAlgorithm AlgorithmIdentifier
|
||||
*/
|
||||
sig_alg2.p = p;
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_CONSTRUCTED |
|
||||
MBEDTLS_ASN1_SEQUENCE);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
if ((end - p) < 1) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
sig_alg2.len = (p + len) - sig_alg2.p;
|
||||
p += len;
|
||||
|
||||
/* Compare both signature algorithms */
|
||||
if (sig_alg1.len != sig_alg2.len) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
if (0 != memcmp(sig_alg1.p, sig_alg2.p, sig_alg1.len)) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
memcpy(&sig_alg, &sig_alg1, sizeof(sig_alg));
|
||||
|
||||
/*
|
||||
* signatureValue BIT STRING
|
||||
*/
|
||||
signature.p = p;
|
||||
ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_BIT_STRING);
|
||||
if (ret != 0) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
signature.len = (p + len) - signature.p;
|
||||
p += len;
|
||||
|
||||
/* Check certificate length */
|
||||
if (p != end) {
|
||||
return IMG_PARSER_ERR_FORMAT;
|
||||
}
|
||||
|
||||
return IMG_PARSER_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Exported functions */
|
||||
|
||||
static void init(void)
|
||||
{
|
||||
mbedtls_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrapper for cert_parse() that clears the static variables used by it in case
|
||||
* of an error.
|
||||
*/
|
||||
static int check_integrity(void *img, unsigned int img_len)
|
||||
{
|
||||
int rc = cert_parse(img, img_len);
|
||||
|
||||
if (rc != IMG_PARSER_OK)
|
||||
clear_temp_vars();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract an authentication parameter from an X509v3 certificate
|
||||
*
|
||||
* This function returns a pointer to the extracted data and its length.
|
||||
* Depending on the type of parameter, a pointer to the data stored in the
|
||||
* certificate may be returned (i.e. an octet string containing a hash). Other
|
||||
* data may need to be copied and formatted (i.e. integers). In the later case,
|
||||
* a buffer of the correct type needs to be statically allocated, filled and
|
||||
* returned.
|
||||
*/
|
||||
static int get_auth_param(const auth_param_type_desc_t *type_desc,
|
||||
void *img, unsigned int img_len,
|
||||
void **param, unsigned int *param_len)
|
||||
{
|
||||
int rc = IMG_PARSER_OK;
|
||||
|
||||
/* We do not use img because the check_integrity function has already
|
||||
* extracted the relevant data (v3_ext, pk, sig_alg, etc) */
|
||||
|
||||
switch (type_desc->type) {
|
||||
case AUTH_PARAM_RAW_DATA:
|
||||
/* Data to be signed */
|
||||
*param = (void *)tbs.p;
|
||||
*param_len = (unsigned int)tbs.len;
|
||||
break;
|
||||
case AUTH_PARAM_HASH:
|
||||
case AUTH_PARAM_NV_CTR:
|
||||
/* All these parameters are included as X509v3 extensions */
|
||||
rc = get_ext(type_desc->cookie, param, param_len);
|
||||
break;
|
||||
case AUTH_PARAM_PUB_KEY:
|
||||
if (type_desc->cookie != 0) {
|
||||
/* Get public key from extension */
|
||||
rc = get_ext(type_desc->cookie, param, param_len);
|
||||
} else {
|
||||
/* Get the subject public key */
|
||||
*param = (void *)pk.p;
|
||||
*param_len = (unsigned int)pk.len;
|
||||
}
|
||||
break;
|
||||
case AUTH_PARAM_SIG_ALG:
|
||||
/* Get the certificate signature algorithm */
|
||||
*param = (void *)sig_alg.p;
|
||||
*param_len = (unsigned int)sig_alg.len;
|
||||
break;
|
||||
case AUTH_PARAM_SIG:
|
||||
/* Get the certificate signature */
|
||||
*param = (void *)signature.p;
|
||||
*param_len = (unsigned int)signature.len;
|
||||
break;
|
||||
default:
|
||||
rc = IMG_PARSER_ERR_NOT_FOUND;
|
||||
break;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
REGISTER_IMG_PARSER_LIB(IMG_CERT, LIB_NAME, init, \
|
||||
check_integrity, get_auth_param);
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
|
||||
#include <drivers/auth/auth_mod.h>
|
||||
#include <drivers/auth/tbbr_cot_common.h>
|
||||
#if USE_TBBR_DEFS
|
||||
#include <tools_share/tbbr_oid.h>
|
||||
#else
|
||||
#include <platform_oid.h>
|
||||
#endif
|
||||
|
||||
static auth_param_type_desc_t scp_bl2u_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SCP_FWU_CFG_HASH_OID);
|
||||
static auth_param_type_desc_t bl2u_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, AP_FWU_CFG_HASH_OID);
|
||||
static auth_param_type_desc_t ns_bl2u_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, FWU_HASH_OID);
|
||||
|
||||
static const auth_img_desc_t bl2_image = {
|
||||
.img_id = BL2_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_boot_fw_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tb_fw_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* FWU auth descriptor.
|
||||
*/
|
||||
static const auth_img_desc_t fwu_cert = {
|
||||
.img_id = FWU_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &subject_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &scp_bl2u_hash,
|
||||
.data = {
|
||||
.ptr = (void *)scp_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &bl2u_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tb_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &ns_bl2u_hash,
|
||||
.data = {
|
||||
.ptr = (void *)nt_world_bl_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/*
|
||||
* SCP_BL2U
|
||||
*/
|
||||
static const auth_img_desc_t scp_bl2u_image = {
|
||||
.img_id = SCP_BL2U_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &fwu_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &scp_bl2u_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/*
|
||||
* BL2U
|
||||
*/
|
||||
static const auth_img_desc_t bl2u_image = {
|
||||
.img_id = BL2U_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &fwu_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &bl2u_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/*
|
||||
* NS_BL2U
|
||||
*/
|
||||
static const auth_img_desc_t ns_bl2u_image = {
|
||||
.img_id = NS_BL2U_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &fwu_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &ns_bl2u_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/*
|
||||
* TB_FW_CONFIG
|
||||
*/
|
||||
static const auth_img_desc_t tb_fw_config = {
|
||||
.img_id = TB_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_boot_fw_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tb_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t fw_config = {
|
||||
.img_id = FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_boot_fw_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* TBBR Chain of trust definition
|
||||
*/
|
||||
static const auth_img_desc_t * const cot_desc[] = {
|
||||
[TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert,
|
||||
[BL2_IMAGE_ID] = &bl2_image,
|
||||
[HW_CONFIG_ID] = &hw_config,
|
||||
[TB_FW_CONFIG_ID] = &tb_fw_config,
|
||||
[FW_CONFIG_ID] = &fw_config,
|
||||
[FWU_CERT_ID] = &fwu_cert,
|
||||
[SCP_BL2U_IMAGE_ID] = &scp_bl2u_image,
|
||||
[BL2U_IMAGE_ID] = &bl2u_image,
|
||||
[NS_BL2U_IMAGE_ID] = &ns_bl2u_image
|
||||
};
|
||||
|
||||
/* Register the CoT in the authentication module */
|
||||
REGISTER_COT(cot_desc);
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <drivers/auth/auth_mod.h>
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#include <drivers/auth/tbbr_cot_common.h>
|
||||
|
||||
#if USE_TBBR_DEFS
|
||||
#include <tools_share/tbbr_oid.h>
|
||||
#else
|
||||
#include <platform_oid.h>
|
||||
#endif
|
||||
#include <platform_def.h>
|
||||
|
||||
|
||||
static unsigned char trusted_world_pk_buf[PK_DER_LEN];
|
||||
static unsigned char non_trusted_world_pk_buf[PK_DER_LEN];
|
||||
static unsigned char content_pk_buf[PK_DER_LEN];
|
||||
static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
|
||||
|
||||
static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
|
||||
static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID);
|
||||
static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID);
|
||||
static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID);
|
||||
static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
|
||||
static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
|
||||
/*
|
||||
* Trusted key certificate
|
||||
*/
|
||||
static const auth_img_desc_t trusted_key_cert = {
|
||||
.img_id = TRUSTED_KEY_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &subject_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &trusted_world_pk,
|
||||
.data = {
|
||||
.ptr = (void *)trusted_world_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &non_trusted_world_pk,
|
||||
.data = {
|
||||
.ptr = (void *)non_trusted_world_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/*
|
||||
* Non-Trusted Firmware
|
||||
*/
|
||||
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,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &non_trusted_world_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &non_trusted_nv_ctr,
|
||||
.plat_nv_ctr = &non_trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &nt_fw_content_pk,
|
||||
.data = {
|
||||
.ptr = (void *)content_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t non_trusted_fw_content_cert = {
|
||||
.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &non_trusted_fw_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &nt_fw_content_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &non_trusted_nv_ctr,
|
||||
.plat_nv_ctr = &non_trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &nt_world_bl_hash,
|
||||
.data = {
|
||||
.ptr = (void *)nt_world_bl_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &nt_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)nt_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t bl33_image = {
|
||||
.img_id = BL33_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &non_trusted_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &nt_world_bl_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static const auth_img_desc_t * const cot_desc[] = {
|
||||
[TRUSTED_KEY_CERT_ID] = &trusted_key_cert,
|
||||
[NON_TRUSTED_FW_KEY_CERT_ID] = &non_trusted_fw_key_cert,
|
||||
[NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert,
|
||||
[BL33_IMAGE_ID] = &bl33_image,
|
||||
};
|
||||
|
||||
/* Register the CoT in the authentication module */
|
||||
REGISTER_COT(cot_desc);
|
||||
@@ -0,0 +1,688 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
|
||||
#include <drivers/auth/auth_mod.h>
|
||||
#include <drivers/auth/tbbr_cot_common.h>
|
||||
#if USE_TBBR_DEFS
|
||||
#include <tools_share/tbbr_oid.h>
|
||||
#else
|
||||
#include <platform_oid.h>
|
||||
#endif
|
||||
|
||||
static unsigned char soc_fw_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tos_fw_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tos_fw_extra1_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tos_fw_extra2_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char trusted_world_pk_buf[PK_DER_LEN];
|
||||
static unsigned char non_trusted_world_pk_buf[PK_DER_LEN];
|
||||
static unsigned char content_pk_buf[PK_DER_LEN];
|
||||
static unsigned char soc_fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tos_fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char nt_fw_config_hash_buf[HASH_DER_LEN];
|
||||
#if defined(SPD_spmd)
|
||||
static unsigned char sp_pkg_hash_buf[MAX_SP_IDS][HASH_DER_LEN];
|
||||
#endif /* SPD_spmd */
|
||||
|
||||
static auth_param_type_desc_t non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
|
||||
static auth_param_type_desc_t trusted_world_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, TRUSTED_WORLD_PK_OID);
|
||||
static auth_param_type_desc_t non_trusted_world_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, NON_TRUSTED_WORLD_PK_OID);
|
||||
static auth_param_type_desc_t scp_fw_content_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, SCP_FW_CONTENT_CERT_PK_OID);
|
||||
static auth_param_type_desc_t soc_fw_content_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, SOC_FW_CONTENT_CERT_PK_OID);
|
||||
static auth_param_type_desc_t tos_fw_content_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, TRUSTED_OS_FW_CONTENT_CERT_PK_OID);
|
||||
static auth_param_type_desc_t nt_fw_content_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, NON_TRUSTED_FW_CONTENT_CERT_PK_OID);
|
||||
static auth_param_type_desc_t scp_fw_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SCP_FW_HASH_OID);
|
||||
static auth_param_type_desc_t soc_fw_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SOC_AP_FW_HASH_OID);
|
||||
static auth_param_type_desc_t soc_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SOC_FW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t tos_fw_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_OS_FW_HASH_OID);
|
||||
static auth_param_type_desc_t tos_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_OS_FW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t tos_fw_extra1_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA1_HASH_OID);
|
||||
static auth_param_type_desc_t tos_fw_extra2_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_OS_FW_EXTRA2_HASH_OID);
|
||||
static auth_param_type_desc_t nt_world_bl_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID);
|
||||
static auth_param_type_desc_t nt_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, NON_TRUSTED_FW_CONFIG_HASH_OID);
|
||||
#if defined(SPD_spmd)
|
||||
static auth_param_type_desc_t sp_pkg1_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG1_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg2_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG2_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg3_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG3_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg4_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG4_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg5_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG5_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg6_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG6_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg7_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG7_HASH_OID);
|
||||
static auth_param_type_desc_t sp_pkg8_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, SP_PKG8_HASH_OID);
|
||||
#endif /* SPD_spmd */
|
||||
|
||||
/*
|
||||
* Trusted key certificate
|
||||
*/
|
||||
static const auth_img_desc_t trusted_key_cert = {
|
||||
.img_id = TRUSTED_KEY_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &subject_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &trusted_world_pk,
|
||||
.data = {
|
||||
.ptr = (void *)trusted_world_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &non_trusted_world_pk,
|
||||
.data = {
|
||||
.ptr = (void *)non_trusted_world_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/*
|
||||
* SCP Firmware
|
||||
*/
|
||||
static const auth_img_desc_t scp_fw_key_cert = {
|
||||
.img_id = SCP_FW_KEY_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &trusted_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &trusted_world_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &scp_fw_content_pk,
|
||||
.data = {
|
||||
.ptr = (void *)content_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t scp_fw_content_cert = {
|
||||
.img_id = SCP_FW_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &scp_fw_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &scp_fw_content_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &scp_fw_hash,
|
||||
.data = {
|
||||
.ptr = (void *)scp_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t scp_bl2_image = {
|
||||
.img_id = SCP_BL2_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &scp_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &scp_fw_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/*
|
||||
* SoC Firmware
|
||||
*/
|
||||
static const auth_img_desc_t soc_fw_key_cert = {
|
||||
.img_id = SOC_FW_KEY_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &trusted_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &trusted_world_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &soc_fw_content_pk,
|
||||
.data = {
|
||||
.ptr = (void *)content_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t soc_fw_content_cert = {
|
||||
.img_id = SOC_FW_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &soc_fw_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &soc_fw_content_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &soc_fw_hash,
|
||||
.data = {
|
||||
.ptr = (void *)soc_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &soc_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)soc_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t bl31_image = {
|
||||
.img_id = BL31_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &soc_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &soc_fw_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/* SOC FW Config */
|
||||
static const auth_img_desc_t soc_fw_config = {
|
||||
.img_id = SOC_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &soc_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &soc_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/*
|
||||
* Trusted OS Firmware
|
||||
*/
|
||||
static const auth_img_desc_t trusted_os_fw_key_cert = {
|
||||
.img_id = TRUSTED_OS_FW_KEY_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &trusted_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &trusted_world_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &tos_fw_content_pk,
|
||||
.data = {
|
||||
.ptr = (void *)content_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t trusted_os_fw_content_cert = {
|
||||
.img_id = TRUSTED_OS_FW_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &trusted_os_fw_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &tos_fw_content_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &tos_fw_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tos_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &tos_fw_extra1_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tos_fw_extra1_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &tos_fw_extra2_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tos_fw_extra2_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[3] = {
|
||||
.type_desc = &tos_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tos_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t bl32_image = {
|
||||
.img_id = BL32_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_os_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tos_fw_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t bl32_extra1_image = {
|
||||
.img_id = BL32_EXTRA1_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_os_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tos_fw_extra1_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t bl32_extra2_image = {
|
||||
.img_id = BL32_EXTRA2_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_os_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tos_fw_extra2_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/* TOS FW Config */
|
||||
static const auth_img_desc_t tos_fw_config = {
|
||||
.img_id = TOS_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_os_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &tos_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/*
|
||||
* Non-Trusted Firmware
|
||||
*/
|
||||
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,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &non_trusted_world_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &non_trusted_nv_ctr,
|
||||
.plat_nv_ctr = &non_trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &nt_fw_content_pk,
|
||||
.data = {
|
||||
.ptr = (void *)content_pk_buf,
|
||||
.len = (unsigned int)PK_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t non_trusted_fw_content_cert = {
|
||||
.img_id = NON_TRUSTED_FW_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &non_trusted_fw_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &nt_fw_content_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &non_trusted_nv_ctr,
|
||||
.plat_nv_ctr = &non_trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &nt_world_bl_hash,
|
||||
.data = {
|
||||
.ptr = (void *)nt_world_bl_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &nt_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)nt_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
static const auth_img_desc_t bl33_image = {
|
||||
.img_id = BL33_IMAGE_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &non_trusted_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &nt_world_bl_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/* NT FW Config */
|
||||
static const auth_img_desc_t nt_fw_config = {
|
||||
.img_id = NT_FW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &non_trusted_fw_content_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &nt_fw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
/* Secure Partitions */
|
||||
#if defined(SPD_spmd)
|
||||
static const auth_img_desc_t sip_sp_content_cert = {
|
||||
.img_id = SIP_SP_CONTENT_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = &trusted_key_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &trusted_world_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &sp_pkg1_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[0],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &sp_pkg2_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[1],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &sp_pkg3_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[2],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[3] = {
|
||||
.type_desc = &sp_pkg4_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[3],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[4] = {
|
||||
.type_desc = &sp_pkg5_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[4],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[5] = {
|
||||
.type_desc = &sp_pkg6_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[5],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[6] = {
|
||||
.type_desc = &sp_pkg7_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[6],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[7] = {
|
||||
.type_desc = &sp_pkg8_hash,
|
||||
.data = {
|
||||
.ptr = (void *)sp_pkg_hash_buf[7],
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
DEFINE_SIP_SP_PKG(1);
|
||||
DEFINE_SIP_SP_PKG(2);
|
||||
DEFINE_SIP_SP_PKG(3);
|
||||
DEFINE_SIP_SP_PKG(4);
|
||||
DEFINE_SIP_SP_PKG(5);
|
||||
DEFINE_SIP_SP_PKG(6);
|
||||
DEFINE_SIP_SP_PKG(7);
|
||||
DEFINE_SIP_SP_PKG(8);
|
||||
#endif /* SPD_spmd */
|
||||
|
||||
static const auth_img_desc_t * const cot_desc[] = {
|
||||
[TRUSTED_BOOT_FW_CERT_ID] = &trusted_boot_fw_cert,
|
||||
[HW_CONFIG_ID] = &hw_config,
|
||||
[TRUSTED_KEY_CERT_ID] = &trusted_key_cert,
|
||||
[SCP_FW_KEY_CERT_ID] = &scp_fw_key_cert,
|
||||
[SCP_FW_CONTENT_CERT_ID] = &scp_fw_content_cert,
|
||||
[SCP_BL2_IMAGE_ID] = &scp_bl2_image,
|
||||
[SOC_FW_KEY_CERT_ID] = &soc_fw_key_cert,
|
||||
[SOC_FW_CONTENT_CERT_ID] = &soc_fw_content_cert,
|
||||
[BL31_IMAGE_ID] = &bl31_image,
|
||||
[SOC_FW_CONFIG_ID] = &soc_fw_config,
|
||||
[TRUSTED_OS_FW_KEY_CERT_ID] = &trusted_os_fw_key_cert,
|
||||
[TRUSTED_OS_FW_CONTENT_CERT_ID] = &trusted_os_fw_content_cert,
|
||||
[BL32_IMAGE_ID] = &bl32_image,
|
||||
[BL32_EXTRA1_IMAGE_ID] = &bl32_extra1_image,
|
||||
[BL32_EXTRA2_IMAGE_ID] = &bl32_extra2_image,
|
||||
[TOS_FW_CONFIG_ID] = &tos_fw_config,
|
||||
[NON_TRUSTED_FW_KEY_CERT_ID] = &non_trusted_fw_key_cert,
|
||||
[NON_TRUSTED_FW_CONTENT_CERT_ID] = &non_trusted_fw_content_cert,
|
||||
[BL33_IMAGE_ID] = &bl33_image,
|
||||
[NT_FW_CONFIG_ID] = &nt_fw_config,
|
||||
#if defined(SPD_spmd)
|
||||
[SIP_SP_CONTENT_CERT_ID] = &sip_sp_content_cert,
|
||||
[SP_PKG1_ID] = &sp_pkg1,
|
||||
[SP_PKG2_ID] = &sp_pkg2,
|
||||
[SP_PKG3_ID] = &sp_pkg3,
|
||||
[SP_PKG4_ID] = &sp_pkg4,
|
||||
[SP_PKG5_ID] = &sp_pkg5,
|
||||
[SP_PKG6_ID] = &sp_pkg6,
|
||||
[SP_PKG7_ID] = &sp_pkg7,
|
||||
[SP_PKG8_ID] = &sp_pkg8,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Register the CoT in the authentication module */
|
||||
REGISTER_COT(cot_desc);
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <platform_def.h>
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
|
||||
#include <drivers/auth/auth_mod.h>
|
||||
#include <drivers/auth/tbbr_cot_common.h>
|
||||
#if USE_TBBR_DEFS
|
||||
#include <tools_share/tbbr_oid.h>
|
||||
#else
|
||||
#include <platform_oid.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The platform must allocate buffers to store the authentication parameters
|
||||
* extracted from the certificates. In this case, because of the way the CoT is
|
||||
* established, we can reuse some of the buffers on different stages
|
||||
*/
|
||||
|
||||
static unsigned char fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char tb_fw_config_hash_buf[HASH_DER_LEN];
|
||||
static unsigned char hw_config_hash_buf[HASH_DER_LEN];
|
||||
unsigned char tb_fw_hash_buf[HASH_DER_LEN];
|
||||
unsigned char scp_fw_hash_buf[HASH_DER_LEN];
|
||||
unsigned char nt_world_bl_hash_buf[HASH_DER_LEN];
|
||||
|
||||
/*
|
||||
* common Parameter type descriptors across BL1 and BL2
|
||||
*/
|
||||
auth_param_type_desc_t trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_NV_CTR, TRUSTED_FW_NVCOUNTER_OID);
|
||||
auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_PUB_KEY, 0);
|
||||
auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_SIG, 0);
|
||||
auth_param_type_desc_t sig_alg = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_SIG_ALG, 0);
|
||||
auth_param_type_desc_t raw_data = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_RAW_DATA, 0);
|
||||
|
||||
/* common hash used across BL1 and BL2 */
|
||||
auth_param_type_desc_t tb_fw_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_BOOT_FW_HASH_OID);
|
||||
auth_param_type_desc_t tb_fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, TRUSTED_BOOT_FW_CONFIG_HASH_OID);
|
||||
auth_param_type_desc_t fw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, FW_CONFIG_HASH_OID);
|
||||
static auth_param_type_desc_t hw_config_hash = AUTH_PARAM_TYPE_DESC(
|
||||
AUTH_PARAM_HASH, HW_CONFIG_HASH_OID);
|
||||
|
||||
/* trusted_boot_fw_cert */
|
||||
const auth_img_desc_t trusted_boot_fw_cert = {
|
||||
.img_id = TRUSTED_BOOT_FW_CERT_ID,
|
||||
.img_type = IMG_CERT,
|
||||
.parent = NULL,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_SIG,
|
||||
.param.sig = {
|
||||
.pk = &subject_pk,
|
||||
.sig = &sig,
|
||||
.alg = &sig_alg,
|
||||
.data = &raw_data
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type = AUTH_METHOD_NV_CTR,
|
||||
.param.nv_ctr = {
|
||||
.cert_nv_ctr = &trusted_nv_ctr,
|
||||
.plat_nv_ctr = &trusted_nv_ctr
|
||||
}
|
||||
}
|
||||
},
|
||||
.authenticated_data = (const auth_param_desc_t[COT_MAX_VERIFIED_PARAMS]) {
|
||||
[0] = {
|
||||
.type_desc = &tb_fw_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tb_fw_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[1] = {
|
||||
.type_desc = &tb_fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)tb_fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[2] = {
|
||||
.type_desc = &hw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)hw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
},
|
||||
[3] = {
|
||||
.type_desc = &fw_config_hash,
|
||||
.data = {
|
||||
.ptr = (void *)fw_config_hash_buf,
|
||||
.len = (unsigned int)HASH_DER_LEN
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* HW Config */
|
||||
const auth_img_desc_t hw_config = {
|
||||
.img_id = HW_CONFIG_ID,
|
||||
.img_type = IMG_RAW,
|
||||
.parent = &trusted_boot_fw_cert,
|
||||
.img_auth_methods = (const auth_method_desc_t[AUTH_METHOD_NUM]) {
|
||||
[0] = {
|
||||
.type = AUTH_METHOD_HASH,
|
||||
.param.hash = {
|
||||
.data = &raw_data,
|
||||
.hash = &hw_config_hash
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user