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();
 }