Delegate auth token parsing to HAL.

Auth tokens have an unfortunate dual character. To most of the system
they are opaque blobs that are intended only to be obtained from one
HAL (e.g. gatekeeper or fingerprint) and passed to another
HAL (keymaster), but keystore actually needs to extract some bits of
information from them in order to determine which of the available blobs
should be provided for a given keymaster key operation.

This CL adds a method that resolves this dual nature by moving the
responsibility of parsing blobs to the HAL so that no component of the
framework has to make any assumptions about their content and all can
treat them as fully opaque. This still means that the various HAL
implementers have to agree on content, but they also have to agree on an
HMAC key which much be securely distributed to all at every boot, so
asking them to agree on an auth token format is perfectly
acceptable. But now the Android system doesn't have to care about the
format.

Bug: 32962548
Test: CTS tests pass, plus manual testing.
Change-Id: I2ab4b4fbea1425fc08aa754fc10f8e386899af25
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
index 3f476cd..328121a 100644
--- a/keystore/auth_token_table.cpp
+++ b/keystore/auth_token_table.cpp
@@ -25,33 +25,6 @@
 
 namespace keystore {
 
-template <typename IntType, uint32_t byteOrder> struct choose_hton;
-
-template <typename IntType> struct choose_hton<IntType, __ORDER_LITTLE_ENDIAN__> {
-    inline static IntType hton(const IntType& value) {
-        IntType result = 0;
-        const unsigned char* inbytes = reinterpret_cast<const unsigned char*>(&value);
-        unsigned char* outbytes = reinterpret_cast<unsigned char*>(&result);
-        for (int i = sizeof(IntType) - 1; i >= 0; --i) {
-            *(outbytes++) = inbytes[i];
-        }
-        return result;
-    }
-};
-
-template <typename IntType> struct choose_hton<IntType, __ORDER_BIG_ENDIAN__> {
-    inline static IntType hton(const IntType& value) { return value; }
-};
-
-template <typename IntType> inline IntType hton(const IntType& value) {
-    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
-}
-
-template <typename IntType> inline IntType ntoh(const IntType& value) {
-    // same operation and hton
-    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
-}
-
 //
 // Some trivial template wrappers around std algorithms, so they take containers not ranges.
 //
@@ -75,8 +48,8 @@
     return time.tv_sec;
 }
 
-void AuthTokenTable::AddAuthenticationToken(const HardwareAuthToken* auth_token) {
-    Entry new_entry(auth_token, clock_function_());
+void AuthTokenTable::AddAuthenticationToken(hidl_vec<uint8_t> token, HardwareAuthTokenInfo info) {
+    Entry new_entry(std::move(token), std::move(info), clock_function_());
     RemoveEntriesSupersededBy(new_entry);
     if (entries_.size() >= max_entries_) {
         ALOGW("Auth token table filled up; replacing oldest entry");
@@ -107,7 +80,7 @@
 
 AuthTokenTable::Error AuthTokenTable::FindAuthorization(const AuthorizationSet& key_info,
                                                         KeyPurpose purpose, uint64_t op_handle,
-                                                        const HardwareAuthToken** found) {
+                                                        const hidl_vec<uint8_t>** found) {
     if (!KeyRequiresAuthentication(key_info, purpose)) return AUTH_NOT_REQUIRED;
 
     auto auth_type =
@@ -125,24 +98,24 @@
 AuthTokenTable::Error
 AuthTokenTable::FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
                                            HardwareAuthenticatorType auth_type, uint64_t op_handle,
-                                           const HardwareAuthToken** found) {
+                                           const hidl_vec<uint8_t>** found) {
     if (op_handle == 0) return OP_HANDLE_REQUIRED;
 
     auto matching_op = find_if(
-        entries_, [&](Entry& e) { return e.token()->challenge == op_handle && !e.completed(); });
+        entries_, [&](Entry& e) { return e.tokenInfo().challenge == op_handle && !e.completed(); });
 
     if (matching_op == entries_.end()) return AUTH_TOKEN_NOT_FOUND;
 
     if (!matching_op->SatisfiesAuth(sids, auth_type)) return AUTH_TOKEN_WRONG_SID;
 
-    *found = matching_op->token();
+    *found = &matching_op->token();
     return OK;
 }
 
 AuthTokenTable::Error AuthTokenTable::FindTimedAuthorization(const std::vector<uint64_t>& sids,
                                                              HardwareAuthenticatorType auth_type,
                                                              const AuthorizationSet& key_info,
-                                                             const HardwareAuthToken** found) {
+                                                             const hidl_vec<uint8_t>** found) {
     Entry* newest_match = NULL;
     for (auto& entry : entries_)
         if (entry.SatisfiesAuth(sids, auth_type) && entry.is_newer_than(newest_match))
@@ -164,7 +137,7 @@
     }
 
     newest_match->UpdateLastUse(now);
-    *found = newest_match->token();
+    *found = &newest_match->token();
     return OK;
 }
 
@@ -194,7 +167,7 @@
 }
 
 void AuthTokenTable::MarkCompleted(const uint64_t op_handle) {
-    auto found = find_if(entries_, [&](Entry& e) { return e.token()->challenge == op_handle; });
+    auto found = find_if(entries_, [&](Entry& e) { return e.tokenInfo().challenge == op_handle; });
     if (found == entries_.end()) return;
 
     assert(!IsSupersededBySomeEntry(*found));
@@ -203,25 +176,16 @@
     if (IsSupersededBySomeEntry(*found)) entries_.erase(found);
 }
 
