Identity Credential: Add method to accept verification token.

This is to facilitate HAL implementations using a TA existing in a
different environment than where auth tokens are minted. This method
will be used by credstore in a companion CL.

This modifies version 2 of the Identity Credential API (which was
never been released) to add a new method and creates version 2 of the
Keymaster types-only AIDL API to include the new VerificationToken
parcelable and SecurityLevel enum.

Bug: 156076333
Test: atest VtsHalIdentityTargetTest
Test: atest android.security.identity.cts

Change-Id: I7d05413a9ec70225ce419079f3cc9daf026cf744
diff --git a/identity/aidl/aidl_api/android.hardware.identity/2/.hash b/identity/aidl/aidl_api/android.hardware.identity/2/.hash
index 1b2c1b6..036ce84 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/2/.hash
+++ b/identity/aidl/aidl_api/android.hardware.identity/2/.hash
@@ -1 +1 @@
-3b0b10b618dbc4bf283aa2bf78833ad3de0a5928
+194e04be642728623d65ec8321a3764fdea52ae0
diff --git a/identity/aidl/aidl_api/android.hardware.identity/2/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/2/android/hardware/identity/IIdentityCredential.aidl
index e8e93f8..88104d9 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/2/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/2/android/hardware/identity/IIdentityCredential.aidl
@@ -28,4 +28,5 @@
   void finishRetrieval(out byte[] mac, out byte[] deviceNameSpaces);
   android.hardware.identity.Certificate generateSigningKeyPair(out byte[] signingKeyBlob);
   void setRequestedNamespaces(in android.hardware.identity.RequestNamespace[] requestNamespaces);
+  void setVerificationToken(in android.hardware.keymaster.VerificationToken verificationToken);
 }
diff --git a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
index e8e93f8..88104d9 100644
--- a/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/aidl_api/android.hardware.identity/current/android/hardware/identity/IIdentityCredential.aidl
@@ -28,4 +28,5 @@
   void finishRetrieval(out byte[] mac, out byte[] deviceNameSpaces);
   android.hardware.identity.Certificate generateSigningKeyPair(out byte[] signingKeyBlob);
   void setRequestedNamespaces(in android.hardware.identity.RequestNamespace[] requestNamespaces);
+  void setVerificationToken(in android.hardware.keymaster.VerificationToken verificationToken);
 }
diff --git a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
index 7cd25e6..d7f47e8 100644
--- a/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
+++ b/identity/aidl/android/hardware/identity/IIdentityCredential.aidl
@@ -20,6 +20,7 @@
 import android.hardware.identity.RequestNamespace;
 import android.hardware.identity.SecureAccessControlProfile;
 import android.hardware.keymaster.HardwareAuthToken;
+import android.hardware.keymaster.VerificationToken;
 
 @VintfStability
 interface IIdentityCredential {
@@ -71,10 +72,11 @@
 
     /**
      * Creates a challenge value to be used for proving successful user authentication. This
-     * is included in the authToken passed to the startRetrieval() method.
+     * is included in the authToken passed to the startRetrieval() method and the
+     * verificationToken passed to the setVerificationToken() method.
      *
      * This method may only be called once per instance. If called more than once, STATUS_FAILED
-     * will be returned.
+     * will be returned. If user authentication is not needed, this method may not be called.
      *
      * @return challenge, a non-zero number.
      */
@@ -83,7 +85,8 @@
     /**
      * Start an entry retrieval process.
      *
-     * The setRequestedNamespaces() method will be called before this method.
+     * The setRequestedNamespaces() and setVerificationToken() methods will be called before
+     * this method is called.
      *
      * This method be called after createEphemeralKeyPair(), setReaderEphemeralPublicKey(),
      * createAuthChallenge() and before startRetrieveEntry(). This method call is followed by
@@ -96,7 +99,19 @@
      * must be identical for each startRetrieval() invocation. If this is not the case, this call
      * fails with the STATUS_SESSION_TRANSCRIPT_MISMATCH error.
      *
-     * If the provided authToken is not valid this method fails with STATUS_INVALID_AUTH_TOKEN.
+     * If either authToken or verificationToken (as passed with setVerificationToken())
+     * is not valid this method fails with STATUS_INVALID_AUTH_TOKEN. Note that valid tokens
+     * are only passed if they are actually needed and available (this can be detected by
+     * the timestamp being set to zero). For example, if no data items with access control
+     * profiles using user authentication are requested, the tokens are not filled in.
+     * It's also possible that no usable auth token is actually available (it could be the user
+     * never unlocked the device within the timeouts in the access control profiles) and
+     * in this case the tokens aren't filled in either.
+     *
+     * For test credentials (identified by the testCredential boolean in the CredentialData
+     * CBOR created at provisioning time), the |mac| field in both the authToken and
+     * verificationToken should not be checked against the shared HMAC key (see IKeyMasterDevice
+     * for details). This is to enable VTS tests to check for correct behavior.
      *
      * Each of the provided accessControlProfiles is checked in this call. If they are not
      * all valid, the call fails with STATUS_INVALID_DATA.
@@ -179,7 +194,8 @@
      *
      * @param authToken
      *   The authentication token that proves the user was authenticated, as required
-     *   by one or more of the provided accessControlProfiles. See above.
+     *   by one or more of the provided accessControlProfiles. This token is only valid
+     *   if the timestamp field is non-zero. See above.
      *
      * @param itemsRequest
      *   If non-empty, contains request data that is signed by the reader. See above.
@@ -358,4 +374,13 @@
      * @param requestNamespaces Namespaces and data items which will be requested.
      */
     void setRequestedNamespaces(in RequestNamespace[] requestNamespaces);
+
+   /**
+    * Sets the VerificationToken. This method must be called before startRetrieval() is
+    * called. This token uses the same challenge as returned by createAuthChallenge().
+    *
+    * @param verificationToken
+    *   The verification token. This token is only valid if the timestamp field is non-zero.
+    */
+    void setVerificationToken(in VerificationToken verificationToken);
 }
