blob: f9df13492161910343dabde623ed484ee90e048b [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
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010022#include <binder/IBinder.h>
23#include <binder/IInterface.h>
24#include <binder/IServiceManager.h>
25#include <keystore/IKeystoreService.h>
26#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 -070035using android::ExportResult;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010036using keystore::KeyCharacteristics;
Darren Krahn69a3dbc2015-09-22 16:21:04 -070037using android::OperationResult;
38using android::String16;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010039using keystore::AuthorizationSet;
40using keystore::AuthorizationSetBuilder;
Darren Krahn69a3dbc2015-09-22 16:21:04 -070041
42namespace {
43
44// Use the UID of the current process.
45const int kDefaultUID = -1;
Darren Krahn251cb282015-09-28 08:51:18 -070046const char kEncryptSuffix[] = "_ENC";
47const char kAuthenticateSuffix[] = "_AUTH";
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010048constexpr uint32_t kAESKeySize = 256; // bits
49constexpr uint32_t kHMACKeySize = 256; // bits
50constexpr uint32_t kHMACOutputSize = 256; // bits
Darren Krahnc8eca232015-10-16 10:54:43 -070051
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"));
59 keystore_ = android::interface_cast<android::IKeystoreService>(keystore_binder_);
60}
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);
89 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;
157 auto result =
Darren Krahn251cb282015-09-28 08:51:18 -0700158 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
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100181KeyStoreNativeReturnCode KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy) {
182 return keystore_->addRngEntropy(blob2hidlVec(entropy));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700183}
184
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100185KeyStoreNativeReturnCode KeystoreClientImpl::generateKey(const std::string& key_name,
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700186 const AuthorizationSet& key_parameters,
187 AuthorizationSet* hardware_enforced_characteristics,
188 AuthorizationSet* software_enforced_characteristics) {
189 String16 key_name16(key_name.data(), key_name.size());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700190 KeyCharacteristics characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100191 auto result =
192 keystore_->generateKey(key_name16, key_parameters.hidl_data(), hidl_vec<uint8_t>(),
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700193 kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100194
195 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
196 * There are no references to Parcel memory after that, and ownership of the newly acquired
197 * memory is with the AuthorizationSet objects. */
198 *hardware_enforced_characteristics = characteristics.teeEnforced;
199 *software_enforced_characteristics = characteristics.softwareEnforced;
200 return result;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700201}
202
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100203KeyStoreNativeReturnCode
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700204KeystoreClientImpl::getKeyCharacteristics(const std::string& key_name,
205 AuthorizationSet* hardware_enforced_characteristics,
206 AuthorizationSet* software_enforced_characteristics) {
207 String16 key_name16(key_name.data(), key_name.size());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700208 KeyCharacteristics characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100209 auto result = keystore_->getKeyCharacteristics(key_name16, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(),
Gaurav Shahce1f9132015-11-02 16:26:57 -0800210 kDefaultUID, &characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100211
212 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
213 * There are no references to Parcel memory after that, and ownership of the newly acquired
214 * memory is with the AuthorizationSet objects. */
215 *hardware_enforced_characteristics = characteristics.teeEnforced;
216 *software_enforced_characteristics = characteristics.softwareEnforced;
217 return result;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700218}
219
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100220KeyStoreNativeReturnCode KeystoreClientImpl::importKey(const std::string& key_name,
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700221 const AuthorizationSet& key_parameters,
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100222 KeyFormat key_format,
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700223 const std::string& key_data,
224 AuthorizationSet* hardware_enforced_characteristics,
225 AuthorizationSet* software_enforced_characteristics) {
226 String16 key_name16(key_name.data(), key_name.size());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100227 auto hidlKeyData = blob2hidlVec(key_data);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700228 KeyCharacteristics characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100229 auto result = keystore_->importKey(key_name16, key_parameters.hidl_data(), key_format,
230 hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics);
231
232 /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
233 * There are no references to Parcel memory after that, and ownership of the newly acquired
234 * memory is with the AuthorizationSet objects. */
235 *hardware_enforced_characteristics = characteristics.teeEnforced;
236 *software_enforced_characteristics = characteristics.softwareEnforced;
237 return result;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700238}
239
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100240KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700241 const std::string& key_name, std::string* export_data) {
242 String16 key_name16(key_name.data(), key_name.size());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700243 ExportResult export_result;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100244 keystore_->exportKey(key_name16, export_format, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(),
Gaurav Shahce1f9132015-11-02 16:26:57 -0800245 kDefaultUID, &export_result);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100246 *export_data = hidlVec2String(export_result.exportData);
247 return export_result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700248}
249
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100250KeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700251 String16 key_name16(key_name.data(), key_name.size());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100252 return keystore_->del(key_name16, kDefaultUID);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700253}
254
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100255KeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() {
256 return keystore_->clear_uid(kDefaultUID);
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700257}
258
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100259KeyStoreNativeReturnCode KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700260 const AuthorizationSet& input_parameters,
261 AuthorizationSet* output_parameters,
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100262 uint64_t* handle) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700263 android::sp<android::IBinder> token(new android::BBinder);
264 String16 key_name16(key_name.data(), key_name.size());
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700265 OperationResult result;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100266 keystore_->begin(token, key_name16, purpose, true /*pruneable*/, input_parameters.hidl_data(),
267 hidl_vec<uint8_t>(), kDefaultUID, &result);
268 if (result.resultCode.isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700269 *handle = getNextVirtualHandle();
270 active_operations_[*handle] = result.token;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100271 if (result.outParams.size()) {
272 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700273 }
274 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100275 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700276}
277
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100278KeyStoreNativeReturnCode KeystoreClientImpl::updateOperation(uint64_t handle,
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700279 const AuthorizationSet& input_parameters,
280 const std::string& input_data,
281 size_t* num_input_bytes_consumed,
282 AuthorizationSet* output_parameters,
283 std::string* output_data) {
284 if (active_operations_.count(handle) == 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100285 return ErrorCode::INVALID_OPERATION_HANDLE;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700286 }
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700287 OperationResult result;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100288 auto hidlInputData = blob2hidlVec(input_data);
289 keystore_->update(active_operations_[handle], input_parameters.hidl_data(), hidlInputData,
290 &result);
291
292 if (result.resultCode.isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700293 *num_input_bytes_consumed = result.inputConsumed;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100294 if (result.outParams.size()) {
295 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700296 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100297 // TODO verify that append should not be assign
298 output_data->append(hidlVec2String(result.data));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700299 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100300 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700301}
302
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100303KeyStoreNativeReturnCode KeystoreClientImpl::finishOperation(uint64_t handle,
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700304 const AuthorizationSet& input_parameters,
305 const std::string& signature_to_verify,
306 AuthorizationSet* output_parameters,
307 std::string* output_data) {
308 if (active_operations_.count(handle) == 0) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100309 return ErrorCode::INVALID_OPERATION_HANDLE;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700310 }
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700311 OperationResult result;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100312 auto hidlSignature = blob2hidlVec(signature_to_verify);
313 keystore_->finish(active_operations_[handle], input_parameters.hidl_data(),
314 hidlSignature,
315 hidl_vec<uint8_t>(), &result);
316
317 if (result.resultCode.isOk()) {
318 if (result.outParams.size()) {
319 *output_parameters = result.outParams;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700320 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100321 // TODO verify that append should not be assign
322 output_data->append(hidlVec2String(result.data));
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700323 active_operations_.erase(handle);
324 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100325 return result.resultCode;
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700326}
327
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100328KeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) {
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 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100332 auto error_code = keystore_->abort(active_operations_[handle]);
333 if (error_code.isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700334 active_operations_.erase(handle);
335 }
336 return error_code;
337}
338
339bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
340 String16 key_name16(key_name.data(), key_name.size());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100341 auto error_code = keystore_->exist(key_name16, kDefaultUID);
342 return error_code.isOk();
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700343}
344
345bool KeystoreClientImpl::listKeys(const std::string& prefix,
346 std::vector<std::string>* key_name_list) {
347 String16 prefix16(prefix.data(), prefix.size());
348 android::Vector<String16> matches;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100349 auto error_code = keystore_->list(prefix16, kDefaultUID, &matches);
350 if (error_code.isOk()) {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700351 for (const auto& match : matches) {
352 android::String8 key_name(match);
353 key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size()));
354 }
355 return true;
356 }
357 return false;
358}
359
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100360uint64_t KeystoreClientImpl::getNextVirtualHandle() {
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700361 return next_virtual_handle_++;
362}
363
Darren Krahn251cb282015-09-28 08:51:18 -0700364bool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name) {
365 bool key_exists = doesKeyExist(key_name);
366 if (key_exists) {
367 bool verified = false;
368 if (!verifyEncryptionKeyAttributes(key_name, &verified)) {
369 return false;
370 }
371 if (!verified) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100372 auto result = deleteKey(key_name);
373 if (!result.isOk()) {
374 ALOGE("Failed to delete invalid encryption key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700375 return false;
376 }
377 key_exists = false;
378 }
379 }
380 if (!key_exists) {
381 AuthorizationSetBuilder key_parameters;
382 key_parameters.AesEncryptionKey(kAESKeySize)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100383 .Padding(PaddingMode::PKCS7)
384 .Authorization(TAG_BLOCK_MODE, BlockMode::CBC)
385 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahn251cb282015-09-28 08:51:18 -0700386 AuthorizationSet hardware_enforced_characteristics;
387 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100388 auto result =
389 generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
Darren Krahn251cb282015-09-28 08:51:18 -0700390 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100391 if (!result.isOk()) {
392 ALOGE("Failed to generate encryption key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700393 return false;
394 }
395 if (hardware_enforced_characteristics.size() == 0) {
396 ALOGW("WARNING: Encryption key is not hardware-backed.");
397 }
398 }
399 return true;
400}
401
402bool KeystoreClientImpl::createOrVerifyAuthenticationKey(const std::string& key_name) {
403 bool key_exists = doesKeyExist(key_name);
404 if (key_exists) {
405 bool verified = false;
406 if (!verifyAuthenticationKeyAttributes(key_name, &verified)) {
407 return false;
408 }
409 if (!verified) {
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100410 auto result = deleteKey(key_name);
411 if (!result.isOk()) {
412 ALOGE("Failed to delete invalid authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700413 return false;
414 }
415 key_exists = false;
416 }
417 }
418 if (!key_exists) {
419 AuthorizationSetBuilder key_parameters;
420 key_parameters.HmacKey(kHMACKeySize)
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100421 .Digest(Digest::SHA_2_256)
422 .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize)
423 .Authorization(TAG_NO_AUTH_REQUIRED);
Darren Krahn251cb282015-09-28 08:51:18 -0700424 AuthorizationSet hardware_enforced_characteristics;
425 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100426 auto result =
427 generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
Darren Krahn251cb282015-09-28 08:51:18 -0700428 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100429 if (!result.isOk()) {
430 ALOGE("Failed to generate authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700431 return false;
432 }
433 if (hardware_enforced_characteristics.size() == 0) {
434 ALOGW("WARNING: Authentication key is not hardware-backed.");
435 }
436 }
437 return true;
438}
439
440bool KeystoreClientImpl::verifyEncryptionKeyAttributes(const std::string& key_name,
441 bool* verified) {
442 AuthorizationSet hardware_enforced_characteristics;
443 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100444 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
Darren Krahn251cb282015-09-28 08:51:18 -0700445 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100446 if (!result.isOk()) {
447 ALOGE("Failed to query encryption key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700448 return false;
449 }
450 *verified = true;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100451 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
452 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
453 if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
Darren Krahn251cb282015-09-28 08:51:18 -0700454 ALOGW("Found encryption key with invalid algorithm.");
455 *verified = false;
456 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100457 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
458 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
459 if (!key_size.isOk() || key_size.value() != kAESKeySize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700460 ALOGW("Found encryption key with invalid size.");
461 *verified = false;
462 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100463 auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
464 software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
465 if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
Darren Krahn251cb282015-09-28 08:51:18 -0700466 ALOGW("Found encryption key with invalid block mode.");
467 *verified = false;
468 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100469 auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
470 software_enforced_characteristics.GetTagValue(TAG_PADDING));
471 if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
Darren Krahn251cb282015-09-28 08:51:18 -0700472 ALOGW("Found encryption key with invalid padding mode.");
473 *verified = false;
474 }
475 if (hardware_enforced_characteristics.size() == 0) {
476 ALOGW("WARNING: Encryption key is not hardware-backed.");
477 }
478 return true;
479}
480
481bool KeystoreClientImpl::verifyAuthenticationKeyAttributes(const std::string& key_name,
482 bool* verified) {
483 AuthorizationSet hardware_enforced_characteristics;
484 AuthorizationSet software_enforced_characteristics;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100485 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
Darren Krahn251cb282015-09-28 08:51:18 -0700486 &software_enforced_characteristics);
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100487 if (!result.isOk()) {
488 ALOGE("Failed to query authentication key: %d", int32_t(result));
Darren Krahn251cb282015-09-28 08:51:18 -0700489 return false;
490 }
491 *verified = true;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100492 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
493 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
494 if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC){
Darren Krahn251cb282015-09-28 08:51:18 -0700495 ALOGW("Found authentication key with invalid algorithm.");
496 *verified = false;
497 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100498 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
499 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
500 if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700501 ALOGW("Found authentication key with invalid size.");
502 *verified = false;
503 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100504 auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
505 software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
506 if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
Darren Krahn251cb282015-09-28 08:51:18 -0700507 ALOGW("Found authentication key with invalid minimum mac size.");
508 *verified = false;
509 }
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100510 auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
511 software_enforced_characteristics.GetTagValue(TAG_DIGEST));
512 if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
Darren Krahn251cb282015-09-28 08:51:18 -0700513 ALOGW("Found authentication key with invalid digest list.");
514 *verified = false;
515 }
516 if (hardware_enforced_characteristics.size() == 0) {
517 ALOGW("WARNING: Authentication key is not hardware-backed.");
518 }
519 return true;
520}
521
Darren Krahn69a3dbc2015-09-22 16:21:04 -0700522} // namespace keystore