10a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden/* 20a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * Copyright 2014 The Android Open Source Project 30a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * 40a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * Licensed under the Apache License, Version 2.0 (the "License"); 50a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * you may not use this file except in compliance with the License. 60a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * You may obtain a copy of the License at 70a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * 80a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * http://www.apache.org/licenses/LICENSE-2.0 90a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * 100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * Unless required by applicable law or agreed to in writing, software 110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * distributed under the License is distributed on an "AS IS" BASIS, 120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * See the License for the specific language governing permissions and 140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden * limitations under the License. 150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden */ 160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <openssl/evp.h> 180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <openssl/x509.h> 190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <keymaster/key_blob.h> 210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include <keymaster/keymaster_defs.h> 220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "asymmetric_key.h" 240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "dsa_operation.h" 250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "ecdsa_operation.h" 260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "openssl_utils.h" 270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden#include "rsa_operation.h" 280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdennamespace keymaster { 300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenconst uint32_t RSA_DEFAULT_KEY_SIZE = 2048; 320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenconst uint64_t RSA_DEFAULT_EXPONENT = 65537; 330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenconst uint32_t DSA_DEFAULT_KEY_SIZE = 2048; 350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenconst uint32_t ECDSA_DEFAULT_KEY_SIZE = 192; 370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t AsymmetricKey::LoadKey(const KeyBlob& blob) { 390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete> evp_key(EVP_PKEY_new()); 400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (evp_key.get() == NULL) 410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden EVP_PKEY* tmp_pkey = evp_key.get(); 440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden const uint8_t* key_material = blob.key_material(); 450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (d2i_PrivateKey(evp_key_type(), &tmp_pkey, &key_material, blob.key_material_length()) == 460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden NULL) { 470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_INVALID_KEY_BLOB; 480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!EvpToInternal(evp_key.get())) 500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t AsymmetricKey::key_material(UniquePtr<uint8_t[]>* material, size_t* size) const { 560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (material == NULL || size == NULL) 570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OUTPUT_PARAMETER_NULL; 580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new()); 600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (pkey.get() == NULL) 610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!InternalToEvp(pkey.get())) 640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *size = i2d_PrivateKey(pkey.get(), NULL /* key_data*/); 670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (*size <= 0) 680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 700a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden material->reset(new uint8_t[*size]); 710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint8_t* tmp = material->get(); 720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden i2d_PrivateKey(pkey.get(), &tmp); 730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 750a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 760a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 770a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t AsymmetricKey::formatted_key_material(keymaster_key_format_t format, 780a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<uint8_t[]>* material, 790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden size_t* size) const { 800a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (format != KM_KEY_FORMAT_X509) 810a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNSUPPORTED_KEY_FORMAT; 820a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 830a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (material == NULL || size == NULL) 840a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OUTPUT_PARAMETER_NULL; 850a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 860a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new()); 870a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!InternalToEvp(pkey.get())) 880a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 890a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 900a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden int key_data_length = i2d_PUBKEY(pkey.get(), NULL); 910a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (key_data_length <= 0) 920a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 940a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden material->reset(new uint8_t[key_data_length]); 950a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (material->get() == NULL) 960a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 970a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 980a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint8_t* tmp = material->get(); 990a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (i2d_PUBKEY(pkey.get(), &tmp) != key_data_length) { 1000a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden material->reset(); 1010a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNKNOWN_ERROR; 1020a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1030a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1040a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *size = key_data_length; 1050a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 1060a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1070a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1080a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenOperation* AsymmetricKey::CreateOperation(keymaster_purpose_t purpose, keymaster_error_t* error) { 1090a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_digest_t digest; 1100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!authorizations().GetTagValue(TAG_DIGEST, &digest) || digest != KM_DIGEST_NONE) { 1110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNSUPPORTED_DIGEST; 1120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 1130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_padding_t padding; 1160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!authorizations().GetTagValue(TAG_PADDING, &padding) || padding != KM_PAD_NONE) { 1170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNSUPPORTED_PADDING_MODE; 1180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 1190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return CreateOperation(purpose, digest, padding, error); 1220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden/* static */ 1250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenRsaKey* RsaKey::GenerateKey(const AuthorizationSet& key_description, const Logger& logger, 1260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_error_t* error) { 1270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!error) 1280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 1290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet authorizations(key_description); 1310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint64_t public_exponent = RSA_DEFAULT_EXPONENT; 1330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!authorizations.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent)) 1340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden authorizations.push_back(Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent)); 1350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint32_t key_size = RSA_DEFAULT_KEY_SIZE; 1370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size)) 1380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden authorizations.push_back(Authorization(TAG_KEY_SIZE, key_size)); 1390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<BIGNUM, BIGNUM_Delete> exponent(BN_new()); 1410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<RSA, RSA_Delete> rsa_key(RSA_new()); 1420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new()); 1430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (rsa_key.get() == NULL || pkey.get() == NULL) { 1440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 1450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 1460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!BN_set_word(exponent.get(), public_exponent) || 1490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden !RSA_generate_key_ex(rsa_key.get(), key_size, exponent.get(), NULL /* callback */)) { 1500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNKNOWN_ERROR; 1510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 1520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden RsaKey* new_key = new RsaKey(rsa_key.release(), authorizations, logger); 1550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = new_key ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED; 1560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return new_key; 1570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 1580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden/* static */ 1600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenRsaKey* RsaKey::ImportKey(const AuthorizationSet& key_description, EVP_PKEY* pkey, 1610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden const Logger& logger, keymaster_error_t* error) { 1620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!error) 1630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 1640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNKNOWN_ERROR; 1650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<RSA, RSA_Delete> rsa_key(EVP_PKEY_get1_RSA(pkey)); 1670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!rsa_key.get()) 1680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 1690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1700a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet authorizations(key_description); 1710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint64_t public_exponent; 1730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (authorizations.GetTagValue(TAG_RSA_PUBLIC_EXPONENT, &public_exponent)) { 1740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // public_exponent specified, make sure it matches the key 1750a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<BIGNUM, BIGNUM_Delete> public_exponent_bn(BN_new()); 1760a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!BN_set_word(public_exponent_bn.get(), public_exponent)) 1770a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 1780a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (BN_cmp(public_exponent_bn.get(), rsa_key->e) != 0) { 1790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH; 1800a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 1810a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1820a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } else { 1830a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // public_exponent not specified, use the one from the key. 1840a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden public_exponent = BN_get_word(rsa_key->e); 1850a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (public_exponent == 0xffffffffL) { 1860a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH; 1870a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 1880a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1890a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden authorizations.push_back(TAG_RSA_PUBLIC_EXPONENT, public_exponent); 1900a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1910a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 1920a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint32_t key_size; 1930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (authorizations.GetTagValue(TAG_KEY_SIZE, &key_size)) { 1940a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // key_size specified, make sure it matches the key. 1950a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (RSA_size(rsa_key.get()) != (int)key_size) { 1960a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH; 1970a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 1980a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 1990a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } else { 2000a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden key_size = RSA_size(rsa_key.get()) * 8; 2010a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden authorizations.push_back(TAG_KEY_SIZE, key_size); 2020a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2030a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2040a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_algorithm_t algorithm; 2050a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (authorizations.GetTagValue(TAG_ALGORITHM, &algorithm)) { 2060a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (algorithm != KM_ALGORITHM_RSA) { 2070a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH; 2080a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 2090a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } else { 2110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden authorizations.push_back(TAG_ALGORITHM, KM_ALGORITHM_RSA); 2120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // Don't bother with the other parameters. If the necessary padding, digest, purpose, etc. are 2150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // missing, the error will be diagnosed when the key is used (when auth checking is 2160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // implemented). 2170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_OK; 2180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return new RsaKey(rsa_key.release(), authorizations, logger); 2190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenRsaKey::RsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error) 2220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden : AsymmetricKey(blob, logger) { 2230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (error) 2240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = LoadKey(blob); 2250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenOperation* RsaKey::CreateOperation(keymaster_purpose_t purpose, keymaster_digest_t digest, 2280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_padding_t padding, keymaster_error_t* error) { 2290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden Operation* op; 2300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (purpose) { 2310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_PURPOSE_SIGN: 232f6ca3a3f1bbe206e2fd05be36da10cb4204e5388Shawn Willden op = new RsaSignOperation(purpose, logger_, digest, padding, rsa_key_.release()); 2330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 2340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_PURPOSE_VERIFY: 235f6ca3a3f1bbe206e2fd05be36da10cb4204e5388Shawn Willden op = new RsaVerifyOperation(purpose, logger_, digest, padding, rsa_key_.release()); 2360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 2370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 2380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNIMPLEMENTED; 2390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 2400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = op ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED; 2420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return op; 2430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenbool RsaKey::EvpToInternal(const EVP_PKEY* pkey) { 2460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden rsa_key_.reset(EVP_PKEY_get1_RSA(const_cast<EVP_PKEY*>(pkey))); 2470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return rsa_key_.get() != NULL; 2480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenbool RsaKey::InternalToEvp(EVP_PKEY* pkey) const { 2510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return EVP_PKEY_set1_RSA(pkey, rsa_key_.get()) == 1; 2520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdentemplate <keymaster_tag_t Tag> 2550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenstatic void GetDsaParamData(const AuthorizationSet& auths, TypedTag<KM_BIGNUM, Tag> tag, 2560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_blob_t* blob) { 2570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!auths.GetTagValue(tag, blob)) 2580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden blob->data = NULL; 2590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden// Store the specified DSA param in auths 2620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdentemplate <keymaster_tag_t Tag> 2630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenstatic void SetDsaParamData(AuthorizationSet* auths, TypedTag<KM_BIGNUM, Tag> tag, BIGNUM* number) { 2640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_blob_t blob; 2650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden convert_bn_to_blob(number, &blob); 2660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden auths->push_back(Authorization(tag, blob)); 2670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden delete[] blob.data; 2680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 2690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2700a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenDsaKey* DsaKey::GenerateKey(const AuthorizationSet& key_description, const Logger& logger, 2710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_error_t* error) { 2720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!error) 2730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 2740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2750a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet authorizations(key_description); 2760a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2770a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_blob_t g_blob; 2780a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden GetDsaParamData(authorizations, TAG_DSA_GENERATOR, &g_blob); 2790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2800a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_blob_t p_blob; 2810a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden GetDsaParamData(authorizations, TAG_DSA_P, &p_blob); 2820a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2830a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_blob_t q_blob; 2840a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden GetDsaParamData(authorizations, TAG_DSA_Q, &q_blob); 2850a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2860a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint32_t key_size = DSA_DEFAULT_KEY_SIZE; 2870a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size)) 2880a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden authorizations.push_back(Authorization(TAG_KEY_SIZE, key_size)); 2890a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2900a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<DSA, DSA_Delete> dsa_key(DSA_new()); 2910a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new()); 2920a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (dsa_key.get() == NULL || pkey.get() == NULL) { 2930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 2940a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 2950a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 2960a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 2970a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // If anything goes wrong in the next section, it's a param problem. 2980a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_INVALID_DSA_PARAMS; 2990a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3000a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (g_blob.data == NULL && p_blob.data == NULL && q_blob.data == NULL) { 3016f0b72fd8b0ea5c52d62dc5853318509b69db076Shawn Willden logger.info("DSA parameters unspecified, generating them for key size %d", key_size); 3020a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!DSA_generate_parameters_ex(dsa_key.get(), key_size, NULL /* seed */, 0 /* seed_len */, 3030a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden NULL /* counter_ret */, NULL /* h_ret */, 3040a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden NULL /* callback */)) { 3056f0b72fd8b0ea5c52d62dc5853318509b69db076Shawn Willden logger.severe("DSA parameter generation failed."); 3060a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3070a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 3080a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3090a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden SetDsaParamData(&authorizations, TAG_DSA_GENERATOR, dsa_key->g); 3100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden SetDsaParamData(&authorizations, TAG_DSA_P, dsa_key->p); 3110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden SetDsaParamData(&authorizations, TAG_DSA_Q, dsa_key->q); 3120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } else if (g_blob.data == NULL || p_blob.data == NULL || q_blob.data == NULL) { 3136f0b72fd8b0ea5c52d62dc5853318509b69db076Shawn Willden logger.severe("Some DSA parameters provided. Provide all or none"); 3140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } else { 3160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // All params provided. Use them. 3170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden dsa_key->g = BN_bin2bn(g_blob.data, g_blob.data_length, NULL); 3180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden dsa_key->p = BN_bin2bn(p_blob.data, p_blob.data_length, NULL); 3190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden dsa_key->q = BN_bin2bn(q_blob.data, q_blob.data_length, NULL); 3200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (dsa_key->g == NULL || dsa_key->p == NULL || dsa_key->q == NULL) { 3220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 3240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 3250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!DSA_generate_key(dsa_key.get())) { 3270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNKNOWN_ERROR; 3280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 3300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden DsaKey* new_key = new DsaKey(dsa_key.release(), authorizations, logger); 3320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = new_key ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED; 3330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return new_key; 3340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 3350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdentemplate <keymaster_tag_t T> 3370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t GetOrCheckDsaParam(TypedTag<KM_BIGNUM, T> tag, BIGNUM* bn, 3380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet* auths) { 3390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_blob_t blob; 3400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (auths->GetTagValue(tag, &blob)) { 3410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // value specified, make sure it matches 3420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<BIGNUM, BIGNUM_Delete> extracted_bn(BN_bin2bn(blob.data, blob.data_length, NULL)); 3430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (extracted_bn.get() == NULL) 3440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_MEMORY_ALLOCATION_FAILED; 3450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (BN_cmp(extracted_bn.get(), bn) != 0) 3460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_IMPORT_PARAMETER_MISMATCH; 3470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } else { 3480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // value not specified, add it 3490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<uint8_t[]> data(new uint8_t[BN_num_bytes(bn)]); 3500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden BN_bn2bin(bn, data.get()); 3510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden auths->push_back(tag, data.get(), BN_num_bytes(bn)); 3520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 3530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 3540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 3550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden/* static */ 3570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdensize_t DsaKey::key_size_bits(DSA* dsa_key) { 3580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // Openssl provides no convenient way to get a DSA key size, but dsa_key->p is L bits long. 3590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // There may be some leading zeros that mess up this calculation, but DSA key sizes are also 3600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // constrained to be multiples of 64 bits. So the key size is the bit length of p rounded up to 3610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // the nearest 64. 3620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return ((BN_num_bytes(dsa_key->p) * 8) + 63) / 64 * 64; 3630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 3640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden/* static */ 3660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenDsaKey* DsaKey::ImportKey(const AuthorizationSet& key_description, EVP_PKEY* pkey, 3670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden const Logger& logger, keymaster_error_t* error) { 3680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!error) 3690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3700a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNKNOWN_ERROR; 3710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<DSA, DSA_Delete> dsa_key(EVP_PKEY_get1_DSA(pkey)); 3730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!dsa_key.get()) 3740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3750a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3760a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet authorizations(key_description); 3770a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3780a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = GetOrCheckDsaParam(TAG_DSA_GENERATOR, dsa_key->g, &authorizations); 3790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (*error != KM_ERROR_OK) 3800a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3810a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3820a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = GetOrCheckDsaParam(TAG_DSA_P, dsa_key->p, &authorizations); 3830a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (*error != KM_ERROR_OK) 3840a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3850a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3860a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = GetOrCheckDsaParam(TAG_DSA_Q, dsa_key->q, &authorizations); 3870a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (*error != KM_ERROR_OK) 3880a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 3890a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3900a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // There's no convenient way to get a DSA key size, but dsa_key->p is L bits long. There may be 3910a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // some leading zeros that mess up this calculation, but DSA key sizes are also constrained to 3920a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // be multiples of 64 bits. So the bit length of p, rounded up to the nearest 64 bits, is the 3930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // key size. 3940a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint32_t extracted_key_size_bits = ((BN_num_bytes(dsa_key->p) * 8) + 63) / 64 * 64; 3950a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 3960a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint32_t key_size_bits; 3970a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (authorizations.GetTagValue(TAG_KEY_SIZE, &key_size_bits)) { 3980a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // key_size_bits specified, make sure it matches the key. 3990a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (key_size_bits != extracted_key_size_bits) { 4000a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH; 4010a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 4020a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4030a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } else { 4040a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // key_size_bits not specified, add it. 4050a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden authorizations.push_back(TAG_KEY_SIZE, extracted_key_size_bits); 4060a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4070a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4080a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_algorithm_t algorithm; 4090a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (authorizations.GetTagValue(TAG_ALGORITHM, &algorithm)) { 4100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (algorithm != KM_ALGORITHM_DSA) { 4110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH; 4120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 4130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } else { 4150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden authorizations.push_back(TAG_ALGORITHM, KM_ALGORITHM_DSA); 4160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // Don't bother with the other parameters. If the necessary padding, digest, purpose, etc. are 4190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // missing, the error will be diagnosed when the key is used (when auth checking is 4200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // implemented). 4210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_OK; 4220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return new DsaKey(dsa_key.release(), authorizations, logger); 4230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenDsaKey::DsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error) 4260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden : AsymmetricKey(blob, logger) { 4270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (error) 4280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = LoadKey(blob); 4290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenOperation* DsaKey::CreateOperation(keymaster_purpose_t purpose, keymaster_digest_t digest, 4320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_padding_t padding, keymaster_error_t* error) { 4330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden Operation* op; 4340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (purpose) { 4350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_PURPOSE_SIGN: 436f6ca3a3f1bbe206e2fd05be36da10cb4204e5388Shawn Willden op = new DsaSignOperation(purpose, logger_, digest, padding, dsa_key_.release()); 4370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 4380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_PURPOSE_VERIFY: 439f6ca3a3f1bbe206e2fd05be36da10cb4204e5388Shawn Willden op = new DsaVerifyOperation(purpose, logger_, digest, padding, dsa_key_.release()); 4400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 4410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 4420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNIMPLEMENTED; 4430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 4440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = op ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED; 4460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return op; 4470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenbool DsaKey::EvpToInternal(const EVP_PKEY* pkey) { 4500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden dsa_key_.reset(EVP_PKEY_get1_DSA(const_cast<EVP_PKEY*>(pkey))); 4510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return dsa_key_.get() != NULL; 4520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenbool DsaKey::InternalToEvp(EVP_PKEY* pkey) const { 4550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return EVP_PKEY_set1_DSA(pkey, dsa_key_.get()) == 1; 4560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden/* static */ 4590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenEcdsaKey* EcdsaKey::GenerateKey(const AuthorizationSet& key_description, const Logger& logger, 4600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_error_t* error) { 4610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!error) 4620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 4630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet authorizations(key_description); 4650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint32_t key_size = ECDSA_DEFAULT_KEY_SIZE; 4670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!authorizations.GetTagValue(TAG_KEY_SIZE, &key_size)) 4680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden authorizations.push_back(Authorization(TAG_KEY_SIZE, key_size)); 4690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4700a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<EC_KEY, ECDSA_Delete> ecdsa_key(EC_KEY_new()); 4710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<EVP_PKEY, EVP_PKEY_Delete> pkey(EVP_PKEY_new()); 4720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (ecdsa_key.get() == NULL || pkey.get() == NULL) { 4730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_MEMORY_ALLOCATION_FAILED; 4740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 4750a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4760a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4770a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<EC_GROUP, EC_GROUP_Delete> group(choose_group(key_size)); 4780a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (group.get() == NULL) { 4790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // Technically, could also have been a memory allocation problem. 4800a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNSUPPORTED_KEY_SIZE; 4810a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 4820a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4830a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4840a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden EC_GROUP_set_point_conversion_form(group.get(), POINT_CONVERSION_UNCOMPRESSED); 4850a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE); 4860a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4870a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (EC_KEY_set_group(ecdsa_key.get(), group.get()) != 1 || 4880a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden EC_KEY_generate_key(ecdsa_key.get()) != 1 || EC_KEY_check_key(ecdsa_key.get()) < 0) { 4890a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNKNOWN_ERROR; 4900a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 4910a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 4920a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden EcdsaKey* new_key = new EcdsaKey(ecdsa_key.release(), authorizations, logger); 4940a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = new_key ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED; 4950a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return new_key; 4960a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 4970a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 4980a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden/* static */ 4990a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenEcdsaKey* EcdsaKey::ImportKey(const AuthorizationSet& key_description, EVP_PKEY* pkey, 5000a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden const Logger& logger, keymaster_error_t* error) { 5010a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!error) 5020a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 5030a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNKNOWN_ERROR; 5040a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 5050a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden UniquePtr<EC_KEY, ECDSA_Delete> ecdsa_key(EVP_PKEY_get1_EC_KEY(pkey)); 5060a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (!ecdsa_key.get()) 5070a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 5080a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 5090a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden AuthorizationSet authorizations(key_description); 5100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 5110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden size_t extracted_key_size_bits; 5120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = get_group_size(*EC_KEY_get0_group(ecdsa_key.get()), &extracted_key_size_bits); 5130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (*error != KM_ERROR_OK) 5140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 5150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 5160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden uint32_t key_size_bits; 5170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (authorizations.GetTagValue(TAG_KEY_SIZE, &key_size_bits)) { 5180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // key_size_bits specified, make sure it matches the key. 5190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (key_size_bits != extracted_key_size_bits) { 5200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH; 5210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 5220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 5230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } else { 5240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // key_size_bits not specified, add it. 5250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden authorizations.push_back(TAG_KEY_SIZE, extracted_key_size_bits); 5260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 5270a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 5280a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_algorithm_t algorithm; 5290a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (authorizations.GetTagValue(TAG_ALGORITHM, &algorithm)) { 5300a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (algorithm != KM_ALGORITHM_ECDSA) { 5310a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_IMPORT_PARAMETER_MISMATCH; 5320a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 5330a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 5340a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } else { 5350a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden authorizations.push_back(TAG_ALGORITHM, KM_ALGORITHM_ECDSA); 5360a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 5370a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 5380a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // Don't bother with the other parameters. If the necessary padding, digest, purpose, etc. are 5390a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // missing, the error will be diagnosed when the key is used (when auth checking is 5400a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden // implemented). 5410a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_OK; 5420a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return new EcdsaKey(ecdsa_key.release(), authorizations, logger); 5430a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 5440a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 5450a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden/* static */ 5460a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenEC_GROUP* EcdsaKey::choose_group(size_t key_size_bits) { 5470a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (key_size_bits) { 5480a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case 192: 5490a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return EC_GROUP_new_by_curve_name(NID_X9_62_prime192v1); 5500a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 5510a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case 224: 5520a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return EC_GROUP_new_by_curve_name(NID_secp224r1); 5530a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 5540a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case 256: 5550a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); 5560a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 5570a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case 384: 5580a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return EC_GROUP_new_by_curve_name(NID_secp384r1); 5590a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 5600a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case 521: 5610a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return EC_GROUP_new_by_curve_name(NID_secp521r1); 5620a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 5630a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 5640a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 5650a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 5660a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 5670a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 5680a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 5690a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden/* static */ 5700a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenkeymaster_error_t EcdsaKey::get_group_size(const EC_GROUP& group, size_t* key_size_bits) { 5710a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (EC_GROUP_get_curve_name(&group)) { 5720a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case NID_X9_62_prime192v1: 5730a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *key_size_bits = 192; 5740a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 5750a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case NID_secp224r1: 5760a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *key_size_bits = 224; 5770a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 5780a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case NID_X9_62_prime256v1: 5790a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *key_size_bits = 256; 5800a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 5810a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case NID_secp384r1: 5820a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *key_size_bits = 384; 5830a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 5840a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case NID_secp521r1: 5850a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *key_size_bits = 521; 5860a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 5870a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 5880a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_UNSUPPORTED_EC_FIELD; 5890a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 5900a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return KM_ERROR_OK; 5910a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 5920a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 5930a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenEcdsaKey::EcdsaKey(const KeyBlob& blob, const Logger& logger, keymaster_error_t* error) 5940a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden : AsymmetricKey(blob, logger) { 5950a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden if (error) 5960a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = LoadKey(blob); 5970a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 5980a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 5990a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn WilldenOperation* EcdsaKey::CreateOperation(keymaster_purpose_t purpose, keymaster_digest_t digest, 6000a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden keymaster_padding_t padding, keymaster_error_t* error) { 6010a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden Operation* op; 6020a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden switch (purpose) { 6030a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_PURPOSE_SIGN: 604f6ca3a3f1bbe206e2fd05be36da10cb4204e5388Shawn Willden op = new EcdsaSignOperation(purpose, logger_, digest, padding, ecdsa_key_.release()); 6050a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 6060a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden case KM_PURPOSE_VERIFY: 607f6ca3a3f1bbe206e2fd05be36da10cb4204e5388Shawn Willden op = new EcdsaVerifyOperation(purpose, logger_, digest, padding, ecdsa_key_.release()); 6080a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden break; 6090a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden default: 6100a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = KM_ERROR_UNIMPLEMENTED; 6110a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return NULL; 6120a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden } 6130a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden *error = op ? KM_ERROR_OK : KM_ERROR_MEMORY_ALLOCATION_FAILED; 6140a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return op; 6150a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 6160a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 6170a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenbool EcdsaKey::EvpToInternal(const EVP_PKEY* pkey) { 6180a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden ecdsa_key_.reset(EVP_PKEY_get1_EC_KEY(const_cast<EVP_PKEY*>(pkey))); 6190a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return ecdsa_key_.get() != NULL; 6200a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 6210a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 6220a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willdenbool EcdsaKey::InternalToEvp(EVP_PKEY* pkey) const { 6230a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden return EVP_PKEY_set1_EC_KEY(pkey, ecdsa_key_.get()) == 1; 6240a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} 6250a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden 6260a4df7e3a83a59e4a5abc3f605d7d7e9f636c682Shawn Willden} // namespace keymaster 627