xref: /rk3399_ARM-atf/tools/cert_create/src/main.c (revision 6f97162237603eb6e5c497e5ba903512bdd428a9)
1*6f971622SJuan Castillo /*
2*6f971622SJuan Castillo  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3*6f971622SJuan Castillo  *
4*6f971622SJuan Castillo  * Redistribution and use in source and binary forms, with or without
5*6f971622SJuan Castillo  * modification, are permitted provided that the following conditions are met:
6*6f971622SJuan Castillo  *
7*6f971622SJuan Castillo  * Redistributions of source code must retain the above copyright notice, this
8*6f971622SJuan Castillo  * list of conditions and the following disclaimer.
9*6f971622SJuan Castillo  *
10*6f971622SJuan Castillo  * Redistributions in binary form must reproduce the above copyright notice,
11*6f971622SJuan Castillo  * this list of conditions and the following disclaimer in the documentation
12*6f971622SJuan Castillo  * and/or other materials provided with the distribution.
13*6f971622SJuan Castillo  *
14*6f971622SJuan Castillo  * Neither the name of ARM nor the names of its contributors may be used
15*6f971622SJuan Castillo  * to endorse or promote products derived from this software without specific
16*6f971622SJuan Castillo  * prior written permission.
17*6f971622SJuan Castillo  *
18*6f971622SJuan Castillo  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19*6f971622SJuan Castillo  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*6f971622SJuan Castillo  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*6f971622SJuan Castillo  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22*6f971622SJuan Castillo  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23*6f971622SJuan Castillo  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24*6f971622SJuan Castillo  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25*6f971622SJuan Castillo  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26*6f971622SJuan Castillo  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27*6f971622SJuan Castillo  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28*6f971622SJuan Castillo  * POSSIBILITY OF SUCH DAMAGE.
29*6f971622SJuan Castillo  */
30*6f971622SJuan Castillo 
31*6f971622SJuan Castillo #include <getopt.h>
32*6f971622SJuan Castillo #include <stdio.h>
33*6f971622SJuan Castillo #include <stdlib.h>
34*6f971622SJuan Castillo #include <string.h>
35*6f971622SJuan Castillo 
36*6f971622SJuan Castillo #include <openssl/conf.h>
37*6f971622SJuan Castillo #include <openssl/engine.h>
38*6f971622SJuan Castillo #include <openssl/err.h>
39*6f971622SJuan Castillo #include <openssl/pem.h>
40*6f971622SJuan Castillo #include <openssl/sha.h>
41*6f971622SJuan Castillo #include <openssl/x509v3.h>
42*6f971622SJuan Castillo 
43*6f971622SJuan Castillo #include "cert.h"
44*6f971622SJuan Castillo #include "debug.h"
45*6f971622SJuan Castillo #include "ext.h"
46*6f971622SJuan Castillo #include "key.h"
47*6f971622SJuan Castillo #include "platform_oid.h"
48*6f971622SJuan Castillo #include "sha.h"
49*6f971622SJuan Castillo #include "tbb_ext.h"
50*6f971622SJuan Castillo #include "tbb_cert.h"
51*6f971622SJuan Castillo #include "tbb_key.h"
52*6f971622SJuan Castillo 
53*6f971622SJuan Castillo /*
54*6f971622SJuan Castillo  * Helper macros to simplify the code. This macro assigns the return value of
55*6f971622SJuan Castillo  * the 'fn' function to 'v' and exits if the value is NULL.
56*6f971622SJuan Castillo  */
57*6f971622SJuan Castillo #define CHECK_NULL(v, fn) \
58*6f971622SJuan Castillo 	do { \
59*6f971622SJuan Castillo 		v = fn; \
60*6f971622SJuan Castillo 		if (v == NULL) { \
61*6f971622SJuan Castillo 			ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \
62*6f971622SJuan Castillo 			exit(1); \
63*6f971622SJuan Castillo 		} \
64*6f971622SJuan Castillo 	} while (0)
65*6f971622SJuan Castillo 
66*6f971622SJuan Castillo /*
67*6f971622SJuan Castillo  * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the
68*6f971622SJuan Castillo  * NID is undefined.
69*6f971622SJuan Castillo  */
70*6f971622SJuan Castillo #define CHECK_OID(v, oid) \
71*6f971622SJuan Castillo 	do { \
72*6f971622SJuan Castillo 		v = OBJ_txt2nid(oid); \
73*6f971622SJuan Castillo 		if (v == NID_undef) { \
74*6f971622SJuan Castillo 			ERROR("Cannot find TBB extension %s\n", oid); \
75*6f971622SJuan Castillo 			exit(1); \
76*6f971622SJuan Castillo 		} \
77*6f971622SJuan Castillo 	} while (0)
78*6f971622SJuan Castillo 
79*6f971622SJuan Castillo #define MAX_FILENAME_LEN		1024
80*6f971622SJuan Castillo #define VAL_DAYS			7300
81*6f971622SJuan Castillo #define ID_TO_BIT_MASK(id)		(1 << id)
82*6f971622SJuan Castillo #define NVCOUNTER_VALUE			0
83*6f971622SJuan Castillo 
84*6f971622SJuan Castillo /* Files */
85*6f971622SJuan Castillo enum {
86*6f971622SJuan Castillo 	/* Image file names (inputs) */
87*6f971622SJuan Castillo 	BL2_ID = 0,
88*6f971622SJuan Castillo 	BL30_ID,
89*6f971622SJuan Castillo 	BL31_ID,
90*6f971622SJuan Castillo 	BL32_ID,
91*6f971622SJuan Castillo 	BL33_ID,
92*6f971622SJuan Castillo 	/* Certificate file names (outputs) */
93*6f971622SJuan Castillo 	BL2_CERT_ID,
94*6f971622SJuan Castillo 	TRUSTED_KEY_CERT_ID,
95*6f971622SJuan Castillo 	BL30_KEY_CERT_ID,
96*6f971622SJuan Castillo 	BL30_CERT_ID,
97*6f971622SJuan Castillo 	BL31_KEY_CERT_ID,
98*6f971622SJuan Castillo 	BL31_CERT_ID,
99*6f971622SJuan Castillo 	BL32_KEY_CERT_ID,
100*6f971622SJuan Castillo 	BL32_CERT_ID,
101*6f971622SJuan Castillo 	BL33_KEY_CERT_ID,
102*6f971622SJuan Castillo 	BL33_CERT_ID,
103*6f971622SJuan Castillo 	/* Key file names (input/output) */
104*6f971622SJuan Castillo 	ROT_KEY_ID,
105*6f971622SJuan Castillo 	TRUSTED_WORLD_KEY_ID,
106*6f971622SJuan Castillo 	NON_TRUSTED_WORLD_KEY_ID,
107*6f971622SJuan Castillo 	BL30_KEY_ID,
108*6f971622SJuan Castillo 	BL31_KEY_ID,
109*6f971622SJuan Castillo 	BL32_KEY_ID,
110*6f971622SJuan Castillo 	BL33_KEY_ID,
111*6f971622SJuan Castillo 	NUM_OPTS
112*6f971622SJuan Castillo };
113*6f971622SJuan Castillo 
114*6f971622SJuan Castillo /* Global options */
115*6f971622SJuan Castillo static int new_keys;
116*6f971622SJuan Castillo static int save_keys;
117*6f971622SJuan Castillo static int print_cert;
118*6f971622SJuan Castillo static int bl30_present;
119*6f971622SJuan Castillo static int bl32_present;
120*6f971622SJuan Castillo 
121*6f971622SJuan Castillo /* We are not checking nvcounters in TF. Include them in the certificates but
122*6f971622SJuan Castillo  * the value will be set to 0 */
123*6f971622SJuan Castillo static int tf_nvcounter;
124*6f971622SJuan Castillo static int non_tf_nvcounter;
125*6f971622SJuan Castillo 
126*6f971622SJuan Castillo /* Info messages created in the Makefile */
127*6f971622SJuan Castillo extern const char build_msg[];
128*6f971622SJuan Castillo extern const char platform_msg[];
129*6f971622SJuan Castillo 
130*6f971622SJuan Castillo 
131*6f971622SJuan Castillo static char *strdup(const char *str)
132*6f971622SJuan Castillo {
133*6f971622SJuan Castillo 	int n = strlen(str) + 1;
134*6f971622SJuan Castillo 	char *dup = malloc(n);
135*6f971622SJuan Castillo 	if (dup) {
136*6f971622SJuan Castillo 		strcpy(dup, str);
137*6f971622SJuan Castillo 	}
138*6f971622SJuan Castillo 	return dup;
139*6f971622SJuan Castillo }
140*6f971622SJuan Castillo 
141*6f971622SJuan Castillo /* Command line options */
142*6f971622SJuan Castillo static const struct option long_opt[] = {
143*6f971622SJuan Castillo 	/* Binary images */
144*6f971622SJuan Castillo 	{"bl2", required_argument, 0, BL2_ID},
145*6f971622SJuan Castillo 	{"bl30", required_argument, 0, BL30_ID},
146*6f971622SJuan Castillo 	{"bl31", required_argument, 0, BL31_ID},
147*6f971622SJuan Castillo 	{"bl32", required_argument, 0, BL32_ID},
148*6f971622SJuan Castillo 	{"bl33", required_argument, 0, BL33_ID},
149*6f971622SJuan Castillo 	/* Certificate files */
150*6f971622SJuan Castillo 	{"bl2-cert", required_argument, 0, BL2_CERT_ID},
151*6f971622SJuan Castillo 	{"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID},
152*6f971622SJuan Castillo 	{"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID},
153*6f971622SJuan Castillo 	{"bl30-cert", required_argument, 0, BL30_CERT_ID},
154*6f971622SJuan Castillo 	{"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID},
155*6f971622SJuan Castillo 	{"bl31-cert", required_argument, 0, BL31_CERT_ID},
156*6f971622SJuan Castillo 	{"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID},
157*6f971622SJuan Castillo 	{"bl32-cert", required_argument, 0, BL32_CERT_ID},
158*6f971622SJuan Castillo 	{"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID},
159*6f971622SJuan Castillo 	{"bl33-cert", required_argument, 0, BL33_CERT_ID},
160*6f971622SJuan Castillo 	/* Private key files */
161*6f971622SJuan Castillo 	{"rot-key", required_argument, 0, ROT_KEY_ID},
162*6f971622SJuan Castillo 	{"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID},
163*6f971622SJuan Castillo 	{"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID},
164*6f971622SJuan Castillo 	{"bl30-key", required_argument, 0, BL30_KEY_ID},
165*6f971622SJuan Castillo 	{"bl31-key", required_argument, 0, BL31_KEY_ID},
166*6f971622SJuan Castillo 	{"bl32-key", required_argument, 0, BL32_KEY_ID},
167*6f971622SJuan Castillo 	{"bl33-key", required_argument, 0, BL33_KEY_ID},
168*6f971622SJuan Castillo 	/* Common options */
169*6f971622SJuan Castillo 	{"help", no_argument, 0, 'h'},
170*6f971622SJuan Castillo 	{"save-keys", no_argument, 0, 'k'},
171*6f971622SJuan Castillo 	{"new-chain", no_argument, 0, 'n'},
172*6f971622SJuan Castillo 	{"print-cert", no_argument, 0, 'p'},
173*6f971622SJuan Castillo 	{0, 0, 0, 0}
174*6f971622SJuan Castillo };
175*6f971622SJuan Castillo 
176*6f971622SJuan Castillo static void print_help(const char *cmd)
177*6f971622SJuan Castillo {
178*6f971622SJuan Castillo 	int i = 0;
179*6f971622SJuan Castillo 	printf("\n\n");
180*6f971622SJuan Castillo 	printf("The certificate generation tool loads the binary images and\n"
181*6f971622SJuan Castillo 	       "optionally the RSA keys, and outputs the key and content\n"
182*6f971622SJuan Castillo 	       "certificates properly signed to implement the chain of trust.\n"
183*6f971622SJuan Castillo 	       "If keys are provided, they must be in PEM format.\n"
184*6f971622SJuan Castillo 	       "Certificates are generated in DER format.\n");
185*6f971622SJuan Castillo 	printf("\n");
186*6f971622SJuan Castillo 	printf("Usage:\n\n");
187*6f971622SJuan Castillo 	printf("    %s [-hknp] \\\n", cmd);
188*6f971622SJuan Castillo 	for (i = 0; i < NUM_OPTS; i++) {
189*6f971622SJuan Castillo 		printf("        --%s <file>  \\\n", long_opt[i].name);
190*6f971622SJuan Castillo 	}
191*6f971622SJuan Castillo 	printf("\n");
192*6f971622SJuan Castillo 	printf("-h    Print help and exit\n");
193*6f971622SJuan Castillo 	printf("-k    Save key pairs into files. Filenames must be provided\n");
194*6f971622SJuan Castillo 	printf("-n    Generate new key pairs if no key files are provided\n");
195*6f971622SJuan Castillo 	printf("-p    Print the certificates in the standard output\n");
196*6f971622SJuan Castillo 	printf("\n");
197*6f971622SJuan Castillo 
198*6f971622SJuan Castillo 	exit(0);
199*6f971622SJuan Castillo }
200*6f971622SJuan Castillo 
201*6f971622SJuan Castillo static void check_cmd_params(void)
202*6f971622SJuan Castillo {
203*6f971622SJuan Castillo 	/* BL2, BL31 and BL33 are mandatory */
204*6f971622SJuan Castillo 	if (certs[BL2_CERT].bin == NULL) {
205*6f971622SJuan Castillo 		ERROR("BL2 image not specified\n");
206*6f971622SJuan Castillo 		exit(1);
207*6f971622SJuan Castillo 	}
208*6f971622SJuan Castillo 
209*6f971622SJuan Castillo 	if (certs[BL31_CERT].bin == NULL) {
210*6f971622SJuan Castillo 		ERROR("BL31 image not specified\n");
211*6f971622SJuan Castillo 		exit(1);
212*6f971622SJuan Castillo 	}
213*6f971622SJuan Castillo 
214*6f971622SJuan Castillo 	if (certs[BL33_CERT].bin == NULL) {
215*6f971622SJuan Castillo 		ERROR("BL33 image not specified\n");
216*6f971622SJuan Castillo 		exit(1);
217*6f971622SJuan Castillo 	}
218*6f971622SJuan Castillo 
219*6f971622SJuan Castillo 	/* BL30 and BL32 are optional */
220*6f971622SJuan Castillo 	if (certs[BL30_CERT].bin != NULL) {
221*6f971622SJuan Castillo 		bl30_present = 1;
222*6f971622SJuan Castillo 	}
223*6f971622SJuan Castillo 
224*6f971622SJuan Castillo 	if (certs[BL32_CERT].bin != NULL) {
225*6f971622SJuan Castillo 		bl32_present = 1;
226*6f971622SJuan Castillo 	}
227*6f971622SJuan Castillo 
228*6f971622SJuan Castillo 	/* TODO: Certificate filenames */
229*6f971622SJuan Castillo 
230*6f971622SJuan Castillo 	/* Filenames to store keys must be specified */
231*6f971622SJuan Castillo 	if (save_keys || !new_keys) {
232*6f971622SJuan Castillo 		if (keys[ROT_KEY].fn == NULL) {
233*6f971622SJuan Castillo 			ERROR("ROT key not specified\n");
234*6f971622SJuan Castillo 			exit(1);
235*6f971622SJuan Castillo 		}
236*6f971622SJuan Castillo 
237*6f971622SJuan Castillo 		if (keys[TRUSTED_WORLD_KEY].fn == NULL) {
238*6f971622SJuan Castillo 			ERROR("Trusted World key not specified\n");
239*6f971622SJuan Castillo 			exit(1);
240*6f971622SJuan Castillo 		}
241*6f971622SJuan Castillo 
242*6f971622SJuan Castillo 		if (keys[NON_TRUSTED_WORLD_KEY].fn == NULL) {
243*6f971622SJuan Castillo 			ERROR("Non-trusted World key not specified\n");
244*6f971622SJuan Castillo 			exit(1);
245*6f971622SJuan Castillo 		}
246*6f971622SJuan Castillo 
247*6f971622SJuan Castillo 		if (keys[BL31_KEY].fn == NULL) {
248*6f971622SJuan Castillo 			ERROR("BL31 key not specified\n");
249*6f971622SJuan Castillo 			exit(1);
250*6f971622SJuan Castillo 		}
251*6f971622SJuan Castillo 
252*6f971622SJuan Castillo 		if (keys[BL33_KEY].fn == NULL) {
253*6f971622SJuan Castillo 			ERROR("BL33 key not specified\n");
254*6f971622SJuan Castillo 			exit(1);
255*6f971622SJuan Castillo 		}
256*6f971622SJuan Castillo 
257*6f971622SJuan Castillo 		if (bl30_present && (keys[BL30_KEY].fn == NULL)) {
258*6f971622SJuan Castillo 			ERROR("BL30 key not specified\n");
259*6f971622SJuan Castillo 			exit(1);
260*6f971622SJuan Castillo 		}
261*6f971622SJuan Castillo 
262*6f971622SJuan Castillo 		if (bl32_present && (keys[BL32_KEY].fn == NULL)) {
263*6f971622SJuan Castillo 			ERROR("BL32 key not specified\n");
264*6f971622SJuan Castillo 			exit(1);
265*6f971622SJuan Castillo 		}
266*6f971622SJuan Castillo 	}
267*6f971622SJuan Castillo }
268*6f971622SJuan Castillo 
269*6f971622SJuan Castillo int main(int argc, char *argv[])
270*6f971622SJuan Castillo {
271*6f971622SJuan Castillo 	STACK_OF(X509_EXTENSION) * sk = NULL;
272*6f971622SJuan Castillo 	X509_EXTENSION *hash_ext = NULL;
273*6f971622SJuan Castillo 	X509_EXTENSION *nvctr_ext = NULL;
274*6f971622SJuan Castillo 	X509_EXTENSION *trusted_key_ext = NULL;
275*6f971622SJuan Castillo 	X509_EXTENSION *non_trusted_key_ext = NULL;
276*6f971622SJuan Castillo 	FILE *file = NULL;
277*6f971622SJuan Castillo 	int i, tz_nvctr_nid, ntz_nvctr_nid, hash_nid, pk_nid;
278*6f971622SJuan Castillo 	int c, opt_idx = 0;
279*6f971622SJuan Castillo 	unsigned char md[SHA256_DIGEST_LENGTH];
280*6f971622SJuan Castillo 
281*6f971622SJuan Castillo 	NOTICE("CoT Generation Tool: %s\n", build_msg);
282*6f971622SJuan Castillo 	NOTICE("Target platform: %s\n", platform_msg);
283*6f971622SJuan Castillo 
284*6f971622SJuan Castillo 	while (1) {
285*6f971622SJuan Castillo 		/* getopt_long stores the option index here. */
286*6f971622SJuan Castillo 		c = getopt_long(argc, argv, "hknp", long_opt, &opt_idx);
287*6f971622SJuan Castillo 
288*6f971622SJuan Castillo 		/* Detect the end of the options. */
289*6f971622SJuan Castillo 		if (c == -1) {
290*6f971622SJuan Castillo 			break;
291*6f971622SJuan Castillo 		}
292*6f971622SJuan Castillo 
293*6f971622SJuan Castillo 		switch (c) {
294*6f971622SJuan Castillo 		case 'h':
295*6f971622SJuan Castillo 			print_help(argv[0]);
296*6f971622SJuan Castillo 			break;
297*6f971622SJuan Castillo 		case 'k':
298*6f971622SJuan Castillo 			save_keys = 1;
299*6f971622SJuan Castillo 			break;
300*6f971622SJuan Castillo 		case 'n':
301*6f971622SJuan Castillo 			new_keys = 1;
302*6f971622SJuan Castillo 			break;
303*6f971622SJuan Castillo 		case 'p':
304*6f971622SJuan Castillo 			print_cert = 1;
305*6f971622SJuan Castillo 			break;
306*6f971622SJuan Castillo 		case BL2_ID:
307*6f971622SJuan Castillo 			certs[BL2_CERT].bin = strdup(optarg);
308*6f971622SJuan Castillo 			break;
309*6f971622SJuan Castillo 		case BL30_ID:
310*6f971622SJuan Castillo 			certs[BL30_CERT].bin = strdup(optarg);
311*6f971622SJuan Castillo 			break;
312*6f971622SJuan Castillo 		case BL31_ID:
313*6f971622SJuan Castillo 			certs[BL31_CERT].bin = strdup(optarg);
314*6f971622SJuan Castillo 			break;
315*6f971622SJuan Castillo 		case BL32_ID:
316*6f971622SJuan Castillo 			certs[BL32_CERT].bin = strdup(optarg);
317*6f971622SJuan Castillo 			break;
318*6f971622SJuan Castillo 		case BL33_ID:
319*6f971622SJuan Castillo 			certs[BL33_CERT].bin = strdup(optarg);
320*6f971622SJuan Castillo 			break;
321*6f971622SJuan Castillo 		case BL2_CERT_ID:
322*6f971622SJuan Castillo 			certs[BL2_CERT].fn = strdup(optarg);
323*6f971622SJuan Castillo 			break;
324*6f971622SJuan Castillo 		case TRUSTED_KEY_CERT_ID:
325*6f971622SJuan Castillo 			certs[TRUSTED_KEY_CERT].fn = strdup(optarg);
326*6f971622SJuan Castillo 			break;
327*6f971622SJuan Castillo 		case BL30_KEY_CERT_ID:
328*6f971622SJuan Castillo 			certs[BL30_KEY_CERT].fn = strdup(optarg);
329*6f971622SJuan Castillo 			break;
330*6f971622SJuan Castillo 		case BL30_CERT_ID:
331*6f971622SJuan Castillo 			certs[BL30_CERT].fn = strdup(optarg);
332*6f971622SJuan Castillo 			break;
333*6f971622SJuan Castillo 		case BL31_KEY_CERT_ID:
334*6f971622SJuan Castillo 			certs[BL31_KEY_CERT].fn = strdup(optarg);
335*6f971622SJuan Castillo 			break;
336*6f971622SJuan Castillo 		case BL31_CERT_ID:
337*6f971622SJuan Castillo 			certs[BL31_CERT].fn = strdup(optarg);
338*6f971622SJuan Castillo 			break;
339*6f971622SJuan Castillo 		case BL32_KEY_CERT_ID:
340*6f971622SJuan Castillo 			certs[BL32_KEY_CERT].fn = strdup(optarg);
341*6f971622SJuan Castillo 			break;
342*6f971622SJuan Castillo 		case BL32_CERT_ID:
343*6f971622SJuan Castillo 			certs[BL32_CERT].fn = strdup(optarg);
344*6f971622SJuan Castillo 			break;
345*6f971622SJuan Castillo 		case BL33_KEY_CERT_ID:
346*6f971622SJuan Castillo 			certs[BL33_KEY_CERT].fn = strdup(optarg);
347*6f971622SJuan Castillo 			break;
348*6f971622SJuan Castillo 		case BL33_CERT_ID:
349*6f971622SJuan Castillo 			certs[BL33_CERT].fn = strdup(optarg);
350*6f971622SJuan Castillo 			break;
351*6f971622SJuan Castillo 		case ROT_KEY_ID:
352*6f971622SJuan Castillo 			keys[ROT_KEY].fn = strdup(optarg);
353*6f971622SJuan Castillo 			break;
354*6f971622SJuan Castillo 		case TRUSTED_WORLD_KEY_ID:
355*6f971622SJuan Castillo 			keys[TRUSTED_WORLD_KEY].fn = strdup(optarg);
356*6f971622SJuan Castillo 			break;
357*6f971622SJuan Castillo 		case NON_TRUSTED_WORLD_KEY_ID:
358*6f971622SJuan Castillo 			keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg);
359*6f971622SJuan Castillo 			break;
360*6f971622SJuan Castillo 		case BL30_KEY_ID:
361*6f971622SJuan Castillo 			keys[BL30_KEY].fn = strdup(optarg);
362*6f971622SJuan Castillo 			break;
363*6f971622SJuan Castillo 		case BL31_KEY_ID:
364*6f971622SJuan Castillo 			keys[BL31_KEY].fn = strdup(optarg);
365*6f971622SJuan Castillo 			break;
366*6f971622SJuan Castillo 		case BL32_KEY_ID:
367*6f971622SJuan Castillo 			keys[BL32_KEY].fn = strdup(optarg);
368*6f971622SJuan Castillo 			break;
369*6f971622SJuan Castillo 		case BL33_KEY_ID:
370*6f971622SJuan Castillo 			keys[BL33_KEY].fn = strdup(optarg);
371*6f971622SJuan Castillo 			break;
372*6f971622SJuan Castillo 		case '?':
373*6f971622SJuan Castillo 		default:
374*6f971622SJuan Castillo 			printf("%s\n", optarg);
375*6f971622SJuan Castillo 			exit(1);
376*6f971622SJuan Castillo 		}
377*6f971622SJuan Castillo 	}
378*6f971622SJuan Castillo 
379*6f971622SJuan Castillo 	/* Set the value of the NVCounters */
380*6f971622SJuan Castillo 	tf_nvcounter = NVCOUNTER_VALUE;
381*6f971622SJuan Castillo 	non_tf_nvcounter = NVCOUNTER_VALUE;
382*6f971622SJuan Castillo 
383*6f971622SJuan Castillo 	/* Check command line arguments */
384*6f971622SJuan Castillo 	check_cmd_params();
385*6f971622SJuan Castillo 
386*6f971622SJuan Castillo 	/* Register the new types and OIDs for the extensions */
387*6f971622SJuan Castillo 	if (ext_init(tbb_ext) != 0) {
388*6f971622SJuan Castillo 		ERROR("Cannot initialize TBB extensions\n");
389*6f971622SJuan Castillo 		exit(1);
390*6f971622SJuan Castillo 	}
391*6f971622SJuan Castillo 
392*6f971622SJuan Castillo 	/* Get non-volatile counters NIDs */
393*6f971622SJuan Castillo 	CHECK_OID(tz_nvctr_nid, TZ_FW_NVCOUNTER_OID);
394*6f971622SJuan Castillo 	CHECK_OID(ntz_nvctr_nid, NTZ_FW_NVCOUNTER_OID);
395*6f971622SJuan Castillo 
396*6f971622SJuan Castillo 	/* Load private keys from files (or generate new ones) */
397*6f971622SJuan Castillo 	if (new_keys) {
398*6f971622SJuan Castillo 		for (i = 0 ; i < NUM_KEYS ; i++) {
399*6f971622SJuan Castillo 			if (!key_new(&keys[i])) {
400*6f971622SJuan Castillo 				ERROR("Error creating %s\n", keys[i].desc);
401*6f971622SJuan Castillo 				exit(1);
402*6f971622SJuan Castillo 			}
403*6f971622SJuan Castillo 		}
404*6f971622SJuan Castillo 	} else {
405*6f971622SJuan Castillo 		for (i = 0 ; i < NUM_KEYS ; i++) {
406*6f971622SJuan Castillo 			if (!key_load(&keys[i])) {
407*6f971622SJuan Castillo 				ERROR("Error loading %s\n", keys[i].desc);
408*6f971622SJuan Castillo 				exit(1);
409*6f971622SJuan Castillo 			}
410*6f971622SJuan Castillo 		}
411*6f971622SJuan Castillo 	}
412*6f971622SJuan Castillo 
413*6f971622SJuan Castillo 	/* *********************************************************************
414*6f971622SJuan Castillo 	 * BL2 certificate (Trusted Boot Firmware certificate):
415*6f971622SJuan Castillo 	 *     - Self-signed with OEM ROT private key
416*6f971622SJuan Castillo 	 *     - Extensions:
417*6f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
418*6f971622SJuan Castillo 	 *         - BL2 hash
419*6f971622SJuan Castillo 	 **********************************************************************/
420*6f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
421*6f971622SJuan Castillo 
422*6f971622SJuan Castillo 	/* Add the NVCounter as a critical extension */
423*6f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
424*6f971622SJuan Castillo 			tf_nvcounter));
425*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
426*6f971622SJuan Castillo 
427*6f971622SJuan Castillo 	/* Add hash of BL2 as an extension */
428*6f971622SJuan Castillo 	if (!sha_file(certs[BL2_CERT].bin, md)) {
429*6f971622SJuan Castillo 		ERROR("Cannot calculate the hash of %s\n", certs[BL2_CERT].bin);
430*6f971622SJuan Castillo 		exit(1);
431*6f971622SJuan Castillo 	}
432*6f971622SJuan Castillo 	CHECK_OID(hash_nid, BL2_HASH_OID);
433*6f971622SJuan Castillo 	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
434*6f971622SJuan Castillo 			SHA256_DIGEST_LENGTH));
435*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, hash_ext);
436*6f971622SJuan Castillo 
437*6f971622SJuan Castillo 	/* Create certificate. Signed with ROT key */
438*6f971622SJuan Castillo 	if (!cert_new(&certs[BL2_CERT], VAL_DAYS, 0, sk)) {
439*6f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[BL2_CERT].cn);
440*6f971622SJuan Castillo 		exit(1);
441*6f971622SJuan Castillo 	}
442*6f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
443*6f971622SJuan Castillo 
444*6f971622SJuan Castillo 	/* *********************************************************************
445*6f971622SJuan Castillo 	 * Trusted Key certificate:
446*6f971622SJuan Castillo 	 *     - Self-signed with OEM ROT private key
447*6f971622SJuan Castillo 	 *     - Extensions:
448*6f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
449*6f971622SJuan Castillo 	 *         - TrustedWorldPK
450*6f971622SJuan Castillo 	 *         - NonTrustedWorldPK
451*6f971622SJuan Castillo 	 **********************************************************************/
452*6f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
453*6f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
454*6f971622SJuan Castillo 			tf_nvcounter));
455*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
456*6f971622SJuan Castillo 	CHECK_OID(pk_nid, TZ_WORLD_PK_OID);
457*6f971622SJuan Castillo 	CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
458*6f971622SJuan Castillo 			keys[TRUSTED_WORLD_KEY].key));
459*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, trusted_key_ext);
460*6f971622SJuan Castillo 	CHECK_OID(pk_nid, NTZ_WORLD_PK_OID);
461*6f971622SJuan Castillo 	CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
462*6f971622SJuan Castillo 			keys[NON_TRUSTED_WORLD_KEY].key));
463*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
464*6f971622SJuan Castillo 	if (!cert_new(&certs[TRUSTED_KEY_CERT], VAL_DAYS, 0, sk)) {
465*6f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[TRUSTED_KEY_CERT].cn);
466*6f971622SJuan Castillo 		exit(1);
467*6f971622SJuan Castillo 	}
468*6f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
469*6f971622SJuan Castillo 
470*6f971622SJuan Castillo 	/* *********************************************************************
471*6f971622SJuan Castillo 	 * BL30 Key certificate (Trusted SCP Firmware Key certificate):
472*6f971622SJuan Castillo 	 *     - Self-signed with Trusted World key
473*6f971622SJuan Castillo 	 *     - Extensions:
474*6f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
475*6f971622SJuan Castillo 	 *         - SCPFirmwareContentCertPK
476*6f971622SJuan Castillo 	 **********************************************************************/
477*6f971622SJuan Castillo 	if (bl30_present) {
478*6f971622SJuan Castillo 		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
479*6f971622SJuan Castillo 		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
480*6f971622SJuan Castillo 				tf_nvcounter));
481*6f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, nvctr_ext);
482*6f971622SJuan Castillo 		CHECK_OID(pk_nid, BL30_CONTENT_CERT_PK_OID);
483*6f971622SJuan Castillo 		CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
484*6f971622SJuan Castillo 				keys[BL30_KEY].key));
485*6f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, trusted_key_ext);
486*6f971622SJuan Castillo 		if (!cert_new(&certs[BL30_KEY_CERT], VAL_DAYS, 0, sk)) {
487*6f971622SJuan Castillo 			ERROR("Cannot create %s\n", certs[BL30_KEY_CERT].cn);
488*6f971622SJuan Castillo 			exit(1);
489*6f971622SJuan Castillo 		}
490*6f971622SJuan Castillo 		sk_X509_EXTENSION_free(sk);
491*6f971622SJuan Castillo 	}
492*6f971622SJuan Castillo 
493*6f971622SJuan Castillo 	/* *********************************************************************
494*6f971622SJuan Castillo 	 * BL30 certificate (SCP Firmware Content certificate):
495*6f971622SJuan Castillo 	 *     - Signed with Trusted World Key
496*6f971622SJuan Castillo 	 *     - Extensions:
497*6f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
498*6f971622SJuan Castillo 	 *         - SCPFirmwareHash
499*6f971622SJuan Castillo 	 **********************************************************************/
500*6f971622SJuan Castillo 	if (bl30_present) {
501*6f971622SJuan Castillo 		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
502*6f971622SJuan Castillo 		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
503*6f971622SJuan Castillo 				tf_nvcounter));
504*6f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, nvctr_ext);
505*6f971622SJuan Castillo 
506*6f971622SJuan Castillo 		if (!sha_file(certs[BL30_CERT].bin, md)) {
507*6f971622SJuan Castillo 			ERROR("Cannot calculate the hash of %s\n",
508*6f971622SJuan Castillo 					certs[BL30_CERT].bin);
509*6f971622SJuan Castillo 			exit(1);
510*6f971622SJuan Castillo 		}
511*6f971622SJuan Castillo 		CHECK_OID(hash_nid, BL30_HASH_OID);
512*6f971622SJuan Castillo 		CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
513*6f971622SJuan Castillo 				SHA256_DIGEST_LENGTH));
514*6f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, hash_ext);
515*6f971622SJuan Castillo 
516*6f971622SJuan Castillo 		if (!cert_new(&certs[BL30_CERT], VAL_DAYS, 0, sk)) {
517*6f971622SJuan Castillo 			ERROR("Cannot create %s\n", certs[BL30_CERT].cn);
518*6f971622SJuan Castillo 			exit(1);
519*6f971622SJuan Castillo 		}
520*6f971622SJuan Castillo 
521*6f971622SJuan Castillo 		sk_X509_EXTENSION_free(sk);
522*6f971622SJuan Castillo 	}
523*6f971622SJuan Castillo 
524*6f971622SJuan Castillo 	/* *********************************************************************
525*6f971622SJuan Castillo 	 * BL31 Key certificate (Trusted SoC Firmware Key certificate):
526*6f971622SJuan Castillo 	 *     - Self-signed with Trusted World key
527*6f971622SJuan Castillo 	 *     - Extensions:
528*6f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
529*6f971622SJuan Castillo 	 *         - SoCFirmwareContentCertPK
530*6f971622SJuan Castillo 	 **********************************************************************/
531*6f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
532*6f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
533*6f971622SJuan Castillo 			tf_nvcounter));
534*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
535*6f971622SJuan Castillo 	CHECK_OID(pk_nid, BL31_CONTENT_CERT_PK_OID);
536*6f971622SJuan Castillo 	CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
537*6f971622SJuan Castillo 			keys[BL31_KEY].key));
538*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, trusted_key_ext);
539*6f971622SJuan Castillo 	if (!cert_new(&certs[BL31_KEY_CERT], VAL_DAYS, 0, sk)) {
540*6f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[BL31_KEY_CERT].cn);
541*6f971622SJuan Castillo 		exit(1);
542*6f971622SJuan Castillo 	}
543*6f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
544*6f971622SJuan Castillo 
545*6f971622SJuan Castillo 	/* *********************************************************************
546*6f971622SJuan Castillo 	 * BL31 certificate (SOC Firmware Content certificate):
547*6f971622SJuan Castillo 	 *     - Signed with Trusted World Key
548*6f971622SJuan Castillo 	 *     - Extensions:
549*6f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
550*6f971622SJuan Castillo 	 *         - BL31 hash
551*6f971622SJuan Castillo 	 **********************************************************************/
552*6f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
553*6f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
554*6f971622SJuan Castillo 			tf_nvcounter));
555*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
556*6f971622SJuan Castillo 
557*6f971622SJuan Castillo 	if (!sha_file(certs[BL31_CERT].bin, md)) {
558*6f971622SJuan Castillo 		ERROR("Cannot calculate the hash of %s\n", certs[BL31_CERT].bin);
559*6f971622SJuan Castillo 		exit(1);
560*6f971622SJuan Castillo 	}
561*6f971622SJuan Castillo 	CHECK_OID(hash_nid, BL31_HASH_OID);
562*6f971622SJuan Castillo 	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
563*6f971622SJuan Castillo 			SHA256_DIGEST_LENGTH));
564*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, hash_ext);
565*6f971622SJuan Castillo 
566*6f971622SJuan Castillo 	if (!cert_new(&certs[BL31_CERT], VAL_DAYS, 0, sk)) {
567*6f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[BL31_CERT].cn);
568*6f971622SJuan Castillo 		exit(1);
569*6f971622SJuan Castillo 	}
570*6f971622SJuan Castillo 
571*6f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
572*6f971622SJuan Castillo 
573*6f971622SJuan Castillo 	/* *********************************************************************
574*6f971622SJuan Castillo 	 * BL32 Key certificate (Trusted OS Firmware Key certificate):
575*6f971622SJuan Castillo 	 *     - Self-signed with Trusted World key
576*6f971622SJuan Castillo 	 *     - Extensions:
577*6f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
578*6f971622SJuan Castillo 	 *         - TrustedOSFirmwareContentCertPK
579*6f971622SJuan Castillo 	 **********************************************************************/
580*6f971622SJuan Castillo 	if (bl32_present) {
581*6f971622SJuan Castillo 		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
582*6f971622SJuan Castillo 		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
583*6f971622SJuan Castillo 				tf_nvcounter));
584*6f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, nvctr_ext);
585*6f971622SJuan Castillo 		CHECK_OID(pk_nid, BL32_CONTENT_CERT_PK_OID);
586*6f971622SJuan Castillo 		CHECK_NULL(trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
587*6f971622SJuan Castillo 				keys[BL32_KEY].key));
588*6f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, trusted_key_ext);
589*6f971622SJuan Castillo 		if (!cert_new(&certs[BL32_KEY_CERT], VAL_DAYS, 0, sk)) {
590*6f971622SJuan Castillo 			ERROR("Cannot create %s\n", certs[BL32_KEY_CERT].cn);
591*6f971622SJuan Castillo 			exit(1);
592*6f971622SJuan Castillo 		}
593*6f971622SJuan Castillo 		sk_X509_EXTENSION_free(sk);
594*6f971622SJuan Castillo 	}
595*6f971622SJuan Castillo 
596*6f971622SJuan Castillo 	/* *********************************************************************
597*6f971622SJuan Castillo 	 * BL32 certificate (TrustedOS Firmware Content certificate):
598*6f971622SJuan Castillo 	 *     - Signed with Trusted World Key
599*6f971622SJuan Castillo 	 *     - Extensions:
600*6f971622SJuan Castillo 	 *         - TrustedFirmwareNVCounter (TODO)
601*6f971622SJuan Castillo 	 *         - BL32 hash
602*6f971622SJuan Castillo 	 **********************************************************************/
603*6f971622SJuan Castillo 	if (bl32_present) {
604*6f971622SJuan Castillo 		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
605*6f971622SJuan Castillo 		CHECK_NULL(nvctr_ext, ext_new_nvcounter(tz_nvctr_nid, EXT_CRIT,
606*6f971622SJuan Castillo 				tf_nvcounter));
607*6f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, nvctr_ext);
608*6f971622SJuan Castillo 
609*6f971622SJuan Castillo 		if (!sha_file(certs[BL32_CERT].bin, md)) {
610*6f971622SJuan Castillo 			ERROR("Cannot calculate the hash of %s\n",
611*6f971622SJuan Castillo 					certs[BL32_CERT].bin);
612*6f971622SJuan Castillo 			exit(1);
613*6f971622SJuan Castillo 		}
614*6f971622SJuan Castillo 		CHECK_OID(hash_nid, BL32_HASH_OID);
615*6f971622SJuan Castillo 		CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
616*6f971622SJuan Castillo 				SHA256_DIGEST_LENGTH));
617*6f971622SJuan Castillo 		sk_X509_EXTENSION_push(sk, hash_ext);
618*6f971622SJuan Castillo 
619*6f971622SJuan Castillo 		if (!cert_new(&certs[BL32_CERT], VAL_DAYS, 0, sk)) {
620*6f971622SJuan Castillo 			ERROR("Cannot create %s\n", certs[BL32_CERT].cn);
621*6f971622SJuan Castillo 			exit(1);
622*6f971622SJuan Castillo 		}
623*6f971622SJuan Castillo 
624*6f971622SJuan Castillo 		sk_X509_EXTENSION_free(sk);
625*6f971622SJuan Castillo 	}
626*6f971622SJuan Castillo 
627*6f971622SJuan Castillo 	/* *********************************************************************
628*6f971622SJuan Castillo 	 * BL33 Key certificate (Non Trusted Firmware Key certificate):
629*6f971622SJuan Castillo 	 *     - Self-signed with Non Trusted World key
630*6f971622SJuan Castillo 	 *     - Extensions:
631*6f971622SJuan Castillo 	 *         - NonTrustedFirmwareNVCounter (TODO)
632*6f971622SJuan Castillo 	 *         - NonTrustedFirmwareContentCertPK
633*6f971622SJuan Castillo 	 **********************************************************************/
634*6f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
635*6f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
636*6f971622SJuan Castillo 			non_tf_nvcounter));
637*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
638*6f971622SJuan Castillo 	CHECK_OID(pk_nid, BL33_CONTENT_CERT_PK_OID);
639*6f971622SJuan Castillo 	CHECK_NULL(non_trusted_key_ext, ext_new_key(pk_nid, EXT_CRIT,
640*6f971622SJuan Castillo 			keys[BL33_KEY].key));
641*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, non_trusted_key_ext);
642*6f971622SJuan Castillo 	if (!cert_new(&certs[BL33_KEY_CERT], VAL_DAYS, 0, sk)) {
643*6f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[BL33_KEY_CERT].cn);
644*6f971622SJuan Castillo 		exit(1);
645*6f971622SJuan Castillo 	}
646*6f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
647*6f971622SJuan Castillo 
648*6f971622SJuan Castillo 	/* *********************************************************************
649*6f971622SJuan Castillo 	 * BL33 certificate (Non-Trusted World Content certificate):
650*6f971622SJuan Castillo 	 *     - Signed with Non-Trusted World Key
651*6f971622SJuan Castillo 	 *     - Extensions:
652*6f971622SJuan Castillo 	 *         - NonTrustedFirmwareNVCounter (TODO)
653*6f971622SJuan Castillo 	 *         - BL33 hash
654*6f971622SJuan Castillo 	 **********************************************************************/
655*6f971622SJuan Castillo 	CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
656*6f971622SJuan Castillo 	CHECK_NULL(nvctr_ext, ext_new_nvcounter(ntz_nvctr_nid, EXT_CRIT,
657*6f971622SJuan Castillo 			non_tf_nvcounter));
658*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, nvctr_ext);
659*6f971622SJuan Castillo 
660*6f971622SJuan Castillo 	if (!sha_file(certs[BL33_CERT].bin, md)) {
661*6f971622SJuan Castillo 		ERROR("Cannot calculate the hash of %s\n", certs[BL33_CERT].bin);
662*6f971622SJuan Castillo 		exit(1);
663*6f971622SJuan Castillo 	}
664*6f971622SJuan Castillo 	CHECK_OID(hash_nid, BL33_HASH_OID);
665*6f971622SJuan Castillo 	CHECK_NULL(hash_ext, ext_new_hash(hash_nid, EXT_CRIT, md,
666*6f971622SJuan Castillo 			SHA256_DIGEST_LENGTH));
667*6f971622SJuan Castillo 	sk_X509_EXTENSION_push(sk, hash_ext);
668*6f971622SJuan Castillo 
669*6f971622SJuan Castillo 	if (!cert_new(&certs[BL33_CERT], VAL_DAYS, 0, sk)) {
670*6f971622SJuan Castillo 		ERROR("Cannot create %s\n", certs[BL33_CERT].cn);
671*6f971622SJuan Castillo 		exit(1);
672*6f971622SJuan Castillo 	}
673*6f971622SJuan Castillo 	sk_X509_EXTENSION_free(sk);
674*6f971622SJuan Castillo 
675*6f971622SJuan Castillo 	/* Print the certificates */
676*6f971622SJuan Castillo 	if (print_cert) {
677*6f971622SJuan Castillo 		for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
678*6f971622SJuan Castillo 			if (!certs[i].x) {
679*6f971622SJuan Castillo 				continue;
680*6f971622SJuan Castillo 			}
681*6f971622SJuan Castillo 			printf("\n\n=====================================\n\n");
682*6f971622SJuan Castillo 			X509_print_fp(stdout, certs[i].x);
683*6f971622SJuan Castillo 		}
684*6f971622SJuan Castillo 	}
685*6f971622SJuan Castillo 
686*6f971622SJuan Castillo 	/* Save created certificates to files */
687*6f971622SJuan Castillo 	for (i = 0 ; i < NUM_CERTIFICATES ; i++) {
688*6f971622SJuan Castillo 		if (certs[i].x && certs[i].fn) {
689*6f971622SJuan Castillo 			file = fopen(certs[i].fn, "w");
690*6f971622SJuan Castillo 			if (file != NULL) {
691*6f971622SJuan Castillo 				i2d_X509_fp(file, certs[i].x);
692*6f971622SJuan Castillo 				fclose(file);
693*6f971622SJuan Castillo 			} else {
694*6f971622SJuan Castillo 				ERROR("Cannot create file %s\n", certs[i].fn);
695*6f971622SJuan Castillo 			}
696*6f971622SJuan Castillo 		}
697*6f971622SJuan Castillo 	}
698*6f971622SJuan Castillo 
699*6f971622SJuan Castillo 	/* Save keys */
700*6f971622SJuan Castillo 	if (save_keys) {
701*6f971622SJuan Castillo 		for (i = 0 ; i < NUM_KEYS ; i++) {
702*6f971622SJuan Castillo 			if (!key_store(&keys[i])) {
703*6f971622SJuan Castillo 				ERROR("Cannot save %s\n", keys[i].desc);
704*6f971622SJuan Castillo 			}
705*6f971622SJuan Castillo 		}
706*6f971622SJuan Castillo 	}
707*6f971622SJuan Castillo 
708*6f971622SJuan Castillo 	X509_EXTENSION_free(hash_ext);
709*6f971622SJuan Castillo 	X509_EXTENSION_free(nvctr_ext);
710*6f971622SJuan Castillo 	X509_EXTENSION_free(trusted_key_ext);
711*6f971622SJuan Castillo 	X509_EXTENSION_free(non_trusted_key_ext);
712*6f971622SJuan Castillo 
713*6f971622SJuan Castillo #ifndef OPENSSL_NO_ENGINE
714*6f971622SJuan Castillo 	ENGINE_cleanup();
715*6f971622SJuan Castillo #endif
716*6f971622SJuan Castillo 	CRYPTO_cleanup_all_ex_data();
717*6f971622SJuan Castillo 
718*6f971622SJuan Castillo 	return 0;
719*6f971622SJuan Castillo }
720