-AuthTokenTable::Entry::Entry(const HardwareAuthToken* token, time_t current_time)
-    : token_(token), time_received_(current_time), last_use_(current_time),
-      operation_completed_(token_->challenge == 0) {}
-
-uint32_t AuthTokenTable::Entry::timestamp_host_order() const {
-    return ntoh(token_->timestamp);
-}
-
-HardwareAuthenticatorType AuthTokenTable::Entry::authenticator_type() const {
-    HardwareAuthenticatorType result = static_cast<HardwareAuthenticatorType>(
-        ntoh(static_cast<uint32_t>(token_->authenticatorType)));
-    return result;
-}
+AuthTokenTable::Entry::Entry(hidl_vec<uint8_t>&& token, HardwareAuthTokenInfo&& tokenInfo,
+                             time_t current_time)
+    : token_(std::move(token)), tokenInfo_(std::move(tokenInfo)), time_received_(current_time),
+      last_use_(current_time), operation_completed_(tokenInfo_.challenge == 0) {}
 
 bool AuthTokenTable::Entry::SatisfiesAuth(const std::vector<uint64_t>& sids,
                                           HardwareAuthenticatorType auth_type) {
     for (auto sid : sids)
-        if ((sid == token_->authenticatorId) ||
-            (sid == token_->userId && (auth_type & authenticator_type()) != 0))
+        if ((sid == tokenInfo_.authenticatorId) ||
+            (sid == tokenInfo_.userId && (auth_type & tokenInfo_.authenticatorType) != 0))
             return true;
     return false;
 }
