xref: /rk3399_ARM-atf/tools/cert_create/src/main.c (revision ccbf890e5e2fb75b4df30f50f06c505702a0e01c)
16f971622SJuan Castillo /*
26f971622SJuan Castillo  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
36f971622SJuan Castillo  *
46f971622SJuan Castillo  * Redistribution and use in source and binary forms, with or without
56f971622SJuan Castillo  * modification, are permitted provided that the following conditions are met:
66f971622SJuan Castillo  *
76f971622SJuan Castillo  * Redistributions of source code must retain the above copyright notice, this
86f971622SJuan Castillo  * list of conditions and the following disclaimer.
96f971622SJuan Castillo  *
106f971622SJuan Castillo  * Redistributions in binary form must reproduce the above copyright notice,
116f971622SJuan Castillo  * this list of conditions and the following disclaimer in the documentation
126f971622SJuan Castillo  * and/or other materials provided with the distribution.
136f971622SJuan Castillo  *
146f971622SJuan Castillo  * Neither the name of ARM nor the names of its contributors may be used
156f971622SJuan Castillo  * to endorse or promote products derived from this software without specific
166f971622SJuan Castillo  * prior written permission.
176f971622SJuan Castillo  *
186f971622SJuan Castillo  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
196f971622SJuan Castillo  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
206f971622SJuan Castillo  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
216f971622SJuan Castillo  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
226f971622SJuan Castillo  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
236f971622SJuan Castillo  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
246f971622SJuan Castillo  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
256f971622SJuan Castillo  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
266f971622SJuan Castillo  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
276f971622SJuan Castillo  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
286f971622SJuan Castillo  * POSSIBILITY OF SUCH DAMAGE.
296f971622SJuan Castillo  */
306f971622SJuan Castillo 
316f971622SJuan Castillo #include <getopt.h>
326f971622SJuan Castillo #include <stdio.h>
336f971622SJuan Castillo #include <stdlib.h>
346f971622SJuan Castillo #include <string.h>
356f971622SJuan Castillo 
366f971622SJuan Castillo #include <openssl/conf.h>
376f971622SJuan Castillo #include <openssl/engine.h>
386f971622SJuan Castillo #include <openssl/err.h>
396f971622SJuan Castillo #include <openssl/pem.h>
406f971622SJuan Castillo #include <openssl/sha.h>
416f971622SJuan Castillo #include <openssl/x509v3.h>
426f971622SJuan Castillo 
436f971622SJuan Castillo #include "cert.h"
446f971622SJuan Castillo #include "debug.h"
456f971622SJuan Castillo #include "ext.h"
466f971622SJuan Castillo #include "key.h"
476f971622SJuan Castillo #include "platform_oid.h"
486f971622SJuan Castillo #include "sha.h"
496f971622SJuan Castillo #include "tbb_ext.h"
506f971622SJuan Castillo #include "tbb_cert.h"
516f971622SJuan Castillo #include "tbb_key.h"
526f971622SJuan Castillo 
536f971622SJuan Castillo /*
546f971622SJuan Castillo  * Helper macros to simplify the code. This macro assigns the return value of
556f971622SJuan Castillo  * the 'fn' function to 'v' and exits if the value is NULL.
566f971622SJuan Castillo  */
576f971622SJuan Castillo #define CHECK_NULL(v, fn) \
586f971622SJuan Castillo 	do { \
596f971622SJuan Castillo 		v = fn; \
606f971622SJuan Castillo 		if (v == NULL) { \
616f971622SJuan Castillo 			ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \
626f971622SJuan Castillo 			exit(1); \
636f971622SJuan Castillo 		} \
646f971622SJuan Castillo 	} while (0)
656f971622SJuan Castillo 
666f971622SJuan Castillo /*
676f971622SJuan Castillo  * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the
686f971622SJuan Castillo  * NID is undefined.
696f971622SJuan Castillo  */
706f971622SJuan Castillo #define CHECK_OID(v, oid) \
716f971622SJuan Castillo 	do { \
726f971622SJuan Castillo 		v = OBJ_txt2nid(oid); \
736f971622SJuan Castillo 		if (v == NID_undef) { \
746f971622SJuan Castillo 			ERROR("Cannot find TBB extension %s\n", oid); \
756f971622SJuan Castillo 			exit(1); \
766f971622SJuan Castillo 		} \
776f971622SJuan Castillo 	} while (0)
786f971622SJuan Castillo 
796f971622SJuan Castillo #define MAX_FILENAME_LEN		1024
806f971622SJuan Castillo #define VAL_DAYS			7300
816f971622SJuan Castillo #define ID_TO_BIT_MASK(id)		(1 << id)
826f971622SJuan Castillo #define NVCOUNTER_VALUE			0
83*ccbf890eSJuan Castillo #define NUM_ELEM(x)			((sizeof(x)) / (sizeof(x[0])))
846f971622SJuan Castillo 
856f971622SJuan Castillo /* Files */
866f971622SJuan Castillo enum {
876f971622SJuan Castillo 	/* Image file names (inputs) */
886f971622SJuan Castillo 	BL2_ID = 0,
896f971622SJuan Castillo 	BL30_ID,
906f971622SJuan Castillo 	BL31_ID,
916f971622SJuan Castillo 	BL32_ID,
926f971622SJuan Castillo 	BL33_ID,
936f971622SJuan Castillo 	/* Certificate file names (outputs) */
946f971622SJuan Castillo 	BL2_CERT_ID,
956f971622SJuan Castillo 	TRUSTED_KEY_CERT_ID,
966f971622SJuan Castillo 	BL30_KEY_CERT_ID,
976f971622SJuan Castillo 	BL30_CERT_ID,
986f971622SJuan Castillo 	BL31_KEY_CERT_ID,
996f971622SJuan Castillo 	BL31_CERT_ID,
1006f971622SJuan Castillo 	BL32_KEY_CERT_ID,
1016f971622SJuan Castillo 	BL32_CERT_ID,
1026f971622SJuan Castillo 	BL33_KEY_CERT_ID,
1036f971622SJuan Castillo 	BL33_CERT_ID,
1046f971622SJuan Castillo 	/* Key file names (input/output) */
1056f971622SJuan Castillo 	ROT_KEY_ID,
1066f971622SJuan Castillo 	TRUSTED_WORLD_KEY_ID,
1076f971622SJuan Castillo 	NON_TRUSTED_WORLD_KEY_ID,
1086f971622SJuan Castillo 	BL30_KEY_ID,
1096f971622SJuan Castillo 	BL31_KEY_ID,
1106f971622SJuan Castillo 	BL32_KEY_ID,
1116f971622SJuan Castillo 	BL33_KEY_ID,
1126f971622SJuan Castillo 	NUM_OPTS
1136f971622SJuan Castillo };
1146f971622SJuan Castillo 
1156f971622SJuan Castillo /* Global options */
116*ccbf890eSJuan Castillo static int key_alg;
1176f971622SJuan Castillo static int new_keys;
1186f971622SJuan Castillo static int save_keys;
1196f971622SJuan Castillo static int print_cert;
1206f971622SJuan Castillo static int bl30_present;
1216f971622SJuan Castillo static int bl32_present;
1226f971622SJuan Castillo 
1236f971622SJuan Castillo /* We are not checking nvcounters in TF. Include them in the certificates but
1246f971622SJuan Castillo  * the value will be set to 0 */
1256f971622SJuan Castillo static int tf_nvcounter;
1266f971622SJuan Castillo static int non_tf_nvcounter;
1276f971622SJuan Castillo 
1286f971622SJuan Castillo /* Info messages created in the Makefile */
1296f971622SJuan Castillo extern const char build_msg[];
1306f971622SJuan Castillo extern const char platform_msg[];
1316f971622SJuan Castillo 
1326f971622SJuan Castillo 
1336f971622SJuan Castillo static char *strdup(const char *str)
1346f971622SJuan Castillo {
1356f971622SJuan Castillo 	int n = strlen(str) + 1;
1366f971622SJuan Castillo 	char *dup = malloc(n);
1376f971622SJuan Castillo 	if (dup) {
1386f971622SJuan Castillo 		strcpy(dup, str);
1396f971622SJuan Castillo 	}
1406f971622SJuan Castillo 	return dup;
1416f971622SJuan Castillo }
1426f971622SJuan Castillo 
143*ccbf890eSJuan Castillo static const char *key_algs_str[] = {
144*ccbf890eSJuan Castillo 	[KEY_ALG_RSA] = "rsa",
145*ccbf890eSJuan Castillo 	[KEY_ALG_ECDSA] = "ecdsa"
146*ccbf890eSJuan Castillo };
147*ccbf890eSJuan Castillo 
1486f971622SJuan Castillo /* Command line options */
1496f971622SJuan Castillo static const struct option long_opt[] = {
1506f971622SJuan Castillo 	/* Binary images */
1516f971622SJuan Castillo 	{"bl2", required_argument, 0, BL2_ID},
1526f971622SJuan Castillo 	{"bl30", required_argument, 0, BL30_ID},
1536f971622SJuan Castillo 	{"bl31", required_argument, 0, BL31_ID},
1546f971622SJuan Castillo 	{"bl32", required_argument, 0, BL32_ID},
1556f971622SJuan Castillo 	{"bl33", required_argument, 0, BL33_ID},
1566f971622SJuan Castillo 	/* Certificate files */
1576f971622SJuan Castillo 	{"bl2-cert", required_argument, 0, BL2_CERT_ID},
1586f971622SJuan Castillo 	{"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID},
1596f971622SJuan Castillo 	{"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID},
1606f971622SJuan Castillo 	{"bl30-cert", required_argument, 0, BL30_CERT_ID},
1616f971622SJuan Castillo 	{"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID},
1626f971622SJuan Castillo 	{"bl31-cert", required_argument, 0, BL31_CERT_ID},
1636f971622SJuan Castillo 	{"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID},
1646f971622SJuan Castillo 	{"bl32-cert", required_argument, 0, BL32_CERT_ID},
1656f971622SJuan Castillo 	{"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID},
1666f971622SJuan Castillo 	{"bl33-cert", required_argument, 0, BL33_CERT_ID},
1676f971622SJuan Castillo 	/* Private key files */
1686f971622SJuan Castillo 	{"rot-key", required_argument, 0, ROT_KEY_ID},
1696f971622SJuan Castillo 	{"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID},
1706f971622SJuan Castillo 	{"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID},
1716f971622SJuan Castillo 	{"bl30-key", required_argument, 0, BL30_KEY_ID},
1726f971622SJuan Castillo 	{"bl31-key", required_argument, 0, BL31_KEY_ID},
1736f971622SJuan Castillo 	{"bl32-key", required_argument, 0, BL32_KEY_ID},
1746f971622SJuan Castillo 	{"bl33-key", required_argument, 0, BL33_KEY_ID},
1756f971622SJuan Castillo 	/* Common options */
176*ccbf890eSJuan Castillo 	{"key-alg", required_argument, 0, 'a'},
1776f971622SJuan Castillo 	{"help", no_argument, 0, 'h'},
1786f971622SJuan Castillo 	{"save-keys", no_argument, 0, 'k'},
1796f971622SJuan Castillo 	{"new-chain", no_argument, 0, 'n'},
1806f971622SJuan Castillo 	{"print-cert", no_argument, 0, 'p'},
1816f971622SJuan Castillo 	{0, 0, 0, 0}
1826f971622SJuan Castillo };
1836f971622SJuan Castillo 
1846f971622SJuan Castillo static void print_help(const char *cmd)
1856f971622SJuan Castillo {
1866f971622SJuan Castillo 	int i = 0;
1876f971622SJuan Castillo 	printf("\n\n");
1886f971622SJuan Castillo 	printf("The certificate generation tool loads the binary images and\n"
1896f971622SJuan Castillo 	       "optionally the RSA keys, and outputs the key and content\n"
1906f971622SJuan Castillo 	       "certificates properly signed to implement the chain of trust.\n"
1916f971622SJuan Castillo 	       "If keys are provided, they must be in PEM format.\n"
1926f971622SJuan Castillo 	       "Certificates are generated in DER format.\n");
1936f971622SJuan Castillo 	printf("\n");
1946f971622SJuan Castillo 	printf("Usage:\n\n");
1956f971622SJuan Castillo 	printf("    %s [-hknp] \\\n", cmd);
1966f971622SJuan Castillo 	for (i = 0; i < NUM_OPTS; i++) {
1976f971622SJuan Castillo 		printf("        --%s <file>  \\\n", long_opt[i].name);
1986f971622SJuan Castillo 	}
1996f971622SJuan Castillo 	printf("\n");
200*ccbf890eSJuan Castillo 	printf("-a    Key algorithm: rsa (default), ecdsa\n");
2016f971622SJuan Castillo 	printf("-h    Print help and exit\n");
2026f971622SJuan Castillo 	printf("-k    Save key pairs into files. Filenames must be provided\n");
2036f971622SJuan Castillo 	printf("-n    Generate new key pairs if no key files are provided\n");
2046f971622SJuan Castillo 	printf("-p    Print the certificates in the standard output\n");
2056f971622SJuan Castillo 	printf("\n");
2066f971622SJuan Castillo 
2076f971622SJuan Castillo 	exit(0);
2086f971622SJuan Castillo }
2096f971622SJuan Castillo 
210*ccbf890eSJuan Castillo static int get_key_alg(const char *key_alg_str)
211*ccbf890eSJuan Castillo {
212*ccbf890eSJuan Castillo 	int i;
213*ccbf890eSJuan Castillo 
214*ccbf890eSJuan Castillo 	for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) {
215*ccbf890eSJuan Castillo 		if (0 == strcmp(key_alg_str, key_algs_str[i])) {
216*ccbf890eSJuan Castillo 			return i;
217*ccbf890eSJuan Castillo 		}
218*ccbf890eSJuan Castillo 	}
219*ccbf890eSJuan Castillo 
220*ccbf890eSJuan Castillo 	return -1;
221*ccbf890eSJuan Castillo }
222*ccbf890eSJuan Castillo 
2236f971622SJuan Castillo static void check_cmd_params(void)
2246f971622SJuan Castillo {
225*ccbf890eSJuan Castillo 	/* Only save new keys */
226*ccbf890eSJuan Castillo 	if (save_keys && !new_keys) {
227*ccbf890eSJuan Castillo 		ERROR("Only new keys can be saved to disk\n");
228*ccbf890eSJuan Castillo 		exit(1);
229*ccbf890eSJuan Castillo 	}
230*ccbf890eSJuan Castillo 
2316f971622SJuan Castillo 	/* BL2, BL31 and BL33 are mandatory */
2326f971622SJuan Castillo 	if (certs[BL2_CERT].bin == NULL) {
2336f971622SJuan Castillo 		ERROR("BL2 image not specified\n");
2346f971622SJuan Castillo 		exit(1);
2356f971622SJuan Castillo 	}
2366f971622SJuan Castillo 
2376f971622SJuan Castillo 	if (certs[BL31_CERT].bin == NULL) {
2386f971622SJuan Castillo 		ERROR("BL31 image not specified\n");
2396f971622SJuan Castillo 		exit(1);
2406f971622SJuan Castillo 	}
2416f971622SJuan Castillo 
2426f971622SJuan Castillo 	if (certs[BL33_CERT].bin == NULL) {
2436f971622SJuan Castillo 		ERROR("BL33 image not specified\n");
2446f971622SJuan Castillo 		exit(1);
2456f971622SJuan Castillo 	}
2466f971622SJuan Castillo 
2476f971622SJuan Castillo 	/* BL30 and BL32 are optional */
2486f971622SJuan Castillo 	if (certs[BL30_CERT].bin != NULL) {
2496f971622SJuan Castillo 		bl30_present = 1;
2506f971622SJuan Castillo 	}
2516f971622SJuan Castillo 
2526f971622SJuan Castillo 	if (certs[BL32_CERT].bin != NULL) {
2536f971622SJuan Castillo 		bl32_present = 1;
2546f971622SJuan Castillo 	}
2556f971622SJuan Castillo 
2566f971622SJuan Castillo 	/* TODO: Certificate filenames */
2576f971622SJuan Castillo 
2586f971622SJuan Castillo 	/* Filenames to store keys must be specified */
2596f971622SJuan Castillo 	if (save_keys || !new_keys) {
2606f971622SJuan Castillo 		if (keys[ROT_KEY].fn == NULL) {
2616f971622SJuan Castillo 			ERROR("ROT key not specified\n");
2626f971622SJuan Castillo 			exit(1);
2636f971622SJuan Castillo 		}
2646f971622SJuan Castillo 
2656f971622SJuan Castillo 		if (keys[TRUSTED_WORLD_KEY].fn == NULL) {
2666f971622SJuan Castillo 			ERROR("Trusted World key not specified\n");
2676f971622SJuan Castillo 			exit(1);
2686f971622SJuan Castillo 		}
2696f971622SJuan Castillo 
2706f971622SJuan Castillo 		if (keys[NON_TRUSTED_WORLD_KEY].fn == NULL) {
2716f971622SJuan Castillo 			ERROR("Non-trusted World key not specified\n");
2726f971622SJuan Castillo 			exit(1);
2736f971622SJuan Castillo 		}
2746f971622SJuan Castillo 
2756f971622SJuan Castillo 		if (keys[BL31_KEY].fn == NULL) {
2766f971622SJuan Castillo 			ERROR("BL31 key not specified\n");
2776f971622SJuan Castillo 			exit(1);
2786f971622SJuan Castillo 		}
2796f971622SJuan Castillo 
2806f971622SJuan Castillo 		if (keys[BL33_KEY].fn == NULL) {
2816f971622SJuan Castillo 			ERROR("BL33 key not specified\n");
2826f971622SJuan Castillo 			exit(1);
2836f971622SJuan Castillo 		}
2846f971622SJuan Castillo 
2856f971622SJuan Castillo 		if (bl30_present && (keys[BL30_KEY].fn == NULL)) {
2866f971622SJuan Castillo 			ERROR("BL30 key not specified\n");
2876f971622SJuan Castillo 			exit(1);
2886f971622SJuan Castillo 		}
2896f971622SJuan Castillo 
2906f971622SJuan Castillo 		if (bl32_present && (keys[BL32_KEY].fn == NULL)) {
2916f971622SJuan Castillo 			ERROR("BL32 key not specified\n");
2926f971622SJuan Castillo 			exit(1);
2936f971622SJuan Castillo 		}
2946f971622SJuan Castillo 	}
2956f971622SJuan Castillo }
2966f971622SJuan Castillo 
2976f971622SJuan Castillo int main(int argc, char *argv[])
2986f971622SJuan Castillo {
2996f971622SJuan Castillo 	STACK_OF(X509_EXTENSION) * sk = NULL;
3006f971622SJuan Castillo 	X509_EXTENSION *hash_ext = NULL;
3016f971622SJuan Castillo 	X509_EXTENSION *nvctr_ext = NULL;
3026f971622SJuan Castillo 	X509_EXTENSION *trusted_key_ext = NULL;
3036f971622SJuan Castillo 	X509_EXTENSION *non_trusted_key_ext = NULL;
3046f971622SJuan Castillo 	FILE *file = NULL;
3056f971622SJuan Castillo 	int i, tz_nvctr_nid, ntz_nvctr_nid, hash_nid, pk_nid;
3066f971622SJuan Castillo 	int c, opt_idx = 0;
307*ccbf890eSJuan Castillo 	unsigned int err_code;
3086f971622SJuan Castillo 	unsigned char md[SHA256_DIGEST_LENGTH];
309c3da66b1SJuan Castillo 	const EVP_MD *md_info;
3106f971622SJuan Castillo 
3116f971622SJuan Castillo 	NOTICE("CoT Generation Tool: %s\n", build_msg);
3126f971622SJuan Castillo 	NOTICE("Target platform: %s\n", platform_msg);
3136f971622SJuan Castillo 
314*ccbf890eSJuan Castillo 	/* Set default options */
315*ccbf890eSJuan Castillo 	key_alg = KEY_ALG_RSA;
316*ccbf890eSJuan Castillo 
3176f971622SJuan Castillo 	while (1) {
3186f971622SJuan Castillo 		/* getopt_long stores the option index here. */
319*ccbf890eSJuan Castillo 		c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx);
3206f971622SJuan Castillo 
3216f971622SJuan Castillo 		/* Detect the end of the options. */
3226f971622SJuan Castillo 		if (c == -1) {
3236f971622SJuan Castillo 			break;
3246f971622SJuan Castillo 		}
3256f971622SJuan Castillo 
3266f971622SJuan Castillo 		switch (c) {
327*ccbf890eSJuan Castillo 		case 'a':
328*ccbf890eSJuan Castillo 			key_alg = get_key_alg(optarg);
329*ccbf890eSJuan Castillo 			if (key_alg < 0) {
330*ccbf890eSJuan Castillo 				ERROR("Invalid key algorithm '%s'\n", optarg);
331*ccbf890eSJuan Castillo 				exit(1);
332*ccbf890eSJuan Castillo 			}
333*ccbf890eSJuan Castillo 			break;
3346f971622SJuan Castillo 		case 'h':
3356f971622SJuan Castillo 			print_help(argv[0]);
3366f971622SJuan Castillo 			break;
3376f971622SJuan Castillo 		case 'k':
3386f971622SJuan Castillo 			save_keys = 1;
3396f971622SJuan Castillo 			break;
3406f971622SJuan Castillo 		case 'n':
3416f971622SJuan Castillo 			new_keys = 1;
3426f971622SJuan Castillo 			break;
3436f971622SJuan Castillo 		case 'p':
3446f971622SJuan Castillo 			print_cert = 1;
3456f971622SJuan Castillo 			break;
3466f971622SJuan Castillo 		case BL2_ID:
3476f971622SJuan Castillo 			certs[BL2_CERT].bin = strdup(optarg);
3486f971622SJuan Castillo 			break;
3496f971622SJuan Castillo 		case BL30_ID:
3506f971622SJuan Castillo 			certs[BL30_CERT].bin = strdup(optarg);
3516f971622SJuan Castillo 			break;
3526f971622SJuan Castillo 		case BL31_ID:
3536f971622SJuan Castillo 			certs[BL31_CERT].bin = strdup(optarg);
3546f971622SJuan Castillo 			break;
3556f971622SJuan Castillo 		case BL32_ID:
3566f971622SJuan Castillo 			certs[BL32_CERT].bin = strdup(optarg);
3576f971622SJuan Castillo 			break;
3586f971622SJuan Castillo 		case BL33_ID:
3596f971622SJuan Castillo 			certs[BL33_CERT].bin = strdup(optarg);
3606f971622SJuan Castillo 			break;
3616f971622SJuan Castillo 		case BL2_CERT_ID:
3626f971622SJuan Castillo 			certs[BL2_CERT].fn = strdup(optarg);
3636f971622SJuan Castillo 			break;
3646f971622SJuan Castillo 		case TRUSTED_KEY_CERT_ID:
3656f971622SJuan Castillo 			certs[TRUSTED_KEY_CERT].fn = strdup(optarg);
3666f971622SJuan Castillo 			break;
3676f971622SJuan Castillo 		case BL30_KEY_CERT_ID:
3686f971622SJuan Castillo 			certs[BL30_KEY_CERT].fn = strdup(optarg);
3696f971622SJuan Castillo 			break;
3706f971622SJuan Castillo 		case BL30_CERT_ID:
3716f971622SJuan Castillo 			certs[BL30_CERT].fn = strdup(optarg);
3726f971622SJuan Castillo 			break;
3736f971622SJuan Castillo 		case BL31_KEY_CERT_ID:
3746f971622SJuan Castillo 			certs[BL31_KEY_CERT].fn = strdup(optarg);
3756f971622SJuan Castillo 			break;
3766f971622SJuan Castillo 		case BL31_CERT_ID:
3776f971622SJuan Castillo 			certs[BL31_CERT].fn = strdup(optarg);
3786f971622SJuan Castillo 			break;
3796f971622SJuan Castillo 		case BL32_KEY_CERT_ID:
3806f971622SJuan Castillo 			certs[BL32_KEY_CERT].fn = strdup(optarg);
3816f971622SJuan Castillo 			break;
3826f971622SJuan Castillo 		case BL32_CERT_ID:
3836f971622SJuan Castillo 			certs[BL32_CERT].fn = strdup(optarg);
3846f971622SJuan Castillo 			break;
3856f971622SJuan Castillo 		case BL33_KEY_CERT_ID:
3866f971622SJuan Castillo 			certs[BL33_KEY_CERT].fn = strdup(optarg);
3876f971622SJuan Castillo 			break;
3886f971622SJuan Castillo 		case BL33_CERT_ID:
3896f971622SJuan Castillo 			certs[BL33_CERT].fn = strdup(optarg);
3906f971622SJuan Castillo 			break;
3916f971622SJuan Castillo 		case ROT_KEY_ID:
3926f971622SJuan Castillo 			keys[ROT_KEY].fn = strdup(optarg);
3936f971622SJuan Castillo 			break;
3946f971622SJuan Castillo 		case TRUSTED_WORLD_KEY_ID:
3956f971622SJuan Castillo 			keys[TRUSTED_WORLD_KEY].fn = strdup(optarg);
3966f971622SJuan Castillo 			break;
3976f971622SJuan Castillo 		case NON_TRUSTED_WORLD_KEY_ID:
3986f971622SJuan Castillo 			keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg);
3996f971622SJuan Castillo 			break;
4006f971622SJuan Castillo 		case BL30_KEY_ID:
4016f971622SJuan Castillo 			keys[BL30_KEY].fn = strdup(optarg);
4026f971622SJuan Castillo 			break;
4036f971622SJuan Castillo 		case BL31_KEY_ID:
4046f971622SJuan Castillo 			keys[BL31_KEY].fn = strdup(optarg);
4056f971622SJuan Castillo 			break;
4066f971622SJuan Castillo 		case BL32_KEY_ID:
4076f971622SJuan Castillo 			keys[BL32_KEY].fn = strdup(optarg);
4086f971622SJuan Castillo 			break;
4096f971622SJuan Castillo 		case BL33_KEY_ID:
4106f971622SJuan Castillo 			keys[BL33_KEY].fn = strdup(optarg);
4116f971622SJuan Castillo 			break;
4126f971622SJuan Castillo 		case '?':
4136f971622SJuan Castillo 		default:
4146f971622SJuan Castillo 			printf("%s\n", optarg);
4156f971622SJuan Castillo 			exit(1);
4166f971622SJuan Castillo 		}
4176f971622SJuan Castillo 	}
4186f971622SJuan Castillo 
4196f971622SJuan Castillo 	/* Set the value of the NVCounters */
4206f971622SJuan Castillo 	tf_nvcounter = NVCOUNTER_VALUE;
4216f971622SJuan Castillo 	non_tf_nvcounter = NVCOUNTER_VALUE;
4226f971622SJuan Castillo 
4236f971622SJuan Castillo 	/* Check command line arguments */
4246f971622SJuan Castillo 	check_cmd_params();
4256f971622SJuan Castillo 
4266f971622SJuan Castillo 	/* Register the new types and OIDs for the extensions */
4276f971622SJuan Castillo 	if (ext_init(tbb_ext) != 0) {
4286f971622SJuan Castillo 		ERROR("Cannot initialize TBB extensions\n");
4296f971622SJuan Castillo 		exit(1);
4306f971622SJuan Castillo 	}
4316f971622SJuan Castillo 
432c3da66b1SJuan Castillo 	/* Indicate SHA256 as image hash algorithm in the certificate
433c3da66b1SJuan Castillo 	 * extension */
434c3da66b1SJuan Castillo 	md_info = EVP_sha256();
435c3da66b1SJuan Castillo 
4366f971622SJuan Castillo 	/* Get non-volatile counters NIDs */
4376f971622SJuan Castillo 	CHECK_OID(tz_nvctr_nid, TZ_FW_NVCOUNTER_OID);
4386f971622SJuan Castillo 	CHECK_OID(ntz_nvctr_nid, NTZ_FW_NVCOUNTER_OID);
4396f971622SJuan Castillo 
4406f971622SJuan Castillo 	/* Load private keys from files (or generate new ones) */
4416f971622SJuan Castillo 	for (i = 0 ; i < NUM_KEYS ; i++) {
442*ccbf890eSJuan Castillo 		/* First try to load the key from disk */
443*ccbf890eSJuan Castillo 		if (key_load(&keys[i], &err_code)) {
444*ccbf890eSJuan Castillo 			/* Key loaded successfully */
445*ccbf890eSJuan Castillo 			continue;
446*ccbf890eSJuan Castillo 		}
447*ccbf890eSJuan Castillo 
448*ccbf890eSJuan Castillo 		/* Key not loaded. Check the error code */
449*ccbf890eSJuan Castillo 		if (err_code == KEY_ERR_MALLOC) {
450*ccbf890eSJuan Castillo 			/* Cannot allocate memory. Abort. */
451*ccbf890eSJuan Castillo 			ERROR("Malloc error while loading '%s'\n", keys[i].fn);
452*ccbf890eSJuan Castillo 			exit(1);
453*ccbf890eSJuan Castillo 		} else if (err_code == KEY_ERR_LOAD) {
454*ccbf890eSJuan Castillo 			/* File exists, but it does not contain a valid private
455*ccbf890eSJuan Castillo 			 * key. Abort. */
456*ccbf890eSJuan Castillo 			ERROR("Error loading '%s'\n", keys[i].fn);
4576f971622SJuan Castillo 			exit(1);
4586f971622SJuan Castillo 		}
459*ccbf890eSJuan Castillo 
460*ccbf890eSJuan Castillo 		/* File does not exist, could not be opened or no filename was
461*ccbf890eSJuan Castillo 		 * given */
462*ccbf890eSJuan Castillo 		if (new_keys) {
463*ccbf890eSJuan Castillo 			/* Try to create a new key */
464*ccbf890eSJuan Castillo 			NOTICE("Creating new key for '%s'\n", keys[i].desc);
465*ccbf890eSJuan Castillo 			if (!key_create(&keys[i], key_alg)) {
466*ccbf890eSJuan Castillo 				ERROR("Error creating key '%s'\n", keys[i].desc);
467*ccbf890eSJuan Castillo 				exit(1);
4686f971622SJuan Castillo 			}
4696f971622SJuan Castillo 		} else {
470*ccbf890eSJuan Castillo 			if (err_code == KEY_ERR_OPEN) {
471*ccbf890eSJuan Castillo 				ERROR("Error opening '%s'\n", keys[i].fn);
472*ccbf890eSJuan Castillo 			} else {
473*ccbf890eSJuan Castillo 				ERROR("Key '%s' not specified\n", keys[i].desc);
4746f971622SJuan Castillo 			}
475*ccbf890eSJuan Castillo 			exit(1);
4766f971622SJuan Castillo 		}
4776f971622SJuan Castillo 	}
4786f971622SJuan Castillo 
4796f971622SJuan Castillo 	/* *********************************************************************
4806f971622SJuan Castillo 	 * BL2 certificate (Trusted Boot Firmware certificate):
4816f971622SJuan Castillo 	 *     - Self-signed with OEM ROT private key
4826f971622SJuan Castillo 	 *     - Extensions:
4836f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
4846f971622SJuan Castillo 	 *         - BL2 hash
4856f971622SJuan Castillo 	 **********************************************************************/
4866f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
4876f971622SJuan Castillo 
4886f971622SJuan Castillo 	/* Add the NVCounter as a critical extension */
4896f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
4906f971622SJuan Castillo 			tf_nvcounter));
4916f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
4926f971622SJuan Castillo 
4936f971622SJuan Castillo 	/* Add hash of BL2 as an extension */
4946f971622SJuan Castillo 	if (!sha_file(certs[BL2_CERT].bin, md)) {
4956f971622SJuan Castillo 		ERROR("Cannot calculate the hash of %s\n", certs[BL2_CERT].bin);
4966f971622SJuan Castillo 		exit(1);
4976f971622SJuan Castillo 	}
4986f971622SJuan Castillo 	CHECK_OID(hash_nid, BL2_HASH_OID);
499c3da66b1SJuan Castillo 	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md,
5006f971622SJuan Castillo 			SHA256_DIGEST_LENGTH));
5016f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, hash_ext);
5026f971622SJuan Castillo 
5036f971622SJuan Castillo 	/* Create certificate. Signed with ROT key */
5046f971622SJuan Castillo 	if (!cert_new(&certs[BL2_CERT], VAL_DAYS, 0, sk)) {
5056f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[BL2_CERT].cn);
5066f971622SJuan Castillo 		exit(1);
5076f971622SJuan Castillo 	}
5086f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
5096f971622SJuan Castillo 
5106f971622SJuan Castillo 	/* *********************************************************************
5116f971622SJuan Castillo 	 * Trusted Key certificate:
5126f971622SJuan Castillo 	 *     - Self-signed with OEM ROT private key
5136f971622SJuan Castillo 	 *     - Extensions:
5146f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
5156f971622SJuan Castillo 	 *         - TrustedWorldPK
5166f971622SJuan Castillo 	 *         - NonTrustedWorldPK
5176f971622SJuan Castillo 	 **********************************************************************/
5186f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
5196f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
5206f971622SJuan Castillo 			tf_nvcounter));
5216f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
5226f971622SJuan Castillo 	CHECK_OID(pk_nid, TZ_WORLD_PK_OID);
5236f971622SJuan Castillo 	CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
5246f971622SJuan Castillo 			keys[TRUSTED_WORLD_KEY].key));
5256f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, trusted_key_ext);
5266f971622SJuan Castillo 	CHECK_OID(pk_nid, NTZ_WORLD_PK_OID);
5276f971622SJuan Castillo 	CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
5286f971622SJuan Castillo 			keys[NON_TRUSTED_WORLD_KEY].key));
5296f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
5306f971622SJuan Castillo 	if (!cert_new(&certs[TRUSTED_KEY_CERT], VAL_DAYS, 0, sk)) {
5316f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[TRUSTED_KEY_CERT].cn);
5326f971622SJuan Castillo 		exit(1);
5336f971622SJuan Castillo 	}
5346f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
5356f971622SJuan Castillo 
5366f971622SJuan Castillo 	/* *********************************************************************
5376f971622SJuan Castillo 	 * BL30 Key certificate (Trusted SCP Firmware Key certificate):
5386f971622SJuan Castillo 	 *     - Self-signed with Trusted World key
5396f971622SJuan Castillo 	 *     - Extensions:
5406f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
5416f971622SJuan Castillo 	 *         - SCPFirmwareContentCertPK
5426f971622SJuan Castillo 	 **********************************************************************/
5436f971622SJuan Castillo 	if (bl30_present) {
5446f971622SJuan Castillo 		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
5456f971622SJuan Castillo 		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
5466f971622SJuan Castillo 				tf_nvcounter));
5476f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, nvctr_ext);
5486f971622SJuan Castillo 		CHECK_OID(pk_nid, BL30_CONTENT_CERT_PK_OID);
5496f971622SJuan Castillo 		CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
5506f971622SJuan Castillo 				keys[BL30_KEY].key));
5516f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, trusted_key_ext);
5526f971622SJuan Castillo 		if (!cert_new(&certs[BL30_KEY_CERT], VAL_DAYS, 0, sk)) {
5536f971622SJuan Castillo 			ERROR("Cannot create %s\n", certs[BL30_KEY_CERT].cn);
5546f971622SJuan Castillo 			exit(1);
5556f971622SJuan Castillo 		}
5566f971622SJuan Castillo 		sk_X509_EXTENSION_free(sk);
5576f971622SJuan Castillo 	}
5586f971622SJuan Castillo 
5596f971622SJuan Castillo 	/* *********************************************************************
5606f971622SJuan Castillo 	 * BL30 certificate (SCP Firmware Content certificate):
5616f971622SJuan Castillo 	 *     - Signed with Trusted World Key
5626f971622SJuan Castillo 	 *     - Extensions:
5636f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
5646f971622SJuan Castillo 	 *         - SCPFirmwareHash
5656f971622SJuan Castillo 	 **********************************************************************/
5666f971622SJuan Castillo 	if (bl30_present) {
5676f971622SJuan Castillo 		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
5686f971622SJuan Castillo 		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
5696f971622SJuan Castillo 				tf_nvcounter));
5706f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, nvctr_ext);
5716f971622SJuan Castillo 
5726f971622SJuan Castillo 		if (!sha_file(certs[BL30_CERT].bin, md)) {
5736f971622SJuan Castillo 			ERROR("Cannot calculate the hash of %s\n",
5746f971622SJuan Castillo 					certs[BL30_CERT].bin);
5756f971622SJuan Castillo 			exit(1);
5766f971622SJuan Castillo 		}
5776f971622SJuan Castillo 		CHECK_OID(hash_nid, BL30_HASH_OID);
578c3da66b1SJuan Castillo 		CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info,
579c3da66b1SJuan Castillo 				md, SHA256_DIGEST_LENGTH));
5806f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, hash_ext);
5816f971622SJuan Castillo 
5826f971622SJuan Castillo 		if (!cert_new(&certs[BL30_CERT], VAL_DAYS, 0, sk)) {
5836f971622SJuan Castillo 			ERROR("Cannot create %s\n", certs[BL30_CERT].cn);
5846f971622SJuan Castillo 			exit(1);
5856f971622SJuan Castillo 		}
5866f971622SJuan Castillo 
5876f971622SJuan Castillo 		sk_X509_EXTENSION_free(sk);
5886f971622SJuan Castillo 	}
5896f971622SJuan Castillo 
5906f971622SJuan Castillo 	/* *********************************************************************
5916f971622SJuan Castillo 	 * BL31 Key certificate (Trusted SoC Firmware Key certificate):
5926f971622SJuan Castillo 	 *     - Self-signed with Trusted World key
5936f971622SJuan Castillo 	 *     - Extensions:
5946f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
5956f971622SJuan Castillo 	 *         - SoCFirmwareContentCertPK
5966f971622SJuan Castillo 	 **********************************************************************/
5976f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
5986f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
5996f971622SJuan Castillo 			tf_nvcounter));
6006f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
6016f971622SJuan Castillo 	CHECK_OID(pk_nid, BL31_CONTENT_CERT_PK_OID);
6026f971622SJuan Castillo 	CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
6036f971622SJuan Castillo 			keys[BL31_KEY].key));
6046f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, trusted_key_ext);
6056f971622SJuan Castillo 	if (!cert_new(&certs[BL31_KEY_CERT], VAL_DAYS, 0, sk)) {
6066f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[BL31_KEY_CERT].cn);
6076f971622SJuan Castillo 		exit(1);
6086f971622SJuan Castillo 	}
6096f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
6106f971622SJuan Castillo 
6116f971622SJuan Castillo 	/* *********************************************************************
6126f971622SJuan Castillo 	 * BL31 certificate (SOC Firmware Content certificate):
6136f971622SJuan Castillo 	 *     - Signed with Trusted World Key
6146f971622SJuan Castillo 	 *     - Extensions:
6156f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
6166f971622SJuan Castillo 	 *         - BL31 hash
6176f971622SJuan Castillo 	 **********************************************************************/
6186f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
6196f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
6206f971622SJuan Castillo 			tf_nvcounter));
6216f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
6226f971622SJuan Castillo 
6236f971622SJuan Castillo 	if (!sha_file(certs[BL31_CERT].bin, md)) {
6246f971622SJuan Castillo 		ERROR("Cannot calculate the hash of %s\n", certs[BL31_CERT].bin);
6256f971622SJuan Castillo 		exit(1);
6266f971622SJuan Castillo 	}
6276f971622SJuan Castillo 	CHECK_OID(hash_nid, BL31_HASH_OID);
628c3da66b1SJuan Castillo 	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md,
6296f971622SJuan Castillo 			SHA256_DIGEST_LENGTH));
6306f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, hash_ext);
6316f971622SJuan Castillo 
6326f971622SJuan Castillo 	if (!cert_new(&certs[BL31_CERT], VAL_DAYS, 0, sk)) {
6336f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[BL31_CERT].cn);
6346f971622SJuan Castillo 		exit(1);
6356f971622SJuan Castillo 	}
6366f971622SJuan Castillo 
6376f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
6386f971622SJuan Castillo 
6396f971622SJuan Castillo 	/* *********************************************************************
6406f971622SJuan Castillo 	 * BL32 Key certificate (Trusted OS Firmware Key certificate):
6416f971622SJuan Castillo 	 *     - Self-signed with Trusted World key
6426f971622SJuan Castillo 	 *     - Extensions:
6436f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
6446f971622SJuan Castillo 	 *         - TrustedOSFirmwareContentCertPK
6456f971622SJuan Castillo 	 **********************************************************************/
6466f971622SJuan Castillo 	if (bl32_present) {
6476f971622SJuan Castillo 		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
6486f971622SJuan Castillo 		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
6496f971622SJuan Castillo 				tf_nvcounter));
6506f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, nvctr_ext);
6516f971622SJuan Castillo 		CHECK_OID(pk_nid, BL32_CONTENT_CERT_PK_OID);
6526f971622SJuan Castillo 		CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
6536f971622SJuan Castillo 				keys[BL32_KEY].key));
6546f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, trusted_key_ext);
6556f971622SJuan Castillo 		if (!cert_new(&certs[BL32_KEY_CERT], VAL_DAYS, 0, sk)) {
6566f971622SJuan Castillo 			ERROR("Cannot create %s\n", certs[BL32_KEY_CERT].cn);
6576f971622SJuan Castillo 			exit(1);
6586f971622SJuan Castillo 		}
6596f971622SJuan Castillo 		sk_X509_EXTENSION_free(sk);
6606f971622SJuan Castillo 	}
6616f971622SJuan Castillo 
6626f971622SJuan Castillo 	/* *********************************************************************
6636f971622SJuan Castillo 	 * BL32 certificate (TrustedOS Firmware Content certificate):
6646f971622SJuan Castillo 	 *     - Signed with Trusted World Key
6656f971622SJuan Castillo 	 *     - Extensions:
6666f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
6676f971622SJuan Castillo 	 *         - BL32 hash
6686f971622SJuan Castillo 	 **********************************************************************/
6696f971622SJuan Castillo 	if (bl32_present) {
6706f971622SJuan Castillo 		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
6716f971622SJuan Castillo 		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
6726f971622SJuan Castillo 				tf_nvcounter));
6736f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, nvctr_ext);
6746f971622SJuan Castillo 
6756f971622SJuan Castillo 		if (!sha_file(certs[BL32_CERT].bin, md)) {
6766f971622SJuan Castillo 			ERROR("Cannot calculate the hash of %s\n",
6776f971622SJuan Castillo 					certs[BL32_CERT].bin);
6786f971622SJuan Castillo 			exit(1);
6796f971622SJuan Castillo 		}
6806f971622SJuan Castillo 		CHECK_OID(hash_nid, BL32_HASH_OID);
681c3da66b1SJuan Castillo 		CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info,
682c3da66b1SJuan Castillo 				md, SHA256_DIGEST_LENGTH));
6836f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, hash_ext);
6846f971622SJuan Castillo 
6856f971622SJuan Castillo 		if (!cert_new(&certs[BL32_CERT], VAL_DAYS, 0, sk)) {
6866f971622SJuan Castillo 			ERROR("Cannot create %s\n", certs[BL32_CERT].cn);
6876f971622SJuan Castillo 			exit(1);
6886f971622SJuan Castillo 		}
6896f971622SJuan Castillo 
6906f971622SJuan Castillo 		sk_X509_EXTENSION_free(sk);
6916f971622SJuan Castillo 	}
6926f971622SJuan Castillo 
6936f971622SJuan Castillo 	/* *********************************************************************
6946f971622SJuan Castillo 	 * BL33 Key certificate (Non Trusted Firmware Key certificate):
6956f971622SJuan Castillo 	 *     - Self-signed with Non Trusted World key
6966f971622SJuan Castillo 	 *     - Extensions:
6976f971622SJuan Castillo 	 *         - NonTrustedFirmwareNVCounter (TODO)
6986f971622SJuan Castillo 	 *         - NonTrustedFirmwareContentCertPK
6996f971622SJuan Castillo 	 **********************************************************************/
7006f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
7016f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
7026f971622SJuan Castillo 			non_tf_nvcounter));
7036f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
7046f971622SJuan Castillo 	CHECK_OID(pk_nid, BL33_CONTENT_CERT_PK_OID);
7056f971622SJuan Castillo 	CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
7066f971622SJuan Castillo 			keys[BL33_KEY].key));
7076f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
7086f971622SJuan Castillo 	if (!cert_new(&certs[BL33_KEY_CERT], VAL_DAYS, 0, sk)) {
7096f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[BL33_KEY_CERT].cn);
7106f971622SJuan Castillo 		exit(1);
7116f971622SJuan Castillo 	}
7126f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
7136f971622SJuan Castillo 
7146f971622SJuan Castillo 	/* *********************************************************************
7156f971622SJuan Castillo 	 * BL33 certificate (Non-Trusted World Content certificate):
7166f971622SJuan Castillo 	 *     - Signed with Non-Trusted World Key
7176f971622SJuan Castillo 	 *     - Extensions:
7186f971622SJuan Castillo 	 *         - NonTrustedFirmwareNVCounter (TODO)
7196f971622SJuan Castillo 	 *         - BL33 hash
7206f971622SJuan Castillo 	 **********************************************************************/
7216f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
7226f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
7236f971622SJuan Castillo 			non_tf_nvcounter));
7246f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
7256f971622SJuan Castillo 
7266f971622SJuan Castillo 	if (!sha_file(certs[BL33_CERT].bin, md)) {
7276f971622SJuan Castillo 		ERROR("Cannot calculate the hash of %s\n", certs[BL33_CERT].bin);
7286f971622SJuan Castillo 		exit(1);
7296f971622SJuan Castillo 	}
7306f971622SJuan Castillo 	CHECK_OID(hash_nid, BL33_HASH_OID);
731c3da66b1SJuan Castillo 	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md_info, md,
7326f971622SJuan Castillo 			SHA256_DIGEST_LENGTH));
7336f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, hash_ext);
7346f971622SJuan Castillo 
7356f971622SJuan Castillo 	if (!cert_new(&certs[BL33_CERT], VAL_DAYS, 0, sk)) {
7366f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[BL33_CERT].cn);
7376f971622SJuan Castillo 		exit(1);
7386f971622SJuan Castillo 	}
7396f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
7406f971622SJuan Castillo 
7416f971622SJuan Castillo 	/* Print the certificates */
7426f971622SJuan Castillo 	if (print_cert) {
7436f971622SJuan Castillo 		for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
7446f971622SJuan Castillo 			if (!certs[i].x) {
7456f971622SJuan Castillo 				continue;
7466f971622SJuan Castillo 			}
7476f971622SJuan Castillo 			printf("\n\n=====================================\n\n");
7486f971622SJuan Castillo 			X509_print_fp(stdout, certs[i].x);
7496f971622SJuan Castillo 		}
7506f971622SJuan Castillo 	}
7516f971622SJuan Castillo 
7526f971622SJuan Castillo 	/* Save created certificates to files */
7536f971622SJuan Castillo 	for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
7546f971622SJuan Castillo 		if (certs[i].x && certs[i].fn) {
7556f971622SJuan Castillo 			file = fopen(certs[i].fn, "w");
7566f971622SJuan Castillo 			if (file != NULL) {
7576f971622SJuan Castillo 				i2d_X509_fp(file, certs[i].x);
7586f971622SJuan Castillo 				fclose(file);
7596f971622SJuan Castillo 			} else {
7606f971622SJuan Castillo 				ERROR("Cannot create file %s\n", certs[i].fn);
7616f971622SJuan Castillo 			}
7626f971622SJuan Castillo 		}
7636f971622SJuan Castillo 	}
7646f971622SJuan Castillo 
7656f971622SJuan Castillo 	/* Save keys */
7666f971622SJuan Castillo 	if (save_keys) {
7676f971622SJuan Castillo 		for (i = 0 ; i < NUM_KEYS ; i++) {
7686f971622SJuan Castillo 			if (!key_store(&keys[i])) {
7696f971622SJuan Castillo 				ERROR("Cannot save %s\n", keys[i].desc);
7706f971622SJuan Castillo 			}
7716f971622SJuan Castillo 		}
7726f971622SJuan Castillo 	}
7736f971622SJuan Castillo 
7746f971622SJuan Castillo 	X509_EXTENSION_free(hash_ext);
7756f971622SJuan Castillo 	X509_EXTENSION_free(nvctr_ext);
7766f971622SJuan Castillo 	X509_EXTENSION_free(trusted_key_ext);
7776f971622SJuan Castillo 	X509_EXTENSION_free(non_trusted_key_ext);
7786f971622SJuan Castillo 
7796f971622SJuan Castillo #ifndef OPENSSL_NO_ENGINE
7806f971622SJuan Castillo 	ENGINE_cleanup();
7816f971622SJuan Castillo #endif
7826f971622SJuan Castillo 	CRYPTO_cleanup_all_ex_data();
7836f971622SJuan Castillo 
7846f971622SJuan Castillo 	return 0;
7856f971622SJuan Castillo }
786