cert_create: add non-volatile counter support
authorJuan Castillo <juan.castillo@arm.com>
Fri, 22 Jan 2016 11:05:24 +0000 (11:05 +0000)
committerJuan Castillo <juan.castillo@arm.com>
Wed, 30 Mar 2016 13:46:30 +0000 (14:46 +0100)
This patch adds non-volatile counter support to the Certificate
Generation tool. The TBBR Chain of Trust definition in the tool
has been extended to include the counters as certificate extensions.
The counter values can be specified in the command line.

The following default counter values are specified in the build
system:

  * Trusted FW Non-Volatile counter = 0
  * Non-Trusted FW Non-Volatile counter = 0

These values can be overridden by the platform at build time.

Change-Id: I7ea10ee78d72748d181df4ee78a7169b3ef2720c

make_helpers/tbbr/tbbr_tools.mk
tools/cert_create/include/ext.h
tools/cert_create/src/main.c
tools/cert_create/src/tbbr/tbb_cert.c
tools/cert_create/src/tbbr/tbb_ext.c

index e934d7203cc491a87f384f3435dc38416c9971ac..71d9747358f10e320dfff7f0ef94c758590857d7 100644 (file)
 TRUSTED_KEY_CERT       :=      ${BUILD_PLAT}/trusted_key.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
 $(eval $(call FIP_ADD_PAYLOAD,${TRUSTED_KEY_CERT},--trusted-key-cert))
 $(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_KEY_CERT},--trusted-key-cert))
index 82a4bcb96f9f8ad150c55e5751320bf22a1028c9..95bde6ce6a4f590288955f1383780a72d0c5c6e3 100644 (file)
 #include <openssl/x509v3.h>
 
 /* Extension types supported */
-enum {
+enum ext_type_e {
        EXT_TYPE_NVCOUNTER,
        EXT_TYPE_PKEY,
        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
  * to be included in the certificates. This extensions will be used to
@@ -50,20 +56,21 @@ typedef struct ext_s {
        const char *oid;        /* OID of the extension */
        const char *sn;         /* Short name */
        const char *ln;         /* Long description */
+       const char *opt;        /* Command line option to specify data */
        const char *help_msg;   /* Help message */
+       const char *arg;        /* Argument passed from command line */
        int asn1_type;          /* OpenSSL ASN1 type of the extension data.
                                 * Supported types are:
                                 *   - V_ASN1_INTEGER
                                 *   - V_ASN1_OCTET_STRING
                                 */
-       int type;
-       const char *opt;        /* Command line option to specify data */
-       /* Extension data (depends on extension type) */
+       int type;               /* See ext_type_e */
+
+       /* Extension attributes (depends on extension type) */
        union {
-               const char *fn; /* File with extension data */
-               int nvcounter;  /* Non volatile counter */
-               int key;        /* Public key */
-       } data;
+               int nvctr_type; /* See nvctr_type_e */
+               int key;        /* Index into array of registered public keys */
+       } attr;
 
        int alias;              /* In case OpenSSL provides an standard
                                 * extension of the same type, add the new
index 3d2b4ba252a01f73530f12b04c9c8f6b269caf7b..c87d9888dd0fa98f0e2b01a3e2ee90afabe3d260 100644 (file)
@@ -196,9 +196,17 @@ static void check_cmd_params(void)
                for (j = 0; j < cert->num_ext; j++) {
                        ext = &extensions[cert->ext[j]];
                        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:
                                /* Key filename must be specified */
-                               key = &keys[ext->data.key];
+                               key = &keys[ext->attr.key];
                                if (!new_keys && key->fn == NULL) {
                                        ERROR("Key '%s' required by '%s' not "
                                              "specified\n", key->desc,
@@ -211,15 +219,15 @@ static void check_cmd_params(void)
                                 * Binary image must be specified
                                 * 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",
                                              ext->ln);
                                        exit(1);
                                }
                                break;
                        default:
-                               ERROR("Unknown extension type in '%s'\n",
-                                     ext->ln);
+                               ERROR("Unknown extension type '%d' in '%s'\n",
+                                     ext->type, ext->ln);
                                exit(1);
                                break;
                        }
@@ -259,7 +267,7 @@ int main(int argc, char *argv[])
        key_t *key = NULL;
        cert_t *cert = NULL;
        FILE *file = NULL;
-       int i, j, ext_nid;
+       int i, j, ext_nid, nvctr;
        int c, opt_idx = 0;
        const struct option *cmd_opt;
        const char *cur_opt;
@@ -331,7 +339,7 @@ int main(int argc, char *argv[])
                case CMD_OPT_EXT:
                        cur_opt = cmd_opt_get_name(opt_idx);
                        ext = ext_get_by_opt(cur_opt);
-                       ext->data.fn = strdup(optarg);
+                       ext->arg = strdup(optarg);
                        break;
                case CMD_OPT_KEY:
                        cur_opt = cmd_opt_get_name(opt_idx);
@@ -420,11 +428,12 @@ int main(int argc, char *argv[])
                         */
                        switch (ext->type) {
                        case EXT_TYPE_NVCOUNTER:
+                               nvctr = atoi(ext->arg);
                                CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid,
-                                               EXT_CRIT, ext->data.nvcounter));
+                                               EXT_CRIT, nvctr));
                                break;
                        case EXT_TYPE_HASH:
