Superencrypt authentication-bound keys.

This CL causes keystore to automatically encrypt all newly-created
keymaster key blobs which are authentication-bound.  This appears on its
face to be pointless, since the sensitive key material in the key blobs
is already encrypted by the Trusted Execution Environment.  It's not
pointless because this adds a cryptographic dependency on the user's
password, including any strengthening performed by
LockSettingService... which may include the use of a separate hardware
trusted module, separate from (and presumably more secure than) the TEE.

A better solution is planned for the next release, but that requires
changes to Gatekeeper and Keymaster. This superencryption will be
removed when that work is done.

Note that the encryption method used by keystore is weak. A separate CL will
replace the weak method with a proper authenticated encryption.

Test: Manual testing.
Bug: 35849499
Change-Id: I0162d352837a1e936e7f08cab2afc5c0f8e0f129
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index cd81674..1a60be4 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -40,15 +40,29 @@
 #include <keystore/keystore_hidl_support.h>
 
 namespace keystore {
+
 using namespace android;
 
-const size_t MAX_OPERATIONS = 15;
+namespace {
+
+constexpr size_t MAX_OPERATIONS = 15;
 
 struct BIGNUM_Delete {
     void operator()(BIGNUM* p) const { BN_free(p); }
 };
 typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
 
+bool containsTag(const hidl_vec<KeyParameter>& params, Tag tag) {
+    return params.end() != std::find_if(params.begin(), params.end(),
+                                        [&](auto& param) { return param.tag == tag; });
+}
+
+bool isAuthenticationBound(const hidl_vec<KeyParameter>& params) {
+    return !containsTag(params, Tag::NO_AUTH_REQUIRED);
+}
+
+}  // anonymous namespace
+
 void KeyStoreService::binderDied(const wp<IBinder>& who) {
     auto operations = mOperationMap.getOperationsForToken(who.unsafe_get());
     for (const auto& token : operations) {
@@ -642,6 +656,9 @@
 
         Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), NULL, 0, ::TYPE_KEYMASTER_10);
         keyBlob.setFallback(usingFallback);
+        if (isAuthenticationBound(params)) {
+            keyBlob.setSuperEncrypted(true);
+        }
         keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
 
         error = mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
@@ -786,6 +803,9 @@
 
         Blob ksBlob(&keyBlob[0], keyBlob.size(), NULL, 0, ::TYPE_KEYMASTER_10);
         ksBlob.setFallback(usingFallback);
+        if (isAuthenticationBound(params)) {
+            ksBlob.setSuperEncrypted(true);
+        }
         ksBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
 
         error = mKeyStore->put(filename.string(), &ksBlob, get_user_id(uid));
@@ -922,6 +942,9 @@
     Blob keyBlob;
     String8 name8(name);
     result->resultCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
+    if (result->resultCode == ResponseCode::LOCKED && keyBlob.isSuperEncrypted()) {
+        result->resultCode = ErrorCode::KEY_USER_NOT_AUTHENTICATED;
+    }
     if (!result->resultCode.isOk()) {
         return;
     }