1 // 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
15 #define LOG_TAG "keystore_client"
16
17 #include "keystore/keystore_client_impl.h"
18
19 #include <string>
20 #include <vector>
21
22 #include <android/security/IKeystoreService.h>
23 #include <binder/IBinder.h>
24 #include <binder/IInterface.h>
25 #include <binder/IServiceManager.h>
26 #include <keystore/keystore.h>
27 #include <log/log.h>
28 #include <utils/String16.h>
29 #include <utils/String8.h>
30
31 #include <keystore/keymaster_types.h>
32 #include <keystore/keystore_hidl_support.h>
33
34 #include "keystore_client.pb.h"
35
36 namespace {
37
38 // Use the UID of the current process.
39 const int kDefaultUID = -1;
40 const char kEncryptSuffix[] = "_ENC";
41 const char kAuthenticateSuffix[] = "_AUTH";
42 constexpr uint32_t kAESKeySize = 256; // bits
43 constexpr uint32_t kHMACKeySize = 256; // bits
44 constexpr uint32_t kHMACOutputSize = 256; // bits
45
46 using android::String16;
47 using android::security::keymaster::ExportResult;
48 using android::security::keymaster::OperationResult;
49 using keystore::AuthorizationSet;
50 using keystore::AuthorizationSetBuilder;
51 using keystore::KeyCharacteristics;
52 using keystore::KeyStoreServiceReturnCode;
53 } // namespace
54
55 namespace keystore {
56
KeystoreClientImpl()57 KeystoreClientImpl::KeystoreClientImpl() {
58 service_manager_ = android::defaultServiceManager();
59 keystore_binder_ = service_manager_->getService(String16("android.security.keystore"));
60 keystore_ = android::interface_cast<android::security::IKeystoreService>(keystore_binder_);
61 }
62
encryptWithAuthentication(const std::string & key_name,const std::string & data,int32_t flags,std::string * encrypted_data)63 bool KeystoreClientImpl::encryptWithAuthentication(const std::string& key_name,
64 const std::string& data, int32_t flags,
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, flags)) {
72 return false;
73 }
74 std::string authentication_key_name = key_name + kAuthenticateSuffix;
75 if (!createOrVerifyAuthenticationKey(authentication_key_name, flags)) {
76 return false;
77 }
78 AuthorizationSetBuilder encrypt_params;
79 encrypt_params.Padding(PaddingMode::PKCS7);
80 encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
81 AuthorizationSet output_params;
82 std::string raw_encrypted_data;
83 if (!oneShotOperation(KeyPurpose::ENCRYPT, encryption_key_name, encrypt_params, data,
84 std::string(), /* signature_to_verify */
85 &output_params, &raw_encrypted_data)) {
86 ALOGE("Encrypt: AES operation failed.");
87 return false;
88 }
89 auto init_vector_blob = output_params.GetTagValue(TAG_NONCE);
90 if (!init_vector_blob.isOk()) {
91 ALOGE("Encrypt: Missing initialization vector.");
92 return false;
93 }
94 std::string init_vector = hidlVec2String(init_vector_blob.value());
95
96 AuthorizationSetBuilder authenticate_params;
97 authenticate_params.Digest(Digest::SHA_2_256);
98 authenticate_params.Authorization(TAG_MAC_LENGTH, kHMACOutputSize);
99 std::string raw_authentication_data;
100 if (!oneShotOperation(KeyPurpose::SIGN, authentication_key_name, authenticate_params,
101 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
decryptWithAuthentication(const std::string & key_name,const std::string & encrypted_data,std::string * data)117 bool 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;
127 authenticate_params.Digest(Digest::SHA_2_256);
128 AuthorizationSet output_params;
129 std::string output_data;
130 if (!oneShotOperation(KeyPurpose::VERIFY, authentication_key_name, authenticate_params,
131 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;
138 encrypt_params.Padding(PaddingMode::PKCS7);
139 encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
140 encrypt_params.Authorization(TAG_NONCE, protobuf.init_vector().data(),
141 protobuf.init_vector().size());
142 if (!oneShotOperation(KeyPurpose::DECRYPT, encryption_key_name, encrypt_params,
143 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
oneShotOperation(KeyPurpose purpose,const std::string & key_name,const AuthorizationSet & input_parameters,const std::string & input_data,const std::string & signature_to_verify,AuthorizationSet * output_parameters,std::string * output_data)151 bool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string& key_name,
152 const AuthorizationSet& input_parameters,
153 const std::string& input_data,
154 const std::string& signature_to_verify,
155 AuthorizationSet* output_parameters,
156 std::string* output_data) {
157 uint64_t handle;
158 auto result = beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
159 if (!result.isOk()) {
160 ALOGE("BeginOperation failed: %d", int32_t(result));
161 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);
168 if (!result.isOk()) {
169 ALOGE("UpdateOperation failed: %d", int32_t(result));
170 return false;
171 }
172 result =
173 finishOperation(handle, empty_params, signature_to_verify, &ignored_params, output_data);
174 if (!result.isOk()) {
175 ALOGE("FinishOperation failed: %d", int32_t(result));
176 return false;
177 }
178 return true;
179 }
180
181 KeyStoreNativeReturnCode
addRandomNumberGeneratorEntropy(const std::string & entropy,int32_t flags)182 KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy, int32_t flags) {
183 int32_t result;
184 auto binder_result = keystore_->addRngEntropy(blob2hidlVec(entropy), flags, &result);
185 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
186 return KeyStoreNativeReturnCode(result);
187 }
188
189 KeyStoreNativeReturnCode
generateKey(const std::string & key_name,const AuthorizationSet & key_parameters,int32_t flags,AuthorizationSet * hardware_enforced_characteristics,AuthorizationSet * software_enforced_characteristics)190 KeystoreClientImpl::generateKey(const std::string& key_name, const AuthorizationSet& key_parameters,
191 int32_t flags, AuthorizationSet* hardware_enforced_characteristics,
192 AuthorizationSet* software_enforced_characteristics) {
193 String16 key_name16(key_name.data(), key_name.size());
194 ::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, flags, &characteristics, &result);
199 if (!binder_result.isOk()) return ResponseCode::SYSTEM_ERROR;
200
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. */
204 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
205 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
206 return KeyStoreNativeReturnCode(result);
207 }
208
209 KeyStoreNativeReturnCode
getKeyCharacteristics(const std::string & key_name,AuthorizationSet * hardware_enforced_characteristics,AuthorizationSet * software_enforced_characteristics)210 KeystoreClientImpl::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());
214 ::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);
219
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. */
223 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
224 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
225 return KeyStoreNativeReturnCode(result);
226 }
227
228 KeyStoreNativeReturnCode
importKey(const std::string & key_name,const AuthorizationSet & key_parameters,KeyFormat key_format,const std::string & key_data,AuthorizationSet * hardware_enforced_characteristics,AuthorizationSet * software_enforced_characteristics)229 KeystoreClientImpl::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) {
233 String16 key_name16(key_name.data(), key_name.size());
234 auto hidlKeyData = blob2hidlVec(key_data);
235 ::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);
240 /* 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. */
243 *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
244 *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
245 return KeyStoreNativeReturnCode(result);
246 }
247
exportKey(KeyFormat export_format,const std::string & key_name,std::string * export_data)248 KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
249 const std::string& key_name,
250 std::string* export_data) {
251 String16 key_name16(key_name.data(), key_name.size());
252 ExportResult export_result;
253 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;
257 *export_data = hidlVec2String(export_result.exportData);
258 return export_result.resultCode;
259 }
260
deleteKey(const std::string & key_name)261 KeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) {
262 String16 key_name16(key_name.data(), key_name.size());
263 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);
267 }
268
deleteAllKeys()269 KeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() {
270 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);
274 }
275
276 KeyStoreNativeReturnCode
beginOperation(KeyPurpose purpose,const std::string & key_name,const AuthorizationSet & input_parameters,AuthorizationSet * output_parameters,uint64_t * handle)277 KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
278 const AuthorizationSet& input_parameters,
279 AuthorizationSet* output_parameters, uint64_t* handle) {
280 android::sp<android::IBinder> token(new android::BBinder);
281 String16 key_name16(key_name.data(), key_name.size());
282 OperationResult result;
283 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;
288 if (result.resultCode.isOk()) {
289 *handle = getNextVirtualHandle();
290 active_operations_[*handle] = result.token;
291 if (result.outParams.size()) {
292 *output_parameters = result.outParams;
293 }
294 }
295 return result.resultCode;
296 }
297
298 KeyStoreNativeReturnCode
updateOperation(uint64_t handle,const AuthorizationSet & input_parameters,const std::string & input_data,size_t * num_input_bytes_consumed,AuthorizationSet * output_parameters,std::string * output_data)299 KeystoreClientImpl::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) {
302 if (active_operations_.count(handle) == 0) {
303 return ErrorCode::INVALID_OPERATION_HANDLE;
304 }
305 OperationResult result;
306 auto hidlInputData = blob2hidlVec(input_data);
307 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;
312
313 if (result.resultCode.isOk()) {
314 *num_input_bytes_consumed = result.inputConsumed;
315 if (result.outParams.size()) {
316 *output_parameters = result.outParams;
317 }
318 // TODO verify that append should not be assign
319 output_data->append(hidlVec2String(result.data));
320 }
321 return result.resultCode;
322 }
323
324 KeyStoreNativeReturnCode
finishOperation(uint64_t handle,const AuthorizationSet & input_parameters,const std::string & signature_to_verify,AuthorizationSet * output_parameters,std::string * output_data)325 KeystoreClientImpl::finishOperation(uint64_t handle, const AuthorizationSet& input_parameters,
326 const std::string& signature_to_verify,
327 AuthorizationSet* output_parameters, std::string* output_data) {
328 if (active_operations_.count(handle) == 0) {
329 return ErrorCode::INVALID_OPERATION_HANDLE;
330 }
331 OperationResult result;
332 auto hidlSignature = blob2hidlVec(signature_to_verify);
333 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;
338
339 if (result.resultCode.isOk()) {
340 if (result.outParams.size()) {
341 *output_parameters = result.outParams;
342 }
343 // TODO verify that append should not be assign
344 output_data->append(hidlVec2String(result.data));
345 active_operations_.erase(handle);
346 }
347 return result.resultCode;
348 }
349
abortOperation(uint64_t handle)350 KeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) {
351 if (active_operations_.count(handle) == 0) {
352 return ErrorCode::INVALID_OPERATION_HANDLE;
353 }
354 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()) {
359 active_operations_.erase(handle);
360 }
361 return KeyStoreNativeReturnCode(result);
362 }
363
doesKeyExist(const std::string & key_name)364 bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
365 String16 key_name16(key_name.data(), key_name.size());
366 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;
370 }
371
listKeys(const std::string & prefix,std::vector<std::string> * key_name_list)372 bool KeystoreClientImpl::listKeys(const std::string& prefix,
373 std::vector<std::string>* key_name_list) {
374 String16 prefix16(prefix.data(), prefix.size());
375 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()));
382 }
383 return true;
384 }
385
getNextVirtualHandle()386 uint64_t KeystoreClientImpl::getNextVirtualHandle() {
387 return next_virtual_handle_++;
388 }
389
createOrVerifyEncryptionKey(const std::string & key_name,int32_t flags)390 bool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name, int32_t flags) {
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) {
398 auto result = deleteKey(key_name);
399 if (!result.isOk()) {
400 ALOGE("Failed to delete invalid encryption key: %d", int32_t(result));
401 return false;
402 }
403 key_exists = false;
404 }
405 }
406 if (!key_exists) {
407 AuthorizationSetBuilder key_parameters;
408 key_parameters.AesEncryptionKey(kAESKeySize)
409 .Padding(PaddingMode::PKCS7)
410 .Authorization(TAG_BLOCK_MODE, BlockMode::CBC)
411 .Authorization(TAG_NO_AUTH_REQUIRED);
412 AuthorizationSet hardware_enforced_characteristics;
413 AuthorizationSet software_enforced_characteristics;
414 auto result =
415 generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
416 &software_enforced_characteristics);
417 if (!result.isOk()) {
418 ALOGE("Failed to generate encryption key: %d", int32_t(result));
419 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
createOrVerifyAuthenticationKey(const std::string & key_name,int32_t flags)428 bool KeystoreClientImpl::createOrVerifyAuthenticationKey(const std::string& key_name,
429 int32_t flags) {
430 bool key_exists = doesKeyExist(key_name);
431 if (key_exists) {
432 bool verified = false;
433 if (!verifyAuthenticationKeyAttributes(key_name, &verified)) {
434 return false;
435 }
436 if (!verified) {
437 auto result = deleteKey(key_name);
438 if (!result.isOk()) {
439 ALOGE("Failed to delete invalid authentication key: %d", int32_t(result));
440 return false;
441 }
442 key_exists = false;
443 }
444 }
445 if (!key_exists) {
446 AuthorizationSetBuilder key_parameters;
447 key_parameters.HmacKey(kHMACKeySize)
448 .Digest(Digest::SHA_2_256)
449 .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize)
450 .Authorization(TAG_NO_AUTH_REQUIRED);
451 AuthorizationSet hardware_enforced_characteristics;
452 AuthorizationSet software_enforced_characteristics;
453 auto result =
454 generateKey(key_name, key_parameters, flags, &hardware_enforced_characteristics,
455 &software_enforced_characteristics);
456 if (!result.isOk()) {
457 ALOGE("Failed to generate authentication key: %d", int32_t(result));
458 return false;
459 }
460 if (hardware_enforced_characteristics.size() == 0) {
461 ALOGW("WARNING: Authentication key is not hardware-backed.");
462 }
463 }
464 return true;
465 }
466
verifyEncryptionKeyAttributes(const std::string & key_name,bool * verified)467 bool KeystoreClientImpl::verifyEncryptionKeyAttributes(const std::string& key_name,
468 bool* verified) {
469 AuthorizationSet hardware_enforced_characteristics;
470 AuthorizationSet software_enforced_characteristics;
471 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
472 &software_enforced_characteristics);
473 if (!result.isOk()) {
474 ALOGE("Failed to query encryption key: %d", int32_t(result));
475 return false;
476 }
477 *verified = true;
478 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
479 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
480 if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
481 ALOGW("Found encryption key with invalid algorithm.");
482 *verified = false;
483 }
484 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
485 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
486 if (!key_size.isOk() || key_size.value() != kAESKeySize) {
487 ALOGW("Found encryption key with invalid size.");
488 *verified = false;
489 }
490 auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
491 software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
492 if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
493 ALOGW("Found encryption key with invalid block mode.");
494 *verified = false;
495 }
496 auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
497 software_enforced_characteristics.GetTagValue(TAG_PADDING));
498 if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
499 ALOGW("Found encryption key with invalid padding mode.");
500 *verified = false;
501 }
502 if (hardware_enforced_characteristics.size() == 0) {
503 ALOGW("WARNING: Encryption key is not hardware-backed.");
504 }
505 return true;
506 }
507
verifyAuthenticationKeyAttributes(const std::string & key_name,bool * verified)508 bool KeystoreClientImpl::verifyAuthenticationKeyAttributes(const std::string& key_name,
509 bool* verified) {
510 AuthorizationSet hardware_enforced_characteristics;
511 AuthorizationSet software_enforced_characteristics;
512 auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
513 &software_enforced_characteristics);
514 if (!result.isOk()) {
515 ALOGE("Failed to query authentication key: %d", int32_t(result));
516 return false;
517 }
518 *verified = true;
519 auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
520 software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
521 if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC) {
522 ALOGW("Found authentication key with invalid algorithm.");
523 *verified = false;
524 }
525 auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
526 software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
527 if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
528 ALOGW("Found authentication key with invalid size.");
529 *verified = false;
530 }
531 auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
532 software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
533 if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
534 ALOGW("Found authentication key with invalid minimum mac size.");
535 *verified = false;
536 }
537 auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
538 software_enforced_characteristics.GetTagValue(TAG_DIGEST));
539 if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
540 ALOGW("Found authentication key with invalid digest list.");
541 *verified = false;
542 }
543 if (hardware_enforced_characteristics.size() == 0) {
544 ALOGW("WARNING: Authentication key is not hardware-backed.");
545 }
546 return true;
547 }
548
549 } // namespace keystore
550