diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index 7efaf8afe8c1360d57ad28a2f341c8ada7f6ebc5..8d7b8a52ac934fed8c8982670e13d37d045bf6c7 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -36,6 +36,7 @@ BINARY		:= ${PROJECT}
 OPENSSL_DIR	:= /usr
 
 OBJECTS := src/cert.o \
+           src/cmd_opt.o \
            src/ext.o \
            src/key.o \
            src/main.o \
diff --git a/tools/cert_create/include/cert.h b/tools/cert_create/include/cert.h
index 18129a7d73b03a1021f3b27c9ad87b52d18821d3..11381c93c8ed8070be734f6d0eb01d817f1b2fa9 100644
--- a/tools/cert_create/include/cert.h
+++ b/tools/cert_create/include/cert.h
@@ -54,6 +54,7 @@ typedef struct cert_s cert_t;
 struct cert_s {
 	int id;			/* Unique identifier */
 
+	const char *opt;	/* Command line option to pass filename */
 	const char *fn;		/* Filename to save the certificate */
 	const char *cn;		/* Subject CN (Company Name) */
 
@@ -67,6 +68,8 @@ struct cert_s {
 };
 
 /* Exported API */
+int cert_init(void);
+cert_t *cert_get_by_opt(const char *opt);
 int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value);
 int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk);
 
diff --git a/tools/cert_create/include/cmd_opt.h b/tools/cert_create/include/cmd_opt.h
new file mode 100644
index 0000000000000000000000000000000000000000..ca48d7caf3f1c94c4edf23523cbb071bf8bd9f05
--- /dev/null
+++ b/tools/cert_create/include/cmd_opt.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CMD_OPT_H_
+#define CMD_OPT_H_
+
+#include <getopt.h>
+
+#define CMD_OPT_MAX_NUM			64
+
+/* Supported long command line option types */
+enum {
+	CMD_OPT_CERT,
+	CMD_OPT_KEY,
+	CMD_OPT_EXT
+};
+
+/* Exported API*/
+int cmd_opt_add(const char *name, int has_arg, int val);
+const struct option *cmd_opt_get_array(void);
+const char *cmd_opt_get_name(int idx);
+
+#endif /* CMD_OPT_H_ */
diff --git a/tools/cert_create/include/ext.h b/tools/cert_create/include/ext.h
index 60455e661222257d3e1fcd74e2f1786861998f63..3c65473b0d142457ab2785c8c487211b7fa8d2a7 100644
--- a/tools/cert_create/include/ext.h
+++ b/tools/cert_create/include/ext.h
@@ -56,6 +56,7 @@ typedef struct ext_s {
 				 *   - V_ASN1_OCTET_STRING
 				 */
 	int type;
+	const char *opt;	/* Command line option to specify data */
 	/* Extension data (depends on extension type) */
 	union {
 		const char *fn;	/* File with extension data */
@@ -79,7 +80,8 @@ enum {
 };
 
 /* Exported API */
-int ext_register(ext_t *tbb_ext);
+int ext_init(void);
+ext_t *ext_get_by_opt(const char *opt);
 X509_EXTENSION *ext_new_hash(int nid, int crit, const EVP_MD *md,
 		unsigned char *buf, size_t len);
 X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value);
diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h
index da9f1195a24c5f9552e6aff25cc1713789ae9b13..6995a06339768f9e136dc17abb2a97cfad5e7a1a 100644
--- a/tools/cert_create/include/key.h
+++ b/tools/cert_create/include/key.h
@@ -63,12 +63,15 @@ enum {
  */
 typedef struct key_s {
 	int id;			/* Key id */
+	const char *opt;	/* Command line option to specify a key */
 	const char *desc;	/* Key description (debug purposes) */
 	char *fn;		/* Filename to load/store the key */
 	EVP_PKEY *key;		/* Key container */
 } key_t;
 
 /* Exported API */
+int key_init(void);
+key_t *key_get_by_opt(const char *opt);
 int key_create(key_t *key, int type);
 int key_load(key_t *key, unsigned int *err_code);
 int key_store(key_t *key);
diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c
index e58b10e15e3b22cd6ed930b5af55dc2c51c3d42a..bf526451388afc2650ae869e2f15fc3ec4b23a7e 100644
--- a/tools/cert_create/src/cert.c
+++ b/tools/cert_create/src/cert.c
@@ -39,6 +39,7 @@
 #include <openssl/x509v3.h>
 
 #include "cert.h"
+#include "cmd_opt.h"
 #include "debug.h"
 #include "key.h"
 #include "platform_oid.h"
@@ -179,3 +180,35 @@ int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk)
 	cert->x = x;
 	return 1;
 }
