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 120 /* Info messages created in the Makefile */ 121 extern const char build_msg[]; 122 extern const char platform_msg[]; 123 124 125 static char *strdup(const char *str) 126 { 127 int n = strlen(str) + 1; 128 char *dup = malloc(n); 129 if (dup) { 130 strcpy(dup, str); 131 } 132 return dup; 133 } 134 135 static const char *key_algs_str[] = { 136 [KEY_ALG_RSA] = "rsa", 137 #ifndef OPENSSL_NO_EC 138 [KEY_ALG_ECDSA] = "ecdsa" 139 #endif /* OPENSSL_NO_EC */ 140 }; 141 142 /* Command line options */ 143 static const struct option long_opt[] = { 144 /* Binary images */ 145 {"bl2", required_argument, 0, BL2_ID}, 146 {"bl30", required_argument, 0, BL30_ID}, 147 {"bl31", required_argument, 0, BL31_ID}, 148 {"bl32", required_argument, 0, BL32_ID}, 149 {"bl33", required_argument, 0, BL33_ID}, 150 /* Certificate files */ 151 {"bl2-cert", required_argument, 0, BL2_CERT_ID}, 152 {"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID}, 153 {"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID}, 154 {"bl30-cert", required_argument, 0, BL30_CERT_ID}, 155 {"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID}, 156 {"bl31-cert", required_argument, 0, BL31_CERT_ID}, 157 {"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID}, 158 {"bl32-cert", required_argument, 0, BL32_CERT_ID}, 159 {"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID}, 160 {"bl33-cert", required_argument, 0, BL33_CERT_ID}, 161 /* Private key files */ 162 {"rot-key", required_argument, 0, ROT_KEY_ID}, 163 {"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID}, 164 {"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID}, 165 {"bl30-key", required_argument, 0, BL30_KEY_ID}, 166 {"bl31-key", required_argument, 0, BL31_KEY_ID}, 167 {"bl32-key", required_argument, 0, BL32_KEY_ID}, 168 {"bl33-key", required_argument, 0, BL33_KEY_ID}, 169 /* Common options */ 170 {"key-alg", required_argument, 0, 'a'}, 171 {"help", no_argument, 0, 'h'}, 172 {"save-keys", no_argument, 0, 'k'}, 173 {"new-chain", no_argument, 0, 'n'}, 174 {"print-cert", no_argument, 0, 'p'}, 175 {0, 0, 0, 0} 176 }; 177 178 static void print_help(const char *cmd) 179 { 180 int i = 0; 181 printf("\n\n"); 182 printf("The certificate generation tool loads the binary images and\n" 183 "optionally the RSA keys, and outputs the key and content\n" 184 "certificates properly signed to implement the chain of trust.\n" 185 "If keys are provided, they must be in PEM format.\n" 186 "Certificates are generated in DER format.\n"); 187 printf("\n"); 188 printf("Usage:\n\n"); 189 printf(" %s [-hknp] \\\n", cmd); 190 for (i = 0; i < NUM_OPTS; i++) { 191 printf(" --%s <file> \\\n", long_opt[i].name); 192 } 193 printf("\n"); 194 printf("-a Key algorithm: rsa (default), ecdsa\n"); 195 printf("-h Print help and exit\n"); 196 printf("-k Save key pairs into files. Filenames must be provided\n"); 197 printf("-n Generate new key pairs if no key files are provided\n"); 198 printf("-p Print the certificates in the standard output\n"); 199 printf("\n"); 200 201 exit(0); 202 } 203 204 static int get_key_alg(const char *key_alg_str) 205 { 206 int i; 207 208 for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) { 209 if (0 == strcmp(key_alg_str, key_algs_str[i])) { 210 return i; 211 } 212 } 213 214 return -1; 215 } 216 217 static void check_cmd_params(void) 218 { 219 cert_t *cert; 220 ext_t *ext; 221 key_t *key; 222 int i, j; 223 224 /* Only save new keys */ 225 if (save_keys && !new_keys) { 226 ERROR("Only new keys can be saved to disk\n"); 227 exit(1); 228 } 229 230 /* Check that all required options have been specified in the 231 * command line */ 232 for (i = 0; i < num_certs; i++) { 233 cert = &certs[i]; 234 if (cert->fn == NULL) { 235 /* Certificate not requested. Skip to the next one */ 236 continue; 237 } 238 239 /* Check that all parameters required to create this certificate 240 * have been specified in the command line */ 241 for (j = 0; j < cert->num_ext; j++) { 242 ext = &extensions[cert->ext[j]]; 243 switch (ext->type) { 244 case EXT_TYPE_PKEY: 245 /* Key filename must be specified */ 246 key = &keys[ext->data.key]; 247 if (!new_keys && key->fn == NULL) { 248 ERROR("Key '%s' required by '%s' not " 249 "specified\n", key->desc, 250 cert->cn); 251 exit(1); 252 } 253 break; 254 case EXT_TYPE_HASH: 255 /* Binary image must be specified */ 256 if (ext->data.fn == NULL) { 257 ERROR("Image for '%s' not specified\n", 258 ext->ln); 259 exit(1); 260 } 261 break; 262 default: 263 ERROR("Unknown extension type in '%s'\n", 264 ext->ln); 265 exit(1); 266 break; 267 } 268 } 269 } 270 } 271 272 int main(int argc, char *argv[]) 273 { 274 STACK_OF(X509_EXTENSION) * sk = NULL; 275 X509_EXTENSION *cert_ext = NULL; 276 ext_t *ext = NULL; 277 cert_t *cert; 278 FILE *file = NULL; 279 int i, j, ext_nid; 280 int c, opt_idx = 0; 281 unsigned int err_code; 282 unsigned char md[SHA256_DIGEST_LENGTH]; 283 const EVP_MD *md_info; 284 285 NOTICE("CoT Generation Tool: %s\n", build_msg); 286 NOTICE("Target platform: %s\n", platform_msg); 287 288 /* Set default options */ 289 key_alg = KEY_ALG_RSA; 290 291 while (1) { 292 /* getopt_long stores the option index here. */ 293 c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx); 294 295 /* Detect the end of the options. */ 296 if (c == -1) { 297 break; 298 } 299 300 switch (c) { 301 case 'a': 302 key_alg = get_key_alg(optarg); 303 if (key_alg < 0) { 304 ERROR("Invalid key algorithm '%s'\n", optarg); 305 exit(1); 306 } 307 break; 308 case 'h': 309 print_help(argv[0]); 310 break; 311 case 'k': 312 save_keys = 1; 313 break; 314 case 'n': 315 new_keys = 1; 316 break; 317 case 'p': 318 print_cert = 1; 319 break; 320 case BL2_ID: 321 extensions[BL2_HASH_EXT].data.fn = strdup(optarg); 322 break; 323 case BL30_ID: 324 extensions[BL30_HASH_EXT].data.fn = strdup(optarg); 325 break; 326 case BL31_ID: 327 extensions[BL31_HASH_EXT].data.fn = strdup(optarg); 328 break; 329 case BL32_ID: 330 extensions[BL32_HASH_EXT].data.fn = strdup(optarg); 331 break; 332 case BL33_ID: 333 extensions[BL33_HASH_EXT].data.fn = strdup(optarg); 334 break; 335 case BL2_CERT_ID: 336 certs[BL2_CERT].fn = strdup(optarg); 337 break; 338 case TRUSTED_KEY_CERT_ID: 339 certs[TRUSTED_KEY_CERT].fn = strdup(optarg); 340 break; 341 case BL30_KEY_CERT_ID: 342 certs[BL30_KEY_CERT].fn = strdup(optarg); 343 break; 344 case BL30_CERT_ID: 345 certs[BL30_CERT].fn = strdup(optarg); 346 break; 347 case BL31_KEY_CERT_ID: 348 certs[BL31_KEY_CERT].fn = strdup(optarg); 349 break; 350 case BL31_CERT_ID: 351 certs[BL31_CERT].fn = strdup(optarg); 352 break; 353 case BL32_KEY_CERT_ID: 354 certs[BL32_KEY_CERT].fn = strdup(optarg); 355 break; 356 case BL32_CERT_ID: 357 certs[BL32_CERT].fn = strdup(optarg); 358 break; 359 case BL33_KEY_CERT_ID: 360 certs[BL33_KEY_CERT].fn = strdup(optarg); 361 break; 362 case BL33_CERT_ID: 363 certs[BL33_CERT].fn = strdup(optarg); 364 break; 365 case ROT_KEY_ID: 366 keys[ROT_KEY].fn = strdup(optarg); 367 break; 368 case TRUSTED_WORLD_KEY_ID: 369 keys[TRUSTED_WORLD_KEY].fn = strdup(optarg); 370 break; 371 case NON_TRUSTED_WORLD_KEY_ID: 372 keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg); 373 break; 374 case BL30_KEY_ID: 375 keys[BL30_KEY].fn = strdup(optarg); 376 break; 377 case BL31_KEY_ID: 378 keys[BL31_KEY].fn = strdup(optarg); 379 break; 380 case BL32_KEY_ID: 381 keys[BL32_KEY].fn = strdup(optarg); 382 break; 383 case BL33_KEY_ID: 384 keys[BL33_KEY].fn = strdup(optarg); 385 break; 386 case '?': 387 default: 388 printf("%s\n", optarg); 389 exit(1); 390 } 391 } 392 393 /* Check command line arguments */ 394 check_cmd_params(); 395 396 /* Register the new types and OIDs for the extensions */ 397 if (ext_register(extensions) != 0) { 398 ERROR("Cannot register TBB extensions\n"); 399 exit(1); 400 } 401 402 /* Indicate SHA256 as image hash algorithm in the certificate 403 * extension */ 404 md_info = EVP_sha256(); 405 406 /* Load private keys from files (or generate new ones) */ 407 for (i = 0 ; i < num_keys ; i++) { 408 /* First try to load the key from disk */ 409 if (key_load(&keys[i], &err_code)) { 410 /* Key loaded successfully */ 411 continue; 412 } 413 414 /* Key not loaded. Check the error code */ 415 if (err_code == KEY_ERR_MALLOC) { 416 /* Cannot allocate memory. Abort. */ 417 ERROR("Malloc error while loading '%s'\n", keys[i].fn); 418 exit(1); 419 } else if (err_code == KEY_ERR_LOAD) { 420 /* File exists, but it does not contain a valid private 421 * key. Abort. */ 422 ERROR("Error loading '%s'\n", keys[i].fn); 423 exit(1); 424 } 425 426 /* File does not exist, could not be opened or no filename was 427 * given */ 428 if (new_keys) { 429 /* Try to create a new key */ 430 NOTICE("Creating new key for '%s'\n", keys[i].desc); 431 if (!key_create(&keys[i], key_alg)) { 432 ERROR("Error creating key '%s'\n", keys[i].desc); 433 exit(1); 434 } 435 } else { 436 if (err_code == KEY_ERR_OPEN) { 437 ERROR("Error opening '%s'\n", keys[i].fn); 438 } else { 439 ERROR("Key '%s' not specified\n", keys[i].desc); 440 } 441 exit(1); 442 } 443 } 444 445 /* Create the certificates */ 446 for (i = 0 ; i < num_certs ; i++) { 447 448 cert = &certs[i]; 449 450 /* Create a new stack of extensions. This stack will be used 451 * to create the certificate */ 452 CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); 453 454 for (j = 0 ; j < cert->num_ext ; j++) { 455 456 ext = &extensions[cert->ext[j]]; 457 458 /* Get OpenSSL internal ID for this extension */ 459 CHECK_OID(ext_nid, ext->oid); 460 461 /* 462 * Three types of extensions are currently supported: 463 * - EXT_TYPE_NVCOUNTER 464 * - EXT_TYPE_HASH 465 * - EXT_TYPE_PKEY 466 */ 467 switch (ext->type) { 468 case EXT_TYPE_NVCOUNTER: 469 CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid, 470 EXT_CRIT, ext->data.nvcounter)); 471 break; 472 case EXT_TYPE_HASH: 473 if (ext->data.fn == NULL) { 474 break; 475 } 476 if (!sha_file(ext->data.fn, md)) { 477 ERROR("Cannot calculate hash of %s\n", 478 ext->data.fn); 479 exit(1); 480 } 481 CHECK_NULL(cert_ext, ext_new_hash(ext_nid, 482 EXT_CRIT, md_info, md, 483 SHA256_DIGEST_LENGTH)); 484 break; 485 case EXT_TYPE_PKEY: 486 CHECK_NULL(cert_ext, ext_new_key(ext_nid, 487 EXT_CRIT, keys[ext->data.key].key)); 488 break; 489 default: 490 ERROR("Unknown extension type in %s\n", 491 cert->cn); 492 exit(1); 493 } 494 495 /* Push the extension into the stack */ 496 sk_X509_EXTENSION_push(sk, cert_ext); 497 } 498 499 /* Create certificate. Signed with ROT key */ 500 if (cert->fn && !cert_new(cert, VAL_DAYS, 0, sk)) { 501 ERROR("Cannot create %s\n", cert->cn); 502 exit(1); 503 } 504 505 sk_X509_EXTENSION_free(sk); 506 } 507 508 509 /* Print the certificates */ 510 if (print_cert) { 511 for (i = 0 ; i < num_certs ; i++) { 512 if (!certs[i].x) { 513 continue; 514 } 515 printf("\n\n=====================================\n\n"); 516 X509_print_fp(stdout, certs[i].x); 517 } 518 } 519 520 /* Save created certificates to files */ 521 for (i = 0 ; i < num_certs ; i++) { 522 if (certs[i].x && certs[i].fn) { 523 file = fopen(certs[i].fn, "w"); 524 if (file != NULL) { 525 i2d_X509_fp(file, certs[i].x); 526 fclose(file); 527 } else { 528 ERROR("Cannot create file %s\n", certs[i].fn); 529 } 530 } 531 } 532 533 /* Save keys */ 534 if (save_keys) { 535 for (i = 0 ; i < num_keys ; i++) { 536 if (!key_store(&keys[i])) { 537 ERROR("Cannot save %s\n", keys[i].desc); 538 } 539 } 540 } 541 542 #ifndef OPENSSL_NO_ENGINE 543 ENGINE_cleanup(); 544 #endif 545 CRYPTO_cleanup_all_ex_data(); 546 547 return 0; 548 } 549