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" 4955e291a4SJuan Castillo #include "tbbr/tbb_ext.h" 5055e291a4SJuan Castillo #include "tbbr/tbb_cert.h" 5155e291a4SJuan Castillo #include "tbbr/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) 82ccbf890eSJuan Castillo #define NUM_ELEM(x) ((sizeof(x)) / (sizeof(x[0]))) 836f971622SJuan Castillo 846f971622SJuan Castillo /* Files */ 856f971622SJuan Castillo enum { 866f971622SJuan Castillo /* Image file names (inputs) */ 876f971622SJuan Castillo BL2_ID = 0, 886f971622SJuan Castillo BL30_ID, 896f971622SJuan Castillo BL31_ID, 906f971622SJuan Castillo BL32_ID, 916f971622SJuan Castillo BL33_ID, 926f971622SJuan Castillo /* Certificate file names (outputs) */ 936f971622SJuan Castillo BL2_CERT_ID, 946f971622SJuan Castillo TRUSTED_KEY_CERT_ID, 956f971622SJuan Castillo BL30_KEY_CERT_ID, 966f971622SJuan Castillo BL30_CERT_ID, 976f971622SJuan Castillo BL31_KEY_CERT_ID, 986f971622SJuan Castillo BL31_CERT_ID, 996f971622SJuan Castillo BL32_KEY_CERT_ID, 1006f971622SJuan Castillo BL32_CERT_ID, 1016f971622SJuan Castillo BL33_KEY_CERT_ID, 1026f971622SJuan Castillo BL33_CERT_ID, 1036f971622SJuan Castillo /* Key file names (input/output) */ 1046f971622SJuan Castillo ROT_KEY_ID, 1056f971622SJuan Castillo TRUSTED_WORLD_KEY_ID, 1066f971622SJuan Castillo NON_TRUSTED_WORLD_KEY_ID, 1076f971622SJuan Castillo BL30_KEY_ID, 1086f971622SJuan Castillo BL31_KEY_ID, 1096f971622SJuan Castillo BL32_KEY_ID, 1106f971622SJuan Castillo BL33_KEY_ID, 1116f971622SJuan Castillo NUM_OPTS 1126f971622SJuan Castillo }; 1136f971622SJuan Castillo 1146f971622SJuan Castillo /* Global options */ 115ccbf890eSJuan Castillo static int key_alg; 1166f971622SJuan Castillo static int new_keys; 1176f971622SJuan Castillo static int save_keys; 1186f971622SJuan Castillo static int print_cert; 1196f971622SJuan Castillo 1206f971622SJuan Castillo /* Info messages created in the Makefile */ 1216f971622SJuan Castillo extern const char build_msg[]; 1226f971622SJuan Castillo extern const char platform_msg[]; 1236f971622SJuan Castillo 1246f971622SJuan Castillo 1256f971622SJuan Castillo static char *strdup(const char *str) 1266f971622SJuan Castillo { 1276f971622SJuan Castillo int n = strlen(str) + 1; 1286f971622SJuan Castillo char *dup = malloc(n); 1296f971622SJuan Castillo if (dup) { 1306f971622SJuan Castillo strcpy(dup, str); 1316f971622SJuan Castillo } 1326f971622SJuan Castillo return dup; 1336f971622SJuan Castillo } 1346f971622SJuan Castillo 135ccbf890eSJuan Castillo static const char *key_algs_str[] = { 136ccbf890eSJuan Castillo [KEY_ALG_RSA] = "rsa", 137ed2a76eaSJuan Castillo #ifndef OPENSSL_NO_EC 138ccbf890eSJuan Castillo [KEY_ALG_ECDSA] = "ecdsa" 139ed2a76eaSJuan Castillo #endif /* OPENSSL_NO_EC */ 140ccbf890eSJuan Castillo }; 141ccbf890eSJuan Castillo 1426f971622SJuan Castillo /* Command line options */ 1436f971622SJuan Castillo static const struct option long_opt[] = { 1446f971622SJuan Castillo /* Binary images */ 1456f971622SJuan Castillo {"bl2", required_argument, 0, BL2_ID}, 1466f971622SJuan Castillo {"bl30", required_argument, 0, BL30_ID}, 1476f971622SJuan Castillo {"bl31", required_argument, 0, BL31_ID}, 1486f971622SJuan Castillo {"bl32", required_argument, 0, BL32_ID}, 1496f971622SJuan Castillo {"bl33", required_argument, 0, BL33_ID}, 1506f971622SJuan Castillo /* Certificate files */ 1516f971622SJuan Castillo {"bl2-cert", required_argument, 0, BL2_CERT_ID}, 1526f971622SJuan Castillo {"trusted-key-cert", required_argument, 0, TRUSTED_KEY_CERT_ID}, 1536f971622SJuan Castillo {"bl30-key-cert", required_argument, 0, BL30_KEY_CERT_ID}, 1546f971622SJuan Castillo {"bl30-cert", required_argument, 0, BL30_CERT_ID}, 1556f971622SJuan Castillo {"bl31-key-cert", required_argument, 0, BL31_KEY_CERT_ID}, 1566f971622SJuan Castillo {"bl31-cert", required_argument, 0, BL31_CERT_ID}, 1576f971622SJuan Castillo {"bl32-key-cert", required_argument, 0, BL32_KEY_CERT_ID}, 1586f971622SJuan Castillo {"bl32-cert", required_argument, 0, BL32_CERT_ID}, 1596f971622SJuan Castillo {"bl33-key-cert", required_argument, 0, BL33_KEY_CERT_ID}, 1606f971622SJuan Castillo {"bl33-cert", required_argument, 0, BL33_CERT_ID}, 1616f971622SJuan Castillo /* Private key files */ 1626f971622SJuan Castillo {"rot-key", required_argument, 0, ROT_KEY_ID}, 1636f971622SJuan Castillo {"trusted-world-key", required_argument, 0, TRUSTED_WORLD_KEY_ID}, 1646f971622SJuan Castillo {"non-trusted-world-key", required_argument, 0, NON_TRUSTED_WORLD_KEY_ID}, 1656f971622SJuan Castillo {"bl30-key", required_argument, 0, BL30_KEY_ID}, 1666f971622SJuan Castillo {"bl31-key", required_argument, 0, BL31_KEY_ID}, 1676f971622SJuan Castillo {"bl32-key", required_argument, 0, BL32_KEY_ID}, 1686f971622SJuan Castillo {"bl33-key", required_argument, 0, BL33_KEY_ID}, 1696f971622SJuan Castillo /* Common options */ 170ccbf890eSJuan Castillo {"key-alg", required_argument, 0, 'a'}, 1716f971622SJuan Castillo {"help", no_argument, 0, 'h'}, 1726f971622SJuan Castillo {"save-keys", no_argument, 0, 'k'}, 1736f971622SJuan Castillo {"new-chain", no_argument, 0, 'n'}, 1746f971622SJuan Castillo {"print-cert", no_argument, 0, 'p'}, 1756f971622SJuan Castillo {0, 0, 0, 0} 1766f971622SJuan Castillo }; 1776f971622SJuan Castillo 1786f971622SJuan Castillo static void print_help(const char *cmd) 1796f971622SJuan Castillo { 1806f971622SJuan Castillo int i = 0; 1816f971622SJuan Castillo printf("\n\n"); 1826f971622SJuan Castillo printf("The certificate generation tool loads the binary images and\n" 1836f971622SJuan Castillo "optionally the RSA keys, and outputs the key and content\n" 1846f971622SJuan Castillo "certificates properly signed to implement the chain of trust.\n" 1856f971622SJuan Castillo "If keys are provided, they must be in PEM format.\n" 1866f971622SJuan Castillo "Certificates are generated in DER format.\n"); 1876f971622SJuan Castillo printf("\n"); 1886f971622SJuan Castillo printf("Usage:\n\n"); 1896f971622SJuan Castillo printf(" %s [-hknp] \\\n", cmd); 1906f971622SJuan Castillo for (i = 0; i < NUM_OPTS; i++) { 1916f971622SJuan Castillo printf(" --%s <file> \\\n", long_opt[i].name); 1926f971622SJuan Castillo } 1936f971622SJuan Castillo printf("\n"); 194ccbf890eSJuan Castillo printf("-a Key algorithm: rsa (default), ecdsa\n"); 1956f971622SJuan Castillo printf("-h Print help and exit\n"); 1966f971622SJuan Castillo printf("-k Save key pairs into files. Filenames must be provided\n"); 1976f971622SJuan Castillo printf("-n Generate new key pairs if no key files are provided\n"); 1986f971622SJuan Castillo printf("-p Print the certificates in the standard output\n"); 1996f971622SJuan Castillo printf("\n"); 2006f971622SJuan Castillo 2016f971622SJuan Castillo exit(0); 2026f971622SJuan Castillo } 2036f971622SJuan Castillo 204ccbf890eSJuan Castillo static int get_key_alg(const char *key_alg_str) 205ccbf890eSJuan Castillo { 206ccbf890eSJuan Castillo int i; 207ccbf890eSJuan Castillo 208ccbf890eSJuan Castillo for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) { 209ccbf890eSJuan Castillo if (0 == strcmp(key_alg_str, key_algs_str[i])) { 210ccbf890eSJuan Castillo return i; 211ccbf890eSJuan Castillo } 212ccbf890eSJuan Castillo } 213ccbf890eSJuan Castillo 214ccbf890eSJuan Castillo return -1; 215ccbf890eSJuan Castillo } 216ccbf890eSJuan Castillo 2176f971622SJuan Castillo static void check_cmd_params(void) 2186f971622SJuan Castillo { 219*dfc90e26SJuan Castillo cert_t *cert; 220*dfc90e26SJuan Castillo ext_t *ext; 221*dfc90e26SJuan Castillo key_t *key; 222*dfc90e26SJuan Castillo int i, j; 223*dfc90e26SJuan Castillo 224ccbf890eSJuan Castillo /* Only save new keys */ 225ccbf890eSJuan Castillo if (save_keys && !new_keys) { 226ccbf890eSJuan Castillo ERROR("Only new keys can be saved to disk\n"); 227ccbf890eSJuan Castillo exit(1); 228ccbf890eSJuan Castillo } 229ccbf890eSJuan Castillo 230*dfc90e26SJuan Castillo /* Check that all required options have been specified in the 231*dfc90e26SJuan Castillo * command line */ 232*dfc90e26SJuan Castillo for (i = 0; i < num_certs; i++) { 233*dfc90e26SJuan Castillo cert = &certs[i]; 234*dfc90e26SJuan Castillo if (cert->fn == NULL) { 235*dfc90e26SJuan Castillo /* Certificate not requested. Skip to the next one */ 236*dfc90e26SJuan Castillo continue; 237*dfc90e26SJuan Castillo } 238*dfc90e26SJuan Castillo 239*dfc90e26SJuan Castillo /* Check that all parameters required to create this certificate 240*dfc90e26SJuan Castillo * have been specified in the command line */ 241*dfc90e26SJuan Castillo for (j = 0; j < cert->num_ext; j++) { 242*dfc90e26SJuan Castillo ext = &extensions[cert->ext[j]]; 243*dfc90e26SJuan Castillo switch (ext->type) { 244*dfc90e26SJuan Castillo case EXT_TYPE_PKEY: 245*dfc90e26SJuan Castillo /* Key filename must be specified */ 246*dfc90e26SJuan Castillo key = &keys[ext->data.key]; 247*dfc90e26SJuan Castillo if (!new_keys && key->fn == NULL) { 248*dfc90e26SJuan Castillo ERROR("Key '%s' required by '%s' not " 249*dfc90e26SJuan Castillo "specified\n", key->desc, 250*dfc90e26SJuan Castillo cert->cn); 2516f971622SJuan Castillo exit(1); 2526f971622SJuan Castillo } 253*dfc90e26SJuan Castillo break; 254*dfc90e26SJuan Castillo case EXT_TYPE_HASH: 255*dfc90e26SJuan Castillo /* Binary image must be specified */ 256*dfc90e26SJuan Castillo if (ext->data.fn == NULL) { 257*dfc90e26SJuan Castillo ERROR("Image for '%s' not specified\n", 258*dfc90e26SJuan Castillo ext->ln); 2596f971622SJuan Castillo exit(1); 2606f971622SJuan Castillo } 261*dfc90e26SJuan Castillo break; 262*dfc90e26SJuan Castillo default: 263*dfc90e26SJuan Castillo ERROR("Unknown extension type in '%s'\n", 264*dfc90e26SJuan Castillo ext->ln); 2656f971622SJuan Castillo exit(1); 266*dfc90e26SJuan Castillo break; 2676f971622SJuan Castillo } 2686f971622SJuan Castillo } 2696f971622SJuan Castillo } 2706f971622SJuan Castillo } 2716f971622SJuan Castillo 2726f971622SJuan Castillo int main(int argc, char *argv[]) 2736f971622SJuan Castillo { 2746f971622SJuan Castillo STACK_OF(X509_EXTENSION) * sk = NULL; 27555e291a4SJuan Castillo X509_EXTENSION *cert_ext = NULL; 27655e291a4SJuan Castillo ext_t *ext = NULL; 27755e291a4SJuan Castillo cert_t *cert; 2786f971622SJuan Castillo FILE *file = NULL; 27955e291a4SJuan Castillo int i, j, ext_nid; 2806f971622SJuan Castillo int c, opt_idx = 0; 281ccbf890eSJuan Castillo unsigned int err_code; 2826f971622SJuan Castillo unsigned char md[SHA256_DIGEST_LENGTH]; 283c3da66b1SJuan Castillo const EVP_MD *md_info; 2846f971622SJuan Castillo 2856f971622SJuan Castillo NOTICE("CoT Generation Tool: %s\n", build_msg); 2866f971622SJuan Castillo NOTICE("Target platform: %s\n", platform_msg); 2876f971622SJuan Castillo 288ccbf890eSJuan Castillo /* Set default options */ 289ccbf890eSJuan Castillo key_alg = KEY_ALG_RSA; 290ccbf890eSJuan Castillo 2916f971622SJuan Castillo while (1) { 2926f971622SJuan Castillo /* getopt_long stores the option index here. */ 293ccbf890eSJuan Castillo c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx); 2946f971622SJuan Castillo 2956f971622SJuan Castillo /* Detect the end of the options. */ 2966f971622SJuan Castillo if (c == -1) { 2976f971622SJuan Castillo break; 2986f971622SJuan Castillo } 2996f971622SJuan Castillo 3006f971622SJuan Castillo switch (c) { 301ccbf890eSJuan Castillo case 'a': 302ccbf890eSJuan Castillo key_alg = get_key_alg(optarg); 303ccbf890eSJuan Castillo if (key_alg < 0) { 304ccbf890eSJuan Castillo ERROR("Invalid key algorithm '%s'\n", optarg); 305ccbf890eSJuan Castillo exit(1); 306ccbf890eSJuan Castillo } 307ccbf890eSJuan Castillo break; 3086f971622SJuan Castillo case 'h': 3096f971622SJuan Castillo print_help(argv[0]); 3106f971622SJuan Castillo break; 3116f971622SJuan Castillo case 'k': 3126f971622SJuan Castillo save_keys = 1; 3136f971622SJuan Castillo break; 3146f971622SJuan Castillo case 'n': 3156f971622SJuan Castillo new_keys = 1; 3166f971622SJuan Castillo break; 3176f971622SJuan Castillo case 'p': 3186f971622SJuan Castillo print_cert = 1; 3196f971622SJuan Castillo break; 3206f971622SJuan Castillo case BL2_ID: 32155e291a4SJuan Castillo extensions[BL2_HASH_EXT].data.fn = strdup(optarg); 3226f971622SJuan Castillo break; 3236f971622SJuan Castillo case BL30_ID: 32455e291a4SJuan Castillo extensions[BL30_HASH_EXT].data.fn = strdup(optarg); 3256f971622SJuan Castillo break; 3266f971622SJuan Castillo case BL31_ID: 32755e291a4SJuan Castillo extensions[BL31_HASH_EXT].data.fn = strdup(optarg); 3286f971622SJuan Castillo break; 3296f971622SJuan Castillo case BL32_ID: 33055e291a4SJuan Castillo extensions[BL32_HASH_EXT].data.fn = strdup(optarg); 3316f971622SJuan Castillo break; 3326f971622SJuan Castillo case BL33_ID: 33355e291a4SJuan Castillo extensions[BL33_HASH_EXT].data.fn = strdup(optarg); 3346f971622SJuan Castillo break; 3356f971622SJuan Castillo case BL2_CERT_ID: 3366f971622SJuan Castillo certs[BL2_CERT].fn = strdup(optarg); 3376f971622SJuan Castillo break; 3386f971622SJuan Castillo case TRUSTED_KEY_CERT_ID: 3396f971622SJuan Castillo certs[TRUSTED_KEY_CERT].fn = strdup(optarg); 3406f971622SJuan Castillo break; 3416f971622SJuan Castillo case BL30_KEY_CERT_ID: 3426f971622SJuan Castillo certs[BL30_KEY_CERT].fn = strdup(optarg); 3436f971622SJuan Castillo break; 3446f971622SJuan Castillo case BL30_CERT_ID: 3456f971622SJuan Castillo certs[BL30_CERT].fn = strdup(optarg); 3466f971622SJuan Castillo break; 3476f971622SJuan Castillo case BL31_KEY_CERT_ID: 3486f971622SJuan Castillo certs[BL31_KEY_CERT].fn = strdup(optarg); 3496f971622SJuan Castillo break; 3506f971622SJuan Castillo case BL31_CERT_ID: 3516f971622SJuan Castillo certs[BL31_CERT].fn = strdup(optarg); 3526f971622SJuan Castillo break; 3536f971622SJuan Castillo case BL32_KEY_CERT_ID: 3546f971622SJuan Castillo certs[BL32_KEY_CERT].fn = strdup(optarg); 3556f971622SJuan Castillo break; 3566f971622SJuan Castillo case BL32_CERT_ID: 3576f971622SJuan Castillo certs[BL32_CERT].fn = strdup(optarg); 3586f971622SJuan Castillo break; 3596f971622SJuan Castillo case BL33_KEY_CERT_ID: 3606f971622SJuan Castillo certs[BL33_KEY_CERT].fn = strdup(optarg); 3616f971622SJuan Castillo break; 3626f971622SJuan Castillo case BL33_CERT_ID: 3636f971622SJuan Castillo certs[BL33_CERT].fn = strdup(optarg); 3646f971622SJuan Castillo break; 3656f971622SJuan Castillo case ROT_KEY_ID: 3666f971622SJuan Castillo keys[ROT_KEY].fn = strdup(optarg); 3676f971622SJuan Castillo break; 3686f971622SJuan Castillo case TRUSTED_WORLD_KEY_ID: 3696f971622SJuan Castillo keys[TRUSTED_WORLD_KEY].fn = strdup(optarg); 3706f971622SJuan Castillo break; 3716f971622SJuan Castillo case NON_TRUSTED_WORLD_KEY_ID: 3726f971622SJuan Castillo keys[NON_TRUSTED_WORLD_KEY].fn = strdup(optarg); 3736f971622SJuan Castillo break; 3746f971622SJuan Castillo case BL30_KEY_ID: 3756f971622SJuan Castillo keys[BL30_KEY].fn = strdup(optarg); 3766f971622SJuan Castillo break; 3776f971622SJuan Castillo case BL31_KEY_ID: 3786f971622SJuan Castillo keys[BL31_KEY].fn = strdup(optarg); 3796f971622SJuan Castillo break; 3806f971622SJuan Castillo case BL32_KEY_ID: 3816f971622SJuan Castillo keys[BL32_KEY].fn = strdup(optarg); 3826f971622SJuan Castillo break; 3836f971622SJuan Castillo case BL33_KEY_ID: 3846f971622SJuan Castillo keys[BL33_KEY].fn = strdup(optarg); 3856f971622SJuan Castillo break; 3866f971622SJuan Castillo case '?': 3876f971622SJuan Castillo default: 3886f971622SJuan Castillo printf("%s\n", optarg); 3896f971622SJuan Castillo exit(1); 3906f971622SJuan Castillo } 3916f971622SJuan Castillo } 3926f971622SJuan Castillo 3936f971622SJuan Castillo /* Check command line arguments */ 3946f971622SJuan Castillo check_cmd_params(); 3956f971622SJuan Castillo 3966f971622SJuan Castillo /* Register the new types and OIDs for the extensions */ 39755e291a4SJuan Castillo if (ext_register(extensions) != 0) { 39855e291a4SJuan Castillo ERROR("Cannot register TBB extensions\n"); 3996f971622SJuan Castillo exit(1); 4006f971622SJuan Castillo } 4016f971622SJuan Castillo 402c3da66b1SJuan Castillo /* Indicate SHA256 as image hash algorithm in the certificate 403c3da66b1SJuan Castillo * extension */ 404c3da66b1SJuan Castillo md_info = EVP_sha256(); 405c3da66b1SJuan Castillo 4066f971622SJuan Castillo /* Load private keys from files (or generate new ones) */ 40755e291a4SJuan Castillo for (i = 0 ; i < num_keys ; i++) { 408ccbf890eSJuan Castillo /* First try to load the key from disk */ 409ccbf890eSJuan Castillo if (key_load(&keys[i], &err_code)) { 410ccbf890eSJuan Castillo /* Key loaded successfully */ 411ccbf890eSJuan Castillo continue; 412ccbf890eSJuan Castillo } 413ccbf890eSJuan Castillo 414ccbf890eSJuan Castillo /* Key not loaded. Check the error code */ 415ccbf890eSJuan Castillo if (err_code == KEY_ERR_MALLOC) { 416ccbf890eSJuan Castillo /* Cannot allocate memory. Abort. */ 417ccbf890eSJuan Castillo ERROR("Malloc error while loading '%s'\n", keys[i].fn); 418ccbf890eSJuan Castillo exit(1); 419ccbf890eSJuan Castillo } else if (err_code == KEY_ERR_LOAD) { 420ccbf890eSJuan Castillo /* File exists, but it does not contain a valid private 421ccbf890eSJuan Castillo * key. Abort. */ 422ccbf890eSJuan Castillo ERROR("Error loading '%s'\n", keys[i].fn); 4236f971622SJuan Castillo exit(1); 4246f971622SJuan Castillo } 425ccbf890eSJuan Castillo 426ccbf890eSJuan Castillo /* File does not exist, could not be opened or no filename was 427ccbf890eSJuan Castillo * given */ 428ccbf890eSJuan Castillo if (new_keys) { 429ccbf890eSJuan Castillo /* Try to create a new key */ 430ccbf890eSJuan Castillo NOTICE("Creating new key for '%s'\n", keys[i].desc); 431ccbf890eSJuan Castillo if (!key_create(&keys[i], key_alg)) { 432ccbf890eSJuan Castillo ERROR("Error creating key '%s'\n", keys[i].desc); 433ccbf890eSJuan Castillo exit(1); 4346f971622SJuan Castillo } 4356f971622SJuan Castillo } else { 436ccbf890eSJuan Castillo if (err_code == KEY_ERR_OPEN) { 437ccbf890eSJuan Castillo ERROR("Error opening '%s'\n", keys[i].fn); 438ccbf890eSJuan Castillo } else { 439ccbf890eSJuan Castillo ERROR("Key '%s' not specified\n", keys[i].desc); 4406f971622SJuan Castillo } 441ccbf890eSJuan Castillo exit(1); 4426f971622SJuan Castillo } 4436f971622SJuan Castillo } 4446f971622SJuan Castillo 44555e291a4SJuan Castillo /* Create the certificates */ 44655e291a4SJuan Castillo for (i = 0 ; i < num_certs ; i++) { 44755e291a4SJuan Castillo 44855e291a4SJuan Castillo cert = &certs[i]; 44955e291a4SJuan Castillo 45055e291a4SJuan Castillo /* Create a new stack of extensions. This stack will be used 45155e291a4SJuan Castillo * to create the certificate */ 4526f971622SJuan Castillo CHECK_NULL(sk, sk_X509_EXTENSION_new_null()); 4536f971622SJuan Castillo 45455e291a4SJuan Castillo for (j = 0 ; j < cert->num_ext ; j++) { 4556f971622SJuan Castillo 45655e291a4SJuan Castillo ext = &extensions[cert->ext[j]]; 45755e291a4SJuan Castillo 45855e291a4SJuan Castillo /* Get OpenSSL internal ID for this extension */ 45955e291a4SJuan Castillo CHECK_OID(ext_nid, ext->oid); 46055e291a4SJuan Castillo 46155e291a4SJuan Castillo /* 46255e291a4SJuan Castillo * Three types of extensions are currently supported: 46355e291a4SJuan Castillo * - EXT_TYPE_NVCOUNTER 46455e291a4SJuan Castillo * - EXT_TYPE_HASH 46555e291a4SJuan Castillo * - EXT_TYPE_PKEY 46655e291a4SJuan Castillo */ 46755e291a4SJuan Castillo switch (ext->type) { 46855e291a4SJuan Castillo case EXT_TYPE_NVCOUNTER: 46955e291a4SJuan Castillo CHECK_NULL(cert_ext, ext_new_nvcounter(ext_nid, 47055e291a4SJuan Castillo EXT_CRIT, ext->data.nvcounter)); 47155e291a4SJuan Castillo break; 47255e291a4SJuan Castillo case EXT_TYPE_HASH: 47355e291a4SJuan Castillo if (ext->data.fn == NULL) { 47455e291a4SJuan Castillo break; 47555e291a4SJuan Castillo } 47655e291a4SJuan Castillo if (!sha_file(ext->data.fn, md)) { 47755e291a4SJuan Castillo ERROR("Cannot calculate hash of %s\n", 47855e291a4SJuan Castillo ext->data.fn); 4796f971622SJuan Castillo exit(1); 4806f971622SJuan Castillo } 48155e291a4SJuan Castillo CHECK_NULL(cert_ext, ext_new_hash(ext_nid, 48255e291a4SJuan Castillo EXT_CRIT, md_info, md, 4836f971622SJuan Castillo SHA256_DIGEST_LENGTH)); 48455e291a4SJuan Castillo break; 48555e291a4SJuan Castillo case EXT_TYPE_PKEY: 48655e291a4SJuan Castillo CHECK_NULL(cert_ext, ext_new_key(ext_nid, 48755e291a4SJuan Castillo EXT_CRIT, keys[ext->data.key].key)); 48855e291a4SJuan Castillo break; 48955e291a4SJuan Castillo default: 49055e291a4SJuan Castillo ERROR("Unknown extension type in %s\n", 49155e291a4SJuan Castillo cert->cn); 49255e291a4SJuan Castillo exit(1); 49355e291a4SJuan Castillo } 49455e291a4SJuan Castillo 49555e291a4SJuan Castillo /* Push the extension into the stack */ 49655e291a4SJuan Castillo sk_X509_EXTENSION_push(sk, cert_ext); 49755e291a4SJuan Castillo } 4986f971622SJuan Castillo 4996f971622SJuan Castillo /* Create certificate. Signed with ROT key */ 500*dfc90e26SJuan Castillo if (cert->fn && !cert_new(cert, VAL_DAYS, 0, sk)) { 50155e291a4SJuan Castillo ERROR("Cannot create %s\n", cert->cn); 5026f971622SJuan Castillo exit(1); 5036f971622SJuan Castillo } 5046f971622SJuan Castillo 5056f971622SJuan Castillo sk_X509_EXTENSION_free(sk); 5066f971622SJuan Castillo } 5076f971622SJuan Castillo 5086f971622SJuan Castillo 5096f971622SJuan Castillo /* Print the certificates */ 5106f971622SJuan Castillo if (print_cert) { 51155e291a4SJuan Castillo for (i = 0 ; i < num_certs ; i++) { 5126f971622SJuan Castillo if (!certs[i].x) { 5136f971622SJuan Castillo continue; 5146f971622SJuan Castillo } 5156f971622SJuan Castillo printf("\n\n=====================================\n\n"); 5166f971622SJuan Castillo X509_print_fp(stdout, certs[i].x); 5176f971622SJuan Castillo } 5186f971622SJuan Castillo } 5196f971622SJuan Castillo 5206f971622SJuan Castillo /* Save created certificates to files */ 52155e291a4SJuan Castillo for (i = 0 ; i < num_certs ; i++) { 5226f971622SJuan Castillo if (certs[i].x && certs[i].fn) { 5236f971622SJuan Castillo file = fopen(certs[i].fn, "w"); 5246f971622SJuan Castillo if (file != NULL) { 5256f971622SJuan Castillo i2d_X509_fp(file, certs[i].x); 5266f971622SJuan Castillo fclose(file); 5276f971622SJuan Castillo } else { 5286f971622SJuan Castillo ERROR("Cannot create file %s\n", certs[i].fn); 5296f971622SJuan Castillo } 5306f971622SJuan Castillo } 5316f971622SJuan Castillo } 5326f971622SJuan Castillo 5336f971622SJuan Castillo /* Save keys */ 5346f971622SJuan Castillo if (save_keys) { 53555e291a4SJuan Castillo for (i = 0 ; i < num_keys ; i++) { 5366f971622SJuan Castillo if (!key_store(&keys[i])) { 5376f971622SJuan Castillo ERROR("Cannot save %s\n", keys[i].desc); 5386f971622SJuan Castillo } 5396f971622SJuan Castillo } 5406f971622SJuan Castillo } 5416f971622SJuan Castillo 5426f971622SJuan Castillo #ifndef OPENSSL_NO_ENGINE 5436f971622SJuan Castillo ENGINE_cleanup(); 5446f971622SJuan Castillo #endif 5456f971622SJuan Castillo CRYPTO_cleanup_all_ex_data(); 5466f971622SJuan Castillo 5476f971622SJuan Castillo return 0; 5486f971622SJuan Castillo } 549