+
+int cert_init(void)
+{
+	cert_t *cert;
+	int rc = 0;
+	unsigned int i;
+
+	for (i = 0; i < num_certs; i++) {
+		cert = &certs[i];
+		rc = cmd_opt_add(cert->opt, required_argument, CMD_OPT_CERT);
+		if (rc != 0) {
+			break;
+		}
+	}
+
+	return rc;
+}
+
+cert_t *cert_get_by_opt(const char *opt)
+{
+	cert_t *cert = NULL;
+	unsigned int i;
+
+	for (i = 0; i < num_certs; i++) {
+		cert = &certs[i];
+		if (0 == strcmp(cert->opt, opt)) {
+			return cert;
+		}
+	}
+
+	return NULL;
+}
diff --git a/tools/cert_create/src/cmd_opt.c b/tools/cert_create/src/cmd_opt.c
new file mode 100644
index 0000000000000000000000000000000000000000..3847b98d424e5c43e0f107536e244588a7a73e3f
--- /dev/null
+++ b/tools/cert_create/src/cmd_opt.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <getopt.h>
+#include <stddef.h>
+#include <cmd_opt.h>
+
+/* Command line options */
+static struct option long_opt[CMD_OPT_MAX_NUM+1];
+static int num_reg_opt;
+
+int cmd_opt_add(const char *name, int has_arg, int val)
+{
+	if (num_reg_opt >= CMD_OPT_MAX_NUM) {
+		return -1;
+	}
+	long_opt[num_reg_opt].name = name;
+	long_opt[num_reg_opt].has_arg = has_arg;
+	long_opt[num_reg_opt].flag = 0;
+	long_opt[num_reg_opt].val = val;
+	num_reg_opt++;
+
+	return 0;
+}
+
+const struct option *cmd_opt_get_array(void)
+{
+	return long_opt;
+}
+
+const char *cmd_opt_get_name(int idx)
+{
+	if (idx >= num_reg_opt) {
+		return NULL;
+	}
+
+	return long_opt[idx].name;
+}
diff --git a/tools/cert_create/src/ext.c b/tools/cert_create/src/ext.c
index 6d09837b03e3d8b6b43dfdc19d505798aa687b69..14aef66134e6624b728266133e34631b01847f64 100644
--- a/tools/cert_create/src/ext.c
+++ b/tools/cert_create/src/ext.c
@@ -35,6 +35,8 @@
 #include <openssl/asn1t.h>
 #include <openssl/err.h>
 #include <openssl/x509v3.h>
+
+#include "cmd_opt.h"
 #include "ext.h"
 
 DECLARE_ASN1_ITEM(ASN1_INTEGER)
@@ -65,13 +67,26 @@ IMPLEMENT_ASN1_FUNCTIONS(HASH)
  *
  * Return: 0 = success, Otherwise: error
  */
