diff --git a/identity/aidl/default/common/IdentityCredential.cpp b/identity/aidl/default/common/IdentityCredential.cpp
new file mode 100644
index 0000000..270fcfa
--- /dev/null
+++ b/identity/aidl/default/common/IdentityCredential.cpp
@@ -0,0 +1,836 @@
+/*
+ * Copyright 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 "IdentityCredential"
+
+#include "IdentityCredential.h"
+#include "IdentityCredentialStore.h"
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <string.h>
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+#include "FakeSecureHardwareProxy.h"
+
+namespace aidl::android::hardware::identity {
+
+using ::aidl::android::hardware::keymaster::Timestamp;
+using ::android::base::StringPrintf;
+using ::std::optional;
+
+using namespace ::android::hardware::identity;
+
+int IdentityCredential::initialize() {
+    if (credentialData_.size() == 0) {
+        LOG(ERROR) << "CredentialData is empty";
+        return IIdentityCredentialStore::STATUS_INVALID_DATA;
+    }
+    auto [item, _, message] = cppbor::parse(credentialData_);
+    if (item == nullptr) {
+        LOG(ERROR) << "CredentialData is not valid CBOR: " << message;
+        return IIdentityCredentialStore::STATUS_INVALID_DATA;
+    }
+
+    const cppbor::Array* arrayItem = item->asArray();
+    if (arrayItem == nullptr || arrayItem->size() != 3) {
+        LOG(ERROR) << "CredentialData is not an array with three elements";
+        return IIdentityCredentialStore::STATUS_INVALID_DATA;
+    }
+
+    const cppbor::Tstr* docTypeItem = (*arrayItem)[0]->asTstr();
+    const cppbor::Bool* testCredentialItem =
+            ((*arrayItem)[1]->asSimple() != nullptr ? ((*arrayItem)[1]->asSimple()->asBool())
+                                                    : nullptr);
+    const cppbor::Bstr* encryptedCredentialKeysItem = (*arrayItem)[2]->asBstr();
+    if (docTypeItem == nullptr || testCredentialItem == nullptr ||
+        encryptedCredentialKeysItem == nullptr) {
+        LOG(ERROR) << "CredentialData unexpected item types";
+        return IIdentityCredentialStore::STATUS_INVALID_DATA;
+    }
+
+    docType_ = docTypeItem->value();
+    testCredential_ = testCredentialItem->value();
+
+    const vector<uint8_t>& encryptedCredentialKeys = encryptedCredentialKeysItem->value();
+
+    if (encryptedCredentialKeys.size() != 80) {
+        LOG(ERROR) << "Unexpected size for encrypted CredentialKeys";
+        return IIdentityCredentialStore::STATUS_INVALID_DATA;
+    }
+
+    if (!hwProxy_->initialize(testCredential_, docType_, encryptedCredentialKeys)) {
+        LOG(ERROR) << "hwProxy->initialize failed";
+        return false;
+    }
+
+    return IIdentityCredentialStore::STATUS_OK;
+}
+
+ndk::ScopedAStatus IdentityCredential::deleteCredential(
+        vector<uint8_t>* outProofOfDeletionSignature) {
+    cppbor::Array array = {"ProofOfDeletion", docType_, testCredential_};
+    vector<uint8_t> proofOfDeletionCbor = array.encode();
+    vector<uint8_t> podDigest = support::sha256(proofOfDeletionCbor);
+
+    optional<vector<uint8_t>> signatureOfToBeSigned =
+            hwProxy_->deleteCredential(docType_, proofOfDeletionCbor.size());
+    if (!signatureOfToBeSigned) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error signing ProofOfDeletion"));
+    }
+
+    optional<vector<uint8_t>> signature =
+            support::coseSignEcDsaWithSignature(signatureOfToBeSigned.value(),
+                                                proofOfDeletionCbor,  // data
+                                                {});                  // certificateChain
+    if (!signature) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error signing data"));
+    }
+
+    *outProofOfDeletionSignature = signature.value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus IdentityCredential::createEphemeralKeyPair(vector<uint8_t>* outKeyPair) {
+    optional<vector<uint8_t>> ephemeralPriv = hwProxy_->createEphemeralKeyPair();
+    if (!ephemeralPriv) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error creating ephemeral key"));
+    }
+    optional<vector<uint8_t>> keyPair = support::ecPrivateKeyToKeyPair(ephemeralPriv.value());
+    if (!keyPair) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error creating ephemeral key-pair"));
+    }
+
+    // Stash public key of this key-pair for later check in startRetrieval().
+    optional<vector<uint8_t>> publicKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    if (!publicKey) {
+        LOG(ERROR) << "Error getting public part of ephemeral key pair";
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Error getting public part of ephemeral key pair"));
+    }
+    ephemeralPublicKey_ = publicKey.value();
+
+    *outKeyPair = keyPair.value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus IdentityCredential::setReaderEphemeralPublicKey(
+        const vector<uint8_t>& publicKey) {
+    readerPublicKey_ = publicKey;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus IdentityCredential::createAuthChallenge(int64_t* outChallenge) {
+    optional<uint64_t> challenge = hwProxy_->createAuthChallenge();
+    if (!challenge) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error generating challenge"));
+    }
+    *outChallenge = challenge.value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus IdentityCredential::setRequestedNamespaces(
+        const vector<RequestNamespace>& requestNamespaces) {
+    requestNamespaces_ = requestNamespaces;
+    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,
+        const vector<uint8_t>& signingKeyBlob, const vector<uint8_t>& sessionTranscript,
+        const vector<uint8_t>& readerSignature, const vector<int32_t>& requestCounts) {
+    std::unique_ptr<cppbor::Item> sessionTranscriptItem;
+    if (sessionTranscript.size() > 0) {
+        auto [item, _, message] = cppbor::parse(sessionTranscript);
+        if (item == nullptr) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "SessionTranscript contains invalid CBOR"));
+        }
+        sessionTranscriptItem = std::move(item);
+    }
+    if (numStartRetrievalCalls_ > 0) {
+        if (sessionTranscript_ != sessionTranscript) {
+            LOG(ERROR) << "Session Transcript changed";
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_SESSION_TRANSCRIPT_MISMATCH,
+                    "Passed-in SessionTranscript doesn't match previously used SessionTranscript"));
+        }
+    }
+    sessionTranscript_ = sessionTranscript;
+
+    // This resets various state in the TA...
+    if (!hwProxy_->startRetrieveEntries()) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error starting retrieving entries"));
+    }
+
+    optional<vector<uint8_t>> signatureOfToBeSigned;
+    if (readerSignature.size() > 0) {
+        signatureOfToBeSigned = support::coseSignGetSignature(readerSignature);
+        if (!signatureOfToBeSigned) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_READER_SIGNATURE_CHECK_FAILED,
+                    "Error extracting signatureOfToBeSigned from COSE_Sign1"));
+        }
+    }
+
+    // Feed the auth token to secure hardware.
+    if (!hwProxy_->setAuthToken(authToken.challenge, authToken.userId, authToken.authenticatorId,
+                                int(authToken.authenticatorType), authToken.timestamp.milliSeconds,
+                                authToken.mac, verificationToken_.challenge,
+                                verificationToken_.timestamp.milliSeconds,
+                                int(verificationToken_.securityLevel), verificationToken_.mac)) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA, "Invalid Auth Token"));
+    }
+
+    // We'll be feeding ACPs interleaved with certificates from the reader
+    // certificate chain...
+    vector<SecureAccessControlProfile> remainingAcps = accessControlProfiles;
+
+    // ... and we'll use those ACPs to build up a 32-bit mask indicating which
+    // of the possible 32 ACPs grants access.
+    uint32_t accessControlProfileMask = 0;
+
+    // If there is a signature, validate that it was made with the top-most key in the
+    // certificate chain embedded in the COSE_Sign1 structure.
+    optional<vector<uint8_t>> readerCertificateChain;
+    if (readerSignature.size() > 0) {
+        readerCertificateChain = support::coseSignGetX5Chain(readerSignature);
+        if (!readerCertificateChain) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_READER_SIGNATURE_CHECK_FAILED,
+                    "Unable to get reader certificate chain from COSE_Sign1"));
+        }
+
+        // First, feed all the reader certificates to the secure hardware. We start
+        // at the end..
+        optional<vector<vector<uint8_t>>> splitCerts =
+                support::certificateChainSplit(readerCertificateChain.value());
+        if (!splitCerts || splitCerts.value().size() == 0) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_READER_SIGNATURE_CHECK_FAILED,
+                    "Error splitting certificate chain from COSE_Sign1"));
+        }
+        for (ssize_t n = splitCerts.value().size() - 1; n >= 0; --n) {
+            const vector<uint8_t>& x509Cert = splitCerts.value()[n];
+            if (!hwProxy_->pushReaderCert(x509Cert)) {
+                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IIdentityCredentialStore::STATUS_READER_SIGNATURE_CHECK_FAILED,
+                        StringPrintf("Error validating reader certificate %zd", n).c_str()));
+            }
+
+            // If we have ACPs for that particular certificate, send them to the
+            // TA right now...
+            //
+            // Remember in this case certificate equality is done by comparing public keys,
+            // not bitwise comparison of the certificates.
+            //
+            optional<vector<uint8_t>> x509CertPubKey =
+                    support::certificateChainGetTopMostKey(x509Cert);
+            if (!x509CertPubKey) {
+                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IIdentityCredentialStore::STATUS_FAILED,
+                        StringPrintf("Error getting public key from reader certificate %zd", n)
+                                .c_str()));
+            }
+            vector<SecureAccessControlProfile>::iterator it = remainingAcps.begin();
+            while (it != remainingAcps.end()) {
+                const SecureAccessControlProfile& profile = *it;
+                if (profile.readerCertificate.encodedCertificate.size() == 0) {
+                    ++it;
+                    continue;
+                }
+                optional<vector<uint8_t>> profilePubKey = support::certificateChainGetTopMostKey(
+                        profile.readerCertificate.encodedCertificate);
+                if (!profilePubKey) {
+                    return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                            IIdentityCredentialStore::STATUS_FAILED,
+                            "Error getting public key from profile"));
+                }
+                if (profilePubKey.value() == x509CertPubKey.value()) {
+                    optional<bool> res = hwProxy_->validateAccessControlProfile(
+                            profile.id, profile.readerCertificate.encodedCertificate,
+                            profile.userAuthenticationRequired, profile.timeoutMillis,
+                            profile.secureUserId, profile.mac);
+                    if (!res) {
+                        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                                "Error validating access control profile"));
+                    }
+                    if (res.value()) {
+                        accessControlProfileMask |= (1 << profile.id);
+                    }
+                    it = remainingAcps.erase(it);
+                } else {
+                    ++it;
+                }
+            }
+        }
+
+        // ... then pass the request message and have the TA check it's signed by the
+        // key in last certificate we pushed.
+        if (sessionTranscript.size() > 0 && itemsRequest.size() > 0 && readerSignature.size() > 0) {
+            optional<vector<uint8_t>> tbsSignature = support::coseSignGetSignature(readerSignature);
+            if (!tbsSignature) {
+                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IIdentityCredentialStore::STATUS_READER_SIGNATURE_CHECK_FAILED,
+                        "Error extracting toBeSigned from COSE_Sign1"));
+            }
+            optional<int> coseSignAlg = support::coseSignGetAlg(readerSignature);
+            if (!coseSignAlg) {
+                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IIdentityCredentialStore::STATUS_READER_SIGNATURE_CHECK_FAILED,
+                        "Error extracting signature algorithm from COSE_Sign1"));
+            }
+            if (!hwProxy_->validateRequestMessage(sessionTranscript, itemsRequest,
+                                                  coseSignAlg.value(), tbsSignature.value())) {
+                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IIdentityCredentialStore::STATUS_READER_SIGNATURE_CHECK_FAILED,
+                        "readerMessage is not signed by top-level certificate"));
+            }
+        }
+    }
+
+    // Feed remaining access control profiles...
+    for (const SecureAccessControlProfile& profile : remainingAcps) {
+        optional<bool> res = hwProxy_->validateAccessControlProfile(
+                profile.id, profile.readerCertificate.encodedCertificate,
+                profile.userAuthenticationRequired, profile.timeoutMillis, profile.secureUserId,
+                profile.mac);
+        if (!res) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Error validating access control profile"));
+        }
+        if (res.value()) {
+            accessControlProfileMask |= (1 << profile.id);
+        }
+    }
+
+    // TODO: move this check to the TA
+#if 1
+    // To prevent replay-attacks, we check that the public part of the ephemeral
+    // key we previously created, is present in the DeviceEngagement part of
+    // SessionTranscript as a COSE_Key, in uncompressed form.
+    //
+    // We do this by just searching for the X and Y coordinates.
+    if (sessionTranscript.size() > 0) {
+        auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_);
+        if (!getXYSuccess) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
+                    "Error extracting X and Y from ePub"));
+        }
+        if (sessionTranscript.size() > 0 &&
+            !(memmem(sessionTranscript.data(), sessionTranscript.size(), ePubX.data(),
+                     ePubX.size()) != nullptr &&
+              memmem(sessionTranscript.data(), sessionTranscript.size(), ePubY.data(),
+                     ePubY.size()) != nullptr)) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
+                    "Did not find ephemeral public key's X and Y coordinates in "
+                    "SessionTranscript (make sure leading zeroes are not used)"));
+        }
+    }
+#endif
+
+    // itemsRequest: If non-empty, contains request data that may be signed by the
+    // reader.  The content can be defined in the way appropriate for the
+    // credential, but there are three requirements that must be met to work with
+    // this HAL:
+    if (itemsRequest.size() > 0) {
+        // 1. The content must be a CBOR-encoded structure.
+        auto [item, _, message] = cppbor::parse(itemsRequest);
+        if (item == nullptr) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_ITEMS_REQUEST_MESSAGE,
+                    "Error decoding CBOR in itemsRequest"));
+        }
+
+        // 2. The CBOR structure must be a map.
+        const cppbor::Map* map = item->asMap();
+        if (map == nullptr) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_ITEMS_REQUEST_MESSAGE,
+                    "itemsRequest is not a CBOR map"));
+        }
+
+        // 3. The map must contain a key "nameSpaces" whose value contains a map, as described in
+        //    the example below.
+        //
+        //   NameSpaces = {
+        //     + NameSpace => DataElements ; Requested data elements for each NameSpace
+        //   }
+        //
+        //   NameSpace = tstr
+        //
+        //   DataElements = {
+        //     + DataElement => IntentToRetain
+        //   }
+        //
+        //   DataElement = tstr
+        //   IntentToRetain = bool
+        //
+        // Here's an example of an |itemsRequest| CBOR value satisfying above requirements 1.
+        // through 3.:
+        //
+        //    {
+        //        'docType' : 'org.iso.18013-5.2019',
+        //        'nameSpaces' : {
+        //            'org.iso.18013-5.2019' : {
+        //                'Last name' : false,
+        //                'Birth date' : false,
+        //                'First name' : false,
+        //                'Home address' : true
+        //            },
+        //            'org.aamva.iso.18013-5.2019' : {
+        //                'Real Id' : false
+        //            }
+        //        }
+        //    }
+        //
+        const cppbor::Map* nsMap = nullptr;
+        for (size_t n = 0; n < map->size(); n++) {
+            const auto& [keyItem, valueItem] = (*map)[n];
+            if (keyItem->type() == cppbor::TSTR && keyItem->asTstr()->value() == "nameSpaces" &&
+                valueItem->type() == cppbor::MAP) {
+                nsMap = valueItem->asMap();
+                break;
+            }
+        }
+        if (nsMap == nullptr) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_ITEMS_REQUEST_MESSAGE,
+                    "No nameSpaces map in top-most map"));
+        }
+
+        for (size_t n = 0; n < nsMap->size(); n++) {
+            auto [nsKeyItem, nsValueItem] = (*nsMap)[n];
+            const cppbor::Tstr* nsKey = nsKeyItem->asTstr();
+            const cppbor::Map* nsInnerMap = nsValueItem->asMap();
+            if (nsKey == nullptr || nsInnerMap == nullptr) {
+                return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                        IIdentityCredentialStore::STATUS_INVALID_ITEMS_REQUEST_MESSAGE,
+                        "Type mismatch in nameSpaces map"));
+            }
+            string requestedNamespace = nsKey->value();
+            set<string> requestedKeys;
+            for (size_t m = 0; m < nsInnerMap->size(); m++) {
+                const auto& [innerMapKeyItem, innerMapValueItem] = (*nsInnerMap)[m];
+                const cppbor::Tstr* nameItem = innerMapKeyItem->asTstr();
+                const cppbor::Simple* simple = innerMapValueItem->asSimple();
+                const cppbor::Bool* intentToRetainItem =
+                        (simple != nullptr) ? simple->asBool() : nullptr;
+                if (nameItem == nullptr || intentToRetainItem == nullptr) {
+                    return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                            IIdentityCredentialStore::STATUS_INVALID_ITEMS_REQUEST_MESSAGE,
+                            "Type mismatch in value in nameSpaces map"));
+                }
+                requestedKeys.insert(nameItem->value());
+            }
+            requestedNameSpacesAndNames_[requestedNamespace] = requestedKeys;
+        }
+    }
+
+    deviceNameSpacesMap_ = cppbor::Map();
+    currentNameSpaceDeviceNameSpacesMap_ = cppbor::Map();
+
+    requestCountsRemaining_ = requestCounts;
+    currentNameSpace_ = "";
+
+    itemsRequest_ = itemsRequest;
+    signingKeyBlob_ = signingKeyBlob;
+
+    // calculate the size of DeviceNameSpaces. We need to know it ahead of time.
+    calcDeviceNameSpacesSize(accessControlProfileMask);
+
+    // Count the number of non-empty namespaces
+    size_t numNamespacesWithValues = 0;
+    for (size_t n = 0; n < expectedNumEntriesPerNamespace_.size(); n++) {
+        if (expectedNumEntriesPerNamespace_[n] > 0) {
+            numNamespacesWithValues += 1;
+        }
+    }
+
+    // Finally, pass info so the HMAC key can be derived and the TA can start
+    // creating the DeviceNameSpaces CBOR...
+    if (sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0 && signingKeyBlob.size() > 0) {
+        // We expect the reader ephemeral public key to be same size and curve
+        // as the ephemeral key we generated (e.g. P-256 key), otherwise ECDH
+        // won't work. So its length should be 65 bytes and it should be
+        // starting with 0x04.
+        if (readerPublicKey_.size() != 65 || readerPublicKey_[0] != 0x04) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_FAILED,
+                    "Reader public key is not in expected format"));
+        }
+        vector<uint8_t> pubKeyP256(readerPublicKey_.begin() + 1, readerPublicKey_.end());
+        if (!hwProxy_->calcMacKey(sessionTranscript_, pubKeyP256, signingKeyBlob, docType_,
+                                  numNamespacesWithValues, expectedDeviceNameSpacesSize_)) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_FAILED, "Error starting retrieving entries"));
+        }
+    }
+
+    numStartRetrievalCalls_ += 1;
+    return ndk::ScopedAStatus::ok();
+}
+
+size_t cborNumBytesForLength(size_t length) {
+    if (length < 24) {
+        return 0;
+    } else if (length <= 0xff) {
+        return 1;
+    } else if (length <= 0xffff) {
+        return 2;
+    } else if (length <= 0xffffffff) {
+        return 4;
+    }
+    return 8;
+}
+
+size_t cborNumBytesForTstr(const string& value) {
+    return 1 + cborNumBytesForLength(value.size()) + value.size();
+}
+
+void IdentityCredential::calcDeviceNameSpacesSize(uint32_t accessControlProfileMask) {
+    /*
+     * This is how DeviceNameSpaces is defined:
+     *
+     *        DeviceNameSpaces = {
+     *            * NameSpace => DeviceSignedItems
+     *        }
+     *        DeviceSignedItems = {
+     *            + DataItemName => DataItemValue
+     *        }
+     *
+     *        Namespace = tstr
+     *        DataItemName = tstr
+     *        DataItemValue = any
+     *
+     * This function will calculate its length using knowledge of how CBOR is
+     * encoded.
+     */
+    size_t ret = 0;
+    vector<unsigned int> numEntriesPerNamespace;
+    for (const RequestNamespace& rns : requestNamespaces_) {
+        vector<RequestDataItem> itemsToInclude;
+
+        for (const RequestDataItem& rdi : rns.items) {
+            // If we have a CBOR request message, skip if item isn't in it
+            if (itemsRequest_.size() > 0) {
+                const auto& it = requestedNameSpacesAndNames_.find(rns.namespaceName);
+                if (it == requestedNameSpacesAndNames_.end()) {
+                    continue;
+                }
+                const set<string>& dataItemNames = it->second;
+                if (dataItemNames.find(rdi.name) == dataItemNames.end()) {
+                    continue;
+                }
+            }
+
+            // Access is granted if at least one of the profiles grants access.
+            //
+            // If an item is configured without any profiles, access is denied.
+            //
+            bool authorized = false;
+            for (auto id : rdi.accessControlProfileIds) {
+                if (accessControlProfileMask & (1 << id)) {
+                    authorized = true;
+                    break;
+                }
+            }
+            if (!authorized) {
+                continue;
+            }
+
+            itemsToInclude.push_back(rdi);
+        }
+
+        numEntriesPerNamespace.push_back(itemsToInclude.size());
+
+        // If no entries are to be in the namespace, we don't include it in
+        // the CBOR...
+        if (itemsToInclude.size() == 0) {
+            continue;
+        }
+
+        // Key: NameSpace
+        ret += cborNumBytesForTstr(rns.namespaceName);
+
+        // Value: Open the DeviceSignedItems map
+        ret += 1 + cborNumBytesForLength(itemsToInclude.size());
+
+        for (const RequestDataItem& item : itemsToInclude) {
+            // Key: DataItemName
+            ret += cborNumBytesForTstr(item.name);
+
+            // Value: DataItemValue - entryData.size is the length of serialized CBOR so we use
+            // that.
+            ret += item.size;
+        }
+    }
+
+    // Now that we know the number of namespaces with values, we know how many
+    // bytes the DeviceNamespaces map in the beginning is going to take up.
+    ret += 1 + cborNumBytesForLength(numEntriesPerNamespace.size());
+
+    expectedDeviceNameSpacesSize_ = ret;
+    expectedNumEntriesPerNamespace_ = numEntriesPerNamespace;
+}
+
+ndk::ScopedAStatus IdentityCredential::startRetrieveEntryValue(
+        const string& nameSpace, const string& name, int32_t entrySize,
+        const vector<int32_t>& accessControlProfileIds) {
+    if (name.empty()) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA, "Name cannot be empty"));
+    }
+    if (nameSpace.empty()) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA, "Name space cannot be empty"));
+    }
+
+    if (requestCountsRemaining_.size() == 0) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                "No more name spaces left to go through"));
+    }
+
+    bool newNamespace;
+    if (currentNameSpace_ == "") {
+        // First call.
+        currentNameSpace_ = nameSpace;
+        newNamespace = true;
+    }
+
+    if (nameSpace == currentNameSpace_) {
+        // Same namespace.
+        if (requestCountsRemaining_[0] == 0) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "No more entries to be retrieved in current name space"));
+        }
+        requestCountsRemaining_[0] -= 1;
+    } else {
+        // New namespace.
+        if (requestCountsRemaining_[0] != 0) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Moved to new name space but one or more entries need to be retrieved "
+                    "in current name space"));
+        }
+        if (currentNameSpaceDeviceNameSpacesMap_.size() > 0) {
+            deviceNameSpacesMap_.add(currentNameSpace_,
+                                     std::move(currentNameSpaceDeviceNameSpacesMap_));
+        }
+        currentNameSpaceDeviceNameSpacesMap_ = cppbor::Map();
+
+        requestCountsRemaining_.erase(requestCountsRemaining_.begin());
+        currentNameSpace_ = nameSpace;
+        newNamespace = true;
+    }
+
+    // It's permissible to have an empty itemsRequest... but if non-empty you can
+    // only request what was specified in said itemsRequest. Enforce that.
+    if (itemsRequest_.size() > 0) {
+        const auto& it = requestedNameSpacesAndNames_.find(nameSpace);
+        if (it == requestedNameSpacesAndNames_.end()) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_NOT_IN_REQUEST_MESSAGE,
+                    "Name space was not requested in startRetrieval"));
+        }
+        const set<string>& dataItemNames = it->second;
+        if (dataItemNames.find(name) == dataItemNames.end()) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_NOT_IN_REQUEST_MESSAGE,
+                    "Data item name in name space was not requested in startRetrieval"));
+        }
+    }
+
+    unsigned int newNamespaceNumEntries = 0;
+    if (newNamespace) {
+        if (expectedNumEntriesPerNamespace_.size() == 0) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "No more populated name spaces left to go through"));
+        }
+        newNamespaceNumEntries = expectedNumEntriesPerNamespace_[0];
+        expectedNumEntriesPerNamespace_.erase(expectedNumEntriesPerNamespace_.begin());
+    }
+
+    // Access control is enforced in the secure hardware.
+    //
+    // ... except for STATUS_NOT_IN_REQUEST_MESSAGE, that's handled above (TODO:
+    // consolidate).
+    //
+    AccessCheckResult res = hwProxy_->startRetrieveEntryValue(
+            nameSpace, name, newNamespaceNumEntries, entrySize, accessControlProfileIds);
+    switch (res) {
+        case AccessCheckResult::kOk:
+            /* Do nothing. */
+            break;
+        case AccessCheckResult::kFailed:
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_FAILED,
+                    "Access control check failed (failed)"));
+            break;
+        case AccessCheckResult::kNoAccessControlProfiles:
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_NO_ACCESS_CONTROL_PROFILES,
+                    "Access control check failed (no access control profiles)"));
+            break;
+        case AccessCheckResult::kUserAuthenticationFailed:
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_USER_AUTHENTICATION_FAILED,
+                    "Access control check failed (user auth)"));
+            break;
+        case AccessCheckResult::kReaderAuthenticationFailed:
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_READER_AUTHENTICATION_FAILED,
+                    "Access control check failed (reader auth)"));
+            break;
+    }
+
+    currentName_ = name;
+    currentAccessControlProfileIds_ = accessControlProfileIds;
+    entryRemainingBytes_ = entrySize;
+    entryValue_.resize(0);
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus IdentityCredential::retrieveEntryValue(const vector<uint8_t>& encryptedContent,
+                                                          vector<uint8_t>* outContent) {
+    optional<vector<uint8_t>> content = hwProxy_->retrieveEntryValue(
+            encryptedContent, currentNameSpace_, currentName_, currentAccessControlProfileIds_);
+    if (!content) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA, "Error decrypting data"));
+    }
+
+    size_t chunkSize = content.value().size();
+
+    if (chunkSize > entryRemainingBytes_) {
+        LOG(ERROR) << "Retrieved chunk of size " << chunkSize
+                   << " is bigger than remaining space of size " << entryRemainingBytes_;
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                "Retrieved chunk is bigger than remaining space"));
+    }
+
+    entryRemainingBytes_ -= chunkSize;
+    if (entryRemainingBytes_ > 0) {
+        if (chunkSize != IdentityCredentialStore::kGcmChunkSize) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Retrieved non-final chunk of size which isn't kGcmChunkSize"));
+        }
+    }
+
+    entryValue_.insert(entryValue_.end(), content.value().begin(), content.value().end());
+
+    if (entryRemainingBytes_ == 0) {
+        auto [entryValueItem, _, message] = cppbor::parse(entryValue_);
+        if (entryValueItem == nullptr) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Retrieved data which is invalid CBOR"));
+        }
+        currentNameSpaceDeviceNameSpacesMap_.add(currentName_, std::move(entryValueItem));
+    }
+
+    *outContent = content.value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus IdentityCredential::finishRetrieval(vector<uint8_t>* outMac,
+                                                       vector<uint8_t>* outDeviceNameSpaces) {
+    if (currentNameSpaceDeviceNameSpacesMap_.size() > 0) {
+        deviceNameSpacesMap_.add(currentNameSpace_,
+                                 std::move(currentNameSpaceDeviceNameSpacesMap_));
+    }
+    vector<uint8_t> encodedDeviceNameSpaces = deviceNameSpacesMap_.encode();
+
+    if (encodedDeviceNameSpaces.size() != expectedDeviceNameSpacesSize_) {
+        LOG(ERROR) << "encodedDeviceNameSpaces is " << encodedDeviceNameSpaces.size() << " bytes, "
+                   << "was expecting " << expectedDeviceNameSpacesSize_;
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                StringPrintf(
+                        "Unexpected CBOR size %zd for encodedDeviceNameSpaces, was expecting %zd",
+                        encodedDeviceNameSpaces.size(), expectedDeviceNameSpacesSize_)
+                        .c_str()));
+    }
+
+    // If there's no signing key or no sessionTranscript or no reader ephemeral
+    // public key, we return the empty MAC.
+    optional<vector<uint8_t>> mac;
+    if (signingKeyBlob_.size() > 0 && sessionTranscript_.size() > 0 &&
+        readerPublicKey_.size() > 0) {
+        optional<vector<uint8_t>> digestToBeMaced = hwProxy_->finishRetrieval();
+        if (!digestToBeMaced || digestToBeMaced.value().size() != 32) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Error generating digestToBeMaced"));
+        }
+        // Now construct COSE_Mac0 from the returned MAC...
+        mac = support::coseMacWithDigest(digestToBeMaced.value(), {} /* data */);
+    }
+
+    *outMac = mac.value_or(vector<uint8_t>({}));
+    *outDeviceNameSpaces = encodedDeviceNameSpaces;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus IdentityCredential::generateSigningKeyPair(
+        vector<uint8_t>* outSigningKeyBlob, Certificate* outSigningKeyCertificate) {
+    time_t now = time(NULL);
+    optional<pair<vector<uint8_t>, vector<uint8_t>>> pair =
+            hwProxy_->generateSigningKeyPair(docType_, now);
+    if (!pair) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error creating signingKey"));
+    }
+
+    *outSigningKeyCertificate = Certificate();
+    outSigningKeyCertificate->encodedCertificate = pair->first;
+
+    *outSigningKeyBlob = pair->second;
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/IdentityCredential.h b/identity/aidl/default/common/IdentityCredential.h
new file mode 100644
index 0000000..2281821
--- /dev/null
+++ b/identity/aidl/default/common/IdentityCredential.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIAL_H
+#define ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIAL_H
+
+#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>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <cppbor/cppbor.h>
+
+#include "IdentityCredentialStore.h"
+#include "SecureHardwareProxy.h"
+
+namespace aidl::android::hardware::identity {
+
+using ::aidl::android::hardware::keymaster::HardwareAuthToken;
+using ::aidl::android::hardware::keymaster::VerificationToken;
+using ::android::sp;
+using ::android::hardware::identity::SecureHardwarePresentationProxy;
+using ::std::map;
+using ::std::set;
+using ::std::string;
+using ::std::vector;
+
+class IdentityCredential : public BnIdentityCredential {
+  public:
+    IdentityCredential(sp<SecureHardwarePresentationProxy> hwProxy,
+                       const vector<uint8_t>& credentialData)
+        : hwProxy_(hwProxy),
+          credentialData_(credentialData),
+          numStartRetrievalCalls_(0),
+          expectedDeviceNameSpacesSize_(0) {}
+
+    // Parses and decrypts credentialData_, return a status code from
+    // IIdentityCredentialStore. Must be called right after construction.
+    int initialize();
+
+    // Methods from IIdentityCredential follow.
+    ndk::ScopedAStatus deleteCredential(vector<uint8_t>* outProofOfDeletionSignature) override;
+    ndk::ScopedAStatus createEphemeralKeyPair(vector<uint8_t>* outKeyPair) override;
+    ndk::ScopedAStatus setReaderEphemeralPublicKey(const vector<uint8_t>& publicKey) override;
+    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,
+            const vector<uint8_t>& signingKeyBlob, const vector<uint8_t>& sessionTranscript,
+            const vector<uint8_t>& readerSignature, const vector<int32_t>& requestCounts) override;
+    ndk::ScopedAStatus startRetrieveEntryValue(
+            const string& nameSpace, const string& name, int32_t entrySize,
+            const vector<int32_t>& accessControlProfileIds) override;
+    ndk::ScopedAStatus retrieveEntryValue(const vector<uint8_t>& encryptedContent,
+                                          vector<uint8_t>* outContent) override;
+    ndk::ScopedAStatus finishRetrieval(vector<uint8_t>* outMac,
+                                       vector<uint8_t>* outDeviceNameSpaces) override;
+    ndk::ScopedAStatus generateSigningKeyPair(vector<uint8_t>* outSigningKeyBlob,
+                                              Certificate* outSigningKeyCertificate) override;
+
+  private:
+    // Set by constructor
+    sp<SecureHardwarePresentationProxy> hwProxy_;
+    vector<uint8_t> credentialData_;
+    int numStartRetrievalCalls_;
+
+    // Set by initialize()
+    string docType_;
+    bool testCredential_;
+
+    // Set by createEphemeralKeyPair()
+    vector<uint8_t> ephemeralPublicKey_;
+
+    // Set by setReaderEphemeralPublicKey()
+    vector<uint8_t> readerPublicKey_;
+
+    // Set by setRequestedNamespaces()
+    vector<RequestNamespace> requestNamespaces_;
+
+    // Set by setVerificationToken().
+    VerificationToken verificationToken_;
+
+    // Set at startRetrieval() time.
+    vector<uint8_t> signingKeyBlob_;
+    vector<uint8_t> sessionTranscript_;
+    vector<uint8_t> itemsRequest_;
+    vector<int32_t> requestCountsRemaining_;
+    map<string, set<string>> requestedNameSpacesAndNames_;
+    cppbor::Map deviceNameSpacesMap_;
+    cppbor::Map currentNameSpaceDeviceNameSpacesMap_;
+
+    // Calculated at startRetrieval() time.
+    size_t expectedDeviceNameSpacesSize_;
+    vector<unsigned int> expectedNumEntriesPerNamespace_;
+
+    // Set at startRetrieveEntryValue() time.
+    string currentNameSpace_;
+    string currentName_;
+    vector<int32_t> currentAccessControlProfileIds_;
+    size_t entryRemainingBytes_;
+    vector<uint8_t> entryValue_;
+
+    void calcDeviceNameSpacesSize(uint32_t accessControlProfileMask);
+};
+
+}  // namespace aidl::android::hardware::identity
+
+#endif  // ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIAL_H
diff --git a/identity/aidl/default/common/IdentityCredentialStore.cpp b/identity/aidl/default/common/IdentityCredentialStore.cpp
new file mode 100644
index 0000000..13f91aa
--- /dev/null
+++ b/identity/aidl/default/common/IdentityCredentialStore.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright 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 "IdentityCredentialStore"
+
+#include <android-base/logging.h>
+
+#include "IdentityCredential.h"
+#include "IdentityCredentialStore.h"
+#include "WritableIdentityCredential.h"
+
+namespace aidl::android::hardware::identity {
+
+ndk::ScopedAStatus IdentityCredentialStore::getHardwareInformation(
+        HardwareInformation* hardwareInformation) {
+    HardwareInformation hw;
+    hw.credentialStoreName = "Identity Credential Reference Implementation";
+    hw.credentialStoreAuthorName = "Google";
+    hw.dataChunkSize = kGcmChunkSize;
+    hw.isDirectAccess = false;
+    hw.supportedDocTypes = {};
+    *hardwareInformation = hw;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus IdentityCredentialStore::createCredential(
+        const string& docType, bool testCredential,
+        shared_ptr<IWritableIdentityCredential>* outWritableCredential) {
+    sp<SecureHardwareProvisioningProxy> hwProxy = hwProxyFactory_->createProvisioningProxy();
+    shared_ptr<WritableIdentityCredential> wc =
+            ndk::SharedRefBase::make<WritableIdentityCredential>(hwProxy, docType, testCredential);
+    if (!wc->initialize()) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Error initializing WritableIdentityCredential"));
+    }
+    *outWritableCredential = wc;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus IdentityCredentialStore::getCredential(
+        CipherSuite cipherSuite, const vector<uint8_t>& credentialData,
+        shared_ptr<IIdentityCredential>* outCredential) {
+    // We only support CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 right now.
+    if (cipherSuite != CipherSuite::CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_CIPHER_SUITE_NOT_SUPPORTED,
+                "Unsupported cipher suite"));
+    }
+
+    sp<SecureHardwarePresentationProxy> hwProxy = hwProxyFactory_->createPresentationProxy();
+    shared_ptr<IdentityCredential> credential =
+            ndk::SharedRefBase::make<IdentityCredential>(hwProxy, credentialData);
+    auto ret = credential->initialize();
+    if (ret != IIdentityCredentialStore::STATUS_OK) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                int(ret), "Error initializing IdentityCredential"));
+    }
+    *outCredential = credential;
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/IdentityCredentialStore.h b/identity/aidl/default/common/IdentityCredentialStore.h
new file mode 100644
index 0000000..d35e632
--- /dev/null
+++ b/identity/aidl/default/common/IdentityCredentialStore.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIALSTORE_H
+#define ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIALSTORE_H
+
+#include <aidl/android/hardware/identity/BnIdentityCredentialStore.h>
+
+#include "SecureHardwareProxy.h"
+
+namespace aidl::android::hardware::identity {
+
+using ::android::sp;
+using ::android::hardware::identity::SecureHardwareProxyFactory;
+using ::std::shared_ptr;
+using ::std::string;
+using ::std::vector;
+
+class IdentityCredentialStore : public BnIdentityCredentialStore {
+  public:
+    IdentityCredentialStore(sp<SecureHardwareProxyFactory> hwProxyFactory)
+        : hwProxyFactory_(hwProxyFactory) {}
+
+    // The GCM chunk size used by this implementation is 64 KiB.
+    static constexpr size_t kGcmChunkSize = 64 * 1024;
+
+    // Methods from IIdentityCredentialStore follow.
+    ndk::ScopedAStatus getHardwareInformation(HardwareInformation* hardwareInformation) override;
+
+    ndk::ScopedAStatus createCredential(
+            const string& docType, bool testCredential,
+            shared_ptr<IWritableIdentityCredential>* outWritableCredential) override;
+
+    ndk::ScopedAStatus getCredential(CipherSuite cipherSuite, const vector<uint8_t>& credentialData,
+                                     shared_ptr<IIdentityCredential>* outCredential) override;
+
+  private:
+    sp<SecureHardwareProxyFactory> hwProxyFactory_;
+};
+
+}  // namespace aidl::android::hardware::identity
+
+#endif  // ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIALSTORE_H
diff --git a/identity/aidl/default/common/SecureHardwareProxy.h b/identity/aidl/default/common/SecureHardwareProxy.h
new file mode 100644
index 0000000..b89ad87
--- /dev/null
+++ b/identity/aidl/default/common/SecureHardwareProxy.h
@@ -0,0 +1,174 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_IDENTITY_SECUREHARDWAREPROXY_H
+#define ANDROID_HARDWARE_IDENTITY_SECUREHARDWAREPROXY_H
+
+#include <utils/RefBase.h>
+#include <optional>
+#include <string>
+#include <utility>
+#include <vector>
+
+namespace android::hardware::identity {
+
+using ::android::RefBase;
+using ::std::optional;
+using ::std::pair;
+using ::std::string;
+using ::std::vector;
+
+// These classes are used to communicate with Secure Hardware. They mimic the
+// API in libEmbeddedIC 1:1 (except for using C++ types) as each call is intended
+// to be forwarded to the Secure Hardware.
+//
+// Instances are instantiated when a provisioning or presentation session
+// starts. When the session is complete, the shutdown() method is called.
+//
+
+// Forward declare.
+//
+class SecureHardwareProvisioningProxy;
+class SecureHardwarePresentationProxy;
+
+// This is a class used to create proxies.
+//
+class SecureHardwareProxyFactory : public RefBase {
+  public:
+    SecureHardwareProxyFactory() {}
+    virtual ~SecureHardwareProxyFactory() {}
+
+    virtual sp<SecureHardwareProvisioningProxy> createProvisioningProxy() = 0;
+    virtual sp<SecureHardwarePresentationProxy> createPresentationProxy() = 0;
+};
+
+// The proxy used for provisioning.
+//
+class SecureHardwareProvisioningProxy : public RefBase {
+  public:
+    SecureHardwareProvisioningProxy() {}
+    virtual ~SecureHardwareProvisioningProxy() {}
+
+    virtual bool initialize(bool testCredential) = 0;
+
+    // Returns public key certificate chain with attestation.
+    //
+    // This must return an entire certificate chain and its implementation must
+    // be coordinated with the implementation of eicOpsCreateCredentialKey() on
+    // the TA side (which may return just a single certificate or the entire
+    // chain).
+    virtual optional<vector<uint8_t>> createCredentialKey(const vector<uint8_t>& challenge,
+                                                          const vector<uint8_t>& applicationId) = 0;
+
+    virtual bool startPersonalization(int accessControlProfileCount, vector<int> entryCounts,
+                                      const string& docType,
+                                      size_t expectedProofOfProvisioningSize) = 0;
+
+    // Returns MAC (28 bytes).
+    virtual optional<vector<uint8_t>> addAccessControlProfile(
+            int id, const vector<uint8_t>& readerCertificate, bool userAuthenticationRequired,
+            uint64_t timeoutMillis, uint64_t secureUserId) = 0;
+
+    virtual bool beginAddEntry(const vector<int>& accessControlProfileIds, const string& nameSpace,
+                               const string& name, uint64_t entrySize) = 0;
+
+    // Returns encryptedContent.
+    virtual optional<vector<uint8_t>> addEntryValue(const vector<int>& accessControlProfileIds,
+                                                    const string& nameSpace, const string& name,
+                                                    const vector<uint8_t>& content) = 0;
+
+    // Returns signatureOfToBeSigned (EIC_ECDSA_P256_SIGNATURE_SIZE bytes).
+    virtual optional<vector<uint8_t>> finishAddingEntries() = 0;
+
+    // Returns encryptedCredentialKeys (80 bytes).
+    virtual optional<vector<uint8_t>> finishGetCredentialData(const string& docType) = 0;
+
+    virtual bool shutdown() = 0;
+};
+
+enum AccessCheckResult {
+    kOk,
+    kFailed,
+    kNoAccessControlProfiles,
+    kUserAuthenticationFailed,
+    kReaderAuthenticationFailed,
+};
+
+// The proxy used for presentation.
+//
+class SecureHardwarePresentationProxy : public RefBase {
+  public:
+    SecureHardwarePresentationProxy() {}
+    virtual ~SecureHardwarePresentationProxy() {}
+
+    virtual bool initialize(bool testCredential, string docType,
+                            vector<uint8_t> encryptedCredentialKeys) = 0;
+
+    // Returns publicKeyCert (1st component) and signingKeyBlob (2nd component)
+    virtual optional<pair<vector<uint8_t>, vector<uint8_t>>> generateSigningKeyPair(string docType,
+                                                                                    time_t now) = 0;
+
+    // Returns private key
+    virtual optional<vector<uint8_t>> createEphemeralKeyPair() = 0;
+
+    virtual optional<uint64_t> createAuthChallenge() = 0;
+
+    virtual bool startRetrieveEntries() = 0;
+
+    virtual bool setAuthToken(uint64_t challenge, uint64_t secureUserId, uint64_t authenticatorId,
+                              int hardwareAuthenticatorType, uint64_t timeStamp,
+                              const vector<uint8_t>& mac, uint64_t verificationTokenChallenge,
+                              uint64_t verificationTokenTimestamp,
+                              int verificationTokenSecurityLevel,
+                              const vector<uint8_t>& verificationTokenMac) = 0;
+
+    virtual bool pushReaderCert(const vector<uint8_t>& certX509) = 0;
+
+    virtual optional<bool> validateAccessControlProfile(int id,
+                                                        const vector<uint8_t>& readerCertificate,
+                                                        bool userAuthenticationRequired,
+                                                        int timeoutMillis, uint64_t secureUserId,
+                                                        const vector<uint8_t>& mac) = 0;
+
+    virtual bool validateRequestMessage(const vector<uint8_t>& sessionTranscript,
+                                        const vector<uint8_t>& requestMessage, int coseSignAlg,
+                                        const vector<uint8_t>& readerSignatureOfToBeSigned) = 0;
+
+    virtual bool calcMacKey(const vector<uint8_t>& sessionTranscript,
+                            const vector<uint8_t>& readerEphemeralPublicKey,
+                            const vector<uint8_t>& signingKeyBlob, const string& docType,
+                            unsigned int numNamespacesWithValues,
+                            size_t expectedProofOfProvisioningSize) = 0;
+
+    virtual AccessCheckResult startRetrieveEntryValue(
+            const string& nameSpace, const string& name, unsigned int newNamespaceNumEntries,
+            int32_t entrySize, const vector<int32_t>& accessControlProfileIds) = 0;
+
+    virtual optional<vector<uint8_t>> retrieveEntryValue(
+            const vector<uint8_t>& encryptedContent, const string& nameSpace, const string& name,
+            const vector<int32_t>& accessControlProfileIds) = 0;
+
+    virtual optional<vector<uint8_t>> finishRetrieval();
+
+    virtual optional<vector<uint8_t>> deleteCredential(const string& docType,
+                                                       size_t proofOfDeletionCborSize) = 0;
+
+    virtual bool shutdown() = 0;
+};
+
+}  // namespace android::hardware::identity
+
+#endif  // ANDROID_HARDWARE_IDENTITY_SECUREHARDWAREPROXY_H
diff --git a/identity/aidl/default/common/WritableIdentityCredential.cpp b/identity/aidl/default/common/WritableIdentityCredential.cpp
new file mode 100644
index 0000000..1328f36
--- /dev/null
+++ b/identity/aidl/default/common/WritableIdentityCredential.cpp
@@ -0,0 +1,383 @@
+/*
+ * Copyright 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 "WritableIdentityCredential"
+
+#include "WritableIdentityCredential.h"
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+#include <cppbor/cppbor.h>
+#include <cppbor/cppbor_parse.h>
+
+#include <utility>
+
+#include "IdentityCredentialStore.h"
+
+#include "FakeSecureHardwareProxy.h"
+
+namespace aidl::android::hardware::identity {
+
+using ::android::base::StringPrintf;
+using ::std::optional;
+using namespace ::android::hardware::identity;
+
+bool WritableIdentityCredential::initialize() {
+    if (!hwProxy_->initialize(testCredential_)) {
+        LOG(ERROR) << "hwProxy->initialize failed";
+        return false;
+    }
+    startPersonalizationCalled_ = false;
+    firstEntry_ = true;
+
+    return true;
+}
+
+WritableIdentityCredential::~WritableIdentityCredential() {}
+
+ndk::ScopedAStatus WritableIdentityCredential::getAttestationCertificate(
+        const vector<uint8_t>& attestationApplicationId,
+        const vector<uint8_t>& attestationChallenge, vector<Certificate>* outCertificateChain) {
+    if (getAttestationCertificateAlreadyCalled_) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Error attestation certificate previously generated"));
+    }
+    getAttestationCertificateAlreadyCalled_ = true;
+
+    if (attestationChallenge.empty()) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA, "Challenge can not be empty"));
+    }
+
+    optional<vector<uint8_t>> certChain =
+            hwProxy_->createCredentialKey(attestationChallenge, attestationApplicationId);
+    if (!certChain) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Error generating attestation certificate chain"));
+    }
+
+    optional<vector<vector<uint8_t>>> certs = support::certificateChainSplit(certChain.value());
+    if (!certs) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Error splitting chain into separate certificates"));
+    }
+
+    *outCertificateChain = vector<Certificate>();
+    for (const vector<uint8_t>& cert : certs.value()) {
+        Certificate c = Certificate();
+        c.encodedCertificate = cert;
+        outCertificateChain->push_back(std::move(c));
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WritableIdentityCredential::setExpectedProofOfProvisioningSize(
+        int32_t expectedProofOfProvisioningSize) {
+    expectedProofOfProvisioningSize_ = expectedProofOfProvisioningSize;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WritableIdentityCredential::startPersonalization(
+        int32_t accessControlProfileCount, const vector<int32_t>& entryCounts) {
+    if (startPersonalizationCalled_) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "startPersonalization called already"));
+    }
+    startPersonalizationCalled_ = true;
+
+    numAccessControlProfileRemaining_ = accessControlProfileCount;
+    remainingEntryCounts_ = entryCounts;
+    entryNameSpace_ = "";
+
+    signedDataAccessControlProfiles_ = cppbor::Array();
+    signedDataNamespaces_ = cppbor::Map();
+    signedDataCurrentNamespace_ = cppbor::Array();
+
+    if (!hwProxy_->startPersonalization(accessControlProfileCount, entryCounts, docType_,
+                                        expectedProofOfProvisioningSize_)) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "eicStartPersonalization"));
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WritableIdentityCredential::addAccessControlProfile(
+        int32_t id, const Certificate& readerCertificate, bool userAuthenticationRequired,
+        int64_t timeoutMillis, int64_t secureUserId,
+        SecureAccessControlProfile* outSecureAccessControlProfile) {
+    if (numAccessControlProfileRemaining_ == 0) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                "numAccessControlProfileRemaining_ is 0 and expected non-zero"));
+    }
+
+    if (accessControlProfileIds_.find(id) != accessControlProfileIds_.end()) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                "Access Control Profile id must be unique"));
+    }
+    accessControlProfileIds_.insert(id);
+
+    if (id < 0 || id >= 32) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                "Access Control Profile id must be non-negative and less than 32"));
+    }
+
+    // Spec requires if |userAuthenticationRequired| is false, then |timeoutMillis| must also
+    // be zero.
+    if (!userAuthenticationRequired && timeoutMillis != 0) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                "userAuthenticationRequired is false but timeout is non-zero"));
+    }
+
+    optional<vector<uint8_t>> mac = hwProxy_->addAccessControlProfile(
+            id, readerCertificate.encodedCertificate, userAuthenticationRequired, timeoutMillis,
+            secureUserId);
+    if (!mac) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "eicAddAccessControlProfile"));
+    }
+
+    SecureAccessControlProfile profile;
+    profile.id = id;
+    profile.readerCertificate = readerCertificate;
+    profile.userAuthenticationRequired = userAuthenticationRequired;
+    profile.timeoutMillis = timeoutMillis;
+    profile.secureUserId = secureUserId;
+    profile.mac = mac.value();
+    cppbor::Map profileMap;
+    profileMap.add("id", profile.id);
+    if (profile.readerCertificate.encodedCertificate.size() > 0) {
+        profileMap.add("readerCertificate",
+                       cppbor::Bstr(profile.readerCertificate.encodedCertificate));
+    }
+    if (profile.userAuthenticationRequired) {
+        profileMap.add("userAuthenticationRequired", profile.userAuthenticationRequired);
+        profileMap.add("timeoutMillis", profile.timeoutMillis);
+    }
+    signedDataAccessControlProfiles_.add(std::move(profileMap));
+
+    numAccessControlProfileRemaining_--;
+
+    *outSecureAccessControlProfile = profile;
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WritableIdentityCredential::beginAddEntry(
+        const vector<int32_t>& accessControlProfileIds, const string& nameSpace, const string& name,
+        int32_t entrySize) {
+    if (numAccessControlProfileRemaining_ != 0) {
+        LOG(ERROR) << "numAccessControlProfileRemaining_ is " << numAccessControlProfileRemaining_
+                   << " and expected zero";
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                "numAccessControlProfileRemaining_ is not zero"));
+    }
+
+    if (remainingEntryCounts_.size() == 0) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA, "No more namespaces to add to"));
+    }
+
+    // Handle initial beginEntry() call.
+    if (firstEntry_) {
+        firstEntry_ = false;
+        entryNameSpace_ = nameSpace;
+        allNameSpaces_.insert(nameSpace);
+    }
+
+    // If the namespace changed...
+    if (nameSpace != entryNameSpace_) {
+        if (allNameSpaces_.find(nameSpace) != allNameSpaces_.end()) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Name space cannot be added in interleaving fashion"));
+        }
+
+        // Then check that all entries in the previous namespace have been added..
+        if (remainingEntryCounts_[0] != 0) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "New namespace but a non-zero number of entries remain to be added"));
+        }
+        remainingEntryCounts_.erase(remainingEntryCounts_.begin());
+        remainingEntryCounts_[0] -= 1;
+        allNameSpaces_.insert(nameSpace);
+
+        if (signedDataCurrentNamespace_.size() > 0) {
+            signedDataNamespaces_.add(entryNameSpace_, std::move(signedDataCurrentNamespace_));
+            signedDataCurrentNamespace_ = cppbor::Array();
+        }
+    } else {
+        // Same namespace...
+        if (remainingEntryCounts_[0] == 0) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Same namespace but no entries remain to be added"));
+        }
+        remainingEntryCounts_[0] -= 1;
+    }
+
+    entryRemainingBytes_ = entrySize;
+    entryNameSpace_ = nameSpace;
+    entryName_ = name;
+    entryAccessControlProfileIds_ = accessControlProfileIds;
+    entryBytes_.resize(0);
+    // LOG(INFO) << "name=" << name << " entrySize=" << entrySize;
+
+    if (!hwProxy_->beginAddEntry(accessControlProfileIds, nameSpace, name, entrySize)) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "eicBeginAddEntry"));
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WritableIdentityCredential::addEntryValue(const vector<uint8_t>& content,
+                                                             vector<uint8_t>* outEncryptedContent) {
+    size_t contentSize = content.size();
+
+    if (contentSize > IdentityCredentialStore::kGcmChunkSize) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                "Passed in chunk of is bigger than kGcmChunkSize"));
+    }
+    if (contentSize > entryRemainingBytes_) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                "Passed in chunk is bigger than remaining space"));
+    }
+
+    entryBytes_.insert(entryBytes_.end(), content.begin(), content.end());
+    entryRemainingBytes_ -= contentSize;
+    if (entryRemainingBytes_ > 0) {
+        if (contentSize != IdentityCredentialStore::kGcmChunkSize) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA,
+                    "Retrieved non-final chunk which isn't kGcmChunkSize"));
+        }
+    }
+
+    optional<vector<uint8_t>> encryptedContent = hwProxy_->addEntryValue(
+            entryAccessControlProfileIds_, entryNameSpace_, entryName_, content);
+    if (!encryptedContent) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "eicAddEntryValue"));
+    }
+
+    if (entryRemainingBytes_ == 0) {
+        // TODO: ideally do do this without parsing the data (but still validate data is valid
+        // CBOR).
+        auto [item, _, message] = cppbor::parse(entryBytes_);
+        if (item == nullptr) {
+            return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                    IIdentityCredentialStore::STATUS_INVALID_DATA, "Data is not valid CBOR"));
+        }
+        cppbor::Map entryMap;
+        entryMap.add("name", entryName_);
+        entryMap.add("value", std::move(item));
+        cppbor::Array profileIdArray;
+        for (auto id : entryAccessControlProfileIds_) {
+            profileIdArray.add(id);
+        }
+        entryMap.add("accessControlProfiles", std::move(profileIdArray));
+        signedDataCurrentNamespace_.add(std::move(entryMap));
+    }
+
+    *outEncryptedContent = encryptedContent.value();
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus WritableIdentityCredential::finishAddingEntries(
+        vector<uint8_t>* outCredentialData, vector<uint8_t>* outProofOfProvisioningSignature) {
+    if (numAccessControlProfileRemaining_ != 0) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                "numAccessControlProfileRemaining_ is not 0 and expected zero"));
+    }
+
+    if (remainingEntryCounts_.size() > 1 || remainingEntryCounts_[0] != 0) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                "More entry spaces remain than startPersonalization configured"));
+    }
+
+    if (signedDataCurrentNamespace_.size() > 0) {
+        signedDataNamespaces_.add(entryNameSpace_, std::move(signedDataCurrentNamespace_));
+    }
+    cppbor::Array popArray;
+    popArray.add("ProofOfProvisioning")
+            .add(docType_)
+            .add(std::move(signedDataAccessControlProfiles_))
+            .add(std::move(signedDataNamespaces_))
+            .add(testCredential_);
+    vector<uint8_t> encodedCbor = popArray.encode();
+
+    if (encodedCbor.size() != expectedProofOfProvisioningSize_) {
+        LOG(ERROR) << "CBOR for proofOfProvisioning is " << encodedCbor.size() << " bytes, "
+                   << "was expecting " << expectedProofOfProvisioningSize_;
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_INVALID_DATA,
+                StringPrintf("Unexpected CBOR size %zd for proofOfProvisioning, was expecting %zd",
+                             encodedCbor.size(), expectedProofOfProvisioningSize_)
+                        .c_str()));
+    }
+
+    optional<vector<uint8_t>> signatureOfToBeSigned = hwProxy_->finishAddingEntries();
+    if (!signatureOfToBeSigned) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "eicFinishAddingEntries"));
+    }
+
+    optional<vector<uint8_t>> signature =
+            support::coseSignEcDsaWithSignature(signatureOfToBeSigned.value(),
+                                                encodedCbor,  // data
+                                                {});          // certificateChain
+    if (!signature) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED, "Error signing data"));
+    }
+
+    optional<vector<uint8_t>> encryptedCredentialKeys = hwProxy_->finishGetCredentialData(docType_);
+    if (!encryptedCredentialKeys) {
+        return ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
+                IIdentityCredentialStore::STATUS_FAILED,
+                "Error generating encrypted CredentialKeys"));
+    }
+    cppbor::Array array;
+    array.add(docType_);
+    array.add(testCredential_);
+    array.add(encryptedCredentialKeys.value());
+    vector<uint8_t> credentialData = array.encode();
+
+    *outCredentialData = credentialData;
+    *outProofOfProvisioningSignature = signature.value();
+    hwProxy_->shutdown();
+
+    return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace aidl::android::hardware::identity
diff --git a/identity/aidl/default/common/WritableIdentityCredential.h b/identity/aidl/default/common/WritableIdentityCredential.h
new file mode 100644
index 0000000..c6f0628
--- /dev/null
+++ b/identity/aidl/default/common/WritableIdentityCredential.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef ANDROID_HARDWARE_IDENTITY_WRITABLEIDENTITYCREDENTIAL_H
+#define ANDROID_HARDWARE_IDENTITY_WRITABLEIDENTITYCREDENTIAL_H
+
+#include <aidl/android/hardware/identity/BnWritableIdentityCredential.h>
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <cppbor.h>
+#include <set>
+
+#include "IdentityCredentialStore.h"
+#include "SecureHardwareProxy.h"
+
+namespace aidl::android::hardware::identity {
+
+using ::android::sp;
+using ::android::hardware::identity::SecureHardwareProvisioningProxy;
+using ::std::set;
+using ::std::string;
+using ::std::vector;
+
+class WritableIdentityCredential : public BnWritableIdentityCredential {
+  public:
+    WritableIdentityCredential(sp<SecureHardwareProvisioningProxy> hwProxy, const string& docType,
+                               bool testCredential)
+        : hwProxy_(hwProxy), docType_(docType), testCredential_(testCredential) {}
+
+    ~WritableIdentityCredential();
+
+    // Creates the Credential Key. Returns false on failure. Must be called
+    // right after construction.
+    bool initialize();
+
+    // Methods from IWritableIdentityCredential follow.
+    ndk::ScopedAStatus getAttestationCertificate(const vector<uint8_t>& attestationApplicationId,
+                                                 const vector<uint8_t>& attestationChallenge,
+                                                 vector<Certificate>* outCertificateChain) override;
+
+    ndk::ScopedAStatus setExpectedProofOfProvisioningSize(
+            int32_t expectedProofOfProvisioningSize) override;
+
+    ndk::ScopedAStatus startPersonalization(int32_t accessControlProfileCount,
+                                            const vector<int32_t>& entryCounts) override;
+
+    ndk::ScopedAStatus addAccessControlProfile(
+            int32_t id, const Certificate& readerCertificate, bool userAuthenticationRequired,
+            int64_t timeoutMillis, int64_t secureUserId,
+            SecureAccessControlProfile* outSecureAccessControlProfile) override;
+
+    ndk::ScopedAStatus beginAddEntry(const vector<int32_t>& accessControlProfileIds,
+                                     const string& nameSpace, const string& name,
+                                     int32_t entrySize) override;
+    ndk::ScopedAStatus addEntryValue(const vector<uint8_t>& content,
+                                     vector<uint8_t>* outEncryptedContent) override;
+
+    ndk::ScopedAStatus finishAddingEntries(
+            vector<uint8_t>* outCredentialData,
+            vector<uint8_t>* outProofOfProvisioningSignature) override;
+
+  private:
+    // Set by constructor.
+    sp<SecureHardwareProvisioningProxy> hwProxy_;
+    string docType_;
+    bool testCredential_;
+
+    // This is set in initialize().
+    bool startPersonalizationCalled_;
+    bool firstEntry_;
+
+    // This is set in getAttestationCertificate().
+    bool getAttestationCertificateAlreadyCalled_ = false;
+
+    // These fields are initialized during startPersonalization()
+    size_t numAccessControlProfileRemaining_;
+    vector<int32_t> remainingEntryCounts_;
+    cppbor::Array signedDataAccessControlProfiles_;
+    cppbor::Map signedDataNamespaces_;
+    cppbor::Array signedDataCurrentNamespace_;
+    size_t expectedProofOfProvisioningSize_;
+
+    // This field is initialized in addAccessControlProfile
+    set<int32_t> accessControlProfileIds_;
+
+    // These fields are initialized during beginAddEntry()
+    size_t entryRemainingBytes_;
+    string entryNameSpace_;
+    string entryName_;
+    vector<int32_t> entryAccessControlProfileIds_;
+    vector<uint8_t> entryBytes_;
+    set<string> allNameSpaces_;
+};
+
+}  // namespace aidl::android::hardware::identity
+
+#endif  // ANDROID_HARDWARE_IDENTITY_WRITABLEIDENTITYCREDENTIAL_H
