diff options
| author | android-build-team Robot <android-build-team-robot@google.com> | 2018-02-18 08:22:40 +0000 |
|---|---|---|
| committer | android-build-team Robot <android-build-team-robot@google.com> | 2018-02-18 08:22:40 +0000 |
| commit | 7e6cfc6979cbac3a93dc3fe4c66bedbb3a8cddf1 (patch) | |
| tree | dd0a4e587e1bcc58b11321d50b33d79284bb75b9 | |
| parent | 551b53c33c53345594aea62024599e7ad373a1dc (diff) | |
| parent | 0f160fbaee9ecf472feb3e332f01c4ddb95caa0e (diff) | |
Snap for 4610834 from 0f160fbaee9ecf472feb3e332f01c4ddb95caa0e to pi-release
Change-Id: I40388543ecfcd7475bfa8737a22f3a8ccd3fad5f
| -rw-r--r-- | keystore/Android.bp | 3 | ||||
| -rw-r--r-- | keystore/KeyStore.cpp | 34 | ||||
| -rw-r--r-- | keystore/binder/android/security/IKeystoreService.aidl | 2 | ||||
| -rw-r--r-- | keystore/blob.cpp | 4 | ||||
| -rw-r--r-- | keystore/include/keystore/keymaster_types.h | 1 | ||||
| -rw-r--r-- | keystore/key_store_service.cpp | 23 | ||||
| -rw-r--r-- | keystore/key_store_service.h | 2 | ||||
| -rw-r--r-- | keystore/keymaster_enforcement.cpp | 23 | ||||
| -rw-r--r-- | keystore/keymaster_enforcement.h | 5 | ||||
| -rw-r--r-- | keystore/keystore_keymaster_enforcement.h | 13 | ||||
| -rw-r--r-- | keystore/keystore_utils.cpp | 9 | ||||
| -rw-r--r-- | keystore/keystore_utils.h | 9 |
12 files changed, 107 insertions, 21 deletions
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 @@ cc_binary { srcs: ["keystore_cli.cpp"], shared_libs: [ "android.hardware.keymaster@3.0", + "android.hardware.keymaster@4.0", "libbinder", "libcrypto", "libcutils", @@ -109,8 +110,8 @@ cc_binary { 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 @@ void KeyStore::lock(uid_t userId) { 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 @@ bool KeyStore::upgradeKeystore() { 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 @@ interface IKeystoreService { 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 @@ ResponseCode AES_gcm_decrypt(const uint8_t* in, uint8_t* out, size_t len, const 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_RESET_SINCE_ID_ROTATION; 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 size_t kMaxOperations = 15; 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 @@ Status KeyStoreService::lock(int32_t userId, int32_t* aidl_return) { 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 @@ Status KeyStoreService::unlock(int32_t userId, const String16& pw, int32_t* aidl 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 @@ Status KeyStoreService::getKeyCharacteristics( 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 @@ Status KeyStoreService::exportKey(const String16& name, int32_t format, 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 @@ Status KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name, 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::isOperationAuthorized(const sp<IBinder>& token, bool* ai } 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 @@ Status KeyStoreService::addAuthToken(const ::std::vector<uint8_t>& authTokenAsVe 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 @@ KeyStoreServiceReturnCode KeyStoreService::upgradeKeyBlob(const String16& name, 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 @@ class KeyStoreService : public android::security::BnKeystoreService, 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 @@ ErrorCode KeymasterEnforcement::AuthorizeBegin(const KeyPurpose purpose, const k 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 @@ ErrorCode KeymasterEnforcement::AuthorizeBegin(const KeyPurpose purpose, const k } 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 @@ ErrorCode KeymasterEnforcement::AuthorizeBegin(const KeyPurpose purpose, const k } } + 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 @@ class KeymasterEnforcement { */ 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 @@ class KeystoreKeymasterEnforcement : public KeymasterEnforcement { // 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 @@ uid_t get_user_id(uid_t uid) { 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 @@ typedef std::unique_ptr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_ 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); |
