Snap for 4610834 from 0f160fbaee9ecf472feb3e332f01c4ddb95caa0e to pi-release

Change-Id: I40388543ecfcd7475bfa8737a22f3a8ccd3fad5f
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 9e882e4..8b2cb62 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -84,6 +84,7 @@
     srcs: ["keystore_cli.cpp"],
     shared_libs: [
         "android.hardware.keymaster@3.0",
+        "android.hardware.keymaster@4.0",
         "libbinder",
         "libcrypto",
         "libcutils",
@@ -109,8 +110,8 @@
     srcs: ["keystore_cli_v2.cpp"],
     shared_libs: [
         "android.hardware.confirmationui@1.0",
-        "android.hardware.keymaster@3.0",
         "libbinder",
+        "android.hardware.keymaster@4.0",
         "libchrome",
         "libutils",
         "libhidlbase",
diff --git a/keystore/KeyStore.cpp b/keystore/KeyStore.cpp
index 0efc4a3..f197d91 100644
--- a/keystore/KeyStore.cpp
+++ b/keystore/KeyStore.cpp
@@ -26,6 +26,7 @@
 #include <utils/String16.h>
 #include <utils/String8.h>
 
+#include <android-base/scopeguard.h>
 #include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
 #include <android/security/IKeystoreService.h>
 #include <log/log_event_list.h>
@@ -36,14 +37,6 @@
 #include "permissions.h"
 #include <keystore/keystore_hidl_support.h>
 
-namespace {
-
-// Tags for audit logging. Be careful and don't log sensitive data.
-// Should be in sync with frameworks/base/core/java/android/app/admin/SecurityLogTags.logtags
-constexpr int SEC_TAG_KEY_DESTROYED = 210026;
-
-}  // anonymous namespace
-
 namespace keystore {
 
 const char* KeyStore::kOldMasterKey = ".masterkey";
@@ -305,10 +298,19 @@
     userState->setState(STATE_LOCKED);
 }
 
+static void maybeLogKeyIntegrityViolation(const char* filename, const BlobType type);
+
 ResponseCode KeyStore::get(const char* filename, Blob* keyBlob, const BlobType type, uid_t userId) {
     UserState* userState = getUserState(userId);
-    ResponseCode rc =
-        keyBlob->readBlob(filename, userState->getEncryptionKey(), userState->getState());
+    ResponseCode rc;
+
+    auto logOnScopeExit = android::base::make_scope_guard([&] {
+        if (rc == ResponseCode::VALUE_CORRUPTED) {
+            maybeLogKeyIntegrityViolation(filename, type);
+        }
+    });
+
+    rc = keyBlob->readBlob(filename, userState->getEncryptionKey(), userState->getState());
     if (rc != ResponseCode::NO_ERROR) {
         return rc;
     }
@@ -837,4 +839,16 @@
     return upgraded;
 }
 
+static void maybeLogKeyIntegrityViolation(const char* filename, const BlobType type) {
+    if (!__android_log_security() || (type != TYPE_KEY_PAIR && type != TYPE_KEYMASTER_10)) return;
+
+    auto uidAlias = filename2UidAlias(filename);
+    uid_t uid = -1;
+    std::string alias;
+
+    if (uidAlias.isOk()) std::tie(uid, alias) = std::move(uidAlias).value();
+
+    log_key_integrity_violation(alias.c_str(), uid);
+}
+
 }  // namespace keystore
diff --git a/keystore/binder/android/security/IKeystoreService.aidl b/keystore/binder/android/security/IKeystoreService.aidl
index 738eb68..45bc070 100644
--- a/keystore/binder/android/security/IKeystoreService.aidl
+++ b/keystore/binder/android/security/IKeystoreService.aidl
@@ -71,7 +71,7 @@
         in byte[] entropy);
     int abort(IBinder handle);
     boolean isOperationAuthorized(IBinder token);
-    int addAuthToken(in byte[] authToken);
+    int addAuthToken(in byte[] authToken, in int userId);
     int onUserAdded(int userId, int parentId);
     int onUserRemoved(int userId);
     int attestKey(String alias, in KeymasterArguments params, out KeymasterCertificateChain chain);
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
index aa1ae37..d21c691 100644
--- a/keystore/blob.cpp
+++ b/keystore/blob.cpp
@@ -114,13 +114,13 @@
     out_pos += out_len;
     if (!EVP_DecryptFinal_ex(ctx.get(), out_pos, &out_len)) {
         ALOGD("Failed to decrypt blob; ciphertext or tag is likely corrupted");
-        return ResponseCode::SYSTEM_ERROR;
+        return ResponseCode::VALUE_CORRUPTED;
     }
     out_pos += out_len;
     if (out_pos - out_tmp.get() != static_cast<ssize_t>(len)) {
         ALOGD("Encrypted plaintext is the wrong size, expected %zu, got %zd", len,
               out_pos - out_tmp.get());
-        return ResponseCode::SYSTEM_ERROR;
+        return ResponseCode::VALUE_CORRUPTED;
     }
 
     std::copy(out_tmp.get(), out_pos, out);
