diff --git a/.gitignore b/.gitignore index 4220018..d3567bc 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,5 @@ # Ignore build products from tools tools/**/*.o tools/fip_create/fip_create +tools/cert_create/src/*.o +tools/cert_create/cert_create diff --git a/Makefile b/Makefile index c59cdb4..777e330 100644 --- a/Makefile +++ b/Makefile @@ -67,6 +67,9 @@ USE_COHERENT_MEM := 1 # Default FIP file name FIP_NAME := fip.bin +# Flags to generate the Chain of Trust +GENERATE_COT := 0 +CREATE_KEYS := 1 # Checkpatch ignores CHECK_IGNORE = --ignore COMPLEX_MACRO @@ -182,7 +185,7 @@ # fip, then the NEED_BL32 needs to be set and BL3-2 would need to point to the bin. endif -.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool fip +.PHONY: all msg_start clean realclean distclean cscope locate-checkpatch checkcodebase checkpatch fiptool fip certtool .SUFFIXES: INCLUDES += -Iinclude/bl31 \ @@ -236,6 +239,10 @@ $(eval $(call assert_boolean,USE_COHERENT_MEM)) $(eval $(call add_define,USE_COHERENT_MEM)) +# Process Generate CoT flags +$(eval $(call assert_boolean,GENERATE_COT)) +$(eval $(call assert_boolean,CREATE_KEYS)) + ASFLAGS += -nostdinc -ffreestanding -Wa,--fatal-warnings \ -Werror -Wmissing-include-dirs \ -mgeneral-regs-only -D__ASSEMBLY__ \ @@ -266,6 +273,28 @@ fiptool: ${FIPTOOL} fip: ${BUILD_PLAT}/${FIP_NAME} +# Variables for use with Certificate Generation Tool +CRTTOOLPATH ?= tools/cert_create +CRTTOOL ?= ${CRTTOOLPATH}/cert_create +certtool: ${CRTTOOL} + +# CoT generation tool default parameters +TRUSTED_KEY_CERT := ${BUILD_PLAT}/trusted_key.crt + +# Pass the private keys to the CoT generation tool in the command line +# If CREATE_KEYS is set, the '-n' option will be added, indicating the tool to create new keys +ifneq (${GENERATE_COT},0) + $(eval CERTS := yes) + + ifneq (${CREATE_KEYS},0) + $(eval CRT_ARGS += -n) + endif + $(eval CRT_ARGS += $(if ${ROT_KEY}, --rot-key ${ROT_KEY})) + $(eval CRT_ARGS += $(if ${TRUSTED_WORLD_KEY}, --trusted-world-key ${TRUSTED_WORLD_KEY})) + $(eval CRT_ARGS += $(if ${NON_TRUSTED_WORLD_KEY}, --non-trusted-world-key ${NON_TRUSTED_WORLD_KEY})) + $(eval CRT_ARGS += --trusted-key-cert ${TRUSTED_KEY_CERT}) +endif + locate-checkpatch: ifndef CHECKPATCH $(error "Please set CHECKPATCH to point to the Linux checkpatch.pl file, eg: CHECKPATCH=../linux/script/checkpatch.pl") @@ -279,12 +308,14 @@ @echo " CLEAN" ${Q}rm -rf ${BUILD_PLAT} ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean + ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean realclean distclean: @echo " REALCLEAN" ${Q}rm -rf ${BUILD_BASE} ${Q}rm -f ${CURDIR}/cscope.* ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} clean + ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} clean checkcodebase: locate-checkpatch @echo " CHECKING STYLE" @@ -298,6 +329,13 @@ @echo " CHECKING STYLE" @git format-patch --stdout ${BASE_COMMIT} | ${CHECKPATCH} ${CHECKPATCH_ARGS} - || true +.PHONY: ${CRTTOOL} +${CRTTOOL}: + ${Q}${MAKE} PLAT=${PLAT} --no-print-directory -C ${CRTTOOLPATH} + @echo + @echo "Built $@ successfully" + @echo + .PHONY: ${FIPTOOL} ${FIPTOOL}: ${Q}${MAKE} --no-print-directory -C ${FIPTOOLPATH} @@ -398,6 +436,37 @@ $(notdir $(patsubst %.S,%.o,$(filter %.S,$(1)))) endef + +# MAKE_TOOL_ARGS macro defines the command line arguments for the FIP and CRT +# tools at each BL stage. Arguments: +# $(1) = BL stage (2, 30, 31, 32, 33) +# $(2) = Binary file +# $(3) = In FIP (false if empty) +# $(4) = Create certificates (false if empty) +# $(5) = Create key certificate (false if empty) +# $(6) = Private key (optional) +define MAKE_TOOL_ARGS + +$(eval FIP_DEPS += $(if $3,$(2),)) +$(eval FIP_ARGS += $(if $3,--bl$(1) $(2),)) + +$(eval CRT_DEPS += $(if $4,$(2),)) +$(eval CRT_DEPS += $(if $4,$(if $6,$(6),))) +$(eval CRT_ARGS += $(if $4,--bl$(1) $(2))) +$(eval CRT_ARGS += $(if $4,$(if $6,--bl$(1)-key $(6)))) +$(eval CRT_ARGS += $(if $4,--bl$(1)-cert $(BUILD_PLAT)/bl$(1).crt)) +$(eval CRT_ARGS += $(if $4,$(if $5,--bl$(1)-key-cert $(BUILD_PLAT)/bl$(1)_key.crt))) + +endef + + +# MAKE_BL macro defines the targets and options to build each BL image. +# Arguments: +# $(1) = BL stage (2, 30, 31, 32, 33) +# $(2) = In FIP (false if empty) +# $(3) = Create certificates (false if empty) +# $(4) = Create key certificate (false if empty) +# $(5) = Private key (optional) define MAKE_BL $(eval BUILD_DIR := ${BUILD_PLAT}/bl$(1)) $(eval SOURCES := $(BL$(1)_SOURCES) $(BL_COMMON_SOURCES) $(PLAT_BL_COMMON_SOURCES)) @@ -438,8 +507,7 @@ all : bl$(1) -$(eval FIP_DEPS += $(if $2,$(BIN),)) -$(eval FIP_ARGS += $(if $2,--bl$(1) $(BIN),)) +$(eval $(call MAKE_TOOL_ARGS,$(1),$(BIN),$(2),$(3),$(4),$(5))) endef @@ -449,23 +517,23 @@ endif ifeq (${NEED_BL2},yes) -$(if ${BL2}, $(eval FIP_DEPS += ${BL2}) $(eval FIP_ARGS += --bl2 ${BL2}),\ - $(eval $(call MAKE_BL,2,in_fip))) +$(if ${BL2}, $(eval $(call MAKE_TOOL_ARGS,2,${BL2},in_fip,${CERTS})),\ + $(eval $(call MAKE_BL,2,in_fip,${CERTS}))) endif ifeq (${NEED_BL31},yes) BL31_SOURCES += ${SPD_SOURCES} -$(if ${BL31}, $(eval FIP_DEPS += ${BL31}) $(eval FIP_ARGS += --bl31 ${BL31}),\ - $(eval $(call MAKE_BL,31,in_fip))) +$(if ${BL31}, $(eval $(call MAKE_TOOL_ARGS,31,${BL31},in_fip,${CERTS},${CERTS},${BL31_KEY})),\ + $(eval $(call MAKE_BL,31,in_fip,${CERTS},${CERTS},${BL31_KEY}))) endif ifeq (${NEED_BL32},yes) -$(if ${BL32}, $(eval FIP_DEPS += ${BL32}) $(eval FIP_ARGS += --bl32 ${BL32}),\ - $(eval $(call MAKE_BL,32,in_fip))) +$(if ${BL32}, $(eval $(call MAKE_TOOL_ARGS,32,${BL32},in_fip,${CERTS},${CERTS},${BL32_KEY})),\ + $(eval $(call MAKE_BL,32,in_fip,${CERTS},${CERTS},${BL32_KEY}))) endif ifeq (${NEED_BL30},yes) -$(if ${BL30}, $(eval FIP_DEPS += ${BL30}) $(eval FIP_ARGS += --bl30 ${BL30}), ) +$(if ${BL30}, $(eval $(call MAKE_TOOL_ARGS,30,${BL30},in_fip,${CERTS},${CERTS},${BL30_KEY}))) # If BL3-0 is needed by the platform then 'BL30' variable must be defined. check_bl30: @@ -479,7 +547,7 @@ endif ifeq (${NEED_BL33},yes) -$(if ${BL33}, $(eval FIP_DEPS += ${BL33}) $(eval FIP_ARGS += --bl33 ${BL33}), ) +$(if ${BL33}, $(eval $(call MAKE_TOOL_ARGS,33,${BL33},in_fip,${CERTS},${CERTS},${BL33_KEY}))) # If BL3-3 is needed by the platform then 'BL33' variable must be defined. check_bl33: @@ -492,6 +560,17 @@ $(if ${BL33},$(warning "BL3-3 is not supported on platform ${PLAT}, it will just be ignored"),) endif +# Add the dependency on the certificates +ifneq (${GENERATE_COT},0) + all: certificates +endif + +certificates: ${CRT_DEPS} ${CRTTOOL} check_bl30 check_bl33 + ${Q}${CRTTOOL} ${CRT_ARGS} + @echo + @echo "Built $@ successfully" + @echo "Certificates can be found in ${BUILD_PLAT}" + @echo ${BUILD_PLAT}/${FIP_NAME}: ${FIP_DEPS} ${FIPTOOL} check_bl30 check_bl33 ${Q}${FIPTOOL} --dump \ @@ -524,6 +603,7 @@ @echo " clean Clean the build for the selected platform" @echo " cscope Generate cscope index" @echo " distclean Remove all build artifacts for all platforms" + @echo " certtool Build the Certificate generation tool" @echo " fiptool Build the Firmware Image Package(FIP) creation tool" @echo "" @echo "note: most build targets require PLAT to be set to a specific platform." diff --git a/plat/fvp/include/platform_oid.h b/plat/fvp/include/platform_oid.h new file mode 100644 index 0000000..38aca12 --- /dev/null +++ b/plat/fvp/include/platform_oid.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 PLATFORM_OID_H_ +#define PLATFORM_OID_H_ + +/* + * This is the list of the different extensions containing relevant information + * to establish the chain of trust. + * + * The OIDs shown here are just an example. Real OIDs should be obtained from + * the ITU-T. + */ + +/* Non-volatile counter extensions */ +#define TZ_FW_NVCOUNTER_OID "1.2.3.1" +#define NTZ_FW_NVCOUNTER_OID "1.2.3.2" + +/* BL2 extensions */ +#define BL2_HASH_OID "1.2.3.3" + +/* Trusted Key extensions */ +#define TZ_WORLD_PK_OID "1.2.3.4" +#define NTZ_WORLD_PK_OID "1.2.3.5" + +/* BL3-1 extensions */ +#define BL31_CONTENT_CERT_PK_OID "1.2.3.6" +#define BL31_HASH_OID "1.2.3.7" + +/* BL3-0 extensions */ +#define BL30_CONTENT_CERT_PK_OID "1.2.3.8" +#define BL30_HASH_OID "1.2.3.9" + +/* BL3-2 extensions */ +#define BL32_CONTENT_CERT_PK_OID "1.2.3.10" +#define BL32_HASH_OID "1.2.3.11" + +/* BL3-3 extensions */ +#define BL33_CONTENT_CERT_PK_OID "1.2.3.12" +#define BL33_HASH_OID "1.2.3.13" + +#endif /* PLATFORM_OID_H_ */ diff --git a/plat/juno/include/platform_oid.h b/plat/juno/include/platform_oid.h new file mode 100644 index 0000000..38aca12 --- /dev/null +++ b/plat/juno/include/platform_oid.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 PLATFORM_OID_H_ +#define PLATFORM_OID_H_ + +/* + * This is the list of the different extensions containing relevant information + * to establish the chain of trust. + * + * The OIDs shown here are just an example. Real OIDs should be obtained from + * the ITU-T. + */ + +/* Non-volatile counter extensions */ +#define TZ_FW_NVCOUNTER_OID "1.2.3.1" +#define NTZ_FW_NVCOUNTER_OID "1.2.3.2" + +/* BL2 extensions */ +#define BL2_HASH_OID "1.2.3.3" + +/* Trusted Key extensions */ +#define TZ_WORLD_PK_OID "1.2.3.4" +#define NTZ_WORLD_PK_OID "1.2.3.5" + +/* BL3-1 extensions */ +#define BL31_CONTENT_CERT_PK_OID "1.2.3.6" +#define BL31_HASH_OID "1.2.3.7" + +/* BL3-0 extensions */ +#define BL30_CONTENT_CERT_PK_OID "1.2.3.8" +#define BL30_HASH_OID "1.2.3.9" + +/* BL3-2 extensions */ +#define BL32_CONTENT_CERT_PK_OID "1.2.3.10" +#define BL32_HASH_OID "1.2.3.11" + +/* BL3-3 extensions */ +#define BL33_CONTENT_CERT_PK_OID "1.2.3.12" +#define BL33_HASH_OID "1.2.3.13" + +#endif /* PLATFORM_OID_H_ */ diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile new file mode 100644 index 0000000..f1aa797 --- /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=.) +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 0000000..48a4146 --- /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 +#include +#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 0000000..dd0510a --- /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 + +/* 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 0000000..d73f573 --- /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 + +/* + * 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 0000000..8819750 --- /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 + +#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 0000000..466d668 --- /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 0000000..4e48125 --- /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 0000000..155d3cb --- /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 0000000..cc927d1 --- /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 0000000..9705643 --- /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 +#include +#include + +#include +#include +#include +#include +#include + +#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 0000000..31f84a8 --- /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 +#include +#include +#include +#include +#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 0000000..b5737d9 --- /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 +#include +#include +#include + +#include +#include +#include + +#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 0000000..6df367a --- /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 +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#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 \\\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 0000000..57026b5 --- /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 +#include + +#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 0000000..8dfda60 --- /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 0000000..0022611 --- /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 +#include +#include +#include +#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 0000000..140aeda --- /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" + } +};