xref: /rk3399_ARM-atf/tools/cert_create/src/main.c (revision fd6007de64fd7e16f6d96972643434c04a77f1c6)
1 /*
2  * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of ARM nor the names of its contributors may be used
15  * to endorse or promote products derived from this software without specific
16  * prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <getopt.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #include <openssl/conf.h>
37 #include <openssl/engine.h>
38 #include <openssl/err.h>
39 #include <openssl/pem.h>
40 #include <openssl/sha.h>
41 #include <openssl/x509v3.h>
42 
43 #include "cert.h"
44 #include "debug.h"
45 #include "ext.h"
46 #include "key.h"
47 #include "platform_oid.h"
48 #include "sha.h"
49 #include "tbbr/tbb_ext.h"
50 #include "tbbr/tbb_cert.h"
51 #include "tbbr/tbb_key.h"
52 
53 /*
54  * Helper macros to simplify the code. This macro assigns the return value of
55  * the 'fn' function to 'v' and exits if the value is NULL.
56  */
57 #define CHECK_NULL(v, fn) \
58 	do { \
59 		v = fn; \
60 		if (v == NULL) { \
61 			ERROR("NULL object at %s:%d\n", __FILE__, __LINE__); \
62 			exit(1); \
63 		} \
64 	} while (0)
65 
66 /*
67  * This macro assigns the NID corresponding to 'oid' to 'v' and exits if the
68  * NID is undefined.
69  */
70 #define CHECK_OID(v, oid) \
71 	do { \
72 		v = OBJ_txt2nid(oid); \
73 		if (v == NID_undef) { \
74 			ERROR("Cannot find TBB extension %s\n", oid); \
75 			exit(1); \
76 		} \
77 	} while (0)
78 
79 #define MAX_FILENAME_LEN		1024
80 #define VAL_DAYS			7300
81 #define ID_TO_BIT_MASK(id)		(1 << id)
82 #define NUM_ELEM(x)			((sizeof(x)) / (sizeof(x[0])))
83 
84 /* Files */
85 enum {
86 	/* Image file names (inputs) */
87 	BL2_ID = 0,
88 	BL30_ID,
89 	BL31_ID,
90 	BL32_ID,
91 	BL33_ID,
92 	/* Certificate file names (outputs) */
93 	BL2_CERT_ID,
94 	TRUSTED_KEY_CERT_ID,
95 	BL30_KEY_CERT_ID,
96 	BL30_CERT_ID,
97 	BL31_KEY_CERT_ID,
98 	BL31_CERT_ID,
99 	BL32_KEY_CERT_ID,
100 	BL32_CERT_ID,
101 	BL33_KEY_CERT_ID,
102 	BL33_CERT_ID,
103 	/* Key file names (input/output) */
104 	ROT_KEY_ID,
105 	TRUSTED_WORLD_KEY_ID,
106 	NON_TRUSTED_WORLD_KEY_ID,
107 	BL30_KEY_ID,
108 	BL31_KEY_ID,
109 	BL32_KEY_ID,
110 	BL33_KEY_ID,
111 	NUM_OPTS
112 };
113 
114 /* Global options */
115 static int key_alg;
116 static int new_keys;
117 static int save_keys;
118 static int print_cert;
119 static int bl30_present;
120 static int bl32_present;
121 
122 /* Info messages created in the Makefile */
123 extern const char build_msg[];
124 extern const char platform_msg[];
125 
126 
127 static char *strdup(const char *str)
128 {
129 	int n = strlen(str) + 1;
130 	char *dup = malloc(n);
131 	if (dup) {
132 		strcpy(dup, str);
133 	}
134 	return dup;
135 }
136 
137 static const char *key_algs_str[] = {
138 	[KEY_ALG_RSA] = "rsa",
139 #ifndef OPENSSL_NO_EC
140 	[KEY_ALG_ECDSA] = "ecdsa"
141 #endif /* OPENSSL_NO_EC */
142 };
143 
144 /* Command line options */
145 static const struct option long_opt[] = {
146 	/* Binary images */
147 	{"bl2", required_argument, 0, BL2_ID},
148 	{"bl30", required_argument, 0, BL30_ID},
149 	{"bl31", required_argument, 0, BL31_ID},
150 	{"bl32", required_argument, 0, BL32_ID},
151 	{"bl33", required_argument, 0, BL33_ID},
152 	/* Certificate files */
153 	{"bl2-cert", required_argument, 0, BL2_CERT_ID},
154 	{"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID},
155 	{"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID},
156 	{"bl30-cert", required_argument, 0, BL30_CERT_ID},
157 	{"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID},
158 	{"bl31-cert", required_argument, 0, BL31_CERT_ID},
159 	{"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID},
160 	{"bl32-cert", required_argument, 0, BL32_CERT_ID},
161 	{"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID},
162 	{"bl33-cert", required_argument, 0, BL33_CERT_ID},
163 	/* Private key files */
164 	{"rot-key", required_argument, 0, ROT_KEY_ID},
165 	{"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID},
166 	{"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID},
167 	{"bl30-key", required_argument, 0, BL30_KEY_ID},
168 	{"bl31-key", required_argument, 0, BL31_KEY_ID},
169 	{"bl32-key", required_argument, 0, BL32_KEY_ID},
170 	{"bl33-key", required_argument, 0, BL33_KEY_ID},
171 	/* Common options */
172 	{"key-alg", required_argument, 0, 'a'},
173 	{"help", no_argument, 0, 'h'},
174 	{"save-keys", no_argument, 0, 'k'},
175 	{"new-chain", no_argument, 0, 'n'},
176 	{"print-cert", no_argument, 0, 'p'},
177 	{0, 0, 0, 0}
178 };
179 
180 static void print_help(const char *cmd)
181 {
182 	int i = 0;
183 	printf("\n\n");
184 	printf("The certificate generation tool loads the binary images and\n"
185 	       "optionally the RSA keys, and outputs the key and content\n"
186 	       "certificates properly signed to implement the chain of trust.\n"
187 	       "If keys are provided, they must be in PEM format.\n"
188 	       "Certificates are generated in DER format.\n");
189 	printf("\n");
190 	printf("Usage:\n\n");
191 	printf("    %s [-hknp] \\\n", cmd);
192 	for (i = 0; i < NUM_OPTS; i++) {
193 		printf("        --%s <file>  \\\n", long_opt[i].name);
194 	}
195 	printf("\n");
196 	printf("-a    Key algorithm: rsa (default), ecdsa\n");
197 	printf("-h    Print help and exit\n");
198 	printf("-k    Save key pairs into files. Filenames must be provided\n");
199 	printf("-n    Generate new key pairs if no key files are provided\n");
200 	printf("-p    Print the certificates in the standard output\n");
201 	printf("\n");
202 
203 	exit(0);
204 }
205 
206 static int get_key_alg(const char *key_alg_str)
207 {
208 	int i;
209 
210 	for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) {
211 		if (0 == strcmp(key_alg_str, key_algs_str[i])) {
212 			return i;
213 		}
214 	}
215 
216 	return -1;
217 }
218 
219 static void check_cmd_params(void)
220 {
221 	/* Only save new keys */
222 	if (save_keys && !new_keys) {
223 		ERROR("Only new keys can be saved to disk\n");
224 		exit(1);
225 	}
226 
227 	/* BL2, BL31 and BL33 are mandatory */
228 	if (extensions[BL2_HASH_EXT].data.fn == NULL) {
229 		ERROR("BL2 image not specified\n");
230 		exit(1);
231 	}
232 
233 	if (extensions[BL31_HASH_EXT].data.fn == NULL) {
234 		ERROR("BL31 image not specified\n");
235 		exit(1);
236 	}
237 
238 	if (extensions[BL33_HASH_EXT].data.fn == NULL) {
239 		ERROR("BL33 image not specified\n");
240 		exit(1);
241 	}
242 
243 	/* BL30 and BL32 are optional */
244 	if (extensions[BL30_HASH_EXT].data.fn != NULL) {
245 		bl30_present = 1;
246 	}
247 
248 	if (extensions[BL32_HASH_EXT].data.fn != NULL) {
249 		bl32_present = 1;
250 	}
251 
252 	/* TODO: Certificate filenames */
253 
254 	/* Filenames to store keys must be specified */
255 	if (save_keys || !new_keys) {
256 		if (keys[ROT_KEY].fn == NULL) {
257 			ERROR("ROT key not specified\n");
258 			exit(1);
259 		}
260 
261 		if (keys[TRUSTED_WORLD_KEY].fn == NULL) {
262 			ERROR("Trusted World key not specified\n");
263 			exit(1);
264 		}
265 
266 		if (keys[NON_TRUSTED_WORLD_KEY].fn == NULL) {
267 			ERROR("Non-trusted World key not specified\n");
268 			exit(1);
269 		}
270 
271 		if (keys[BL31_KEY].fn == NULL) {
272 			ERROR("BL31 key not specified\n");
273 			exit(1);
274 		}
275 
276 		if (keys[BL33_KEY].fn == NULL) {
277 			ERROR("BL33 key not specified\n");
278 			exit(1);
279 		}
280 
281 		if (bl30_present && (keys[BL30_KEY].fn == NULL)) {
282 			ERROR("BL30 key not specified\n");
283 			exit(1);
284 		}
285 
286 		if (bl32_present && (keys[BL32_KEY].fn == NULL)) {
287 			ERROR("BL32 key not specified\n");
288 			exit(1);
289 		}
290 	}
291 }
292 
293 int main(int argc, char *argv[])
294 {
295 	STACK_OF(X509_EXTENSION) * sk = NULL;
296 	X509_EXTENSION *cert_ext = NULL;
297 	ext_t *ext = NULL;
298 	cert_t *cert;
299 	FILE *file = NULL;
300 	int i, j, ext_nid;
301 	int c, opt_idx = 0;
302 	unsigned int err_code;
303 	unsigned char md[SHA256_DIGEST_LENGTH];
304 	const EVP_MD *md_info;
305 
306 	NOTICE("CoT Generation Tool: %s\n", build_msg);
307 	NOTICE("Target platform: %s\n", platform_msg);
308 
309 	/* Set default options */
310 	key_alg = KEY_ALG_RSA;
311 
312 	while (1) {
313 		/* getopt_long stores the option index here. */
314 		c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx);
315 
316 		/* Detect the end of the options. */
317 		if (c == -1) {
318 			break;
319 		}
320 
321 		switch (c) {
322 		case 'a':
323 			key_alg = get_key_alg(optarg);
324 			if (key_alg < 0) {
325 				ERROR("Invalid key algorithm '%s'\n", optarg);
326 				exit(1);
327 			}
328 			break;
329 		case 'h':
330 			print_help(argv[0]);
331 			break;
332 		case 'k':
333 			save_keys = 1;
334 			break;
335 		case 'n':
336 			new_keys = 1;
337 			break;
338 		case 'p':
339 			print_cert = 1;
340 			break;
341 		case BL2_ID:
342 			extensions[BL2_HASH_EXT].data.fn = strdup(optarg);
343 			break;
344 		case BL30_ID:
345 			extensions[BL30_HASH_EXT].data.fn = strdup(optarg);
346 			break;
347 		case BL31_ID:
348 			extensions[BL31_HASH_EXT].data.fn = strdup(optarg);
349 			break;
350 		case BL32_ID:
351 			extensions[BL32_HASH_EXT].data.fn = strdup(optarg);
352 			break;
353 		case BL33_ID:
354 			extensions[BL33_HASH_EXT].data.fn = strdup(optarg);
355 			break;
356 		case BL2_CERT_ID:
357 			certs[BL2_CERT].fn = strdup(optarg);
358 			break;
359 		case TRUSTED_KEY_CERT_ID:
360 			certs[TRUSTED_KEY_CERT].fn = strdup(optarg);
361 			break;
362 		case BL30_KEY_CERT_ID:
363 			certs[BL30_KEY_CERT].fn = strdup(optarg);
364 			break;
365 		case BL30_CERT_ID:
366 			certs[BL30_CERT].fn = strdup(optarg);
367 			break;
368 		case BL31_KEY_CERT_ID:
369 			certs[BL31_KEY_CERT].fn = strdup(optarg);
370 			break;
371 		case BL31_CERT_ID:
372 			certs[BL31_CERT].fn = strdup(optarg);
373 			break;
374 		case BL32_KEY_CERT_ID:
375 			certs[BL32_KEY_CERT].fn = strdup(optarg);
376 			break;
377 		case BL32_CERT_ID:
378 			certs[BL32_CERT].fn = strdup(optarg);
379 			break;
380 		case BL33_KEY_CERT_ID:
381 			certs[BL33_KEY_CERT].fn = strdup(optarg);
382 			break;
383 		case BL33_CERT_ID:
384 			certs[BL33_CERT].fn = strdup(optarg);
385 			break;
386 		case ROT_KEY_ID:
387 			keys[ROT_KEY].fn = strdup(optarg);
388 			break;
389 		case TRUSTED_WORLD_KEY_ID:
390 			keys[TRUSTED_WORLD_KEY].fn = strdup(optarg);
391 			break;
392 		case NON_TRUSTED_WORLD_KEY_ID:
393 			keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg);
394 			break;
395 		case BL30_KEY_ID:
396 			keys[BL30_KEY].fn = strdup(optarg);
397 			break;
398 		case BL31_KEY_ID:
399 			keys[BL31_KEY].fn = strdup(optarg);
400 			break;
401 		case BL32_KEY_ID:
402 			keys[BL32_KEY].fn = strdup(optarg);
403 			break;
404 		case BL33_KEY_ID:
405 			keys[BL33_KEY].fn = strdup(optarg);
406 			break;
407 		case '?':
408 		default:
409 			printf("%s\n", optarg);
410 			exit(1);
411 		}
412 	}
413 
414 	/* Check command line arguments */
415 	check_cmd_params();
416 
417 	/* Register the new types and OIDs for the extensions */
418 	if (ext_register(extensions) != 0) {
419 		ERROR("Cannot register TBB extensions\n");
420 		exit(1);
421 	}
422 
423 	/* Indicate SHA256 as image hash algorithm in the certificate
424 	 * extension */
425 	md_info = EVP_sha256();
426 
427 	/* Load private keys from files (or generate new ones) */
428 	for (i = 0 ; i < num_keys ; i++) {
429 		/* First try to load the key from disk */
430 		if (key_load(&keys[i], &err_code)) {
431 			/* Key loaded successfully */
432 			continue;
433 		}
434 
435 		/* Key not loaded. Check the error code */
436 		if (err_code == KEY_ERR_MALLOC) {
437 			/* Cannot allocate memory. Abort. */
438 			ERROR("Malloc error while loading '%s'\n", keys[i].fn);
439 			exit(1);
440 		} else if (err_code == KEY_ERR_LOAD) {
441 			/* File exists, but it does not contain a valid private
442 			 * key. Abort. */
443 			ERROR("Error loading '%s'\n", keys[i].fn);
444 			exit(1);
445 		}
446 
447 		/* File does not exist, could not be opened or no filename was
448 		 * given */
449 		if (new_keys) {
450 			/* Try to create a new key */
451 			NOTICE("Creating new key for '%s'\n", keys[i].desc);
452 			if (!key_create(&keys[i], key_alg)) {
453 				ERROR("Error creating key '%s'\n", keys[i].desc);
454 				exit(1);
455 			}
456 		} else {
457 			if (err_code == KEY_ERR_OPEN) {
458 				ERROR("Error opening '%s'\n", keys[i].fn);
459 			} else {
460 				ERROR("Key '%s' not specified\n", keys[i].desc);
461 			}
462 			exit(1);
463 		}
464 	}
465 
466 	/* Create the certificates */
467 	for (i = 0 ; i < num_certs ; i++) {
468 
469 		cert = &certs[i];
470 
471 		/* Create a new stack of extensions. This stack will be used
472 		 * to create the certificate */
473 		CHECK_NULL(sk, sk_X509_EXTENSION_new_null());
474 
475 		for (j = 0 ; j < cert->num_ext ; j++) {
476 
477 			ext = &extensions[cert->ext[j]];
478 
479 			/* Get OpenSSL internal ID for this extension */
480 			CHECK_OID(ext_nid, ext->oid);
481 
482 			/*
483 			 * Three types of extensions are currently supported:
484 			 *     - EXT_TYPE_NVCOUNTER
485 			 *     - EXT_TYPE_HASH
486 			 *     - EXT_TYPE_PKEY
487 			 */
488 			switch (ext->type) {
489 			case EXT_TYPE_NVCOUNTER:
490 				CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid,
491 						EXT_CRIT, ext->data.nvcounter));
492 				break;
493 			case EXT_TYPE_HASH:
494 				if (ext->data.fn == NULL) {
495 					break;
496 				}
497 				if (!sha_file(ext->data.fn, md)) {
498 					ERROR("Cannot calculate hash of %s\n",
499 						ext->data.fn);
500 					exit(1);
501 				}
502 				CHECK_NULL(cert_ext, ext_new_hash(ext_nid,
503 						EXT_CRIT, md_info, md,
504 						SHA256_DIGEST_LENGTH));
505 				break;
506 			case EXT_TYPE_PKEY:
507 				CHECK_NULL(cert_ext, ext_new_key(ext_nid,
508 					EXT_CRIT, keys[ext->data.key].key));
509 				break;
510 			default:
511 				ERROR("Unknown extension type in %s\n",
512 						cert->cn);
513 				exit(1);
514 			}
515 
516 			/* Push the extension into the stack */
517 			sk_X509_EXTENSION_push(sk, cert_ext);
518 		}
519 
520 		/* Create certificate. Signed with ROT key */
521 		if (!cert_new(cert, VAL_DAYS, 0, sk)) {
522 			ERROR("Cannot create %s\n", cert->cn);
523 			exit(1);
524 		}
525 
526 		sk_X509_EXTENSION_free(sk);
527 	}
528 
529 
530 	/* Print the certificates */
531 	if (print_cert) {
532 		for (i = 0 ; i < num_certs ; i++) {
533 			if (!certs[i].x) {
534 				continue;
535 			}
536 			printf("\n\n=====================================\n\n");
537 			X509_print_fp(stdout, certs[i].x);
538 		}
539 	}
540 
541 	/* Save created certificates to files */
542 	for (i = 0 ; i < num_certs ; i++) {
543 		if (certs[i].x && certs[i].fn) {
544 			file = fopen(certs[i].fn, "w");
545 			if (file != NULL) {
546 				i2d_X509_fp(file, certs[i].x);
547 				fclose(file);
548 			} else {
549 				ERROR("Cannot create file %s\n", certs[i].fn);
550 			}
551 		}
552 	}
553 
554 	/* Save keys */
555 	if (save_keys) {
556 		for (i = 0 ; i < num_keys ; i++) {
557 			if (!key_store(&keys[i])) {
558 				ERROR("Cannot save %s\n", keys[i].desc);
559 			}
560 		}
561 	}
562 
563 #ifndef OPENSSL_NO_ENGINE
564 	ENGINE_cleanup();
565 #endif
566 	CRYPTO_cleanup_all_ex_data();
567 
568 	return 0;
569 }
570