@@ -233,10 +197,9 @@
 bool AuthTokenTable::Entry::Supersedes(const Entry& entry) const {
     if (!entry.completed()) return false;
 
-    return (token_->userId == entry.token_->userId &&
-            token_->authenticatorType == entry.token_->authenticatorType &&
-            token_->authenticatorType == entry.token_->authenticatorType &&
-            timestamp_host_order() > entry.timestamp_host_order());
+    return (tokenInfo_.userId == entry.tokenInfo_.userId &&
+            tokenInfo_.authenticatorType == entry.tokenInfo_.authenticatorType &&
+            tokenInfo_.timestamp > entry.tokenInfo_.timestamp);
 }
 
 }  // namespace keymaster
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index 6f7aab1..9bc944c 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -25,7 +25,7 @@
 
 namespace keystore {
 
-using android::hardware::keymaster::V3_0::HardwareAuthToken;
+using android::hardware::keymaster::V3_0::HardwareAuthTokenInfo;
 
 namespace test {
 class AuthTokenTableTest;
@@ -59,9 +59,9 @@
     };
 
     /**
-     * Add an authorization token to the table.  The table takes ownership of the argument.
+     * Add an authorization token to the table.
      */
-    void AddAuthenticationToken(const HardwareAuthToken* token);
+    void AddAuthenticationToken(hidl_vec<uint8_t> token, HardwareAuthTokenInfo info);
 
     /**
      * Find an authorization token that authorizes the operation specified by \p operation_handle on
@@ -74,7 +74,7 @@
      * The table retains ownership of the returned object.
      */
     Error FindAuthorization(const AuthorizationSet& key_info, KeyPurpose purpose,
-                            uint64_t op_handle, const HardwareAuthToken** found);
+                            uint64_t op_handle, const hidl_vec<uint8_t>** token_found);
 
     /**
      * Mark operation completed.  This allows tokens associated with the specified operation to be
@@ -97,11 +97,12 @@
 
     class Entry {
       public:
-        Entry(const HardwareAuthToken* token, time_t current_time);
+        Entry(hidl_vec<uint8_t>&& token, HardwareAuthTokenInfo&& tokenInfo, time_t current_time);
         Entry(Entry&& entry) { *this = std::move(entry); }
 
         void operator=(Entry&& rhs) {
             token_ = std::move(rhs.token_);
+            tokenInfo_ = std::move(rhs.tokenInfo_);
             time_received_ = rhs.time_received_;
             last_use_ = rhs.last_use_;
             operation_completed_ = rhs.operation_completed_;
@@ -116,19 +117,19 @@
 
         bool is_newer_than(const Entry* entry) {
             if (!entry) return true;
-            return timestamp_host_order() > entry->timestamp_host_order();
+            return tokenInfo_.timestamp > entry->tokenInfo_.timestamp;
         }
 
         void mark_completed() { operation_completed_ = true; }
 
-        const HardwareAuthToken* token() { return token_.get(); }
+        const hidl_vec<uint8_t>& token() { return token_; }
+        const HardwareAuthTokenInfo& tokenInfo() { return tokenInfo_; }
         time_t time_received() const { return time_received_; }
         bool completed() const { return operation_completed_; }
-        uint32_t timestamp_host_order() const;
-        HardwareAuthenticatorType authenticator_type() const;
 
       private:
-        std::unique_ptr<const HardwareAuthToken> token_;
+        hidl_vec<uint8_t> token_;
+        HardwareAuthTokenInfo tokenInfo_;
         time_t time_received_;
         time_t last_use_;
         bool operation_completed_;
@@ -136,10 +137,10 @@
 
     Error FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
                                      HardwareAuthenticatorType auth_type, uint64_t op_handle,
-                                     const HardwareAuthToken** found);
+                                     const hidl_vec<uint8_t>** found);
     Error FindTimedAuthorization(const std::vector<uint64_t>& sids,
                                  HardwareAuthenticatorType auth_type,
-                                 const AuthorizationSet& key_info, const HardwareAuthToken** found);
+                                 const AuthorizationSet& key_info, const hidl_vec<uint8_t>** found);
     void ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids);
     void RemoveEntriesSupersededBy(const Entry& entry);
     bool IsSupersededBySomeEntry(const Entry& entry);
diff --git a/keystore/include/keystore/keymaster_tags.h b/keystore/include/keystore/keymaster_tags.h
index 05a33cd..a003c60 100644
--- a/keystore/include/keystore/keymaster_tags.h
+++ b/keystore/include/keystore/keymaster_tags.h
@@ -70,7 +70,7 @@
 using ::android::hardware::keymaster::V3_0::Digest;
 using ::android::hardware::keymaster::V3_0::EcCurve;
 using ::android::hardware::keymaster::V3_0::ErrorCode;
-using ::android::hardware::keymaster::V3_0::HardwareAuthToken;
+using ::android::hardware::keymaster::V3_0::HardwareAuthTokenInfo;
 using ::android::hardware::keymaster::V3_0::HardwareAuthenticatorType;
 using ::android::hardware::keymaster::V3_0::IKeymasterDevice;
 using ::android::hardware::keymaster::V3_0::KeyBlobUsageRequirements;
diff --git a/keystore/include/keystore/keystore_hidl_support.h b/keystore/include/keystore/keystore_hidl_support.h
index 3c64d2a..253e81a 100644
--- a/keystore/include/keystore/keystore_hidl_support.h
+++ b/keystore/include/keystore/keystore_hidl_support.h
@@ -97,30 +97,6 @@
     return std::copy(value_ptr, value_ptr + sizeof(value), dest);
 }
 
-inline static hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) {
-    static_assert(
-        std::is_same<decltype(token.hmac), ::android::hardware::hidl_array<uint8_t, 32>>::value,
-        "This function assumes token HMAC is 32 bytes, but it might not be.");
-    static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
-                          sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
-                          sizeof(token.timestamp) + 32 /* HMAC size */
-                      == sizeof(hw_auth_token_t),
-                  "HardwareAuthToken content size does not match hw_auth_token_t size");
-
-    hidl_vec<uint8_t> result;
-    result.resize(sizeof(hw_auth_token_t));
-    auto pos = result.begin();
-    *pos++ = 0;  // Version byte
-    pos = copy_bytes_to_iterator(token.challenge, pos);
-    pos = copy_bytes_to_iterator(token.userId, pos);
-    pos = copy_bytes_to_iterator(token.authenticatorId, pos);
-    pos = copy_bytes_to_iterator(token.authenticatorType, pos);
-    pos = copy_bytes_to_iterator(token.timestamp, pos);
-    pos = std::copy(token.hmac.data(), token.hmac.data() + token.hmac.size(), pos);
-
-    return result;
-}
-
 inline std::string hidlVec2String(const hidl_vec<uint8_t>& value) {
     return std::string(reinterpret_cast<const std::string::value_type*>(&value[0]), value.size());
 }
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index cd81674..4c1f360 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -893,9 +893,9 @@
     }
 }
 