diff --git a/keystore/include/keystore/keymaster_types.h b/keystore/include/keystore/keymaster_types.h
index 62b43be..bd61294 100644
--- a/keystore/include/keystore/keymaster_types.h
+++ b/keystore/include/keystore/keymaster_types.h
@@ -83,6 +83,7 @@
 using keymaster::TAG_RSA_PUBLIC_EXPONENT;
 using keymaster::TAG_USAGE_EXPIRE_DATETIME;
 using keymaster::TAG_USER_AUTH_TYPE;
+using keymaster::TAG_USER_ID;
 using keymaster::TAG_USER_SECURE_ID;
 
 using keymaster::NullOr;
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 89c31a5..da1b9d8 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -64,11 +64,6 @@
 constexpr double kIdRotationPeriod = 30 * 24 * 60 * 60; /* Thirty days, in seconds */
 const char* kTimestampFilePath = "timestamp";
 
-// Tags for audit logging. Be careful and don't log sensitive data.
-// Should be in sync with frameworks/base/core/java/android/app/admin/SecurityLogTags.logtags
-constexpr int SEC_TAG_AUTH_KEY_GENERATED = 210024;
-constexpr int SEC_TAG_KEY_IMPORTED = 210025;
-
 struct BIGNUM_Delete {
     void operator()(BIGNUM* p) const { BN_free(p); }
 };
@@ -372,6 +367,7 @@
         return Status::ok();
     }
 
+    enforcement_policy.set_device_locked(true, userId);
     mKeyStore->lock(userId);
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
     return Status::ok();
@@ -400,6 +396,7 @@
         return Status::ok();
     }
 
+    enforcement_policy.set_device_locked(false, userId);
     const String8 password8(pw);
     // read master key, decrypt with password, initialize mMasterKey*.
     *aidl_return = static_cast<int32_t>(mKeyStore->readMasterKey(password8, userId));
@@ -916,6 +913,9 @@
     auto hidlCb = [&](ErrorCode ret, const KeyCharacteristics& keyCharacteristics) {
         error = ret;
         if (!error.isOk()) {
+            if (error == ErrorCode::INVALID_KEY_BLOB) {
+                log_key_integrity_violation(name8, targetUid);
+            }
             return;
         }
         *outCharacteristics =
@@ -1100,6 +1100,9 @@
     auto hidlCb = [&](ErrorCode ret, const ::android::hardware::hidl_vec<uint8_t>& keyMaterial) {
         result->resultCode = ret;
         if (!result->resultCode.isOk()) {
+            if (result->resultCode == ErrorCode::INVALID_KEY_BLOB) {
+                log_key_integrity_violation(name8, targetUid);
+            }
             return;
         }
         result->exportData = keyMaterial;
@@ -1262,6 +1265,9 @@
                       uint64_t operationHandle) {
         result->resultCode = ret;
         if (!result->resultCode.isOk()) {
+            if (result->resultCode == ErrorCode::INVALID_KEY_BLOB) {
+                log_key_integrity_violation(name8, targetUid);
+            }
             return;
         }
         result->handle = operationHandle;
@@ -1466,7 +1472,7 @@
 }
 
 Status KeyStoreService::addAuthToken(const ::std::vector<uint8_t>& authTokenAsVector,
-                                     int32_t* aidl_return) {
+                                     int32_t userId, int32_t* aidl_return) {
 
     // TODO(swillden): When gatekeeper and fingerprint are ready, this should be updated to
     // receive a HardwareAuthToken, rather than an opaque byte array.
@@ -1488,6 +1494,8 @@
         return Status::ok();
     }
 
+    enforcement_policy.set_device_locked(false, userId);
+
     mAuthTokenTable.AddAuthenticationToken(hidlVec2AuthToken(hidl_vec<uint8_t>(authTokenAsVector)));
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
     return Status::ok();
@@ -2151,6 +2159,9 @@
     auto hidlCb = [&](ErrorCode ret, const ::std::vector<uint8_t>& upgradedKeyBlob) {
         error = ret;
         if (!error.isOk()) {
+            if (error == ErrorCode::INVALID_KEY_BLOB) {
+                log_key_integrity_violation(name8, uid);
+            }
             return;
         }
 
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index ce809f8..b238dc4 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -145,7 +145,7 @@
                                     int32_t* _aidl_return) override;
     ::android::binder::Status isOperationAuthorized(const ::android::sp<::android::IBinder>& token,
                                                     bool* _aidl_return) override;
-    ::android::binder::Status addAuthToken(const ::std::vector<uint8_t>& authToken,
+    ::android::binder::Status addAuthToken(const ::std::vector<uint8_t>& authToken, int32_t userId,
                                            int32_t* _aidl_return) override;
     ::android::binder::Status onUserAdded(int32_t userId, int32_t parentId,
                                           int32_t* _aidl_return) override;
diff --git a/keystore/keymaster_enforcement.cpp b/keystore/keymaster_enforcement.cpp
index d78a5a6..5a6e591 100644
--- a/keystore/keymaster_enforcement.cpp
+++ b/keystore/keymaster_enforcement.cpp
@@ -223,6 +223,8 @@
     bool caller_nonce_authorized_by_key = false;
     bool authentication_required = false;
     bool auth_token_matched = false;
+    bool unlocked_device_required = false;
+    int32_t user_id = -1;
 
     for (auto& param : auth_set) {
 
@@ -282,10 +284,18 @@
             }
             break;
 
+        case Tag::USER_ID:
+            user_id = authorizationValue(TAG_USER_ID, param).value();
+            break;
+
         case Tag::CALLER_NONCE:
             caller_nonce_authorized_by_key = true;
             break;
 
+        case Tag::UNLOCKED_DEVICE_REQUIRED:
+            unlocked_device_required = true;
+            break;
+
         /* Tags should never be in key auths. */
         case Tag::INVALID:
         case Tag::ROOT_OF_TRUST:
@@ -356,6 +366,19 @@
         }
     }
 
