blob: b9a142e55b719107339f5d78c2899657feec4a43 [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
Rob Barnesbb6cabd2018-10-04 17:10:37 -060019#include <future>
Darren Krahn69a3dbc2015-09-22 16:21:04 -070020#include <string>
21#include <vector>
22
Rob Barnesbb6cabd2018-10-04 17:10:37 -060023#include <android/security/keystore/IKeystoreService.h>
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010024#include <binder/IBinder.h>
25#include <binder/IInterface.h>
26#include <binder/IServiceManager.h>
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010027#include <keystore/keystore.h>
28#include <log/log.h>
29#include <utils/String16.h>
30#include <utils/String8.h>
Darren Krahn69a3dbc2015-09-22 16:21:04 -070031
Shawn Willdenbb22a6c2017-12-06 19:35:28 -070032#include <keystore/keymaster_types.h>
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010033#include <keystore/keystore_hidl_support.h>
Rob Barnesbb6cabd2018-10-04 17:10:37 -060034#include <keystore/keystore_promises.h>
Darren Krahn251cb282015-09-28 08:51:18 -070035
Shawn Willdenbb22a6c2017-12-06 19:35:28 -070036#include "keystore_client.pb.h"
37
Darren Krahn69a3dbc2015-09-22 16:21:04 -070038namespace {
39
40// Use the UID of the current process.
41const int kDefaultUID = -1;
Darren Krahn251cb282015-09-28 08:51:18 -070042const char kEncryptSuffix[] = "_ENC";
43const char kAuthenticateSuffix[] = "_AUTH";
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010044constexpr uint32_t kAESKeySize = 256; // bits
45constexpr uint32_t kHMACKeySize = 256; // bits
46constexpr uint32_t kHMACOutputSize = 256; // bits
Darren Krahnc8eca232015-10-16 10:54:43 -070047
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -070048using android::String16;
49using android::security::keymaster::ExportResult;
50using android::security::keymaster::OperationResult;
Rob Barnesbb6cabd2018-10-04 17:10:37 -060051using android::security::keystore::KeystoreResponse;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -070052using keystore::AuthorizationSet;
53using keystore::AuthorizationSetBuilder;
54using keystore::KeyCharacteristics;
55using keystore::KeyStoreServiceReturnCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -070056} // namespace
57
58namespace keystore {
59
60KeystoreClientImpl::KeystoreClientImpl() {
61 service_manager_ = android::defaultServiceManager();
62 keystore_binder_ = service_manager_->getService(String16("android.security.keystore"));
Rob Barnesbb6cabd2018-10-04 17:10:37 -060063 keystore_ =
64 android::interface_cast<android::security::keystore::IKeystoreService>(keystore_binder_);
Darren Krahn69a3dbc2015-09-22 16:21:04 -070065}
66
Darren Krahn251cb282015-09-28 08:51:18 -070067bool KeystoreClientImpl::encryptWithAuthentication(const std::string& key_name,
Janis Danisevskisc1460142017-12-18 16:48:46 -080068 const std::string& data, int32_t flags,
Darren Krahn251cb282015-09-28 08:51:18 -070069 std::string* encrypted_data) {
70 // The encryption algorithm is AES-256-CBC with PKCS #7 padding and a random
71 // IV. The authentication algorithm is HMAC-SHA256 and is computed over the
72 // cipher-text (i.e. Encrypt-then-MAC approach). This was chosen over AES-GCM
73 // because hardware support for GCM is not mandatory for all Brillo devices.
74 std::string encryption_key_name = key_name + kEncryptSuffix;
Janis Danisevskisc1460142017-12-18 16:48:46 -080075 if (!createOrVerifyEncryptionKey(encryption_key_name, flags)) {
Darren Krahn251cb282015-09-28 08:51:18 -070076 return false;
77 }
78 std::string authentication_key_name = key_name + kAuthenticateSuffix;
Janis Danisevskisc1460142017-12-18 16:48:46 -080079 if (!createOrVerifyAuthenticationKey(authentication_key_name, flags)) {
Darren Krahn251cb282015-09-28 08:51:18 -070080 return false;
81 }
82 AuthorizationSetBuilder encrypt_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010083 encrypt_params.Padding(PaddingMode::PKCS7);
84 encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
Darren Krahn251cb282015-09-28 08:51:18 -070085 AuthorizationSet output_params;
86 std::string raw_encrypted_data;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010087 if (!oneShotOperation(KeyPurpose::ENCRYPT, encryption_key_name, encrypt_params, data,
Darren Krahn251cb282015-09-28 08:51:18 -070088 std::string(), /* signature_to_verify */
89 &output_params, &raw_encrypted_data)) {
90 ALOGE("Encrypt: AES operation failed.");
91 return false;
92 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010093 auto init_vector_blob = output_params.GetTagValue(TAG_NONCE);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -070094 if (!init_vector_blob.isOk()) {
Darren Krahn251cb282015-09-28 08:51:18 -070095 ALOGE("Encrypt: Missing initialization vector.");
96 return false;
97 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010098 std::string init_vector = hidlVec2String(init_vector_blob.value());
Darren Krahn251cb282015-09-28 08:51:18 -070099
100 AuthorizationSetBuilder authenticate_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100101 authenticate_params.Digest(Digest::SHA_2_256);
102 authenticate_params.Authorization(TAG_MAC_LENGTH, kHMACOutputSize);
Darren Krahn251cb282015-09-28 08:51:18 -0700103 std::string raw_authentication_data;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100104 if (!oneShotOperation(KeyPurpose::SIGN, authentication_key_name, authenticate_params,
Darren Krahn251cb282015-09-28 08:51:18 -0700105 init_vector + raw_encrypted_data, std::string(), /* signature_to_verify */
106 &output_params, &raw_authentication_data)) {
107 ALOGE("Encrypt: HMAC operation failed.");
108 return false;
109 }
110 EncryptedData protobuf;
111 protobuf.set_init_vector(init_vector);
112 protobuf.set_authentication_data(raw_authentication_data);
113 protobuf.set_encrypted_data(raw_encrypted_data);
114 if (!protobuf.SerializeToString(encrypted_data)) {
115 ALOGE("Encrypt: Failed to serialize EncryptedData protobuf.");
116 return false;
117 }
118 return true;
119}
120
121bool KeystoreClientImpl::decryptWithAuthentication(const std::string& key_name,
122 const std::string& encrypted_data,
123 std::string* data) {
124 EncryptedData protobuf;
125 if (!protobuf.ParseFromString(encrypted_data)) {
126 ALOGE("Decrypt: Failed to parse EncryptedData protobuf.");
127 }
128 // Verify authentication before attempting decryption.
129 std::string authentication_key_name = key_name + kAuthenticateSuffix;
130 AuthorizationSetBuilder authenticate_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100131 authenticate_params.Digest(Digest::SHA_2_256);
Darren Krahn251cb282015-09-28 08:51:18 -0700132 AuthorizationSet output_params;
133 std::string output_data;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100134 if (!oneShotOperation(KeyPurpose::VERIFY, authentication_key_name, authenticate_params,
Darren Krahn251cb282015-09-28 08:51:18 -0700135 protobuf.init_vector() + protobuf.encrypted_data(),
136 protobuf.authentication_data(), &output_params, &output_data)) {
137 ALOGE("Decrypt: HMAC operation failed.");
138 return false;
139 }
140 std::string encryption_key_name = key_name + kEncryptSuffix;
141 AuthorizationSetBuilder encrypt_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100142 encrypt_params.Padding(PaddingMode::PKCS7);
143 encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
144 encrypt_params.Authorization(TAG_NONCE, protobuf.init_vector().data(),
Darren Krahn251cb282015-09-28 08:51:18 -0700145 protobuf.init_vector().size());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100146 if (!oneShotOperation(KeyPurpose::DECRYPT, encryption_key_name, encrypt_params,
Darren Krahn251cb282015-09-28 08:51:18 -0700147 protobuf.encrypted_data(), std::string(), /* signature_to_verify */
148 &output_params, data)) {
149 ALOGE("Decrypt: AES operation failed.");
150 return false;
151 }
152 return true;
153}
154
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100155bool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string& key_name,
156 const AuthorizationSet& input_parameters,
Darren Krahn251cb282015-09-28 08:51:18 -0700157 const std::string& input_data,
158 const std::string& signature_to_verify,
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100159 AuthorizationSet* output_parameters,
Darren Krahn251cb282015-09-28 08:51:18 -0700160 std::string* output_data) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100161 uint64_t handle;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700162 auto result = beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100163 if (!result.isOk()) {
Branden Archer70080742018-11-20 11:04:11 -0800164 ALOGE("BeginOperation failed: %d", result.getErrorCode());
Darren Krahn251cb282015-09-28 08:51:18 -0700165 return false;
166 }
167 AuthorizationSet empty_params;
168 size_t num_input_bytes_consumed;
169 AuthorizationSet ignored_params;
170 result = updateOperation(handle, empty_params, input_data, &num_input_bytes_consumed,
171 &ignored_params, output_data);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100172 if (!result.isOk()) {
Branden Archer70080742018-11-20 11:04:11 -0800173 ALOGE("UpdateOperation failed: %d", result.getErrorCode());
Darren Krahn251cb282015-09-28 08:51:18 -0700174 return false;
175 }
176 result =
177 finishOperation(handle, empty_params, signature_to_verify, &ignored_params, output_data);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100178 if (!result.isOk()) {
Branden Archer70080742018-11-20 11:04:11 -0800179 ALOGE("FinishOperation failed: %d", result.getErrorCode());
Darren Krahn251cb282015-09-28 08:51:18 -0700180 return false;
181 }
182 return true;
183}
184
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700185KeyStoreNativeReturnCode
Janis Danisevskisc1460142017-12-18 16:48:46 -0800186KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy, int32_t flags) {
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600187 int32_t error_code;
188
189 android::sp<KeystoreResponsePromise> promise(new KeystoreResponsePromise());
190 auto future = promise->get_future();
191
192 auto binder_result =
193 keystore_->addRngEntropy(promise, blob2hidlVec(entropy), flags, &error_code);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700194 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600195
196 KeyStoreNativeReturnCode rc(error_code);
197 if (!rc.isOk()) return rc;
198
199 auto result = future.get();
200
201 return KeyStoreNativeReturnCode(result.response_code());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700202}
203
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700204KeyStoreNativeReturnCode
205KeystoreClientImpl::generateKey(const std::string& key_name, const AuthorizationSet& key_parameters,
Janis Danisevskisc1460142017-12-18 16:48:46 -0800206 int32_t flags, AuthorizationSet* hardware_enforced_characteristics,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700207 AuthorizationSet* software_enforced_characteristics) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700208 String16 key_name16(key_name.data(), key_name.size());
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600209 int32_t error_code;
210 android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
211 auto future = promise->get_future();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700212 auto binder_result = keystore_->generateKey(
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600213 promise, key_name16,
214 ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
215 hidl_vec<uint8_t>() /* entropy */, kDefaultUID, flags, &error_code);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700216 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100217
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600218 KeyStoreNativeReturnCode rc(error_code);
219 if (!rc.isOk()) return rc;
220
221 auto [km_response, characteristics] = future.get();
222
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100223 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
224 * There are no references to Parcel memory after that, and ownership of the newly acquired
225 * memory is with the AuthorizationSet objects. */
Shawn Willden0329a822017-12-04 13:55:14 -0700226 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700227 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600228 return KeyStoreNativeReturnCode(km_response.response_code());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700229}
230
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100231KeyStoreNativeReturnCode
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700232KeystoreClientImpl::getKeyCharacteristics(const std::string& key_name,
233 AuthorizationSet* hardware_enforced_characteristics,
234 AuthorizationSet* software_enforced_characteristics) {
235 String16 key_name16(key_name.data(), key_name.size());
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600236 int32_t error_code;
237 android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
238 auto future = promise->get_future();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700239 auto binder_result = keystore_->getKeyCharacteristics(
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600240 promise, key_name16, android::security::keymaster::KeymasterBlob(),
241 android::security::keymaster::KeymasterBlob(), kDefaultUID, &error_code);
242 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
243
244 KeyStoreNativeReturnCode rc(error_code);
245 if (!rc.isOk()) return rc;
246
247 auto [km_response, characteristics] = future.get();
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100248
249 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
250 * There are no references to Parcel memory after that, and ownership of the newly acquired
251 * memory is with the AuthorizationSet objects. */
Shawn Willden0329a822017-12-04 13:55:14 -0700252 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700253 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600254 return KeyStoreNativeReturnCode(km_response.response_code());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700255}
256
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700257KeyStoreNativeReturnCode
258KeystoreClientImpl::importKey(const std::string& key_name, const AuthorizationSet& key_parameters,
259 KeyFormat key_format, const std::string& key_data,
260 AuthorizationSet* hardware_enforced_characteristics,
261 AuthorizationSet* software_enforced_characteristics) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700262 String16 key_name16(key_name.data(), key_name.size());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100263 auto hidlKeyData = blob2hidlVec(key_data);
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600264 int32_t error_code;
265 android::sp<KeyCharacteristicsPromise> promise(new KeyCharacteristicsPromise);
266 auto future = promise->get_future();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700267 auto binder_result = keystore_->importKey(
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600268 promise, key_name16,
269 ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
270 (int)key_format, hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &error_code);
271 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
272
273 KeyStoreNativeReturnCode rc(error_code);
274 if (!rc.isOk()) return rc;
275
276 auto [km_response, characteristics] = future.get();
277
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100278 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
279 * There are no references to Parcel memory after that, and ownership of the newly acquired
280 * memory is with the AuthorizationSet objects. */
Shawn Willden0329a822017-12-04 13:55:14 -0700281 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700282 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600283 return KeyStoreNativeReturnCode(km_response.response_code());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700284}
285
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100286KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700287 const std::string& key_name,
288 std::string* export_data) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700289 String16 key_name16(key_name.data(), key_name.size());
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600290 int32_t error_code;
291 android::sp<KeystoreExportPromise> promise(new KeystoreExportPromise);
292 auto future = promise->get_future();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700293 auto binder_result = keystore_->exportKey(
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600294 promise, key_name16, (int)export_format, android::security::keymaster::KeymasterBlob(),
295 android::security::keymaster::KeymasterBlob(), kDefaultUID, &error_code);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700296 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600297
298 KeyStoreNativeReturnCode rc(error_code);
299 if (!rc.isOk()) return rc;
300
301 auto export_result = future.get();
302 if (!export_result.resultCode.isOk()) return export_result.resultCode;
303
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100304 *export_data = hidlVec2String(export_result.exportData);
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600305
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100306 return export_result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700307}
308
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100309KeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700310 String16 key_name16(key_name.data(), key_name.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700311 int32_t result;
312 auto binder_result = keystore_->del(key_name16, kDefaultUID, &result);
313 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
314 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700315}
316
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100317KeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() {
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700318 int32_t result;
319 auto binder_result = keystore_->clear_uid(kDefaultUID, &result);
320 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
321 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700322}
323
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700324KeyStoreNativeReturnCode
325KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
326 const AuthorizationSet& input_parameters,
327 AuthorizationSet* output_parameters, uint64_t* handle) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700328 android::sp<android::IBinder> token(new android::BBinder);
329 String16 key_name16(key_name.data(), key_name.size());
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600330 int32_t error_code;
331 android::sp<OperationResultPromise> promise(new OperationResultPromise{});
332 auto future = promise->get_future();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700333 auto binder_result = keystore_->begin(
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600334 promise, token, key_name16, (int)purpose, true /*pruneable*/,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700335 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600336 hidl_vec<uint8_t>() /* entropy */, kDefaultUID, &error_code);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700337 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600338 KeyStoreNativeReturnCode rc(error_code);
339 if (!rc.isOk()) return rc;
340
341 OperationResult result = future.get();
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100342 if (result.resultCode.isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700343 *handle = getNextVirtualHandle();
344 active_operations_[*handle] = result.token;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100345 if (result.outParams.size()) {
346 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700347 }
348 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100349 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700350}
351
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700352KeyStoreNativeReturnCode
353KeystoreClientImpl::updateOperation(uint64_t handle, const AuthorizationSet& input_parameters,
354 const std::string& input_data, size_t* num_input_bytes_consumed,
355 AuthorizationSet* output_parameters, std::string* output_data) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700356 if (active_operations_.count(handle) == 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100357 return ErrorCode::INVALID_OPERATION_HANDLE;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700358 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100359 auto hidlInputData = blob2hidlVec(input_data);
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600360 int32_t error_code;
361 android::sp<OperationResultPromise> promise(new OperationResultPromise{});
362 auto future = promise->get_future();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700363 auto binder_result = keystore_->update(
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600364 promise, active_operations_[handle],
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700365 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600366 hidlInputData, &error_code);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700367 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600368 KeyStoreNativeReturnCode rc(error_code);
369 if (!rc.isOk()) return rc;
370
371 OperationResult result = future.get();
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100372
373 if (result.resultCode.isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700374 *num_input_bytes_consumed = result.inputConsumed;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100375 if (result.outParams.size()) {
376 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700377 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100378 // TODO verify that append should not be assign
379 output_data->append(hidlVec2String(result.data));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700380 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100381 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700382}
383
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700384KeyStoreNativeReturnCode
385KeystoreClientImpl::finishOperation(uint64_t handle, const AuthorizationSet& input_parameters,
386 const std::string& signature_to_verify,
387 AuthorizationSet* output_parameters, std::string* output_data) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700388 if (active_operations_.count(handle) == 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100389 return ErrorCode::INVALID_OPERATION_HANDLE;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700390 }
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600391 int32_t error_code;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100392 auto hidlSignature = blob2hidlVec(signature_to_verify);
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600393 android::sp<OperationResultPromise> promise(new OperationResultPromise{});
394 auto future = promise->get_future();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700395 auto binder_result = keystore_->finish(
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600396 promise, active_operations_[handle],
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700397 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600398 (std::vector<uint8_t>)hidlSignature, hidl_vec<uint8_t>(), &error_code);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700399 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600400 KeyStoreNativeReturnCode rc(error_code);
401 if (!rc.isOk()) return rc;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100402
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600403 OperationResult result = future.get();
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100404 if (result.resultCode.isOk()) {
405 if (result.outParams.size()) {
406 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700407 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100408 // TODO verify that append should not be assign
409 output_data->append(hidlVec2String(result.data));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700410 active_operations_.erase(handle);
411 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100412 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700413}
414
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100415KeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700416 if (active_operations_.count(handle) == 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100417 return ErrorCode::INVALID_OPERATION_HANDLE;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700418 }
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700419 int32_t result;
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600420 android::sp<KeystoreResponsePromise> promise(new KeystoreResponsePromise{});
421 auto future = promise->get_future();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700422 // Current implementation does not return exceptions in android::binder::Status
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600423 auto binder_result = keystore_->abort(promise, active_operations_[handle], &result);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700424 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600425 KeyStoreNativeReturnCode rc(result);
426 if (!rc.isOk()) return rc;
427 rc = KeyStoreNativeReturnCode(future.get().response_code());
428 if (rc.isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700429 active_operations_.erase(handle);
430 }
Rob Barnesbb6cabd2018-10-04 17:10:37 -0600431 return rc;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700432}
433
434bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
435 String16 key_name16(key_name.data(), key_name.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700436 int32_t result;
437 auto binder_result = keystore_->exist(key_name16, kDefaultUID, &result);
438 if (!binder_result.isOk()) return false; // binder error
Branden Archer1a87fdc2018-11-21 14:58:01 -0800439 return result == static_cast<int32_t>(ResponseCode::NO_ERROR);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700440}
441
442bool KeystoreClientImpl::listKeys(const std::string& prefix,
443 std::vector<std::string>* key_name_list) {
444 String16 prefix16(prefix.data(), prefix.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700445 std::vector<::android::String16> matches;
446 auto binder_result = keystore_->list(prefix16, kDefaultUID, &matches);
447 if (!binder_result.isOk()) return false;
448
449 for (const auto& match : matches) {
450 android::String8 key_name(match);
451 key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size()));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700452 }
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700453 return true;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700454}
455
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100456uint64_t KeystoreClientImpl::getNextVirtualHandle() {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700457 return next_virtual_handle_++;
458}
459
Janis Danisevskisc1460142017-12-18 16:48:46 -0800460bool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name, int32_t flags) {
Darren Krahn251cb282015-09-28 08:51:18 -0700461 bool key_exists = doesKeyExist(key_name);
462 if (key_exists) {
463 bool verified = false;
464 if (!verifyEncryptionKeyAttributes(key_name, &verified)) {
465 return false;
466 }
467 if (!verified) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100468 auto result = deleteKey(key_name);
469 if (!result.isOk()) {
Branden Archer70080742018-11-20 11:04:11 -0800470 ALOGE("Failed to delete invalid encryption key: %d", result.getErrorCode());
Darren Krahn251cb282015-09-28 08:51:18 -0700471 return false;
472 }
473 key_exists = false;
474 }
475 }
476 if (!key_exists) {
477 AuthorizationSetBuilder key_parameters;
478 key_parameters.AesEncryptionKey(kAESKeySize)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100479 .Padding(PaddingMode::PKCS7)
480 .Authorization(TAG_BLOCK_MODE, BlockMode::CBC)
481 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahn251cb282015-09-28 08:51:18 -0700482 AuthorizationSet hardware_enforced_characteristics;
483 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc1460142017-12-18 16:48:46 -0800484 auto result =
485 generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
486 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100487 if (!result.isOk()) {
Branden Archer70080742018-11-20 11:04:11 -0800488 ALOGE("Failed to generate encryption key: %d", result.getErrorCode());
Darren Krahn251cb282015-09-28 08:51:18 -0700489 return false;
490 }
491 if (hardware_enforced_characteristics.size() == 0) {
492 ALOGW("WARNING: Encryption key is not hardware-backed.");
493 }
494 }
495 return true;
496}
497
Janis Danisevskisc1460142017-12-18 16:48:46 -0800498bool KeystoreClientImpl::createOrVerifyAuthenticationKey(const std::string& key_name,
499 int32_t flags) {
Darren Krahn251cb282015-09-28 08:51:18 -0700500 bool key_exists = doesKeyExist(key_name);
501 if (key_exists) {
502 bool verified = false;
503 if (!verifyAuthenticationKeyAttributes(key_name, &verified)) {
504 return false;
505 }
506 if (!verified) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100507 auto result = deleteKey(key_name);
508 if (!result.isOk()) {
Branden Archer70080742018-11-20 11:04:11 -0800509 ALOGE("Failed to delete invalid authentication key: %d", result.getErrorCode());
Darren Krahn251cb282015-09-28 08:51:18 -0700510 return false;
511 }
512 key_exists = false;
513 }
514 }
515 if (!key_exists) {
516 AuthorizationSetBuilder key_parameters;
517 key_parameters.HmacKey(kHMACKeySize)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100518 .Digest(Digest::SHA_2_256)
519 .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize)
520 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahn251cb282015-09-28 08:51:18 -0700521 AuthorizationSet hardware_enforced_characteristics;
522 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc1460142017-12-18 16:48:46 -0800523 auto result =
524 generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
525 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100526 if (!result.isOk()) {
Branden Archer70080742018-11-20 11:04:11 -0800527 ALOGE("Failed to generate authentication key: %d", result.getErrorCode());
Darren Krahn251cb282015-09-28 08:51:18 -0700528 return false;
529 }
530 if (hardware_enforced_characteristics.size() == 0) {
531 ALOGW("WARNING: Authentication key is not hardware-backed.");
532 }
533 }
534 return true;
535}
536
537bool KeystoreClientImpl::verifyEncryptionKeyAttributes(const std::string& key_name,
538 bool* verified) {
539 AuthorizationSet hardware_enforced_characteristics;
540 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100541 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700542 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100543 if (!result.isOk()) {
Branden Archer70080742018-11-20 11:04:11 -0800544 ALOGE("Failed to query encryption key: %d", result.getErrorCode());
Darren Krahn251cb282015-09-28 08:51:18 -0700545 return false;
546 }
547 *verified = true;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100548 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700549 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100550 if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
Darren Krahn251cb282015-09-28 08:51:18 -0700551 ALOGW("Found encryption key with invalid algorithm.");
552 *verified = false;
553 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100554 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700555 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100556 if (!key_size.isOk() || key_size.value() != kAESKeySize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700557 ALOGW("Found encryption key with invalid size.");
558 *verified = false;
559 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100560 auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700561 software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100562 if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
Darren Krahn251cb282015-09-28 08:51:18 -0700563 ALOGW("Found encryption key with invalid block mode.");
564 *verified = false;
565 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100566 auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700567 software_enforced_characteristics.GetTagValue(TAG_PADDING));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100568 if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
Darren Krahn251cb282015-09-28 08:51:18 -0700569 ALOGW("Found encryption key with invalid padding mode.");
570 *verified = false;
571 }
572 if (hardware_enforced_characteristics.size() == 0) {
573 ALOGW("WARNING: Encryption key is not hardware-backed.");
574 }
575 return true;
576}
577
578bool KeystoreClientImpl::verifyAuthenticationKeyAttributes(const std::string& key_name,
579 bool* verified) {
580 AuthorizationSet hardware_enforced_characteristics;
581 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100582 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700583 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100584 if (!result.isOk()) {
Branden Archer70080742018-11-20 11:04:11 -0800585 ALOGE("Failed to query authentication key: %d", result.getErrorCode());
Darren Krahn251cb282015-09-28 08:51:18 -0700586 return false;
587 }
588 *verified = true;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100589 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700590 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
591 if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC) {
Darren Krahn251cb282015-09-28 08:51:18 -0700592 ALOGW("Found authentication key with invalid algorithm.");
593 *verified = false;
594 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100595 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700596 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100597 if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700598 ALOGW("Found authentication key with invalid size.");
599 *verified = false;
600 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100601 auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700602 software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100603 if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700604 ALOGW("Found authentication key with invalid minimum mac size.");
605 *verified = false;
606 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100607 auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700608 software_enforced_characteristics.GetTagValue(TAG_DIGEST));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100609 if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
Darren Krahn251cb282015-09-28 08:51:18 -0700610 ALOGW("Found authentication key with invalid digest list.");
611 *verified = false;
612 }
613 if (hardware_enforced_characteristics.size() == 0) {
614 ALOGW("WARNING: Authentication key is not hardware-backed.");
615 }
616 return true;
617}
618
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700619} // namespace keystore