KeyMint: improve HAL spec and tests

- clarify & test BIGNUM spec
- allow alternative return codes when requesting device unique
  attestation
- use specific error for early boot import failure
- test more early boot key scenarios (in post-early-boot mode)

Bug: 188672564
Test: VtsAidlKeyMintTargetTest
Merged-In: I70a342084a29144aef1ed0ff80fec02cc06ffbc0
Change-Id: I70a342084a29144aef1ed0ff80fec02cc06ffbc0
diff --git a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
index 881354d..76f0a24 100644
--- a/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
+++ b/security/keymint/aidl/vts/functional/AttestKeyTest.cpp
@@ -180,7 +180,9 @@
     auto subject = "cert subj 2";
     vector<uint8_t> subject_der(make_name_from_str(subject));
 
-    uint64_t serial_int = 66;
+    // An X.509 certificate serial number SHOULD be >0, but this is not policed. Check
+    // that a zero value doesn't cause problems.
+    uint64_t serial_int = 0;
     vector<uint8_t> serial_blob(build_serial_blob(serial_int));
 
     /*
@@ -223,7 +225,7 @@
     auto subject2 = "cert subject";
     vector<uint8_t> subject_der2(make_name_from_str(subject2));
 
-    uint64_t serial_int2 = 987;
+    uint64_t serial_int2 = 255;
     vector<uint8_t> serial_blob2(build_serial_blob(serial_int2));
 
     EXPECT_EQ(ErrorCode::OK,
diff --git a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
index 6f0ee4e..b0f056a 100644
--- a/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
+++ b/security/keymint/aidl/vts/functional/DeviceUniqueAttestationTest.cpp
@@ -75,7 +75,7 @@
                                       .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
                               &key_blob, &key_characteristics);
 
-    ASSERT_EQ(result, ErrorCode::INVALID_ARGUMENT);
+    ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
 }
 
 /*
@@ -101,7 +101,7 @@
                                       .Authorization(TAG_DEVICE_UNIQUE_ATTESTATION),
                               &key_blob, &key_characteristics);
 
-    ASSERT_EQ(result, ErrorCode::INVALID_ARGUMENT);
+    ASSERT_TRUE(result == ErrorCode::INVALID_ARGUMENT || result == ErrorCode::UNSUPPORTED_TAG);
 }
 
 /*
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 8c4e0c3..305364a 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -1185,6 +1185,14 @@
         return {};
     }
 
+    if (serial_blob.empty() || serial_blob[0] & 0x80) {
+        // An empty blob is OpenSSL's encoding of the zero value; we need single zero byte.
+        // Top bit being set indicates a negative number in two's complement, but our input
+        // was positive.
+        // In either case, prepend a zero byte.
+        serial_blob.insert(serial_blob.begin(), 0x00);
+    }
+
     return serial_blob;
 }
 
diff --git a/security/keymint/aidl/vts/functional/KeyMintTest.cpp b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
index 293a010..349f44a 100644
--- a/security/keymint/aidl/vts/functional/KeyMintTest.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintTest.cpp
@@ -6320,7 +6320,13 @@
 
 using EarlyBootKeyTest = KeyMintAidlTestBase;
 
+/*
+ * EarlyBootKeyTest.CreateEarlyBootKeys
+ *
+ * Verifies that creating early boot keys succeeds, even at a later stage (after boot).
+ */
 TEST_P(EarlyBootKeyTest, CreateEarlyBootKeys) {
+    // Early boot keys can be created after early boot.
     auto [aesKeyData, hmacKeyData, rsaKeyData, ecdsaKeyData] =
             CreateTestKeys(TAG_EARLY_BOOT_ONLY, ErrorCode::OK);
 
@@ -6330,6 +6336,41 @@
     CheckedDeleteKey(&ecdsaKeyData.blob);
 }
 
+/*
+ * EarlyBootKeyTest.UsetEarlyBootKeyFailure
+ *
+ * Verifies that using early boot keys at a later stage fails.
+ */
+TEST_P(EarlyBootKeyTest, UseEarlyBootKeyFailure) {
+    ASSERT_EQ(ErrorCode::OK, GenerateKey(AuthorizationSetBuilder()
+                                                 .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                 .Authorization(TAG_EARLY_BOOT_ONLY)
+                                                 .HmacKey(128)
+                                                 .Digest(Digest::SHA_2_256)
+                                                 .Authorization(TAG_MIN_MAC_LENGTH, 256)));
+    AuthorizationSet output_params;
+    EXPECT_EQ(ErrorCode::EARLY_BOOT_ENDED, Begin(KeyPurpose::SIGN, key_blob_,
+                                                 AuthorizationSetBuilder()
+                                                         .Digest(Digest::SHA_2_256)
+                                                         .Authorization(TAG_MAC_LENGTH, 256),
+                                                 &output_params));
+}
+
+/*
+ * EarlyBootKeyTest.ImportEarlyBootKeyFailure
+ *
+ * Verifies that importing early boot keys fails.
+ */
+TEST_P(EarlyBootKeyTest, ImportEarlyBootKeyFailure) {
+    ASSERT_EQ(ErrorCode::EARLY_BOOT_ENDED, ImportKey(AuthorizationSetBuilder()
+                                                             .Authorization(TAG_NO_AUTH_REQUIRED)
+                                                             .Authorization(TAG_EARLY_BOOT_ONLY)
+                                                             .EcdsaSigningKey(256)
+                                                             .Digest(Digest::SHA_2_256)
+                                                             .SetDefaultValidity(),
+                                                     KeyFormat::PKCS8, ec_256_key));
+}
+
 // This is a more comprehensive test, but it can only be run on a machine which is still in early
 // boot stage, which no proper Android device is by the time we can run VTS.  To use this,
 // un-disable it and modify vold to remove the call to earlyBootEnded().  Running the test will end