diff --git a/identity/Android.bp b/identity/Android.bp
new file mode 100644
index 0000000..240e107
--- /dev/null
+++ b/identity/Android.bp
@@ -0,0 +1,86 @@
+cc_defaults {
+    name: "identity_defaults",
+    cflags: [
+        "-Wall",
+        // "-Werror",
+        "-Wextra",
+        "-Wunused",
+    ],
+    sanitize: {
+        misc_undefined : ["integer"],
+    },
+    clang : true,
+}
+
+cc_binary {
+    name: "credstore",
+    defaults: ["identity_defaults"],
+
+    srcs: [
+        "main.cpp",
+        "CredentialStore.cpp",
+        "CredentialStoreFactory.cpp",
+        "WritableCredential.cpp",
+        "Credential.cpp",
+        "CredentialData.cpp",
+        "Util.cpp",
+    ],
+    init_rc: ["credstore.rc"],
+    shared_libs: [
+        "android.hardware.identity@1.0",
+        "android.hardware.keymaster@4.0",
+        "libbase",
+        "libbinder",
+        "libkeystore_aidl",
+        "libcredstore_aidl",
+        "libutils",
+        "libhidlbase",
+        "android.hardware.identity-support-lib",
+        "libkeymaster4support",
+    ],
+    static_libs: [
+        "libcppbor",
+    ]
+}
+
+filegroup {
+    name: "credstore_aidl",
+    srcs: [
+        "binder/android/security/identity/ICredential.aidl",
+        "binder/android/security/identity/IWritableCredential.aidl",
+        "binder/android/security/identity/ICredentialStore.aidl",
+        "binder/android/security/identity/AccessControlProfileParcel.aidl",
+        "binder/android/security/identity/EntryNamespaceParcel.aidl",
+        "binder/android/security/identity/EntryParcel.aidl",
+        "binder/android/security/identity/RequestNamespaceParcel.aidl",
+        "binder/android/security/identity/RequestEntryParcel.aidl",
+        "binder/android/security/identity/ResultNamespaceParcel.aidl",
+        "binder/android/security/identity/ResultEntryParcel.aidl",
+        "binder/android/security/identity/GetEntriesResultParcel.aidl",
+        "binder/android/security/identity/AuthKeyParcel.aidl",
+        "binder/android/security/identity/SecurityHardwareInfoParcel.aidl",
+        "binder/android/security/identity/ICredentialStoreFactory.aidl",
+    ],
+    path: "binder",
+}
+
+cc_library_shared {
+    name: "libcredstore_aidl",
+    srcs: [
+        ":credstore_aidl",
+        ],
+    aidl: {
+        export_aidl_headers: true,
+        include_dirs: [
+            "system/security/identity/binder",
+        ],
+    },
+    shared_libs: [
+        "libbinder",
+        "libutils",
+        "libkeymaster4support",
+    ],
+    export_shared_lib_headers: [
+        "libbinder",
+    ],
+}
diff --git a/identity/Credential.cpp b/identity/Credential.cpp
new file mode 100644
index 0000000..6b03309
--- /dev/null
+++ b/identity/Credential.cpp
@@ -0,0 +1,494 @@
+/*
+ * 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 "Credential"
+
+#include <android-base/logging.h>
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <android/security/identity/ICredentialStore.h>
+
+#include <android/security/keystore/IKeystoreService.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <keymasterV4_0/keymaster_utils.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+#include "Credential.h"
+#include "CredentialData.h"
+#include "Util.h"
+
+namespace android {
+namespace security {
+namespace identity {
+
+using std::optional;
+
+using android::security::keystore::IKeystoreService;
+
+using ::android::hardware::hidl_vec;
+
+using ::android::hardware::identity::V1_0::Result;
+using ::android::hardware::identity::V1_0::ResultCode;
+using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
+
+using ::android::hardware::identity::support::ecKeyPairGetPkcs12;
+using ::android::hardware::identity::support::ecKeyPairGetPrivateKey;
+using ::android::hardware::identity::support::ecKeyPairGetPublicKey;
+using ::android::hardware::identity::support::sha256;
+
+using android::hardware::keymaster::V4_0::HardwareAuthToken;
+
+Credential::Credential(const std::string& dataPath, const std::string& credentialName)
+    : dataPath_(dataPath), credentialName_(credentialName) {}
+
+Credential::~Credential() {}
+
+Status Credential::loadCredential(sp<IIdentityCredentialStore> halStoreBinder) {
+    uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
+    sp<CredentialData> data = new CredentialData(dataPath_, callingUid, credentialName_);
+    if (!data->loadFromDisk()) {
+        LOG(ERROR) << "Error loading data for credential";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error loading data for credential");
+    }
+
+    data_ = data;
+
+    Result result;
+    sp<IIdentityCredential> halBinder;
+    halStoreBinder->getCredential(
+        data_->getCredentialData(),
+        [&](const Result& _result, const sp<IIdentityCredential>& _halBinder) {
+            result = _result;
+            halBinder = _halBinder;
+        });
+    if (result.code != ResultCode::OK) {
+        LOG(ERROR) << "Error getting HAL binder";
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC);
+    }
+
+    halBinder_ = halBinder;
+
+    return Status::ok();
+}
+
+Status Credential::getCredentialKeyCertificateChain(std::vector<uint8_t>* _aidl_return) {
+    *_aidl_return = data_->getAttestationCertificate();
+    return Status::ok();
+}
+
+// Returns operation handle
+Status Credential::selectAuthKey(bool allowUsingExhaustedKeys, int64_t* _aidl_return) {
+
+    selectedAuthKey_ = data_->selectAuthKey(allowUsingExhaustedKeys);
+    if (selectedAuthKey_ == nullptr) {
+        return Status::fromServiceSpecificError(
+            ICredentialStore::ERROR_NO_AUTHENTICATION_KEY_AVAILABLE,
+            "No suitable authentication key available");
+    }
+
+    Result result;
+    uint64_t challenge;
+    halBinder_->createAuthChallenge([&](const Result& _result, uint64_t _challenge) {
+        result = _result;
+        challenge = _challenge;
+    });
+    if (result.code != ResultCode::OK) {
+        LOG(ERROR) << "createAuthChallenge() failed " << ((int)result.code) << ": "
+                   << result.message;
+        return halResultToGenericError(result);
+    }
+    if (challenge == 0) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Returned challenge is 0 (bug in HAL or TA)");
+    }
+
+    selectedChallenge_ = challenge;
+    *_aidl_return = challenge;
+    return Status::ok();
+}
+
+// Returns false if an error occurred communicating with keystore.
+//
+// Sets |authToken| to the empty vector if an auth token couldn't be obtained.
+//
+bool getAuthTokenFromKeystore(uint64_t challenge, uint64_t secureUserId,
+                              unsigned int authTokenMaxAgeMillis, vector<uint8_t>& authToken) {
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
+    sp<IKeystoreService> keystore = interface_cast<IKeystoreService>(binder);
+    if (keystore == nullptr) {
+        return false;
+    }
+
+    vector<uint8_t> returnedAuthToken;
+    Status ret = keystore->getAuthTokenForCredstore(challenge, secureUserId, authTokenMaxAgeMillis,
+                                                    &returnedAuthToken);
+    if (!ret.isOk()) {
+        return false;
+    }
+    authToken = returnedAuthToken;
+    return true;
+}
+
+Status Credential::getEntries(const vector<uint8_t>& requestMessage,
+                              const vector<RequestNamespaceParcel>& requestNamespaces,
+                              const vector<uint8_t>& sessionTranscript,
+                              const vector<uint8_t>& readerSignature, bool allowUsingExhaustedKeys,
+                              GetEntriesResultParcel* _aidl_return) {
+    GetEntriesResultParcel ret;
+
+    // Calculate requestCounts ahead of time and be careful not to include
+    // elements that don't exist.
+    //
+    // Also go through and figure out which access control profiles to include
+    // in the startRetrieval() call.
+    vector<uint16_t> requestCounts;
+    const vector<SecureAccessControlProfile>& allProfiles = data_->getSecureAccessControlProfiles();
+    vector<bool> includeProfile(allProfiles.size());
+    for (const RequestNamespaceParcel& rns : requestNamespaces) {
+        size_t numEntriesInNsToRequest = 0;
+        for (const RequestEntryParcel& rep : rns.entries) {
+            if (data_->hasEntryData(rns.namespaceName, rep.name)) {
+                numEntriesInNsToRequest++;
+            }
+
+            optional<EntryData> data = data_->getEntryData(rns.namespaceName, rep.name);
+            if (data) {
+                for (uint16_t id : data.value().accessControlProfileIds) {
+                    if (id >= includeProfile.size()) {
+                        LOG(ERROR) << "Invalid accessControlProfileId " << id << " for "
+                                   << rns.namespaceName << ": " << rep.name;
+                        return Status::fromServiceSpecificError(
+                            ICredentialStore::ERROR_GENERIC, "Invalid accessProfileId for entry");
+                    }
+                    includeProfile[id] = true;
+                }
+            }
+        }
+        requestCounts.push_back(numEntriesInNsToRequest);
+    }
+
+    // Now that we know which profiles are needed, send only those to the
+    // HAL.
+    vector<SecureAccessControlProfile> selectedProfiles;
+    for (size_t n = 0; n < allProfiles.size(); n++) {
+        if (includeProfile[n]) {
+            selectedProfiles.push_back(allProfiles[n]);
+        }
+    }
+
+    // Calculate the highest [1] non-zero timeout and if user-auth is needed
+    // ... we need this to select an appropriate authToken.
+    //
+    // [1] : Why do we request the highest timeout and not the lowest? Well, we
+    //       return partial results in getEntries e.g. if some data elements
+    //       fail to authorize we'll still return the ones that did not fail. So
+    //       e.g. consider data elements A and B where A has an ACP with 60
+    //       seconds and B has an ACP with 3600 seconds. In this case we'll be
+    //       fine with getting an authToken for e.g. 2400 seconds which would
+    //       mean returning only B.
+    //
+    bool userAuthNeeded = false;
+    unsigned int authTokenMaxAgeMillis = 0;
+    for (auto& profile : selectedProfiles) {
+        if (profile.userAuthenticationRequired) {
+            userAuthNeeded = true;
+            if (profile.timeoutMillis > 0) {
+                if (profile.timeoutMillis > authTokenMaxAgeMillis) {
+                    authTokenMaxAgeMillis = profile.timeoutMillis;
+                }
+            }
+        }
+    }
+
+    // If requesting a challenge-based authToken the idea is that authentication
+    // happens as part of the transaction. As such, authTokenMaxAgeMillis should
+    // be nearly zero. We'll use 10 seconds for this.
+    if (userAuthNeeded && selectedChallenge_ != 0) {
+        authTokenMaxAgeMillis = 10 * 1000;
+    }
+
+    // Only get an authToken if it's actually needed.
+    HardwareAuthToken authToken;
+    if (userAuthNeeded) {
+        vector<uint8_t> authTokenBytes;
+        if (!getAuthTokenFromKeystore(selectedChallenge_, data_->getSecureUserId(),
+                                      authTokenMaxAgeMillis, authTokenBytes)) {
+            LOG(ERROR) << "Error getting auth token from keystore";
+            return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                    "Error getting auth token from keystore");
+        }
+        if (authTokenBytes.size() > 0) {
+            authToken =
+                android::hardware::keymaster::V4_0::support::hidlVec2AuthToken(authTokenBytes);
+        }
+    }
+
+    Result result;
+    halBinder_->startRetrieval(selectedProfiles, authToken, requestMessage, sessionTranscript,
+                               readerSignature, requestCounts,
+                               [&](const Result& _result) { result = _result; });
+    if (result.code == ResultCode::EPHEMERAL_PUBLIC_KEY_NOT_FOUND) {
+        LOG(ERROR) << "startRetrieval() failed " << ((int)result.code) << ": " << result.message;
+        return Status::fromServiceSpecificError(
+            ICredentialStore::ERROR_EPHEMERAL_PUBLIC_KEY_NOT_FOUND, result.message.c_str());
+    } else if (result.code == ResultCode::READER_SIGNATURE_CHECK_FAILED) {
+        LOG(ERROR) << "startRetrieval() failed " << ((int)result.code) << ": " << result.message;
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_INVALID_READER_SIGNATURE,
+                                                result.message.c_str());
+    } else if (result.code == ResultCode::INVALID_ITEMS_REQUEST_MESSAGE) {
+        LOG(ERROR) << "startRetrieval() failed " << ((int)result.code) << ": " << result.message;
+        return Status::fromServiceSpecificError(
+            ICredentialStore::ERROR_INVALID_ITEMS_REQUEST_MESSAGE, result.message.c_str());
+    } else if (result.code == ResultCode::SESSION_TRANSCRIPT_MISMATCH) {
+        LOG(ERROR) << "startRetrieval() failed " << ((int)result.code) << ": " << result.message;
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_SESSION_TRANSCRIPT_MISMATCH,
+                                                result.message.c_str());
+    } else if (result.code != ResultCode::OK) {
+        LOG(ERROR) << "startRetrieval() failed " << ((int)result.code) << ": " << result.message;
+        return halResultToGenericError(result);
+    }
+
+    for (const RequestNamespaceParcel& rns : requestNamespaces) {
+        ResultNamespaceParcel resultNamespaceParcel;
+        resultNamespaceParcel.namespaceName = rns.namespaceName;
+
+        for (const RequestEntryParcel& rep : rns.entries) {
+            ResultEntryParcel resultEntryParcel;
+            resultEntryParcel.name = rep.name;
+
+            optional<EntryData> data = data_->getEntryData(rns.namespaceName, rep.name);
+            if (!data) {
+                resultEntryParcel.status = STATUS_NO_SUCH_ENTRY;
+                resultNamespaceParcel.entries.push_back(resultEntryParcel);
+                continue;
+            }
+
+            halBinder_->startRetrieveEntryValue(rns.namespaceName, rep.name, data.value().size,
+                                                data.value().accessControlProfileIds,
+                                                [&](const Result& _result) { result = _result; });
+            if (result.code == ResultCode::USER_AUTHENTICATION_FAILED) {
+                resultEntryParcel.status = STATUS_USER_AUTHENTICATION_FAILED;
+                resultNamespaceParcel.entries.push_back(resultEntryParcel);
+                continue;
+            } else if (result.code == ResultCode::READER_AUTHENTICATION_FAILED) {
+                resultEntryParcel.status = STATUS_READER_AUTHENTICATION_FAILED;
+                resultNamespaceParcel.entries.push_back(resultEntryParcel);
+                continue;
+            } else if (result.code == ResultCode::NOT_IN_REQUEST_MESSAGE) {
+                resultEntryParcel.status = STATUS_NOT_IN_REQUEST_MESSAGE;
+                resultNamespaceParcel.entries.push_back(resultEntryParcel);
+                continue;
+            } else if (result.code == ResultCode::NO_ACCESS_CONTROL_PROFILES) {
+                resultEntryParcel.status = STATUS_NO_ACCESS_CONTROL_PROFILES;
+                resultNamespaceParcel.entries.push_back(resultEntryParcel);
+                continue;
+            } else if (result.code != ResultCode::OK) {
+                LOG(ERROR) << "startRetrieveEntryValue() failed " << ((int)result.code) << ": "
+                           << result.message;
+                return halResultToGenericError(result);
+            }
+
+            vector<uint8_t> value;
+            for (const auto& encryptedChunk : data.value().encryptedChunks) {
+                halBinder_->retrieveEntryValue(
+                    encryptedChunk, [&](const Result& _result, const hidl_vec<uint8_t>& chunk) {
+                        result = _result;
+                        value.insert(value.end(), chunk.begin(), chunk.end());
+                    });
+                if (result.code != ResultCode::OK) {
+                    LOG(ERROR) << "retrieveEntryValue failed() " << ((int)result.code) << ": "
+                               << result.message;
+                    return halResultToGenericError(result);
+                }
+            }
+
+            resultEntryParcel.status = STATUS_OK;
+            resultEntryParcel.value = value;
+            resultNamespaceParcel.entries.push_back(resultEntryParcel);
+        }
+        ret.resultNamespaces.push_back(resultNamespaceParcel);
+    }
+
+    // Note that the selectAuthKey() method is only called if a CryptoObject is involved at
+    // the Java layer. So we could end up with no previously selected auth key and we may
+    // need one.
+    const AuthKeyData* authKey = selectedAuthKey_;
+    if (sessionTranscript.size() > 0) {
+        if (authKey == nullptr) {
+            authKey = data_->selectAuthKey(allowUsingExhaustedKeys);
+            if (authKey == nullptr) {
+                return Status::fromServiceSpecificError(
+                    ICredentialStore::ERROR_NO_AUTHENTICATION_KEY_AVAILABLE,
+                    "No suitable authentication key available");
+            }
+        }
+    }
+
+    vector<uint8_t> signingKeyBlob;
+    if (authKey != nullptr) {
+        signingKeyBlob = authKey->keyBlob;
+    }
+    halBinder_->finishRetrieval(signingKeyBlob, [&](const Result& _result,
+                                                    const hidl_vec<uint8_t>& _mac,
+                                                    const hidl_vec<uint8_t>& _deviceNameSpaces) {
+        result = _result;
+        ret.mac = _mac;
+        ret.deviceNameSpaces = _deviceNameSpaces;
+        if (authKey != nullptr) {
+            ret.staticAuthenticationData = authKey->staticAuthenticationData;
+        }
+    });
+    if (result.code != ResultCode::OK) {
+        LOG(ERROR) << "finishRetrieval failed() " << ((int)result.code) << ": " << result.message;
+        return halResultToGenericError(result);
+    }
+
+    // Ensure useCount is updated on disk.
+    if (authKey != nullptr) {
+        if (!data_->saveToDisk()) {
+            return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                    "Error saving data");
+        }
+    }
+
+    *_aidl_return = ret;
+    return Status::ok();
+}
+
+Status Credential::deleteCredential(vector<uint8_t>* _aidl_return) {
+    Result result;
+    halBinder_->deleteCredential(
+        [&](const Result& _result, const hidl_vec<uint8_t>& _proofOfDeletionSignature) {
+            result = _result;
+            *_aidl_return = _proofOfDeletionSignature;
+        });
+    if (result.code != ResultCode::OK) {
+        LOG(ERROR) << "deleteCredential failed() " << ((int)result.code) << ": " << result.message;
+        return halResultToGenericError(result);
+    }
+    if (!data_->deleteCredential()) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error deleting credential data on disk");
+    }
+    return Status::ok();
+}
+
+Status Credential::createEphemeralKeyPair(vector<uint8_t>* _aidl_return) {
+    Result result;
+
+    vector<uint8_t> keyPair;
+    halBinder_->createEphemeralKeyPair(
+        [&](const Result& _result, const hidl_vec<uint8_t>& _keyPair) {
+            result = _result;
+            keyPair = _keyPair;
+        });
+    if (result.code != ResultCode::OK) {
+        LOG(ERROR) << "createEphemeralKeyPair failed() " << ((int)result.code) << ": "
+                   << result.message;
+        return halResultToGenericError(result);
+    }
+
+    optional<vector<uint8_t>> pkcs12Bytes = ecKeyPairGetPkcs12(keyPair,
+                                                               "ephemeralKey",  // Alias for key
+                                                               "0",  // Serial, as a decimal number
+                                                               "Credstore",      // Issuer
+                                                               "Ephemeral Key",  // Subject
+                                                               0,  // Validity Not Before
+                                                               24 * 60 * 60);  // Validity Not After
+    if (!pkcs12Bytes) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error creating PKCS#12 structure for key pair");
+    }
+    *_aidl_return = pkcs12Bytes.value();
+    return Status::ok();
+}
+
+Status Credential::setReaderEphemeralPublicKey(const vector<uint8_t>& publicKey) {
+    Result result;
+    halBinder_->setReaderEphemeralPublicKey(publicKey,
+                                            [&](const Result& _result) { result = _result; });
+    if (result.code != ResultCode::OK) {
+        LOG(ERROR) << "setReaderEphemeralPublicKey failed() " << ((int)result.code) << ": "
+                   << result.message;
+        return halResultToGenericError(result);
+    }
+    return Status::ok();
+}
+
+Status Credential::setAvailableAuthenticationKeys(int32_t keyCount, int32_t maxUsesPerKey) {
+    data_->setAvailableAuthenticationKeys(keyCount, maxUsesPerKey);
+    if (!data_->saveToDisk()) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error saving data");
+    }
+    return Status::ok();
+}
+
+Status Credential::getAuthKeysNeedingCertification(vector<AuthKeyParcel>* _aidl_return) {
+    optional<vector<vector<uint8_t>>> keysNeedingCert =
+        data_->getAuthKeysNeedingCertification(halBinder_);
+    if (!keysNeedingCert) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error getting auth keys neededing certification");
+    }
+    vector<AuthKeyParcel> authKeyParcels;
+    for (const vector<uint8_t>& key : keysNeedingCert.value()) {
+        AuthKeyParcel authKeyParcel;
+        authKeyParcel.x509cert = key;
+        authKeyParcels.push_back(authKeyParcel);
+    }
+    if (!data_->saveToDisk()) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error saving data");
+    }
+    *_aidl_return = authKeyParcels;
+    return Status::ok();
+}
+
+Status Credential::storeStaticAuthenticationData(const AuthKeyParcel& authenticationKey,
+                                                 const vector<uint8_t>& staticAuthData) {
+    if (!data_->storeStaticAuthenticationData(authenticationKey.x509cert, staticAuthData)) {
+        return Status::fromServiceSpecificError(
+            ICredentialStore::ERROR_AUTHENTICATION_KEY_NOT_FOUND,
+            "Error finding authentication key to store static "
+            "authentication data for");
+    }
+    if (!data_->saveToDisk()) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error saving data");
+    }
+    return Status::ok();
+}
+
+Status Credential::getAuthenticationDataUsageCount(vector<int32_t>* _aidl_return) {
+    const vector<AuthKeyData>& authKeyDatas = data_->getAuthKeyDatas();
+    vector<int32_t> ret;
+    for (const AuthKeyData& authKeyData : authKeyDatas) {
+        ret.push_back(authKeyData.useCount);
+    }
+    *_aidl_return = ret;
+    return Status::ok();
+}
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
diff --git a/identity/Credential.h b/identity/Credential.h
new file mode 100644
index 0000000..356d75f
--- /dev/null
+++ b/identity/Credential.h
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_SECURITY_CREDENTIAL_H_
+#define SYSTEM_SECURITY_CREDENTIAL_H_
+
+#include <string>
+#include <vector>
+
+#include <android/security/identity/BnCredential.h>
+
+#include <android/hardware/identity/1.0/IIdentityCredentialStore.h>
+#include <android/hardware/identity/1.0/types.h>
+
+#include "CredentialData.h"
+
+namespace android {
+namespace security {
+namespace identity {
+
+using ::android::sp;
+using ::android::binder::Status;
+using ::std::string;
+using ::std::vector;
+
+using ::android::hardware::identity::V1_0::IIdentityCredential;
+using ::android::hardware::identity::V1_0::IIdentityCredentialStore;
+
+class Credential : public BnCredential {
+  public:
+    Credential(const string& dataPath, const string& credentialName);
+    ~Credential();
+
+    Status loadCredential(sp<IIdentityCredentialStore> halStoreBinder);
+
+    // ICredential overrides
+    Status createEphemeralKeyPair(vector<uint8_t>* _aidl_return) override;
+
+    Status setReaderEphemeralPublicKey(const vector<uint8_t>& publicKey) override;
+
+    Status deleteCredential(vector<uint8_t>* _aidl_return) override;
+
+    Status getCredentialKeyCertificateChain(vector<uint8_t>* _aidl_return) override;
+
+    Status selectAuthKey(bool allowUsingExhaustedKeys, int64_t* _aidl_return) override;
+
+    Status getEntries(const vector<uint8_t>& requestMessage,
+                      const vector<RequestNamespaceParcel>& requestNamespaces,
+                      const vector<uint8_t>& sessionTranscript,
+                      const vector<uint8_t>& readerSignature, bool allowUsingExhaustedKeys,
+                      GetEntriesResultParcel* _aidl_return) override;
+
+    Status setAvailableAuthenticationKeys(int32_t keyCount, int32_t maxUsesPerKey) override;
+    Status getAuthKeysNeedingCertification(vector<AuthKeyParcel>* _aidl_return) override;
+    Status storeStaticAuthenticationData(const AuthKeyParcel& authenticationKey,
+                                         const vector<uint8_t>& staticAuthData) override;
+    Status getAuthenticationDataUsageCount(vector<int32_t>* _aidl_return) override;
+
+  private:
+    string dataPath_;
+    string credentialName_;
+
+    const AuthKeyData* selectedAuthKey_ = nullptr;
+    uint64_t selectedChallenge_ = 0;
+
+    sp<CredentialData> data_;
+
+    sp<IIdentityCredential> halBinder_;
+};
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
+
+#endif  // SYSTEM_SECURITY_IDENTITY_CREDENTIAL_H_
diff --git a/identity/CredentialData.cpp b/identity/CredentialData.cpp
new file mode 100644
index 0000000..99dd04b
--- /dev/null
+++ b/identity/CredentialData.cpp
@@ -0,0 +1,568 @@
+/*
+ * 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 "CredentialData"
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include "CredentialData.h"
+#include "Util.h"
+
+namespace android {
+namespace security {
+namespace identity {
+
+using android::hardware::identity::V1_0::Result;
+using android::hardware::identity::V1_0::ResultCode;
+using std::optional;
+
+string CredentialData::calculateCredentialFileName(const string& dataPath, uid_t ownerUid,
+                                                   const string& name) {
+    return android::base::StringPrintf(
+        "%s/%d-%s", dataPath.c_str(), (int)ownerUid,
+        android::hardware::identity::support::encodeHex(name).c_str());
+}
+
+CredentialData::CredentialData(const string& dataPath, uid_t ownerUid, const string& name)
+    : dataPath_(dataPath), ownerUid_(ownerUid), name_(name), secureUserId_(0) {
+    fileName_ = calculateCredentialFileName(dataPath_, ownerUid_, name_);
+}
+
+void CredentialData::setSecureUserId(int64_t secureUserId) {
+    secureUserId_ = secureUserId;
+}
+
+void CredentialData::setCredentialData(const vector<uint8_t>& credentialData) {
+    credentialData_ = credentialData;
+}
+
+void CredentialData::setAttestationCertificate(const vector<uint8_t>& attestationCertificate) {
+    attestationCertificate_ = attestationCertificate;
+}
+
+void CredentialData::addSecureAccessControlProfile(
+    const SecureAccessControlProfile& secureAccessControlProfile) {
+    secureAccessControlProfiles_.push_back(secureAccessControlProfile);
+}
+
+void CredentialData::addEntryData(const string& namespaceName, const string& entryName,
+                                  const EntryData& data) {
+    idToEncryptedChunks_[namespaceName + ":" + entryName] = data;
+}
+
+bool CredentialData::saveToDisk() const {
+    cppbor::Map map;
+
+    map.add("secureUserId", secureUserId_);
+
+    map.add("credentialData", credentialData_);
+
+    map.add("attestationCertificate", attestationCertificate_);
+
+    cppbor::Array sacpArray;
+    for (const SecureAccessControlProfile& sacp : secureAccessControlProfiles_) {
+        cppbor::Array array;
+        array.add(sacp.id);
+        array.add((const vector<uint8_t>&)sacp.readerCertificate);
+        array.add(sacp.userAuthenticationRequired);
+        array.add(sacp.timeoutMillis);
+        array.add(sacp.secureUserId);
+        vector<uint8_t> mac = sacp.mac;
+        array.add(mac);
+        sacpArray.add(std::move(array));
+    }
+    map.add("secureAccessControlProfiles", std::move(sacpArray));
+
+    cppbor::Map encryptedBlobsMap;
+    for (auto const& [nsAndName, entryData] : idToEncryptedChunks_) {
+        cppbor::Array encryptedChunkArray;
+        for (const vector<uint8_t>& encryptedChunk : entryData.encryptedChunks) {
+            encryptedChunkArray.add(encryptedChunk);
+        }
+        cppbor::Array entryDataArray;
+        entryDataArray.add(entryData.size);
+        cppbor::Array idsArray;
+        for (uint16_t id : entryData.accessControlProfileIds) {
+            idsArray.add(id);
+        }
+        entryDataArray.add(std::move(idsArray));
+        entryDataArray.add(std::move(encryptedChunkArray));
+        encryptedBlobsMap.add(nsAndName, std::move(entryDataArray));
+    }
+    map.add("entryData", std::move(encryptedBlobsMap));
+    map.add("authKeyCount", keyCount_);
+    map.add("maxUsesPerAuthKey", maxUsesPerKey_);
+
+    cppbor::Array authKeyDatasArray;
+    for (const AuthKeyData& data : authKeyDatas_) {
+        cppbor::Array array;
+        array.add(data.certificate);
+        array.add(data.keyBlob);
+        array.add(data.staticAuthenticationData);
+        array.add(data.pendingCertificate);
+        array.add(data.pendingKeyBlob);
+        array.add(data.useCount);
+        authKeyDatasArray.add(std::move(array));
+    }
+    map.add("authKeyData", std::move(authKeyDatasArray));
+
+    vector<uint8_t> credentialData = map.encode();
+
+    return fileSetContents(fileName_, credentialData);
+}
+
+optional<SecureAccessControlProfile> parseSacp(const cppbor::Item& item) {
+    const cppbor::Array* array = item.asArray();
+    if (array == nullptr || array->size() < 6) {
+        LOG(ERROR) << "The SACP CBOR is not an array with at least six elements (size="
+                   << (array != nullptr ? array->size() : -1) << ")";
+        return {};
+    }
+    const cppbor::Int* itemId = ((*array)[0])->asInt();
+    const cppbor::Bstr* itemReaderCertificate = ((*array)[1])->asBstr();
+    const cppbor::Simple* simple = ((*array)[2])->asSimple();
+    const cppbor::Bool* itemUserAuthenticationRequired =
+        (simple != nullptr ? (simple->asBool()) : nullptr);
+    const cppbor::Int* itemTimeoutMillis = ((*array)[3])->asInt();
+    const cppbor::Int* itesecureUserId_ = ((*array)[4])->asInt();
+    const cppbor::Bstr* itemMac = ((*array)[5])->asBstr();
+    if (itemId == nullptr || itemReaderCertificate == nullptr ||
+        itemUserAuthenticationRequired == nullptr || itemTimeoutMillis == nullptr ||
+        itesecureUserId_ == nullptr || itemMac == nullptr) {
+        LOG(ERROR) << "One or more items SACP array in CBOR is of wrong type";
+        return {};
+    }
+    SecureAccessControlProfile sacp;
+    sacp.id = itemId->value();
+    sacp.readerCertificate = itemReaderCertificate->value();
+    sacp.userAuthenticationRequired = itemUserAuthenticationRequired->value();
+    sacp.timeoutMillis = itemTimeoutMillis->value();
+    sacp.secureUserId = itesecureUserId_->value();
+    sacp.mac = itemMac->value();
+    return sacp;
+}
+
+optional<AuthKeyData> parseAuthKeyData(const cppbor::Item& item) {
+    const cppbor::Array* array = item.asArray();
+    if (array == nullptr || array->size() < 6) {
+        LOG(ERROR) << "The AuthKeyData CBOR is not an array with at least six elements";
+        return {};
+    }
+    const cppbor::Bstr* itemCertificate = ((*array)[0])->asBstr();
+    const cppbor::Bstr* itemKeyBlob = ((*array)[1])->asBstr();
+    const cppbor::Bstr* itemStaticAuthenticationData = ((*array)[2])->asBstr();
+    const cppbor::Bstr* itemPendingCertificate = ((*array)[3])->asBstr();
+    const cppbor::Bstr* itemPendingKeyBlob = ((*array)[4])->asBstr();
+    const cppbor::Int* itemUseCount = ((*array)[5])->asInt();
+    if (itemCertificate == nullptr || itemKeyBlob == nullptr ||
+        itemStaticAuthenticationData == nullptr || itemPendingCertificate == nullptr ||
+        itemPendingKeyBlob == nullptr || itemUseCount == nullptr) {
+        LOG(ERROR) << "One or more items in AuthKeyData array in CBOR is of wrong type";
+        return {};
+    }
+    AuthKeyData authKeyData;
+    authKeyData.certificate = itemCertificate->value();
+    authKeyData.keyBlob = itemKeyBlob->value();
+    authKeyData.staticAuthenticationData = itemStaticAuthenticationData->value();
+    authKeyData.pendingCertificate = itemPendingCertificate->value();
+    authKeyData.pendingKeyBlob = itemPendingKeyBlob->value();
+    authKeyData.useCount = itemUseCount->value();
+    return authKeyData;
+}
+
+vector<uint16_t> parseAccessControlProfileIds(const cppbor::Item& item) {
+    const cppbor::Array* array = item.asArray();
+    if (array == nullptr) {
+        LOG(ERROR) << "The accessControlProfileIds member is not an array";
+        return {};
+    }
+
+    vector<uint16_t> accessControlProfileIds;
+    for (size_t n = 0; n < array->size(); n++) {
+        const cppbor::Int* itemInt = ((*array)[n])->asInt();
+        if (itemInt == nullptr) {
+            LOG(ERROR) << "An item in the accessControlProfileIds array is not a bstr";
+            return {};
+        }
+        accessControlProfileIds.push_back(itemInt->value());
+    }
+    return accessControlProfileIds;
+}
+
+optional<vector<vector<uint8_t>>> parseEncryptedChunks(const cppbor::Item& item) {
+    const cppbor::Array* array = item.asArray();
+    if (array == nullptr) {
+        LOG(ERROR) << "The encryptedChunks member is not an array";
+        return {};
+    }
+
+    vector<vector<uint8_t>> encryptedChunks;
+    for (size_t n = 0; n < array->size(); n++) {
+        const cppbor::Bstr* itemBstr = ((*array)[n])->asBstr();
+        if (itemBstr == nullptr) {
+            LOG(ERROR) << "An item in the encryptedChunks array is not a bstr";
+            return {};
+        }
+        encryptedChunks.push_back(itemBstr->value());
+    }
+    return encryptedChunks;
+}
+
+bool CredentialData::loadFromDisk() {
+
+    // Reset all data.
+    credentialData_.clear();
+    attestationCertificate_.clear();
+    secureAccessControlProfiles_.clear();
+    idToEncryptedChunks_.clear();
+    authKeyDatas_.clear();
+    keyCount_ = 0;
+    maxUsesPerKey_ = 1;
+
+    optional<vector<uint8_t>> data = fileGetContents(fileName_);
+    if (!data) {
+        LOG(ERROR) << "Error loading data";
+        return false;
+    }
+
+    auto [item, _ /* newPos */, message] = cppbor::parse(data.value());
+    if (item == nullptr) {
+        LOG(ERROR) << "Data loaded from " << fileName_ << " is not valid CBOR: " << message;
+        return false;
+    }
+
+    const cppbor::Map* map = item->asMap();
+    if (map == nullptr) {
+        LOG(ERROR) << "Top-level item is not a map";
+        return false;
+    }
+
+    for (size_t n = 0; n < map->size(); n++) {
+        auto [keyItem, valueItem] = (*map)[n];
+        const cppbor::Tstr* tstr = keyItem->asTstr();
+        if (tstr == nullptr) {
+            LOG(ERROR) << "Key item in top-level map is not a tstr";
+            return false;
+        }
+        const string& key = tstr->value();
+
+        if (key == "secureUserId") {
+            const cppbor::Int* number = valueItem->asInt();
+            if (number == nullptr) {
+                LOG(ERROR) << "Value for secureUserId is not a number";
+                return false;
+            }
+            secureUserId_ = number->value();
+        } else if (key == "credentialData") {
+            const cppbor::Bstr* valueBstr = valueItem->asBstr();
+            if (valueBstr == nullptr) {
+                LOG(ERROR) << "Value for credentialData is not a bstr";
+                return false;
+            }
+            credentialData_ = valueBstr->value();
+        } else if (key == "attestationCertificate") {
+            const cppbor::Bstr* valueBstr = valueItem->asBstr();
+            if (valueBstr == nullptr) {
+                LOG(ERROR) << "Value for attestationCertificate is not a bstr";
+                return false;
+            }
+            attestationCertificate_ = valueBstr->value();
+        } else if (key == "secureAccessControlProfiles") {
+            const cppbor::Array* array = valueItem->asArray();
+            if (array == nullptr) {
+                LOG(ERROR) << "Value for attestationCertificate is not an array";
+                return false;
+            }
+            for (size_t m = 0; m < array->size(); m++) {
+                const std::unique_ptr<cppbor::Item>& item = (*array)[m];
+                optional<SecureAccessControlProfile> sacp = parseSacp(*item);
+                if (!sacp) {
+                    LOG(ERROR) << "Error parsing SecureAccessControlProfile";
+                    return false;
+                }
+                secureAccessControlProfiles_.push_back(sacp.value());
+            }
+
+        } else if (key == "entryData") {
+            const cppbor::Map* map = valueItem->asMap();
+            if (map == nullptr) {
+                LOG(ERROR) << "Value for encryptedChunks is not an map";
+                return false;
+            }
+            for (size_t m = 0; m < map->size(); m++) {
+                auto [ecKeyItem, ecValueItem] = (*map)[m];
+                const cppbor::Tstr* ecTstr = ecKeyItem->asTstr();
+                if (ecTstr == nullptr) {
+                    LOG(ERROR) << "Key item in encryptedChunks map is not a tstr";
+                    return false;
+                }
+                const string& ecId = ecTstr->value();
+
+                const cppbor::Array* ecEntryArrayItem = ecValueItem->asArray();
+                if (ecEntryArrayItem == nullptr || ecEntryArrayItem->size() < 3) {
+                    LOG(ERROR) << "Value item in encryptedChunks map is an array with at least two "
+                                  "elements";
+                    return false;
+                }
+                const cppbor::Int* ecEntrySizeItem = (*ecEntryArrayItem)[0]->asInt();
+                if (ecEntrySizeItem == nullptr) {
+                    LOG(ERROR) << "Entry size not a number";
+                    return false;
+                }
+                uint64_t entrySize = ecEntrySizeItem->value();
+
+                optional<vector<uint16_t>> accessControlProfileIds =
+                    parseAccessControlProfileIds(*(*ecEntryArrayItem)[1]);
+                if (!accessControlProfileIds) {
+                    LOG(ERROR) << "Error parsing access control profile ids";
+                    return false;
+                }
+
+                optional<vector<vector<uint8_t>>> encryptedChunks =
+                    parseEncryptedChunks(*(*ecEntryArrayItem)[2]);
+                if (!encryptedChunks) {
+                    LOG(ERROR) << "Error parsing encrypted chunks";
+                    return false;
+                }
+
+                EntryData data;
+                data.size = entrySize;
+                data.accessControlProfileIds = accessControlProfileIds.value();
+                data.encryptedChunks = encryptedChunks.value();
+                idToEncryptedChunks_[ecId] = data;
+            }
+
+        } else if (key == "authKeyData") {
+            const cppbor::Array* array = valueItem->asArray();
+            if (array == nullptr) {
+                LOG(ERROR) << "Value for authData is not an array";
+                return false;
+            }
+            for (size_t m = 0; m < array->size(); m++) {
+                const std::unique_ptr<cppbor::Item>& item = (*array)[m];
+                optional<AuthKeyData> authKeyData = parseAuthKeyData(*item);
+                if (!authKeyData) {
+                    LOG(ERROR) << "Error parsing AuthKeyData";
+                    return false;
+                }
+                authKeyDatas_.push_back(authKeyData.value());
+            }
+
+        } else if (key == "authKeyCount") {
+            const cppbor::Int* number = valueItem->asInt();
+            if (number == nullptr) {
+                LOG(ERROR) << "Value for authKeyCount is not a number";
+                return false;
+            }
+            keyCount_ = number->value();
+
+        } else if (key == "maxUsesPerAuthKey") {
+            const cppbor::Int* number = valueItem->asInt();
+            if (number == nullptr) {
+                LOG(ERROR) << "Value for maxUsesPerAuthKey is not a number";
+                return false;
+            }
+            maxUsesPerKey_ = number->value();
+        }
+    }
+
+    if (credentialData_.size() == 0 || attestationCertificate_.size() == 0) {
+        LOG(ERROR) << "Missing credentialData or attestationCertificate";
+        return false;
+    }
+
+    if (size_t(keyCount_) != authKeyDatas_.size()) {
+        LOG(ERROR) << "keyCount_=" << keyCount_
+                   << " != authKeyDatas_.size()=" << authKeyDatas_.size();
+        return false;
+    }
+
+    return true;
+}
+
+const vector<uint8_t>& CredentialData::getCredentialData() const {
+    return credentialData_;
+}
+
+int64_t CredentialData::getSecureUserId() {
+    return secureUserId_;
+}
+
+const vector<uint8_t>& CredentialData::getAttestationCertificate() const {
+    return attestationCertificate_;
+}
+
+const vector<SecureAccessControlProfile>& CredentialData::getSecureAccessControlProfiles() const {
+    return secureAccessControlProfiles_;
+}
+
+bool CredentialData::hasEntryData(const string& namespaceName, const string& entryName) const {
+    string id = namespaceName + ":" + entryName;
+    auto iter = idToEncryptedChunks_.find(id);
+    if (iter == idToEncryptedChunks_.end()) {
+        return false;
+    }
+    return true;
+}
+
+optional<EntryData> CredentialData::getEntryData(const string& namespaceName,
+                                                 const string& entryName) const {
+    string id = namespaceName + ":" + entryName;
+    auto iter = idToEncryptedChunks_.find(id);
+    if (iter == idToEncryptedChunks_.end()) {
+        return {};
+    }
+    return iter->second;
+}
+
+bool CredentialData::deleteCredential() {
+    if (unlink(fileName_.c_str()) != 0) {
+        PLOG(ERROR) << "Error deleting " << fileName_;
+        return false;
+    }
+    return true;
+}
+
+optional<bool> CredentialData::credentialExists(const string& dataPath, uid_t ownerUid,
+                                                const string& name) {
+    struct stat statbuf;
+    string filename = calculateCredentialFileName(dataPath, ownerUid, name);
+    if (stat(filename.c_str(), &statbuf) != 0) {
+        if (errno == ENOENT) {
+            return false;
+        }
+        PLOG(ERROR) << "Error getting information about " << filename;
+        return {};
+    }
+    return true;
+}
+
+// ---
+
+void CredentialData::setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey) {
+    keyCount_ = keyCount;
+    maxUsesPerKey_ = maxUsesPerKey;
+
+    // If growing the number of auth keys (prevKeyCount < keyCount_ case) we'll add
+    // new AuthKeyData structs to |authKeyDatas_| and each struct will have empty |certificate|
+    // and |pendingCertificate| fields. Those will be filled out when the
+    // getAuthKeysNeedingCertification() is called.
+    //
+    // If shrinking, we'll just delete the AuthKeyData structs at the end. There's nothing
+    // else to do, the HAL doesn't need to know we're nuking these authentication keys.
+    //
+    // Therefore, in either case it's as simple as just resizing the vector.
+    authKeyDatas_.resize(keyCount_);
+}
+
+const vector<AuthKeyData>& CredentialData::getAuthKeyDatas() const {
+    return authKeyDatas_;
+}
+
+const AuthKeyData* CredentialData::selectAuthKey(bool allowUsingExhaustedKeys) {
+    AuthKeyData* candidate = nullptr;
+
+    int n = 0;
+    int candidateNum = -1;
+    for (AuthKeyData& data : authKeyDatas_) {
+        if (data.certificate.size() != 0) {
+            if (candidate == nullptr || data.useCount < candidate->useCount) {
+                candidate = &data;
+                candidateNum = n;
+            }
+        }
+        n++;
+    }
+
+    if (candidate == nullptr) {
+        return nullptr;
+    }
+
+    if (candidate->useCount >= maxUsesPerKey_ && !allowUsingExhaustedKeys) {
+        return nullptr;
+    }
+
+    candidate->useCount += 1;
+    return candidate;
+}
+
+optional<vector<vector<uint8_t>>> CredentialData::getAuthKeysNeedingCertification(
+    const sp<android::hardware::identity::V1_0::IIdentityCredential>& halBinder) {
+
+    vector<vector<uint8_t>> keysNeedingCert;
+
+    for (AuthKeyData& data : authKeyDatas_) {
+        bool newKeyNeeded = (data.certificate.size() == 0) || (data.useCount >= maxUsesPerKey_);
+        bool certificationPending = (data.pendingCertificate.size() > 0);
+        if (newKeyNeeded && !certificationPending) {
+            Result result;
+            vector<uint8_t> signingKeyBlob;
+            vector<uint8_t> signingKeyCertificate;
+            halBinder->generateSigningKeyPair(
+                [&](const Result& _result,
+                    const android::hardware::hidl_vec<uint8_t> _signingKeyBlob,
+                    const android::hardware::hidl_vec<uint8_t> _signingKeyCertificate) {
+                    result = _result;
+                    signingKeyBlob = _signingKeyBlob;
+                    signingKeyCertificate = _signingKeyCertificate;
+                });
+            if (result.code != ResultCode::OK) {
+                LOG(ERROR) << "Error generating signing key-pair";
+                return {};
+            }
+            data.pendingCertificate = signingKeyCertificate;
+            data.pendingKeyBlob = signingKeyBlob;
+            certificationPending = true;
+        }
+
+        if (certificationPending) {
+            keysNeedingCert.push_back(data.pendingCertificate);
+        }
+    }
+    return keysNeedingCert;
+}
+
+bool CredentialData::storeStaticAuthenticationData(const vector<uint8_t>& authenticationKey,
+                                                   const vector<uint8_t>& staticAuthData) {
+    for (AuthKeyData& data : authKeyDatas_) {
+        if (data.pendingCertificate == authenticationKey) {
+            data.certificate = data.pendingCertificate;
+            data.keyBlob = data.pendingKeyBlob;
+            data.staticAuthenticationData = staticAuthData;
+            data.pendingCertificate.clear();
+            data.pendingKeyBlob.clear();
+            data.useCount = 0;
+            return true;
+        }
+    }
+    return false;
+}
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
diff --git a/identity/CredentialData.h b/identity/CredentialData.h
new file mode 100644
index 0000000..39e41f8
--- /dev/null
+++ b/identity/CredentialData.h
@@ -0,0 +1,144 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_SECURITY_CREDENTIAL_DATA_H_
+#define SYSTEM_SECURITY_CREDENTIAL_DATA_H_
+
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <android/hardware/identity/1.0/IIdentityCredential.h>
+#include <android/hardware/identity/1.0/types.h>
+
+namespace android {
+namespace security {
+namespace identity {
+
+using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
+using ::std::map;
+using ::std::optional;
+using ::std::pair;
+using ::std::string;
+using ::std::tuple;
+using ::std::vector;
+
+struct EntryData {
+    EntryData() {}
+
+    uint64_t size = 0;
+    vector<uint16_t> accessControlProfileIds;
+    vector<vector<uint8_t>> encryptedChunks;
+};
+
+struct AuthKeyData {
+    AuthKeyData() {}
+
+    vector<uint8_t> certificate;
+    vector<uint8_t> keyBlob;
+    vector<uint8_t> staticAuthenticationData;
+    vector<uint8_t> pendingCertificate;
+    vector<uint8_t> pendingKeyBlob;
+    int useCount = 0;
+};
+
+class CredentialData : public RefBase {
+  public:
+    CredentialData(const string& dataPath, uid_t ownerUid, const string& name);
+
+    static string calculateCredentialFileName(const string& dataPath, uid_t ownerUid,
+                                              const string& name);
+
+    static optional<bool> credentialExists(const string& dataPath, uid_t ownerUid,
+                                           const string& name);
+
+    void setSecureUserId(int64_t secureUserId);
+
+    void setCredentialData(const vector<uint8_t>& credentialData);
+
+    void setAttestationCertificate(const vector<uint8_t>& attestationCertificate);
+
+    void
+    addSecureAccessControlProfile(const SecureAccessControlProfile& secureAccessControlProfile);
+
+    void addEntryData(const string& namespaceName, const string& entryName, const EntryData& data);
+
+    bool saveToDisk() const;
+
+    bool loadFromDisk();
+
+    bool deleteCredential();
+
+    void setAvailableAuthenticationKeys(int keyCount, int maxUsesPerKey);
+
+    // Getters
+
+    int64_t getSecureUserId();
+
+    const vector<uint8_t>& getCredentialData() const;
+
+    const vector<uint8_t>& getAttestationCertificate() const;
+
+    const vector<SecureAccessControlProfile>& getSecureAccessControlProfiles() const;
+
+    bool hasEntryData(const string& namespaceName, const string& entryName) const;
+
+    optional<EntryData> getEntryData(const string& namespaceName, const string& entryName) const;
+
+    const vector<AuthKeyData>& getAuthKeyDatas() const;
+
+    // Returns |nullptr| if a suitable key cannot be found. Otherwise returns
+    // the authentication and increases its use-count.
+    const AuthKeyData* selectAuthKey(bool allowUsingExhaustedKeys);
+
+    optional<vector<vector<uint8_t>>> getAuthKeysNeedingCertification(
+        const sp<android::hardware::identity::V1_0::IIdentityCredential>& halBinder);
+
+    bool storeStaticAuthenticationData(const vector<uint8_t>& authenticationKey,
+                                       const vector<uint8_t>& staticAuthData);
+
+  private:
+    // Set by constructor.
+    //
+    string dataPath_;
+    uid_t ownerUid_;
+    string name_;
+
+    // Calculated at construction time, from |dataPath_|, |ownerUid_|, |name_|.
+    string fileName_;
+
+    // Data serialized in CBOR from here:
+    //
+    int64_t secureUserId_;
+    vector<uint8_t> credentialData_;
+    vector<uint8_t> attestationCertificate_;
+    vector<SecureAccessControlProfile> secureAccessControlProfiles_;
+    map<string, EntryData> idToEncryptedChunks_;
+
+    int keyCount_ = 0;
+    int maxUsesPerKey_ = 1;
+    vector<AuthKeyData> authKeyDatas_;  // Always |keyCount_| long.
+};
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
+
+#endif  // SYSTEM_SECURITY_CREDENTIAL_DATA_H_
diff --git a/identity/CredentialStore.cpp b/identity/CredentialStore.cpp
new file mode 100644
index 0000000..b13a7b0
--- /dev/null
+++ b/identity/CredentialStore.cpp
@@ -0,0 +1,161 @@
+/*
+ * 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 "CredentialStore"
+
+#include <algorithm>
+
+#include <android-base/logging.h>
+
+#include <binder/IPCThreadState.h>
+
+#include "Credential.h"
+#include "CredentialStore.h"
+#include "Util.h"
+#include "WritableCredential.h"
+
+namespace android {
+namespace security {
+namespace identity {
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::identity::V1_0::Result;
+using ::android::hardware::identity::V1_0::ResultCode;
+
+using ::android::hardware::identity::V1_0::IWritableIdentityCredential;
+
+CredentialStore::CredentialStore(const std::string& dataPath, sp<IIdentityCredentialStore> hal)
+    : dataPath_(dataPath), hal_(hal) {}
+
+bool CredentialStore::init() {
+    Result result;
+    hal_->getHardwareInformation([&](const Result& _result, const hidl_string& credentialStoreName,
+                                     const hidl_string& credentialStoreAuthorName,
+                                     uint32_t _dataChunkSize, bool _isDirectAccess,
+                                     const hidl_vec<hidl_string>& _supportedDocTypes) {
+        result = _result;
+        dataChunkSize_ = _dataChunkSize;
+        isDirectAccess_ = _isDirectAccess;
+        supportedDocTypes_.clear();
+        for (auto& docType : _supportedDocTypes) {
+            supportedDocTypes_.push_back(docType);
+        }
+        LOG(INFO) << "Connected to Identity Credential HAL with name '" << credentialStoreName
+                  << "' authored by '" << credentialStoreAuthorName << "' with chunk size "
+                  << _dataChunkSize << " and directoAccess set to "
+                  << (_isDirectAccess ? "true" : "false");
+    });
+    if (result.code != ResultCode::OK) {
+        LOG(ERROR) << "Error getting hardware information: " << (int)result.code << ": "
+                   << result.message;
+        return false;
+    }
+    return true;
+}
+
+CredentialStore::~CredentialStore() {}
+
+Status CredentialStore::getSecurityHardwareInfo(SecurityHardwareInfoParcel* _aidl_return) {
+    SecurityHardwareInfoParcel info;
+    info.directAccess = isDirectAccess_;
+    info.supportedDocTypes = supportedDocTypes_;
+    *_aidl_return = info;
+    return Status::ok();
+};
+
+Status CredentialStore::createCredential(const std::string& credentialName,
+                                         const std::string& docType,
+                                         sp<IWritableCredential>* _aidl_return) {
+    uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
+    optional<bool> credentialExists =
+        CredentialData::credentialExists(dataPath_, callingUid, credentialName);
+    if (!credentialExists.has_value()) {
+        return Status::fromServiceSpecificError(
+            ERROR_GENERIC, "Error determining if credential with given name exists");
+    }
+    if (credentialExists.value()) {
+        return Status::fromServiceSpecificError(ERROR_ALREADY_PERSONALIZED,
+                                                "Credential with given name already exists");
+    }
+
+    if (supportedDocTypes_.size() > 0) {
+        if (std::find(supportedDocTypes_.begin(), supportedDocTypes_.end(), docType) ==
+            supportedDocTypes_.end()) {
+            return Status::fromServiceSpecificError(ERROR_DOCUMENT_TYPE_NOT_SUPPORTED,
+                                                    "No support for given document type");
+        }
+    }
+
+    Result result;
+    sp<IWritableIdentityCredential> halWritableCredential;
+    hal_->createCredential(
+        docType, false,
+        [&](const Result& _result, const sp<IWritableIdentityCredential>& _halWritableCredential) {
+            result = _result;
+            halWritableCredential = _halWritableCredential;
+        });
+    if (result.code != ResultCode::OK) {
+        return halResultToGenericError(result);
+    }
+
+    sp<IWritableCredential> writableCredential = new WritableCredential(
+        dataPath_, credentialName, docType, dataChunkSize_, halWritableCredential);
+    *_aidl_return = writableCredential;
+    return Status::ok();
+}
+
+// Keep in sync with IdentityCredentialStore.java
+//
+
+const int CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 = 1;
+
+Status CredentialStore::getCredentialByName(const std::string& credentialName, int32_t cipherSuite,
+                                            sp<ICredential>* _aidl_return) {
+    *_aidl_return = nullptr;
+
+    uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
+    optional<bool> credentialExists =
+        CredentialData::credentialExists(dataPath_, callingUid, credentialName);
+    if (!credentialExists.has_value()) {
+        return Status::fromServiceSpecificError(
+            ERROR_GENERIC, "Error determining if credential with given name exists");
+    }
+    if (!credentialExists.value()) {
+        return Status::fromServiceSpecificError(ERROR_NO_SUCH_CREDENTIAL,
+                                                "Credential with given name doesn't exist");
+    }
+
+    // We only support a single cipher-suite right now.
+    if (cipherSuite != CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256) {
+        return Status::fromServiceSpecificError(ERROR_CIPHER_SUITE_NOT_SUPPORTED,
+                                                "Cipher suite not supported");
+    }
+
+    sp<Credential> credential = new Credential(dataPath_, credentialName);
+
+    Status loadStatus = credential->loadCredential(hal_);
+    if (!loadStatus.isOk()) {
+        LOG(ERROR) << "Error loading credential";
+    } else {
+        *_aidl_return = credential;
+    }
+    return loadStatus;
+}
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
diff --git a/identity/CredentialStore.h b/identity/CredentialStore.h
new file mode 100644
index 0000000..8d679a2
--- /dev/null
+++ b/identity/CredentialStore.h
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_SECURITY_CREDENTIAL_STORE_H_
+#define SYSTEM_SECURITY_CREDENTIAL_STORE_H_
+
+#include <string>
+#include <vector>
+
+#include <android/hardware/identity/1.0/IIdentityCredentialStore.h>
+#include <android/hardware/identity/1.0/types.h>
+
+#include <android/security/identity/BnCredentialStore.h>
+
+namespace android {
+namespace security {
+namespace identity {
+
+using ::android::sp;
+using ::android::binder::Status;
+using ::std::string;
+using ::std::unique_ptr;
+using ::std::vector;
+
+using ::android::hardware::identity::V1_0::IIdentityCredentialStore;
+
+class CredentialStore : public BnCredentialStore {
+  public:
+    CredentialStore(const string& dataPath, sp<IIdentityCredentialStore> hal);
+    ~CredentialStore();
+
+    bool init();
+
+    // ICredentialStore overrides
+    Status getSecurityHardwareInfo(SecurityHardwareInfoParcel* _aidl_return) override;
+
+    Status createCredential(const string& credentialName, const string& docType,
+                            sp<IWritableCredential>* _aidl_return) override;
+
+    Status getCredentialByName(const string& credentialName, int32_t cipherSuite,
+                               sp<ICredential>* _aidl_return) override;
+
+  private:
+    string dataPath_;
+
+    sp<IIdentityCredentialStore> hal_;
+
+    bool isDirectAccess_;
+    vector<string> supportedDocTypes_;
+    size_t dataChunkSize_;
+};
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
+
+#endif  // SYSTEM_SECURITY_CREDENTIAL_STORE_H_
diff --git a/identity/CredentialStoreFactory.cpp b/identity/CredentialStoreFactory.cpp
new file mode 100644
index 0000000..947adf3
--- /dev/null
+++ b/identity/CredentialStoreFactory.cpp
@@ -0,0 +1,91 @@
+/*
+ * 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 "CredentialStoreFactory"
+
+#include <android-base/logging.h>
+
+#include <binder/IPCThreadState.h>
+
+#include "CredentialStore.h"
+#include "CredentialStoreFactory.h"
+
+namespace android {
+namespace security {
+namespace identity {
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::identity::V1_0::IIdentityCredentialStore;
+using ::android::hardware::identity::V1_0::Result;
+using ::android::hardware::identity::V1_0::ResultCode;
+
+CredentialStoreFactory::CredentialStoreFactory(const std::string& dataPath) : dataPath_(dataPath) {}
+
+CredentialStoreFactory::~CredentialStoreFactory() {}
+
+CredentialStore* CredentialStoreFactory::createCredentialStore(const string& serviceName) {
+    sp<IIdentityCredentialStore> hal = IIdentityCredentialStore::tryGetService(serviceName);
+    if (hal.get() == nullptr) {
+        LOG(ERROR) << "Error get hal for store with service name '" << serviceName << "'";
+        return nullptr;
+    }
+
+    CredentialStore* store = new CredentialStore(dataPath_, hal);
+    if (!store->init()) {
+        LOG(ERROR) << "Error initializing CredentialStore with service name '" << serviceName
+                   << "'";
+        delete store;
+        return nullptr;
+    }
+
+    return store;
+}
+
+Status CredentialStoreFactory::getCredentialStore(int32_t credentialStoreType,
+                                                  sp<ICredentialStore>* _aidl_return) {
+    switch (credentialStoreType) {
+    case CREDENTIAL_STORE_TYPE_DEFAULT:
+        if (defaultStore_.get() == nullptr) {
+            defaultStore_ = createCredentialStore("default");
+        }
+        if (defaultStore_.get() == nullptr) {
+            return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                    "Error creating default store");
+        }
+        *_aidl_return = defaultStore_.get();
+        return Status::ok();
+
+    case CREDENTIAL_STORE_TYPE_DIRECT_ACCESS:
+        if (directAccessStore_.get() == nullptr) {
+            directAccessStore_ = createCredentialStore("directAccess");
+        }
+        if (directAccessStore_.get() == nullptr) {
+            return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                    "Error creating direct access store");
+        }
+        *_aidl_return = directAccessStore_.get();
+        return Status::ok();
+        break;
+    }
+
+    return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                            "Unknown credential store type");
+}
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
diff --git a/identity/CredentialStoreFactory.h b/identity/CredentialStoreFactory.h
new file mode 100644
index 0000000..3aef618
--- /dev/null
+++ b/identity/CredentialStoreFactory.h
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_SECURITY_CREDENTIAL_STORE_FACTORY_H_
+#define SYSTEM_SECURITY_CREDENTIAL_STORE_FACTORY_H_
+
+#include <android/security/identity/BnCredentialStoreFactory.h>
+
+#include "CredentialStore.h"
+
+namespace android {
+namespace security {
+namespace identity {
+
+using ::android::sp;
+using ::android::binder::Status;
+using ::std::string;
+
+class CredentialStoreFactory : public BnCredentialStoreFactory {
+  public:
+    explicit CredentialStoreFactory(const string& dataPath);
+    ~CredentialStoreFactory();
+
+    Status getCredentialStore(int32_t credentialStoreType,
+                              sp<ICredentialStore>* _aidl_return) override;
+
+  private:
+    CredentialStore* createCredentialStore(const string& serviceName);
+
+    string dataPath_;
+
+    sp<CredentialStore> defaultStore_;
+    sp<CredentialStore> directAccessStore_;
+};
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
+
+#endif  // SYSTEM_SECURITY_CREDENTIAL_STORE_FACTORY_H_
diff --git a/identity/Util.cpp b/identity/Util.cpp
new file mode 100644
index 0000000..c397913
--- /dev/null
+++ b/identity/Util.cpp
@@ -0,0 +1,125 @@
+/*
+ * 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 "Util"
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+#include <android/security/identity/ICredentialStore.h>
+
+#include "Util.h"
+
+namespace android {
+namespace security {
+namespace identity {
+
+using ::android::base::StringPrintf;
+
+Status halResultToGenericError(const Result& result) {
+    string message =
+        StringPrintf("HAL failed with code %d: %s", int(result.code), result.message.c_str());
+    return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC, message.c_str());
+}
+
+optional<vector<uint8_t>> fileGetContents(const string& path) {
+    int fd = open(path.c_str(), O_RDONLY);
+    if (fd == -1) {
+        PLOG(ERROR) << "Error opening " << path;
+        return {};
+    }
+
+    struct stat statbuf;
+    if (fstat(fd, &statbuf) != 0) {
+        PLOG(ERROR) << "Error statting " << path;
+        close(fd);
+        return {};
+    }
+    vector<uint8_t> data;
+    data.resize(statbuf.st_size);
+
+    uint8_t* p = data.data();
+    size_t remaining = data.size();
+    while (remaining > 0) {
+        size_t numRead = TEMP_FAILURE_RETRY(read(fd, p, remaining));
+        if (numRead <= 0) {
+            PLOG(ERROR) << "Failed reading from '" << path << "'";
+            close(fd);
+            return {};
+        }
+        p += numRead;
+        remaining -= numRead;
+    }
+    close(fd);
+
+    return data;
+}
+
+bool fileSetContents(const string& path, const vector<uint8_t>& data) {
+    char tempName[4096];
+    int fd;
+
+    string tempNameStr = path + ".XXXXXX";
+    if (tempNameStr.size() >= sizeof tempName - 1) {
+        LOG(ERROR) << "Path name too long";
+        return false;
+    }
+    strncpy(tempName, tempNameStr.c_str(), sizeof tempName);
+
+    fd = mkstemp(tempName);
+    if (fd == -1) {
+        PLOG(ERROR) << "Error creating temp file for '" << path << "'";
+        return false;
+    }
+
+    const uint8_t* p = data.data();
+    size_t remaining = data.size();
+    while (remaining > 0) {
+        size_t numWritten = TEMP_FAILURE_RETRY(write(fd, p, remaining));
+        if (numWritten <= 0) {
+            PLOG(ERROR) << "Failed writing into temp file for '" << path << "'";
+            close(fd);
+            return false;
+        }
+        p += numWritten;
+        remaining -= numWritten;
+    }
+
+    if (TEMP_FAILURE_RETRY(fsync(fd) == -1)) {
+        PLOG(ERROR) << "Failed fsyncing temp file for '" << path << "'";
+        close(fd);
+        return false;
+    }
+    close(fd);
+
+    if (rename(tempName, path.c_str()) != 0) {
+        PLOG(ERROR) << "Error renaming temp file for '" << path << "'";
+        close(fd);
+        return false;
+    }
+
+    return true;
+}
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
diff --git a/identity/Util.h b/identity/Util.h
new file mode 100644
index 0000000..bb0e275
--- /dev/null
+++ b/identity/Util.h
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_SECURITY_IDENTITY_UTIL_H_
+#define SYSTEM_SECURITY_IDENTITY_UTIL_H_
+
+#include <string>
+#include <vector>
+
+#include <android/hardware/identity/1.0/IIdentityCredentialStore.h>
+#include <android/hardware/identity/1.0/types.h>
+#include <binder/Status.h>
+
+namespace android {
+namespace security {
+namespace identity {
+
+using ::std::optional;
+using ::std::string;
+using ::std::vector;
+
+using ::android::binder::Status;
+using ::android::hardware::identity::V1_0::Result;
+
+Status halResultToGenericError(const Result& result);
+
+// Helper function to atomically write |data| into file at |path|.
+//
+// Returns true on success, false on error.
+//
+bool fileSetContents(const string& path, const vector<uint8_t>& data);
+
+// Helper function which reads contents offile at |path| into |data|.
+//
+// Returns nothing on error, the content on success.
+//
+optional<vector<uint8_t>> fileGetContents(const string& path);
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
+
+#endif  // SYSTEM_SECURITY_IDENTITY_UTIL_H_
diff --git a/identity/WritableCredential.cpp b/identity/WritableCredential.cpp
new file mode 100644
index 0000000..f58ec16
--- /dev/null
+++ b/identity/WritableCredential.cpp
@@ -0,0 +1,192 @@
+/*
+ * 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 "WritableCredential"
+
+#include <android-base/logging.h>
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <android/security/identity/ICredentialStore.h>
+
+#include <binder/IPCThreadState.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+#include "CredentialData.h"
+#include "Util.h"
+#include "WritableCredential.h"
+
+namespace android {
+namespace security {
+namespace identity {
+
+using ::std::pair;
+
+using ::android::hardware::hidl_vec;
+
+using ::android::hardware::identity::V1_0::Result;
+using ::android::hardware::identity::V1_0::ResultCode;
+using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
+
+using ::android::hardware::identity::support::chunkVector;
+
+WritableCredential::WritableCredential(const string& dataPath, const string& credentialName,
+                                       const string& /*docType*/, size_t dataChunkSize,
+                                       sp<IWritableIdentityCredential> halBinder)
+    : dataPath_(dataPath), credentialName_(credentialName), dataChunkSize_(dataChunkSize),
+      halBinder_(halBinder) {}
+
+WritableCredential::~WritableCredential() {}
+
+Status WritableCredential::ensureAttestationCertificateExists(const vector<uint8_t>& challenge) {
+    vector<uint8_t> attestationCertificate;
+
+    if (!attestationCertificate_.empty()) {
+        return Status::ok();
+    }
+
+    Result result;
+    halBinder_->getAttestationCertificate(
+        challenge, [&](const Result& _result, const hidl_vec<uint8_t>& _attestationCertificate) {
+            result = _result;
+            attestationCertificate = _attestationCertificate;
+        });
+    if (result.code != ResultCode::OK) {
+        LOG(ERROR) << "Error calling getAttestationCertificate()";
+        return halResultToGenericError(result);
+    }
+    attestationCertificate_ = attestationCertificate;
+    return Status::ok();
+}
+
+Status WritableCredential::getCredentialKeyCertificateChain(const vector<uint8_t>& challenge,
+                                                            vector<uint8_t>* _aidl_return) {
+
+    Status ensureStatus = ensureAttestationCertificateExists(challenge);
+    if (!ensureStatus.isOk()) {
+        return ensureStatus;
+    }
+
+    *_aidl_return = attestationCertificate_;
+    return Status::ok();
+}
+
+Status
+WritableCredential::personalize(const vector<AccessControlProfileParcel>& accessControlProfiles,
+                                const vector<EntryNamespaceParcel>& entryNamespaces,
+                                int64_t secureUserId, vector<uint8_t>* _aidl_return) {
+    Status ensureStatus = ensureAttestationCertificateExists({});
+    if (!ensureStatus.isOk()) {
+        return ensureStatus;
+    }
+
+    uid_t callingUid = android::IPCThreadState::self()->getCallingUid();
+    CredentialData data = CredentialData(dataPath_, callingUid, credentialName_);
+
+    // Note: The value 0 is used to convey that no user-authentication is needed for this
+    // credential. This is to allow creating credentials w/o user authentication on devices
+    // where Secure lock screen is not enabled.
+    data.setSecureUserId(secureUserId);
+
+    data.setAttestationCertificate(attestationCertificate_);
+
+    vector<uint16_t> entryCounts;
+    for (const EntryNamespaceParcel& ensParcel : entryNamespaces) {
+        entryCounts.push_back(ensParcel.entries.size());
+    }
+
+    Result result;
+    halBinder_->startPersonalization(accessControlProfiles.size(), entryCounts,
+                                     [&](const Result& _result) { result = _result; });
+    if (result.code != ResultCode::OK) {
+        return halResultToGenericError(result);
+    }
+
+    for (const AccessControlProfileParcel& acpParcel : accessControlProfiles) {
+        halBinder_->addAccessControlProfile(
+            acpParcel.id, acpParcel.readerCertificate, acpParcel.userAuthenticationRequired,
+            acpParcel.userAuthenticationTimeoutMillis, secureUserId,
+            [&](const Result& _result, const SecureAccessControlProfile& profile) {
+                data.addSecureAccessControlProfile(profile);
+                result = _result;
+            });
+        if (result.code != ResultCode::OK) {
+            return halResultToGenericError(result);
+        }
+    }
+
+    for (const EntryNamespaceParcel& ensParcel : entryNamespaces) {
+        for (const EntryParcel& eParcel : ensParcel.entries) {
+            vector<vector<uint8_t>> chunks = chunkVector(eParcel.value, dataChunkSize_);
+
+            vector<uint16_t> ids;
+            std::copy(eParcel.accessControlProfileIds.begin(),
+                      eParcel.accessControlProfileIds.end(), std::back_inserter(ids));
+
+            halBinder_->beginAddEntry(ids, ensParcel.namespaceName, eParcel.name,
+                                      eParcel.value.size(),
+                                      [&](const Result& _result) { result = _result; });
+            if (result.code != ResultCode::OK) {
+                return halResultToGenericError(result);
+            }
+
+            vector<vector<uint8_t>> encryptedChunks;
+            for (const auto& chunk : chunks) {
+                halBinder_->addEntryValue(
+                    chunk, [&](const Result& _result, const hidl_vec<uint8_t>& encryptedContent) {
+                        result = _result;
+                        encryptedChunks.push_back(encryptedContent);
+                    });
+                if (result.code != ResultCode::OK) {
+                    return halResultToGenericError(result);
+                }
+            }
+            EntryData eData;
+            eData.size = eParcel.value.size();
+            eData.accessControlProfileIds = std::move(ids);
+            eData.encryptedChunks = std::move(encryptedChunks);
+            data.addEntryData(ensParcel.namespaceName, eParcel.name, eData);
+        }
+    }
+
+    vector<uint8_t> credentialData;
+    vector<uint8_t> proofOfProvisioningSignature;
+    halBinder_->finishAddingEntries([&](const Result& _result,
+                                        const hidl_vec<uint8_t>& _credentialData,
+                                        const hidl_vec<uint8_t>& _proofOfProvisioningSignature) {
+        data.setCredentialData(_credentialData);
+        result = _result;
+        credentialData = _credentialData;
+        proofOfProvisioningSignature = _proofOfProvisioningSignature;
+    });
+    if (result.code != ResultCode::OK) {
+        return halResultToGenericError(result);
+    }
+
+    if (!data.saveToDisk()) {
+        return Status::fromServiceSpecificError(ICredentialStore::ERROR_GENERIC,
+                                                "Error saving credential data to disk");
+    }
+
+    *_aidl_return = proofOfProvisioningSignature;
+    return Status::ok();
+}
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
diff --git a/identity/WritableCredential.h b/identity/WritableCredential.h
new file mode 100644
index 0000000..47987ce
--- /dev/null
+++ b/identity/WritableCredential.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+#ifndef SYSTEM_SECURITY_WRITABLE_CREDENTIAL_H_
+#define SYSTEM_SECURITY_WRITABLE_CREDENTIAL_H_
+
+#include <string>
+#include <vector>
+
+#include <android/security/identity/BnWritableCredential.h>
+
+#include <android/hardware/identity/1.0/IIdentityCredentialStore.h>
+#include <android/hardware/identity/1.0/types.h>
+
+namespace android {
+namespace security {
+namespace identity {
+
+using ::android::binder::Status;
+using ::android::hardware::identity::V1_0::IWritableIdentityCredential;
+using ::std::string;
+using ::std::vector;
+
+class WritableCredential : public BnWritableCredential {
+  public:
+    WritableCredential(const string& dataPath, const string& credentialName, const string& docType,
+                       size_t dataChunkSize, sp<IWritableIdentityCredential> halBinder);
+    ~WritableCredential();
+
+    // IWritableCredential overrides
+    Status getCredentialKeyCertificateChain(const vector<uint8_t>& challenge,
+                                            vector<uint8_t>* _aidl_return) override;
+
+    Status personalize(const vector<AccessControlProfileParcel>& accessControlProfiles,
+                       const vector<EntryNamespaceParcel>& entryNamespaces, int64_t secureUserId,
+                       vector<uint8_t>* _aidl_return) override;
+
+  private:
+    string dataPath_;
+    string credentialName_;
+    size_t dataChunkSize_;
+    sp<IWritableIdentityCredential> halBinder_;
+    vector<uint8_t> attestationCertificate_;
+
+    Status ensureAttestationCertificateExists(const vector<uint8_t>& challenge);
+};
+
+}  // namespace identity
+}  // namespace security
+}  // namespace android
+
+#endif  // SYSTEM_SECURITY_WRITABLE_CREDENTIAL_H_
diff --git a/identity/binder/android/security/identity/AccessControlProfileParcel.aidl b/identity/binder/android/security/identity/AccessControlProfileParcel.aidl
new file mode 100644
index 0000000..4bb85a9
--- /dev/null
+++ b/identity/binder/android/security/identity/AccessControlProfileParcel.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+/**
+ * @hide
+ */
+parcelable AccessControlProfileParcel {
+    int id;
+    byte[] readerCertificate;
+    boolean userAuthenticationRequired;
+    long userAuthenticationTimeoutMillis;
+}
diff --git a/identity/binder/android/security/identity/AuthKeyParcel.aidl b/identity/binder/android/security/identity/AuthKeyParcel.aidl
new file mode 100644
index 0000000..9374b8e
--- /dev/null
+++ b/identity/binder/android/security/identity/AuthKeyParcel.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+/**
+ * @hide
+ */
+parcelable AuthKeyParcel {
+    byte[] x509cert;
+}
diff --git a/identity/binder/android/security/identity/EntryNamespaceParcel.aidl b/identity/binder/android/security/identity/EntryNamespaceParcel.aidl
new file mode 100644
index 0000000..50758c8
--- /dev/null
+++ b/identity/binder/android/security/identity/EntryNamespaceParcel.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+import android.security.identity.EntryParcel;
+
+/**
+ * @hide
+ */
+parcelable EntryNamespaceParcel {
+    @utf8InCpp String namespaceName;
+    EntryParcel[] entries;
+}
diff --git a/identity/binder/android/security/identity/EntryParcel.aidl b/identity/binder/android/security/identity/EntryParcel.aidl
new file mode 100644
index 0000000..8d236d4
--- /dev/null
+++ b/identity/binder/android/security/identity/EntryParcel.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+/**
+ * @hide
+ */
+parcelable EntryParcel {
+    @utf8InCpp String name;
+    byte[] value;
+    int[] accessControlProfileIds;
+}
diff --git a/identity/binder/android/security/identity/GetEntriesResultParcel.aidl b/identity/binder/android/security/identity/GetEntriesResultParcel.aidl
new file mode 100644
index 0000000..03b363c
--- /dev/null
+++ b/identity/binder/android/security/identity/GetEntriesResultParcel.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+import android.security.identity.ResultNamespaceParcel;
+
+/**
+ * @hide
+ */
+parcelable GetEntriesResultParcel {
+    ResultNamespaceParcel[] resultNamespaces;
+    byte[] deviceNameSpaces;
+    byte[] mac;
+    byte[] staticAuthenticationData;
+}
diff --git a/identity/binder/android/security/identity/ICredential.aidl b/identity/binder/android/security/identity/ICredential.aidl
new file mode 100644
index 0000000..7bd0df7
--- /dev/null
+++ b/identity/binder/android/security/identity/ICredential.aidl
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+import android.security.identity.RequestNamespaceParcel;
+import android.security.identity.GetEntriesResultParcel;
+import android.security.identity.AuthKeyParcel;
+
+/**
+ * @hide
+ */
+interface ICredential {
+    /* The STATUS_* constants are used in the status field in ResultEntryParcel.
+     * Keep in sync with ResultNamespace.java.
+     */
+    const int STATUS_OK = 0;
+    const int STATUS_NO_SUCH_ENTRY = 1;
+    const int STATUS_NOT_REQUESTED = 2;
+    const int STATUS_NOT_IN_REQUEST_MESSAGE = 3;
+    const int STATUS_USER_AUTHENTICATION_FAILED = 4;
+    const int STATUS_READER_AUTHENTICATION_FAILED = 5;
+    const int STATUS_NO_ACCESS_CONTROL_PROFILES = 6;
+
+    byte[] createEphemeralKeyPair();
+
+    void setReaderEphemeralPublicKey(in byte[] publicKey);
+
+    byte[] deleteCredential();
+
+    byte[] getCredentialKeyCertificateChain();
+
+    long selectAuthKey(in boolean allowUsingExhaustedKeys);
+
+    GetEntriesResultParcel getEntries(in byte[] requestMessage,
+                                      in RequestNamespaceParcel[] requestNamespaces,
+                                      in byte[] sessionTranscript,
+                                      in byte[] readerSignature,
+                                      in boolean allowUsingExhaustedKeys);
+
+    void setAvailableAuthenticationKeys(in int keyCount, in int maxUsesPerKey);
+
+    AuthKeyParcel[] getAuthKeysNeedingCertification();
+
+    void storeStaticAuthenticationData(in AuthKeyParcel authenticationKey, in byte[] staticAuthData);
+
+    int[] getAuthenticationDataUsageCount();
+}
+
diff --git a/identity/binder/android/security/identity/ICredentialStore.aidl b/identity/binder/android/security/identity/ICredentialStore.aidl
new file mode 100644
index 0000000..1039831
--- /dev/null
+++ b/identity/binder/android/security/identity/ICredentialStore.aidl
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+import android.security.identity.IWritableCredential;
+import android.security.identity.ICredential;
+import android.security.identity.SecurityHardwareInfoParcel;
+
+/**
+ * @hide
+ */
+interface ICredentialStore {
+    /* All binder calls may return a ServiceSpecificException
+     * with the following error codes:
+     */
+    const int ERROR_NONE = 0;
+    const int ERROR_GENERIC = 1;
+    const int ERROR_ALREADY_PERSONALIZED = 2;
+    const int ERROR_NO_SUCH_CREDENTIAL = 3;
+    const int ERROR_CIPHER_SUITE_NOT_SUPPORTED = 4;
+    const int ERROR_EPHEMERAL_PUBLIC_KEY_NOT_FOUND = 5;
+    const int ERROR_NO_AUTHENTICATION_KEY_AVAILABLE = 6;
+    const int ERROR_INVALID_READER_SIGNATURE = 7;
+    const int ERROR_DOCUMENT_TYPE_NOT_SUPPORTED = 8;
+    const int ERROR_AUTHENTICATION_KEY_NOT_FOUND = 9;
+    const int ERROR_INVALID_ITEMS_REQUEST_MESSAGE = 10;
+    const int ERROR_SESSION_TRANSCRIPT_MISMATCH = 11;
+
+    SecurityHardwareInfoParcel getSecurityHardwareInfo();
+
+    IWritableCredential createCredential(in @utf8InCpp String credentialName,
+                                         in @utf8InCpp String docType);
+    ICredential getCredentialByName(in @utf8InCpp String credentialName,
+                                    in int cipherSuite);
+}
diff --git a/identity/binder/android/security/identity/ICredentialStoreFactory.aidl b/identity/binder/android/security/identity/ICredentialStoreFactory.aidl
new file mode 100644
index 0000000..3164f28
--- /dev/null
+++ b/identity/binder/android/security/identity/ICredentialStoreFactory.aidl
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+import android.security.identity.ICredentialStore;
+
+/**
+ * @hide
+ */
+interface ICredentialStoreFactory {
+    const int CREDENTIAL_STORE_TYPE_DEFAULT = 0;
+    const int CREDENTIAL_STORE_TYPE_DIRECT_ACCESS = 1;
+
+    ICredentialStore getCredentialStore(int credentialStoreType);
+}
diff --git a/identity/binder/android/security/identity/IWritableCredential.aidl b/identity/binder/android/security/identity/IWritableCredential.aidl
new file mode 100644
index 0000000..0e7ca4c
--- /dev/null
+++ b/identity/binder/android/security/identity/IWritableCredential.aidl
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+import android.security.identity.AccessControlProfileParcel;
+import android.security.identity.EntryNamespaceParcel;
+
+/**
+ * @hide
+ */
+interface IWritableCredential {
+    byte[] getCredentialKeyCertificateChain(in byte[] challenge);
+    byte[] personalize(in AccessControlProfileParcel[] accessControlProfiles,
+                       in EntryNamespaceParcel[] entryNamespaces,
+                       in long secureUserId);
+}
diff --git a/identity/binder/android/security/identity/RequestEntryParcel.aidl b/identity/binder/android/security/identity/RequestEntryParcel.aidl
new file mode 100644
index 0000000..77d80c1
--- /dev/null
+++ b/identity/binder/android/security/identity/RequestEntryParcel.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+/**
+ * @hide
+ */
+parcelable RequestEntryParcel {
+    @utf8InCpp String name;
+}
diff --git a/identity/binder/android/security/identity/RequestNamespaceParcel.aidl b/identity/binder/android/security/identity/RequestNamespaceParcel.aidl
new file mode 100644
index 0000000..a4fb624
--- /dev/null
+++ b/identity/binder/android/security/identity/RequestNamespaceParcel.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+import android.security.identity.RequestEntryParcel;
+
+/**
+ * @hide
+ */
+parcelable RequestNamespaceParcel {
+    @utf8InCpp String namespaceName;
+    RequestEntryParcel[] entries;
+}
diff --git a/identity/binder/android/security/identity/ResultEntryParcel.aidl b/identity/binder/android/security/identity/ResultEntryParcel.aidl
new file mode 100644
index 0000000..fb4f9ef
--- /dev/null
+++ b/identity/binder/android/security/identity/ResultEntryParcel.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+/**
+ * @hide
+ */
+parcelable ResultEntryParcel {
+    int status;
+    @utf8InCpp String name;
+    byte[] value;
+}
diff --git a/identity/binder/android/security/identity/ResultNamespaceParcel.aidl b/identity/binder/android/security/identity/ResultNamespaceParcel.aidl
new file mode 100644
index 0000000..c9543d9
--- /dev/null
+++ b/identity/binder/android/security/identity/ResultNamespaceParcel.aidl
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+import android.security.identity.ResultEntryParcel;
+
+/**
+ * @hide
+ */
+parcelable ResultNamespaceParcel {
+    @utf8InCpp String namespaceName;
+    ResultEntryParcel[] entries;
+}
diff --git a/identity/binder/android/security/identity/SecurityHardwareInfoParcel.aidl b/identity/binder/android/security/identity/SecurityHardwareInfoParcel.aidl
new file mode 100644
index 0000000..cabaf21
--- /dev/null
+++ b/identity/binder/android/security/identity/SecurityHardwareInfoParcel.aidl
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package android.security.identity;
+
+/**
+ * @hide
+ */
+parcelable SecurityHardwareInfoParcel {
+    boolean directAccess;
+    @utf8InCpp String[] supportedDocTypes;
+}
diff --git a/identity/credstore.rc b/identity/credstore.rc
new file mode 100644
index 0000000..12c1e72
--- /dev/null
+++ b/identity/credstore.rc
@@ -0,0 +1,5 @@
+service credstore /system/bin/credstore /data/misc/credstore
+    class main
+    user keystore
+    group keystore drmrpc readproc log
+    writepid /dev/cpuset/foreground/tasks
\ No newline at end of file
diff --git a/identity/main.cpp b/identity/main.cpp
new file mode 100644
index 0000000..af03a30
--- /dev/null
+++ b/identity/main.cpp
@@ -0,0 +1,59 @@
+/*
+ * 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 "android.security.identity"
+
+#include <filesystem>
+
+#include <unistd.h>
+
+#include <android-base/logging.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include "CredentialStoreFactory.h"
+
+#include <cppbor.h>
+
+using ::std::string;
+
+using ::android::IPCThreadState;
+using ::android::IServiceManager;
+using ::android::sp;
+using ::android::String16;
+using ::android::base::InitLogging;
+using ::android::base::StderrLogger;
+
+using ::android::security::identity::CredentialStoreFactory;
+
+int main(int argc, char* argv[]) {
+    InitLogging(argv, StderrLogger);
+
+    CHECK(argc == 2) << "A directory must be specified";
+    string data_dir = string(argv[1]);
+    CHECK(chdir(data_dir.c_str()) != -1) << "chdir: " << data_dir << ": " << strerror(errno);
+
+    sp<IServiceManager> sm = ::android::defaultServiceManager();
+    sp<CredentialStoreFactory> factory = new CredentialStoreFactory(data_dir);
+
+    auto ret = sm->addService(String16("android.security.identity"), factory);
+    CHECK(ret == ::android::OK) << "Couldn't register binder service";
+    LOG(ERROR) << "Registered binder service";
+
+    IPCThreadState::self()->joinThreadPool();
+
+    return 0;
+}
