169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// Copyright 2015 The Android Open Source Project 269a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// 369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// Licensed under the Apache License, Version 2.0 (the "License"); 469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// you may not use this file except in compliance with the License. 569a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// You may obtain a copy of the License at 669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// 769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// http://www.apache.org/licenses/LICENSE-2.0 869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// 969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// Unless required by applicable law or agreed to in writing, software 1069a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// distributed under the License is distributed on an "AS IS" BASIS, 1169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1269a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// See the License for the specific language governing permissions and 1369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// limitations under the License. 1469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 15251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn#define LOG_TAG "keystore_client" 16251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn 1769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn#include "keystore/keystore_client_impl.h" 1869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 1969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn#include <string> 2069a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn#include <vector> 2169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 22c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include <binder/IBinder.h> 23c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include <binder/IInterface.h> 24c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include <binder/IServiceManager.h> 25c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include <keystore/IKeystoreService.h> 26c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include <keystore/keystore.h> 27c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include <log/log.h> 28c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include <utils/String16.h> 29c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include <utils/String8.h> 3069a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 31251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn#include "keystore_client.pb.h" 32c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include <keystore/authorization_set.h> 33c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis#include <keystore/keystore_hidl_support.h> 34251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn 3569a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahnusing android::ExportResult; 36c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskisusing keystore::KeyCharacteristics; 3769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahnusing android::OperationResult; 3869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahnusing android::String16; 39c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskisusing keystore::AuthorizationSet; 40c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskisusing keystore::AuthorizationSetBuilder; 4169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 4269a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahnnamespace { 4369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 4469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn// Use the UID of the current process. 4569a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahnconst int kDefaultUID = -1; 46251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahnconst char kEncryptSuffix[] = "_ENC"; 47251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahnconst char kAuthenticateSuffix[] = "_AUTH"; 48c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskisconstexpr uint32_t kAESKeySize = 256; // bits 49c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskisconstexpr uint32_t kHMACKeySize = 256; // bits 50c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskisconstexpr uint32_t kHMACOutputSize = 256; // bits 51c8eca23793dcaf933c4dace4127de710698b7a4cDarren Krahn 5269a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} // namespace 5369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 5469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahnnamespace keystore { 5569a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 5669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren KrahnKeystoreClientImpl::KeystoreClientImpl() { 5769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn service_manager_ = android::defaultServiceManager(); 5869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn keystore_binder_ = service_manager_->getService(String16("android.security.keystore")); 5969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn keystore_ = android::interface_cast<android::IKeystoreService>(keystore_binder_); 6069a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 6169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 62251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahnbool KeystoreClientImpl::encryptWithAuthentication(const std::string& key_name, 63251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn const std::string& data, 64251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn std::string* encrypted_data) { 65251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn // The encryption algorithm is AES-256-CBC with PKCS #7 padding and a random 66251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn // IV. The authentication algorithm is HMAC-SHA256 and is computed over the 67251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn // cipher-text (i.e. Encrypt-then-MAC approach). This was chosen over AES-GCM 68251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn // because hardware support for GCM is not mandatory for all Brillo devices. 69251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn std::string encryption_key_name = key_name + kEncryptSuffix; 70251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (!createOrVerifyEncryptionKey(encryption_key_name)) { 71251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 72251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 73251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn std::string authentication_key_name = key_name + kAuthenticateSuffix; 74251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (!createOrVerifyAuthenticationKey(authentication_key_name)) { 75251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 76251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 77251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSetBuilder encrypt_params; 78c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis encrypt_params.Padding(PaddingMode::PKCS7); 79c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC); 80251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet output_params; 81251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn std::string raw_encrypted_data; 82c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!oneShotOperation(KeyPurpose::ENCRYPT, encryption_key_name, encrypt_params, data, 83251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn std::string(), /* signature_to_verify */ 84251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn &output_params, &raw_encrypted_data)) { 85251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGE("Encrypt: AES operation failed."); 86251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 87251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 88c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto init_vector_blob = output_params.GetTagValue(TAG_NONCE); 89c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!init_vector_blob.isOk()){ 90251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGE("Encrypt: Missing initialization vector."); 91251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 92251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 93c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis std::string init_vector = hidlVec2String(init_vector_blob.value()); 94251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn 95251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSetBuilder authenticate_params; 96c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis authenticate_params.Digest(Digest::SHA_2_256); 97c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis authenticate_params.Authorization(TAG_MAC_LENGTH, kHMACOutputSize); 98251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn std::string raw_authentication_data; 99c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!oneShotOperation(KeyPurpose::SIGN, authentication_key_name, authenticate_params, 100251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn init_vector + raw_encrypted_data, std::string(), /* signature_to_verify */ 101251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn &output_params, &raw_authentication_data)) { 102251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGE("Encrypt: HMAC operation failed."); 103251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 104251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 105251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn EncryptedData protobuf; 106251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn protobuf.set_init_vector(init_vector); 107251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn protobuf.set_authentication_data(raw_authentication_data); 108251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn protobuf.set_encrypted_data(raw_encrypted_data); 109251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (!protobuf.SerializeToString(encrypted_data)) { 110251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGE("Encrypt: Failed to serialize EncryptedData protobuf."); 111251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 112251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 113251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return true; 114251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn} 115251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn 116251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahnbool KeystoreClientImpl::decryptWithAuthentication(const std::string& key_name, 117251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn const std::string& encrypted_data, 118251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn std::string* data) { 119251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn EncryptedData protobuf; 120251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (!protobuf.ParseFromString(encrypted_data)) { 121251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGE("Decrypt: Failed to parse EncryptedData protobuf."); 122251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 123251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn // Verify authentication before attempting decryption. 124251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn std::string authentication_key_name = key_name + kAuthenticateSuffix; 125251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSetBuilder authenticate_params; 126c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis authenticate_params.Digest(Digest::SHA_2_256); 127251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet output_params; 128251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn std::string output_data; 129c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!oneShotOperation(KeyPurpose::VERIFY, authentication_key_name, authenticate_params, 130251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn protobuf.init_vector() + protobuf.encrypted_data(), 131251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn protobuf.authentication_data(), &output_params, &output_data)) { 132251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGE("Decrypt: HMAC operation failed."); 133251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 134251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 135251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn std::string encryption_key_name = key_name + kEncryptSuffix; 136251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSetBuilder encrypt_params; 137c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis encrypt_params.Padding(PaddingMode::PKCS7); 138c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC); 139c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis encrypt_params.Authorization(TAG_NONCE, protobuf.init_vector().data(), 140251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn protobuf.init_vector().size()); 141c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!oneShotOperation(KeyPurpose::DECRYPT, encryption_key_name, encrypt_params, 142251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn protobuf.encrypted_data(), std::string(), /* signature_to_verify */ 143251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn &output_params, data)) { 144251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGE("Decrypt: AES operation failed."); 145251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 146251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 147251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return true; 148251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn} 149251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn 150c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskisbool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string& key_name, 151c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis const AuthorizationSet& input_parameters, 152251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn const std::string& input_data, 153251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn const std::string& signature_to_verify, 154c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis AuthorizationSet* output_parameters, 155251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn std::string* output_data) { 156c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis uint64_t handle; 157c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto result = 158251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn beginOperation(purpose, key_name, input_parameters, output_parameters, &handle); 159c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!result.isOk()) { 160c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis ALOGE("BeginOperation failed: %d", int32_t(result)); 161251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 162251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 163251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet empty_params; 164251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn size_t num_input_bytes_consumed; 165251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet ignored_params; 166251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn result = updateOperation(handle, empty_params, input_data, &num_input_bytes_consumed, 167251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn &ignored_params, output_data); 168c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!result.isOk()) { 169c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis ALOGE("UpdateOperation failed: %d", int32_t(result)); 170251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 171251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 172251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn result = 173251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn finishOperation(handle, empty_params, signature_to_verify, &ignored_params, output_data); 174c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!result.isOk()) { 175c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis ALOGE("FinishOperation failed: %d", int32_t(result)); 176251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 177251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 178251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return true; 179251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn} 180251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn 181c7a9fa29c185a8c1889486d4acf00fd59c513870Janis DanisevskisKeyStoreNativeReturnCode KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy) { 182c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return keystore_->addRngEntropy(blob2hidlVec(entropy)); 18369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 18469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 185c7a9fa29c185a8c1889486d4acf00fd59c513870Janis DanisevskisKeyStoreNativeReturnCode KeystoreClientImpl::generateKey(const std::string& key_name, 18669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn const AuthorizationSet& key_parameters, 18769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn AuthorizationSet* hardware_enforced_characteristics, 18869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn AuthorizationSet* software_enforced_characteristics) { 18969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn String16 key_name16(key_name.data(), key_name.size()); 19069a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn KeyCharacteristics characteristics; 191c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto result = 192c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis keystore_->generateKey(key_name16, key_parameters.hidl_data(), hidl_vec<uint8_t>(), 19369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics); 194c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis 195c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy. 196c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis * There are no references to Parcel memory after that, and ownership of the newly acquired 197c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis * memory is with the AuthorizationSet objects. */ 198c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis *hardware_enforced_characteristics = characteristics.teeEnforced; 199c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis *software_enforced_characteristics = characteristics.softwareEnforced; 200c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return result; 20169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 20269a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 203c7a9fa29c185a8c1889486d4acf00fd59c513870Janis DanisevskisKeyStoreNativeReturnCode 20469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren KrahnKeystoreClientImpl::getKeyCharacteristics(const std::string& key_name, 20569a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn AuthorizationSet* hardware_enforced_characteristics, 20669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn AuthorizationSet* software_enforced_characteristics) { 20769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn String16 key_name16(key_name.data(), key_name.size()); 20869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn KeyCharacteristics characteristics; 209c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto result = keystore_->getKeyCharacteristics(key_name16, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(), 210ce1f913223faf41b5ee2ffba54702b54e17d6606Gaurav Shah kDefaultUID, &characteristics); 211c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis 212c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy. 213c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis * There are no references to Parcel memory after that, and ownership of the newly acquired 214c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis * memory is with the AuthorizationSet objects. */ 215c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis *hardware_enforced_characteristics = characteristics.teeEnforced; 216c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis *software_enforced_characteristics = characteristics.softwareEnforced; 217c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return result; 21869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 21969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 220c7a9fa29c185a8c1889486d4acf00fd59c513870Janis DanisevskisKeyStoreNativeReturnCode KeystoreClientImpl::importKey(const std::string& key_name, 22169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn const AuthorizationSet& key_parameters, 222c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis KeyFormat key_format, 22369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn const std::string& key_data, 22469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn AuthorizationSet* hardware_enforced_characteristics, 22569a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn AuthorizationSet* software_enforced_characteristics) { 22669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn String16 key_name16(key_name.data(), key_name.size()); 227c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto hidlKeyData = blob2hidlVec(key_data); 22869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn KeyCharacteristics characteristics; 229c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto result = keystore_->importKey(key_name16, key_parameters.hidl_data(), key_format, 230c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics); 231c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis 232c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy. 233c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis * There are no references to Parcel memory after that, and ownership of the newly acquired 234c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis * memory is with the AuthorizationSet objects. */ 235c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis *hardware_enforced_characteristics = characteristics.teeEnforced; 236c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis *software_enforced_characteristics = characteristics.softwareEnforced; 237c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return result; 23869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 23969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 240c7a9fa29c185a8c1889486d4acf00fd59c513870Janis DanisevskisKeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format, 24169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn const std::string& key_name, std::string* export_data) { 24269a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn String16 key_name16(key_name.data(), key_name.size()); 24369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn ExportResult export_result; 244c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis keystore_->exportKey(key_name16, export_format, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(), 245ce1f913223faf41b5ee2ffba54702b54e17d6606Gaurav Shah kDefaultUID, &export_result); 246c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis *export_data = hidlVec2String(export_result.exportData); 247c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return export_result.resultCode; 24869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 24969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 250c7a9fa29c185a8c1889486d4acf00fd59c513870Janis DanisevskisKeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) { 25169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn String16 key_name16(key_name.data(), key_name.size()); 252c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return keystore_->del(key_name16, kDefaultUID); 25369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 25469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 255c7a9fa29c185a8c1889486d4acf00fd59c513870Janis DanisevskisKeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() { 256c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return keystore_->clear_uid(kDefaultUID); 25769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 25869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 259c7a9fa29c185a8c1889486d4acf00fd59c513870Janis DanisevskisKeyStoreNativeReturnCode KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name, 26069a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn const AuthorizationSet& input_parameters, 26169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn AuthorizationSet* output_parameters, 262c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis uint64_t* handle) { 26369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn android::sp<android::IBinder> token(new android::BBinder); 26469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn String16 key_name16(key_name.data(), key_name.size()); 26569a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn OperationResult result; 266c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis keystore_->begin(token, key_name16, purpose, true /*pruneable*/, input_parameters.hidl_data(), 267c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis hidl_vec<uint8_t>(), kDefaultUID, &result); 268c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (result.resultCode.isOk()) { 26969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn *handle = getNextVirtualHandle(); 27069a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn active_operations_[*handle] = result.token; 271c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (result.outParams.size()) { 272c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis *output_parameters = result.outParams; 27369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 27469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 275c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return result.resultCode; 27669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 27769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 278c7a9fa29c185a8c1889486d4acf00fd59c513870Janis DanisevskisKeyStoreNativeReturnCode KeystoreClientImpl::updateOperation(uint64_t handle, 27969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn const AuthorizationSet& input_parameters, 28069a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn const std::string& input_data, 28169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn size_t* num_input_bytes_consumed, 28269a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn AuthorizationSet* output_parameters, 28369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn std::string* output_data) { 28469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn if (active_operations_.count(handle) == 0) { 285c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return ErrorCode::INVALID_OPERATION_HANDLE; 28669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 28769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn OperationResult result; 288c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto hidlInputData = blob2hidlVec(input_data); 289c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis keystore_->update(active_operations_[handle], input_parameters.hidl_data(), hidlInputData, 290c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis &result); 291c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis 292c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (result.resultCode.isOk()) { 29369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn *num_input_bytes_consumed = result.inputConsumed; 294c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (result.outParams.size()) { 295c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis *output_parameters = result.outParams; 29669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 297c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis // TODO verify that append should not be assign 298c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis output_data->append(hidlVec2String(result.data)); 29969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 300c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return result.resultCode; 30169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 30269a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 303c7a9fa29c185a8c1889486d4acf00fd59c513870Janis DanisevskisKeyStoreNativeReturnCode KeystoreClientImpl::finishOperation(uint64_t handle, 30469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn const AuthorizationSet& input_parameters, 30569a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn const std::string& signature_to_verify, 30669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn AuthorizationSet* output_parameters, 30769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn std::string* output_data) { 30869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn if (active_operations_.count(handle) == 0) { 309c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return ErrorCode::INVALID_OPERATION_HANDLE; 31069a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 31169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn OperationResult result; 312c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto hidlSignature = blob2hidlVec(signature_to_verify); 313c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis keystore_->finish(active_operations_[handle], input_parameters.hidl_data(), 314c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis hidlSignature, 315c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis hidl_vec<uint8_t>(), &result); 316c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis 317c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (result.resultCode.isOk()) { 318c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (result.outParams.size()) { 319c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis *output_parameters = result.outParams; 32069a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 321c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis // TODO verify that append should not be assign 322c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis output_data->append(hidlVec2String(result.data)); 32369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn active_operations_.erase(handle); 32469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 325c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return result.resultCode; 32669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 32769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 328c7a9fa29c185a8c1889486d4acf00fd59c513870Janis DanisevskisKeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) { 32969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn if (active_operations_.count(handle) == 0) { 330c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return ErrorCode::INVALID_OPERATION_HANDLE; 33169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 332c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto error_code = keystore_->abort(active_operations_[handle]); 333c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (error_code.isOk()) { 33469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn active_operations_.erase(handle); 33569a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 33669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn return error_code; 33769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 33869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 33969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahnbool KeystoreClientImpl::doesKeyExist(const std::string& key_name) { 34069a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn String16 key_name16(key_name.data(), key_name.size()); 341c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto error_code = keystore_->exist(key_name16, kDefaultUID); 342c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis return error_code.isOk(); 34369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 34469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 34569a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahnbool KeystoreClientImpl::listKeys(const std::string& prefix, 34669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn std::vector<std::string>* key_name_list) { 34769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn String16 prefix16(prefix.data(), prefix.size()); 34869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn android::Vector<String16> matches; 349c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto error_code = keystore_->list(prefix16, kDefaultUID, &matches); 350c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (error_code.isOk()) { 35169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn for (const auto& match : matches) { 35269a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn android::String8 key_name(match); 35369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size())); 35469a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 35569a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn return true; 35669a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn } 35769a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn return false; 35869a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 35969a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 360c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskisuint64_t KeystoreClientImpl::getNextVirtualHandle() { 36169a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn return next_virtual_handle_++; 36269a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} 36369a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn 364251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahnbool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name) { 365251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn bool key_exists = doesKeyExist(key_name); 366251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (key_exists) { 367251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn bool verified = false; 368251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (!verifyEncryptionKeyAttributes(key_name, &verified)) { 369251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 370251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 371251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (!verified) { 372c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto result = deleteKey(key_name); 373c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!result.isOk()) { 374c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis ALOGE("Failed to delete invalid encryption key: %d", int32_t(result)); 375251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 376251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 377251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn key_exists = false; 378251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 379251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 380251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (!key_exists) { 381251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSetBuilder key_parameters; 382251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn key_parameters.AesEncryptionKey(kAESKeySize) 383c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis .Padding(PaddingMode::PKCS7) 384c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis .Authorization(TAG_BLOCK_MODE, BlockMode::CBC) 385c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis .Authorization(TAG_NO_AUTH_REQUIRED); 386251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet hardware_enforced_characteristics; 387251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet software_enforced_characteristics; 388c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto result = 389c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis generateKey(key_name, key_parameters, &hardware_enforced_characteristics, 390251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn &software_enforced_characteristics); 391c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!result.isOk()) { 392c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis ALOGE("Failed to generate encryption key: %d", int32_t(result)); 393251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 394251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 395251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (hardware_enforced_characteristics.size() == 0) { 396251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("WARNING: Encryption key is not hardware-backed."); 397251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 398251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 399251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return true; 400251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn} 401251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn 402251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahnbool KeystoreClientImpl::createOrVerifyAuthenticationKey(const std::string& key_name) { 403251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn bool key_exists = doesKeyExist(key_name); 404251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (key_exists) { 405251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn bool verified = false; 406251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (!verifyAuthenticationKeyAttributes(key_name, &verified)) { 407251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 408251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 409251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (!verified) { 410c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto result = deleteKey(key_name); 411c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!result.isOk()) { 412c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis ALOGE("Failed to delete invalid authentication key: %d", int32_t(result)); 413251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 414251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 415251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn key_exists = false; 416251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 417251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 418251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (!key_exists) { 419251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSetBuilder key_parameters; 420251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn key_parameters.HmacKey(kHMACKeySize) 421c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis .Digest(Digest::SHA_2_256) 422c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize) 423c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis .Authorization(TAG_NO_AUTH_REQUIRED); 424251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet hardware_enforced_characteristics; 425251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet software_enforced_characteristics; 426c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto result = 427c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis generateKey(key_name, key_parameters, &hardware_enforced_characteristics, 428251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn &software_enforced_characteristics); 429c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!result.isOk()) { 430c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis ALOGE("Failed to generate authentication key: %d", int32_t(result)); 431251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 432251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 433251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (hardware_enforced_characteristics.size() == 0) { 434251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("WARNING: Authentication key is not hardware-backed."); 435251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 436251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 437251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return true; 438251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn} 439251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn 440251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahnbool KeystoreClientImpl::verifyEncryptionKeyAttributes(const std::string& key_name, 441251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn bool* verified) { 442251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet hardware_enforced_characteristics; 443251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet software_enforced_characteristics; 444c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics, 445251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn &software_enforced_characteristics); 446c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!result.isOk()) { 447c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis ALOGE("Failed to query encryption key: %d", int32_t(result)); 448251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 449251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 450251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn *verified = true; 451c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM), 452c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis software_enforced_characteristics.GetTagValue(TAG_ALGORITHM)); 453c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) { 454251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("Found encryption key with invalid algorithm."); 455251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn *verified = false; 456251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 457c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE), 458c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE)); 459c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!key_size.isOk() || key_size.value() != kAESKeySize) { 460251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("Found encryption key with invalid size."); 461251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn *verified = false; 462251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 463c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE), 464c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE)); 465c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) { 466251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("Found encryption key with invalid block mode."); 467251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn *verified = false; 468251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 469c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING), 470c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis software_enforced_characteristics.GetTagValue(TAG_PADDING)); 471c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) { 472251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("Found encryption key with invalid padding mode."); 473251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn *verified = false; 474251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 475251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (hardware_enforced_characteristics.size() == 0) { 476251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("WARNING: Encryption key is not hardware-backed."); 477251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 478251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return true; 479251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn} 480251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn 481251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahnbool KeystoreClientImpl::verifyAuthenticationKeyAttributes(const std::string& key_name, 482251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn bool* verified) { 483251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet hardware_enforced_characteristics; 484251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn AuthorizationSet software_enforced_characteristics; 485c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics, 486251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn &software_enforced_characteristics); 487c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!result.isOk()) { 488c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis ALOGE("Failed to query authentication key: %d", int32_t(result)); 489251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return false; 490251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 491251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn *verified = true; 492c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM), 493c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis software_enforced_characteristics.GetTagValue(TAG_ALGORITHM)); 494c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC){ 495251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("Found authentication key with invalid algorithm."); 496251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn *verified = false; 497251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 498c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE), 499c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE)); 500c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!key_size.isOk() || key_size.value() != kHMACKeySize) { 501251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("Found authentication key with invalid size."); 502251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn *verified = false; 503251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 504c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH), 505c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH)); 506c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) { 507251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("Found authentication key with invalid minimum mac size."); 508251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn *verified = false; 509251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 510c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST), 511c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis software_enforced_characteristics.GetTagValue(TAG_DIGEST)); 512c7a9fa29c185a8c1889486d4acf00fd59c513870Janis Danisevskis if (!digest.isOk() || digest.value() != Digest::SHA_2_256) { 513251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("Found authentication key with invalid digest list."); 514251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn *verified = false; 515251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 516251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn if (hardware_enforced_characteristics.size() == 0) { 517251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn ALOGW("WARNING: Authentication key is not hardware-backed."); 518251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn } 519251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn return true; 520251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn} 521251cb28132e456f81374c8f8a983a5a9ad9aaee8Darren Krahn 52269a3dbc2bbbe0b304eb91376ff7f79c8bde995a1Darren Krahn} // namespace keystore 523