blob: 6d998adadca36586bab951612486cc1436742492 [file] [log] [blame]
Darren Krahn69a3dbc2015-09-22 16:21:04 -07001// Copyright 2015 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Darren Krahn251cb282015-09-28 08:51:18 -070015#define LOG_TAG "keystore_client"
16
Darren Krahn69a3dbc2015-09-22 16:21:04 -070017#include "keystore/keystore_client_impl.h"
18
19#include <string>
20#include <vector>
21
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -070022#include <android/security/IKeystoreService.h>
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010023#include <binder/IBinder.h>
24#include <binder/IInterface.h>
25#include <binder/IServiceManager.h>
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010026#include <keystore/keystore.h>
27#include <log/log.h>
28#include <utils/String16.h>
29#include <utils/String8.h>
Darren Krahn69a3dbc2015-09-22 16:21:04 -070030
Shawn Willdenbb22a6c2017-12-06 19:35:28 -070031#include <keystore/keymaster_types.h>
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010032#include <keystore/keystore_hidl_support.h>
Darren Krahn251cb282015-09-28 08:51:18 -070033
Shawn Willdenbb22a6c2017-12-06 19:35:28 -070034#include "keystore_client.pb.h"
35
Darren Krahn69a3dbc2015-09-22 16:21:04 -070036namespace {
37
38// Use the UID of the current process.
39const int kDefaultUID = -1;
Darren Krahn251cb282015-09-28 08:51:18 -070040const char kEncryptSuffix[] = "_ENC";
41const char kAuthenticateSuffix[] = "_AUTH";
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010042constexpr uint32_t kAESKeySize = 256; // bits
43constexpr uint32_t kHMACKeySize = 256; // bits
44constexpr uint32_t kHMACOutputSize = 256; // bits
Darren Krahnc8eca232015-10-16 10:54:43 -070045
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -070046using android::String16;
47using android::security::keymaster::ExportResult;
48using android::security::keymaster::OperationResult;
49using keystore::AuthorizationSet;
50using keystore::AuthorizationSetBuilder;
51using keystore::KeyCharacteristics;
52using keystore::KeyStoreServiceReturnCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -070053} // namespace
54
55namespace keystore {
56
57KeystoreClientImpl::KeystoreClientImpl() {
58 service_manager_ = android::defaultServiceManager();
59 keystore_binder_ = service_manager_->getService(String16("android.security.keystore"));
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -070060 keystore_ = android::interface_cast<android::security::IKeystoreService>(keystore_binder_);
Darren Krahn69a3dbc2015-09-22 16:21:04 -070061}
62
Darren Krahn251cb282015-09-28 08:51:18 -070063bool KeystoreClientImpl::encryptWithAuthentication(const std::string& key_name,
Janis Danisevskisc1460142017-12-18 16:48:46 -080064 const std::string& data, int32_t flags,
Darren Krahn251cb282015-09-28 08:51:18 -070065 std::string* encrypted_data) {
66 // The encryption algorithm is AES-256-CBC with PKCS #7 padding and a random
67 // IV. The authentication algorithm is HMAC-SHA256 and is computed over the
68 // cipher-text (i.e. Encrypt-then-MAC approach). This was chosen over AES-GCM
69 // because hardware support for GCM is not mandatory for all Brillo devices.
70 std::string encryption_key_name = key_name + kEncryptSuffix;
Janis Danisevskisc1460142017-12-18 16:48:46 -080071 if (!createOrVerifyEncryptionKey(encryption_key_name, flags)) {
Darren Krahn251cb282015-09-28 08:51:18 -070072 return false;
73 }
74 std::string authentication_key_name = key_name + kAuthenticateSuffix;
Janis Danisevskisc1460142017-12-18 16:48:46 -080075 if (!createOrVerifyAuthenticationKey(authentication_key_name, flags)) {
Darren Krahn251cb282015-09-28 08:51:18 -070076 return false;
77 }
78 AuthorizationSetBuilder encrypt_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010079 encrypt_params.Padding(PaddingMode::PKCS7);
80 encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
Darren Krahn251cb282015-09-28 08:51:18 -070081 AuthorizationSet output_params;
82 std::string raw_encrypted_data;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010083 if (!oneShotOperation(KeyPurpose::ENCRYPT, encryption_key_name, encrypt_params, data,
Darren Krahn251cb282015-09-28 08:51:18 -070084 std::string(), /* signature_to_verify */
85 &output_params, &raw_encrypted_data)) {
86 ALOGE("Encrypt: AES operation failed.");
87 return false;
88 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010089 auto init_vector_blob = output_params.GetTagValue(TAG_NONCE);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -070090 if (!init_vector_blob.isOk()) {
Darren Krahn251cb282015-09-28 08:51:18 -070091 ALOGE("Encrypt: Missing initialization vector.");
92 return false;
93 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010094 std::string init_vector = hidlVec2String(init_vector_blob.value());
Darren Krahn251cb282015-09-28 08:51:18 -070095
96 AuthorizationSetBuilder authenticate_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010097 authenticate_params.Digest(Digest::SHA_2_256);
98 authenticate_params.Authorization(TAG_MAC_LENGTH, kHMACOutputSize);
Darren Krahn251cb282015-09-28 08:51:18 -070099 std::string raw_authentication_data;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100100 if (!oneShotOperation(KeyPurpose::SIGN, authentication_key_name, authenticate_params,
Darren Krahn251cb282015-09-28 08:51:18 -0700101 init_vector + raw_encrypted_data, std::string(), /* signature_to_verify */
102 &output_params, &raw_authentication_data)) {
103 ALOGE("Encrypt: HMAC operation failed.");
104 return false;
105 }
106 EncryptedData protobuf;
107 protobuf.set_init_vector(init_vector);
108 protobuf.set_authentication_data(raw_authentication_data);
109 protobuf.set_encrypted_data(raw_encrypted_data);
110 if (!protobuf.SerializeToString(encrypted_data)) {
111 ALOGE("Encrypt: Failed to serialize EncryptedData protobuf.");
112 return false;
113 }
114 return true;
115}
116
117bool KeystoreClientImpl::decryptWithAuthentication(const std::string& key_name,
118 const std::string& encrypted_data,
119 std::string* data) {
120 EncryptedData protobuf;
121 if (!protobuf.ParseFromString(encrypted_data)) {
122 ALOGE("Decrypt: Failed to parse EncryptedData protobuf.");
123 }
124 // Verify authentication before attempting decryption.
125 std::string authentication_key_name = key_name + kAuthenticateSuffix;
126 AuthorizationSetBuilder authenticate_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100127 authenticate_params.Digest(Digest::SHA_2_256);
Darren Krahn251cb282015-09-28 08:51:18 -0700128 AuthorizationSet output_params;
129 std::string output_data;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100130 if (!oneShotOperation(KeyPurpose::VERIFY, authentication_key_name, authenticate_params,
Darren Krahn251cb282015-09-28 08:51:18 -0700131 protobuf.init_vector() + protobuf.encrypted_data(),
132 protobuf.authentication_data(), &output_params, &output_data)) {
133 ALOGE("Decrypt: HMAC operation failed.");
134 return false;
135 }
136 std::string encryption_key_name = key_name + kEncryptSuffix;
137 AuthorizationSetBuilder encrypt_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100138 encrypt_params.Padding(PaddingMode::PKCS7);
139 encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
140 encrypt_params.Authorization(TAG_NONCE, protobuf.init_vector().data(),
Darren Krahn251cb282015-09-28 08:51:18 -0700141 protobuf.init_vector().size());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100142 if (!oneShotOperation(KeyPurpose::DECRYPT, encryption_key_name, encrypt_params,
Darren Krahn251cb282015-09-28 08:51:18 -0700143 protobuf.encrypted_data(), std::string(), /* signature_to_verify */
144 &output_params, data)) {
145 ALOGE("Decrypt: AES operation failed.");
146 return false;
147 }
148 return true;
149}
150
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100151bool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string& key_name,
152 const AuthorizationSet& input_parameters,
Darren Krahn251cb282015-09-28 08:51:18 -0700153 const std::string& input_data,
154 const std::string& signature_to_verify,
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100155 AuthorizationSet* output_parameters,
Darren Krahn251cb282015-09-28 08:51:18 -0700156 std::string* output_data) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100157 uint64_t handle;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700158 auto result = beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100159 if (!result.isOk()) {
160 ALOGE("BeginOperation failed: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700161 return false;
162 }
163 AuthorizationSet empty_params;
164 size_t num_input_bytes_consumed;
165 AuthorizationSet ignored_params;
166 result = updateOperation(handle, empty_params, input_data, &num_input_bytes_consumed,
167 &ignored_params, output_data);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100168 if (!result.isOk()) {
169 ALOGE("UpdateOperation failed: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700170 return false;
171 }
172 result =
173 finishOperation(handle, empty_params, signature_to_verify, &ignored_params, output_data);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100174 if (!result.isOk()) {
175 ALOGE("FinishOperation failed: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700176 return false;
177 }
178 return true;
179}
180
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700181KeyStoreNativeReturnCode
Janis Danisevskisc1460142017-12-18 16:48:46 -0800182KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy, int32_t flags) {
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700183 int32_t result;
Janis Danisevskisc1460142017-12-18 16:48:46 -0800184 auto binder_result = keystore_->addRngEntropy(blob2hidlVec(entropy), flags, &result);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700185 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
186 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700187}
188
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700189KeyStoreNativeReturnCode
190KeystoreClientImpl::generateKey(const std::string& key_name, const AuthorizationSet& key_parameters,
Janis Danisevskisc1460142017-12-18 16:48:46 -0800191 int32_t flags, AuthorizationSet* hardware_enforced_characteristics,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700192 AuthorizationSet* software_enforced_characteristics) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700193 String16 key_name16(key_name.data(), key_name.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700194 ::android::security::keymaster::KeyCharacteristics characteristics;
195 int32_t result;
196 auto binder_result = keystore_->generateKey(
197 key_name16, ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
Janis Danisevskisc1460142017-12-18 16:48:46 -0800198 hidl_vec<uint8_t>() /* entropy */, kDefaultUID, flags, &characteristics, &result);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700199 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100200
201 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
202 * There are no references to Parcel memory after that, and ownership of the newly acquired
203 * memory is with the AuthorizationSet objects. */
Shawn Willden0329a822017-12-04 13:55:14 -0700204 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700205 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
206 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700207}
208
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100209KeyStoreNativeReturnCode
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700210KeystoreClientImpl::getKeyCharacteristics(const std::string& key_name,
211 AuthorizationSet* hardware_enforced_characteristics,
212 AuthorizationSet* software_enforced_characteristics) {
213 String16 key_name16(key_name.data(), key_name.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700214 ::android::security::keymaster::KeyCharacteristics characteristics;
215 int32_t result;
216 auto binder_result = keystore_->getKeyCharacteristics(
217 key_name16, android::security::keymaster::KeymasterBlob(),
218 android::security::keymaster::KeymasterBlob(), kDefaultUID, &characteristics, &result);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100219
220 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
221 * There are no references to Parcel memory after that, and ownership of the newly acquired
222 * memory is with the AuthorizationSet objects. */
Shawn Willden0329a822017-12-04 13:55:14 -0700223 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700224 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
225 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700226}
227
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700228KeyStoreNativeReturnCode
229KeystoreClientImpl::importKey(const std::string& key_name, const AuthorizationSet& key_parameters,
230 KeyFormat key_format, const std::string& key_data,
231 AuthorizationSet* hardware_enforced_characteristics,
232 AuthorizationSet* software_enforced_characteristics) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700233 String16 key_name16(key_name.data(), key_name.size());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100234 auto hidlKeyData = blob2hidlVec(key_data);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700235 ::android::security::keymaster::KeyCharacteristics characteristics;
236 int32_t result;
237 auto binder_result = keystore_->importKey(
238 key_name16, ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
239 (int)key_format, hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics, &result);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100240 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
241 * There are no references to Parcel memory after that, and ownership of the newly acquired
242 * memory is with the AuthorizationSet objects. */
Shawn Willden0329a822017-12-04 13:55:14 -0700243 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700244 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
245 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700246}
247
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100248KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700249 const std::string& key_name,
250 std::string* export_data) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700251 String16 key_name16(key_name.data(), key_name.size());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700252 ExportResult export_result;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700253 auto binder_result = keystore_->exportKey(
254 key_name16, (int)export_format, android::security::keymaster::KeymasterBlob(),
255 android::security::keymaster::KeymasterBlob(), kDefaultUID, &export_result);
256 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100257 *export_data = hidlVec2String(export_result.exportData);
258 return export_result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700259}
260
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100261KeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700262 String16 key_name16(key_name.data(), key_name.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700263 int32_t result;
264 auto binder_result = keystore_->del(key_name16, kDefaultUID, &result);
265 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
266 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700267}
268
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100269KeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() {
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700270 int32_t result;
271 auto binder_result = keystore_->clear_uid(kDefaultUID, &result);
272 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
273 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700274}
275
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700276KeyStoreNativeReturnCode
277KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
278 const AuthorizationSet& input_parameters,
279 AuthorizationSet* output_parameters, uint64_t* handle) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700280 android::sp<android::IBinder> token(new android::BBinder);
281 String16 key_name16(key_name.data(), key_name.size());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700282 OperationResult result;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700283 auto binder_result = keystore_->begin(
284 token, key_name16, (int)purpose, true /*pruneable*/,
285 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
286 hidl_vec<uint8_t>() /* entropy */, kDefaultUID, &result);
287 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100288 if (result.resultCode.isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700289 *handle = getNextVirtualHandle();
290 active_operations_[*handle] = result.token;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100291 if (result.outParams.size()) {
292 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700293 }
294 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100295 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700296}
297
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700298KeyStoreNativeReturnCode
299KeystoreClientImpl::updateOperation(uint64_t handle, const AuthorizationSet& input_parameters,
300 const std::string& input_data, size_t* num_input_bytes_consumed,
301 AuthorizationSet* output_parameters, std::string* output_data) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700302 if (active_operations_.count(handle) == 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100303 return ErrorCode::INVALID_OPERATION_HANDLE;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700304 }
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700305 OperationResult result;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100306 auto hidlInputData = blob2hidlVec(input_data);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700307 auto binder_result = keystore_->update(
308 active_operations_[handle],
309 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
310 hidlInputData, &result);
311 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100312
313 if (result.resultCode.isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700314 *num_input_bytes_consumed = result.inputConsumed;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100315 if (result.outParams.size()) {
316 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700317 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100318 // TODO verify that append should not be assign
319 output_data->append(hidlVec2String(result.data));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700320 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100321 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700322}
323
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700324KeyStoreNativeReturnCode
325KeystoreClientImpl::finishOperation(uint64_t handle, const AuthorizationSet& input_parameters,
326 const std::string& signature_to_verify,
327 AuthorizationSet* output_parameters, std::string* output_data) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700328 if (active_operations_.count(handle) == 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100329 return ErrorCode::INVALID_OPERATION_HANDLE;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700330 }
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700331 OperationResult result;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100332 auto hidlSignature = blob2hidlVec(signature_to_verify);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700333 auto binder_result = keystore_->finish(
334 active_operations_[handle],
335 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
336 (std::vector<uint8_t>)hidlSignature, hidl_vec<uint8_t>(), &result);
337 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100338
339 if (result.resultCode.isOk()) {
340 if (result.outParams.size()) {
341 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700342 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100343 // TODO verify that append should not be assign
344 output_data->append(hidlVec2String(result.data));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700345 active_operations_.erase(handle);
346 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100347 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700348}
349
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100350KeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700351 if (active_operations_.count(handle) == 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100352 return ErrorCode::INVALID_OPERATION_HANDLE;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700353 }
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700354 int32_t result;
355 // Current implementation does not return exceptions in android::binder::Status
356 auto binder_result = keystore_->abort(active_operations_[handle], &result);
357 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
358 if (KeyStoreNativeReturnCode(result).isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700359 active_operations_.erase(handle);
360 }
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700361 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700362}
363
364bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
365 String16 key_name16(key_name.data(), key_name.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700366 int32_t result;
367 auto binder_result = keystore_->exist(key_name16, kDefaultUID, &result);
368 if (!binder_result.isOk()) return false; // binder error
369 return result;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700370}
371
372bool KeystoreClientImpl::listKeys(const std::string& prefix,
373 std::vector<std::string>* key_name_list) {
374 String16 prefix16(prefix.data(), prefix.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700375 std::vector<::android::String16> matches;
376 auto binder_result = keystore_->list(prefix16, kDefaultUID, &matches);
377 if (!binder_result.isOk()) return false;
378
379 for (const auto& match : matches) {
380 android::String8 key_name(match);
381 key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size()));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700382 }
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700383 return true;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700384}
385
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100386uint64_t KeystoreClientImpl::getNextVirtualHandle() {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700387 return next_virtual_handle_++;
388}
389
Janis Danisevskisc1460142017-12-18 16:48:46 -0800390bool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name, int32_t flags) {
Darren Krahn251cb282015-09-28 08:51:18 -0700391 bool key_exists = doesKeyExist(key_name);
392 if (key_exists) {
393 bool verified = false;
394 if (!verifyEncryptionKeyAttributes(key_name, &verified)) {
395 return false;
396 }
397 if (!verified) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100398 auto result = deleteKey(key_name);
399 if (!result.isOk()) {
400 ALOGE("Failed to delete invalid encryption key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700401 return false;
402 }
403 key_exists = false;
404 }
405 }
406 if (!key_exists) {
407 AuthorizationSetBuilder key_parameters;
408 key_parameters.AesEncryptionKey(kAESKeySize)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100409 .Padding(PaddingMode::PKCS7)
410 .Authorization(TAG_BLOCK_MODE, BlockMode::CBC)
411 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahn251cb282015-09-28 08:51:18 -0700412 AuthorizationSet hardware_enforced_characteristics;
413 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc1460142017-12-18 16:48:46 -0800414 auto result =
415 generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
416 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100417 if (!result.isOk()) {
418 ALOGE("Failed to generate encryption key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700419 return false;
420 }
421 if (hardware_enforced_characteristics.size() == 0) {
422 ALOGW("WARNING: Encryption key is not hardware-backed.");
423 }
424 }
425 return true;
426}
427
Janis Danisevskisc1460142017-12-18 16:48:46 -0800428bool KeystoreClientImpl::createOrVerifyAuthenticationKey(const std::string& key_name,
429 int32_t flags) {
Darren Krahn251cb282015-09-28 08:51:18 -0700430 bool key_exists = doesKeyExist(key_name);
431 if (key_exists) {
432 bool verified = false;
433 if (!verifyAuthenticationKeyAttributes(key_name, &verified)) {
434 return false;
435 }
436 if (!verified) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100437 auto result = deleteKey(key_name);
438 if (!result.isOk()) {
439 ALOGE("Failed to delete invalid authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700440 return false;
441 }
442 key_exists = false;
443 }
444 }
445 if (!key_exists) {
446 AuthorizationSetBuilder key_parameters;
447 key_parameters.HmacKey(kHMACKeySize)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100448 .Digest(Digest::SHA_2_256)
449 .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize)
450 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahn251cb282015-09-28 08:51:18 -0700451 AuthorizationSet hardware_enforced_characteristics;
452 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc1460142017-12-18 16:48:46 -0800453 auto result =
454 generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
455 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100456 if (!result.isOk()) {
457 ALOGE("Failed to generate authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700458 return false;
459 }
460 if (hardware_enforced_characteristics.size() == 0) {
461 ALOGW("WARNING: Authentication key is not hardware-backed.");
462 }
463 }
464 return true;
465}
466
467bool KeystoreClientImpl::verifyEncryptionKeyAttributes(const std::string& key_name,
468 bool* verified) {
469 AuthorizationSet hardware_enforced_characteristics;
470 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100471 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700472 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100473 if (!result.isOk()) {
474 ALOGE("Failed to query encryption key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700475 return false;
476 }
477 *verified = true;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100478 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700479 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100480 if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
Darren Krahn251cb282015-09-28 08:51:18 -0700481 ALOGW("Found encryption key with invalid algorithm.");
482 *verified = false;
483 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100484 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700485 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100486 if (!key_size.isOk() || key_size.value() != kAESKeySize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700487 ALOGW("Found encryption key with invalid size.");
488 *verified = false;
489 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100490 auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700491 software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100492 if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
Darren Krahn251cb282015-09-28 08:51:18 -0700493 ALOGW("Found encryption key with invalid block mode.");
494 *verified = false;
495 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100496 auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700497 software_enforced_characteristics.GetTagValue(TAG_PADDING));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100498 if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
Darren Krahn251cb282015-09-28 08:51:18 -0700499 ALOGW("Found encryption key with invalid padding mode.");
500 *verified = false;
501 }
502 if (hardware_enforced_characteristics.size() == 0) {
503 ALOGW("WARNING: Encryption key is not hardware-backed.");
504 }
505 return true;
506}
507
508bool KeystoreClientImpl::verifyAuthenticationKeyAttributes(const std::string& key_name,
509 bool* verified) {
510 AuthorizationSet hardware_enforced_characteristics;
511 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100512 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700513 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100514 if (!result.isOk()) {
515 ALOGE("Failed to query authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700516 return false;
517 }
518 *verified = true;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100519 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700520 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
521 if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC) {
Darren Krahn251cb282015-09-28 08:51:18 -0700522 ALOGW("Found authentication key with invalid algorithm.");
523 *verified = false;
524 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100525 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700526 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100527 if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700528 ALOGW("Found authentication key with invalid size.");
529 *verified = false;
530 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100531 auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700532 software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100533 if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700534 ALOGW("Found authentication key with invalid minimum mac size.");
535 *verified = false;
536 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100537 auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700538 software_enforced_characteristics.GetTagValue(TAG_DIGEST));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100539 if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
Darren Krahn251cb282015-09-28 08:51:18 -0700540 ALOGW("Found authentication key with invalid digest list.");
541 *verified = false;
542 }
543 if (hardware_enforced_characteristics.size() == 0) {
544 ALOGW("WARNING: Authentication key is not hardware-backed.");
545 }
546 return true;
547}
548
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700549} // namespace keystore