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/evp.h> 386f971622SJuan Castillo #include <openssl/pem.h> 396f971622SJuan Castillo 406f971622SJuan Castillo #include "cert.h" 416f971622SJuan Castillo #include "debug.h" 426f971622SJuan Castillo #include "key.h" 436f971622SJuan Castillo #include "platform_oid.h" 446f971622SJuan Castillo #include "sha.h" 456f971622SJuan Castillo 466f971622SJuan Castillo #define MAX_FILENAME_LEN 1024 476f971622SJuan Castillo 486f971622SJuan Castillo /* 49ccbf890eSJuan Castillo * Create a new key container 506f971622SJuan Castillo */ 51ccbf890eSJuan Castillo static int key_new(key_t *key) 52ccbf890eSJuan Castillo { 53ccbf890eSJuan Castillo /* Create key pair container */ 54ccbf890eSJuan Castillo key->key = EVP_PKEY_new(); 55ccbf890eSJuan Castillo if (key->key == NULL) { 56ccbf890eSJuan Castillo return 0; 57ccbf890eSJuan Castillo } 58ccbf890eSJuan Castillo 59ccbf890eSJuan Castillo return 1; 60ccbf890eSJuan Castillo } 61ccbf890eSJuan Castillo 62*ed2a76eaSJuan Castillo static int key_create_rsa(key_t *key) 636f971622SJuan Castillo { 646f971622SJuan Castillo RSA *rsa = NULL; 656f971622SJuan Castillo 666f971622SJuan Castillo rsa = RSA_generate_key(RSA_KEY_BITS, RSA_F4, NULL, NULL); 67ccbf890eSJuan Castillo if (rsa == NULL) { 68ccbf890eSJuan Castillo printf("Cannot create RSA key\n"); 69ccbf890eSJuan Castillo goto err; 70ccbf890eSJuan Castillo } 71ccbf890eSJuan Castillo if (!EVP_PKEY_assign_RSA(key->key, rsa)) { 726f971622SJuan Castillo printf("Cannot assign RSA key\n"); 73ccbf890eSJuan Castillo goto err; 74ccbf890eSJuan Castillo } 75*ed2a76eaSJuan Castillo 76*ed2a76eaSJuan Castillo return 1; 77*ed2a76eaSJuan Castillo err: 78*ed2a76eaSJuan Castillo RSA_free(rsa); 79*ed2a76eaSJuan Castillo return 0; 80*ed2a76eaSJuan Castillo } 81*ed2a76eaSJuan Castillo 82*ed2a76eaSJuan Castillo #ifndef OPENSSL_NO_EC 83*ed2a76eaSJuan Castillo static int key_create_ecdsa(key_t *key) 84*ed2a76eaSJuan Castillo { 85*ed2a76eaSJuan Castillo EC_KEY *ec = NULL; 86*ed2a76eaSJuan Castillo 87ccbf890eSJuan Castillo ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); 88ccbf890eSJuan Castillo if (ec == NULL) { 89ccbf890eSJuan Castillo printf("Cannot create EC key\n"); 90ccbf890eSJuan Castillo goto err; 91ccbf890eSJuan Castillo } 92ccbf890eSJuan Castillo if (!EC_KEY_generate_key(ec)) { 93ccbf890eSJuan Castillo printf("Cannot generate EC key\n"); 94ccbf890eSJuan Castillo goto err; 95ccbf890eSJuan Castillo } 96ccbf890eSJuan Castillo EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS); 97ccbf890eSJuan Castillo EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE); 98ccbf890eSJuan Castillo if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) { 99ccbf890eSJuan Castillo printf("Cannot assign EC key\n"); 100ccbf890eSJuan Castillo goto err; 101ccbf890eSJuan Castillo } 1026f971622SJuan Castillo 103ccbf890eSJuan Castillo return 1; 104ccbf890eSJuan Castillo err: 105ccbf890eSJuan Castillo EC_KEY_free(ec); 106*ed2a76eaSJuan Castillo return 0; 107*ed2a76eaSJuan Castillo } 108*ed2a76eaSJuan Castillo #endif /* OPENSSL_NO_EC */ 109*ed2a76eaSJuan Castillo 110*ed2a76eaSJuan Castillo typedef int (*key_create_fn_t)(key_t *key); 111*ed2a76eaSJuan Castillo static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = { 112*ed2a76eaSJuan Castillo key_create_rsa, 113*ed2a76eaSJuan Castillo #ifndef OPENSSL_NO_EC 114*ed2a76eaSJuan Castillo key_create_ecdsa, 115*ed2a76eaSJuan Castillo #endif /* OPENSSL_NO_EC */ 116*ed2a76eaSJuan Castillo }; 117*ed2a76eaSJuan Castillo 118*ed2a76eaSJuan Castillo int key_create(key_t *key, int type) 119*ed2a76eaSJuan Castillo { 120*ed2a76eaSJuan Castillo if (type >= KEY_ALG_MAX_NUM) { 121*ed2a76eaSJuan Castillo printf("Invalid key type\n"); 122*ed2a76eaSJuan Castillo return 0; 123*ed2a76eaSJuan Castillo } 124*ed2a76eaSJuan Castillo 125*ed2a76eaSJuan Castillo /* Create OpenSSL key container */ 126*ed2a76eaSJuan Castillo if (!key_new(key)) { 127*ed2a76eaSJuan Castillo return 0; 128*ed2a76eaSJuan Castillo } 129*ed2a76eaSJuan Castillo 130*ed2a76eaSJuan Castillo if (key_create_fn[type]) { 131*ed2a76eaSJuan Castillo return key_create_fn[type](key); 132*ed2a76eaSJuan Castillo } 133ccbf890eSJuan Castillo 1346f971622SJuan Castillo return 0; 1356f971622SJuan Castillo } 1366f971622SJuan Castillo 137ccbf890eSJuan Castillo int key_load(key_t *key, unsigned int *err_code) 1386f971622SJuan Castillo { 1396f971622SJuan Castillo FILE *fp = NULL; 1406f971622SJuan Castillo EVP_PKEY *k = NULL; 1416f971622SJuan Castillo 142ccbf890eSJuan Castillo /* Create OpenSSL key container */ 143ccbf890eSJuan Castillo if (!key_new(key)) { 144ccbf890eSJuan Castillo *err_code = KEY_ERR_MALLOC; 1456f971622SJuan Castillo return 0; 1466f971622SJuan Castillo } 1476f971622SJuan Castillo 1486f971622SJuan Castillo if (key->fn) { 1496f971622SJuan Castillo /* Load key from file */ 1506f971622SJuan Castillo fp = fopen(key->fn, "r"); 1516f971622SJuan Castillo if (fp) { 152ccbf890eSJuan Castillo k = PEM_read_PrivateKey(fp, &key->key, NULL, NULL); 1536f971622SJuan Castillo fclose(fp); 1546f971622SJuan Castillo if (k) { 155ccbf890eSJuan Castillo *err_code = KEY_ERR_NONE; 1566f971622SJuan Castillo return 1; 1576f971622SJuan Castillo } else { 158ccbf890eSJuan Castillo ERROR("Cannot load key from %s\n", key->fn); 159ccbf890eSJuan Castillo *err_code = KEY_ERR_LOAD; 1606f971622SJuan Castillo } 1616f971622SJuan Castillo } else { 162ccbf890eSJuan Castillo WARN("Cannot open file %s\n", key->fn); 163ccbf890eSJuan Castillo *err_code = KEY_ERR_OPEN; 1646f971622SJuan Castillo } 1656f971622SJuan Castillo } else { 166ccbf890eSJuan Castillo WARN("Key filename not specified\n"); 167ccbf890eSJuan Castillo *err_code = KEY_ERR_FILENAME; 1686f971622SJuan Castillo } 1696f971622SJuan Castillo 1706f971622SJuan Castillo return 0; 1716f971622SJuan Castillo } 1726f971622SJuan Castillo 1736f971622SJuan Castillo int key_store(key_t *key) 1746f971622SJuan Castillo { 1756f971622SJuan Castillo FILE *fp = NULL; 1766f971622SJuan Castillo 1776f971622SJuan Castillo if (key->fn) { 1786f971622SJuan Castillo fp = fopen(key->fn, "w"); 1796f971622SJuan Castillo if (fp) { 1806f971622SJuan Castillo PEM_write_PrivateKey(fp, key->key, 1816f971622SJuan Castillo NULL, NULL, 0, NULL, NULL); 1826f971622SJuan Castillo fclose(fp); 1836f971622SJuan Castillo return 1; 1846f971622SJuan Castillo } else { 1856f971622SJuan Castillo ERROR("Cannot create file %s\n", key->fn); 1866f971622SJuan Castillo } 1876f971622SJuan Castillo } else { 1886f971622SJuan Castillo ERROR("Key filename not specified\n"); 1896f971622SJuan Castillo } 1906f971622SJuan Castillo 1916f971622SJuan Castillo return 0; 1926f971622SJuan Castillo } 193