blob: 99fe60673968c46e016d395d383beffec90ae49c [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
Darren Krahn251cb282015-09-28 08:51:18 -070031#include "keystore_client.pb.h"
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010032#include <keystore/authorization_set.h>
33#include <keystore/keystore_hidl_support.h>
Darren Krahn251cb282015-09-28 08:51:18 -070034
Darren Krahn69a3dbc2015-09-22 16:21:04 -070035namespace {
36
37// Use the UID of the current process.
38const int kDefaultUID = -1;
Darren Krahn251cb282015-09-28 08:51:18 -070039const char kEncryptSuffix[] = "_ENC";
40const char kAuthenticateSuffix[] = "_AUTH";
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010041constexpr uint32_t kAESKeySize = 256; // bits
42constexpr uint32_t kHMACKeySize = 256; // bits
43constexpr uint32_t kHMACOutputSize = 256; // bits
Darren Krahnc8eca232015-10-16 10:54:43 -070044
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -070045using android::String16;
46using android::security::keymaster::ExportResult;
47using android::security::keymaster::OperationResult;
48using keystore::AuthorizationSet;
49using keystore::AuthorizationSetBuilder;
50using keystore::KeyCharacteristics;
51using keystore::KeyStoreServiceReturnCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -070052} // namespace
53
54namespace keystore {
55
56KeystoreClientImpl::KeystoreClientImpl() {
57 service_manager_ = android::defaultServiceManager();
58 keystore_binder_ = service_manager_->getService(String16("android.security.keystore"));
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -070059 keystore_ = android::interface_cast<android::security::IKeystoreService>(keystore_binder_);
Darren Krahn69a3dbc2015-09-22 16:21:04 -070060}
61
Darren Krahn251cb282015-09-28 08:51:18 -070062bool KeystoreClientImpl::encryptWithAuthentication(const std::string& key_name,
63 const std::string& data,
64 std::string* encrypted_data) {
65 // The encryption algorithm is AES-256-CBC with PKCS #7 padding and a random
66 // IV. The authentication algorithm is HMAC-SHA256 and is computed over the
67 // cipher-text (i.e. Encrypt-then-MAC approach). This was chosen over AES-GCM
68 // because hardware support for GCM is not mandatory for all Brillo devices.
69 std::string encryption_key_name = key_name + kEncryptSuffix;
70 if (!createOrVerifyEncryptionKey(encryption_key_name)) {
71 return false;
72 }
73 std::string authentication_key_name = key_name + kAuthenticateSuffix;
74 if (!createOrVerifyAuthenticationKey(authentication_key_name)) {
75 return false;
76 }
77 AuthorizationSetBuilder encrypt_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010078 encrypt_params.Padding(PaddingMode::PKCS7);
79 encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
Darren Krahn251cb282015-09-28 08:51:18 -070080 AuthorizationSet output_params;
81 std::string raw_encrypted_data;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010082 if (!oneShotOperation(KeyPurpose::ENCRYPT, encryption_key_name, encrypt_params, data,
Darren Krahn251cb282015-09-28 08:51:18 -070083 std::string(), /* signature_to_verify */
84 &output_params, &raw_encrypted_data)) {
85 ALOGE("Encrypt: AES operation failed.");
86 return false;
87 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010088 auto init_vector_blob = output_params.GetTagValue(TAG_NONCE);
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -070089 if (!init_vector_blob.isOk()) {
Darren Krahn251cb282015-09-28 08:51:18 -070090 ALOGE("Encrypt: Missing initialization vector.");
91 return false;
92 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010093 std::string init_vector = hidlVec2String(init_vector_blob.value());
Darren Krahn251cb282015-09-28 08:51:18 -070094
95 AuthorizationSetBuilder authenticate_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010096 authenticate_params.Digest(Digest::SHA_2_256);
97 authenticate_params.Authorization(TAG_MAC_LENGTH, kHMACOutputSize);
Darren Krahn251cb282015-09-28 08:51:18 -070098 std::string raw_authentication_data;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010099 if (!oneShotOperation(KeyPurpose::SIGN, authentication_key_name, authenticate_params,
Darren Krahn251cb282015-09-28 08:51:18 -0700100 init_vector + raw_encrypted_data, std::string(), /* signature_to_verify */
101 &output_params, &raw_authentication_data)) {
102 ALOGE("Encrypt: HMAC operation failed.");
103 return false;
104 }
105 EncryptedData protobuf;
106 protobuf.set_init_vector(init_vector);
107 protobuf.set_authentication_data(raw_authentication_data);
108 protobuf.set_encrypted_data(raw_encrypted_data);
109 if (!protobuf.SerializeToString(encrypted_data)) {
110 ALOGE("Encrypt: Failed to serialize EncryptedData protobuf.");
111 return false;
112 }
113 return true;
114}
115
116bool KeystoreClientImpl::decryptWithAuthentication(const std::string& key_name,
117 const std::string& encrypted_data,
118 std::string* data) {
119 EncryptedData protobuf;
120 if (!protobuf.ParseFromString(encrypted_data)) {
121 ALOGE("Decrypt: Failed to parse EncryptedData protobuf.");
122 }
123 // Verify authentication before attempting decryption.
124 std::string authentication_key_name = key_name + kAuthenticateSuffix;
125 AuthorizationSetBuilder authenticate_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100126 authenticate_params.Digest(Digest::SHA_2_256);
Darren Krahn251cb282015-09-28 08:51:18 -0700127 AuthorizationSet output_params;
128 std::string output_data;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100129 if (!oneShotOperation(KeyPurpose::VERIFY, authentication_key_name, authenticate_params,
Darren Krahn251cb282015-09-28 08:51:18 -0700130 protobuf.init_vector() + protobuf.encrypted_data(),
131 protobuf.authentication_data(), &output_params, &output_data)) {
132 ALOGE("Decrypt: HMAC operation failed.");
133 return false;
134 }
135 std::string encryption_key_name = key_name + kEncryptSuffix;
136 AuthorizationSetBuilder encrypt_params;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100137 encrypt_params.Padding(PaddingMode::PKCS7);
138 encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
139 encrypt_params.Authorization(TAG_NONCE, protobuf.init_vector().data(),
Darren Krahn251cb282015-09-28 08:51:18 -0700140 protobuf.init_vector().size());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100141 if (!oneShotOperation(KeyPurpose::DECRYPT, encryption_key_name, encrypt_params,
Darren Krahn251cb282015-09-28 08:51:18 -0700142 protobuf.encrypted_data(), std::string(), /* signature_to_verify */
143 &output_params, data)) {
144 ALOGE("Decrypt: AES operation failed.");
145 return false;
146 }
147 return true;
148}
149
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100150bool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string& key_name,
151 const AuthorizationSet& input_parameters,
Darren Krahn251cb282015-09-28 08:51:18 -0700152 const std::string& input_data,
153 const std::string& signature_to_verify,
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100154 AuthorizationSet* output_parameters,
Darren Krahn251cb282015-09-28 08:51:18 -0700155 std::string* output_data) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100156 uint64_t handle;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700157 auto result = beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100158 if (!result.isOk()) {
159 ALOGE("BeginOperation failed: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700160 return false;
161 }
162 AuthorizationSet empty_params;
163 size_t num_input_bytes_consumed;
164 AuthorizationSet ignored_params;
165 result = updateOperation(handle, empty_params, input_data, &num_input_bytes_consumed,
166 &ignored_params, output_data);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100167 if (!result.isOk()) {
168 ALOGE("UpdateOperation failed: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700169 return false;
170 }
171 result =
172 finishOperation(handle, empty_params, signature_to_verify, &ignored_params, output_data);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100173 if (!result.isOk()) {
174 ALOGE("FinishOperation failed: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700175 return false;
176 }
177 return true;
178}
179
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700180KeyStoreNativeReturnCode
181KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy) {
182 int32_t result;
183 auto binder_result = keystore_->addRngEntropy(blob2hidlVec(entropy), &result);
184 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
185 return KeyStoreNativeReturnCode(result);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700186}
187
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700188KeyStoreNativeReturnCode
189KeystoreClientImpl::generateKey(const std::string& key_name, const AuthorizationSet& key_parameters,
190 AuthorizationSet* hardware_enforced_characteristics,
191 AuthorizationSet* software_enforced_characteristics) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700192 String16 key_name16(key_name.data(), key_name.size());
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700193 ::android::security::keymaster::KeyCharacteristics characteristics;
194 int32_t result;
195 auto binder_result = keystore_->generateKey(
196 key_name16, ::android::security::keymaster::KeymasterArguments(key_parameters.hidl_data()),
197 hidl_vec<uint8_t>() /* entropy */, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics,
198 &result);
199 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. */
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700204 *hardware_enforced_characteristics = characteristics.teeEnforced.getParameters();
205 *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. */
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700223 *hardware_enforced_characteristics = characteristics.teeEnforced.getParameters();
224 *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. */
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700243 *hardware_enforced_characteristics = characteristics.teeEnforced.getParameters();
244 *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
Darren Krahn251cb282015-09-28 08:51:18 -0700390bool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name) {
391 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;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700414 auto result = generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
415 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100416 if (!result.isOk()) {
417 ALOGE("Failed to generate encryption key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700418 return false;
419 }
420 if (hardware_enforced_characteristics.size() == 0) {
421 ALOGW("WARNING: Encryption key is not hardware-backed.");
422 }
423 }
424 return true;
425}
426
427bool KeystoreClientImpl::createOrVerifyAuthenticationKey(const std::string& key_name) {
428 bool key_exists = doesKeyExist(key_name);
429 if (key_exists) {
430 bool verified = false;
431 if (!verifyAuthenticationKeyAttributes(key_name, &verified)) {
432 return false;
433 }
434 if (!verified) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100435 auto result = deleteKey(key_name);
436 if (!result.isOk()) {
437 ALOGE("Failed to delete invalid authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700438 return false;
439 }
440 key_exists = false;
441 }
442 }
443 if (!key_exists) {
444 AuthorizationSetBuilder key_parameters;
445 key_parameters.HmacKey(kHMACKeySize)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100446 .Digest(Digest::SHA_2_256)
447 .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize)
448 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahn251cb282015-09-28 08:51:18 -0700449 AuthorizationSet hardware_enforced_characteristics;
450 AuthorizationSet software_enforced_characteristics;
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700451 auto result = generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
452 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100453 if (!result.isOk()) {
454 ALOGE("Failed to generate authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700455 return false;
456 }
457 if (hardware_enforced_characteristics.size() == 0) {
458 ALOGW("WARNING: Authentication key is not hardware-backed.");
459 }
460 }
461 return true;
462}
463
464bool KeystoreClientImpl::verifyEncryptionKeyAttributes(const std::string& key_name,
465 bool* verified) {
466 AuthorizationSet hardware_enforced_characteristics;
467 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100468 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700469 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100470 if (!result.isOk()) {
471 ALOGE("Failed to query encryption key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700472 return false;
473 }
474 *verified = true;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100475 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700476 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100477 if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
Darren Krahn251cb282015-09-28 08:51:18 -0700478 ALOGW("Found encryption key with invalid algorithm.");
479 *verified = false;
480 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100481 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700482 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100483 if (!key_size.isOk() || key_size.value() != kAESKeySize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700484 ALOGW("Found encryption key with invalid size.");
485 *verified = false;
486 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100487 auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700488 software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100489 if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
Darren Krahn251cb282015-09-28 08:51:18 -0700490 ALOGW("Found encryption key with invalid block mode.");
491 *verified = false;
492 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100493 auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700494 software_enforced_characteristics.GetTagValue(TAG_PADDING));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100495 if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
Darren Krahn251cb282015-09-28 08:51:18 -0700496 ALOGW("Found encryption key with invalid padding mode.");
497 *verified = false;
498 }
499 if (hardware_enforced_characteristics.size() == 0) {
500 ALOGW("WARNING: Encryption key is not hardware-backed.");
501 }
502 return true;
503}
504
505bool KeystoreClientImpl::verifyAuthenticationKeyAttributes(const std::string& key_name,
506 bool* verified) {
507 AuthorizationSet hardware_enforced_characteristics;
508 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100509 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700510 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100511 if (!result.isOk()) {
512 ALOGE("Failed to query authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700513 return false;
514 }
515 *verified = true;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100516 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700517 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
518 if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC) {
Darren Krahn251cb282015-09-28 08:51:18 -0700519 ALOGW("Found authentication key with invalid algorithm.");
520 *verified = false;
521 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100522 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700523 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100524 if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700525 ALOGW("Found authentication key with invalid size.");
526 *verified = false;
527 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100528 auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700529 software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100530 if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700531 ALOGW("Found authentication key with invalid minimum mac size.");
532 *verified = false;
533 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100534 auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
Dmitry Dementyeva447b3c2017-10-27 23:09:53 -0700535 software_enforced_characteristics.GetTagValue(TAG_DIGEST));
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100536 if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
Darren Krahn251cb282015-09-28 08:51:18 -0700537 ALOGW("Found authentication key with invalid digest list.");
538 *verified = false;
539 }
540 if (hardware_enforced_characteristics.size() == 0) {
541 ALOGW("WARNING: Authentication key is not hardware-backed.");
542 }
543 return true;
544}
545
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700546} // namespace keystore