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