-int ext_register(ext_t *exts)
+int ext_init(void)
 {
 	ext_t *ext;
 	X509V3_EXT_METHOD *m;
-	int i = 0, nid, ret;
+	int nid, ret;
+	unsigned int i;
 
-	while ((ext = &exts[i++]) && ext->oid) {
+	for (i = 0; i < num_extensions; i++) {
+		ext = &extensions[i];
+		/* Register command line option */
+		if (ext->opt) {
+			if (cmd_opt_add(ext->opt, required_argument,
+					CMD_OPT_EXT)) {
+				return 1;
+			}
+		}
+		/* Register the extension OID in OpenSSL */
+		if (ext->oid == NULL) {
+			continue;
+		}
 		nid = OBJ_create(ext->oid, ext->sn, ext->ln);
 		if (ext->alias) {
 			X509V3_EXT_add_alias(nid, ext->alias);
@@ -295,3 +310,20 @@ X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k)
 
 	return ex;
 }
+
+ext_t *ext_get_by_opt(const char *opt)
+{
+	ext_t *ext = NULL;
+	unsigned int i;
+
+	/* Sequential search. This is not a performance concern since the number
+	 * of extensions is bounded and the code runs on a host machine */
+	for (i = 0; i < num_extensions; i++) {
+		ext = &extensions[i];
+		if (ext->opt && !strcmp(ext->opt, opt)) {
+			return ext;
+		}
+	}
+
+	return NULL;
+}
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index 6072d9ccee1127ce4e86fea60ead1ad684edecd5..76d528b92ca9ba55c2146b3f307995aec2f32fbe 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -38,6 +38,7 @@
 #include <openssl/pem.h>
 
 #include "cert.h"
+#include "cmd_opt.h"
 #include "debug.h"
 #include "key.h"
 #include "platform_oid.h"
@@ -190,3 +191,40 @@ int key_store(key_t *key)
 
 	return 0;
 }
+
+int key_init(void)
+{
+	key_t *key;
+	int rc = 0;
+	unsigned int i;
+
+	for (i = 0; i < num_keys; i++) {
+		key = &keys[i];
+		if (key->opt != NULL) {
+			rc = cmd_opt_add(key->opt, required_argument,
+					 CMD_OPT_KEY);
+			if (rc != 0) {
+				break;
+			}
+		}
+	}
+
+	return rc;
+}
+
+key_t *key_get_by_opt(const char *opt)
+{
+	key_t *key = NULL;
+	unsigned int i;
+
+	/* Sequential search. This is not a performance concern since the number
+	 * of keys is bounded and the code runs on a host machine */
+	for (i = 0; i < num_keys; i++) {
+		key = &keys[i];
+		if (0 == strcmp(key->opt, opt)) {
+			return key;
+		}
+	}
+
+	return NULL;
+}
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index 29bf4528c1e580bd0f0a4fd5726dad7c9a56ce24..b7ad33fe36804697112ce501b1e4906057c2ae63 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -41,6 +41,7 @@
 #include <openssl/x509v3.h>
 
 #include "cert.h"
+#include "cmd_opt.h"
 #include "debug.h"
 #include "ext.h"
 #include "key.h"
@@ -116,8 +117,6 @@ static int key_alg;
 static int new_keys;
 static int save_keys;
 static int print_cert;
-static int bl30_present;
-static int bl32_present;
 
 /* Info messages created in the Makefile */
 extern const char build_msg[];
@@ -141,43 +140,7 @@ static const char *key_algs_str[] = {
 #endif /* OPENSSL_NO_EC */
 };
 
-/* Command line options */
-static const struct option long_opt[] = {
-	/* Binary images */
-	{"bl2", required_argument, 0, BL2_ID},
-	{"bl30", required_argument, 0, BL30_ID},
-	{"bl31", required_argument, 0, BL31_ID},
-	{"bl32", required_argument, 0, BL32_ID},
-	{"bl33", required_argument, 0, BL33_ID},
-	/* Certificate files */
-	{"bl2-cert", required_argument, 0, BL2_CERT_ID},
-	{"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID},
-	{"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID},
-	{"bl30-cert", required_argument, 0, BL30_CERT_ID},
-	{"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID},
-	{"bl31-cert", required_argument, 0, BL31_CERT_ID},
-	{"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID},
-	{"bl32-cert", required_argument, 0, BL32_CERT_ID},
-	{"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID},
-	{"bl33-cert", required_argument, 0, BL33_CERT_ID},
-	/* Private key files */
-	{"rot-key", required_argument, 0, ROT_KEY_ID},
-	{"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID},
-	{"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID},
-	{"bl30-key", required_argument, 0, BL30_KEY_ID},
-	{"bl31-key", required_argument, 0, BL31_KEY_ID},
-	{"bl32-key", required_argument, 0, BL32_KEY_ID},
-	{"bl33-key", required_argument, 0, BL33_KEY_ID},
-	/* Common options */
-	{"key-alg", required_argument, 0, 'a'},
-	{"help", no_argument, 0, 'h'},
-	{"save-keys", no_argument, 0, 'k'},
-	{"new-chain", no_argument, 0, 'n'},
-	{"print-cert", no_argument, 0, 'p'},
-	{0, 0, 0, 0}
-};
-
-static void print_help(const char *cmd)
+static void print_help(const char *cmd, const struct option *long_opt)
 {
 	int i = 0;
 	printf("\n\n");
@@ -218,74 +181,55 @@ static int get_key_alg(const char *key_alg_str)
 
 static void check_cmd_params(void)
 {
+	cert_t *cert;
+	ext_t *ext;
+	key_t *key;
+	int i, j;
+
 	/* Only save new keys */
 	if (save_keys && !new_keys) {
 		ERROR("Only new keys can be saved to disk\n");
 		exit(1);
 	}
 
-	/* BL2, BL31 and BL33 are mandatory */
-	if (extensions[BL2_HASH_EXT].data.fn == NULL) {
-		ERROR("BL2 image not specified\n");
-		exit(1);
-	}
-
-	if (extensions[BL31_HASH_EXT].data.fn == NULL) {
-		ERROR("BL31 image not specified\n");
-		exit(1);
-	}
-
-	if (extensions[BL33_HASH_EXT].data.fn == NULL) {
-		ERROR("BL33 image not specified\n");
-		exit(1);
-	}
-
-	/* BL30 and BL32 are optional */
-	if (extensions[BL30_HASH_EXT].data.fn != NULL) {
-		bl30_present = 1;
-	}
-
-	if (extensions[BL32_HASH_EXT].data.fn != NULL) {
-		bl32_present = 1;
-	}
-
-	/* TODO: Certificate filenames */
-
-	/* Filenames to store keys must be specified */
-	if (save_keys || !new_keys) {
-		if (keys[ROT_KEY].fn == NULL) {
-			ERROR("ROT key not specified\n");
-			exit(1);
-		}
-
-		if (keys[TRUSTED_WORLD_KEY].fn == NULL) {
-			ERROR("Trusted World key not specified\n");
-			exit(1);
-		}
-
-		if (keys[NON_TRUSTED_WORLD_KEY].fn == NULL) {
-			ERROR("Non-trusted World key not specified\n");
-			exit(1);
-		}
-
-		if (keys[BL31_KEY].fn == NULL) {
-			ERROR("BL31 key not specified\n");
-			exit(1);
-		}
-
-		if (keys[BL33_KEY].fn == NULL) {
-			ERROR("BL33 key not specified\n");
-			exit(1);
-		}
-
-		if (bl30_present && (keys[BL30_KEY].fn == NULL)) {
-			ERROR("BL30 key not specified\n");
-			exit(1);
+	/* Check that all required options have been specified in the
+	 * command line */
+	for (i = 0; i < num_certs; i++) {
+		cert = &certs[i];
+		if (cert->fn == NULL) {
+			/* Certificate not requested. Skip to the next one */
+			continue;
 		}
 
-		if (bl32_present && (keys[BL32_KEY].fn == NULL)) {
-			ERROR("BL32 key not specified\n");
-			exit(1);
+		/* Check that all parameters required to create this certificate
+		 * have been specified in the command line */
+		for (j = 0; j < cert->num_ext; j++) {
+			ext = &extensions[cert->ext[j]];
+			switch (ext->type) {
+			case EXT_TYPE_PKEY:
+				/* Key filename must be specified */
+				key = &keys[ext->data.key];
+				if (!new_keys && key->fn == NULL) {
+					ERROR("Key '%s' required by '%s' not "
+					      "specified\n", key->desc,
+					      cert->cn);
+					exit(1);
+				}
+				break;
+			case EXT_TYPE_HASH:
+				/* Binary image must be specified */
+				if (ext->data.fn == NULL) {
+					ERROR("Image for '%s' not specified\n",
+					      ext->ln);
+					exit(1);
+				}
+				break;
+			default:
+				ERROR("Unknown extension type in '%s'\n",
+				      ext->ln);
+				exit(1);
+				break;
+			}
 		}
 	}
 }
@@ -295,10 +239,13 @@ int main(int argc, char *argv[])
 	STACK_OF(X509_EXTENSION) * sk = NULL;
 	X509_EXTENSION *cert_ext = NULL;
 	ext_t *ext = NULL;
-	cert_t *cert;
+	key_t *key = NULL;
+	cert_t *cert = NULL;
 	FILE *file = NULL;
 	int i, j, ext_nid;
 	int c, opt_idx = 0;
+	const struct option *cmd_opt;
+	const char *cur_opt;
 	unsigned int err_code;
 	unsigned char md[SHA256_DIGEST_LENGTH];
 	const EVP_MD *md_info;
@@ -309,9 +256,37 @@ int main(int argc, char *argv[])
 	/* Set default options */
 	key_alg = KEY_ALG_RSA;
 
+	/* Add common command line options */
+	cmd_opt_add("key-alg", required_argument, 'a');
+	cmd_opt_add("help", no_argument, 'h');
+	cmd_opt_add("save-keys", no_argument, 'k');
+	cmd_opt_add("new-chain", no_argument, 'n');
+	cmd_opt_add("print-cert", no_argument, 'p');
+
+	/* Initialize the certificates */
+	if (cert_init() != 0) {
+		ERROR("Cannot initialize certificates\n");
+		exit(1);
+	}
+
+	/* Initialize the keys */
+	if (key_init() != 0) {
+		ERROR("Cannot initialize keys\n");
+		exit(1);
+	}
+
+	/* Initialize the new types and register OIDs for the extensions */
+	if (ext_init() != 0) {
+		ERROR("Cannot initialize TBB extensions\n");
+		exit(1);
+	}
+
+	/* Get the command line options populated during the initialization */
+	cmd_opt = cmd_opt_get_array();
+
 	while (1) {
 		/* getopt_long stores the option index here. */
-		c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx);
+		c = getopt_long(argc, argv, "ahknp", cmd_opt, &opt_idx);
 
 		/* Detect the end of the options. */
 		if (c == -1) {
@@ -327,7 +302,7 @@ int main(int argc, char *argv[])
 			}
 			break;
 		case 'h':
-			print_help(argv[0]);
+			print_help(argv[0], cmd_opt);
 			break;
 		case 'k':
 			save_keys = 1;
@@ -338,71 +313,20 @@ int main(int argc, char *argv[])
 		case 'p':
 			print_cert = 1;
 			break;
-		case BL2_ID:
-			extensions[BL2_HASH_EXT].data.fn = strdup(optarg);
-			break;
-		case BL30_ID:
-			extensions[BL30_HASH_EXT].data.fn = strdup(optarg);
+		case CMD_OPT_EXT:
+			cur_opt = cmd_opt_get_name(opt_idx);
+			ext = ext_get_by_opt(cur_opt);
+			ext->data.fn = strdup(optarg);
 			break;
-		case BL31_ID:
-			extensions[BL31_HASH_EXT].data.fn = strdup(optarg);
+		case CMD_OPT_KEY:
+			cur_opt = cmd_opt_get_name(opt_idx);
+			key = key_get_by_opt(cur_opt);
+			key->fn = strdup(optarg);
 			break;
-		case BL32_ID:
-			extensions[BL32_HASH_EXT].data.fn = strdup(optarg);
-			break;
-		case BL33_ID:
-			extensions[BL33_HASH_EXT].data.fn = strdup(optarg);
-			break;
-		case BL2_CERT_ID:
-			certs[BL2_CERT].fn = strdup(optarg);
-			break;
-		case TRUSTED_KEY_CERT_ID:
-			certs[TRUSTED_KEY_CERT].fn = strdup(optarg);
-			break;
-		case BL30_KEY_CERT_ID:
-			certs[BL30_KEY_CERT].fn = strdup(optarg);
-			break;
-		case BL30_CERT_ID:
-			certs[BL30_CERT].fn = strdup(optarg);
-			break;
-		case BL31_KEY_CERT_ID:
-			certs[BL31_KEY_CERT].fn = strdup(optarg);
-			break;
-		case BL31_CERT_ID:
-			certs[BL31_CERT].fn = strdup(optarg);
-			break;
-		case BL32_KEY_CERT_ID:
-			certs[BL32_KEY_CERT].fn = strdup(optarg);
-			break;
-		case BL32_CERT_ID:
-			certs[BL32_CERT].fn = strdup(optarg);
-			break;
-		case BL33_KEY_CERT_ID:
-			certs[BL33_KEY_CERT].fn = strdup(optarg);
-			break;
-		case BL33_CERT_ID:
-			certs[BL33_CERT].fn = strdup(optarg);
-			break;
-		case ROT_KEY_ID:
-			keys[ROT_KEY].fn = strdup(optarg);
-			break;
-		case TRUSTED_WORLD_KEY_ID:
-			keys[TRUSTED_WORLD_KEY].fn = strdup(optarg);
-			break;
-		case NON_TRUSTED_WORLD_KEY_ID:
-			keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg);
-			break;
-		case BL30_KEY_ID:
-			keys[BL30_KEY].fn = strdup(optarg);
-			break;
-		case BL31_KEY_ID:
-			keys[BL31_KEY].fn = strdup(optarg);
-			break;
-		case BL32_KEY_ID:
-			keys[BL32_KEY].fn = strdup(optarg);
-			break;
-		case BL33_KEY_ID:
-			keys[BL33_KEY].fn = strdup(optarg);
+		case CMD_OPT_CERT:
+			cur_opt = cmd_opt_get_name(opt_idx);
+			cert = cert_get_by_opt(cur_opt);
+			cert->fn = strdup(optarg);
 			break;
 		case '?':
 		default:
@@ -414,12 +338,6 @@ int main(int argc, char *argv[])
 	/* Check command line arguments */
 	check_cmd_params();
 
-	/* Register the new types and OIDs for the extensions */
-	if (ext_register(extensions) != 0) {
-		ERROR("Cannot register TBB extensions\n");
-		exit(1);
-	}
-
 	/* Indicate SHA256 as image hash algorithm in the certificate
 	 * extension */
 	md_info = EVP_sha256();
@@ -518,7 +436,7 @@ int main(int argc, char *argv[])
 		}
 
 		/* Create certificate. Signed with ROT key */
-		if (!cert_new(cert, VAL_DAYS, 0, sk)) {
+		if (cert->fn && !cert_new(cert, VAL_DAYS, 0, sk)) {
 			ERROR("Cannot create %s\n", cert->cn);
 			exit(1);
 		}
diff --git a/tools/cert_create/src/tbbr/tbb_cert.c b/tools/cert_create/src/tbbr/tbb_cert.c
index d0ae836796dbf490d957eaefa510732cd8403ab7..770bd6a0aac4a38ce5c02c64bc838741a2f2b49f 100644
--- a/tools/cert_create/src/tbbr/tbb_cert.c
+++ b/tools/cert_create/src/tbbr/tbb_cert.c
@@ -42,6 +42,7 @@
 static cert_t tbb_certs[] = {
 	[BL2_CERT] = {
 		.id = BL2_CERT,
+		.opt = "bl2-cert",
 		.fn = NULL,
 		.cn = "BL2 Certificate",
 		.key = ROT_KEY,
@@ -53,6 +54,7 @@ static cert_t tbb_certs[] = {
 	},
 	[TRUSTED_KEY_CERT] = {
 		.id = TRUSTED_KEY_CERT,
+		.opt = "trusted-key-cert",
 		.fn = NULL,
 		.cn = "Trusted Key Certificate",
 		.key = ROT_KEY,
@@ -65,6 +67,7 @@ static cert_t tbb_certs[] = {
 	},
 	[BL30_KEY_CERT] = {
 		.id = BL30_KEY_CERT,
+		.opt = "bl30-key-cert",
 		.fn = NULL,
 		.cn = "BL3-0 Key Certificate",
 		.key = TRUSTED_WORLD_KEY,
@@ -76,6 +79,7 @@ static cert_t tbb_certs[] = {
 	},
 	[BL30_CERT] = {
 		.id = BL30_CERT,
+		.opt = "bl30-cert",
 		.fn = NULL,
 		.cn = "BL3-0 Content Certificate",
 		.key = BL30_KEY,
@@ -87,6 +91,7 @@ static cert_t tbb_certs[] = {
 	},
 	[BL31_KEY_CERT] = {
 		.id = BL31_KEY_CERT,
+		.opt = "bl31-key-cert",
 		.fn = NULL,
 		.cn = "BL3-1 Key Certificate",
 		.key = TRUSTED_WORLD_KEY,
@@ -98,6 +103,7 @@ static cert_t tbb_certs[] = {
 	},
 	[BL31_CERT] = {
 		.id = BL31_CERT,
+		.opt = "bl31-cert",
 		.fn = NULL,
 		.cn = "BL3-1 Content Certificate",
 		.key = BL31_KEY,
@@ -109,6 +115,7 @@ static cert_t tbb_certs[] = {
 	},
 	[BL32_KEY_CERT] = {
 		.id = BL32_KEY_CERT,
+		.opt = "bl32-key-cert",
 		.fn = NULL,
 		.cn = "BL3-2 Key Certificate",
 		.key = TRUSTED_WORLD_KEY,
@@ -120,6 +127,7 @@ static cert_t tbb_certs[] = {
 	},
 	[BL32_CERT] = {
 		.id = BL32_CERT,
+		.opt = "bl32-cert",
 		.fn = NULL,
 		.cn = "BL3-2 Content Certificate",
 		.key = BL32_KEY,
@@ -131,6 +139,7 @@ static cert_t tbb_certs[] = {
 	},
 	[BL33_KEY_CERT] = {
 		.id = BL33_KEY_CERT,
+		.opt = "bl33-key-cert",
 		.fn = NULL,
 		.cn = "BL3-3 Key Certificate",
 		.key = NON_TRUSTED_WORLD_KEY,
@@ -142,6 +151,7 @@ static cert_t tbb_certs[] = {
 	},
 	[BL33_CERT] = {
 		.id = BL33_CERT,
+		.opt = "bl33-cert",
 		.fn = NULL,
 		.cn = "BL3-3 Content Certificate",
 		.key = BL33_KEY,
diff --git a/tools/cert_create/src/tbbr/tbb_ext.c b/tools/cert_create/src/tbbr/tbb_ext.c
index c4816df247eb8a10278e744dbe45cbe799fd4229..c39c9e6a41749ad047bcb0e3cb6ad94b1ad8053e 100644
--- a/tools/cert_create/src/tbbr/tbb_ext.c
+++ b/tools/cert_create/src/tbbr/tbb_ext.c
@@ -60,6 +60,7 @@ static ext_t tbb_ext[] = {
 	},
 	[BL2_HASH_EXT] = {
 		.oid = BL2_HASH_OID,
+		.opt = "bl2",
 		.sn = "TrustedBootFirmwareHash",
 		.ln = "Trusted Boot Firmware (BL2) hash (SHA256)",
 		.asn1_type = V_ASN1_OCTET_STRING,
@@ -91,6 +92,7 @@ static ext_t tbb_ext[] = {
 	},
 	[BL30_HASH_EXT] = {
 		.oid = BL30_HASH_OID,
+		.opt = "bl30",
 		.sn = "SCPFirmwareHash",
 		.ln = "SCP Firmware (BL30) hash (SHA256)",
 		.asn1_type = V_ASN1_OCTET_STRING,
@@ -106,6 +108,7 @@ static ext_t tbb_ext[] = {
 	},
 	[BL31_HASH_EXT] = {
 		.oid = BL31_HASH_OID,
+		.opt = "bl31",
 		.sn = "SoCAPFirmwareHash",
 		.ln = "SoC AP Firmware (BL31) hash (SHA256)",
 		.asn1_type = V_ASN1_OCTET_STRING,
@@ -121,6 +124,7 @@ static ext_t tbb_ext[] = {
 	},
 	[BL32_HASH_EXT] = {
 		.oid = BL32_HASH_OID,
+		.opt = "bl32",
 		.sn = "TrustedOSHash",
 		.ln = "Trusted OS (BL32) hash (SHA256)",
 		.asn1_type = V_ASN1_OCTET_STRING,
@@ -136,6 +140,7 @@ static ext_t tbb_ext[] = {
 	},
 	[BL33_HASH_EXT] = {
 		.oid = BL33_HASH_OID,
+		.opt = "bl33",
 		.sn = "NonTrustedWorldBootloaderHash",
 		.ln = "Non-Trusted World (BL33) hash (SHA256)",
 		.asn1_type = V_ASN1_OCTET_STRING,
diff --git a/tools/cert_create/src/tbbr/tbb_key.c b/tools/cert_create/src/tbbr/tbb_key.c
index 36855599c75651df8afee1dc1a2e0ffb696768fe..eaaf1ff1e813ac053fc45f682b49455ef5677faf 100644
--- a/tools/cert_create/src/tbbr/tbb_key.c
+++ b/tools/cert_create/src/tbbr/tbb_key.c
@@ -38,30 +38,37 @@
 static key_t tbb_keys[] = {
 	[ROT_KEY] = {
 		.id = ROT_KEY,
+		.opt = "rot-key",
 		.desc = "Root Of Trust key"
 	},
 	[TRUSTED_WORLD_KEY] = {
 		.id = TRUSTED_WORLD_KEY,
+		.opt = "trusted-world-key",
 		.desc = "Trusted World key"
 	},
 	[NON_TRUSTED_WORLD_KEY] = {
 		.id = NON_TRUSTED_WORLD_KEY,
+		.opt = "non-trusted-world-key",
 		.desc = "Non Trusted World key"
 	},
 	[BL30_KEY] = {
 		.id = BL30_KEY,
+		.opt = "bl30-key",
 		.desc = "BL30 key"
 	},
 	[BL31_KEY] = {
 		.id = BL31_KEY,
+		.opt = "bl31-key",
 		.desc = "BL31 key"
 	},
 	[BL32_KEY] = {
 		.id = BL32_KEY,
+		.opt = "bl32-key",
 		.desc = "BL32 key"
 	},
 	[BL33_KEY] = {
 		.id = BL33_KEY,
+		.opt = "bl33-key",
 		.desc = "BL33 key"
 	}
 };