summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/cert_create/Makefile92
-rw-r--r--tools/cert_create/include/cert.h69
-rw-r--r--tools/cert_create/include/debug.h83
-rw-r--r--tools/cert_create/include/ext.h70
-rw-r--r--tools/cert_create/include/key.h57
-rw-r--r--tools/cert_create/include/sha.h36
-rw-r--r--tools/cert_create/include/tbb_cert.h58
-rw-r--r--tools/cert_create/include/tbb_ext.h38
-rw-r--r--tools/cert_create/include/tbb_key.h55
-rw-r--r--tools/cert_create/src/cert.c180
-rw-r--r--tools/cert_create/src/ext.c233
-rw-r--r--tools/cert_create/src/key.c131
-rw-r--r--tools/cert_create/src/main.c719
-rw-r--r--tools/cert_create/src/sha.c64
-rw-r--r--tools/cert_create/src/tbb_cert.c111
-rw-r--r--tools/cert_create/src/tbb_ext.c118
-rw-r--r--tools/cert_create/src/tbb_key.c67
17 files changed, 2181 insertions, 0 deletions
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
new file mode 100644
index 00000000..f1aa7974
--- /dev/null
+++ b/tools/cert_create/Makefile
@@ -0,0 +1,92 @@
+#
+# 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.
+#
+
+PROJECT := cert_create
+PLAT := none
+V := 0
+DEBUG := 0
+BINARY := ${PROJECT}
+
+OBJECTS := src/cert.o \
+ src/ext.o \
+ src/key.o \
+ src/main.o \
+ src/tbb_cert.o \
+ src/tbb_ext.o \
+ src/tbb_key.o \
+ src/sha.o
+
+CFLAGS := -Wall -std=c99
+
+# Check the platform
+ifeq (${PLAT},none)
+ $(error Error: No platform defined. Use PLAT=<platform>.)
+endif
+
+ifeq (${DEBUG},1)
+ CFLAGS += -g -O0 -DDEBUG -DLOG_LEVEL=40
+else
+ CFLAGS += -O2 -DLOG_LEVEL=20
+endif
+ifeq (${V},0)
+ Q := @
+else
+ Q :=
+endif
+
+# Make soft links and include from local directory otherwise wrong headers
+# could get pulled in from firmware tree.
+INC_DIR := -I ./include -I ../../plat/${PLAT}/include
+LIB_DIR :=
+LIB := -lssl -lcrypto
+
+CC := gcc
+RM := rm -rf
+
+.PHONY: all clean
+
+all: clean ${BINARY}
+
+${BINARY}: ${OBJECTS} Makefile
+ @echo " LD $@"
+ @echo 'const char build_msg[] = "Built : "__TIME__", "__DATE__; \
+ const char platform_msg[] = "${PLAT}";' | \
+ ${CC} -c ${CFLAGS} -xc - -o src/build_msg.o
+ ${Q}${CC} src/build_msg.o ${OBJECTS} ${LIB_DIR} ${LIB} -o $@
+
+%.o: %.c
+ @echo " CC $<"
+ ${Q}${CC} -c ${CFLAGS} ${INC_DIR} $< -o $@
+
+clean:
+ ${Q}${RM} -f src/build_msg.o ${OBJECTS}
+
+realclean: clean
+ ${Q}${RM} -f ${BINARY}
diff --git a/tools/cert_create/include/cert.h b/tools/cert_create/include/cert.h
new file mode 100644
index 00000000..48a41462
--- /dev/null
+++ b/tools/cert_create/include/cert.h
@@ -0,0 +1,69 @@
+/*
+ * 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 CERT_H_
+#define CERT_H_
+
+#include <openssl/ossl_typ.h>
+#include <openssl/x509.h>
+#include "key.h"
+
+/*
+ * This structure contains information related to the generation of the
+ * certificates. All these fields must be known and specified at build time
+ * except for the file name, which is picked up from the command line at
+ * run time.
+ *
+ * One instance of this structure must be created for each of the certificates
+ * present in the chain of trust.
+ *
+ * If the issuer points to this same instance, the generated certificate will
+ * be self-signed.
+ */
+typedef struct cert_s cert_t;
+struct cert_s {
+ int id; /* Unique identifier */
+
+ const char *fn; /* Filename to save the certificate */
+ const char *bin; /* Image associated to this certificate */
+
+ const char *cn; /* Subject CN (Company Name) */
+
+ X509 *x; /* X509 certificate container */
+ key_t *key; /* Key to be signed */
+
+ cert_t *issuer; /* Issuer certificate */
+};
+
+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);
+
+#endif /* CERT_H_ */
diff --git a/tools/cert_create/include/debug.h b/tools/cert_create/include/debug.h
new file mode 100644
index 00000000..dd0510a5
--- /dev/null
+++ b/tools/cert_create/include/debug.h
@@ -0,0 +1,83 @@
+/*
+ * 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 __DEBUG_H__
+#define __DEBUG_H__
+
+#include <stdio.h>
+
+/* The log output macros print output to the console. These macros produce
+ * compiled log output only if the LOG_LEVEL defined in the makefile (or the
+ * make command line) is greater or equal than the level required for that
+ * type of log output.
+ * The format expected is the same as for printf(). For example:
+ * INFO("Info %s.\n", "message") -> INFO: Info message.
+ * WARN("Warning %s.\n", "message") -> WARNING: Warning message.
+ */
+
+#define LOG_LEVEL_NONE 0
+#define LOG_LEVEL_ERROR 10
+#define LOG_LEVEL_NOTICE 20
+#define LOG_LEVEL_WARNING 30
+#define LOG_LEVEL_INFO 40
+#define LOG_LEVEL_VERBOSE 50
+
+
+#if LOG_LEVEL >= LOG_LEVEL_NOTICE
+# define NOTICE(...) printf("NOTICE: " __VA_ARGS__)
+#else
+# define NOTICE(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_ERROR
+# define ERROR(...) printf("ERROR: " __VA_ARGS__)
+#else
+# define ERROR(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_WARNING
+# define WARN(...) printf("WARNING: " __VA_ARGS__)
+#else
+# define WARN(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_INFO
+# define INFO(...) printf("INFO: " __VA_ARGS__)
+#else
+# define INFO(...)
+#endif
+
+#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
+# define VERBOSE(...) printf("VERBOSE: " __VA_ARGS__)
+#else
+# define VERBOSE(...)
+#endif
+
+#endif /* __DEBUG_H__ */
diff --git a/tools/cert_create/include/ext.h b/tools/cert_create/include/ext.h
new file mode 100644
index 00000000..d73f5734
--- /dev/null
+++ b/tools/cert_create/include/ext.h
@@ -0,0 +1,70 @@
+/*
+ * 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 EXT_H_
+#define EXT_H_
+
+#include <openssl/x509v3.h>
+
+/*
+ * This structure contains the relevant information to create the extensions
+ * to be included in the certificates. This extensions will be used to
+ * establish the chain of trust.
+ */
+typedef struct ext_s {
+ const char *oid; /* OID of the extension */
+ const char *sn; /* Short name */
+ const char *ln; /* Long description */
+ int type; /* OpenSSL ASN1 type of the extension data.
+ * Supported types are:
+ * - V_ASN1_INTEGER
+ * - V_ASN1_OCTET_STRING
+ */
+ int alias; /* In case OpenSSL provides an standard
+ * extension of the same type, add the new
+ * extension as an alias of this one
+ */
+
+ X509V3_EXT_METHOD method; /* This field may be used to define a custom
+ * function to print the contents of the
+ * extension */
+} ext_t;
+
+enum {
+ EXT_NON_CRIT = 0,
+ EXT_CRIT = !EXT_NON_CRIT,
+};
+
+int ext_init(ext_t *tbb_ext);
+X509_EXTENSION *ext_new_hash(int nid, int crit, unsigned char *buf, size_t len);
+X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value);
+X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k);
+
+#endif /* EXT_H_ */
diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h
new file mode 100644
index 00000000..88197500
--- /dev/null
+++ b/tools/cert_create/include/key.h
@@ -0,0 +1,57 @@
+/*
+ * 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 KEY_H_
+#define KEY_H_
+
+#include <openssl/ossl_typ.h>
+
+#define RSA_KEY_BITS 2048
+
+/*
+ * This structure contains the relevant information to create the keys
+ * required to sign the certificates.
+ *
+ * One instance of this structure must be created for each key, usually in an
+ * array fashion. The filename is obtained at run time from the command line
+ * parameters
+ */
+typedef struct key_s {
+ int id; /* Key id */
+ const char *desc; /* Key description (debug purposes) */
+ char *fn; /* Filename to load/store the key */
+ EVP_PKEY *key; /* Key container */
+} key_t;
+
+int key_new(key_t *key);
+int key_load(key_t *key);
+int key_store(key_t *key);
+
+#endif /* KEY_H_ */
diff --git a/tools/cert_create/include/sha.h b/tools/cert_create/include/sha.h
new file mode 100644
index 00000000..466d6689
--- /dev/null
+++ b/tools/cert_create/include/sha.h
@@ -0,0 +1,36 @@
+/*
+ * 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 SHA_H_
+#define SHA_H_
+
+int sha_file(const char *filename, unsigned char *md);
+
+#endif /* SHA_H_ */
diff --git a/tools/cert_create/include/tbb_cert.h b/tools/cert_create/include/tbb_cert.h
new file mode 100644
index 00000000..4e481258
--- /dev/null
+++ b/tools/cert_create/include/tbb_cert.h
@@ -0,0 +1,58 @@
+/*
+ * 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 TBB_CERT_H_
+#define TBB_CERT_H_
+
+#include "cert.h"
+
+/*
+ * Enumerate the certificates that are used to establish the chain of trust
+ */
+enum {
+ BL2_CERT,
+ TRUSTED_KEY_CERT,
+ BL30_KEY_CERT,
+ BL30_CERT,
+ BL31_KEY_CERT,
+ BL31_CERT,
+ BL32_KEY_CERT,
+ BL32_CERT,
+ BL33_KEY_CERT,
+ BL33_CERT,
+ NUM_CERTIFICATES,
+};
+
+/*
+ * Array containing the certificate instances
+ */
+extern cert_t certs[NUM_CERTIFICATES];
+
+#endif /* TBB_CERT_H_ */
diff --git a/tools/cert_create/include/tbb_ext.h b/tools/cert_create/include/tbb_ext.h
new file mode 100644
index 00000000..155d3cb4
--- /dev/null
+++ b/tools/cert_create/include/tbb_ext.h
@@ -0,0 +1,38 @@
+/*
+ * 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 TBB_EXT_H_
+#define TBB_EXT_H_
+
+#include "ext.h"
+
+/* Array containing the extensions used in the chain of trust */
+extern ext_t tbb_ext[];
+
+#endif /* TBB_EXT_H_ */
diff --git a/tools/cert_create/include/tbb_key.h b/tools/cert_create/include/tbb_key.h
new file mode 100644
index 00000000..cc927d1e
--- /dev/null
+++ b/tools/cert_create/include/tbb_key.h
@@ -0,0 +1,55 @@
+/*
+ * 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 TBB_KEY_H_
+#define TBB_KEY_H_
+
+#include "key.h"
+
+/*
+ * Enumerate the keys that are used to establish the chain of trust
+ */
+enum {
+ ROT_KEY,
+ TRUSTED_WORLD_KEY,
+ NON_TRUSTED_WORLD_KEY,
+ BL30_KEY,
+ BL31_KEY,
+ BL32_KEY,
+ BL33_KEY,
+ NUM_KEYS
+};
+
+/*
+ * Array containing the key instances
+ */
+extern key_t keys[];
+
+#endif /* TBB_KEY_H_ */
diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c
new file mode 100644
index 00000000..9705643d
--- /dev/null
+++ b/tools/cert_create/src/cert.c
@@ -0,0 +1,180 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/conf.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/sha.h>
+#include <openssl/x509v3.h>
+
+#include "cert.h"
+#include "debug.h"
+#include "key.h"
+#include "platform_oid.h"
+#include "sha.h"
+
+#define SERIAL_RAND_BITS 64
+
+int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
+{
+ BIGNUM *btmp;
+ int ret = 0;
+ if (b)
+ btmp = b;
+ else
+ btmp = BN_new();
+
+ if (!btmp)
+ return 0;
+
+ if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
+ goto error;
+ if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
+ goto error;
+
+ ret = 1;
+
+error:
+
+ if (!b)
+ BN_free(btmp);
+
+ return ret;
+}
+
+int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value)
+{
+ X509_EXTENSION *ex;
+ X509V3_CTX ctx;
+
+ /* No configuration database */
+ X509V3_set_ctx_nodb(&ctx);
+
+ /* Set issuer and subject certificates in the context */
+ X509V3_set_ctx(&ctx, issuer, subject, NULL, NULL, 0);
+ ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
+ if (!ex) {
+ ERR_print_errors_fp(stdout);
+ return 0;
+ }
+
+ X509_add_ext(subject, ex, -1);
+ X509_EXTENSION_free(ex);
+
+ return 1;
+}
+
+
+int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk)
+{
+ EVP_PKEY *pkey = cert->key->key;
+ EVP_PKEY *ikey = cert->issuer->key->key;
+ X509 *issuer = cert->issuer->x;
+ X509 *x = NULL;
+ X509_EXTENSION *ex = NULL;
+ X509_NAME *name = NULL;
+ ASN1_INTEGER *sno = NULL;
+ int i, num;
+
+ /* Create the certificate structure */
+ x = X509_new();
+ if (!x) {
+ return 0;
+ }
+
+ /* If we do not have a key, use the issuer key (the certificate will
+ * become self signed). This happens in content certificates. */
+ if (!pkey) {
+ pkey = ikey;
+ }
+
+ /* If we do not have an issuer certificate, use our own (the certificate
+ * will become self signed) */
+ if (!issuer) {
+ issuer = x;
+ }
+
+ /* x509.v3 */
+ X509_set_version(x, 2);
+
+ /* Random serial number */
+ sno = ASN1_INTEGER_new();
+ rand_serial(NULL, sno);
+ X509_set_serialNumber(x, sno);
+ ASN1_INTEGER_free(sno);
+
+ X509_gmtime_adj(X509_get_notBefore(x), 0);
+ X509_gmtime_adj(X509_get_notAfter(x), (long)60*60*24*days);
+ X509_set_pubkey(x, pkey);
+
+ /* Subject name */
+ name = X509_get_subject_name(x);
+ X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
+ (const unsigned char *)cert->cn, -1, -1, 0);
+ X509_set_subject_name(x, name);
+
+ /* Issuer name */
+ name = X509_get_issuer_name(x);
+ X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
+ (const unsigned char *)cert->issuer->cn, -1, -1, 0);
+ X509_set_issuer_name(x, name);
+
+ /* Add various extensions: standard extensions */
+ cert_add_ext(issuer, x, NID_subject_key_identifier, "hash");
+ cert_add_ext(issuer, x, NID_authority_key_identifier, "keyid:always");
+ if (ca) {
+ cert_add_ext(issuer, x, NID_basic_constraints, "CA:TRUE");
+ cert_add_ext(issuer, x, NID_key_usage, "keyCertSign");
+ } else {
+ cert_add_ext(issuer, x, NID_basic_constraints, "CA:FALSE");
+ }
+
+ /* Add custom extensions */
+ if (sk != NULL) {
+ num = sk_X509_EXTENSION_num(sk);
+ for (i = 0; i < num; i++) {
+ ex = sk_X509_EXTENSION_value(sk, i);
+ X509_add_ext(x, ex, -1);
+ }
+ }
+
+ /* Sign the certificate with the issuer key */
+ if (!X509_sign(x, ikey, EVP_sha1())) {
+ ERR_print_errors_fp(stdout);
+ return 0;
+ }
+
+ cert->x = x;
+ return 1;
+}
diff --git a/tools/cert_create/src/ext.c b/tools/cert_create/src/ext.c
new file mode 100644
index 00000000..31f84a86
--- /dev/null
+++ b/tools/cert_create/src/ext.c
@@ -0,0 +1,233 @@
+/*
+ * 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 <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include "ext.h"
+
+DECLARE_ASN1_ITEM(ASN1_INTEGER)
+DECLARE_ASN1_ITEM(ASN1_OCTET_STRING)
+
+/*
+ * This function adds the TBB extensions to the internal extension list
+ * maintained by OpenSSL so they can be used later.
+ *
+ * It also initializes the methods to print the contents of the extension. If an
+ * alias is specified in the TBB extension, we reuse the methods of the alias.
+ * Otherwise, only methods for V_ASN1_INTEGER and V_ASN1_OCTET_STRING are
+ * provided. Any other type will be printed as a raw ascii string.
+ *
+ * Return: 0 = success, Otherwise: error
+ */
+int ext_init(ext_t *tbb_ext)
+{
+ ext_t *ext;
+ X509V3_EXT_METHOD *m;
+ int i = 0, nid, ret;
+
+ while ((ext = &tbb_ext[i++]) && ext->oid) {
+ nid = OBJ_create(ext->oid, ext->sn, ext->ln);
+ if (ext->alias) {
+ X509V3_EXT_add_alias(nid, ext->alias);
+ } else {
+ m = &ext->method;
+ memset(m, 0x0, sizeof(X509V3_EXT_METHOD));
+ switch (ext->type) {
+ case V_ASN1_INTEGER:
+ m->it = ASN1_ITEM_ref(ASN1_INTEGER);
+ m->i2s = (X509V3_EXT_I2S)i2s_ASN1_INTEGER;
+ m->s2i = (X509V3_EXT_S2I)s2i_ASN1_INTEGER;
+ break;
+ case V_ASN1_OCTET_STRING:
+ m->it = ASN1_ITEM_ref(ASN1_OCTET_STRING);
+ m->i2s = (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING;
+ m->s2i = (X509V3_EXT_S2I)s2i_ASN1_OCTET_STRING;
+ break;
+ default:
+ continue;
+ }
+ m->ext_nid = nid;
+ ret = X509V3_EXT_add(m);
+ if (!ret) {
+ ERR_print_errors_fp(stdout);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+ * Create a new extension
+ *
+ * Extension ::= SEQUENCE {
+ * id OBJECT IDENTIFIER,
+ * critical BOOLEAN DEFAULT FALSE,
+ * value OCTET STRING }
+ *
+ * Parameters:
+ * pex: OpenSSL extension pointer (output parameter)
+ * nid: extension identifier
+ * crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
+ * data: extension data. This data will be encapsulated in an Octet String
+ *
+ * Return: Extension address, NULL if error
+ */
+static
+X509_EXTENSION *ext_new(int nid, int crit, unsigned char *data, int len)
+{
+ X509_EXTENSION *ex;
+ ASN1_OCTET_STRING *ext_data;
+
+ /* Octet string containing the extension data */
+ ext_data = ASN1_OCTET_STRING_new();
+ ASN1_OCTET_STRING_set(ext_data, data, len);
+
+ /* Create the extension */
+ ex = X509_EXTENSION_create_by_NID(NULL, nid, crit, ext_data);
+
+ /* The extension makes a copy of the data, so we can free this object */
+ ASN1_OCTET_STRING_free(ext_data);
+
+ return ex;
+}
+
+/*
+ * Creates a x509v3 extension containing a hash encapsulated in an ASN1 Octet
+ * String
+ *
+ * Parameters:
+ * pex: OpenSSL extension pointer (output parameter)
+ * nid: extension identifier
+ * crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
+ * buf: pointer to the buffer that contains the hash
+ * len: size of the hash in bytes
+ *
+ * Return: Extension address, NULL if error
+ */
+X509_EXTENSION *ext_new_hash(int nid, int crit, unsigned char *buf, size_t len)
+{
+ X509_EXTENSION *ex = NULL;
+ ASN1_OCTET_STRING *hash = NULL;
+ unsigned char *p = NULL;
+ int sz = -1;
+
+ /* Encode Hash */
+ hash = ASN1_OCTET_STRING_new();
+ ASN1_OCTET_STRING_set(hash, buf, len);
+ sz = i2d_ASN1_OCTET_STRING(hash, NULL);
+ i2d_ASN1_OCTET_STRING(hash, &p);
+
+ /* Create the extension */
+ ex = ext_new(nid, crit, p, sz);
+
+ /* Clean up */
+ OPENSSL_free(p);
+ ASN1_OCTET_STRING_free(hash);
+
+ return ex;
+}
+
+/*
+ * Creates a x509v3 extension containing a nvcounter encapsulated in an ASN1
+ * Integer
+ *
+ * Parameters:
+ * pex: OpenSSL extension pointer (output parameter)
+ * nid: extension identifier
+ * crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
+ * value: nvcounter value
+ *
+ * Return: Extension address, NULL if error
+ */
+X509_EXTENSION *ext_new_nvcounter(int nid, int crit, int value)
+{
+ X509_EXTENSION *ex = NULL;
+ ASN1_INTEGER *counter = NULL;
+ unsigned char *p = NULL;
+ int sz = -1;
+
+ /* Encode counter */
+ counter = ASN1_INTEGER_new();
+ ASN1_INTEGER_set(counter, value);
+ sz = i2d_ASN1_INTEGER(counter, NULL);
+ i2d_ASN1_INTEGER(counter, &p);
+
+ /* Create the extension */
+ ex = ext_new(nid, crit, p, sz);
+
+ /* Free objects */
+ OPENSSL_free(p);
+ ASN1_INTEGER_free(counter);
+
+ return ex;
+}
+
+/*
+ * Creates a x509v3 extension containing a public key in DER format:
+ *
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * subjectPublicKey BIT STRING }
+ *
+ * Parameters:
+ * pex: OpenSSL extension pointer (output parameter)
+ * nid: extension identifier
+ * crit: extension critical (EXT_NON_CRIT, EXT_CRIT)
+ * k: key
+ *
+ * Return: Extension address, NULL if error
+ */
+X509_EXTENSION *ext_new_key(int nid, int crit, EVP_PKEY *k)
+{
+ X509_EXTENSION *ex = NULL;
+ unsigned char *p = NULL;
+ int sz = -1;
+
+ /* Encode key */
+ BIO *mem = BIO_new(BIO_s_mem());
+ if (i2d_PUBKEY_bio(mem, k) <= 0) {
+ ERR_print_errors_fp(stderr);
+ return NULL;
+ }
+ p = (unsigned char *)OPENSSL_malloc(4096);
+ sz = BIO_read(mem, p, 4096);
+
+ /* Create the extension */
+ ex = ext_new(nid, crit, p, sz);
+
+ /* Clean up */
+ OPENSSL_free(p);
+
+ return ex;
+}
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
new file mode 100644
index 00000000..b5737d93
--- /dev/null
+++ b/tools/cert_create/src/key.c
@@ -0,0 +1,131 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/conf.h>
+#include <openssl/evp.h>
+#include <openssl/pem.h>
+
+#include "cert.h"
+#include "debug.h"
+#include "key.h"
+#include "platform_oid.h"
+#include "sha.h"
+
+#define MAX_FILENAME_LEN 1024
+
+/*
+ * Create a new key
+ */
+int key_new(key_t *key)
+{
+ RSA *rsa = NULL;
+ EVP_PKEY *k = NULL;
+
+ /* Create key pair container */
+ k = EVP_PKEY_new();
+ if (k == NULL) {
+ return 0;
+ }
+
+ /* Generate a new RSA key */
+ rsa = RSA_generate_key(RSA_KEY_BITS, RSA_F4, NULL, NULL);
+ if (EVP_PKEY_assign_RSA(k, rsa)) {
+ key->key = k;
+ return 1;
+ } else {
+ printf("Cannot assign RSA key\n");
+ }
+
+ if (k)
+ EVP_PKEY_free(k);
+ return 0;
+}
+
+int key_load(key_t *key)
+{
+ FILE *fp = NULL;
+ EVP_PKEY *k = NULL;
+
+ /* Create key pair container */
+ k = EVP_PKEY_new();
+ if (k == NULL) {
+ return 0;
+ }
+
+ if (key->fn) {
+ /* Load key from file */
+ fp = fopen(key->fn, "r");
+ if (fp) {
+ k = PEM_read_PrivateKey(fp, &k, NULL, NULL);
+ fclose(fp);
+ if (k) {
+ key->key = k;
+ return 1;
+ } else {
+ ERROR("Cannot read key from %s\n", key->fn);
+ }
+ } else {
+ ERROR("Cannot open file %s\n", key->fn);
+ }
+ } else {
+ ERROR("Key filename not specified\n");
+ }
+
+ if (k)
+ EVP_PKEY_free(k);
+
+ return 0;
+}
+
+int key_store(key_t *key)
+{
+ FILE *fp = NULL;
+
+ if (key->fn) {
+ fp = fopen(key->fn, "w");
+ if (fp) {
+ PEM_write_PrivateKey(fp, key->key,
+ NULL, NULL, 0, NULL, NULL);
+ fclose(fp);
+ return 1;
+ } else {
+ ERROR("Cannot create file %s\n", key->fn);
+ }
+ } else {
+ ERROR("Key filename not specified\n");
+ }
+
+ return 0;
+}
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
new file mode 100644
index 00000000..6df367a2
--- /dev/null
+++ b/tools/cert_create/src/main.c
@@ -0,0 +1,719 @@
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/conf.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/sha.h>
+#include <openssl/x509v3.h>
+
+#include "cert.h"
+#include "debug.h"
+#include "ext.h"
+#include "key.h"
+#include "platform_oid.h"
+#include "sha.h"
+#include "tbb_ext.h"
+#include "tbb_cert.h"
+#include "tbb_key.h"
+
+/*
+ * Helper macros to simplify the code. This macro assigns the return value of
+ * the 'fn' function to 'v' and exits if the value is NULL.
+ */
+#define CHECK_NULL(v, fn) \
+ do { \
+ v = fn; \
+ if (v == NULL) { \
+ ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \
+ exit(1); \
+ } \
+ } while (0)
+
+/*
+ * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the
+ * NID is undefined.
+ */
+#define CHECK_OID(v, oid) \
+ do { \
+ v = OBJ_txt2nid(oid); \
+ if (v == NID_undef) { \
+ ERROR("Cannot find TBB extension %s\n", oid); \
+ exit(1); \
+ } \
+ } while (0)
+
+#define MAX_FILENAME_LEN 1024
+#define VAL_DAYS 7300
+#define ID_TO_BIT_MASK(id) (1 << id)
+#define NVCOUNTER_VALUE 0
+
+/* Files */
+enum {
+ /* Image file names (inputs) */
+ BL2_ID = 0,
+ BL30_ID,
+ BL31_ID,
+ BL32_ID,
+ BL33_ID,
+ /* Certificate file names (outputs) */
+ BL2_CERT_ID,
+ TRUSTED_KEY_CERT_ID,
+ BL30_KEY_CERT_ID,
+ BL30_CERT_ID,
+ BL31_KEY_CERT_ID,
+ BL31_CERT_ID,
+ BL32_KEY_CERT_ID,
+ BL32_CERT_ID,
+ BL33_KEY_CERT_ID,
+ BL33_CERT_ID,
+ /* Key file names (input/output) */
+ ROT_KEY_ID,
+ TRUSTED_WORLD_KEY_ID,
+ NON_TRUSTED_WORLD_KEY_ID,
+ BL30_KEY_ID,
+ BL31_KEY_ID,
+ BL32_KEY_ID,
+ BL33_KEY_ID,
+ NUM_OPTS
+};
+
+/* Global options */
+static int new_keys;
+static int save_keys;
+static int print_cert;
+static int bl30_present;
+static int bl32_present;
+
+/* We are not checking nvcounters in TF. Include them in the certificates but
+ * the value will be set to 0 */
+static int tf_nvcounter;
+static int non_tf_nvcounter;
+
+/* Info messages created in the Makefile */
+extern const char build_msg[];
+extern const char platform_msg[];
+
+
+static char *strdup(const char *str)
+{
+ int n = strlen(str) + 1;
+ char *dup = malloc(n);
+ if (dup) {
+ strcpy(dup, str);
+ }
+ return dup;
+}
+
+/* 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 */
+ {"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)
+{
+ int i = 0;
+ printf("\n\n");
+ printf("The certificate generation tool loads the binary images and\n"
+ "optionally the RSA keys, and outputs the key and content\n"
+ "certificates properly signed to implement the chain of trust.\n"
+ "If keys are provided, they must be in PEM format.\n"
+ "Certificates are generated in DER format.\n");
+ printf("\n");
+ printf("Usage:\n\n");
+ printf(" %s [-hknp] \\\n", cmd);
+ for (i = 0; i < NUM_OPTS; i++) {
+ printf(" --%s <file> \\\n", long_opt[i].name);
+ }
+ printf("\n");
+ printf("-h Print help and exit\n");
+ printf("-k Save key pairs into files. Filenames must be provided\n");
+ printf("-n Generate new key pairs if no key files are provided\n");
+ printf("-p Print the certificates in the standard output\n");
+ printf("\n");
+
+ exit(0);
+}
+
+static void check_cmd_params(void)
+{
+ /* BL2, BL31 and BL33 are mandatory */
+ if (certs[BL2_CERT].bin == NULL) {
+ ERROR("BL2 image not specified\n");
+ exit(1);
+ }
+
+ if (certs[BL31_CERT].bin == NULL) {
+ ERROR("BL31 image not specified\n");
+ exit(1);
+ }
+
+ if (certs[BL33_CERT].bin == NULL) {
+ ERROR("BL33 image not specified\n");
+ exit(1);
+ }
+
+ /* BL30 and BL32 are optional */
+ if (certs[BL30_CERT].bin != NULL) {
+ bl30_present = 1;
+ }
+
+ if (certs[BL32_CERT].bin != 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);
+ }
+
+ if (bl32_present && (keys[BL32_KEY].fn == NULL)) {
+ ERROR("BL32 key not specified\n");
+ exit(1);
+ }
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ STACK_OF(X509_EXTENSION) * sk = NULL;
+ X509_EXTENSION *hash_ext = NULL;
+ X509_EXTENSION *nvctr_ext = NULL;
+ X509_EXTENSION *trusted_key_ext = NULL;
+ X509_EXTENSION *non_trusted_key_ext = NULL;
+ FILE *file = NULL;
+ int i, tz_nvctr_nid, ntz_nvctr_nid, hash_nid, pk_nid;
+ int c, opt_idx = 0;
+ unsigned char md[SHA256_DIGEST_LENGTH];
+
+ NOTICE("CoT Generation Tool: %s\n", build_msg);
+ NOTICE("Target platform: %s\n", platform_msg);
+
+ while (1) {
+ /* getopt_long stores the option index here. */
+ c = getopt_long(argc, argv, "hknp", long_opt, &opt_idx);
+
+ /* Detect the end of the options. */
+ if (c == -1) {
+ break;
+ }
+
+ switch (c) {
+ case 'h':
+ print_help(argv[0]);
+ break;
+ case 'k':
+ save_keys = 1;
+ break;
+ case 'n':
+ new_keys = 1;
+ break;
+ case 'p':
+ print_cert = 1;
+ break;
+ case BL2_ID:
+ certs[BL2_CERT].bin = strdup(optarg);
+ break;
+ case BL30_ID:
+ certs[BL30_CERT].bin = strdup(optarg);
+ break;
+ case BL31_ID:
+ certs[BL31_CERT].bin = strdup(optarg);
+ break;
+ case BL32_ID:
+ certs[BL32_CERT].bin = strdup(optarg);
+ break;
+ case BL33_ID:
+ certs[BL33_CERT].bin = 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);
+ break;
+ case '?':
+ default:
+ printf("%s\n", optarg);
+ exit(1);
+ }
+ }
+
+ /* Set the value of the NVCounters */
+ tf_nvcounter = NVCOUNTER_VALUE;
+ non_tf_nvcounter = NVCOUNTER_VALUE;
+
+ /* Check command line arguments */
+ check_cmd_params();
+
+ /* Register the new types and OIDs for the extensions */
+ if (ext_init(tbb_ext) != 0) {
+ ERROR("Cannot initialize TBB extensions\n");
+ exit(1);
+ }
+
+ /* Get non-volatile counters NIDs */
+ CHECK_OID(tz_nvctr_nid, TZ_FW_NVCOUNTER_OID);
+ CHECK_OID(ntz_nvctr_nid, NTZ_FW_NVCOUNTER_OID);
+
+ /* Load private keys from files (or generate new ones) */
+ if (new_keys) {
+ for (i = 0 ; i < NUM_KEYS ; i++) {
+ if (!key_new(&keys[i])) {
+ ERROR("Error creating %s\n", keys[i].desc);
+ exit(1);
+ }
+ }
+ } else {
+ for (i = 0 ; i < NUM_KEYS ; i++) {
+ if (!key_load(&keys[i])) {
+ ERROR("Error loading %s\n", keys[i].desc);
+ exit(1);
+ }
+ }
+ }
+
+ /* *********************************************************************
+ * BL2 certificate (Trusted Boot Firmware certificate):
+ * - Self-signed with OEM ROT private key
+ * - Extensions:
+ * - TrustedFirmwareNVCounter (TODO)
+ * - BL2 hash
+ **********************************************************************/
+ CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+
+ /* Add the NVCounter as a critical extension */
+ CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+ tf_nvcounter));
+ sk_X509_EXTENSION_push(sk, nvctr_ext);
+
+ /* Add hash of BL2 as an extension */
+ if (!sha_file(certs[BL2_CERT].bin, md)) {
+ ERROR("Cannot calculate the hash of %s\n", certs[BL2_CERT].bin);
+ exit(1);
+ }
+ CHECK_OID(hash_nid, BL2_HASH_OID);
+ CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
+ SHA256_DIGEST_LENGTH));
+ sk_X509_EXTENSION_push(sk, hash_ext);
+
+ /* Create certificate. Signed with ROT key */
+ if (!cert_new(&certs[BL2_CERT], VAL_DAYS, 0, sk)) {
+ ERROR("Cannot create %s\n", certs[BL2_CERT].cn);
+ exit(1);
+ }
+ sk_X509_EXTENSION_free(sk);
+
+ /* *********************************************************************
+ * Trusted Key certificate:
+ * - Self-signed with OEM ROT private key
+ * - Extensions:
+ * - TrustedFirmwareNVCounter (TODO)
+ * - TrustedWorldPK
+ * - NonTrustedWorldPK
+ **********************************************************************/
+ CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+ CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+ tf_nvcounter));
+ sk_X509_EXTENSION_push(sk, nvctr_ext);
+ CHECK_OID(pk_nid, TZ_WORLD_PK_OID);
+ CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+ keys[TRUSTED_WORLD_KEY].key));
+ sk_X509_EXTENSION_push(sk, trusted_key_ext);
+ CHECK_OID(pk_nid, NTZ_WORLD_PK_OID);
+ CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+ keys[NON_TRUSTED_WORLD_KEY].key));
+ sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
+ if (!cert_new(&certs[TRUSTED_KEY_CERT], VAL_DAYS, 0, sk)) {
+ ERROR("Cannot create %s\n", certs[TRUSTED_KEY_CERT].cn);
+ exit(1);
+ }
+ sk_X509_EXTENSION_free(sk);
+
+ /* *********************************************************************
+ * BL30 Key certificate (Trusted SCP Firmware Key certificate):
+ * - Self-signed with Trusted World key
+ * - Extensions:
+ * - TrustedFirmwareNVCounter (TODO)
+ * - SCPFirmwareContentCertPK
+ **********************************************************************/
+ if (bl30_present) {
+ CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+ CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+ tf_nvcounter));
+ sk_X509_EXTENSION_push(sk, nvctr_ext);
+ CHECK_OID(pk_nid, BL30_CONTENT_CERT_PK_OID);
+ CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+ keys[BL30_KEY].key));
+ sk_X509_EXTENSION_push(sk, trusted_key_ext);
+ if (!cert_new(&certs[BL30_KEY_CERT], VAL_DAYS, 0, sk)) {
+ ERROR("Cannot create %s\n", certs[BL30_KEY_CERT].cn);
+ exit(1);
+ }
+ sk_X509_EXTENSION_free(sk);
+ }
+
+ /* *********************************************************************
+ * BL30 certificate (SCP Firmware Content certificate):
+ * - Signed with Trusted World Key
+ * - Extensions:
+ * - TrustedFirmwareNVCounter (TODO)
+ * - SCPFirmwareHash
+ **********************************************************************/
+ if (bl30_present) {
+ CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+ CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+ tf_nvcounter));
+ sk_X509_EXTENSION_push(sk, nvctr_ext);
+
+ if (!sha_file(certs[BL30_CERT].bin, md)) {
+ ERROR("Cannot calculate the hash of %s\n",
+ certs[BL30_CERT].bin);
+ exit(1);
+ }
+ CHECK_OID(hash_nid, BL30_HASH_OID);
+ CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
+ SHA256_DIGEST_LENGTH));
+ sk_X509_EXTENSION_push(sk, hash_ext);
+
+ if (!cert_new(&certs[BL30_CERT], VAL_DAYS, 0, sk)) {
+ ERROR("Cannot create %s\n", certs[BL30_CERT].cn);
+ exit(1);
+ }
+
+ sk_X509_EXTENSION_free(sk);
+ }
+
+ /* *********************************************************************
+ * BL31 Key certificate (Trusted SoC Firmware Key certificate):
+ * - Self-signed with Trusted World key
+ * - Extensions:
+ * - TrustedFirmwareNVCounter (TODO)
+ * - SoCFirmwareContentCertPK
+ **********************************************************************/
+ CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+ CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+ tf_nvcounter));
+ sk_X509_EXTENSION_push(sk, nvctr_ext);
+ CHECK_OID(pk_nid, BL31_CONTENT_CERT_PK_OID);
+ CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+ keys[BL31_KEY].key));
+ sk_X509_EXTENSION_push(sk, trusted_key_ext);
+ if (!cert_new(&certs[BL31_KEY_CERT], VAL_DAYS, 0, sk)) {
+ ERROR("Cannot create %s\n", certs[BL31_KEY_CERT].cn);
+ exit(1);
+ }
+ sk_X509_EXTENSION_free(sk);
+
+ /* *********************************************************************
+ * BL31 certificate (SOC Firmware Content certificate):
+ * - Signed with Trusted World Key
+ * - Extensions:
+ * - TrustedFirmwareNVCounter (TODO)
+ * - BL31 hash
+ **********************************************************************/
+ CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+ CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+ tf_nvcounter));
+ sk_X509_EXTENSION_push(sk, nvctr_ext);
+
+ if (!sha_file(certs[BL31_CERT].bin, md)) {
+ ERROR("Cannot calculate the hash of %s\n", certs[BL31_CERT].bin);
+ exit(1);
+ }
+ CHECK_OID(hash_nid, BL31_HASH_OID);
+ CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
+ SHA256_DIGEST_LENGTH));
+ sk_X509_EXTENSION_push(sk, hash_ext);
+
+ if (!cert_new(&certs[BL31_CERT], VAL_DAYS, 0, sk)) {
+ ERROR("Cannot create %s\n", certs[BL31_CERT].cn);
+ exit(1);
+ }
+
+ sk_X509_EXTENSION_free(sk);
+
+ /* *********************************************************************
+ * BL32 Key certificate (Trusted OS Firmware Key certificate):
+ * - Self-signed with Trusted World key
+ * - Extensions:
+ * - TrustedFirmwareNVCounter (TODO)
+ * - TrustedOSFirmwareContentCertPK
+ **********************************************************************/
+ if (bl32_present) {
+ CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+ CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+ tf_nvcounter));
+ sk_X509_EXTENSION_push(sk, nvctr_ext);
+ CHECK_OID(pk_nid, BL32_CONTENT_CERT_PK_OID);
+ CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+ keys[BL32_KEY].key));
+ sk_X509_EXTENSION_push(sk, trusted_key_ext);
+ if (!cert_new(&certs[BL32_KEY_CERT], VAL_DAYS, 0, sk)) {
+ ERROR("Cannot create %s\n", certs[BL32_KEY_CERT].cn);
+ exit(1);
+ }
+ sk_X509_EXTENSION_free(sk);
+ }
+
+ /* *********************************************************************
+ * BL32 certificate (TrustedOS Firmware Content certificate):
+ * - Signed with Trusted World Key
+ * - Extensions:
+ * - TrustedFirmwareNVCounter (TODO)
+ * - BL32 hash
+ **********************************************************************/
+ if (bl32_present) {
+ CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+ CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
+ tf_nvcounter));
+ sk_X509_EXTENSION_push(sk, nvctr_ext);
+
+ if (!sha_file(certs[BL32_CERT].bin, md)) {
+ ERROR("Cannot calculate the hash of %s\n",
+ certs[BL32_CERT].bin);
+ exit(1);
+ }
+ CHECK_OID(hash_nid, BL32_HASH_OID);
+ CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
+ SHA256_DIGEST_LENGTH));
+ sk_X509_EXTENSION_push(sk, hash_ext);
+
+ if (!cert_new(&certs[BL32_CERT], VAL_DAYS, 0, sk)) {
+ ERROR("Cannot create %s\n", certs[BL32_CERT].cn);
+ exit(1);
+ }
+
+ sk_X509_EXTENSION_free(sk);
+ }
+
+ /* *********************************************************************
+ * BL33 Key certificate (Non Trusted Firmware Key certificate):
+ * - Self-signed with Non Trusted World key
+ * - Extensions:
+ * - NonTrustedFirmwareNVCounter (TODO)
+ * - NonTrustedFirmwareContentCertPK
+ **********************************************************************/
+ CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+ CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
+ non_tf_nvcounter));
+ sk_X509_EXTENSION_push(sk, nvctr_ext);
+ CHECK_OID(pk_nid, BL33_CONTENT_CERT_PK_OID);
+ CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
+ keys[BL33_KEY].key));
+ sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
+ if (!cert_new(&certs[BL33_KEY_CERT], VAL_DAYS, 0, sk)) {
+ ERROR("Cannot create %s\n", certs[BL33_KEY_CERT].cn);
+ exit(1);
+ }
+ sk_X509_EXTENSION_free(sk);
+
+ /* *********************************************************************
+ * BL33 certificate (Non-Trusted World Content certificate):
+ * - Signed with Non-Trusted World Key
+ * - Extensions:
+ * - NonTrustedFirmwareNVCounter (TODO)
+ * - BL33 hash
+ **********************************************************************/
+ CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
+ CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
+ non_tf_nvcounter));
+ sk_X509_EXTENSION_push(sk, nvctr_ext);
+
+ if (!sha_file(certs[BL33_CERT].bin, md)) {
+ ERROR("Cannot calculate the hash of %s\n", certs[BL33_CERT].bin);
+ exit(1);
+ }
+ CHECK_OID(hash_nid, BL33_HASH_OID);
+ CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
+ SHA256_DIGEST_LENGTH));
+ sk_X509_EXTENSION_push(sk, hash_ext);
+
+ if (!cert_new(&certs[BL33_CERT], VAL_DAYS, 0, sk)) {
+ ERROR("Cannot create %s\n", certs[BL33_CERT].cn);
+ exit(1);
+ }
+ sk_X509_EXTENSION_free(sk);
+
+ /* Print the certificates */
+ if (print_cert) {
+ for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
+ if (!certs[i].x) {
+ continue;
+ }
+ printf("\n\n=====================================\n\n");
+ X509_print_fp(stdout, certs[i].x);
+ }
+ }
+
+ /* Save created certificates to files */
+ for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
+ if (certs[i].x && certs[i].fn) {
+ file = fopen(certs[i].fn, "w");
+ if (file != NULL) {
+ i2d_X509_fp(file, certs[i].x);
+ fclose(file);
+ } else {
+ ERROR("Cannot create file %s\n", certs[i].fn);
+ }
+ }
+ }
+
+ /* Save keys */
+ if (save_keys) {
+ for (i = 0 ; i < NUM_KEYS ; i++) {
+ if (!key_store(&keys[i])) {
+ ERROR("Cannot save %s\n", keys[i].desc);
+ }
+ }
+ }
+
+ X509_EXTENSION_free(hash_ext);
+ X509_EXTENSION_free(nvctr_ext);
+ X509_EXTENSION_free(trusted_key_ext);
+ X509_EXTENSION_free(non_trusted_key_ext);
+
+#ifndef OPENSSL_NO_ENGINE
+ ENGINE_cleanup();
+#endif
+ CRYPTO_cleanup_all_ex_data();
+
+ return 0;
+}
diff --git a/tools/cert_create/src/sha.c b/tools/cert_create/src/sha.c
new file mode 100644
index 00000000..57026b56
--- /dev/null
+++ b/tools/cert_create/src/sha.c
@@ -0,0 +1,64 @@
+/*
+ * 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 <stdio.h>
+#include <openssl/sha.h>
+
+#include "debug.h"
+
+#define BUFFER_SIZE 256
+
+int sha_file(const char *filename, unsigned char *md)
+{
+ FILE *inFile;
+ SHA256_CTX shaContext;
+ int bytes;
+ unsigned char data[BUFFER_SIZE];
+
+ if ((filename == NULL) || (md == NULL)) {
+ ERROR("%s(): NULL argument\n", __FUNCTION__);
+ return 0;
+ }
+
+ inFile = fopen(filename, "rb");
+ if (inFile == NULL) {
+ ERROR("Cannot read %s\n", filename);
+ return 0;
+ }
+
+ SHA256_Init(&shaContext);
+ while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
+ SHA256_Update(&shaContext, data, bytes);
+ }
+ SHA256_Final(md, &shaContext);
+
+ fclose(inFile);
+ return 1;
+}
diff --git a/tools/cert_create/src/tbb_cert.c b/tools/cert_create/src/tbb_cert.c
new file mode 100644
index 00000000..8dfda605
--- /dev/null
+++ b/tools/cert_create/src/tbb_cert.c
@@ -0,0 +1,111 @@
+/*
+ * 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 "tbb_cert.h"
+#include "tbb_key.h"
+
+/*
+ * Certificates used in the chain of trust
+ *
+ * The order of the certificates must follow the enumeration specified in
+ * tbb_cert.h. All certificates are self-signed.
+ */
+cert_t certs[NUM_CERTIFICATES] = {
+ {
+ .id = BL2_CERT,
+ .fn = NULL,
+ .cn = "BL2 Certificate",
+ .key = &keys[ROT_KEY],
+ .issuer = &certs[BL2_CERT],
+ },
+ {
+ .id = TRUSTED_KEY_CERT,
+ .fn = NULL,
+ .cn = "Trusted Key Certificate",
+ .key = &keys[ROT_KEY],
+ .issuer = &certs[TRUSTED_KEY_CERT],
+ },
+ {
+ .id = BL30_KEY_CERT,
+ .fn = NULL,
+ .cn = "BL3-0 Key Certificate",
+ .key = &keys[TRUSTED_WORLD_KEY],
+ .issuer = &certs[BL30_KEY_CERT],
+ },
+ {
+ .id = BL30_CERT,
+ .fn = NULL,
+ .cn = "BL3-0 Content Certificate",
+ .key = &keys[BL30_KEY],
+ .issuer = &certs[BL30_CERT],
+ },
+ {
+ .id = BL31_KEY_CERT,
+ .fn = NULL,
+ .cn = "BL3-1 Key Certificate",
+ .key = &keys[TRUSTED_WORLD_KEY],
+ .issuer = &certs[BL31_KEY_CERT],
+ },
+ {
+ .id = BL31_CERT,
+ .fn = NULL,
+ .cn = "BL3-1 Content Certificate",
+ .key = &keys[BL31_KEY],
+ .issuer = &certs[BL31_CERT],
+ },
+ {
+ .id = BL32_KEY_CERT,
+ .fn = NULL,
+ .cn = "BL3-2 Key Certificate",
+ .key = &keys[TRUSTED_WORLD_KEY],
+ .issuer = &certs[BL32_KEY_CERT],
+ },
+ {
+ .id = BL32_CERT,
+ .fn = NULL,
+ .cn = "BL3-2 Content Certificate",
+ .key = &keys[BL32_KEY],
+ .issuer = &certs[BL32_CERT],
+ },
+ {
+ .id = BL33_KEY_CERT,
+ .fn = NULL,
+ .cn = "BL3-3 Key Certificate",
+ .key = &keys[NON_TRUSTED_WORLD_KEY],
+ .issuer = &certs[BL33_KEY_CERT],
+ },
+ {
+ .id = BL33_CERT,
+ .fn = NULL,
+ .cn = "BL3-3 Content Certificate",
+ .key = &keys[BL33_KEY],
+ .issuer = &certs[BL33_CERT],
+ }
+};
diff --git a/tools/cert_create/src/tbb_ext.c b/tools/cert_create/src/tbb_ext.c
new file mode 100644
index 00000000..0022611c
--- /dev/null
+++ b/tools/cert_create/src/tbb_ext.c
@@ -0,0 +1,118 @@
+/*
+ * 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 <stdio.h>
+#include <string.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include "ext.h"
+#include "platform_oid.h"
+
+ext_t tbb_ext[] = {
+ {
+ .oid = TZ_FW_NVCOUNTER_OID,
+ .sn = "TrustedNvCounter",
+ .ln = "Non-volatile trusted counter",
+ .type = V_ASN1_INTEGER
+ },
+ {
+ .oid = NTZ_FW_NVCOUNTER_OID,
+ .sn = "NonTrustedNvCounter",
+ .ln = "Non-volatile non-trusted counter",
+ .type = V_ASN1_INTEGER
+ },
+ {
+ .oid = BL2_HASH_OID,
+ .sn = "TrustedBootFirmwareHash",
+ .ln = "Trusted Boot Firmware (BL2) hash (SHA256)",
+ .type = V_ASN1_OCTET_STRING
+ },
+ {
+ .oid = TZ_WORLD_PK_OID,
+ .sn = "TrustedWorldPublicKey",
+ .ln = "Trusted World Public Key",
+ .type = V_ASN1_OCTET_STRING
+ },
+ {
+ .oid = NTZ_WORLD_PK_OID,
+ .sn = "NonTrustedWorldPublicKey",
+ .ln = "Non-Trusted World Public Key",
+ .type = V_ASN1_OCTET_STRING
+ },
+ {
+ .oid = BL31_CONTENT_CERT_PK_OID,
+ .sn = "SoCFirmwareContentCertPK",
+ .ln = "SoC Firmware content certificate public key",
+ .type = V_ASN1_OCTET_STRING
+ },
+ {
+ .oid = BL31_HASH_OID,
+ .sn = "APROMPatchHash",
+ .ln = "AP ROM patch hash",
+ .type = V_ASN1_OCTET_STRING
+ },
+ {
+ .oid = BL30_CONTENT_CERT_PK_OID,
+ .sn = "SCPFirmwareContentCertPK",
+ .ln = "SCP Firmware content certificate public key",
+ .type = V_ASN1_OCTET_STRING
+ },
+ {
+ .oid = BL30_HASH_OID,
+ .sn = "SCPFirmwareHash",
+ .ln = "SCP Firmware (BL30) hash (SHA256)",
+ .type = V_ASN1_OCTET_STRING
+ },
+ {
+ .oid = BL32_CONTENT_CERT_PK_OID,
+ .sn = "TrustedOSFirmwareContentCertPK",
+ .ln = "Trusted OS Firmware content certificate public key",
+ .type = V_ASN1_OCTET_STRING
+ },
+ {
+ .oid = BL32_HASH_OID,
+ .sn = "TrustedOSHash",
+ .ln = "Trusted OS (BL32) hash (SHA256)",
+ .type = V_ASN1_OCTET_STRING
+ },
+ {
+ .oid = BL33_CONTENT_CERT_PK_OID,
+ .sn = "NonTrustedFirmwareContentCertPK",
+ .ln = "Non-Trusted Firmware content certificate public key",
+ .type = V_ASN1_OCTET_STRING
+ },
+ {
+ .oid = BL33_HASH_OID,
+ .sn = "NonTrustedWorldBootloaderHash",
+ .ln = "Non-Trusted World (BL33) hash (SHA256)",
+ .type = V_ASN1_OCTET_STRING
+ },
+ { 0, 0, 0, 0 }
+};
diff --git a/tools/cert_create/src/tbb_key.c b/tools/cert_create/src/tbb_key.c
new file mode 100644
index 00000000..140aeda1
--- /dev/null
+++ b/tools/cert_create/src/tbb_key.c
@@ -0,0 +1,67 @@
+/*
+ * 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 "tbb_key.h"
+
+/*
+ * Keys used to establish the chain of trust
+ *
+ * The order of the keys must follow the enumeration specified in tbb_key.h
+ */
+key_t keys[NUM_KEYS] = {
+ {
+ .id = ROT_KEY,
+ .desc = "Root Of Trust key"
+ },
+ {
+ .id = TRUSTED_WORLD_KEY,
+ .desc = "Trusted World key"
+ },
+ {
+ .id = NON_TRUSTED_WORLD_KEY,
+ .desc = "Non Trusted World key"
+ },
+ {
+ .id = BL30_KEY,
+ .desc = "BL30 key"
+ },
+ {
+ .id = BL31_KEY,
+ .desc = "BL31 key"
+ },
+ {
+ .id = BL32_KEY,
+ .desc = "BL32 key"
+ },
+ {
+ .id = BL33_KEY,
+ .desc = "BL33 key"
+ }
+};