-static inline void addAuthTokenToParams(AuthorizationSet* params, const HardwareAuthToken* token) {
+static inline void addAuthTokenToParams(AuthorizationSet* params, const hidl_vec<uint8_t>* token) {
     if (token) {
-        params->push_back(TAG_AUTH_TOKEN, authToken2HidlVec(*token));
+        params->push_back(TAG_AUTH_TOKEN, *token);
     }
 }
 
@@ -944,7 +944,7 @@
         return;
     }
 
-    const HardwareAuthToken* authToken = NULL;
+    const hidl_vec<uint8_t>* authToken = NULL;
 
     // Merge these characteristics with the ones cached when the key was generated or imported
     Blob charBlob;
@@ -1050,7 +1050,7 @@
     assert(characteristics.softwareEnforced.size() == 0);
 
     if (authToken) {
-        mOperationMap.setOperationAuthToken(operationToken, authToken);
+        mOperationMap.setOperationAuthToken(operationToken, *authToken);
     }
     // Return the authentication lookup result. If this is a per operation
     // auth'd key then the resultCode will be ::OP_AUTH_NEEDED and the
@@ -1197,7 +1197,7 @@
     if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
         return false;
     }
-    const HardwareAuthToken* authToken = NULL;
+    const hidl_vec<uint8_t>* authToken = NULL;
     mOperationMap.getOperationAuthToken(token, &authToken);
     AuthorizationSet ignored;
     auto authResult = addOperationAuthTokenIfNeeded(token, &ignored);
@@ -1205,38 +1205,25 @@
 }
 
 KeyStoreServiceReturnCode KeyStoreService::addAuthToken(const uint8_t* token, size_t length) {
-    // TODO(swillden): When gatekeeper and fingerprint are ready, this should be updated to
-    // receive a HardwareAuthToken, rather than an opaque byte array.
-
     if (!checkBinderPermission(P_ADD_AUTH)) {
         ALOGW("addAuthToken: permission denied for %d", IPCThreadState::self()->getCallingUid());
         return ResponseCode::PERMISSION_DENIED;
     }
-    if (length != sizeof(hw_auth_token_t)) {
-        return ErrorCode::INVALID_ARGUMENT;
-    }
 
-    hw_auth_token_t authToken;
-    memcpy(reinterpret_cast<void*>(&authToken), token, sizeof(hw_auth_token_t));
-    if (authToken.version != 0) {
-        return ErrorCode::INVALID_ARGUMENT;
-    }
+    hidl_vec<uint8_t> hidl_token;
+    hidl_token.setToExternal(const_cast<uint8_t*>(token), length);
 
-    std::unique_ptr<HardwareAuthToken> hidlAuthToken(new HardwareAuthToken);
-    hidlAuthToken->challenge = authToken.challenge;
-    hidlAuthToken->userId = authToken.user_id;
-    hidlAuthToken->authenticatorId = authToken.authenticator_id;
-    hidlAuthToken->authenticatorType = authToken.authenticator_type;
-    hidlAuthToken->timestamp = authToken.timestamp;
-    static_assert(
-        std::is_same<decltype(hidlAuthToken->hmac),
-                     ::android::hardware::hidl_array<uint8_t, sizeof(authToken.hmac)>>::value,
-        "This function assumes token HMAC is 32 bytes, but it might not be.");
-    std::copy(authToken.hmac, authToken.hmac + sizeof(authToken.hmac), hidlAuthToken->hmac.data());
-
-    // The table takes ownership of authToken.
-    mAuthTokenTable.AddAuthenticationToken(hidlAuthToken.release());
-    return ResponseCode::NO_ERROR;
+    ErrorCode error;
+    KeyStoreServiceReturnCode rc =
+        KS_HANDLE_HIDL_ERROR(mKeyStore->getDevice()->parseHardwareAuthToken(
+            hidl_token, [&](ErrorCode hidlError, const HardwareAuthTokenInfo& tokenInfo) {
+                error = hidlError;
+                if (error == ErrorCode::OK) {
+                    mAuthTokenTable.AddAuthenticationToken(hidl_token, tokenInfo);
+                }
+            }));
+    if (rc.isOk()) rc = error;
+    return rc;
 }
 
 constexpr size_t KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE = 1024;
