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