Change KeyMint KeyCharacteristics
Support key characteristics with three security levels, and don't
store unenforced authorizations with keys or bind them to keys.
Bug: 163606833
Test: atest VtsAidlKeyMintTargetTest
Change-Id: I5abadc892fe5909d297bd035cf6e582b21e57f5f
diff --git a/ng/AndroidKeyMintDevice.cpp b/ng/AndroidKeyMintDevice.cpp
index f024fef..504d179 100644
--- a/ng/AndroidKeyMintDevice.cpp
+++ b/ng/AndroidKeyMintDevice.cpp
@@ -15,7 +15,7 @@
*/
#define LOG_TAG "android.hardware.security.keymint-impl"
-#include <log/log.h>
+#include <android-base/logging.h>
#include "AndroidKeyMintDevice.h"
@@ -33,6 +33,123 @@
using namespace ::keymaster;
using namespace km_utils;
+namespace {
+
+vector<KeyCharacteristics> convertKeyCharacteristics(SecurityLevel keyMintSecurityLevel,
+ const AuthorizationSet& sw_enforced,
+ const AuthorizationSet& hw_enforced) {
+ KeyCharacteristics enforced;
+
+ enforced.securityLevel = keyMintSecurityLevel;
+ if (keyMintSecurityLevel != SecurityLevel::SOFTWARE) {
+ // We're pretending to be TRUSTED_ENVIRONMENT or STRONGBOX. Only the entries in hw_enforced
+ // should be returned.
+ enforced.authorizations = kmParamSet2Aidl(hw_enforced);
+ KeyCharacteristics enforced{keyMintSecurityLevel, kmParamSet2Aidl(hw_enforced)};
+ return {std::move(enforced)};
+ }
+
+ CHECK(hw_enforced.empty()) << "Hardware-enforced list is non-empty for pure SW KeyMint";
+
+ // This is a pure software implementation, so all tags are in sw_enforced. We need to walk
+ // through the SW-enforced list and figure out which tags to return and which not.
+
+ for (auto& entry : sw_enforced) {
+ switch (entry.tag) {
+ /* Invalid and unused */
+ case KM_TAG_ECIES_SINGLE_HASH_MODE:
+ case KM_TAG_INVALID:
+ case KM_TAG_KDF:
+ CHECK(false) << "We shouldn't see tag " << entry.tag;
+ break;
+
+ /* Unimplemented */
+ case KM_TAG_ALLOW_WHILE_ON_BODY:
+ case KM_TAG_APPLICATION_ID:
+ case KM_TAG_BOOTLOADER_ONLY:
+ case KM_TAG_EARLY_BOOT_ONLY:
+ case KM_TAG_ROLLBACK_RESISTANCE:
+ case KM_TAG_ROLLBACK_RESISTANT:
+ case KM_TAG_STORAGE_KEY:
+ break;
+
+ /* Unenforceable */
+ case KM_TAG_ACTIVE_DATETIME:
+ case KM_TAG_ALL_APPLICATIONS:
+ case KM_TAG_ALL_USERS:
+ case KM_TAG_CREATION_DATETIME:
+ case KM_TAG_ORIGINATION_EXPIRE_DATETIME:
+ case KM_TAG_TRUSTED_CONFIRMATION_REQUIRED:
+ case KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED:
+ case KM_TAG_USAGE_EXPIRE_DATETIME:
+ case KM_TAG_USER_ID:
+ break;
+
+ /* Disallowed in KeyCharacteristics */
+ case KM_TAG_APPLICATION_DATA:
+ break;
+
+ /* Not key characteristics */
+ case KM_TAG_ASSOCIATED_DATA:
+ case KM_TAG_ATTESTATION_APPLICATION_ID:
+ case KM_TAG_ATTESTATION_CHALLENGE:
+ case KM_TAG_ATTESTATION_ID_BRAND:
+ case KM_TAG_ATTESTATION_ID_DEVICE:
+ case KM_TAG_ATTESTATION_ID_IMEI:
+ case KM_TAG_ATTESTATION_ID_MANUFACTURER:
+ case KM_TAG_ATTESTATION_ID_MEID:
+ case KM_TAG_ATTESTATION_ID_MODEL:
+ case KM_TAG_ATTESTATION_ID_PRODUCT:
+ case KM_TAG_ATTESTATION_ID_SERIAL:
+ case KM_TAG_AUTH_TOKEN:
+ case KM_TAG_CERTIFICATE_SERIAL:
+ case KM_TAG_CERTIFICATE_SUBJECT:
+ case KM_TAG_CONFIRMATION_TOKEN:
+ case KM_TAG_DEVICE_UNIQUE_ATTESTATION:
+ case KM_TAG_IDENTITY_CREDENTIAL_KEY:
+ case KM_TAG_MAC_LENGTH:
+ case KM_TAG_NONCE:
+ case KM_TAG_RESET_SINCE_ID_ROTATION:
+ case KM_TAG_ROOT_OF_TRUST:
+ case KM_TAG_UNIQUE_ID:
+ break;
+
+ /* Enforced */
+ case KM_TAG_ALGORITHM:
+ case KM_TAG_AUTH_TIMEOUT:
+ case KM_TAG_BLOB_USAGE_REQUIREMENTS:
+ case KM_TAG_BLOCK_MODE:
+ case KM_TAG_BOOT_PATCHLEVEL:
+ case KM_TAG_CALLER_NONCE:
+ case KM_TAG_DIGEST:
+ case KM_TAG_EC_CURVE:
+ case KM_TAG_EXPORTABLE:
+ case KM_TAG_INCLUDE_UNIQUE_ID:
+ case KM_TAG_KEY_SIZE:
+ case KM_TAG_MAX_USES_PER_BOOT:
+ case KM_TAG_MIN_MAC_LENGTH:
+ case KM_TAG_MIN_SECONDS_BETWEEN_OPS:
+ case KM_TAG_NO_AUTH_REQUIRED:
+ case KM_TAG_ORIGIN:
+ case KM_TAG_OS_PATCHLEVEL:
+ case KM_TAG_OS_VERSION:
+ case KM_TAG_PADDING:
+ case KM_TAG_PURPOSE:
+ case KM_TAG_RSA_OAEP_MGF_DIGEST:
+ case KM_TAG_RSA_PUBLIC_EXPONENT:
+ case KM_TAG_UNLOCKED_DEVICE_REQUIRED:
+ case KM_TAG_USER_AUTH_TYPE:
+ case KM_TAG_USER_SECURE_ID:
+ case KM_TAG_VENDOR_PATCHLEVEL:
+ enforced.authorizations.push_back(kmParam2Aidl(entry));
+ }
+ }
+
+ return {std::move(enforced)};
+}
+
+} // namespace
+
constexpr size_t kOperationTableSize = 16;
AndroidKeyMintDevice::AndroidKeyMintDevice(SecurityLevel securityLevel)
@@ -103,9 +220,7 @@
}
ScopedAStatus AndroidKeyMintDevice::generateKey(const vector<KeyParameter>& keyParams,
- ByteArray* generatedKeyBlob,
- KeyCharacteristics* generatedKeyCharacteristics,
- vector<Certificate>* /* certChain */) {
+ KeyCreationResult* creationResult) {
GenerateKeyRequest request(impl_->message_version());
request.key_description.Reinitialize(KmParamSet(keyParams));
@@ -126,18 +241,15 @@
return kmError2ScopedAStatus(response.error);
}
- generatedKeyBlob->data = kmBlob2vector(response.key_blob);
- generatedKeyCharacteristics->hardwareEnforced = kmParamSet2Aidl(response.enforced);
- generatedKeyCharacteristics->softwareEnforced = kmParamSet2Aidl(response.unenforced);
-
+ creationResult->keyBlob = kmBlob2vector(response.key_blob);
+ creationResult->keyCharacteristics =
+ convertKeyCharacteristics(securityLevel_, response.unenforced, response.enforced);
return ScopedAStatus::ok();
}
ScopedAStatus AndroidKeyMintDevice::importKey(const vector<KeyParameter>& keyParams,
KeyFormat keyFormat, const vector<uint8_t>& keyData,
- ByteArray* importedKeyBlob,
- KeyCharacteristics* importedKeyCharacteristics,
- vector<Certificate>* /* certChain */) {
+ KeyCreationResult* creationResult) {
ImportKeyRequest request(impl_->message_version());
request.key_description.Reinitialize(KmParamSet(keyParams));
@@ -151,18 +263,19 @@
return kmError2ScopedAStatus(response.error);
}
- importedKeyBlob->data = kmBlob2vector(response.key_blob);
- importedKeyCharacteristics->hardwareEnforced = kmParamSet2Aidl(response.enforced);
- importedKeyCharacteristics->softwareEnforced = kmParamSet2Aidl(response.unenforced);
+ creationResult->keyBlob = kmBlob2vector(response.key_blob);
+ creationResult->keyCharacteristics =
+ convertKeyCharacteristics(securityLevel_, response.unenforced, response.enforced);
return ScopedAStatus::ok();
}
-ScopedAStatus AndroidKeyMintDevice::importWrappedKey(
- const vector<uint8_t>& wrappedKeyData, const vector<uint8_t>& wrappingKeyBlob,
- const vector<uint8_t>& maskingKey, const vector<KeyParameter>& unwrappingParams,
- int64_t passwordSid, int64_t biometricSid, ByteArray* importedKeyBlob,
- KeyCharacteristics* importedKeyCharacteristics) {
+ScopedAStatus AndroidKeyMintDevice::importWrappedKey(const vector<uint8_t>& wrappedKeyData,
+ const vector<uint8_t>& wrappingKeyBlob,
+ const vector<uint8_t>& maskingKey,
+ const vector<KeyParameter>& unwrappingParams,
+ int64_t passwordSid, int64_t biometricSid,
+ KeyCreationResult* creationResult) {
ImportWrappedKeyRequest request(impl_->message_version());
request.SetWrappedMaterial(wrappedKeyData.data(), wrappedKeyData.size());
@@ -179,9 +292,9 @@
return kmError2ScopedAStatus(response.error);
}
- importedKeyBlob->data = kmBlob2vector(response.key_blob);
- importedKeyCharacteristics->hardwareEnforced = kmParamSet2Aidl(response.enforced);
- importedKeyCharacteristics->softwareEnforced = kmParamSet2Aidl(response.unenforced);
+ creationResult->keyBlob = kmBlob2vector(response.key_blob);
+ creationResult->keyCharacteristics =
+ convertKeyCharacteristics(securityLevel_, response.unenforced, response.enforced);
return ScopedAStatus::ok();
}