@@ -1507,18 +1494,20 @@
 }
 
 /**
- * Get the auth token for this operation from the auth token table.
+ * Get the auth token for this operation from the auth token table.  The caller does not acquire
+ * ownership of the auth token.
  *
- * Returns ResponseCode::NO_ERROR if the auth token was set or none was required.
- *         ::OP_AUTH_NEEDED if it is a per op authorization, no
- *         authorization token exists for that operation and
- *         failOnTokenMissing is false.
- *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth
- *         token for the operation
+ * Returns:
+ *         ResponseCode::NO_ERROR if the auth token was set or none was required.
+ *
+ *         ::OP_AUTH_NEEDED if it is a per op authorization, no authorization token exists for that
+ *         operation and failOnTokenMissing is false.
+ *
+ *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth token for the operation
  */
 KeyStoreServiceReturnCode KeyStoreService::getAuthToken(const KeyCharacteristics& characteristics,
                                                         uint64_t handle, KeyPurpose purpose,
-                                                        const HardwareAuthToken** authToken,
+                                                        const hidl_vec<uint8_t>** authToken,
                                                         bool failOnTokenMissing) {
 
     AuthorizationSet allCharacteristics;
@@ -1560,7 +1549,7 @@
  */
 KeyStoreServiceReturnCode KeyStoreService::addOperationAuthTokenIfNeeded(const sp<IBinder>& token,
                                                                          AuthorizationSet* params) {
-    const HardwareAuthToken* authToken = nullptr;
+    const hidl_vec<uint8_t>* authToken = nullptr;
     mOperationMap.getOperationAuthToken(token, &authToken);
     if (!authToken) {
         km_device_t dev;
@@ -1576,7 +1565,7 @@
             return result;
         }
         if (authToken) {
-            mOperationMap.setOperationAuthToken(token, authToken);
+            mOperationMap.setOperationAuthToken(token, *authToken);
         }
     }
     addAuthTokenToParams(params, authToken);
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index 432e780..835b0c9 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -203,7 +203,7 @@
      */
     KeyStoreServiceReturnCode getAuthToken(const KeyCharacteristics& characteristics,
                                            uint64_t handle, KeyPurpose purpose,
-                                           const HardwareAuthToken** authToken,
+                                           const hidl_vec<uint8_t>** authToken,
                                            bool failOnTokenMissing = true);
 
     /**
diff --git a/keystore/legacy_keymaster_device_wrapper.cpp b/keystore/legacy_keymaster_device_wrapper.cpp
index 187252e..1a9b508 100644
--- a/keystore/legacy_keymaster_device_wrapper.cpp
+++ b/keystore/legacy_keymaster_device_wrapper.cpp
@@ -204,6 +204,13 @@
     return Void();
 }
 
+Return<void>
+LegacyKeymasterDeviceWrapper::parseHardwareAuthToken(const hidl_vec<uint8_t>& /* token */,
+                                                     parseHardwareAuthToken_cb _hidl_cb) {
+    // parseHardwareAuthToken is only called on a real HAL, never on the fallback device.
+    _hidl_cb(ErrorCode::UNIMPLEMENTED, HardwareAuthTokenInfo());
+    return Void();
+}
 Return<ErrorCode> LegacyKeymasterDeviceWrapper::addRngEntropy(const hidl_vec<uint8_t>& data) {
     return legacy_enum_conversion(
         keymaster_device_->add_rng_entropy(keymaster_device_, &data[0], data.size()));
diff --git a/keystore/legacy_keymaster_device_wrapper.h b/keystore/legacy_keymaster_device_wrapper.h
index ad26221..d5ba61c 100644
--- a/keystore/legacy_keymaster_device_wrapper.h
+++ b/keystore/legacy_keymaster_device_wrapper.h
@@ -19,8 +19,8 @@
 #define LEGACY_KEYMASTER_DEVICE_WRAPPER_H_
 
 #include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <hidl/Status.h>
 #include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
 
 struct keymaster2_device;
 typedef struct keymaster2_device keymaster2_device_t;
@@ -29,6 +29,7 @@
 namespace keystore {
 
 using ::android::hardware::keymaster::V3_0::ErrorCode;
+using ::android::hardware::keymaster::V3_0::HardwareAuthTokenInfo;
 using ::android::hardware::keymaster::V3_0::IKeymasterDevice;
 using ::android::hardware::keymaster::V3_0::KeyCharacteristics;
 using ::android::hardware::keymaster::V3_0::KeyFormat;
@@ -48,6 +49,8 @@
 
     // Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
     Return<void> getHardwareFeatures(getHardwareFeatures_cb _hidl_cb);
+    Return<void> parseHardwareAuthToken(const hidl_vec<uint8_t>& token,
+                                        parseHardwareAuthToken_cb _hidl_cb);
     Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override;
     Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
                              generateKey_cb _hidl_cb) override;
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
index 8c39716..f56e7f8 100644
--- a/keystore/operation.cpp
+++ b/keystore/operation.cpp
@@ -117,23 +117,22 @@
 }
 
 bool OperationMap::getOperationAuthToken(const sp<IBinder>& token,
-                                         const HardwareAuthToken** outToken) {
+                                         const hidl_vec<uint8_t>** outToken) {
     auto entry = mMap.find(token);
     if (entry == mMap.end()) {
         return false;
     }
-    *outToken = entry->second.authToken.get();
+    *outToken = &entry->second.authToken;
     return true;
 }
 
 bool OperationMap::setOperationAuthToken(const sp<IBinder>& token,
-                                         const HardwareAuthToken* authToken) {
+                                         hidl_vec<uint8_t> authToken) {
     auto entry = mMap.find(token);
     if (entry == mMap.end()) {
         return false;
     }
-    entry->second.authToken.reset(new HardwareAuthToken);
-    *entry->second.authToken = *authToken;
+    entry->second.authToken = std::move(authToken);
     return true;
 }
 
diff --git a/keystore/operation.h b/keystore/operation.h
index e69b43a..9ca0a11 100644
--- a/keystore/operation.h
+++ b/keystore/operation.h
@@ -55,9 +55,9 @@
     size_t getOperationCount() const { return mMap.size(); }
     size_t getPruneableOperationCount() const;
     bool getOperationAuthToken(const android::sp<android::IBinder>& token,
-                               const HardwareAuthToken** outToken);
+                               const hidl_vec<uint8_t>** outToken);
     bool setOperationAuthToken(const android::sp<android::IBinder>& token,
-                               const HardwareAuthToken* authToken);
+                               hidl_vec<uint8_t> authToken);
     android::sp<android::IBinder> getOldestPruneableOperation();
     std::vector<android::sp<android::IBinder>>
     getOperationsForToken(const android::sp<android::IBinder>& appToken);
@@ -76,7 +76,7 @@
         km_device_t device;
         KeyCharacteristics characteristics;
         android::sp<android::IBinder> appToken;
-        std::unique_ptr<HardwareAuthToken> authToken;
+        hidl_vec<uint8_t> authToken;
     };
     std::map<android::sp<android::IBinder>, Operation> mMap;
     std::vector<android::sp<android::IBinder>> mLru;