diff --git a/identity/1.0/default/WritableIdentityCredential.cpp b/identity/1.0/default/WritableIdentityCredential.cpp
new file mode 100644
index 0000000..548b4c0
--- /dev/null
+++ b/identity/1.0/default/WritableIdentityCredential.cpp
@@ -0,0 +1,426 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "WritableIdentityCredential"
+
+#include "WritableIdentityCredential.h"
+#include "IdentityCredentialStore.h"
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <android-base/logging.h>
+
+#include <cppbor/cppbor.h>
+#include <cppbor/cppbor_parse.h>
+
+namespace android {
+namespace hardware {
+namespace identity {
+namespace implementation {
+
+using ::std::optional;
+
+// Writes CBOR-encoded structure to |credentialKeys| containing |storageKey| and
+// |credentialPrivKey|.
+static bool generateCredentialKeys(const vector<uint8_t>& storageKey,
+                                   const vector<uint8_t>& credentialPrivKey,
+                                   vector<uint8_t>& credentialKeys) {
+    if (storageKey.size() != 16) {
+        LOG(ERROR) << "Size of storageKey is not 16";
+        return false;
+    }
+
+    cppbor::Array array;
+    array.add(cppbor::Bstr(storageKey));
+    array.add(cppbor::Bstr(credentialPrivKey));
+    credentialKeys = array.encode();
+    return true;
+}
+
+// Writes CBOR-encoded structure to |credentialData| containing |docType|,
+// |testCredential| and |credentialKeys|. The latter element will be stored in
+// encrypted form, using |hardwareBoundKey| as the encryption key.
+bool generateCredentialData(const vector<uint8_t>& hardwareBoundKey, const string& docType,
+                            bool testCredential, const vector<uint8_t>& credentialKeys,
+                            vector<uint8_t>& credentialData) {
+    optional<vector<uint8_t>> nonce = support::getRandom(12);
+    if (!nonce) {
+        LOG(ERROR) << "Error getting random";
+        return false;
+    }
+    vector<uint8_t> docTypeAsVec(docType.begin(), docType.end());
+    optional<vector<uint8_t>> credentialBlob = support::encryptAes128Gcm(
+            hardwareBoundKey, nonce.value(), credentialKeys, docTypeAsVec);
+    if (!credentialBlob) {
+        LOG(ERROR) << "Error encrypting CredentialKeys blob";
+        return false;
+    }
+
+    cppbor::Array array;
+    array.add(docType);
+    array.add(testCredential);
+    array.add(cppbor::Bstr(credentialBlob.value()));
+    credentialData = array.encode();
+    return true;
+}
+
+bool WritableIdentityCredential::initialize() {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    if (!keyPair) {
+        LOG(ERROR) << "Error creating credentialKey";
+        return false;
+    }
+
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    if (!pubKey) {
+        LOG(ERROR) << "Error getting public part of credentialKey";
+        return false;
+    }
+    credentialPubKey_ = pubKey.value();
+
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    if (!privKey) {
+        LOG(ERROR) << "Error getting private part of credentialKey";
+        return false;
+    }
+    credentialPrivKey_ = privKey.value();
+
+    optional<vector<uint8_t>> random = support::getRandom(16);
+    if (!random) {
+        LOG(ERROR) << "Error creating storageKey";
+        return false;
+    }
+    storageKey_ = random.value();
+
+    return true;
+}
+
+Return<void> WritableIdentityCredential::getAttestationCertificate(
+        const hidl_vec<uint8_t>& /* attestationChallenge */,
+        getAttestationCertificate_cb _hidl_cb) {
+    // For now, we dynamically generate an attestion key on each and every
+    // request and use that to sign CredentialKey. In a real implementation this
+    // would look very differently.
+    optional<vector<uint8_t>> attestationKeyPair = support::createEcKeyPair();
+    if (!attestationKeyPair) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error creating attestationKey"), {});
+        return Void();
+    }
+
+    optional<vector<uint8_t>> attestationPubKey =
+            support::ecKeyPairGetPublicKey(attestationKeyPair.value());
+    if (!attestationPubKey) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error getting public part of attestationKey"),
+                 {});
+        return Void();
+    }
+
+    optional<vector<uint8_t>> attestationPrivKey =
+            support::ecKeyPairGetPrivateKey(attestationKeyPair.value());
+    if (!attestationPrivKey) {
+        _hidl_cb(
+                support::result(ResultCode::FAILED, "Error getting private part of attestationKey"),
+                {});
+        return Void();
+    }
+
+    string serialDecimal;
+    string issuer;
+    string subject;
+    time_t validityNotBefore = time(nullptr);
+    time_t validityNotAfter = validityNotBefore + 365 * 24 * 3600;
+
+    // First create a certificate for |credentialPubKey| which is signed by
+    // |attestationPrivKey|.
+    //
+    serialDecimal = "0";  // TODO: set serial to |attestationChallenge|
+    issuer = "Android Open Source Project";
+    subject = "Android IdentityCredential CredentialKey";
+    optional<vector<uint8_t>> credentialPubKeyCertificate = support::ecPublicKeyGenerateCertificate(
+            credentialPubKey_, attestationPrivKey.value(), serialDecimal, issuer, subject,
+            validityNotBefore, validityNotAfter);
+    if (!credentialPubKeyCertificate) {
+        _hidl_cb(support::result(ResultCode::FAILED,
+                                 "Error creating certificate for credentialPubKey"),
+                 {});
+        return Void();
+    }
+
+    // This is followed by a certificate for |attestationPubKey| self-signed by
+    // |attestationPrivKey|.
+    serialDecimal = "0";  // TODO: set serial
+    issuer = "Android Open Source Project";
+    subject = "Android IdentityCredential AttestationKey";
+    optional<vector<uint8_t>> attestationKeyCertificate = support::ecPublicKeyGenerateCertificate(
+            attestationPubKey.value(), attestationPrivKey.value(), serialDecimal, issuer, subject,
+            validityNotBefore, validityNotAfter);
+    if (!attestationKeyCertificate) {
+        _hidl_cb(support::result(ResultCode::FAILED,
+                                 "Error creating certificate for attestationPubKey"),
+                 {});
+        return Void();
+    }
+
+    // Concatenate the certificates to form the chain.
+    vector<uint8_t> certificateChain;
+    certificateChain.insert(certificateChain.end(), credentialPubKeyCertificate.value().begin(),
+                            credentialPubKeyCertificate.value().end());
+    certificateChain.insert(certificateChain.end(), attestationKeyCertificate.value().begin(),
+                            attestationKeyCertificate.value().end());
+
+    _hidl_cb(support::resultOK(), certificateChain);
+    return Void();
+}
+
+Return<void> WritableIdentityCredential::startPersonalization(uint16_t accessControlProfileCount,
+                                                              const hidl_vec<uint16_t>& entryCounts,
+                                                              startPersonalization_cb _hidl_cb) {
+    numAccessControlProfileRemaining_ = accessControlProfileCount;
+    remainingEntryCounts_ = entryCounts;
+    entryNameSpace_ = "";
+
+    signedDataAccessControlProfiles_ = cppbor::Array();
+    signedDataNamespaces_ = cppbor::Map();
+    signedDataCurrentNamespace_ = cppbor::Array();
+
+    _hidl_cb(support::resultOK());
+    return Void();
+}
+
+Return<void> WritableIdentityCredential::addAccessControlProfile(
+        uint16_t id, const hidl_vec<uint8_t>& readerCertificate, bool userAuthenticationRequired,
+        uint64_t timeoutMillis, uint64_t secureUserId, addAccessControlProfile_cb _hidl_cb) {
+    SecureAccessControlProfile profile;
+
+    if (numAccessControlProfileRemaining_ == 0) {
+        _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                 "numAccessControlProfileRemaining_ is 0 and expected non-zero"),
+                 profile);
+        return Void();
+    }
+
+    // Spec requires if |userAuthenticationRequired| is false, then |timeoutMillis| must also
+    // be zero.
+    if (!userAuthenticationRequired && timeoutMillis != 0) {
+        _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                 "userAuthenticationRequired is false but timeout is non-zero"),
+                 profile);
+        return Void();
+    }
+
+    profile.id = id;
+    profile.readerCertificate = readerCertificate;
+    profile.userAuthenticationRequired = userAuthenticationRequired;
+    profile.timeoutMillis = timeoutMillis;
+    profile.secureUserId = secureUserId;
+    optional<vector<uint8_t>> mac =
+            support::secureAccessControlProfileCalcMac(profile, storageKey_);
+    if (!mac) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error calculating MAC for profile"), profile);
+        return Void();
+    }
+    profile.mac = mac.value();
+
+    cppbor::Map profileMap;
+    profileMap.add("id", profile.id);
+    if (profile.readerCertificate.size() > 0) {
+        profileMap.add("readerCertificate", cppbor::Bstr(profile.readerCertificate));
+    }
+    if (profile.userAuthenticationRequired) {
+        profileMap.add("userAuthenticationRequired", profile.userAuthenticationRequired);
+        profileMap.add("timeoutMillis", profile.timeoutMillis);
+    }
+    signedDataAccessControlProfiles_.add(std::move(profileMap));
+
+    numAccessControlProfileRemaining_--;
+
+    _hidl_cb(support::resultOK(), profile);
+    return Void();
+}
+
+Return<void> WritableIdentityCredential::beginAddEntry(
+        const hidl_vec<uint16_t>& accessControlProfileIds, const hidl_string& nameSpace,
+        const hidl_string& name, uint32_t entrySize, beginAddEntry_cb _hidl_cb) {
+    if (numAccessControlProfileRemaining_ != 0) {
+        LOG(ERROR) << "numAccessControlProfileRemaining_ is " << numAccessControlProfileRemaining_
+                   << " and expected zero";
+        _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                 "numAccessControlProfileRemaining_ is %zd and expected zero",
+                                 numAccessControlProfileRemaining_));
+        return Void();
+    }
+
+    if (remainingEntryCounts_.size() == 0) {
+        _hidl_cb(support::result(ResultCode::INVALID_DATA, "No more namespaces to add to"));
+        return Void();
+    }
+
+    // Handle initial beginEntry() call.
+    if (entryNameSpace_ == "") {
+        entryNameSpace_ = nameSpace;
+    }
+
+    // If the namespace changed...
+    if (nameSpace != entryNameSpace_) {
+        // Then check that all entries in the previous namespace have been added..
+        if (remainingEntryCounts_[0] != 0) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                     "New namespace but %d entries remain to be added",
+                                     int(remainingEntryCounts_[0])));
+            return Void();
+        }
+        remainingEntryCounts_.erase(remainingEntryCounts_.begin());
+
+        if (signedDataCurrentNamespace_.size() > 0) {
+            signedDataNamespaces_.add(entryNameSpace_, std::move(signedDataCurrentNamespace_));
+            signedDataCurrentNamespace_ = cppbor::Array();
+        }
+    } else {
+        // Same namespace...
+        if (remainingEntryCounts_[0] == 0) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                     "Same namespace but no entries remain to be added"));
+            return Void();
+        }
+        remainingEntryCounts_[0] -= 1;
+    }
+
+    entryAdditionalData_ =
+            support::entryCreateAdditionalData(nameSpace, name, accessControlProfileIds);
+
+    entryRemainingBytes_ = entrySize;
+    entryNameSpace_ = nameSpace;
+    entryName_ = name;
+    entryAccessControlProfileIds_ = accessControlProfileIds;
+    entryBytes_.resize(0);
+    // LOG(INFO) << "name=" << name << " entrySize=" << entrySize;
+
+    _hidl_cb(support::resultOK());
+    return Void();
+}
+
+Return<void> WritableIdentityCredential::addEntryValue(const hidl_vec<uint8_t>& content,
+                                                       addEntryValue_cb _hidl_cb) {
+    size_t contentSize = content.size();
+
+    if (contentSize > IdentityCredentialStore::kGcmChunkSize) {
+        _hidl_cb(support::result(
+                         ResultCode::INVALID_DATA,
+                         "Passed in chunk of size %zd is bigger than kGcmChunkSize which is %zd",
+                         contentSize, IdentityCredentialStore::kGcmChunkSize),
+                 {});
+        return Void();
+    }
+    if (contentSize > entryRemainingBytes_) {
+        _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                 "Passed in chunk of size %zd is bigger than remaining space "
+                                 "of size %zd",
+                                 contentSize, entryRemainingBytes_),
+                 {});
+        return Void();
+    }
+
+    entryBytes_.insert(entryBytes_.end(), content.begin(), content.end());
+    entryRemainingBytes_ -= contentSize;
+    if (entryRemainingBytes_ > 0) {
+        if (contentSize != IdentityCredentialStore::kGcmChunkSize) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                     "Retrieved non-final chunk of size %zd but expected "
+                                     "kGcmChunkSize which is %zd",
+                                     contentSize, IdentityCredentialStore::kGcmChunkSize),
+                     {});
+            return Void();
+        }
+    }
+
+    optional<vector<uint8_t>> nonce = support::getRandom(12);
+    if (!nonce) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error getting nonce"), {});
+        return Void();
+    }
+    optional<vector<uint8_t>> encryptedContent =
+            support::encryptAes128Gcm(storageKey_, nonce.value(), content, entryAdditionalData_);
+    if (!encryptedContent) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error encrypting content"), {});
+        return Void();
+    }
+
+    if (entryRemainingBytes_ == 0) {
+        // TODO: ideally do do this without parsing the data (but still validate data is valid
+        // CBOR).
+        auto [item, _, message] = cppbor::parse(entryBytes_);
+        if (item == nullptr) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA, "Data is not valid CBOR"), {});
+            return Void();
+        }
+        cppbor::Map entryMap;
+        entryMap.add("name", entryName_);
+        entryMap.add("value", std::move(item));
+        cppbor::Array profileIdArray;
+        for (auto id : entryAccessControlProfileIds_) {
+            profileIdArray.add(id);
+        }
+        entryMap.add("accessControlProfiles", std::move(profileIdArray));
+        signedDataCurrentNamespace_.add(std::move(entryMap));
+    }
+
+    _hidl_cb(support::resultOK(), encryptedContent.value());
+    return Void();
+}
+
+Return<void> WritableIdentityCredential::finishAddingEntries(finishAddingEntries_cb _hidl_cb) {
+    if (signedDataCurrentNamespace_.size() > 0) {
+        signedDataNamespaces_.add(entryNameSpace_, std::move(signedDataCurrentNamespace_));
+    }
+    cppbor::Array popArray;
+    popArray.add("ProofOfProvisioning")
+            .add(docType_)
+            .add(std::move(signedDataAccessControlProfiles_))
+            .add(std::move(signedDataNamespaces_))
+            .add(testCredential_);
+    vector<uint8_t> encodedCbor = popArray.encode();
+
+    optional<vector<uint8_t>> signature = support::coseSignEcDsa(credentialPrivKey_,
+                                                                 encodedCbor,  // payload
+                                                                 {},           // additionalData
+                                                                 {});          // certificateChain
+    if (!signature) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error signing data"), {}, {});
+        return Void();
+    }
+
+    vector<uint8_t> credentialKeys;
+    if (!generateCredentialKeys(storageKey_, credentialPrivKey_, credentialKeys)) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error generating CredentialKeys"), {}, {});
+        return Void();
+    }
+
+    vector<uint8_t> credentialData;
+    if (!generateCredentialData(testCredential_ ? support::getTestHardwareBoundKey()
+                                                : support::getHardwareBoundKey(),
+                                docType_, testCredential_, credentialKeys, credentialData)) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error generating CredentialData"), {}, {});
+        return Void();
+    }
+
+    _hidl_cb(support::resultOK(), credentialData, signature.value());
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