-                               if (ext->data.fn == NULL) {
+                               if (ext->arg == NULL) {
                                        if (ext->optional) {
                                                /* Include a hash filled with zeros */
                                                memset(md, 0x0, SHA256_DIGEST_LENGTH);
@@ -434,9 +443,9 @@ int main(int argc, char *argv[])
                                        }
                                } else {
                                        /* 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",
-                                                       ext->data.fn);
+                                                       ext->arg);
                                                exit(1);
                                        }
                                }
@@ -446,11 +455,11 @@ int main(int argc, char *argv[])
                                break;
                        case EXT_TYPE_PKEY:
                                CHECK_NULL(cert_ext, ext_new_key(ext_nid,
-                                       EXT_CRIT, keys[ext->data.key].key));
+                                       EXT_CRIT, keys[ext->attr.key].key));
                                break;
                        default:
-                               ERROR("Unknown extension type in %s\n",
-                                               cert->cn);
+                               ERROR("Unknown extension type '%d' in %s\n",
+                                               ext->type, cert->cn);
                                exit(1);
                        }
 
index 7a50ab3550952e04c30ea62b42eccc17d988e82e..8f7feb51cde8a7112ab16e3622ae80a3fdc31ad4 100644 (file)
@@ -49,9 +49,10 @@ static cert_t tbb_certs[] = {
                .key = ROT_KEY,
                .issuer = TRUSTED_BOOT_FW_CERT,
                .ext = {
+                       TRUSTED_FW_NVCOUNTER_EXT,
                        TRUSTED_BOOT_FW_HASH_EXT
                },
-               .num_ext = 1
+               .num_ext = 2
        },
        [TRUSTED_KEY_CERT] = {
                .id = TRUSTED_KEY_CERT,
@@ -62,10 +63,11 @@ static cert_t tbb_certs[] = {
                .key = ROT_KEY,
                .issuer = TRUSTED_KEY_CERT,
                .ext = {
+                       TRUSTED_FW_NVCOUNTER_EXT,
                        TRUSTED_WORLD_PK_EXT,
                        NON_TRUSTED_WORLD_PK_EXT
                },
-               .num_ext = 2
+               .num_ext = 3
        },
        [SCP_FW_KEY_CERT] = {
                .id = SCP_FW_KEY_CERT,
@@ -76,9 +78,10 @@ static cert_t tbb_certs[] = {
                .key = TRUSTED_WORLD_KEY,
                .issuer = SCP_FW_KEY_CERT,
                .ext = {
+                       TRUSTED_FW_NVCOUNTER_EXT,
                        SCP_FW_CONTENT_CERT_PK_EXT
                },
-               .num_ext = 1
+               .num_ext = 2
        },
        [SCP_FW_CONTENT_CERT] = {
                .id = SCP_FW_CONTENT_CERT,
@@ -89,9 +92,10 @@ static cert_t tbb_certs[] = {
                .key = SCP_FW_CONTENT_CERT_KEY,
                .issuer = SCP_FW_CONTENT_CERT,
                .ext = {
+                       TRUSTED_FW_NVCOUNTER_EXT,
                        SCP_FW_HASH_EXT
                },
-               .num_ext = 1
+               .num_ext = 2
        },
        [SOC_FW_KEY_CERT] = {
                .id = SOC_FW_KEY_CERT,
@@ -102,9 +106,10 @@ static cert_t tbb_certs[] = {
                .key = TRUSTED_WORLD_KEY,
                .issuer = SOC_FW_KEY_CERT,
                .ext = {
+                       TRUSTED_FW_NVCOUNTER_EXT,
                        SOC_FW_CONTENT_CERT_PK_EXT
                },
-               .num_ext = 1
+               .num_ext = 2
        },
        [SOC_FW_CONTENT_CERT] = {
                .id = SOC_FW_CONTENT_CERT,
@@ -115,9 +120,10 @@ static cert_t tbb_certs[] = {
                .key = SOC_FW_CONTENT_CERT_KEY,
                .issuer = SOC_FW_CONTENT_CERT,
                .ext = {
+                       TRUSTED_FW_NVCOUNTER_EXT,
                        SOC_AP_FW_HASH_EXT
                },
-               .num_ext = 1
+               .num_ext = 2
        },
        [TRUSTED_OS_FW_KEY_CERT] = {
                .id = TRUSTED_OS_FW_KEY_CERT,
@@ -128,9 +134,10 @@ static cert_t tbb_certs[] = {
                .key = TRUSTED_WORLD_KEY,
                .issuer = TRUSTED_OS_FW_KEY_CERT,
                .ext = {
+                       TRUSTED_FW_NVCOUNTER_EXT,
                        TRUSTED_OS_FW_CONTENT_CERT_PK_EXT
                },
-               .num_ext = 1
+               .num_ext = 2
        },
        [TRUSTED_OS_FW_CONTENT_CERT] = {
                .id = TRUSTED_OS_FW_CONTENT_CERT,
@@ -141,9 +148,10 @@ static cert_t tbb_certs[] = {
                .key = TRUSTED_OS_FW_CONTENT_CERT_KEY,
                .issuer = TRUSTED_OS_FW_CONTENT_CERT,
                .ext = {
+                       TRUSTED_FW_NVCOUNTER_EXT,
                        TRUSTED_OS_FW_HASH_EXT
                },
-               .num_ext = 1
+               .num_ext = 2
        },
        [NON_TRUSTED_FW_KEY_CERT] = {
                .id = NON_TRUSTED_FW_KEY_CERT,
@@ -154,9 +162,10 @@ static cert_t tbb_certs[] = {
                .key = NON_TRUSTED_WORLD_KEY,
                .issuer = NON_TRUSTED_FW_KEY_CERT,
                .ext = {
+                       NON_TRUSTED_FW_NVCOUNTER_EXT,
                        NON_TRUSTED_FW_CONTENT_CERT_PK_EXT
                },
-               .num_ext = 1
+               .num_ext = 2
        },
        [NON_TRUSTED_FW_CONTENT_CERT] = {
                .id = NON_TRUSTED_FW_CONTENT_CERT,
@@ -167,9 +176,10 @@ static cert_t tbb_certs[] = {
                .key = NON_TRUSTED_FW_CONTENT_CERT_KEY,
                .issuer = NON_TRUSTED_FW_CONTENT_CERT,
                .ext = {
+                       NON_TRUSTED_FW_NVCOUNTER_EXT,
                        NON_TRUSTED_WORLD_BOOTLOADER_HASH_EXT
                },
-               .num_ext = 1
+               .num_ext = 2
        },
        [FWU_CERT] = {
                .id = FWU_CERT,
index 8bcb0704d376f5681b6bb12671f2b0198126277b..5304bd5e3eeeba9253a900131165fb7c7cb858b2 100644 (file)
 static ext_t tbb_ext[] = {
        [TRUSTED_FW_NVCOUNTER_EXT] = {
                .oid = TRUSTED_FW_NVCOUNTER_OID,
+               .opt = "tfw-nvctr",
+               .help_msg = "Trusted Firmware Non-Volatile counter value",
                .sn = "TrustedWorldNVCounter",
                .ln = "Trusted World Non-Volatile counter",
                .asn1_type = V_ASN1_INTEGER,
                .type = EXT_TYPE_NVCOUNTER,
-               .data.nvcounter = TRUSTED_WORLD_NVCTR_VALUE
+               .attr.nvctr_type = NVCTR_TYPE_TFW
        },
        [NON_TRUSTED_FW_NVCOUNTER_EXT] = {
                .oid = NON_TRUSTED_FW_NVCOUNTER_OID,
+               .opt = "ntfw-nvctr",
+               .help_msg = "Non-Trusted Firmware Non-Volatile counter value",
                .sn = "NormalWorldNVCounter",
-               .ln = "Normal World Non-Volatile counter",
+               .ln = "Non-Trusted Firmware Non-Volatile counter",
                .asn1_type = V_ASN1_INTEGER,
                .type = EXT_TYPE_NVCOUNTER,
-               .data.nvcounter = NORMAL_WORLD_NVCTR_VALUE
+               .attr.nvctr_type = NVCTR_TYPE_NTFW
        },
        [TRUSTED_BOOT_FW_HASH_EXT] = {
                .oid = TRUSTED_BOOT_FW_HASH_OID,
@@ -73,7 +77,7 @@ static ext_t tbb_ext[] = {
                .ln = "Trusted World Public Key",
                .asn1_type = V_ASN1_OCTET_STRING,
                .type = EXT_TYPE_PKEY,
-               .data.key = TRUSTED_WORLD_KEY
+               .attr.key = TRUSTED_WORLD_KEY
        },
        [NON_TRUSTED_WORLD_PK_EXT] = {
                .oid = NON_TRUSTED_WORLD_PK_OID,
@@ -81,7 +85,7 @@ static ext_t tbb_ext[] = {
                .ln = "Non-Trusted World Public Key",
                .asn1_type = V_ASN1_OCTET_STRING,
                .type = EXT_TYPE_PKEY,
-               .data.key = NON_TRUSTED_WORLD_KEY
+               .attr.key = NON_TRUSTED_WORLD_KEY
        },
        [SCP_FW_CONTENT_CERT_PK_EXT] = {
                .oid = SCP_FW_CONTENT_CERT_PK_OID,
@@ -89,7 +93,7 @@ static ext_t tbb_ext[] = {
                .ln = "SCP Firmware content certificate public key",
                .asn1_type = V_ASN1_OCTET_STRING,
                .type = EXT_TYPE_PKEY,
-               .data.key = SCP_FW_CONTENT_CERT_KEY
+               .attr.key = SCP_FW_CONTENT_CERT_KEY
        },
        [SCP_FW_HASH_EXT] = {
                .oid = SCP_FW_HASH_OID,
@@ -106,7 +110,7 @@ static ext_t tbb_ext[] = {
                .ln = "SoC Firmware content certificate public key",
                .asn1_type = V_ASN1_OCTET_STRING,
                .type = EXT_TYPE_PKEY,
-               .data.key = SOC_FW_CONTENT_CERT_KEY
+               .attr.key = SOC_FW_CONTENT_CERT_KEY
        },
        [SOC_AP_FW_HASH_EXT] = {
                .oid = SOC_AP_FW_HASH_OID,
@@ -123,7 +127,7 @@ static ext_t tbb_ext[] = {
                .ln = "Trusted OS Firmware content certificate public key",
                .asn1_type = V_ASN1_OCTET_STRING,
                .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] = {
                .oid = TRUSTED_OS_FW_HASH_OID,
@@ -140,7 +144,7 @@ static ext_t tbb_ext[] = {
                .ln = "Non-Trusted Firmware content certificate public key",
                .asn1_type = V_ASN1_OCTET_STRING,
                .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] = {
                .oid = NON_TRUSTED_WORLD_BOOTLOADER_HASH_OID,