+    if (unlocked_device_required && is_device_locked(user_id)) {
+        switch (purpose) {
+        case KeyPurpose::ENCRYPT:
+        case KeyPurpose::VERIFY:
+            /* These are okay */
+            break;
+        case KeyPurpose::DECRYPT:
+        case KeyPurpose::SIGN:
+        case KeyPurpose::WRAP_KEY:
+            return ErrorCode::DEVICE_LOCKED;
+        };
+    }
+
     if (authentication_required && !auth_token_matched) {
         ALOGE("Auth required but no matching auth token found");
         return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
diff --git a/keystore/keymaster_enforcement.h b/keystore/keymaster_enforcement.h
index d7b27fc..6e6c54f 100644
--- a/keystore/keymaster_enforcement.h
+++ b/keystore/keymaster_enforcement.h
@@ -142,6 +142,11 @@
      */
     virtual bool ValidateTokenSignature(const HardwareAuthToken& token) const = 0;
 
+    /*
+     * Returns true if the device screen is currently locked for the specified user.
+     */
+    virtual bool is_device_locked(int32_t userId) const = 0;
+
   private:
     ErrorCode AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
                                       const HardwareAuthToken& auth_token, uint64_t op_handle);
diff --git a/keystore/keystore_keymaster_enforcement.h b/keystore/keystore_keymaster_enforcement.h
index 3cdf649..e114ea9 100644
--- a/keystore/keystore_keymaster_enforcement.h
+++ b/keystore/keystore_keymaster_enforcement.h
@@ -84,6 +84,19 @@
         // signing key. Assume the token is good.
         return true;
     }
+
+    bool is_device_locked(int32_t userId) const override {
+        // If we haven't had a set call for this user yet, assume the device is locked.
+        if (mIsDeviceLockedForUser.count(userId) == 0) return true;
+        return mIsDeviceLockedForUser.find(userId)->second;
+    }
+
+    void set_device_locked(bool isLocked, int32_t userId) {
+        mIsDeviceLockedForUser[userId] = isLocked;
+    }
+
+  private:
+    std::map<int32_t, bool> mIsDeviceLockedForUser;
 };
 
 } // namespace keystore
diff --git a/keystore/keystore_utils.cpp b/keystore/keystore_utils.cpp
index 3da3791..e5ae29a 100644
--- a/keystore/keystore_utils.cpp
+++ b/keystore/keystore_utils.cpp
@@ -24,6 +24,9 @@
 
 #include <cutils/log.h>
 #include <private/android_filesystem_config.h>
+#include <private/android_logger.h>
+
+#include <log/log_event_list.h>
 
 #include <keystore/keymaster_types.h>
 #include <keystore/keystore_client.h>
@@ -95,6 +98,12 @@
     return uid / AID_USER;
 }
 
+void log_key_integrity_violation(const char* name, uid_t uid) {
+    if (!__android_log_security()) return;
+    android_log_event_list(SEC_TAG_KEY_INTEGRITY_VIOLATION)
+        << name << int32_t(uid) << LOG_ID_SECURITY;
+}
+
 namespace keystore {
 
 hidl_vec<uint8_t> blob2hidlVec(const Blob& blob) {
diff --git a/keystore/keystore_utils.h b/keystore/keystore_utils.h
index f1211de..3bc9c01 100644
--- a/keystore/keystore_utils.h
+++ b/keystore/keystore_utils.h
@@ -56,6 +56,15 @@
 
 class Blob;
 
+// Tags for audit logging. Be careful and don't log sensitive data.
+// Should be in sync with frameworks/base/core/java/android/app/admin/SecurityLogTags.logtags
+constexpr int SEC_TAG_KEY_DESTROYED = 210026;
+constexpr int SEC_TAG_KEY_INTEGRITY_VIOLATION = 210032;
+constexpr int SEC_TAG_AUTH_KEY_GENERATED = 210024;
+constexpr int SEC_TAG_KEY_IMPORTED = 210025;
+
+void log_key_integrity_violation(const char* name, uid_t uid);
+
 namespace keystore {
 
 hidl_vec<uint8_t> blob2hidlVec(const Blob& blob);