blob: 4ff865a002602b5e50af3e766acae9e7ff48182d [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,
64 const std::string& data,
65 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;
71 if (!createOrVerifyEncryptionKey(encryption_key_name)) {
72 return false;
73 }
74 std::string authentication_key_name = key_name + kAuthenticateSuffix;
75 if (!createOrVerifyAuthenticationKey(authentication_key_name)) {
76 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
182KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy) {
183 int32_t result;
184 auto binder_result = keystore_->addRngEntropy(blob2hidlVec(entropy), &result);
185 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,
191 AuthorizationSet* hardware_enforced_characteristics,
192 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()),
198 hidl_vec<uint8_t>() /* entropy */, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics,
199 &result);
200 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100201
202 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
203 * There are no references to Parcel memory after that, and ownership of the newly acquired
204 * memory is with the AuthorizationSet objects. */
Shawn Willden0329a822017-12-04 13:55:14 -0700205 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700206 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
207 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700208}
209
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100210KeyStoreNativeReturnCode
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700211KeystoreClientImpl::getKeyCharacteristics(const std::string& key_name,
212 AuthorizationSet* hardware_enforced_characteristics,
213 AuthorizationSet* software_enforced_characteristics) {
214 String16 key_name16(key_name.data(), key_name.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700215 ::android::security::keymaster::KeyCharacteristics characteristics;
216 int32_t result;
217 auto binder_result = keystore_->getKeyCharacteristics(
218 key_name16, android::security::keymaster::KeymasterBlob(),
219 android::security::keymaster::KeymasterBlob(), kDefaultUID, &characteristics, &result);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100220
221 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
222 * There are no references to Parcel memory after that, and ownership of the newly acquired
223 * memory is with the AuthorizationSet objects. */
Shawn Willden0329a822017-12-04 13:55:14 -0700224 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700225 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
226 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700227}
228
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700229KeyStoreNativeReturnCode
230KeystoreClientImpl::importKey(const std::string& key_name, const AuthorizationSet& key_parameters,
231 KeyFormat key_format, const std::string& key_data,
232 AuthorizationSet* hardware_enforced_characteristics,
233 AuthorizationSet* software_enforced_characteristics) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700234 String16 key_name16(key_name.data(), key_name.size());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100235 auto hidlKeyData = blob2hidlVec(key_data);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700236 ::android::security::keymaster::KeyCharacteristics characteristics;
237 int32_t result;
238 auto binder_result = keystore_->importKey(
239 key_name16, ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
240 (int)key_format, hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics, &result);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100241 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
242 * There are no references to Parcel memory after that, and ownership of the newly acquired
243 * memory is with the AuthorizationSet objects. */
Shawn Willden0329a822017-12-04 13:55:14 -0700244 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700245 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
246 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700247}
248
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100249KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700250 const std::string& key_name,
251 std::string* export_data) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700252 String16 key_name16(key_name.data(), key_name.size());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700253 ExportResult export_result;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700254 auto binder_result = keystore_->exportKey(
255 key_name16, (int)export_format, android::security::keymaster::KeymasterBlob(),
256 android::security::keymaster::KeymasterBlob(), kDefaultUID, &export_result);
257 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100258 *export_data = hidlVec2String(export_result.exportData);
259 return export_result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700260}
261
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100262KeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700263 String16 key_name16(key_name.data(), key_name.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700264 int32_t result;
265 auto binder_result = keystore_->del(key_name16, kDefaultUID, &result);
266 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
267 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700268}
269
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100270KeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() {
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700271 int32_t result;
272 auto binder_result = keystore_->clear_uid(kDefaultUID, &result);
273 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
274 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700275}
276
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700277KeyStoreNativeReturnCode
278KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
279 const AuthorizationSet& input_parameters,
280 AuthorizationSet* output_parameters, uint64_t* handle) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700281 android::sp<android::IBinder> token(new android::BBinder);
282 String16 key_name16(key_name.data(), key_name.size());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700283 OperationResult result;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700284 auto binder_result = keystore_->begin(
285 token, key_name16, (int)purpose, true /*pruneable*/,
286 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
287 hidl_vec<uint8_t>() /* entropy */, kDefaultUID, &result);
288 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100289 if (result.resultCode.isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700290 *handle = getNextVirtualHandle();
291 active_operations_[*handle] = result.token;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100292 if (result.outParams.size()) {
293 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700294 }
295 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100296 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700297}
298
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700299KeyStoreNativeReturnCode
300KeystoreClientImpl::updateOperation(uint64_t handle, const AuthorizationSet& input_parameters,
301 const std::string& input_data, size_t* num_input_bytes_consumed,
302 AuthorizationSet* output_parameters, std::string* output_data) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700303 if (active_operations_.count(handle) == 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100304 return ErrorCode::INVALID_OPERATION_HANDLE;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700305 }
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700306 OperationResult result;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100307 auto hidlInputData = blob2hidlVec(input_data);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700308 auto binder_result = keystore_->update(
309 active_operations_[handle],
310 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
311 hidlInputData, &result);
312 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100313
314 if (result.resultCode.isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700315 *num_input_bytes_consumed = result.inputConsumed;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100316 if (result.outParams.size()) {
317 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700318 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100319 // TODO verify that append should not be assign
320 output_data->append(hidlVec2String(result.data));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700321 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100322 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700323}
324
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700325KeyStoreNativeReturnCode
326KeystoreClientImpl::finishOperation(uint64_t handle, const AuthorizationSet& input_parameters,
327 const std::string& signature_to_verify,
328 AuthorizationSet* output_parameters, std::string* output_data) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700329 if (active_operations_.count(handle) == 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100330 return ErrorCode::INVALID_OPERATION_HANDLE;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700331 }
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700332 OperationResult result;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100333 auto hidlSignature = blob2hidlVec(signature_to_verify);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700334 auto binder_result = keystore_->finish(
335 active_operations_[handle],
336 android::security::keymaster::KeymasterArguments(input_parameters.hidl_data()),
337 (std::vector<uint8_t>)hidlSignature, hidl_vec<uint8_t>(), &result);
338 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100339
340 if (result.resultCode.isOk()) {
341 if (result.outParams.size()) {
342 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700343 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100344 // TODO verify that append should not be assign
345 output_data->append(hidlVec2String(result.data));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700346 active_operations_.erase(handle);
347 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100348 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700349}
350
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100351KeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700352 if (active_operations_.count(handle) == 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100353 return ErrorCode::INVALID_OPERATION_HANDLE;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700354 }
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700355 int32_t result;
356 // Current implementation does not return exceptions in android::binder::Status
357 auto binder_result = keystore_->abort(active_operations_[handle], &result);
358 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
359 if (KeyStoreNativeReturnCode(result).isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700360 active_operations_.erase(handle);
361 }
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700362 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700363}
364
365bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
366 String16 key_name16(key_name.data(), key_name.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700367 int32_t result;
368 auto binder_result = keystore_->exist(key_name16, kDefaultUID, &result);
369 if (!binder_result.isOk()) return false; // binder error
370 return result;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700371}
372
373bool KeystoreClientImpl::listKeys(const std::string& prefix,
374 std::vector<std::string>* key_name_list) {
375 String16 prefix16(prefix.data(), prefix.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700376 std::vector<::android::String16> matches;
377 auto binder_result = keystore_->list(prefix16, kDefaultUID, &matches);
378 if (!binder_result.isOk()) return false;
379
380 for (const auto& match : matches) {
381 android::String8 key_name(match);
382 key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size()));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700383 }
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700384 return true;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700385}
386
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100387uint64_t KeystoreClientImpl::getNextVirtualHandle() {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700388 return next_virtual_handle_++;
389}
390
Darren Krahn251cb282015-09-28 08:51:18 -0700391bool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name) {
392 bool key_exists = doesKeyExist(key_name);
393 if (key_exists) {
394 bool verified = false;
395 if (!verifyEncryptionKeyAttributes(key_name, &verified)) {
396 return false;
397 }
398 if (!verified) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100399 auto result = deleteKey(key_name);
400 if (!result.isOk()) {
401 ALOGE("Failed to delete invalid encryption key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700402 return false;
403 }
404 key_exists = false;
405 }
406 }
407 if (!key_exists) {
408 AuthorizationSetBuilder key_parameters;
409 key_parameters.AesEncryptionKey(kAESKeySize)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100410 .Padding(PaddingMode::PKCS7)
411 .Authorization(TAG_BLOCK_MODE, BlockMode::CBC)
412 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahn251cb282015-09-28 08:51:18 -0700413 AuthorizationSet hardware_enforced_characteristics;
414 AuthorizationSet software_enforced_characteristics;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700415 auto result = generateKey(key_name, key_parameters, &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
428bool KeystoreClientImpl::createOrVerifyAuthenticationKey(const std::string& key_name) {
429 bool key_exists = doesKeyExist(key_name);
430 if (key_exists) {
431 bool verified = false;
432 if (!verifyAuthenticationKeyAttributes(key_name, &verified)) {
433 return false;
434 }
435 if (!verified) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100436 auto result = deleteKey(key_name);
437 if (!result.isOk()) {
438 ALOGE("Failed to delete invalid authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700439 return false;
440 }
441 key_exists = false;
442 }
443 }
444 if (!key_exists) {
445 AuthorizationSetBuilder key_parameters;
446 key_parameters.HmacKey(kHMACKeySize)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100447 .Digest(Digest::SHA_2_256)
448 .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize)
449 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahn251cb282015-09-28 08:51:18 -0700450 AuthorizationSet hardware_enforced_characteristics;
451 AuthorizationSet software_enforced_characteristics;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700452 auto result = generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
453 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100454 if (!result.isOk()) {
455 ALOGE("Failed to generate authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700456 return false;
457 }
458 if (hardware_enforced_characteristics.size() == 0) {
459 ALOGW("WARNING: Authentication key is not hardware-backed.");
460 }
461 }
462 return true;
463}
464
465bool KeystoreClientImpl::verifyEncryptionKeyAttributes(const std::string& key_name,
466 bool* verified) {
467 AuthorizationSet hardware_enforced_characteristics;
468 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100469 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700470 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100471 if (!result.isOk()) {
472 ALOGE("Failed to query encryption key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700473 return false;
474 }
475 *verified = true;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100476 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700477 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100478 if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
Darren Krahn251cb282015-09-28 08:51:18 -0700479 ALOGW("Found encryption key with invalid algorithm.");
480 *verified = false;
481 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100482 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700483 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100484 if (!key_size.isOk() || key_size.value() != kAESKeySize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700485 ALOGW("Found encryption key with invalid size.");
486 *verified = false;
487 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100488 auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700489 software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100490 if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
Darren Krahn251cb282015-09-28 08:51:18 -0700491 ALOGW("Found encryption key with invalid block mode.");
492 *verified = false;
493 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100494 auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700495 software_enforced_characteristics.GetTagValue(TAG_PADDING));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100496 if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
Darren Krahn251cb282015-09-28 08:51:18 -0700497 ALOGW("Found encryption key with invalid padding mode.");
498 *verified = false;
499 }
500 if (hardware_enforced_characteristics.size() == 0) {
501 ALOGW("WARNING: Encryption key is not hardware-backed.");
502 }
503 return true;
504}
505
506bool KeystoreClientImpl::verifyAuthenticationKeyAttributes(const std::string& key_name,
507 bool* verified) {
508 AuthorizationSet hardware_enforced_characteristics;
509 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100510 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700511 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100512 if (!result.isOk()) {
513 ALOGE("Failed to query authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700514 return false;
515 }
516 *verified = true;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100517 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700518 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
519 if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC) {
Darren Krahn251cb282015-09-28 08:51:18 -0700520 ALOGW("Found authentication key with invalid algorithm.");
521 *verified = false;
522 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100523 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700524 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100525 if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700526 ALOGW("Found authentication key with invalid size.");
527 *verified = false;
528 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100529 auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700530 software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100531 if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700532 ALOGW("Found authentication key with invalid minimum mac size.");
533 *verified = false;
534 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100535 auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700536 software_enforced_characteristics.GetTagValue(TAG_DIGEST));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100537 if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
Darren Krahn251cb282015-09-28 08:51:18 -0700538 ALOGW("Found authentication key with invalid digest list.");
539 *verified = false;
540 }
541 if (hardware_enforced_characteristics.size() == 0) {
542 ALOGW("WARNING: Authentication key is not hardware-backed.");
543 }
544 return true;
545}
546
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700547} // namespace keystore