14d306ec792b4348253aa77dff965bff5def1dccbShawn Willden/* 24d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * Copyright 2015 The Android Open Source Project 34d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * 44d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * Licensed under the Apache License, Version 2.0 (the "License"); 54d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * you may not use this file except in compliance with the License. 64d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * You may obtain a copy of the License at 74d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * 84d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * http://www.apache.org/licenses/LICENSE-2.0 94d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * 104d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * Unless required by applicable law or agreed to in writing, software 114d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * distributed under the License is distributed on an "AS IS" BASIS, 124d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * See the License for the specific language governing permissions and 144d306ec792b4348253aa77dff965bff5def1dccbShawn Willden * limitations under the License. 154d306ec792b4348253aa77dff965bff5def1dccbShawn Willden */ 164d306ec792b4348253aa77dff965bff5def1dccbShawn Willden 174d306ec792b4348253aa77dff965bff5def1dccbShawn Willden#include "openssl_utils.h" 184d306ec792b4348253aa77dff965bff5def1dccbShawn Willden 19398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden#include <keymaster/android_keymaster_utils.h> 20398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden 214d306ec792b4348253aa77dff965bff5def1dccbShawn Willden#include "openssl_err.h" 224d306ec792b4348253aa77dff965bff5def1dccbShawn Willden 234d306ec792b4348253aa77dff965bff5def1dccbShawn Willdennamespace keymaster { 244d306ec792b4348253aa77dff965bff5def1dccbShawn Willden 25fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duongkeymaster_error_t ec_get_group_size(const EC_GROUP* group, size_t* key_size_bits) { 26fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong switch (EC_GROUP_get_curve_name(group)) { 27fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong case NID_secp224r1: 28fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong *key_size_bits = 224; 29fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong break; 30fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong case NID_X9_62_prime256v1: 31fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong *key_size_bits = 256; 32fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong break; 33fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong case NID_secp384r1: 34fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong *key_size_bits = 384; 35fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong break; 36fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong case NID_secp521r1: 37fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong *key_size_bits = 521; 38fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong break; 39fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong default: 40fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong return KM_ERROR_UNSUPPORTED_EC_FIELD; 41fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong } 42fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong return KM_ERROR_OK; 43fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong} 44fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong 45fabacaf3e6019804cc8a98a2b8296be1d0125519Thai DuongEC_GROUP* ec_get_group(keymaster_ec_curve_t curve) { 46fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong switch (curve) { 47fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong case KM_EC_CURVE_P_224: 48fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong return EC_GROUP_new_by_curve_name(NID_secp224r1); 49fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong break; 50fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong case KM_EC_CURVE_P_256: 51fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); 52fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong break; 53fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong case KM_EC_CURVE_P_384: 54fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong return EC_GROUP_new_by_curve_name(NID_secp384r1); 55fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong break; 56fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong case KM_EC_CURVE_P_521: 57fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong return EC_GROUP_new_by_curve_name(NID_secp521r1); 58fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong break; 59fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong default: 60fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong return nullptr; 61fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong break; 62fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong } 63fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong} 64fabacaf3e6019804cc8a98a2b8296be1d0125519Thai Duong 654d306ec792b4348253aa77dff965bff5def1dccbShawn Willdenstatic int convert_to_evp(keymaster_algorithm_t algorithm) { 664d306ec792b4348253aa77dff965bff5def1dccbShawn Willden switch (algorithm) { 674d306ec792b4348253aa77dff965bff5def1dccbShawn Willden case KM_ALGORITHM_RSA: 684d306ec792b4348253aa77dff965bff5def1dccbShawn Willden return EVP_PKEY_RSA; 699c65b2bd1978a918b52a459596dafc7dde992416Shawn Willden case KM_ALGORITHM_EC: 704d306ec792b4348253aa77dff965bff5def1dccbShawn Willden return EVP_PKEY_EC; 714d306ec792b4348253aa77dff965bff5def1dccbShawn Willden default: 724d306ec792b4348253aa77dff965bff5def1dccbShawn Willden return -1; 734d306ec792b4348253aa77dff965bff5def1dccbShawn Willden }; 744d306ec792b4348253aa77dff965bff5def1dccbShawn Willden} 754d306ec792b4348253aa77dff965bff5def1dccbShawn Willden 764d306ec792b4348253aa77dff965bff5def1dccbShawn Willdenkeymaster_error_t convert_pkcs8_blob_to_evp(const uint8_t* key_data, size_t key_length, 774d306ec792b4348253aa77dff965bff5def1dccbShawn Willden keymaster_algorithm_t expected_algorithm, 784d306ec792b4348253aa77dff965bff5def1dccbShawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* pkey) { 794d306ec792b4348253aa77dff965bff5def1dccbShawn Willden if (key_data == NULL || key_length <= 0) 804d306ec792b4348253aa77dff965bff5def1dccbShawn Willden return KM_ERROR_INVALID_KEY_BLOB; 814d306ec792b4348253aa77dff965bff5def1dccbShawn Willden 824d306ec792b4348253aa77dff965bff5def1dccbShawn Willden UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> pkcs8( 834d306ec792b4348253aa77dff965bff5def1dccbShawn Willden d2i_PKCS8_PRIV_KEY_INFO(NULL, &key_data, key_length)); 844d306ec792b4348253aa77dff965bff5def1dccbShawn Willden if (pkcs8.get() == NULL) 854d306ec792b4348253aa77dff965bff5def1dccbShawn Willden return TranslateLastOpenSslError(true /* log_message */); 864d306ec792b4348253aa77dff965bff5def1dccbShawn Willden 874d306ec792b4348253aa77dff965bff5def1dccbShawn Willden pkey->reset(EVP_PKCS82PKEY(pkcs8.get())); 884d306ec792b4348253aa77dff965bff5def1dccbShawn Willden if (!pkey->get()) 894d306ec792b4348253aa77dff965bff5def1dccbShawn Willden return TranslateLastOpenSslError(true /* log_message */); 904d306ec792b4348253aa77dff965bff5def1dccbShawn Willden 914d306ec792b4348253aa77dff965bff5def1dccbShawn Willden if (EVP_PKEY_type((*pkey)->type) != convert_to_evp(expected_algorithm)) { 924d306ec792b4348253aa77dff965bff5def1dccbShawn Willden LOG_E("EVP key algorithm was %d, not the expected %d", EVP_PKEY_type((*pkey)->type), 934d306ec792b4348253aa77dff965bff5def1dccbShawn Willden convert_to_evp(expected_algorithm)); 944d306ec792b4348253aa77dff965bff5def1dccbShawn Willden return KM_ERROR_INVALID_KEY_BLOB; 954d306ec792b4348253aa77dff965bff5def1dccbShawn Willden } 964d306ec792b4348253aa77dff965bff5def1dccbShawn Willden 974d306ec792b4348253aa77dff965bff5def1dccbShawn Willden return KM_ERROR_OK; 984d306ec792b4348253aa77dff965bff5def1dccbShawn Willden} 994d306ec792b4348253aa77dff965bff5def1dccbShawn Willden 100398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willdenkeymaster_error_t KeyMaterialToEvpKey(keymaster_key_format_t key_format, 101398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden const KeymasterKeyBlob& key_material, 102398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden keymaster_algorithm_t expected_algorithm, 103398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete>* pkey) { 104398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden if (key_format != KM_KEY_FORMAT_PKCS8) 105398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden return KM_ERROR_UNSUPPORTED_KEY_FORMAT; 106398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden 107398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden return convert_pkcs8_blob_to_evp(key_material.key_material, key_material.key_material_size, 108398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden expected_algorithm, pkey); 109398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden} 110398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden 111398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willdenkeymaster_error_t EvpKeyToKeyMaterial(const EVP_PKEY* pkey, KeymasterKeyBlob* key_blob) { 112398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden int key_data_size = i2d_PrivateKey(pkey, NULL /* key_data*/); 113398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden if (key_data_size <= 0) 114398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden return TranslateLastOpenSslError(); 115398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden 1160f906ec40f6ade7955c6b967ea522aade54ea2e4Shawn Willden if (!key_blob->Reset(key_data_size)) 117398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 118398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden 119398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden uint8_t* tmp = key_blob->writable_data(); 120398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden i2d_PrivateKey(pkey, &tmp); 121398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden 122398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden return KM_ERROR_OK; 123398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden} 124398c158a0206217025f327c2d26bb6c86659f5a0Shawn Willden 125d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willdensize_t ec_group_size_bits(EC_KEY* ec_key) { 126d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden const EC_GROUP* group = EC_KEY_get0_group(ec_key); 127d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden UniquePtr<BN_CTX, BN_CTX_Delete> bn_ctx(BN_CTX_new()); 128d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden UniquePtr<BIGNUM, BIGNUM_Delete> order(BN_new()); 129d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden if (!EC_GROUP_get_order(group, order.get(), bn_ctx.get())) { 130d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden LOG_E("Failed to get EC group order", 0); 131d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden return 0; 132d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden } 133d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden return BN_num_bits(order.get()); 134d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden} 135d599b15c0693950bdc72fb867872044fdc484ef5Shawn Willden 1364d306ec792b4348253aa77dff965bff5def1dccbShawn Willden} // namespace keymaster 137