diff --git a/identity/aidl/default/IdentityCredential.cpp b/identity/aidl/default/IdentityCredential.cpp
index ff4107a..381eb84 100644
--- a/identity/aidl/default/IdentityCredential.cpp
+++ b/identity/aidl/default/IdentityCredential.cpp
@@ -198,15 +198,8 @@
     return false;
 }
 
-Timestamp clockGetTime() {
-    struct timespec time;
-    clock_gettime(CLOCK_MONOTONIC, &time);
-    Timestamp ts;
-    ts.milliSeconds = time.tv_sec * 1000 + time.tv_nsec / 1000000;
-    return ts;
-}
-
 bool checkUserAuthentication(const SecureAccessControlProfile& profile,
+                             const VerificationToken& verificationToken,
                              const HardwareAuthToken& authToken, uint64_t authChallenge) {
     if (profile.secureUserId != authToken.userId) {
         LOG(ERROR) << "secureUserId in profile (" << profile.secureUserId
@@ -214,6 +207,15 @@
         return false;
     }
 
+    if (verificationToken.timestamp.milliSeconds == 0) {
+        LOG(ERROR) << "VerificationToken is not set";
+        return false;
+    }
+    if (authToken.timestamp.milliSeconds == 0) {
+        LOG(ERROR) << "AuthToken is not set";
+        return false;
+    }
+
     if (profile.timeoutMillis == 0) {
         if (authToken.challenge == 0) {
             LOG(ERROR) << "No challenge in authToken";
@@ -227,19 +229,11 @@
         return true;
     }
 
-    // Note that the Epoch for timestamps in HardwareAuthToken is at the
-    // discretion of the vendor:
+    // Timeout-based user auth follows. The verification token conveys what the
+    // time is right now in the environment which generated the auth token. This
+    // is what makes it possible to do timeout-based checks.
     //
-    //   "[...] since some starting point (generally the most recent device
-    //    boot) which all of the applications within one secure environment
-    //    must agree upon."
-    //
-    // Therefore, if this software implementation is used on a device which isn't
-    // the emulator then the assumption that the epoch is the same as used in
-    // clockGetTime above will not hold. This is OK as this software
-    // implementation should never be used on a real device.
-    //
-    Timestamp now = clockGetTime();
+    const Timestamp now = verificationToken.timestamp;
     if (authToken.timestamp.milliSeconds > now.milliSeconds) {
         LOG(ERROR) << "Timestamp in authToken (" << authToken.timestamp.milliSeconds
                    << ") is in the future (now: " << now.milliSeconds << ")";
@@ -261,6 +255,12 @@
     return ndk::ScopedAStatus::ok();
 }
 
+ndk::ScopedAStatus IdentityCredential::setVerificationToken(
+        const VerificationToken& verificationToken) {
+    verificationToken_ = verificationToken;
+    return ndk::ScopedAStatus::ok();
+}
+
 ndk::ScopedAStatus IdentityCredential::startRetrieval(
         const vector<SecureAccessControlProfile>& accessControlProfiles,
         const HardwareAuthToken& authToken, const vector<uint8_t>& itemsRequest,
@@ -483,7 +483,8 @@
         }
         int accessControlCheck = IIdentityCredentialStore::STATUS_OK;
         if (profile.userAuthenticationRequired) {
-            if (!haveAuthToken || !checkUserAuthentication(profile, authToken, authChallenge_)) {
+            if (!haveAuthToken ||
+                !checkUserAuthentication(profile, verificationToken_, authToken, authChallenge_)) {
                 accessControlCheck = IIdentityCredentialStore::STATUS_USER_AUTHENTICATION_FAILED;
             }
         } else if (profile.readerCertificate.encodedCertificate.size() > 0) {
diff --git a/identity/aidl/default/IdentityCredential.h b/identity/aidl/default/IdentityCredential.h
index a8bad88..a82531d 100644
--- a/identity/aidl/default/IdentityCredential.h
+++ b/identity/aidl/default/IdentityCredential.h
@@ -19,6 +19,7 @@
 
 #include <aidl/android/hardware/identity/BnIdentityCredential.h>
 #include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
+#include <aidl/android/hardware/keymaster/VerificationToken.h>
 #include <android/hardware/identity/support/IdentityCredentialSupport.h>
 
 #include <map>
@@ -31,6 +32,7 @@
 namespace aidl::android::hardware::identity {
 
 using ::aidl::android::hardware::keymaster::HardwareAuthToken;
+using ::aidl::android::hardware::keymaster::VerificationToken;
 using ::std::map;
 using ::std::set;
 using ::std::string;
@@ -55,6 +57,7 @@
     ndk::ScopedAStatus createAuthChallenge(int64_t* outChallenge) override;
     ndk::ScopedAStatus setRequestedNamespaces(
             const vector<RequestNamespace>& requestNamespaces) override;
+    ndk::ScopedAStatus setVerificationToken(const VerificationToken& verificationToken) override;
     ndk::ScopedAStatus startRetrieval(
             const vector<SecureAccessControlProfile>& accessControlProfiles,
             const HardwareAuthToken& authToken, const vector<uint8_t>& itemsRequest,
@@ -93,6 +96,9 @@
     // Set by setRequestedNamespaces()
     vector<RequestNamespace> requestNamespaces_;
 
+    // Set by setVerificationToken().
+    VerificationToken verificationToken_;
+
     // Set at startRetrieval() time.
     map<int32_t, int> profileIdToAccessCheckResult_;
     vector<uint8_t> signingKeyBlob_;
diff --git a/identity/aidl/default/service.cpp b/identity/aidl/default/service.cpp
index f05c615..bf95df5 100644
--- a/identity/aidl/default/service.cpp
+++ b/identity/aidl/default/service.cpp
@@ -22,9 +22,14 @@
 
 #include "IdentityCredentialStore.h"
 
+using ::android::base::InitLogging;
+using ::android::base::StderrLogger;
+
 using aidl::android::hardware::identity::IdentityCredentialStore;
 
-int main() {
+int main(int /*argc*/, char* argv[]) {
+    InitLogging(argv, StderrLogger);
+
     ABinderProcess_setThreadPoolMaxThreadCount(0);
     std::shared_ptr<IdentityCredentialStore> store =
             ndk::SharedRefBase::make<IdentityCredentialStore>();
diff --git a/identity/aidl/vts/VtsHalIdentityEndToEndTest.cpp b/identity/aidl/vts/VtsHalIdentityEndToEndTest.cpp
index 807feab..17145b4 100644
--- a/identity/aidl/vts/VtsHalIdentityEndToEndTest.cpp
+++ b/identity/aidl/vts/VtsHalIdentityEndToEndTest.cpp
@@ -43,6 +43,7 @@
 using ::android::binder::Status;
 
 using ::android::hardware::keymaster::HardwareAuthToken;
+using ::android::hardware::keymaster::VerificationToken;
 
 class IdentityAidl : public testing::TestWithParam<std::string> {
   public:
@@ -82,7 +83,20 @@
                                                           // Profile 1 (no authentication)
                                                           {1, {}, false, 0}};
 
+    // It doesn't matter since no user auth is needed in this particular test,
+    // but for good measure, clear out the tokens we pass to the HAL.
     HardwareAuthToken authToken;
+    VerificationToken verificationToken;
+    authToken.challenge = 0;
+    authToken.userId = 0;
+    authToken.authenticatorId = 0;
+    authToken.authenticatorType = ::android::hardware::keymaster::HardwareAuthenticatorType::NONE;
+    authToken.timestamp.milliSeconds = 0;
+    authToken.mac.clear();
+    verificationToken.challenge = 0;
+    verificationToken.timestamp.milliSeconds = 0;
+    verificationToken.securityLevel = ::android::hardware::keymaster::SecurityLevel::SOFTWARE;
+    verificationToken.mac.clear();
 
     // Here's the actual test data:
     const vector<test_utils::TestEntryData> testEntries = {
@@ -274,7 +288,10 @@
     ASSERT_TRUE(credential->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
 
     vector<RequestNamespace> requestedNamespaces = test_utils::buildRequestNamespaces(testEntries);
-    ASSERT_TRUE(credential->setRequestedNamespaces(requestedNamespaces).isOk());
+    // OK to fail, not available in v1 HAL
+    credential->setRequestedNamespaces(requestedNamespaces).isOk();
+    // OK to fail, not available in v1 HAL
+    credential->setVerificationToken(verificationToken);
     ASSERT_TRUE(credential
                         ->startRetrieval(secureProfiles.value(), authToken, itemsRequestBytes,
                                          signingKeyBlob, sessionTranscriptBytes,
diff --git a/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h b/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h
index 61645f8..f585d62 100644
--- a/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h
+++ b/keymaster/4.0/support/include/keymasterV4_0/keymaster_utils.h
@@ -18,6 +18,8 @@
 #define HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_UTILS_H_
 
 #include <android/hardware/keymaster/4.0/types.h>
+#include <optional>
+#include <vector>
 
 namespace android {
 namespace hardware {
@@ -52,6 +54,15 @@
 HardwareAuthToken hidlVec2AuthToken(const hidl_vec<uint8_t>& buffer);
 hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token);
 
+// Serializes and deserializes a verification token. This format is private and
+// not stable between releases and should not be persisted to disk.
+//
+// Currently doesn't support the |parametersVerified| field, will fail if set.
+//
+std::optional<VerificationToken> deserializeVerificationToken(
+        const std::vector<uint8_t>& serializedToken);
+std::optional<std::vector<uint8_t>> serializeVerificationToken(const VerificationToken& token);
+
 uint32_t getOsVersion();
 uint32_t getOsPatchlevel();
 
diff --git a/keymaster/4.0/support/keymaster_utils.cpp b/keymaster/4.0/support/keymaster_utils.cpp
index 850a776..366cd0e 100644
--- a/keymaster/4.0/support/keymaster_utils.cpp
+++ b/keymaster/4.0/support/keymaster_utils.cpp
@@ -16,6 +16,7 @@
 
 #include <regex.h>
 
+#include <android-base/logging.h>
 #include <android-base/properties.h>
 #include <hardware/hw_auth_token.h>
 #include <keymasterV4_0/keymaster_utils.h>
@@ -110,6 +111,80 @@
     return token;
 }
 
+void appendUint64(std::vector<uint8_t>& vec, uint64_t value) {
+    for (size_t n = 0; n < sizeof(uint64_t); n++) {
+        uint8_t byte = (value >> (n * 8)) & 0xff;
+        vec.push_back(byte);
+    }
+}
+
+uint64_t extractUint64(const std::vector<uint8_t>& data, size_t offset) {
+    uint64_t value = 0;
+    for (size_t n = 0; n < sizeof(uint64_t); n++) {
+        uint8_t byte = data[offset + n];
+        value |= byte << (n * 8);
+    }
+    return value;
+}
+
+void appendUint32(std::vector<uint8_t>& vec, uint32_t value) {
+    for (size_t n = 0; n < sizeof(uint32_t); n++) {
+        uint8_t byte = (value >> (n * 8)) & 0xff;
+        vec.push_back(byte);
+    }
+}
+
+uint32_t extractUint32(const std::vector<uint8_t>& data, size_t offset) {
+    uint32_t value = 0;
+    for (size_t n = 0; n < sizeof(uint32_t); n++) {
+        uint8_t byte = data[offset + n];
+        value |= byte << (n * 8);
+    }
+    return value;
+}
+
+std::optional<std::vector<uint8_t>> serializeVerificationToken(const VerificationToken& token) {
+    if (token.parametersVerified.size() > 0) {
+        LOG(ERROR) << "Serializing verification tokens with parametersVerified is not supported";
+        return {};
+    }
+    if (!(token.mac.size() == 0 || token.mac.size() == 32)) {
+        LOG(ERROR) << "Unexpected MAC size " << token.mac.size() << ", expected 0 or 32";
+        return {};
+    }
+    std::vector<uint8_t> serializedToken;
+    appendUint64(serializedToken, token.challenge);
+    appendUint64(serializedToken, token.timestamp);
+    appendUint32(serializedToken, uint32_t(token.securityLevel));
+    appendUint32(serializedToken, token.mac.size());
+    serializedToken.insert(serializedToken.end(), token.mac.begin(), token.mac.end());
+    return serializedToken;
+}
+
+std::optional<VerificationToken> deserializeVerificationToken(
+        const std::vector<uint8_t>& serializedToken) {
+    if (serializedToken.size() < 24) {
+        LOG(ERROR) << "Unexpected serialized VerificationToken size " << serializedToken.size()
+                   << ", expected at least 24 bytes";
+        return {};
+    }
+    VerificationToken token;
+    token.challenge = extractUint64(serializedToken, 0);
+    token.timestamp = extractUint64(serializedToken, 8);
+    token.securityLevel = SecurityLevel(extractUint32(serializedToken, 16));
+    size_t macSize = extractUint32(serializedToken, 20);
+    size_t expectedSerializedSize = 24 + macSize;
+    if (serializedToken.size() != expectedSerializedSize) {
+        LOG(ERROR) << "Unexpected serialized VerificationToken size " << serializedToken.size()
+                   << ", expected " << expectedSerializedSize;
+        return {};
+    }
+    if (macSize > 0) {
+        token.mac = std::vector<uint8_t>(serializedToken.begin() + 24, serializedToken.end());
+    }
+    return token;
+}
+
 namespace {
 
 constexpr char kPlatformVersionProp[] = "ro.build.version.release";
diff --git a/keymaster/aidl/Android.bp b/keymaster/aidl/Android.bp
index 3011da6..56a3ca9 100644
--- a/keymaster/aidl/Android.bp
+++ b/keymaster/aidl/Android.bp
@@ -15,5 +15,8 @@
             },
         },
     },
-    versions: ["1"],
+    versions: [
+        "1",
+        "2",
+    ],
 }
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/2/.hash b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/.hash
new file mode 100644
index 0000000..9d5974e
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/.hash
@@ -0,0 +1 @@
+91ab0be1887410935f564e3938ff12c5f5f8c59d
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/HardwareAuthToken.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/HardwareAuthToken.aidl
new file mode 100644
index 0000000..db1df2b
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/HardwareAuthToken.aidl
@@ -0,0 +1,27 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.keymaster;
+@VintfStability
+parcelable HardwareAuthToken {
+  long challenge;
+  long userId;
+  long authenticatorId;
+  android.hardware.keymaster.HardwareAuthenticatorType authenticatorType;
+  android.hardware.keymaster.Timestamp timestamp;
+  byte[] mac;
+}
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/HardwareAuthenticatorType.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/HardwareAuthenticatorType.aidl
new file mode 100644
index 0000000..924567f
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/HardwareAuthenticatorType.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.keymaster;
+@Backing(type="int") @VintfStability
+enum HardwareAuthenticatorType {
+  NONE = 0,
+  PASSWORD = 1,
+  FINGERPRINT = 2,
+  ANY = -1,
+}
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/SecurityLevel.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/SecurityLevel.aidl
new file mode 100644
index 0000000..127c1bf
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/SecurityLevel.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.keymaster;
+@Backing(type="int") @VintfStability
+enum SecurityLevel {
+  SOFTWARE = 0,
+  TRUSTED_ENVIRONMENT = 1,
+  STRONGBOX = 2,
+}
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/Timestamp.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/Timestamp.aidl
new file mode 100644
index 0000000..45fa1ae
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/Timestamp.aidl
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.keymaster;
+@VintfStability
+parcelable Timestamp {
+  long milliSeconds;
+}
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/VerificationToken.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/VerificationToken.aidl
new file mode 100644
index 0000000..0633765
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/2/android/hardware/keymaster/VerificationToken.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.keymaster;
+@VintfStability
+parcelable VerificationToken {
+  long challenge;
+  android.hardware.keymaster.Timestamp timestamp;
+  android.hardware.keymaster.SecurityLevel securityLevel;
+  byte[] mac;
+}
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/SecurityLevel.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/SecurityLevel.aidl
new file mode 100644
index 0000000..127c1bf
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/SecurityLevel.aidl
@@ -0,0 +1,24 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.keymaster;
+@Backing(type="int") @VintfStability
+enum SecurityLevel {
+  SOFTWARE = 0,
+  TRUSTED_ENVIRONMENT = 1,
+  STRONGBOX = 2,
+}
diff --git a/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/VerificationToken.aidl b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/VerificationToken.aidl
new file mode 100644
index 0000000..0633765
--- /dev/null
+++ b/keymaster/aidl/aidl_api/android.hardware.keymaster/current/android/hardware/keymaster/VerificationToken.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.keymaster;
+@VintfStability
+parcelable VerificationToken {
+  long challenge;
+  android.hardware.keymaster.Timestamp timestamp;
+  android.hardware.keymaster.SecurityLevel securityLevel;
+  byte[] mac;
+}
diff --git a/keymaster/aidl/android/hardware/keymaster/SecurityLevel.aidl b/keymaster/aidl/android/hardware/keymaster/SecurityLevel.aidl
new file mode 100644
index 0000000..f129783
--- /dev/null
+++ b/keymaster/aidl/android/hardware/keymaster/SecurityLevel.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.keymaster;
+
+/**
+ * Device security levels.
+ */
+@VintfStability
+@Backing(type="int")
+enum SecurityLevel {
+    SOFTWARE = 0,
+    TRUSTED_ENVIRONMENT = 1,
+    /**
+     * STRONGBOX specifies that the secure hardware satisfies the requirements specified in CDD
+     * 9.11.2.
+     */
+    STRONGBOX = 2,
+}
diff --git a/keymaster/aidl/android/hardware/keymaster/VerificationToken.aidl b/keymaster/aidl/android/hardware/keymaster/VerificationToken.aidl
new file mode 100644
index 0000000..eff9ca6
--- /dev/null
+++ b/keymaster/aidl/android/hardware/keymaster/VerificationToken.aidl
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.keymaster;
+
+import android.hardware.keymaster.SecurityLevel;
+import android.hardware.keymaster.Timestamp;
+import android.hardware.keymaster.HardwareAuthenticatorType;
+
+/**
+ * VerificationToken instances are used for secure environments to authenticate one another.
+ *
+ * This version of the parcelable currently don't use the parametersVerified field since it's not
+ * needed for time-based verification. This can be added in a later version, if needed.
+ */
+@VintfStability
+parcelable VerificationToken {
+    /**
+     * The operation handle, used to ensure freshness.
+     */
+    long challenge;
+
+    /**
+     * The current time of the secure environment that generates the VerificationToken.  This can be
+     * checked against auth tokens generated by the same secure environment, which avoids needing to
+     * synchronize clocks.
+     */
+    Timestamp timestamp;
+
+    /**
+     * SecurityLevel of the secure environment that generated the token.
+     */
+    SecurityLevel securityLevel;
+
+    /**
+     * 32-byte HMAC-SHA256 of the above values, computed as:
+     *
+     *    HMAC(H,
+     *         "Auth Verification" || challenge || timestamp || securityLevel || parametersVerified)
+     *
+     * where:
+     *
+     *   ``HMAC'' is the shared HMAC key (see computeSharedHmac() in IKeymaster).
+     *
+     *   ``||'' represents concatenation
+     *
+     * The representation of challenge and timestamp is as 64-bit unsigned integers in big-endian
+     * order.  securityLevel is represented as a 32-bit unsigned integer in big-endian order.
+     *
+     * If parametersVerified is non-empty, the representation of parametersVerified is an ASN.1 DER
+     * encoded representation of the values.  The ASN.1 schema used is the AuthorizationList schema
+     * from the Keystore attestation documentation.  If parametersVerified is empty, it is simply
+     * omitted from the HMAC computation.
+     */
+    byte[] mac;
+}