Commit 5d29c760 authored by danh-arm's avatar danh-arm
Browse files

Merge pull request #572 from jcastillo-arm/jc/tbb_nvcounter

TBB NVcounter support
parents a8f6e21e 48279d52
...@@ -633,6 +633,35 @@ retrieved from the platform. The function also reports extra information related ...@@ -633,6 +633,35 @@ retrieved from the platform. The function also reports extra information related
to the ROTPK in the flags parameter. to the ROTPK in the flags parameter.
### Function: plat_get_nv_ctr()
Argument : void *, unsigned int *
Return : int
This function is mandatory when Trusted Board Boot is enabled. It returns the
non-volatile counter value stored in the platform in the second argument. The
cookie in the first argument may be used to select the counter in case the
platform provides more than one (for example, on platforms that use the default
TBBR CoT, the cookie will correspond to the OID values defined in
TRUSTED_FW_NVCOUNTER_OID or NON_TRUSTED_FW_NVCOUNTER_OID).
The function returns 0 on success. Any other value means the counter value could
not be retrieved from the platform.
### Function: plat_set_nv_ctr()
Argument : void *, unsigned int
Return : int
This function is mandatory when Trusted Board Boot is enabled. It sets a new
counter value in the platform. The cookie in the first argument may be used to
select the counter (as explained in plat_get_nv_ctr()).
The function returns 0 on success. Any other value means the counter value could
not be updated.
2.3 Common mandatory modifications 2.3 Common mandatory modifications
--------------------------------- ---------------------------------
......
...@@ -40,6 +40,9 @@ ...@@ -40,6 +40,9 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
/* ASN.1 tags */
#define ASN1_INTEGER 0x02
#define return_if_error(rc) \ #define return_if_error(rc) \
do { \ do { \
if (rc != 0) { \ if (rc != 0) { \
...@@ -226,6 +229,83 @@ static int auth_signature(const auth_method_param_sig_t *param, ...@@ -226,6 +229,83 @@ static int auth_signature(const auth_method_param_sig_t *param,
return rc; 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.
*
* Return: 0 = success, Otherwise = error
*/
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)
{
char *p;
void *data_ptr = NULL;
unsigned int data_len, len, i;
unsigned int cert_nv_ctr, plat_nv_ctr;
int rc = 0;
/* 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 = (char *)data_ptr;
if (*p != ASN1_INTEGER) {
/* Invalid ASN.1 integer */
return 1;
}
p++;
/* NV-counters are unsigned integers up to 32-bit */
len = (unsigned int)(*p & 0x7f);
if ((*p & 0x80) || (len > 4)) {
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 (img_desc->parent == NULL) {
/* This certificate has been signed with the ROT key.
* Update the platform counter value */
rc = plat_set_nv_ctr(param->plat_nv_ctr->cookie,
cert_nv_ctr);
return_if_error(rc);
} else {
/* Secondary certificates cannot modify the counter */
return 1;
}
}
return 0;
}
/* /*
* Return the parent id in the output parameter '*parent_id' * Return the parent id in the output parameter '*parent_id'
* *
...@@ -310,6 +390,10 @@ int auth_mod_verify_img(unsigned int img_id, ...@@ -310,6 +390,10 @@ int auth_mod_verify_img(unsigned int img_id,
rc = auth_signature(&auth_method->param.sig, rc = auth_signature(&auth_method->param.sig,
img_desc, img_ptr, img_len); img_desc, img_ptr, img_len);
break; break;
case AUTH_METHOD_NV_CTR:
rc = auth_nvctr(&auth_method->param.nv_ctr,
img_desc, img_ptr, img_len);
break;
default: default:
/* Unknown authentication method */ /* Unknown authentication method */
rc = 1; rc = 1;
......
...@@ -405,6 +405,13 @@ static int check_integrity(void *img, unsigned int img_len) ...@@ -405,6 +405,13 @@ static int check_integrity(void *img, unsigned int img_len)
/* /*
* Extract an authentication parameter from an X509v3 certificate * 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, static int get_auth_param(const auth_param_type_desc_t *type_desc,
void *img, unsigned int img_len, void *img, unsigned int img_len,
...@@ -422,6 +429,7 @@ static int get_auth_param(const auth_param_type_desc_t *type_desc, ...@@ -422,6 +429,7 @@ static int get_auth_param(const auth_param_type_desc_t *type_desc,
*param_len = (unsigned int)tbs.len; *param_len = (unsigned int)tbs.len;
break; break;
case AUTH_PARAM_HASH: case AUTH_PARAM_HASH:
case AUTH_PARAM_NV_CTR:
/* All these parameters are included as X509v3 extensions */ /* All these parameters are included as X509v3 extensions */
rc = get_ext(type_desc->cookie, param, param_len); rc = get_ext(type_desc->cookie, param, param_len);
break; break;
......
...@@ -56,6 +56,11 @@ static unsigned char content_pk_buf[PK_DER_LEN]; ...@@ -56,6 +56,11 @@ static unsigned char content_pk_buf[PK_DER_LEN];
/* /*
* Parameter type descriptors * 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 non_trusted_nv_ctr = AUTH_PARAM_TYPE_DESC(
AUTH_PARAM_NV_CTR, NON_TRUSTED_FW_NVCOUNTER_OID);
static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC( static auth_param_type_desc_t subject_pk = AUTH_PARAM_TYPE_DESC(
AUTH_PARAM_PUB_KEY, 0); AUTH_PARAM_PUB_KEY, 0);
static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC( static auth_param_type_desc_t sig = AUTH_PARAM_TYPE_DESC(
...@@ -116,6 +121,13 @@ static const auth_img_desc_t cot_desc[] = { ...@@ -116,6 +121,13 @@ static const auth_img_desc_t cot_desc[] = {
.alg = &sig_alg, .alg = &sig_alg,
.data = &raw_data, .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 = { .authenticated_data = {
...@@ -158,6 +170,13 @@ static const auth_img_desc_t cot_desc[] = { ...@@ -158,6 +170,13 @@ static const auth_img_desc_t cot_desc[] = {
.alg = &sig_alg, .alg = &sig_alg,
.data = &raw_data, .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 = { .authenticated_data = {
...@@ -193,6 +212,13 @@ static const auth_img_desc_t cot_desc[] = { ...@@ -193,6 +212,13 @@ static const auth_img_desc_t cot_desc[] = {
.alg = &sig_alg, .alg = &sig_alg,
.data = &raw_data, .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 = { .authenticated_data = {
...@@ -218,6 +244,13 @@ static const auth_img_desc_t cot_desc[] = { ...@@ -218,6 +244,13 @@ static const auth_img_desc_t cot_desc[] = {
.alg = &sig_alg, .alg = &sig_alg,
.data = &raw_data, .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 = { .authenticated_data = {
...@@ -260,6 +293,13 @@ static const auth_img_desc_t cot_desc[] = { ...@@ -260,6 +293,13 @@ static const auth_img_desc_t cot_desc[] = {
.alg = &sig_alg, .alg = &sig_alg,
.data = &raw_data, .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 = { .authenticated_data = {
...@@ -285,6 +325,13 @@ static const auth_img_desc_t cot_desc[] = { ...@@ -285,6 +325,13 @@ static const auth_img_desc_t cot_desc[] = {
.alg = &sig_alg, .alg = &sig_alg,
.data = &raw_data, .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 = { .authenticated_data = {
...@@ -327,6 +374,13 @@ static const auth_img_desc_t cot_desc[] = { ...@@ -327,6 +374,13 @@ static const auth_img_desc_t cot_desc[] = {
.alg = &sig_alg, .alg = &sig_alg,
.data = &raw_data, .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 = { .authenticated_data = {
...@@ -352,6 +406,13 @@ static const auth_img_desc_t cot_desc[] = { ...@@ -352,6 +406,13 @@ static const auth_img_desc_t cot_desc[] = {
.alg = &sig_alg, .alg = &sig_alg,
.data = &raw_data, .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 = { .authenticated_data = {
...@@ -394,6 +455,13 @@ static const auth_img_desc_t cot_desc[] = { ...@@ -394,6 +455,13 @@ static const auth_img_desc_t cot_desc[] = {
.alg = &sig_alg, .alg = &sig_alg,
.data = &raw_data, .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 = { .authenticated_data = {
...@@ -419,6 +487,13 @@ static const auth_img_desc_t cot_desc[] = { ...@@ -419,6 +487,13 @@ static const auth_img_desc_t cot_desc[] = {
.alg = &sig_alg, .alg = &sig_alg,
.data = &raw_data, .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 = { .authenticated_data = {
......
...@@ -46,6 +46,7 @@ typedef enum auth_param_type_enum { ...@@ -46,6 +46,7 @@ typedef enum auth_param_type_enum {
AUTH_PARAM_SIG_ALG, /* The image signature algorithm */ AUTH_PARAM_SIG_ALG, /* The image signature algorithm */
AUTH_PARAM_HASH, /* A hash (including the algorithm) */ AUTH_PARAM_HASH, /* A hash (including the algorithm) */
AUTH_PARAM_PUB_KEY, /* A public key */ AUTH_PARAM_PUB_KEY, /* A public key */
AUTH_PARAM_NV_CTR, /* A non-volatile counter */
} auth_param_type_t; } auth_param_type_t;
/* /*
...@@ -80,6 +81,7 @@ typedef enum auth_method_type_enum { ...@@ -80,6 +81,7 @@ typedef enum auth_method_type_enum {
AUTH_METHOD_NONE = 0, AUTH_METHOD_NONE = 0,
AUTH_METHOD_HASH, /* Authenticate by hash matching */ AUTH_METHOD_HASH, /* Authenticate by hash matching */
AUTH_METHOD_SIG, /* Authenticate by PK operation */ AUTH_METHOD_SIG, /* Authenticate by PK operation */
AUTH_METHOD_NV_CTR, /* Authenticate by Non-Volatile Counter */
AUTH_METHOD_NUM /* Number of methods */ AUTH_METHOD_NUM /* Number of methods */
} auth_method_type_t; } auth_method_type_t;
...@@ -105,7 +107,8 @@ typedef struct auth_method_param_sig_s { ...@@ -105,7 +107,8 @@ typedef struct auth_method_param_sig_s {
* Parameters for authentication by NV counter * Parameters for authentication by NV counter
*/ */
typedef struct auth_method_param_nv_ctr_s { typedef struct auth_method_param_nv_ctr_s {
auth_param_type_desc_t *nv_ctr; /* NV counter value */ auth_param_type_desc_t *cert_nv_ctr; /* NV counter in certificate */
auth_param_type_desc_t *plat_nv_ctr; /* NV counter in platform */
} auth_method_param_nv_ctr_t; } auth_method_param_nv_ctr_t;
/* /*
......
...@@ -65,6 +65,13 @@ ...@@ -65,6 +65,13 @@
*/ */
#define SOC_CSS_NIC400_APB4_BRIDGE 4 #define SOC_CSS_NIC400_APB4_BRIDGE 4
/* Non-volatile counters */
#define SOC_TRUSTED_NVCTR_BASE 0x7fe70000
#define TFW_NVCTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0000)
#define TFW_NVCTR_SIZE 4
#define NTFW_CTR_BASE (SOC_TRUSTED_NVCTR_BASE + 0x0004)
#define NTFW_CTR_SIZE 4
/* Keys */ /* Keys */
#define SOC_KEYS_BASE 0x7fe80000 #define SOC_KEYS_BASE 0x7fe80000
#define TZ_PUB_KEY_HASH_BASE (SOC_KEYS_BASE + 0x0000) #define TZ_PUB_KEY_HASH_BASE (SOC_KEYS_BASE + 0x0000)
......
...@@ -249,6 +249,8 @@ void bl32_plat_enable_mmu(uint32_t flags); ...@@ -249,6 +249,8 @@ void bl32_plat_enable_mmu(uint32_t flags);
******************************************************************************/ ******************************************************************************/
int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
unsigned int *flags); unsigned int *flags);
int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr);
int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr);
#if ENABLE_PLAT_COMPAT #if ENABLE_PLAT_COMPAT
/* /*
......
...@@ -58,6 +58,14 @@ ...@@ -58,6 +58,14 @@
TRUSTED_KEY_CERT := ${BUILD_PLAT}/trusted_key.crt TRUSTED_KEY_CERT := ${BUILD_PLAT}/trusted_key.crt
FWU_CERT := ${BUILD_PLAT}/fwu_cert.crt FWU_CERT := ${BUILD_PLAT}/fwu_cert.crt
# Default non-volatile counter values (overridable by the platform)
TFW_NVCTR_VAL ?= 0
NTFW_NVCTR_VAL ?= 0
# Pass the non-volatile counters to the cert_create tool
$(eval $(call CERT_ADD_CMD_OPT,${TFW_NVCTR_VAL},--tfw-nvctr))
$(eval $(call CERT_ADD_CMD_OPT,${NTFW_NVCTR_VAL},--ntfw-nvctr))
# Add Trusted Key certificate to the fip_create and cert_create command line options # Add Trusted Key certificate to the fip_create and cert_create command line options
$(eval $(call FIP_ADD_PAYLOAD,${TRUSTED_KEY_CERT},--trusted-key-cert)) $(eval $(call FIP_ADD_PAYLOAD,${TRUSTED_KEY_CERT},--trusted-key-cert))
$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_KEY_CERT},--trusted-key-cert)) $(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_KEY_CERT},--trusted-key-cert))
......
...@@ -31,11 +31,14 @@ ...@@ -31,11 +31,14 @@
#include <arm_def.h> #include <arm_def.h>
#include <assert.h> #include <assert.h>
#include <platform.h> #include <platform.h>
#include <platform_oid.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
/* Weak definition may be overridden in specific platform */ /* Weak definition may be overridden in specific platform */
#pragma weak plat_match_rotpk #pragma weak plat_match_rotpk
#pragma weak plat_get_nv_ctr
#pragma weak plat_set_nv_ctr
/* SHA256 algorithm */ /* SHA256 algorithm */
#define SHA256_BYTES 32 #define SHA256_BYTES 32
...@@ -148,3 +151,43 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len, ...@@ -148,3 +151,43 @@ int plat_get_rotpk_info(void *cookie, void **key_ptr, unsigned int *key_len,
return 0; return 0;
} }
/*
* Return the non-volatile counter value stored in the platform. The cookie
* will contain the OID of the counter in the certificate.
*
* Return: 0 = success, Otherwise = error
*/
int plat_get_nv_ctr(void *cookie, unsigned int *nv_ctr)
{
const char *oid;
uint32_t *nv_ctr_addr;
assert(cookie != NULL);
assert(nv_ctr != NULL);
oid = (const char *)cookie;
if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) {
nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE;
} else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) {
nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE;
} else {
return 1;
}
*nv_ctr = (unsigned int)(*nv_ctr_addr);
return 0;
}
/*
* Store a new non-volatile counter value. On Juno and FVP, the non-volatile
* counters are RO and cannot be modified. We expect the values in the
* certificates to always match the RO values so that this function is never
* called.
*
* Return: 0 = success, Otherwise = error
*/
int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr)
{
return 1;
}
...@@ -51,6 +51,11 @@ ifneq (${TRUSTED_BOARD_BOOT},0) ...@@ -51,6 +51,11 @@ ifneq (${TRUSTED_BOARD_BOOT},0)
endif endif
$(eval $(call add_define,ARM_ROTPK_LOCATION_ID)) $(eval $(call add_define,ARM_ROTPK_LOCATION_ID))
# Certificate NV-Counters. Use values corresponding to tied off values in
# ARM development platforms
TFW_NVCTR_VAL ?= 31
NTFW_NVCTR_VAL ?= 223
BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c BL1_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c BL2_SOURCES += plat/arm/board/common/board_arm_trusted_boot.c
endif endif
......
...@@ -69,7 +69,13 @@ ...@@ -69,7 +69,13 @@
#define PCIE_EXP_BASE 0x40000000 #define PCIE_EXP_BASE 0x40000000
#define TZRNG_BASE 0x7fe60000 #define TZRNG_BASE 0x7fe60000
#define TZNVCTR_BASE 0x7fe70000
/* Non-volatile counters */
#define TRUSTED_NVCTR_BASE 0x7fe70000
#define TFW_NVCTR_BASE (TRUSTED_NVCTR_BASE + 0x0000)
#define TFW_NVCTR_SIZE 4
#define NTFW_CTR_BASE (TRUSTED_NVCTR_BASE + 0x0004)
#define NTFW_CTR_SIZE 4
/* Keys */ /* Keys */
#define SOC_KEYS_BASE 0x7fe80000 #define SOC_KEYS_BASE 0x7fe80000
......
...@@ -35,12 +35,18 @@ ...@@ -35,12 +35,18 @@
#include <openssl/x509v3.h> #include <openssl/x509v3.h>
/* Extension types supported */ /* Extension types supported */
enum { enum ext_type_e {
EXT_TYPE_NVCOUNTER, EXT_TYPE_NVCOUNTER,
EXT_TYPE_PKEY, EXT_TYPE_PKEY,
EXT_TYPE_HASH EXT_TYPE_HASH
}; };
/* NV-Counter types */
enum nvctr_type_e {
NVCTR_TYPE_TFW,
NVCTR_TYPE_NTFW
};
/* /*
* This structure contains the relevant information to create the extensions * This structure contains the relevant information to create the extensions
* to be included in the certificates. This extensions will be used to * to be included in the certificates. This extensions will be used to
...@@ -50,20 +56,21 @@ typedef struct ext_s { ...@@ -50,20 +56,21 @@ typedef struct ext_s {
const char *oid; /* OID of the extension */ const char *oid; /* OID of the extension */
const char *sn; /* Short name */ const char *sn; /* Short name */
const char *ln; /* Long description */ const char *ln; /* Long description */
const char *opt; /* Command line option to specify data */
const char *help_msg; /* Help message */ const char *help_msg; /* Help message */
const char *arg; /* Argument passed from command line */
int asn1_type; /* OpenSSL ASN1 type of the extension data. int asn1_type; /* OpenSSL ASN1 type of the extension data.
* Supported types are: * Supported types are:
* - V_ASN1_INTEGER * - V_ASN1_INTEGER
* - V_ASN1_OCTET_STRING * - V_ASN1_OCTET_STRING
*/ */
int type; int type; /* See ext_type_e */
const char *opt; /* Command line option to specify data */
/* Extension data (depends on extension type) */ /* Extension attributes (depends on extension type) */
union { union {
const char *fn; /* File with extension data */ int nvctr_type; /* See nvctr_type_e */
int nvcounter; /* Non volatile counter */ int key; /* Index into array of registered public keys */
int key; /* Public key */ } attr;
} data;
int alias; /* In case OpenSSL provides an standard int alias; /* In case OpenSSL provides an standard
* extension of the same type, add the new * extension of the same type, add the new
......
...@@ -196,9 +196,17 @@ static void check_cmd_params(void) ...@@ -196,9 +196,17 @@ static void check_cmd_params(void)
for (j = 0; j < cert->num_ext; j++) { for (j = 0; j < cert->num_ext; j++) {
ext = &extensions[cert->ext[j]]; ext = &extensions[cert->ext[j]];
switch (ext->type) { switch (ext->type) {
case EXT_TYPE_NVCOUNTER:
/* Counter value must be specified */
if ((!ext->optional) && (ext->arg == NULL)) {
ERROR("Value for '%s' not specified\n",
ext->ln);
exit(1);
}
break;
case EXT_TYPE_PKEY: case EXT_TYPE_PKEY:
/* Key filename must be specified */ /* Key filename must be specified */
key = &keys[ext->data.key]; key = &keys[ext->attr.key];
if (!new_keys && key->fn == NULL) { if (!new_keys && key->fn == NULL) {
ERROR("Key '%s' required by '%s' not " ERROR("Key '%s' required by '%s' not "
"specified\n", key->desc, "specified\n", key->desc,
...@@ -211,15 +219,15 @@ static void check_cmd_params(void) ...@@ -211,15 +219,15 @@ static void check_cmd_params(void)
* Binary image must be specified * Binary image must be specified
* unless it is explicitly made optional. * unless it is explicitly made optional.
*/ */
if ((!ext->optional) && (ext->data.fn == NULL)) { if ((!ext->optional) && (ext->arg == NULL)) {
ERROR("Image for '%s' not specified\n", ERROR("Image for '%s' not specified\n",
ext->ln); ext->ln);
exit(1); exit(1);
} }
break; break;
default: default:
ERROR("Unknown extension type in '%s'\n", ERROR("Unknown extension type '%d' in '%s'\n",
ext->ln); ext->type, ext->ln);
exit(1); exit(1);
break; break;
} }
...@@ -259,7 +267,7 @@ int main(int argc, char *argv[]) ...@@ -259,7 +267,7 @@ int main(int argc, char *argv[])
key_t *key = NULL; key_t *key = NULL;
cert_t *cert = NULL; cert_t *cert = NULL;
FILE *file = NULL; FILE *file = NULL;
int i, j, ext_nid; int i, j, ext_nid, nvctr;
int c, opt_idx = 0; int c, opt_idx = 0;
const struct option *cmd_opt; const struct option *cmd_opt;
const char *cur_opt; const char *cur_opt;
...@@ -331,7 +339,7 @@ int main(int argc, char *argv[]) ...@@ -331,7 +339,7 @@ int main(int argc, char *argv[])
case CMD_OPT_EXT: case CMD_OPT_EXT:
cur_opt = cmd_opt_get_name(opt_idx); cur_opt = cmd_opt_get_name(opt_idx);
ext = ext_get_by_opt(cur_opt); ext = ext_get_by_opt(cur_opt);
ext->data.fn = strdup(optarg); ext->arg = strdup(optarg);
break; break;
case CMD_OPT_KEY: case CMD_OPT_KEY:
cur_opt = cmd_opt_get_name(opt_idx); cur_opt = cmd_opt_get_name(opt_idx);
...@@ -420,11 +428,12 @@ int main(int argc, char *argv[]) ...@@ -420,11 +428,12 @@ int main(int argc, char *argv[])
*/ */
switch (ext->type) { switch (ext->type) {
case EXT_TYPE_NVCOUNTER: case EXT_TYPE_NVCOUNTER:
nvctr = atoi(ext->arg);
CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid, CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid,
EXT_CRIT, ext->data.nvcounter)); EXT_CRIT, nvctr));
break; break;
case EXT_TYPE_HASH: case EXT_TYPE_HASH:
if (ext->data.fn == NULL) { if (ext->arg == NULL) {
if (ext->optional) { if (ext->optional) {
/* Include a hash filled with zeros */ /* Include a hash filled with zeros */
memset(md, 0x0, SHA256_DIGEST_LENGTH); memset(md, 0x0, SHA256_DIGEST_LENGTH);
...@@ -434,9 +443,9 @@ int main(int argc, char *argv[]) ...@@ -434,9 +443,9 @@ int main(int argc, char *argv[])
} }
} else { } else {
/* Calculate the hash of the file */ /* Calculate the hash of the file */
if (!sha_file(ext->data.fn, md)) { if (!sha_file(ext->arg, md)) {
ERROR("Cannot calculate hash of %s\n", ERROR("Cannot calculate hash of %s\n",
ext->data.fn); ext->arg);
exit(1); exit(1);
} }
} }
...@@ -446,11 +455,11 @@ int main(int argc, char *argv[]) ...@@ -446,11 +455,11 @@ int main(int argc, char *argv[])
break; break;
case EXT_TYPE_PKEY: case EXT_TYPE_PKEY:
CHECK_NULL(cert_ext, ext_new_key(ext_nid, CHECK_NULL(cert_ext, ext_new_key(ext_nid,
EXT_CRIT, keys[ext->data.key].key)); EXT_CRIT, keys[ext->attr.key].key));
break; break;
default: default:
ERROR("Unknown extension type in %s\n", ERROR("Unknown extension type '%d' in %s\n",
cert->cn); ext->type, cert->cn);
exit(1); exit(1);
} }
......
...@@ -49,9 +49,10 @@ static cert_t tbb_certs[] = { ...@@ -49,9 +49,10 @@ static cert_t tbb_certs[] = {
.key = ROT_KEY, .key = ROT_KEY,
.issuer = TRUSTED_BOOT_FW_CERT, .issuer = TRUSTED_BOOT_FW_CERT,
.ext = { .ext = {
TRUSTED_FW_NVCOUNTER_EXT,
TRUSTED_BOOT_FW_HASH_EXT TRUSTED_BOOT_FW_HASH_EXT
}, },
.num_ext = 1 .num_ext = 2
}, },
[TRUSTED_KEY_CERT] = { [TRUSTED_KEY_CERT] = {
.id = TRUSTED_KEY_CERT, .id = TRUSTED_KEY_CERT,
...@@ -62,10 +63,11 @@ static cert_t tbb_certs[] = { ...@@ -62,10 +63,11 @@ static cert_t tbb_certs[] = {
.key = ROT_KEY, .key = ROT_KEY,
.issuer = TRUSTED_KEY_CERT, .issuer = TRUSTED_KEY_CERT,
.ext = { .ext = {
TRUSTED_FW_NVCOUNTER_EXT,
TRUSTED_WORLD_PK_EXT, TRUSTED_WORLD_PK_EXT,
NON_TRUSTED_WORLD_PK_EXT NON_TRUSTED_WORLD_PK_EXT
}, },
.num_ext = 2 .num_ext = 3
}, },
[SCP_FW_KEY_CERT] = { [SCP_FW_KEY_CERT] = {
.id = SCP_FW_KEY_CERT, .id = SCP_FW_KEY_CERT,
...@@ -76,9 +78,10 @@ static cert_t tbb_certs[] = { ...@@ -76,9 +78,10 @@ static cert_t tbb_certs[] = {
.key = TRUSTED_WORLD_KEY, .key = TRUSTED_WORLD_KEY,
.issuer = SCP_FW_KEY_CERT, .issuer = SCP_FW_KEY_CERT,
.ext = { .ext = {
TRUSTED_FW_NVCOUNTER_EXT,
SCP_FW_CONTENT_CERT_PK_EXT SCP_FW_CONTENT_CERT_PK_EXT
}, },
.num_ext = 1 .num_ext = 2
}, },
[SCP_FW_CONTENT_CERT] = { [SCP_FW_CONTENT_CERT] = {
.id = SCP_FW_CONTENT_CERT, .id = SCP_FW_CONTENT_CERT,
...@@ -89,9 +92,10 @@ static cert_t tbb_certs[] = { ...@@ -89,9 +92,10 @@ static cert_t tbb_certs[] = {
.key = SCP_FW_CONTENT_CERT_KEY, .key = SCP_FW_CONTENT_CERT_KEY,
.issuer = SCP_FW_CONTENT_CERT, .issuer = SCP_FW_CONTENT_CERT,
.ext = { .ext = {
TRUSTED_FW_NVCOUNTER_EXT,
SCP_FW_HASH_EXT SCP_FW_HASH_EXT
}, },
.num_ext = 1 .num_ext = 2
}, },
[SOC_FW_KEY_CERT] = { [SOC_FW_KEY_CERT] = {
.id = SOC_FW_KEY_CERT, .id = SOC_FW_KEY_CERT,
...@@ -102,9 +106,10 @@ static cert_t tbb_certs[] = { ...@@ -102,9 +106,10 @@ static cert_t tbb_certs[] = {
.key = TRUSTED_WORLD_KEY, .key = TRUSTED_WORLD_KEY,
.issuer = SOC_FW_KEY_CERT, .issuer = SOC_FW_KEY_CERT,
.ext = { .ext = {
TRUSTED_FW_NVCOUNTER_EXT,
SOC_FW_CONTENT_CERT_PK_EXT SOC_FW_CONTENT_CERT_PK_EXT
}, },
.num_ext = 1 .num_ext = 2
}, },
[SOC_FW_CONTENT_CERT] = { [SOC_FW_CONTENT_CERT] = {
.id = SOC_FW_CONTENT_CERT, .id = SOC_FW_CONTENT_CERT,
...@@ -115,9 +120,10 @@ static cert_t tbb_certs[] = { ...@@ -115,9 +120,10 @@ static cert_t tbb_certs[] = {
.key = SOC_FW_CONTENT_CERT_KEY, .key = SOC_FW_CONTENT_CERT_KEY,
.issuer = SOC_FW_CONTENT_CERT, .issuer = SOC_FW_CONTENT_CERT,
.ext = { .ext = {
TRUSTED_FW_NVCOUNTER_EXT,
SOC_AP_FW_HASH_EXT SOC_AP_FW_HASH_EXT
}, },
.num_ext = 1 .num_ext = 2
}, },
[TRUSTED_OS_FW_KEY_CERT] = { [TRUSTED_OS_FW_KEY_CERT] = {
.id = TRUSTED_OS_FW_KEY_CERT, .id = TRUSTED_OS_FW_KEY_CERT,
...@@ -128,9 +134,10 @@ static cert_t tbb_certs[] = { ...@@ -128,9 +134,10 @@ static cert_t tbb_certs[] = {
.key = TRUSTED_WORLD_KEY, .key = TRUSTED_WORLD_KEY,
.issuer = TRUSTED_OS_FW_KEY_CERT, .issuer = TRUSTED_OS_FW_KEY_CERT,
.ext = { .ext = {
TRUSTED_FW_NVCOUNTER_EXT,
TRUSTED_OS_FW_CONTENT_CERT_PK_EXT TRUSTED_OS_FW_CONTENT_CERT_PK_EXT
}, },
.num_ext = 1 .num_ext = 2
}, },
[TRUSTED_OS_FW_CONTENT_CERT] = { [TRUSTED_OS_FW_CONTENT_CERT] = {
.id = TRUSTED_OS_FW_CONTENT_CERT, .id = TRUSTED_OS_FW_CONTENT_CERT,
...@@ -141,9 +148,10 @@ static cert_t tbb_certs[] = { ...@@ -141,9 +148,10 @@ static cert_t tbb_certs[] = {
.key = TRUSTED_OS_FW_CONTENT_CERT_KEY, .key = TRUSTED_OS_FW_CONTENT_CERT_KEY,
.issuer = TRUSTED_OS_FW_CONTENT_CERT, .issuer = TRUSTED_OS_FW_CONTENT_CERT,
.ext = { .ext = {
TRUSTED_FW_NVCOUNTER_EXT,
TRUSTED_OS_FW_HASH_EXT TRUSTED_OS_FW_HASH_EXT
}, },
.num_ext = 1 .num_ext = 2
}, },
[NON_TRUSTED_FW_KEY_CERT] = { [NON_TRUSTED_FW_KEY_CERT] = {
.id = NON_TRUSTED_FW_KEY_CERT, .id = NON_TRUSTED_FW_KEY_CERT,
...@@ -154,9 +162,10 @@ static cert_t tbb_certs[] = { ...@@ -154,9 +162,10 @@ static cert_t tbb_certs[] = {
.key = NON_TRUSTED_WORLD_KEY, .key = NON_TRUSTED_WORLD_KEY,
.issuer = NON_TRUSTED_FW_KEY_CERT, .issuer = NON_TRUSTED_FW_KEY_CERT,
.ext = { .ext = {
NON_TRUSTED_FW_NVCOUNTER_EXT,
NON_TRUSTED_FW_CONTENT_CERT_PK_EXT NON_TRUSTED_FW_CONTENT_CERT_PK_EXT
}, },
.num_ext = 1 .num_ext = 2
}, },
[NON_TRUSTED_FW_CONTENT_CERT] = { [NON_TRUSTED_FW_CONTENT_CERT] = {
.id = NON_TRUSTED_FW_CONTENT_CERT, .id = NON_TRUSTED_FW_CONTENT_CERT,
...@@ -167,9 +176,10 @@ static cert_t tbb_certs[] = { ...@@ -167,9 +176,10 @@ static cert_t tbb_certs[] = {
.key = NON_TRUSTED_FW_CONTENT_CERT_KEY, .key = NON_TRUSTED_FW_CONTENT_CERT_KEY,
.issuer = NON_TRUSTED_FW_CONTENT_CERT, .issuer = NON_TRUSTED_FW_CONTENT_CERT,
.ext = { .ext = {
NON_TRUSTED_FW_NVCOUNTER_EXT,
NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT
}, },
.num_ext = 1 .num_ext = 2
}, },
[FWU_CERT] = { [FWU_CERT] = {
.id = FWU_CERT, .id = FWU_CERT,
......
...@@ -44,19 +44,23 @@ ...@@ -44,19 +44,23 @@
static ext_t tbb_ext[] = { static ext_t tbb_ext[] = {
[TRUSTED_FW_NVCOUNTER_EXT] = { [TRUSTED_FW_NVCOUNTER_EXT] = {
.oid = TRUSTED_FW_NVCOUNTER_OID, .oid = TRUSTED_FW_NVCOUNTER_OID,
.opt = "tfw-nvctr",
.help_msg = "Trusted Firmware Non-Volatile counter value",
.sn = "TrustedWorldNVCounter", .sn = "TrustedWorldNVCounter",
.ln = "Trusted World Non-Volatile counter", .ln = "Trusted World Non-Volatile counter",
.asn1_type = V_ASN1_INTEGER, .asn1_type = V_ASN1_INTEGER,
.type = EXT_TYPE_NVCOUNTER, .type = EXT_TYPE_NVCOUNTER,
.data.nvcounter = TRUSTED_WORLD_NVCTR_VALUE .attr.nvctr_type = NVCTR_TYPE_TFW
}, },
[NON_TRUSTED_FW_NVCOUNTER_EXT] = { [NON_TRUSTED_FW_NVCOUNTER_EXT] = {
.oid = NON_TRUSTED_FW_NVCOUNTER_OID, .oid = NON_TRUSTED_FW_NVCOUNTER_OID,
.opt = "ntfw-nvctr",
.help_msg = "Non-Trusted Firmware Non-Volatile counter value",
.sn = "NormalWorldNVCounter", .sn = "NormalWorldNVCounter",
.ln = "Normal World Non-Volatile counter", .ln = "Non-Trusted Firmware Non-Volatile counter",
.asn1_type = V_ASN1_INTEGER, .asn1_type = V_ASN1_INTEGER,
.type = EXT_TYPE_NVCOUNTER, .type = EXT_TYPE_NVCOUNTER,
.data.nvcounter = NORMAL_WORLD_NVCTR_VALUE .attr.nvctr_type = NVCTR_TYPE_NTFW
}, },
[TRUSTED_BOOT_FW_HASH_EXT] = { [TRUSTED_BOOT_FW_HASH_EXT] = {
.oid = TRUSTED_BOOT_FW_HASH_OID, .oid = TRUSTED_BOOT_FW_HASH_OID,
...@@ -73,7 +77,7 @@ static ext_t tbb_ext[] = { ...@@ -73,7 +77,7 @@ static ext_t tbb_ext[] = {
.ln = "Trusted World Public Key", .ln = "Trusted World Public Key",
.asn1_type = V_ASN1_OCTET_STRING, .asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY, .type = EXT_TYPE_PKEY,
.data.key = TRUSTED_WORLD_KEY .attr.key = TRUSTED_WORLD_KEY
}, },
[NON_TRUSTED_WORLD_PK_EXT] = { [NON_TRUSTED_WORLD_PK_EXT] = {
.oid = NON_TRUSTED_WORLD_PK_OID, .oid = NON_TRUSTED_WORLD_PK_OID,
...@@ -81,7 +85,7 @@ static ext_t tbb_ext[] = { ...@@ -81,7 +85,7 @@ static ext_t tbb_ext[] = {
.ln = "Non-Trusted World Public Key", .ln = "Non-Trusted World Public Key",
.asn1_type = V_ASN1_OCTET_STRING, .asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY, .type = EXT_TYPE_PKEY,
.data.key = NON_TRUSTED_WORLD_KEY .attr.key = NON_TRUSTED_WORLD_KEY
}, },
[SCP_FW_CONTENT_CERT_PK_EXT] = { [SCP_FW_CONTENT_CERT_PK_EXT] = {
.oid = SCP_FW_CONTENT_CERT_PK_OID, .oid = SCP_FW_CONTENT_CERT_PK_OID,
...@@ -89,7 +93,7 @@ static ext_t tbb_ext[] = { ...@@ -89,7 +93,7 @@ static ext_t tbb_ext[] = {
.ln = "SCP Firmware content certificate public key", .ln = "SCP Firmware content certificate public key",
.asn1_type = V_ASN1_OCTET_STRING, .asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY, .type = EXT_TYPE_PKEY,
.data.key = SCP_FW_CONTENT_CERT_KEY .attr.key = SCP_FW_CONTENT_CERT_KEY
}, },
[SCP_FW_HASH_EXT] = { [SCP_FW_HASH_EXT] = {
.oid = SCP_FW_HASH_OID, .oid = SCP_FW_HASH_OID,
...@@ -106,7 +110,7 @@ static ext_t tbb_ext[] = { ...@@ -106,7 +110,7 @@ static ext_t tbb_ext[] = {
.ln = "SoC Firmware content certificate public key", .ln = "SoC Firmware content certificate public key",
.asn1_type = V_ASN1_OCTET_STRING, .asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY, .type = EXT_TYPE_PKEY,
.data.key = SOC_FW_CONTENT_CERT_KEY .attr.key = SOC_FW_CONTENT_CERT_KEY
}, },
[SOC_AP_FW_HASH_EXT] = { [SOC_AP_FW_HASH_EXT] = {
.oid = SOC_AP_FW_HASH_OID, .oid = SOC_AP_FW_HASH_OID,
...@@ -123,7 +127,7 @@ static ext_t tbb_ext[] = { ...@@ -123,7 +127,7 @@ static ext_t tbb_ext[] = {
.ln = "Trusted OS Firmware content certificate public key", .ln = "Trusted OS Firmware content certificate public key",
.asn1_type = V_ASN1_OCTET_STRING, .asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY, .type = EXT_TYPE_PKEY,
.data.key = TRUSTED_OS_FW_CONTENT_CERT_KEY .attr.key = TRUSTED_OS_FW_CONTENT_CERT_KEY
}, },
[TRUSTED_OS_FW_HASH_EXT] = { [TRUSTED_OS_FW_HASH_EXT] = {
.oid = TRUSTED_OS_FW_HASH_OID, .oid = TRUSTED_OS_FW_HASH_OID,
...@@ -140,7 +144,7 @@ static ext_t tbb_ext[] = { ...@@ -140,7 +144,7 @@ static ext_t tbb_ext[] = {
.ln = "Non-Trusted Firmware content certificate public key", .ln = "Non-Trusted Firmware content certificate public key",
.asn1_type = V_ASN1_OCTET_STRING, .asn1_type = V_ASN1_OCTET_STRING,
.type = EXT_TYPE_PKEY, .type = EXT_TYPE_PKEY,
.data.key = NON_TRUSTED_FW_CONTENT_CERT_KEY .attr.key = NON_TRUSTED_FW_CONTENT_CERT_KEY
}, },
[NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT] = { [NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT] = {
.oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID, .oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment