diff --git a/identity/aidl/vts/ReaderAuthTests.cpp b/identity/aidl/vts/ReaderAuthTests.cpp
new file mode 100644
index 0000000..680ba5b
--- /dev/null
+++ b/identity/aidl/vts/ReaderAuthTests.cpp
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#define LOG_TAG "ReaderAuthTests"
+
+#include <aidl/Gtest.h>
+#include <aidl/Vintf.h>
+#include <aidl/android/hardware/keymaster/HardwareAuthToken.h>
+#include <aidl/android/hardware/keymaster/VerificationToken.h>
+#include <android-base/logging.h>
+#include <android/hardware/identity/IIdentityCredentialStore.h>
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+#include <binder/IServiceManager.h>
+#include <binder/ProcessState.h>
+#include <cppbor.h>
+#include <cppbor_parse.h>
+#include <gtest/gtest.h>
+#include <future>
+#include <map>
+#include <utility>
+
+#include "VtsIdentityTestUtils.h"
+
+namespace android::hardware::identity {
+
+using std::endl;
+using std::make_pair;
+using std::map;
+using std::optional;
+using std::pair;
+using std::string;
+using std::tie;
+using std::vector;
+
+using ::android::sp;
+using ::android::String16;
+using ::android::binder::Status;
+
+using ::android::hardware::keymaster::HardwareAuthToken;
+using ::android::hardware::keymaster::VerificationToken;
+
+class ReaderAuthTests : public testing::TestWithParam<string> {
+  public:
+    virtual void SetUp() override {
+        credentialStore_ = android::waitForDeclaredService<IIdentityCredentialStore>(
+                String16(GetParam().c_str()));
+        ASSERT_NE(credentialStore_, nullptr);
+    }
+
+    void provisionData();
+    void retrieveData(const vector<uint8_t>& readerPrivateKey,
+                      const vector<vector<uint8_t>>& readerCertChain, bool expectSuccess,
+                      bool leaveOutAccessibleToAllFromRequestMessage);
+
+    // Set by provisionData
+    vector<uint8_t> readerPublicKey_;
+    vector<uint8_t> readerPrivateKey_;
+    vector<uint8_t> intermediateAPublicKey_;
+    vector<uint8_t> intermediateAPrivateKey_;
+    vector<uint8_t> intermediateBPublicKey_;
+    vector<uint8_t> intermediateBPrivateKey_;
+    vector<uint8_t> intermediateCPublicKey_;
+    vector<uint8_t> intermediateCPrivateKey_;
+
+    vector<uint8_t> cert_A_SelfSigned_;
+
+    vector<uint8_t> cert_B_SelfSigned_;
+
+    vector<uint8_t> cert_B_SignedBy_C_;
+
+    vector<uint8_t> cert_C_SelfSigned_;
+
+    vector<uint8_t> cert_reader_SelfSigned_;
+    vector<uint8_t> cert_reader_SignedBy_A_;
+    vector<uint8_t> cert_reader_SignedBy_B_;
+
+    SecureAccessControlProfile sacp0_;
+    SecureAccessControlProfile sacp1_;
+    SecureAccessControlProfile sacp2_;
+    SecureAccessControlProfile sacp3_;
+
+    vector<uint8_t> encContentAccessibleByA_;
+    vector<uint8_t> encContentAccessibleByAorB_;
+    vector<uint8_t> encContentAccessibleByB_;
+    vector<uint8_t> encContentAccessibleByC_;
+    vector<uint8_t> encContentAccessibleByAll_;
+    vector<uint8_t> encContentAccessibleByNone_;
+
+    vector<uint8_t> credentialData_;
+
+    // Set by retrieveData()
+    bool canGetAccessibleByA_;
+    bool canGetAccessibleByAorB_;
+    bool canGetAccessibleByB_;
+    bool canGetAccessibleByC_;
+    bool canGetAccessibleByAll_;
+    bool canGetAccessibleByNone_;
+
+    sp<IIdentityCredentialStore> credentialStore_;
+};
+
+pair<vector<uint8_t>, vector<uint8_t>> generateReaderKey() {
+    optional<vector<uint8_t>> keyPKCS8 = support::createEcKeyPair();
+    optional<vector<uint8_t>> publicKey = support::ecKeyPairGetPublicKey(keyPKCS8.value());
+    optional<vector<uint8_t>> privateKey = support::ecKeyPairGetPrivateKey(keyPKCS8.value());
+    return make_pair(publicKey.value(), privateKey.value());
+}
+
+vector<uint8_t> generateReaderCert(const vector<uint8_t>& publicKey,
+                                   const vector<uint8_t>& signingKey) {
+    time_t validityNotBefore = 0;
+    time_t validityNotAfter = 0xffffffff;
+    optional<vector<uint8_t>> cert =
+            support::ecPublicKeyGenerateCertificate(publicKey, signingKey, "24601", "Issuer",
+                                                    "Subject", validityNotBefore, validityNotAfter);
+    return cert.value();
+}
+
+void ReaderAuthTests::provisionData() {
+    // Keys and certificates for intermediates.
+    tie(intermediateAPublicKey_, intermediateAPrivateKey_) = generateReaderKey();
+    tie(intermediateBPublicKey_, intermediateBPrivateKey_) = generateReaderKey();
+    tie(intermediateCPublicKey_, intermediateCPrivateKey_) = generateReaderKey();
+
+    cert_A_SelfSigned_ = generateReaderCert(intermediateAPublicKey_, intermediateAPrivateKey_);
+
+    cert_B_SelfSigned_ = generateReaderCert(intermediateBPublicKey_, intermediateBPrivateKey_);
+
+    cert_B_SignedBy_C_ = generateReaderCert(intermediateBPublicKey_, intermediateCPrivateKey_);
+
+    cert_C_SelfSigned_ = generateReaderCert(intermediateCPublicKey_, intermediateCPrivateKey_);
+
+    // Key and self-signed certificate reader
+    tie(readerPublicKey_, readerPrivateKey_) = generateReaderKey();
+    cert_reader_SelfSigned_ = generateReaderCert(readerPublicKey_, readerPrivateKey_);
+
+    // Certificate for reader signed by intermediates
+    cert_reader_SignedBy_A_ = generateReaderCert(readerPublicKey_, intermediateAPrivateKey_);
+    cert_reader_SignedBy_B_ = generateReaderCert(readerPublicKey_, intermediateBPrivateKey_);
+
+    string docType = "org.iso.18013-5.2019.mdl";
+    bool testCredential = true;
+    sp<IWritableIdentityCredential> wc;
+    ASSERT_TRUE(credentialStore_->createCredential(docType, testCredential, &wc).isOk());
+
+    vector<uint8_t> attestationApplicationId = {};
+    vector<uint8_t> attestationChallenge = {1};
+    vector<Certificate> certChain;
+    ASSERT_TRUE(wc->getAttestationCertificate(attestationApplicationId, attestationChallenge,
+                                              &certChain)
+                        .isOk());
+
+    size_t proofOfProvisioningSize =
+            465 + cert_A_SelfSigned_.size() + cert_B_SelfSigned_.size() + cert_C_SelfSigned_.size();
+    ASSERT_TRUE(wc->setExpectedProofOfProvisioningSize(proofOfProvisioningSize).isOk());
+
+    // Not in v1 HAL, may fail
+    wc->startPersonalization(4 /* numAccessControlProfiles */,
+                             {6} /* numDataElementsPerNamespace */);
+
+    // AIDL expects certificates wrapped in the Certificate type...
+    Certificate cert_A;
+    Certificate cert_B;
+    Certificate cert_C;
+    cert_A.encodedCertificate = cert_A_SelfSigned_;
+    cert_B.encodedCertificate = cert_B_SelfSigned_;
+    cert_C.encodedCertificate = cert_C_SelfSigned_;
+
+    // Access control profile 0: accessible by A
+    ASSERT_TRUE(wc->addAccessControlProfile(0, cert_A, false, 0, 0, &sacp0_).isOk());
+
+    // Access control profile 1: accessible by B
+    ASSERT_TRUE(wc->addAccessControlProfile(1, cert_B, false, 0, 0, &sacp1_).isOk());
+
+    // Access control profile 2: accessible by C
+    ASSERT_TRUE(wc->addAccessControlProfile(2, cert_C, false, 0, 0, &sacp2_).isOk());
+
+    // Access control profile 3: open access
+    ASSERT_TRUE(wc->addAccessControlProfile(3, {}, false, 0, 0, &sacp3_).isOk());
+
+    // Data Element: "Accessible by A"
+    ASSERT_TRUE(wc->beginAddEntry({0}, "ns", "Accessible by A", 1).isOk());
+    ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByA_).isOk());
+
+    // Data Element: "Accessible by A or B"
+    ASSERT_TRUE(wc->beginAddEntry({0, 1}, "ns", "Accessible by A or B", 1).isOk());
+    ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByAorB_).isOk());
+
+    // Data Element: "Accessible by B"
+    ASSERT_TRUE(wc->beginAddEntry({1}, "ns", "Accessible by B", 1).isOk());
+    ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByB_).isOk());
+
+    // Data Element: "Accessible by C"
+    ASSERT_TRUE(wc->beginAddEntry({2}, "ns", "Accessible by C", 1).isOk());
+    ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByC_).isOk());
+
+    // Data Element: "Accessible by All"
+    ASSERT_TRUE(wc->beginAddEntry({3}, "ns", "Accessible by All", 1).isOk());
+    ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByAll_).isOk());
+
+    // Data Element: "Accessible by None"
+    ASSERT_TRUE(wc->beginAddEntry({}, "ns", "Accessible by None", 1).isOk());
+    ASSERT_TRUE(wc->addEntryValue({9}, &encContentAccessibleByNone_).isOk());
+
+    vector<uint8_t> proofOfProvisioningSignature;
+    ASSERT_TRUE(wc->finishAddingEntries(&credentialData_, &proofOfProvisioningSignature).isOk());
+}
+
+RequestDataItem buildRequestDataItem(const string& name, size_t size,
+                                     vector<int32_t> accessControlProfileIds) {
+    RequestDataItem item;
+    item.name = name;
+    item.size = size;
+    item.accessControlProfileIds = accessControlProfileIds;
+    return item;
+}
+
+void ReaderAuthTests::retrieveData(const vector<uint8_t>& readerPrivateKey,
+                                   const vector<vector<uint8_t>>& readerCertChain,
+                                   bool expectSuccess,
+                                   bool leaveOutAccessibleToAllFromRequestMessage) {
+    canGetAccessibleByA_ = false;
+    canGetAccessibleByAorB_ = false;
+    canGetAccessibleByB_ = false;
+    canGetAccessibleByC_ = false;
+    canGetAccessibleByAll_ = false;
+    canGetAccessibleByNone_ = false;
+
+    sp<IIdentityCredential> c;
+    ASSERT_TRUE(credentialStore_
+                        ->getCredential(
+                                CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
+                                credentialData_, &c)
+                        .isOk());
+
+    optional<vector<uint8_t>> readerEKeyPair = support::createEcKeyPair();
+    optional<vector<uint8_t>> readerEPublicKey =
+            support::ecKeyPairGetPublicKey(readerEKeyPair.value());
+    ASSERT_TRUE(c->setReaderEphemeralPublicKey(readerEPublicKey.value()).isOk());
+
+    vector<uint8_t> eKeyPair;
+    ASSERT_TRUE(c->createEphemeralKeyPair(&eKeyPair).isOk());
+    optional<vector<uint8_t>> ePublicKey = support::ecKeyPairGetPublicKey(eKeyPair);
+
+    // Calculate requestData field and sign it with the reader key.
+    auto [getXYSuccess, ephX, ephY] = support::ecPublicKeyGetXandY(ePublicKey.value());
+    ASSERT_TRUE(getXYSuccess);
+    cppbor::Map deviceEngagement = cppbor::Map().add("ephX", ephX).add("ephY", ephY);
+    vector<uint8_t> deviceEngagementBytes = deviceEngagement.encode();
+    vector<uint8_t> eReaderPubBytes = cppbor::Tstr("ignored").encode();
+    cppbor::Array sessionTranscript = cppbor::Array()
+                                              .add(cppbor::Semantic(24, deviceEngagementBytes))
+                                              .add(cppbor::Semantic(24, eReaderPubBytes));
+    vector<uint8_t> sessionTranscriptBytes = sessionTranscript.encode();
+
+    vector<uint8_t> itemsRequestBytes;
+    if (leaveOutAccessibleToAllFromRequestMessage) {
+        itemsRequestBytes =
+                cppbor::Map("nameSpaces",
+                            cppbor::Map().add("ns", cppbor::Map()
+                                                            .add("Accessible by A", false)
+                                                            .add("Accessible by A or B", false)
+                                                            .add("Accessible by B", false)
+                                                            .add("Accessible by C", false)
+                                                            .add("Accessible by None", false)))
+                        .encode();
+    } else {
+        itemsRequestBytes =
+                cppbor::Map("nameSpaces",
+                            cppbor::Map().add("ns", cppbor::Map()
+                                                            .add("Accessible by A", false)
+                                                            .add("Accessible by A or B", false)
+                                                            .add("Accessible by B", false)
+                                                            .add("Accessible by C", false)
+                                                            .add("Accessible by All", false)
+                                                            .add("Accessible by None", false)))
+                        .encode();
+    }
+    vector<uint8_t> dataToSign = cppbor::Array()
+                                         .add("ReaderAuthentication")
+                                         .add(sessionTranscript.clone())
+                                         .add(cppbor::Semantic(24, itemsRequestBytes))
+                                         .encode();
+
+    optional<vector<uint8_t>> readerSignature =
+            support::coseSignEcDsa(readerPrivateKey,  // private key for reader
+                                   {},                // content
+                                   dataToSign,        // detached content
+                                   support::certificateChainJoin(readerCertChain));
+    ASSERT_TRUE(readerSignature);
+
+    // Generate the key that will be used to sign AuthenticatedData.
+    vector<uint8_t> signingKeyBlob;
+    Certificate signingKeyCertificate;
+    ASSERT_TRUE(c->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
+
+    RequestNamespace rns;
+    rns.namespaceName = "ns";
+    rns.items.push_back(buildRequestDataItem("Accessible by A", 1, {0}));
+    rns.items.push_back(buildRequestDataItem("Accessible by A or B", 1, {0, 1}));
+    rns.items.push_back(buildRequestDataItem("Accessible by B", 1, {1}));
+    rns.items.push_back(buildRequestDataItem("Accessible by C", 1, {2}));
+    rns.items.push_back(buildRequestDataItem("Accessible by All", 1, {3}));
+    rns.items.push_back(buildRequestDataItem("Accessible by None", 1, {}));
+    // OK to fail, not available in v1 HAL
+    c->setRequestedNamespaces({rns}).isOk();
+
+    // 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();
+    // OK to fail, not available in v1 HAL
+    c->setVerificationToken(verificationToken);
+
+    Status status = c->startRetrieval(
+            {sacp0_, sacp1_, sacp2_, sacp3_}, authToken, itemsRequestBytes, signingKeyBlob,
+            sessionTranscriptBytes, readerSignature.value(), {6 /* numDataElementsPerNamespace */});
+    if (expectSuccess) {
+        ASSERT_TRUE(status.isOk());
+    } else {
+        ASSERT_FALSE(status.isOk());
+        return;
+    }
+
+    vector<uint8_t> decrypted;
+
+    status = c->startRetrieveEntryValue("ns", "Accessible by A", 1, {0});
+    if (status.isOk()) {
+        canGetAccessibleByA_ = true;
+        ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByA_, &decrypted).isOk());
+    }
+
+    status = c->startRetrieveEntryValue("ns", "Accessible by A or B", 1, {0, 1});
+    if (status.isOk()) {
+        canGetAccessibleByAorB_ = true;
+        ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByAorB_, &decrypted).isOk());
+    }
+
+    status = c->startRetrieveEntryValue("ns", "Accessible by B", 1, {1});
+    if (status.isOk()) {
+        canGetAccessibleByB_ = true;
+        ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByB_, &decrypted).isOk());
+    }
+
+    status = c->startRetrieveEntryValue("ns", "Accessible by C", 1, {2});
+    if (status.isOk()) {
+        canGetAccessibleByC_ = true;
+        ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByC_, &decrypted).isOk());
+    }
+
+    status = c->startRetrieveEntryValue("ns", "Accessible by All", 1, {3});
+    if (status.isOk()) {
+        canGetAccessibleByAll_ = true;
+        ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByAll_, &decrypted).isOk());
+    }
+
+    status = c->startRetrieveEntryValue("ns", "Accessible by None", 1, {});
+    if (status.isOk()) {
+        canGetAccessibleByNone_ = true;
+        ASSERT_TRUE(c->retrieveEntryValue(encContentAccessibleByNone_, &decrypted).isOk());
+    }
+
+    vector<uint8_t> mac;
+    vector<uint8_t> deviceNameSpaces;
+    ASSERT_TRUE(c->finishRetrieval(&mac, &deviceNameSpaces).isOk());
+}
+
+TEST_P(ReaderAuthTests, presentingChain_Reader) {
+    provisionData();
+    retrieveData(readerPrivateKey_, {cert_reader_SelfSigned_}, true /* expectSuccess */,
+                 false /* leaveOutAccessibleToAllFromRequestMessage */);
+    EXPECT_FALSE(canGetAccessibleByA_);
+    EXPECT_FALSE(canGetAccessibleByAorB_);
+    EXPECT_FALSE(canGetAccessibleByB_);
+    EXPECT_FALSE(canGetAccessibleByC_);
+    EXPECT_TRUE(canGetAccessibleByAll_);
+    EXPECT_FALSE(canGetAccessibleByNone_);
+}
+
+TEST_P(ReaderAuthTests, presentingChain_Reader_A) {
+    provisionData();
+    retrieveData(readerPrivateKey_, {cert_reader_SignedBy_A_, cert_A_SelfSigned_},
+                 true /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
+    EXPECT_TRUE(canGetAccessibleByA_);
+    EXPECT_TRUE(canGetAccessibleByAorB_);
+    EXPECT_FALSE(canGetAccessibleByB_);
+    EXPECT_FALSE(canGetAccessibleByC_);
+    EXPECT_TRUE(canGetAccessibleByAll_);
+    EXPECT_FALSE(canGetAccessibleByNone_);
+}
+
+TEST_P(ReaderAuthTests, presentingChain_Reader_B) {
+    provisionData();
+    retrieveData(readerPrivateKey_, {cert_reader_SignedBy_B_, cert_B_SelfSigned_},
+                 true /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
+    EXPECT_FALSE(canGetAccessibleByA_);
+    EXPECT_TRUE(canGetAccessibleByAorB_);
+    EXPECT_TRUE(canGetAccessibleByB_);
+    EXPECT_FALSE(canGetAccessibleByC_);
+    EXPECT_TRUE(canGetAccessibleByAll_);
+    EXPECT_FALSE(canGetAccessibleByNone_);
+}
+
+// This test proves that for the purpose of determining inclusion of an ACP certificate
+// in a presented reader chain, certificate equality is done by comparing public keys,
+// not bitwise comparison of the certificates.
+//
+// Specifically for this test, the ACP is configured with cert_B_SelfSigned_ and the
+// reader is presenting cert_B_SignedBy_C_. Both certificates have the same public
+// key - intermediateBPublicKey_ - but they are signed by different keys.
+//
+TEST_P(ReaderAuthTests, presentingChain_Reader_B_C) {
+    provisionData();
+    retrieveData(readerPrivateKey_,
+                 {cert_reader_SignedBy_B_, cert_B_SignedBy_C_, cert_C_SelfSigned_},
+                 true /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
+    EXPECT_FALSE(canGetAccessibleByA_);
+    EXPECT_TRUE(canGetAccessibleByAorB_);
+    EXPECT_TRUE(canGetAccessibleByB_);
+    EXPECT_TRUE(canGetAccessibleByC_);
+    EXPECT_TRUE(canGetAccessibleByAll_);
+    EXPECT_FALSE(canGetAccessibleByNone_);
+}
+
+// This test presents a reader chain where the chain is invalid because
+// the 2nd certificate in the chain isn't signed by the 3rd one.
+//
+TEST_P(ReaderAuthTests, presentingInvalidChain) {
+    provisionData();
+    retrieveData(readerPrivateKey_,
+                 {cert_reader_SignedBy_B_, cert_B_SelfSigned_, cert_C_SelfSigned_},
+                 false /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
+}
+
+// This tests presents a valid reader chain but where requestMessage isn't
+// signed by the private key corresponding to the public key in the top-level
+// certificate.
+//
+TEST_P(ReaderAuthTests, presentingMessageSignedNotByTopLevel) {
+    provisionData();
+    retrieveData(intermediateBPrivateKey_,
+                 {cert_reader_SignedBy_B_, cert_B_SignedBy_C_, cert_C_SelfSigned_},
+                 false /* expectSuccess */, false /* leaveOutAccessibleToAllFromRequestMessage */);
+}
+
+// This test leaves out "Accessible by All" data element from the signed request
+// message (the CBOR from the reader) while still including this data element at
+// the API level. The call on the API level for said element will fail with
+// STATUS_NOT_IN_REQUEST_MESSAGE but this doesn't prevent the other elements
+// from being returned (if authorized, of course).
+//
+// This test verifies that.
+//
+TEST_P(ReaderAuthTests, limitedMessage) {
+    provisionData();
+    retrieveData(readerPrivateKey_, {cert_reader_SelfSigned_}, true /* expectSuccess */,
+                 true /* leaveOutAccessibleToAllFromRequestMessage */);
+    EXPECT_FALSE(canGetAccessibleByA_);
+    EXPECT_FALSE(canGetAccessibleByAorB_);
+    EXPECT_FALSE(canGetAccessibleByB_);
+    EXPECT_FALSE(canGetAccessibleByC_);
+    EXPECT_FALSE(canGetAccessibleByAll_);
+    EXPECT_FALSE(canGetAccessibleByNone_);
+}
+
+TEST_P(ReaderAuthTests, ephemeralKeyNotInSessionTranscript) {
+    provisionData();
+
+    sp<IIdentityCredential> c;
+    ASSERT_TRUE(credentialStore_
+                        ->getCredential(
+                                CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256,
+                                credentialData_, &c)
+                        .isOk());
+
+    optional<vector<uint8_t>> readerEKeyPair = support::createEcKeyPair();
+    optional<vector<uint8_t>> readerEPublicKey =
+            support::ecKeyPairGetPublicKey(readerEKeyPair.value());
+    ASSERT_TRUE(c->setReaderEphemeralPublicKey(readerEPublicKey.value()).isOk());
+
+    vector<uint8_t> eKeyPair;
+    ASSERT_TRUE(c->createEphemeralKeyPair(&eKeyPair).isOk());
+    optional<vector<uint8_t>> ePublicKey = support::ecKeyPairGetPublicKey(eKeyPair);
+
+    // Calculate requestData field and sign it with the reader key.
+    auto [getXYSuccess, ephX, ephY] = support::ecPublicKeyGetXandY(ePublicKey.value());
+    ASSERT_TRUE(getXYSuccess);
+    // Instead of include the X and Y coordinates (|ephX| and |ephY|), add NUL bytes instead.
+    vector<uint8_t> nulls(32);
+    cppbor::Map deviceEngagement = cppbor::Map().add("ephX", nulls).add("ephY", nulls);
+    vector<uint8_t> deviceEngagementBytes = deviceEngagement.encode();
+    vector<uint8_t> eReaderPubBytes = cppbor::Tstr("ignored").encode();
+    cppbor::Array sessionTranscript = cppbor::Array()
+                                              .add(cppbor::Semantic(24, deviceEngagementBytes))
+                                              .add(cppbor::Semantic(24, eReaderPubBytes));
+    vector<uint8_t> sessionTranscriptBytes = sessionTranscript.encode();
+
+    vector<uint8_t> itemsRequestBytes;
+    itemsRequestBytes =
+            cppbor::Map("nameSpaces",
+                        cppbor::Map().add("ns", cppbor::Map()
+                                                        .add("Accessible by A", false)
+                                                        .add("Accessible by A or B", false)
+                                                        .add("Accessible by B", false)
+                                                        .add("Accessible by C", false)
+                                                        .add("Accessible by None", false)))
+                    .encode();
+    vector<uint8_t> dataToSign = cppbor::Array()
+                                         .add("ReaderAuthentication")
+                                         .add(sessionTranscript.clone())
+                                         .add(cppbor::Semantic(24, itemsRequestBytes))
+                                         .encode();
+
+    vector<vector<uint8_t>> readerCertChain = {cert_reader_SelfSigned_};
+    optional<vector<uint8_t>> readerSignature =
+            support::coseSignEcDsa(readerPrivateKey_,  // private key for reader
+                                   {},                 // content
+                                   dataToSign,         // detached content
+                                   support::certificateChainJoin(readerCertChain));
+    ASSERT_TRUE(readerSignature);
+
+    // Generate the key that will be used to sign AuthenticatedData.
+    vector<uint8_t> signingKeyBlob;
+    Certificate signingKeyCertificate;
+    ASSERT_TRUE(c->generateSigningKeyPair(&signingKeyBlob, &signingKeyCertificate).isOk());
+
+    RequestNamespace rns;
+    rns.namespaceName = "ns";
+    rns.items.push_back(buildRequestDataItem("Accessible by A", 1, {0}));
+    rns.items.push_back(buildRequestDataItem("Accessible by A or B", 1, {0, 1}));
+    rns.items.push_back(buildRequestDataItem("Accessible by B", 1, {1}));
+    rns.items.push_back(buildRequestDataItem("Accessible by C", 1, {2}));
+    rns.items.push_back(buildRequestDataItem("Accessible by All", 1, {3}));
+    rns.items.push_back(buildRequestDataItem("Accessible by None", 1, {}));
+    // OK to fail, not available in v1 HAL
+    c->setRequestedNamespaces({rns}).isOk();
+
+    // 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::TRUSTED_ENVIRONMENT;
+    verificationToken.mac.clear();
+    // OK to fail, not available in v1 HAL
+    c->setVerificationToken(verificationToken);
+
+    // Finally check that STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND is returned.
+    // This proves that the TA checked for X and Y coordinatets and didn't find
+    // them.
+    Status status = c->startRetrieval(
+            {sacp0_, sacp1_, sacp2_, sacp3_}, authToken, itemsRequestBytes, signingKeyBlob,
+            sessionTranscriptBytes, readerSignature.value(), {6 /* numDataElementsPerNamespace */});
+    ASSERT_FALSE(status.isOk());
+    ASSERT_EQ(binder::Status::EX_SERVICE_SPECIFIC, status.exceptionCode());
+    ASSERT_EQ(IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
+              status.serviceSpecificErrorCode());
+}
+
+INSTANTIATE_TEST_SUITE_P(
+        Identity, ReaderAuthTests,
+        testing::ValuesIn(android::getAidlHalInstanceNames(IIdentityCredentialStore::descriptor)),
+        android::PrintInstanceNameToString);
+
+}  // namespace android::hardware::identity
