diff --git a/identity/1.0/Android.bp b/identity/1.0/Android.bp
new file mode 100644
index 0000000..a5cea90
--- /dev/null
+++ b/identity/1.0/Android.bp
@@ -0,0 +1,25 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.identity@1.0",
+    root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "types.hal",
+        "IIdentityCredential.hal",
+        "IIdentityCredentialStore.hal",
+        "IWritableIdentityCredential.hal",
+    ],
+    interfaces: [
+        "android.hidl.base@1.0",
+        "android.hardware.keymaster@4.0",
+    ],
+    types: [
+        "AuditLogEntry",
+        "ResultCode",
+        "SecureAccessControlProfile",
+    ],
+    gen_java: false,
+}
diff --git a/identity/1.0/IIdentityCredential.hal b/identity/1.0/IIdentityCredential.hal
new file mode 100644
index 0000000..75f6e18
--- /dev/null
+++ b/identity/1.0/IIdentityCredential.hal
@@ -0,0 +1,343 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.identity@1.0;
+
+import android.hardware.keymaster@4.0::HardwareAuthToken;
+
+interface IIdentityCredential {
+    /**
+     * Delete a credential.
+     *
+     * This method returns a COSE_Sign1 data structure signed by CredentialKey
+     * with payload set to the ProofOfDeletion CBOR below:
+     *
+     *     ProofOfDeletion = [
+     *          "ProofOfDeletion",            ; tstr
+     *          tstr,                         ; DocType
+     *          bool                          ; true if this is a test credential, should
+     *                                        ; always be false.
+     *     ]
+     *
+     * After this method has been called, the persistent storage used for credentialData should
+     * be deleted.
+     *
+     * @return proofOfDeletionSignature is a COSE_Sign1 signature described above.
+     */
+    deleteCredential()
+        generates(Result result, vec<uint8_t> proofOfDeletionSignature);
+
+    /**
+     * Creates an ephemeral EC key pair, for use in establishing a seceure session with a reader.
+     * This method returns the private key so the caller can perform an ECDH key agreement operation
+     * with the reader.  The reason for generating the key pair in the secure environment is so that
+     * the secure environment knows what public key to expect to find in the session transcript.
+     *
+     * This method may only be called once per instance. If called more than once, FAILED
+     * will be returned.
+     *
+     * @return result is OK on success or FAILED if an error occurred.
+     *
+     * @return keyPair contains the unencrypted key-pair in PKCS#8 format.
+     */
+    createEphemeralKeyPair() generates (Result result, vec<uint8_t> keyPair);
+
+    /**
+     * Sets the public part of the reader's ephemeral key pair.
+     *
+     * This method may only be called once per instance. If called more than once, FAILED
+     * will be returned.
+     *
+     * @param publicKey contains the reader's ephemeral public key, in uncompressed form.
+     *
+     * @return result is OK on success or FAILED if an error occurred.
+     */
+    setReaderEphemeralPublicKey(vec<uint8_t> publicKey) generates (Result result);
+
+    /**
+     * Creates a challenge value to be used for proving successful user authentication. This
+     * is included in the authToken passed to the startRetrieval() method.
+     *
+     * This method may only be called once per instance. If called more than once, FAILED
+     * will be returned.
+     *
+     * @return result is OK on success or FAILED if an error occurred.
+     *
+     * @return challenge on success, is a non-zero number.
+     */
+    createAuthChallenge() generates (Result result, uint64_t challenge);
+
+    /**
+     * Start an entry retrieval process.
+     *
+     * This method be called after createEphemeralKeyPair(), setReaderEphemeralPublicKey(),
+     * createAuthChallenge() and before startRetrieveEntry(). This method call is followed by
+     * multiple calls of startRetrieveEntryValue(), retrieveEntryValue(), and finally
+     * finishRetrieval().This whole process is called a "credential presentation".
+     *
+     * It is permissible to perform multiple credential presentations using the same instance (e.g.
+     * startRetrieval(), then multiple calls of startRetrieveEntryValue(), retrieveEntryValue(),
+     * then finally finishRetrieval()) but if this is done, the sessionTranscript parameter
+     * must be identical for each startRetrieval() invocation. If this is not the case, this call
+     * fails with the SESSION_TRANSCRIPT_MISMATCH error.
+     *
+     * If the provided authToken is not valid this method fails with INVALID_AUTH_TOKEN.
+     *
+     * Each of the provided accessControlProfiles is checked in this call. If they are not
+     * all valid, the call fails with INVALID_DATA.
+     *
+     * For the itemsRequest parameter, the content can be defined in the way appropriate for
+     * the credential, but there are three requirements that must be met to work with this HAL:
+     *
+     *  1. The content must be a CBOR-encoded structure.
+     *  2. The CBOR structure must be a map.
+     *  3. The map must contain a tstr key "nameSpaces" whose value contains a map, as described in
+     *     the example below.
+     *
+     * If these requirements are not met the startRetrieval() call fails with
+     * INVALID_ITEMS_REQUEST_MESSAGE.
+     *
+     * Here's an example of ItemsRequest CBOR which conforms to this requirement:
+     *
+     *   ItemsRequest = {
+     *     ? "docType" : DocType,
+     *       "nameSpaces" : NameSpaces,
+     *     ? "requestInfo" : {* tstr => any}   ; Additional info the reader wants to provide
+     *   }
+     *
+     *   DocType = tstr
+     *
+     *   NameSpaces = {
+     *     + NameSpace => DataElements    ; Requested data elements for each NameSpace
+     *   }
+     *
+     *   NameSpace = tstr
+     *
+     *   DataElements = {
+     *     + DataElement => IntentToRetain
+     *   }
+     *
+     *   DataElement = tstr
+     *   IntentToRetain = bool
+     *
+     * For the readerSignature parameter, this can either be empty or if non-empty it
+     * must be a COSE_Sign1 structure with an ECDSA signature over the content of the
+     * CBOR conforming to the following CDDL:
+     *
+     *     ReaderAuthentication = [
+     *       "ReaderAuthentication",
+     *       SessionTranscript,
+     *       ItemsRequestBytes
+     *     ]
+     *
+     *     SessionTranscript = [
+     *       DeviceEngagementBytes,
+     *       EReaderKeyBytes
+     *     ]
+     *
+     *     DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement)
+     *     EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub)
+     *     ItemsRequestBytes = #6.24(bstr .cbor ItemsRequest)
+     *
+     * The public key corresponding to the key used to made signature, can be found in the
+     * 'x5chain' unprotected header element of the COSE_Sign1 structure (as as described
+     * in 'draft-ietf-cose-x509-04'). There will be at least one certificate in said element
+     * and there may be more (and if so, each certificate must be signed by its successor).
+     * This is checked and if the check fails the call fails with READER_SIGNATURE_CHECK_FAILED.
+     *
+     * The SessionTranscript CBOR is conveyed in the sessionTranscript parameter. It
+     * is permissible for this to be empty in which case the readerSignature parameter
+     * must also be empty. If this is not the case, the call fails with FAILED.
+     *
+     * If the SessionTranscript CBOR is not empty, the X and Y coordinates of the public
+     * part of the key-pair previously generated by createEphemeralKeyPair() must appear
+     * somewhere in the bytes of DeviceEngagement structure. Both X and Y should be in
+     * uncompressed form. If this is not satisfied, the call fails with
+     * EPHEMERAL_PUBLIC_KEY_NOT_FOUND.
+     *
+     * @param accessControlProfiles
+     *   Access control profiles that are required to retrieve the entries that are going to be
+     *   requested with IIdentityCredential.retrieveEntryValue(). See above.
+     *
+     * @param authToken
+     *   The authentication token that proves the user was authenticated, as required
+     *   by one or more of the provided accessControlProfiles. See above.
+     *
+     * @param itemsRequest
+     *   If non-empty, contains request data that is signed by the reader. See above.
+     *
+     * @param sessionTranscript
+     *   Either empty or the CBOR of the SessionTranscript. See above.
+     *
+     * @param readerSignature
+     *   readerSignature is either empty or contains a CBOR_Sign1 structure. See above.
+     *
+     * @param requestCounts
+     *   requestCounts specifies the number of data items that are going to be requested, per
+     *   namespace.  The number of elements in the vector must be the number of namespaces for which
+     *   data items will be requested in retrieveEntryValue() calls, and the values of the elments
+     *   must be the number of items from each namespace, in order, that will be requested in
+     *   retrieveEntryValue() calls.
+     *   Note that it's the caller's responsibility to ensure that the counts correspond to the
+     *   retrieveEntryValue() calls that will be made, and that every retrieveEntryValue() call
+     *   will succeed (i.e. that the access control profile checks will succeed).  This means that
+     *   it's the responsibility of the caller to determine which access control checks will fail
+     *   and remove the corresponding requests from the counts.
+     *
+     * @return result is OK on success. If an error occurs one of the values described above
+     *   will be returned.
+     */
+    startRetrieval(vec<SecureAccessControlProfile> accessControlProfiles,
+                   HardwareAuthToken authToken,
+                   vec<uint8_t> itemsRequest,
+                   vec<uint8_t> sessionTranscript,
+                   vec<uint8_t> readerSignature,
+                   vec<uint16_t> requestCounts) generates(Result result);
+
+    /**
+     * Starts retrieving an entry, subject to access control requirements.  Entries must be
+     * retrieved in namespace groups as specified in the requestCounts parameter.
+     *
+     * If the requestData parameter as passed to startRetrieval() was non-empty
+     * this method must only be called with entries specified in that field. If this
+     * requirement is not met, the call fails with NOT_IN_REQUEST_MESSAGE.
+     *
+     * If nameSpace or name is empty this call fails with INVALID_DATA.
+     *
+     * Each access control profile for the entry is checked. If user authentication
+     * is required and the supplied auth token doesn't provide it the call fails
+     * with USER_AUTHENTICATION_FAILED. If reader authentication is required and
+     * a suitable reader certificate chain isn't presented, the call fails with
+     * READER_AUTHENTICATION_FAILED.
+     *
+     * It is permissible to keep retrieving values if an access control check fails.
+     *
+     * @param nameSpace is the namespace of the element, e.g. "org.iso.18013"
+     *
+     * @param name is the name of the element.
+     *
+     * @param entrySize is the size of the entry value, if it's a text string or a byte string.
+     *     It must be zero if the entry value is an integer or boolean. If this requirement
+     *     is not met the call fails with INVALID_DATA.
+     *
+     * @param accessControlProfileIds specifies the set of access control profiles that can
+     *     authorize access to the provisioned element. If an identifier of a profile
+     *     is given and this profile wasn't passed to startRetrieval() this call fails
+     *     with INVALID_DATA.
+     *
+     * @return result is OK on success. Otherwise one of INVALID_DATA, FAILED,
+     *     USER_AUTHENTICATION_FAILED, READER_AUTHENTICATION_FAILED.
+     */
+    startRetrieveEntryValue(string nameSpace, string name, uint32_t entrySize,
+                            vec<uint16_t> accessControlProfileIds)
+        generates (Result result);
+
+
+    /**
+     * Retrieves an entry value, or part of one, if the entry value is larger than gcmChunkSize.
+     * May only be called after startRetrieveEntry().
+     *
+     * If the passed in data is not authentic, can't be decrypted, is of the wrong size, or can't
+     * be decoded, this call fails with INVALID_DATA.
+     *
+     * @param encryptedContent contains the encrypted and MACed content.
+     *
+     * @return result is OK on success, INVALID_DATA, or FAILED if an error occurred.
+     *
+     * @return content is the entry value as CBOR, or part of the entry value in the case the
+     *    content exceeds gcmChunkSize in length.
+     */
+    retrieveEntryValue(vec<uint8_t> encryptedContent)
+        generates (Result result, vec<uint8_t> content);
+
+
+    /**
+     * End retrieval of data, optionally returning a message authentication code over the
+     * returned data.
+     *
+     * If signingKeyBlob or the sessionTranscript parameter passed to startRetrieval() is
+     * empty then the returned MAC will be empty.
+     *
+     * @param signingKeyBlob is either empty or a signingKeyBlob (see generateSigningKeyPair(),
+     *    below) containing the signing key to use to sign the data retrieved. If this
+     *    is not in the right format the call fails with INVALID_DATA.
+     *
+     * @return result is OK on success, INVALID_DATA or FAILED if an error occurred.
+     *
+     * @return mac is empty if signingKeyBlob or the sessionTranscript passed to
+     *    startRetrieval() is empty. Otherwise it is a COSE_Mac0 with empty payload
+     *    and the detached content is set to DeviceAuthentication as defined below.
+     *    The key used for the MAC operation is EMacKey and is derived as follows:
+     *
+     *     KDF(ECDH(SDeviceKey.Priv, EReaderKey.Pub))
+     *
+     *    where SDeviceKey.Priv is the key identified by signingKeyBlob. The KDF
+     *    and ECDH functions shall be the same as the ciphersuite selected and
+     *    passed to IIdentityStore.getCredential(). The EMacKey shall be derived
+     *    using a salt of 0x00.
+     *
+     *        DeviceAuthentication = [
+     *            "DeviceAuthentication",
+     *            SessionTranscript,
+     *            DocType,
+     *            DeviceNameSpaceBytes,
+     *        ]
+     *
+     *        DocType = tstr
+     *
+     *        SessionTranscript = [
+     *            DeviceEngagementBytes,
+     *            EReaderKeyBytes
+     *        ]
+     *
+     *        DeviceEngagementBytes = #6.24(bstr .cbor DeviceEngagement)
+     *        EReaderKeyBytes = #6.24(bstr .cbor EReaderKey.Pub)
+     *        DeviceNameSpacesBytes = #6.24(bstr .cbor DeviceNameSpaces)
+     *
+     *    where
+     *
+     *        DeviceNameSpaces = {
+     *            * NameSpace => DeviceSignedItems
+     *        }
+     *        DeviceSignedItems = {
+     *            + DataItemName => DataItemValue
+     *        }
+     *
+     *        Namespace = tstr
+     *        DataItemName = tstr
+     *        DataItemValue = any
+     *
+     *
+     * @return deviceNameSpaces the bytes of DeviceNameSpaces.
+     */
+    finishRetrieval(vec<uint8_t> signingKeyBlob)
+        generates(Result result, vec<uint8_t> mac, vec<uint8_t> deviceNameSpaces);
+
+
+    /**
+     * Generate a key pair to be used for signing session data and retrieved data items.
+     *
+     * @return result is OK on success or FAILED if an error occurred.
+     *
+     * @return signingKeyBlob contains an encrypted copy of the newly-generated private signing key.
+     *
+     * @return signingKeyCertificate contains an X.509 certificate for the new signing key, signed
+     *     by the credential key.
+     */
+    generateSigningKeyPair()
+        generates(Result result, vec<uint8_t> signingKeyBlob,
+                  vec<uint8_t> signingKeyCertificate);
+};
diff --git a/identity/1.0/IIdentityCredentialStore.hal b/identity/1.0/IIdentityCredentialStore.hal
new file mode 100644
index 0000000..118ca6f
--- /dev/null
+++ b/identity/1.0/IIdentityCredentialStore.hal
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.identity@1.0;
+
+import IWritableIdentityCredential;
+import IIdentityCredential;
+
+/**
+ * IIdentityCredentialStore provides an interface to a secure store for user identity documents.
+ * This HAL is deliberately fairly general and abstract.  To the extent possible, specification of
+ * the message formats and semantics of communication with credential verification devices and
+ * issuing authorities (IAs) is out of scope for this HAL.  It provides the interface with secure
+ * storage but a credential-specific Android application will be required to implement the
+ * presentation and verification protocols and processes appropriate for the specific credential
+ * type.
+ *
+ * The design of this HAL makes few assumptions about the underlying secure hardware.  In particular
+ * it does not assume that the secure hardware has any storage beyond that needed for a persistent,
+ * hardware-bound AES-128 key.  However, its design allows the use of secure hardware that does have
+ * storage, specifically to enable "direct access".  Most often credentials will be accessed through
+ * this HAL and through the Android layers above it but that requires that the Android device be
+ * powered up and fully functional.  It is desirable to allow identity credential usage when the
+ * Android device's battery is too low to boot the Android operating system, so direct access to the
+ * secure hardware via NFC may allow data retrieval, if the secure hardware chooses to implement it.
+ * Definition of how data is retrieved in low power mode is explicitly out of scope for this HAL
+ * specification; it's up to the relevant identity credential standards to define.
+ *
+ * The 'default' HAL instance is explicitly not for direct access and the 'direct_access' HAL
+ * instance - if available - is for direct access. Applications are expected to provision their
+ * credential to both instances (and the contents may differ), not just one of them.
+ *
+ * Multiple credentials can be created.  Each credential comprises:
+ *
+ * - A document type, which is a UTF-8 string of at most 256 bytes.
+ *
+ * - A set of namespaces, which serve to disambiguate value names.  Namespaces are UTF-8 strings of
+ *   up to 256 bytes in length (most should be much shorter).  It is recommended that namespaces be
+ *   structured as reverse domain names so that IANA effectively serves as the namespace registrar.
+ *
+ * - For each namespase, a set of name/value pairs, each with an associated set of access control
+ *   profile IDs.  Names are UTF-8 strings of up to 256 bytes in length (most should be much
+ *   shorter).  Values stored must be encoed as valid CBOR (https://tools.ietf.org/html/rfc7049) and
+ *   the encoeded size is is limited to at most 512 KiB.
+ *
+ * - A set of access control profiles, each with a profile ID and a specification of the
+ *   conditions which satisfy the profile's requirements.
+ *
+ * - An asymmetric key pair which is used to authenticate the credential to the IA, called the
+ *   CredentialKey. This key is attested to by the secure hardware using Android Keystore
+ *   attestation (https://source.android.com/security/keystore/attestation). See
+ *   getAttestationCertificate() in the IWritableIdentityCredential for more information.
+ *
+ * - A set of zero or more named reader authentication public keys, which are used to authenticate
+ *   an authorized reader to the credential.
+ *
+ * - A set of named signing keys, which are used to sign collections of values and session
+ *   transcripts.
+ *
+ * Cryptographic notation:
+ *
+ * Throughout this HAL, cryptographic operations are specified in detail.  To avoid repeating the
+ * definition of the notation, it's specified here.  It is assumed that the reader is familiar with
+ * standard cryptographic algorithms and constructs.
+ *
+ *     AES-GCM-ENC(K, N, D, A) represents AES-GCM encryption with key 'K', nonce 'N', additional
+ *         authenticated data 'A' and data 'D'.  The nonce is usually specified as 'R', meaning 12
+ *         random bytes.  The nonce is always 12 bytes and is prepended to the ciphertext. The GCM
+ *         tag is 16 bytes, appended to the ciphertext.  AES-GCM-DEC with the same argument notation
+ *         represents the corresponding decryption operation.
+ *
+ *    ECDSA(K, D) represents ECDSA signing of data 'D' with key 'K'.
+ *
+ *    || represents concatenation
+ *
+ *    {} represents an empty input; 0 bytes of data.
+ *
+ *    HBK represents a device-unique, hardware-bound AES-128 key which exists only in secure
+ *        hardware, except for "test" credential stores (see createCredential(), below).  For test
+ *        stores, an all-zero value is used in place of the HBK.
+ *
+ * Data encoding notation:
+ *
+ * Various fields need to be encoded as precisely-specified byte arrays.  Where existing standards
+ * define appropriate encodings, those are used.  For example, X.509 certificates.  Where new
+ * encodings are needed, CBOR is used.  CBOR maps are described in CDDL notation
+ * (https://tools.ietf.org/html/draft-ietf-cbor-cddl-06).
+ */
+interface IIdentityCredentialStore {
+
+    /**
+     * Returns information about hardware.
+     *
+     * The isDirectAccess output parameter indicates whether this credential store
+     * implementation is for direct access. Credentials provisioned in credential
+     * stores with this set to true, should use reader authentication on all data elements.
+     *
+     * @return result is OK on success, FAILED if an error occurred.
+     *
+     * @return credentialStoreName the name of the credential store implementation.
+     *
+     * @return credentialStoreAuthorName the name of the credential store author.
+     *
+     * @return dataChunkSize the maximum size of data chunks.
+     *
+     * @return isDirectAccess whether the provisioned credential is available through
+     *     direct access.
+     *
+     * @return supportedDocTypes if empty, then any document type is supported, otherwise
+     *     only the document types returned are supported.
+     */
+    getHardwareInformation()
+        generates(Result result,
+                  string credentialStoreName,
+                  string credentialStoreAuthorName,
+                  uint32_t dataChunkSize,
+                  bool isDirectAccess,
+                  vec<string> supportedDocTypes);
+
+    /**
+     * createCredential creates a new Credential.  When a Credential is created, two cryptographic
+     * keys are created: StorageKey, an AES key used to secure the externalized Credential
+     * contents, and CredentialKeyPair, an EC key pair used to authenticate the store to the IA.  In
+     * addition, all of the Credential data content is imported and a certificate for the
+     * CredentialKeyPair and a signature produced with the CredentialKeyPair are created.  These
+     * latter values may be checked by an issuing authority to verify that the data was imported
+     * into secure hardware and that it was imported unmodified.
+     *
+     * @param docType is an optional name (may be an empty string) that identifies the type of
+     *     credential being created, e.g. "org.iso.18013-5.2019.mdl" (the doc type of the ISO
+     *     driving license standard).
+     *
+     * @param testCredential indicates if this is a test store.  Test credentials must use an
+     *     all-zeros hardware-bound key (HBK) and must set the test bit in the
+     *     personalizationReceipt (see finishAddingEntries(), in IWritableIdentityCredential).
+     *
+     * @return result is OK on success, FAILED if an error occurred.
+     *
+     * @return writableCredential is an IWritableIdentityCredential HIDL interface that provides
+     *     operations to provision a credential.
+     */
+    createCredential(string docType, bool testCredential)
+        generates(Result result, IWritableIdentityCredential writableCredential);
+
+    /**
+     * getCredential retrieves an IIdentityCredential HIDL interface which allows use of a stored
+     * Credential.
+     *
+     * The cipher suite used to communicate with the remote verifier must also be specified. Currently
+     * only a single cipher-suite is supported and the details of this are as follow:
+     *
+     *  - ECDHE with HKDF-SHA-256 for key agreement.
+     *  - AES-256 with GCM block mode for authenticated encryption (nonces are incremented by one
+     *    for every message).
+     *  - ECDSA with SHA-256 for signing (used for signing session transcripts to defeat
+     *    man-in-the-middle attacks), signing keys are not ephemeral.
+     *
+     * Support for other cipher suites may be added in a future version of this HAL.
+     *
+     * @param credentialData is a CBOR-encoded structure containing metadata about the credential
+     *     and an encrypted byte array that contains data used to secure the credential.  See the
+     *     return argument of the same name in finishAddingEntries(), in IWritableIdentityCredential.
+     *
+     * @return result is OK on success or INVALID_DATA if the passed in credentialData
+     *     cannot be decoded or decrypted.
+     *
+     * @return credential is an IIdentityCredential HIDL interface that provides operations on the
+     *     Credential.
+     */
+    getCredential(vec<uint8_t> credentialData)
+        generates (Result result, IIdentityCredential credential);
+};
diff --git a/identity/1.0/IWritableIdentityCredential.hal b/identity/1.0/IWritableIdentityCredential.hal
new file mode 100644
index 0000000..b1ce00d
--- /dev/null
+++ b/identity/1.0/IWritableIdentityCredential.hal
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.identity@1.0;
+
+/**
+ * IWritableIdentityCredential is used to personalize a new identity credential.  Credentials cannot
+ * be updated or modified after creation; any changes require deletion and re-creation.
+ */
+interface IWritableIdentityCredential {
+    /**
+     * Gets the certificate chain for credentialKey which can be used to prove the hardware
+     * characteristics to an issuing authority.  Must not be called more than once.
+     *
+     * The certificate chain must be generated using Keymaster Attestation
+     * (see https://source.android.com/security/keystore/attestation) and must also
+     * have the Tag::IDENTITY_CREDENTIAL_KEY tag from KeyMaster 4.1 set. This tag indicates
+     * that this key is an Identity Credential key (which can only sign/MAC very
+     * specific messages) and not an Android Keystore key (which can be used to sign/MAC
+     * anything).
+     *
+     * @param attestationChallenge a challenge set by the issuer to ensure freshness.
+     *
+     * @return result is OK on success, FAILED if an error occurred.
+     *
+     * @return certificate is the X.509 certificate chain for the credentialKey
+     */
+    getAttestationCertificate(vec<uint8_t> attestationChallenge)
+        generates(Result result, vec<uint8_t> certificate);
+
+    /**
+     * Start the personalization process.
+     *
+     * startPersonalization must not be called more than once.
+     *
+     * @param accessControlProfileCount specifies the number of access control profiles that will be
+     *     provisioned with addAccessControlProfile().
+     *
+     * @param entryCounts specifies the number of data entries that will be provisioned with
+     *     beginAddEntry() and addEntry(). Each item in the array specifies how many entries
+     *     will be added for each name space.
+     *
+     * @return result is OK on success, FAILED if an error occurred.
+     *
+     */
+    startPersonalization(uint16_t accessControlProfileCount, vec<uint16_t> entryCounts)
+        generates(Result result);
+
+    /**
+     * Add an access control profile, which defines the requirements or retrieval of one or more
+     * entries.  If both readerCertificate and userAuthenticationRequired are empty/false,
+     * associated entries are open access, requiring no authentication to read (though the caller
+     * is free to require other authentication above this HAL).
+     *
+     * This method must be called exactly as many times as specified in the startPersonalization()
+     * accessControlProfileCount parameter. If this is requirement is not met, the method fails
+     * with INVALID_DATA.
+     *
+     * @param id a numeric identifier that must be unique within the context of a Credential and may
+     *     be used to reference the profile. If this is not satisfied the call fails with
+     *     INVALID_DATA.
+     *
+     * @param readerCertificate if non-empty, specifies a X.509 certificate (or chain of certificates)
+     *     that must be used to authenticate requests (see the readerSignature parameter in
+     *     IIdentityCredential.startRetrieval).
+     *
+     * @param userAuthenticationRequired if true, specifies that the user is required to
+     *     authenticate to allow requests.  Required authentication freshness is specified by
+     *     timeout below.
+     *
+     * @param timeoutMillis specifies the amount of time, in milliseconds, for which a user
+     *     authentication (see userAuthenticationRequired above) is valid, if
+     *     userAuthenticationRequired is true. If the timout is zero then authentication is
+     *     required for each reader session. If userAuthenticationRequired is false, the timeout
+     *     must be zero. If this requirement is not met the call fails with INVALID_DATA.
+     *
+     * @param secureUserId must be non-zero if userAuthenticationRequired is true. It is not
+     *     related to any Android user ID or UID, but is created in the Gatekeeper application
+     *     in the secure environment. If this requirement is not met the call fails with
+     *     INVALID_DATA.
+     *
+     * @return result is OK on success, INVALID_DATA or FAILED if an error occurred.
+     *
+     * @return secureAccessControlProfile is a structure with the passed-in data and MAC created
+     *     with storageKey for authenticating the data at a later point in time.
+     */
+    addAccessControlProfile(uint16_t id, vec<uint8_t> readerCertificate,
+                            bool userAuthenticationRequired, uint64_t timeoutMillis,
+                            uint64_t secureUserId)
+        generates(Result result, SecureAccessControlProfile secureAccessControlProfile);
+
+    /**
+     * Begins the process of adding an entry to the credential.  All access control profiles must be
+     * added before calling this method.  Entries must be added in namespace "groups", meaning all
+     * entries of one namespace must be added before adding entries from another namespace.
+     *
+     * This method must be called exactly as many times as the sum of the items in the entryCounts
+     * parameter specified in the startPersonalization(), and must be followed by one or more calls
+     * to addEntryValue(). If this requirement is not met the method fails with INVALID_DATA.
+     *
+     * @param accessControlProfileIds specifies the set of access control profiles that can
+     *     authorize access to the provisioned element.
+     *
+     * @param nameSpace is the namespace of the element, e.g. "org.iso.18013"
+     *
+     * @param name is the name of the element.
+     *
+     * @param entrySize is the size of the entry value. If this requirement
+     *     is not met this method fails with INVALID_DATA.
+     *
+     * @return result is OK on success, INVALID_DATA or FAILED if an error occurred.
+     */
+    beginAddEntry(vec<uint16_t> accessControlProfileIds, string nameSpace,
+                  string name, uint32_t entrySize)
+        generates(Result result);
+
+    /**
+     * Continues the process of adding an entry, providing a value or part of a value.
+     *
+     * In the common case, this method will be called only once per entry added.  In the case of
+     * values that are larger than the secure environment's GCM chunk size
+     * (see IIdentityCredentialStore.getHardwareInformation()), the caller must provide the
+     * value in chunks.  All chunks must be exactly gcmChunkSize except the last and the sum of all
+     * chunk sizes must equal the value of the beginAddEntry() entrySize argument. If this
+     * requirement is not met the call fails with INVALID_DATA.
+     *
+     * @param content is the entry value, encoded as CBOR. In the case the content exceeds gcmChunkSize,
+     *     this may be partial content up to gcmChunkSize bytes long.
+     *
+     * @return result is OK on success, INVALID_DATA or FAILED if an error occurred.
+     *
+     * @return encryptedContent contains the encrypted and MACed content.  For directly-available
+     *     credentials the contents are implementation-defined but must not exceed 32 bytes in
+     *     length.
+     *
+     *     For other credentials, encryptedContent contains:
+     *
+     *         AES-GCM-ENC(storageKey, R, Data, AdditionalData)
+     *
+     *     where:
+     *
+     *         Data = any   ; value
+     *
+     *         AdditionalData = {
+     *             "Namespace" : tstr,
+     *             "Name" : tstr,
+     *             "AccessControlProfileIds" : [ + uint ],
+     *         }
+     */
+    addEntryValue(vec<uint8_t> content)
+        generates(Result result, vec<uint8_t> encryptedContent);
+
+    /**
+     * Finishes adding entries and returns a signature that an issuing authority may use to validate
+     * that all data was provisioned correctly.
+     *
+     * After this method is called, the IWritableIdentityCredential is no longer usable.
+     *
+     * @return result is OK on success or FAILED if an error occurred.
+     *
+     * @return credentialData is a CBOR-encoded structure (in CDDL notation):
+     *
+     *         CredentialData = [
+     *              tstr,   ; docType, an optional name that identifies the type of credential
+     *              bool,   ; testCredential, indicates if this is a test credential
+     *              bstr    ; an opaque byte vector with encrypted data, see below
+     *         ]
+     *
+     *     The last element is an opaque byte vector which contains encrypted copies of the
+     *     secrets used to secure the new credential's data and to authenticate the credential to
+     *     the issuing authority.  It contains:
+     *
+     *         AES-GCM-ENC(HBK, R, CredentialKeys, docType)
+     *
+     *     where HBK is a unique hardware-bound key that has never existed outside of the secure
+     *     environment (except it's all zeroes if testCredential is True) and CredentialKeys is
+     *     the CBOR-encoded structure (in CDDL notation):
+     *
+     *         CredentialKeys = [
+     *              bstr,   ; storageKey, a 128-bit AES key
+     *              bstr    ; credentialPrivKey, the private key for credentialKey
+     *         ]
+     *
+     * @return proofOfProvisioningSignature proves to the IA that the credential was imported into the
+     *     secure hardware without alteration or error.  When the final addEntry() call is made
+     *     (when the number of provisioned entries equals the sum of the items in
+     *     startPersonalization() entryCounts parameter), it a COSE_Sign1 structure
+     *     signed by CredentialKey with payload set to the ProofOfProvisioning CBOR below:
+     *
+     *          ProofOfProvisioning = [
+     *              "ProofOfProvisioning",
+     *              tstr,                         ; DocType
+     *              [ * AccessControlProfile ],
+     *              ProvisionedData,
+     *              bool                          ; true if this is a test credential, should
+     *                                            ; always be false.
+     *          ]
+     *
+     *          AccessControlProfile = {
+     *              "id" : uint,
+     *              ? "readerCertificate" : bstr,
+     *              ? (
+     *                  "userAuthenticationRequired" : bool,
+     *                  "timeoutMillis" : uint,
+     *              )
+     *          }
+     *
+     *          ProvisionedData = {
+     *              * Namespace => [ + Entry ]
+     *          },
+     *
+     *          Namespace = tstr
+     *
+     *          Entry = {
+     *              "name" : tstr,
+     *              "value" : any,
+     *              "accessControlProfiles" : [ * uint ],
+     *          }
+     */
+    finishAddingEntries()
+        generates(Result result, vec<uint8_t> credentialData,
+                  vec<uint8_t> proofOfProvisioningSignature);
+};
diff --git a/identity/1.0/default/Android.bp b/identity/1.0/default/Android.bp
new file mode 100644
index 0000000..d2b2966
--- /dev/null
+++ b/identity/1.0/default/Android.bp
@@ -0,0 +1,43 @@
+//
+// 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.
+//
+
+cc_binary {
+    name: "android.hardware.identity@1.0-service.example",
+    init_rc: ["android.hardware.identity@1.0-service.example.rc"],
+    vendor: true,
+    relative_install_path: "hw",
+    cflags: [
+        "-Wall",
+        "-Wextra",
+    ],
+    srcs: [
+        "service.cpp",
+        "IdentityCredential.cpp",
+        "IdentityCredentialStore.cpp",
+        "WritableIdentityCredential.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.identity@1.0",
+        "android.hardware.identity-support-lib",
+        "android.hardware.keymaster@4.0",
+        "libcppbor",
+        "libcrypto",
+        "libbase",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+    ],
+}
diff --git a/identity/1.0/default/IdentityCredential.cpp b/identity/1.0/default/IdentityCredential.cpp
new file mode 100644
index 0000000..b0a5e56
--- /dev/null
+++ b/identity/1.0/default/IdentityCredential.cpp
@@ -0,0 +1,773 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "IdentityCredential"
+
+#include "IdentityCredential.h"
+#include "IdentityCredentialStore.h"
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <string.h>
+
+#include <android-base/logging.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+namespace android {
+namespace hardware {
+namespace identity {
+namespace implementation {
+
+using ::android::hardware::keymaster::V4_0::Timestamp;
+using ::std::optional;
+
+Return<void> IdentityCredential::deleteCredential(deleteCredential_cb _hidl_cb) {
+    cppbor::Array array = {"ProofOfDeletion", docType_, testCredential_};
+    vector<uint8_t> proofOfDeletion = array.encode();
+
+    optional<vector<uint8_t>> proofOfDeletionSignature =
+            support::coseSignEcDsa(credentialPrivKey_,
+                                   proofOfDeletion,  // payload
+                                   {},               // additionalData
+                                   {});              // certificateChain
+    if (!proofOfDeletionSignature) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error signing data"), {});
+        return Void();
+    }
+
+    _hidl_cb(support::resultOK(), proofOfDeletionSignature.value());
+    return Void();
+}
+
+Return<void> IdentityCredential::createEphemeralKeyPair(createEphemeralKeyPair_cb _hidl_cb) {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    if (!keyPair) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error creating ephemeral key pair"), {});
+        return Void();
+    }
+
+    // Stash public key of this key-pair for later check in startRetrieval().
+    optional<vector<uint8_t>> publicKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    if (!publicKey) {
+        _hidl_cb(support::result(ResultCode::FAILED,
+                                 "Error getting public part of ephemeral key pair"),
+                 {});
+        return Void();
+    }
+    ephemeralPublicKey_ = publicKey.value();
+
+    _hidl_cb(support::resultOK(), keyPair.value());
+    return Void();
+}
+
+Return<void> IdentityCredential::setReaderEphemeralPublicKey(
+        const hidl_vec<uint8_t>& publicKey, setReaderEphemeralPublicKey_cb _hidl_cb) {
+    readerPublicKey_ = publicKey;
+    _hidl_cb(support::resultOK());
+    return Void();
+}
+
+ResultCode IdentityCredential::initialize() {
+    auto [item, _, message] = cppbor::parse(credentialData_);
+    if (item == nullptr) {
+        LOG(ERROR) << "CredentialData is not valid CBOR: " << message;
+        return ResultCode::INVALID_DATA;
+    }
+
+    const cppbor::Array* arrayItem = item->asArray();
+    if (arrayItem == nullptr || arrayItem->size() != 3) {
+        LOG(ERROR) << "CredentialData is not an array with three elements";
+        return ResultCode::INVALID_DATA;
+    }
+
+    const cppbor::Tstr* docTypeItem = (*arrayItem)[0]->asTstr();
+    const cppbor::Bool* testCredentialItem =
+            ((*arrayItem)[1]->asSimple() != nullptr ? ((*arrayItem)[1]->asSimple()->asBool())
+                                                    : nullptr);
+    const cppbor::Bstr* encryptedCredentialKeysItem = (*arrayItem)[2]->asBstr();
+    if (docTypeItem == nullptr || testCredentialItem == nullptr ||
+        encryptedCredentialKeysItem == nullptr) {
+        LOG(ERROR) << "CredentialData unexpected item types";
+        return ResultCode::INVALID_DATA;
+    }
+
+    docType_ = docTypeItem->value();
+    testCredential_ = testCredentialItem->value();
+
+    vector<uint8_t> hardwareBoundKey;
+    if (testCredential_) {
+        hardwareBoundKey = support::getTestHardwareBoundKey();
+    } else {
+        hardwareBoundKey = support::getHardwareBoundKey();
+    }
+
+    const vector<uint8_t>& encryptedCredentialKeys = encryptedCredentialKeysItem->value();
+    const vector<uint8_t> docTypeVec(docType_.begin(), docType_.end());
+    optional<vector<uint8_t>> decryptedCredentialKeys =
+            support::decryptAes128Gcm(hardwareBoundKey, encryptedCredentialKeys, docTypeVec);
+    if (!decryptedCredentialKeys) {
+        LOG(ERROR) << "Error decrypting CredentialKeys";
+        return ResultCode::INVALID_DATA;
+    }
+
+    auto [dckItem, dckPos, dckMessage] = cppbor::parse(decryptedCredentialKeys.value());
+    if (dckItem == nullptr) {
+        LOG(ERROR) << "Decrypted CredentialKeys is not valid CBOR: " << dckMessage;
+        return ResultCode::INVALID_DATA;
+    }
+    const cppbor::Array* dckArrayItem = dckItem->asArray();
+    if (dckArrayItem == nullptr || dckArrayItem->size() != 2) {
+        LOG(ERROR) << "Decrypted CredentialKeys is not an array with two elements";
+        return ResultCode::INVALID_DATA;
+    }
+    const cppbor::Bstr* storageKeyItem = (*dckArrayItem)[0]->asBstr();
+    const cppbor::Bstr* credentialPrivKeyItem = (*dckArrayItem)[1]->asBstr();
+    if (storageKeyItem == nullptr || credentialPrivKeyItem == nullptr) {
+        LOG(ERROR) << "CredentialKeys unexpected item types";
+        return ResultCode::INVALID_DATA;
+    }
+    storageKey_ = storageKeyItem->value();
+    credentialPrivKey_ = credentialPrivKeyItem->value();
+
+    return ResultCode::OK;
+}
+
+Return<void> IdentityCredential::createAuthChallenge(createAuthChallenge_cb _hidl_cb) {
+    uint64_t challenge = 0;
+    while (challenge == 0) {
+        optional<vector<uint8_t>> bytes = support::getRandom(8);
+        if (!bytes) {
+            _hidl_cb(support::result(ResultCode::FAILED, "Error getting random data for challenge"),
+                     0);
+            return Void();
+        }
+
+        challenge = 0;
+        for (size_t n = 0; n < bytes.value().size(); n++) {
+            challenge |= ((bytes.value())[n] << (n * 8));
+        }
+    }
+
+    authChallenge_ = challenge;
+    _hidl_cb(support::resultOK(), challenge);
+    return Void();
+}
+
+// TODO: this could be a lot faster if we did all the splitting and pubkey extraction
+// ahead of time.
+bool checkReaderAuthentication(const SecureAccessControlProfile& profile,
+                               const vector<uint8_t>& readerCertificateChain) {
+    optional<vector<uint8_t>> acpPubKey =
+            support::certificateChainGetTopMostKey(profile.readerCertificate);
+    if (!acpPubKey) {
+        LOG(ERROR) << "Error extracting public key from readerCertificate in profile";
+        return false;
+    }
+
+    optional<vector<vector<uint8_t>>> certificatesInChain =
+            support::certificateChainSplit(readerCertificateChain);
+    if (!certificatesInChain) {
+        LOG(ERROR) << "Error splitting readerCertificateChain";
+        return false;
+    }
+    for (const vector<uint8_t>& certInChain : certificatesInChain.value()) {
+        optional<vector<uint8_t>> certPubKey = support::certificateChainGetTopMostKey(certInChain);
+        if (!certPubKey) {
+            LOG(ERROR)
+                    << "Error extracting public key from certificate in chain presented by reader";
+            return false;
+        }
+        if (acpPubKey.value() == certPubKey.value()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+Timestamp clockGetTime() {
+    struct timespec time;
+    clock_gettime(CLOCK_MONOTONIC, &time);
+    return time.tv_sec * 1000 + time.tv_nsec / 1000000;
+}
+
+bool checkUserAuthentication(const SecureAccessControlProfile& profile,
+                             const HardwareAuthToken& authToken, uint64_t authChallenge) {
+    if (profile.secureUserId != authToken.userId) {
+        LOG(ERROR) << "secureUserId in profile (" << profile.secureUserId
+                   << ") differs from userId in authToken (" << authToken.userId << ")";
+        return false;
+    }
+
+    if (profile.timeoutMillis == 0) {
+        if (authToken.challenge == 0) {
+            LOG(ERROR) << "No challenge in authToken";
+            return false;
+        }
+
+        if (authToken.challenge != authChallenge) {
+            LOG(ERROR) << "Challenge in authToken doesn't match the challenge we created";
+            return false;
+        }
+        return true;
+    }
+
+    // Note that the Epoch for timestamps in HardwareAuthToken is at the
+    // discretion of the vendor:
+    //
+    //   "[...] since some starting point (generally the most recent device
+    //    boot) which all of the applications within one secure environment
+    //    must agree upon."
+    //
+    // Therefore, if this software implementation is used on a device which isn't
+    // the emulator then the assumption that the epoch is the same as used in
+    // clockGetTime above will not hold. This is OK as this software
+    // implementation should never be used on a real device.
+    //
+    Timestamp now = clockGetTime();
+    if (authToken.timestamp > now) {
+        LOG(ERROR) << "Timestamp in authToken (" << authToken.timestamp
+                   << ") is in the future (now: " << now << ")";
+        return false;
+    }
+    if (now > authToken.timestamp + profile.timeoutMillis) {
+        LOG(ERROR) << "Deadline for authToken (" << authToken.timestamp << " + "
+                   << profile.timeoutMillis << " = "
+                   << (authToken.timestamp + profile.timeoutMillis)
+                   << ") is in the past (now: " << now << ")";
+        return false;
+    }
+
+    return true;
+}
+
+Return<void> IdentityCredential::startRetrieval(
+        const hidl_vec<SecureAccessControlProfile>& accessControlProfiles,
+        const HardwareAuthToken& authToken, const hidl_vec<uint8_t>& itemsRequest,
+        const hidl_vec<uint8_t>& sessionTranscript, const hidl_vec<uint8_t>& readerSignature,
+        const hidl_vec<uint16_t>& requestCounts, startRetrieval_cb _hidl_cb) {
+    if (sessionTranscript.size() > 0) {
+        auto [item, _, message] = cppbor::parse(sessionTranscript);
+        if (item == nullptr) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                     "SessionTranscript contains invalid CBOR"));
+            return Void();
+        }
+        sessionTranscriptItem_ = std::move(item);
+    }
+    if (numStartRetrievalCalls_ > 0) {
+        if (sessionTranscript_ != vector<uint8_t>(sessionTranscript)) {
+            _hidl_cb(support::result(
+                    ResultCode::SESSION_TRANSCRIPT_MISMATCH,
+                    "Passed-in SessionTranscript doesn't match previously used SessionTranscript"));
+            return Void();
+        }
+    }
+    sessionTranscript_ = sessionTranscript;
+
+    // If there is a signature, validate that it was made with the top-most key in the
+    // certificate chain embedded in the COSE_Sign1 structure.
+    optional<vector<uint8_t>> readerCertificateChain;
+    if (readerSignature.size() > 0) {
+        readerCertificateChain = support::coseSignGetX5Chain(readerSignature);
+        if (!readerCertificateChain) {
+            _hidl_cb(support::result(ResultCode::READER_SIGNATURE_CHECK_FAILED,
+                                     "Unable to get reader certificate chain from COSE_Sign1"));
+            return Void();
+        }
+
+        if (!support::certificateChainValidate(readerCertificateChain.value())) {
+            _hidl_cb(support::result(ResultCode::READER_SIGNATURE_CHECK_FAILED,
+                                     "Error validating reader certificate chain"));
+            return Void();
+        }
+
+        optional<vector<uint8_t>> readerPublicKey =
+                support::certificateChainGetTopMostKey(readerCertificateChain.value());
+        if (!readerPublicKey) {
+            _hidl_cb(support::result(ResultCode::READER_SIGNATURE_CHECK_FAILED,
+                                     "Unable to get public key from reader certificate chain"));
+            return Void();
+        }
+
+        const vector<uint8_t>& itemsRequestBytes = itemsRequest;
+        vector<uint8_t> dataThatWasSigned = cppbor::Array()
+                                                    .add("ReaderAuthentication")
+                                                    .add(sessionTranscriptItem_->clone())
+                                                    .add(cppbor::Semantic(24, itemsRequestBytes))
+                                                    .encode();
+        if (!support::coseCheckEcDsaSignature(readerSignature,
+                                              dataThatWasSigned,  // detached content
+                                              readerPublicKey.value())) {
+            _hidl_cb(support::result(ResultCode::READER_SIGNATURE_CHECK_FAILED,
+                                     "readerSignature check failed"));
+            return Void();
+        }
+    }
+
+    // Here's where we would validate the passed-in |authToken| to assure ourselves
+    // that it comes from the e.g. biometric hardware and wasn't made up by an attacker.
+    //
+    // However this involves calculating the MAC. However this requires access
+    // to the key needed to a pre-shared key which we don't have...
+    //
+
+    // To prevent replay-attacks, we check that the public part of the ephemeral
+    // key we previously created, is present in the DeviceEngagement part of
+    // SessionTranscript as a COSE_Key, in uncompressed form.
+    //
+    // We do this by just searching for the X and Y coordinates.
+    if (sessionTranscript.size() > 0) {
+        const cppbor::Array* array = sessionTranscriptItem_->asArray();
+        if (array == nullptr || array->size() != 2) {
+            _hidl_cb(support::result(ResultCode::EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
+                                     "SessionTranscript is not an array with two items"));
+            return Void();
+        }
+        const cppbor::Semantic* taggedEncodedDE = (*array)[0]->asSemantic();
+        if (taggedEncodedDE == nullptr || taggedEncodedDE->value() != 24) {
+            _hidl_cb(support::result(ResultCode::EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
+                                     "First item in SessionTranscript array is not a "
+                                     "semantic with value 24"));
+            return Void();
+        }
+        const cppbor::Bstr* encodedDE = (taggedEncodedDE->child())->asBstr();
+        if (encodedDE == nullptr) {
+            _hidl_cb(support::result(ResultCode::EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
+                                     "Child of semantic in first item in SessionTranscript "
+                                     "array is not a bstr"));
+            return Void();
+        }
+        const vector<uint8_t>& bytesDE = encodedDE->value();
+
+        auto [getXYSuccess, ePubX, ePubY] = support::ecPublicKeyGetXandY(ephemeralPublicKey_);
+        if (!getXYSuccess) {
+            _hidl_cb(support::result(ResultCode::EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
+                                     "Error extracting X and Y from ePub"));
+            return Void();
+        }
+        if (sessionTranscript.size() > 0 &&
+            !(memmem(bytesDE.data(), bytesDE.size(), ePubX.data(), ePubX.size()) != nullptr &&
+              memmem(bytesDE.data(), bytesDE.size(), ePubY.data(), ePubY.size()) != nullptr)) {
+            _hidl_cb(support::result(ResultCode::EPHEMERAL_PUBLIC_KEY_NOT_FOUND,
+                                     "Did not find ephemeral public key's X and Y coordinates in "
+                                     "SessionTranscript (make sure leading zeroes are not used)"));
+            return Void();
+        }
+    }
+
+    // itemsRequest: If non-empty, contains request data that may be signed by the
+    // reader.  The content can be defined in the way appropriate for the
+    // credential, but there are three requirements that must be met to work with
+    // this HAL:
+    if (itemsRequest.size() > 0) {
+        // 1. The content must be a CBOR-encoded structure.
+        auto [item, _, message] = cppbor::parse(itemsRequest);
+        if (item == nullptr) {
+            _hidl_cb(support::result(ResultCode::INVALID_ITEMS_REQUEST_MESSAGE,
+                                     "Error decoding CBOR in itemsRequest: %s", message.c_str()));
+            return Void();
+        }
+
+        // 2. The CBOR structure must be a map.
+        const cppbor::Map* map = item->asMap();
+        if (map == nullptr) {
+            _hidl_cb(support::result(ResultCode::INVALID_ITEMS_REQUEST_MESSAGE,
+                                     "itemsRequest is not a CBOR map"));
+            return Void();
+        }
+
+        // 3. The map must contain a key "nameSpaces" whose value contains a map, as described in
+        //    the example below.
+        //
+        //   NameSpaces = {
+        //     + NameSpace => DataElements ; Requested data elements for each NameSpace
+        //   }
+        //
+        //   NameSpace = tstr
+        //
+        //   DataElements = {
+        //     + DataElement => IntentToRetain
+        //   }
+        //
+        //   DataElement = tstr
+        //   IntentToRetain = bool
+        //
+        // Here's an example of an |itemsRequest| CBOR value satisfying above requirements 1.
+        // through 3.:
+        //
+        //    {
+        //        'docType' : 'org.iso.18013-5.2019',
+        //        'nameSpaces' : {
+        //            'org.iso.18013-5.2019' : {
+        //                'Last name' : false,
+        //                'Birth date' : false,
+        //                'First name' : false,
+        //                'Home address' : true
+        //            },
+        //            'org.aamva.iso.18013-5.2019' : {
+        //                'Real Id' : false
+        //            }
+        //        }
+        //    }
+        //
+        const cppbor::Map* nsMap = nullptr;
+        for (size_t n = 0; n < map->size(); n++) {
+            const auto& [keyItem, valueItem] = (*map)[n];
+            if (keyItem->type() == cppbor::TSTR && keyItem->asTstr()->value() == "nameSpaces" &&
+                valueItem->type() == cppbor::MAP) {
+                nsMap = valueItem->asMap();
+                break;
+            }
+        }
+        if (nsMap == nullptr) {
+            _hidl_cb(support::result(ResultCode::INVALID_ITEMS_REQUEST_MESSAGE,
+                                     "No nameSpaces map in top-most map"));
+            return Void();
+        }
+
+        for (size_t n = 0; n < nsMap->size(); n++) {
+            auto [nsKeyItem, nsValueItem] = (*nsMap)[n];
+            const cppbor::Tstr* nsKey = nsKeyItem->asTstr();
+            const cppbor::Map* nsInnerMap = nsValueItem->asMap();
+            if (nsKey == nullptr || nsInnerMap == nullptr) {
+                _hidl_cb(support::result(ResultCode::INVALID_ITEMS_REQUEST_MESSAGE,
+                                         "Type mismatch in nameSpaces map"));
+                return Void();
+            }
+            string requestedNamespace = nsKey->value();
+            vector<string> requestedKeys;
+            for (size_t m = 0; m < nsInnerMap->size(); m++) {
+                const auto& [innerMapKeyItem, innerMapValueItem] = (*nsInnerMap)[m];
+                const cppbor::Tstr* nameItem = innerMapKeyItem->asTstr();
+                const cppbor::Simple* simple = innerMapValueItem->asSimple();
+                const cppbor::Bool* intentToRetainItem =
+                        (simple != nullptr) ? simple->asBool() : nullptr;
+                if (nameItem == nullptr || intentToRetainItem == nullptr) {
+                    _hidl_cb(support::result(ResultCode::INVALID_ITEMS_REQUEST_MESSAGE,
+                                             "Type mismatch in value in nameSpaces map"));
+                    return Void();
+                }
+                requestedKeys.push_back(nameItem->value());
+            }
+            requestedNameSpacesAndNames_[requestedNamespace] = requestedKeys;
+        }
+    }
+
+    // Finally, validate all the access control profiles in the requestData.
+    bool haveAuthToken = (authToken.mac.size() > 0);
+    for (const auto& profile : accessControlProfiles) {
+        if (!support::secureAccessControlProfileCheckMac(profile, storageKey_)) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                     "Error checking MAC for profile with id %d", int(profile.id)));
+            return Void();
+        }
+        ResultCode accessControlCheck = ResultCode::OK;
+        if (profile.userAuthenticationRequired) {
+            if (!haveAuthToken || !checkUserAuthentication(profile, authToken, authChallenge_)) {
+                accessControlCheck = ResultCode::USER_AUTHENTICATION_FAILED;
+            }
+        } else if (profile.readerCertificate.size() > 0) {
+            if (!readerCertificateChain ||
+                !checkReaderAuthentication(profile, readerCertificateChain.value())) {
+                accessControlCheck = ResultCode::READER_AUTHENTICATION_FAILED;
+            }
+        }
+        profileIdToAccessCheckResult_[profile.id] = accessControlCheck;
+    }
+
+    deviceNameSpacesMap_ = cppbor::Map();
+    currentNameSpaceDeviceNameSpacesMap_ = cppbor::Map();
+
+    requestCountsRemaining_ = requestCounts;
+    currentNameSpace_ = "";
+
+    itemsRequest_ = itemsRequest;
+
+    numStartRetrievalCalls_ += 1;
+    _hidl_cb(support::resultOK());
+    return Void();
+}
+
+Return<void> IdentityCredential::startRetrieveEntryValue(
+        const hidl_string& nameSpace, const hidl_string& name, uint32_t entrySize,
+        const hidl_vec<uint16_t>& accessControlProfileIds, startRetrieveEntryValue_cb _hidl_cb) {
+    if (name.empty()) {
+        _hidl_cb(support::result(ResultCode::INVALID_DATA, "Name cannot be empty"));
+        return Void();
+    }
+    if (nameSpace.empty()) {
+        _hidl_cb(support::result(ResultCode::INVALID_DATA, "Name space cannot be empty"));
+        return Void();
+    }
+
+    if (requestCountsRemaining_.size() == 0) {
+        _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                 "No more name spaces left to go through"));
+        return Void();
+    }
+
+    if (currentNameSpace_ == "") {
+        // First call.
+        currentNameSpace_ = nameSpace;
+    }
+
+    if (nameSpace == currentNameSpace_) {
+        // Same namespace.
+        if (requestCountsRemaining_[0] == 0) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                     "No more entries to be retrieved in current name space"));
+            return Void();
+        }
+        requestCountsRemaining_[0] -= 1;
+    } else {
+        // New namespace.
+        if (requestCountsRemaining_[0] != 0) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                     "Moved to new name space but %d entries need to be retrieved "
+                                     "in current name space",
+                                     int(requestCountsRemaining_[0])));
+            return Void();
+        }
+        if (currentNameSpaceDeviceNameSpacesMap_.size() > 0) {
+            deviceNameSpacesMap_.add(currentNameSpace_,
+                                     std::move(currentNameSpaceDeviceNameSpacesMap_));
+        }
+        currentNameSpaceDeviceNameSpacesMap_ = cppbor::Map();
+
+        requestCountsRemaining_.erase(requestCountsRemaining_.begin());
+        currentNameSpace_ = nameSpace;
+    }
+
+    // It's permissible to have an empty itemsRequest... but if non-empty you can
+    // only request what was specified in said itemsRequest. Enforce that.
+    if (itemsRequest_.size() > 0) {
+        const auto& it = requestedNameSpacesAndNames_.find(nameSpace);
+        if (it == requestedNameSpacesAndNames_.end()) {
+            _hidl_cb(support::result(ResultCode::NOT_IN_REQUEST_MESSAGE,
+                                     "Name space '%s' was not requested in startRetrieval",
+                                     nameSpace.c_str()));
+            return Void();
+        }
+        const auto& dataItemNames = it->second;
+        if (std::find(dataItemNames.begin(), dataItemNames.end(), name) == dataItemNames.end()) {
+            _hidl_cb(support::result(
+                    ResultCode::NOT_IN_REQUEST_MESSAGE,
+                    "Data item name '%s' in name space '%s' was not requested in startRetrieval",
+                    name.c_str(), nameSpace.c_str()));
+            return Void();
+        }
+    }
+
+    // Enforce access control.
+    //
+    // Access is granted if at least one of the profiles grants access.
+    //
+    // If an item is configured without any profiles, access is denied.
+    //
+    ResultCode accessControl = ResultCode::NO_ACCESS_CONTROL_PROFILES;
+    for (auto id : accessControlProfileIds) {
+        auto search = profileIdToAccessCheckResult_.find(id);
+        if (search == profileIdToAccessCheckResult_.end()) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                     "Requested entry with unvalidated profile id %d", (int(id))));
+            return Void();
+        }
+        ResultCode accessControlForProfile = search->second;
+        if (accessControlForProfile == ResultCode::OK) {
+            accessControl = ResultCode::OK;
+            break;
+        }
+        accessControl = accessControlForProfile;
+    }
+    if (accessControl != ResultCode::OK) {
+        _hidl_cb(support::result(accessControl, "Access control check failed"));
+        return Void();
+    }
+
+    entryAdditionalData_ =
+            support::entryCreateAdditionalData(nameSpace, name, accessControlProfileIds);
+
+    currentName_ = name;
+    entryRemainingBytes_ = entrySize;
+    entryValue_.resize(0);
+
+    _hidl_cb(support::resultOK());
+    return Void();
+}
+
+Return<void> IdentityCredential::retrieveEntryValue(const hidl_vec<uint8_t>& encryptedContent,
+                                                    retrieveEntryValue_cb _hidl_cb) {
+    optional<vector<uint8_t>> content =
+            support::decryptAes128Gcm(storageKey_, encryptedContent, entryAdditionalData_);
+    if (!content) {
+        _hidl_cb(support::result(ResultCode::INVALID_DATA, "Error decrypting data"), {});
+        return Void();
+    }
+
+    size_t chunkSize = content.value().size();
+
+    if (chunkSize > entryRemainingBytes_) {
+        LOG(ERROR) << "Retrieved chunk of size " << chunkSize
+                   << " is bigger than remaining space of size " << entryRemainingBytes_;
+        _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                 "Retrieved chunk of size %zd is bigger than remaining space "
+                                 "of size %zd",
+                                 chunkSize, entryRemainingBytes_),
+                 {});
+        return Void();
+    }
+
+    entryRemainingBytes_ -= chunkSize;
+    if (entryRemainingBytes_ > 0) {
+        if (chunkSize != IdentityCredentialStore::kGcmChunkSize) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA,
+                                     "Retrieved non-final chunk of size %zd but expected "
+                                     "kGcmChunkSize which is %zd",
+                                     chunkSize, IdentityCredentialStore::kGcmChunkSize),
+                     {});
+            return Void();
+        }
+    }
+
+    entryValue_.insert(entryValue_.end(), content.value().begin(), content.value().end());
+
+    if (entryRemainingBytes_ == 0) {
+        auto [entryValueItem, _, message] = cppbor::parse(entryValue_);
+        if (entryValueItem == nullptr) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA, "Retrieved data invalid CBOR"), {});
+            return Void();
+        }
+        currentNameSpaceDeviceNameSpacesMap_.add(currentName_, std::move(entryValueItem));
+    }
+
+    _hidl_cb(support::resultOK(), content.value());
+    return Void();
+}
+
+Return<void> IdentityCredential::finishRetrieval(const hidl_vec<uint8_t>& signingKeyBlob,
+                                                 finishRetrieval_cb _hidl_cb) {
+    if (currentNameSpaceDeviceNameSpacesMap_.size() > 0) {
+        deviceNameSpacesMap_.add(currentNameSpace_,
+                                 std::move(currentNameSpaceDeviceNameSpacesMap_));
+    }
+    vector<uint8_t> encodedDeviceNameSpaces = deviceNameSpacesMap_.encode();
+
+    // If there's no signing key or no sessionTranscript or no reader ephemeral
+    // public key, we return the empty MAC.
+    optional<vector<uint8_t>> mac;
+    if (signingKeyBlob.size() > 0 && sessionTranscript_.size() > 0 && readerPublicKey_.size() > 0) {
+        cppbor::Array array;
+        array.add("DeviceAuthentication");
+        array.add(sessionTranscriptItem_->clone());
+        array.add(docType_);
+        array.add(cppbor::Semantic(24, encodedDeviceNameSpaces));
+        vector<uint8_t> encodedDeviceAuthentication = array.encode();
+
+        vector<uint8_t> docTypeAsBlob(docType_.begin(), docType_.end());
+        optional<vector<uint8_t>> signingKey =
+                support::decryptAes128Gcm(storageKey_, signingKeyBlob, docTypeAsBlob);
+        if (!signingKey) {
+            _hidl_cb(support::result(ResultCode::INVALID_DATA, "Error decrypting signingKeyBlob"),
+                     {}, {});
+            return Void();
+        }
+
+        optional<vector<uint8_t>> sharedSecret =
+                support::ecdh(readerPublicKey_, signingKey.value());
+        if (!sharedSecret) {
+            _hidl_cb(support::result(ResultCode::FAILED, "Error doing ECDH"), {}, {});
+            return Void();
+        }
+
+        vector<uint8_t> salt = {0x00};
+        vector<uint8_t> info = {};
+        optional<vector<uint8_t>> derivedKey = support::hkdf(sharedSecret.value(), salt, info, 32);
+        if (!derivedKey) {
+            _hidl_cb(support::result(ResultCode::FAILED, "Error deriving key from shared secret"),
+                     {}, {});
+            return Void();
+        }
+
+        mac = support::coseMac0(derivedKey.value(), {},        // payload
+                                encodedDeviceAuthentication);  // additionalData
+        if (!mac) {
+            _hidl_cb(support::result(ResultCode::FAILED, "Error MACing data"), {}, {});
+            return Void();
+        }
+    }
+
+    _hidl_cb(support::resultOK(), mac.value_or(vector<uint8_t>({})), encodedDeviceNameSpaces);
+    return Void();
+}
+
+Return<void> IdentityCredential::generateSigningKeyPair(generateSigningKeyPair_cb _hidl_cb) {
+    string serialDecimal = "0";  // TODO: set serial to something unique
+    string issuer = "Android Open Source Project";
+    string subject = "Android IdentityCredential Reference Implementation";
+    time_t validityNotBefore = time(nullptr);
+    time_t validityNotAfter = validityNotBefore + 365 * 24 * 3600;
+
+    optional<vector<uint8_t>> signingKeyPKCS8 = support::createEcKeyPair();
+    if (!signingKeyPKCS8) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error creating signingKey"), {}, {});
+        return Void();
+    }
+
+    optional<vector<uint8_t>> signingPublicKey =
+            support::ecKeyPairGetPublicKey(signingKeyPKCS8.value());
+    if (!signingPublicKey) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error getting public part of signingKey"), {},
+                 {});
+        return Void();
+    }
+
+    optional<vector<uint8_t>> signingKey = support::ecKeyPairGetPrivateKey(signingKeyPKCS8.value());
+    if (!signingKey) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error getting private part of signingKey"),
+                 {}, {});
+        return Void();
+    }
+
+    optional<vector<uint8_t>> certificate = support::ecPublicKeyGenerateCertificate(
+            signingPublicKey.value(), credentialPrivKey_, serialDecimal, issuer, subject,
+            validityNotBefore, validityNotAfter);
+    if (!certificate) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error creating signingKey"), {}, {});
+        return Void();
+    }
+
+    optional<vector<uint8_t>> nonce = support::getRandom(12);
+    if (!nonce) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error getting random"), {}, {});
+        return Void();
+    }
+    vector<uint8_t> docTypeAsBlob(docType_.begin(), docType_.end());
+    optional<vector<uint8_t>> encryptedSigningKey = support::encryptAes128Gcm(
+            storageKey_, nonce.value(), signingKey.value(), docTypeAsBlob);
+    if (!encryptedSigningKey) {
+        _hidl_cb(support::result(ResultCode::FAILED, "Error encrypting signingKey"), {}, {});
+        return Void();
+    }
+    _hidl_cb(support::resultOK(), encryptedSigningKey.value(), certificate.value());
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
diff --git a/identity/1.0/default/IdentityCredential.h b/identity/1.0/default/IdentityCredential.h
new file mode 100644
index 0000000..eb8787b
--- /dev/null
+++ b/identity/1.0/default/IdentityCredential.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIAL_H
+#define ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIAL_H
+
+#include <android/hardware/identity/1.0/IIdentityCredential.h>
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <cppbor/cppbor.h>
+
+namespace android {
+namespace hardware {
+namespace identity {
+namespace implementation {
+
+using ::std::map;
+using ::std::string;
+using ::std::vector;
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::identity::V1_0::IIdentityCredential;
+using ::android::hardware::identity::V1_0::Result;
+using ::android::hardware::identity::V1_0::ResultCode;
+using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
+using ::android::hardware::keymaster::V4_0::HardwareAuthToken;
+
+using MapStringToVectorOfStrings = map<string, vector<string>>;
+
+class IdentityCredential : public IIdentityCredential {
+  public:
+    IdentityCredential(const hidl_vec<uint8_t>& credentialData)
+        : credentialData_(credentialData), numStartRetrievalCalls_(0), authChallenge_(0) {}
+
+    // Parses and decrypts credentialData_, return false on failure. Must be
+    // called right after construction.
+    ResultCode initialize();
+
+    // Methods from ::android::hardware::identity::IIdentityCredential follow.
+
+    Return<void> deleteCredential(deleteCredential_cb _hidl_cb) override;
+    Return<void> createEphemeralKeyPair(createEphemeralKeyPair_cb _hidl_cb) override;
+
+    Return<void> setReaderEphemeralPublicKey(const hidl_vec<uint8_t>& publicKey,
+                                             setReaderEphemeralPublicKey_cb _hidl_cb) override;
+
+    Return<void> createAuthChallenge(createAuthChallenge_cb _hidl_cb) override;
+
+    Return<void> startRetrieval(const hidl_vec<SecureAccessControlProfile>& accessControlProfiles,
+                                const HardwareAuthToken& authToken,
+                                const hidl_vec<uint8_t>& itemsRequest,
+                                const hidl_vec<uint8_t>& sessionTranscript,
+                                const hidl_vec<uint8_t>& readerSignature,
+                                const hidl_vec<uint16_t>& requestCounts,
+                                startRetrieval_cb _hidl_cb) override;
+    Return<void> startRetrieveEntryValue(const hidl_string& nameSpace, const hidl_string& name,
+                                         uint32_t entrySize,
+                                         const hidl_vec<uint16_t>& accessControlProfileIds,
+                                         startRetrieveEntryValue_cb _hidl_cb) override;
+    Return<void> retrieveEntryValue(const hidl_vec<uint8_t>& encryptedContent,
+                                    retrieveEntryValue_cb _hidl_cb) override;
+    Return<void> finishRetrieval(const hidl_vec<uint8_t>& signingKeyBlob,
+                                 finishRetrieval_cb _hidl_cb) override;
+
+    Return<void> generateSigningKeyPair(generateSigningKeyPair_cb _hidl_cb) override;
+
+  private:
+    // Set by constructor
+    vector<uint8_t> credentialData_;
+    int numStartRetrievalCalls_;
+
+    // Set by initialize()
+    string docType_;
+    bool testCredential_;
+    vector<uint8_t> storageKey_;
+    vector<uint8_t> credentialPrivKey_;
+
+    // Set by createEphemeralKeyPair()
+    vector<uint8_t> ephemeralPublicKey_;
+
+    // Set by setReaderEphemeralPublicKey()
+    vector<uint8_t> readerPublicKey_;
+
+    // Set by createAuthChallenge()
+    uint64_t authChallenge_;
+
+    // Set at startRetrieval() time.
+    map<uint16_t, ResultCode> profileIdToAccessCheckResult_;
+    vector<uint8_t> sessionTranscript_;
+    std::unique_ptr<cppbor::Item> sessionTranscriptItem_;
+    vector<uint8_t> itemsRequest_;
+    vector<uint16_t> requestCountsRemaining_;
+    MapStringToVectorOfStrings requestedNameSpacesAndNames_;
+    cppbor::Map deviceNameSpacesMap_;
+    cppbor::Map currentNameSpaceDeviceNameSpacesMap_;
+
+    // Set at startRetrieveEntryValue() time.
+    string currentNameSpace_;
+    string currentName_;
+    size_t entryRemainingBytes_;
+    vector<uint8_t> entryValue_;
+    vector<uint8_t> entryAdditionalData_;
+};
+
+}  // namespace implementation
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIAL_H
diff --git a/identity/1.0/default/IdentityCredentialStore.cpp b/identity/1.0/default/IdentityCredentialStore.cpp
new file mode 100644
index 0000000..9eb1e70
--- /dev/null
+++ b/identity/1.0/default/IdentityCredentialStore.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "IdentityCredentialStore"
+
+#include "IdentityCredentialStore.h"
+#include "IdentityCredential.h"
+#include "WritableIdentityCredential.h"
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace hardware {
+namespace identity {
+namespace implementation {
+
+// Methods from ::android::hardware::identity::IIdentityCredentialStore follow.
+
+Return<void> IdentityCredentialStore::getHardwareInformation(getHardwareInformation_cb _hidl_cb) {
+    _hidl_cb(support::resultOK(), "IdentityCredential Reference Implementation", "Google",
+             kGcmChunkSize, false /* isDirectAccess */, {} /* supportedDocTypes */);
+    return Void();
+}
+
+Return<void> IdentityCredentialStore::createCredential(const hidl_string& docType,
+                                                       bool testCredential,
+                                                       createCredential_cb _hidl_cb) {
+    auto writable_credential = new WritableIdentityCredential(docType, testCredential);
+    if (!writable_credential->initialize()) {
+        _hidl_cb(support::result(ResultCode::FAILED,
+                                 "Error initializing WritableIdentityCredential"),
+                 writable_credential);
+        return Void();
+    }
+    _hidl_cb(support::resultOK(), writable_credential);
+    return Void();
+}
+
+Return<void> IdentityCredentialStore::getCredential(const hidl_vec<uint8_t>& credentialData,
+                                                    getCredential_cb _hidl_cb) {
+    auto credential = new IdentityCredential(credentialData);
+    // We only support CIPHERSUITE_ECDHE_HKDF_ECDSA_WITH_AES_256_GCM_SHA256 right now.
+    auto ret = credential->initialize();
+    if (ret != ResultCode::OK) {
+        _hidl_cb(support::result(ret, "Error initializing IdentityCredential"), credential);
+        return Void();
+    }
+    _hidl_cb(support::resultOK(), credential);
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
diff --git a/identity/1.0/default/IdentityCredentialStore.h b/identity/1.0/default/IdentityCredentialStore.h
new file mode 100644
index 0000000..ad75360
--- /dev/null
+++ b/identity/1.0/default/IdentityCredentialStore.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIALSTORE_H
+#define ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIALSTORE_H
+
+#include <android/hardware/identity/1.0/IIdentityCredentialStore.h>
+
+namespace android {
+namespace hardware {
+namespace identity {
+namespace implementation {
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::identity::V1_0::IIdentityCredentialStore;
+using ::android::hardware::identity::V1_0::Result;
+using ::android::hardware::identity::V1_0::ResultCode;
+
+class IdentityCredentialStore : public IIdentityCredentialStore {
+  public:
+    IdentityCredentialStore() {}
+
+    // The GCM chunk size used by this implementation is 64 KiB.
+    static constexpr size_t kGcmChunkSize = 64 * 1024;
+
+    // Methods from ::android::hardware::identity::IIdentityCredentialStore follow.
+    Return<void> getHardwareInformation(getHardwareInformation_cb _hidl_cb) override;
+    Return<void> createCredential(const hidl_string& docType, bool testCredential,
+                                  createCredential_cb _hidl_cb) override;
+    Return<void> getCredential(const hidl_vec<uint8_t>& credentialData,
+                               getCredential_cb _hidl_cb) override;
+};
+
+}  // namespace implementation
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_IDENTITY_IDENTITYCREDENTIALSTORE_H
diff --git a/identity/1.0/default/OWNERS b/identity/1.0/default/OWNERS
new file mode 100644
index 0000000..6969910
--- /dev/null
+++ b/identity/1.0/default/OWNERS
@@ -0,0 +1,2 @@
+swillden@google.com
+zeuthen@google.com
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
diff --git a/identity/1.0/default/WritableIdentityCredential.h b/identity/1.0/default/WritableIdentityCredential.h
new file mode 100644
index 0000000..9f4e303
--- /dev/null
+++ b/identity/1.0/default/WritableIdentityCredential.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_IDENTITY_WRITABLEIDENTITYCREDENTIAL_H
+#define ANDROID_HARDWARE_IDENTITY_WRITABLEIDENTITYCREDENTIAL_H
+
+#include <android/hardware/identity/1.0/IWritableIdentityCredential.h>
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <cppbor.h>
+
+namespace android {
+namespace hardware {
+namespace identity {
+namespace implementation {
+
+using ::std::string;
+using ::std::vector;
+
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::identity::V1_0::IWritableIdentityCredential;
+using ::android::hardware::identity::V1_0::Result;
+using ::android::hardware::identity::V1_0::ResultCode;
+using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
+
+class WritableIdentityCredential : public IWritableIdentityCredential {
+  public:
+    WritableIdentityCredential(const hidl_string& docType, bool testCredential)
+        : docType_(docType), testCredential_(testCredential) {}
+
+    // Creates the Credential Key. Returns false on failure. Must be called
+    // right after construction.
+    bool initialize();
+
+    // Methods from ::android::hardware::identity::IWritableIdentityCredential
+    // follow.
+    Return<void> getAttestationCertificate(const hidl_vec<uint8_t>& attestationChallenge,
+                                           getAttestationCertificate_cb _hidl_cb) override;
+
+    Return<void> startPersonalization(uint16_t accessControlProfileCount,
+                                      const hidl_vec<uint16_t>& entryCounts,
+                                      startPersonalization_cb _hidl_cb) override;
+
+    Return<void> addAccessControlProfile(uint16_t id, const hidl_vec<uint8_t>& readerCertificate,
+                                         bool userAuthenticationRequired, uint64_t timeoutMillis,
+                                         uint64_t secureUserId,
+                                         addAccessControlProfile_cb _hidl_cb) override;
+
+    Return<void> beginAddEntry(const hidl_vec<uint16_t>& accessControlProfileIds,
+                               const hidl_string& nameSpace, const hidl_string& name,
+                               uint32_t entrySize, beginAddEntry_cb _hidl_cb) override;
+
+    Return<void> addEntryValue(const hidl_vec<uint8_t>& content,
+                               addEntryValue_cb _hidl_cb) override;
+
+    Return<void> finishAddingEntries(finishAddingEntries_cb _hidl_cb) override;
+
+  private:
+    string docType_;
+    bool testCredential_;
+
+    // These are set in initialize().
+    vector<uint8_t> storageKey_;
+    vector<uint8_t> credentialPrivKey_;
+    vector<uint8_t> credentialPubKey_;
+
+    // These fields are initialized during startPersonalization()
+    size_t numAccessControlProfileRemaining_;
+    vector<uint16_t> remainingEntryCounts_;
+    cppbor::Array signedDataAccessControlProfiles_;
+    cppbor::Map signedDataNamespaces_;
+    cppbor::Array signedDataCurrentNamespace_;
+
+    // These fields are initialized during beginAddEntry()
+    size_t entryRemainingBytes_;
+    vector<uint8_t> entryAdditionalData_;
+    string entryNameSpace_;
+    string entryName_;
+    vector<uint16_t> entryAccessControlProfileIds_;
+    vector<uint8_t> entryBytes_;
+};
+
+}  // namespace implementation
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_IDENTITY_WRITABLEIDENTITYCREDENTIAL_H
diff --git a/identity/1.0/default/android.hardware.identity@1.0-service.example.rc b/identity/1.0/default/android.hardware.identity@1.0-service.example.rc
new file mode 100644
index 0000000..1eb7319
--- /dev/null
+++ b/identity/1.0/default/android.hardware.identity@1.0-service.example.rc
@@ -0,0 +1,3 @@
+service vendor.identity-1-0 /vendor/bin/hw/android.hardware.identity@1.0-service.example
+    class hal
+    user nobody
diff --git a/identity/1.0/default/service.cpp b/identity/1.0/default/service.cpp
new file mode 100644
index 0000000..839e803
--- /dev/null
+++ b/identity/1.0/default/service.cpp
@@ -0,0 +1,40 @@
+/*
+ * 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 "android.hardware.identity@1.0-service"
+
+#include <android-base/logging.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "IdentityCredentialStore.h"
+
+using android::hardware::joinRpcThreadpool;
+using android::hardware::identity::implementation::IdentityCredentialStore;
+
+int main(int /* argc */, char* argv[]) {
+    ::android::hardware::configureRpcThreadpool(1, true /*willJoinThreadpool*/);
+
+    ::android::base::InitLogging(argv, &android::base::StderrLogger);
+
+    auto identity_store = new IdentityCredentialStore();
+    auto status = identity_store->registerAsService();
+    if (status != android::OK) {
+        LOG(FATAL) << "Could not register service for IdentityCredentialStore 1.0 (" << status
+                   << ")";
+    }
+    joinRpcThreadpool();
+    return -1;  // Should never get here.
+}
diff --git a/identity/1.0/types.hal b/identity/1.0/types.hal
new file mode 100644
index 0000000..5aedfea
--- /dev/null
+++ b/identity/1.0/types.hal
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2018 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.hardware.identity@1.0;
+
+/**
+ * The ResultCode enumeration is used to convey the status of an operation.
+ */
+enum ResultCode : int32_t {
+    /**
+     * Success.
+     */
+    OK = 0,
+
+    /**
+     * The operation failed. This is used as a generic catch-all for errors that don't belong
+     * in other categories, including memory/resource allocation failures and I/O errors.
+     */
+    FAILED = 1,
+
+    /**
+     * The passed data was invalid. This is a generic catch all for errors that don't belong
+     * in other categories related to parameter validation.
+     */
+    INVALID_DATA = 2,
+
+    /**
+     * The authToken parameter passed to IIdentityCredential.startRetrieval() is not valid.
+     */
+    INVALID_AUTH_TOKEN = 3,
+
+    /**
+     * The itemsRequest parameter passed to IIdentityCredential.startRetrieval() does not meet
+     * the requirements described in the documentation for that method.
+     */
+    INVALID_ITEMS_REQUEST_MESSAGE = 4,
+
+    /**
+     * The readerSignature parameter in IIdentityCredential.startRetrieval() is invalid,
+     * doesn't contain an embedded certificate chain, or the signature failed to
+     * validate.
+     */
+    READER_SIGNATURE_CHECK_FAILED = 5,
+
+    /**
+     * The sessionTranscript passed to startRetrieval() did not contain the ephmeral public
+     * key returned by createEphemeralPublicKey().
+     */
+    EPHEMERAL_PUBLIC_KEY_NOT_FOUND = 6,
+
+    /**
+     * An access condition related to user authentication was not satisfied.
+     */
+    USER_AUTHENTICATION_FAILED = 7,
+
+    /**
+     * An access condition related to reader authentication was not satisfied.
+     */
+    READER_AUTHENTICATION_FAILED = 8,
+
+    /**
+    * The request data element has no access control profiles associated so it cannot be accessed.
+    */
+    NO_ACCESS_CONTROL_PROFILES = 9,
+
+    /**
+     * The requested data element is not in the provided non-empty itemsRequest message.
+     */
+    NOT_IN_REQUEST_MESSAGE = 10,
+
+    /**
+     * The passed-in sessionTranscript doesn't match the previously passed-in sessionTranscript.
+     */
+    SESSION_TRANSCRIPT_MISMATCH = 11,
+};
+
+/**
+ * A result has a ResultCode and corresponding textual message.
+ */
+struct Result {
+    /**
+     * The result code.
+     *
+     * Implementations must not use values not defined in the ResultCode enumeration.
+     */
+    ResultCode code;
+
+    /**
+     * A human-readable message in English conveying more detail about a failure.
+     *
+     * If code is ResultCode::OK this field must be set to the empty string.
+     */
+    string message;
+};
+
+struct SecureAccessControlProfile {
+    /**
+     * id is a numeric identifier that must be unique within the context of a Credential and may be
+     * used to reference the profile.
+     */
+    uint16_t id;
+
+    /**
+     * readerCertificate, if non-empty, specifies a single X.509 certificate (not a chain
+     * of certificates) that must be used to authenticate requests. For details about how
+     * this is done, see the readerSignature paremter of IIdentityCredential.startRetrieval.
+     */
+    vec<uint8_t> readerCertificate;
+
+    /**
+     * if true, the user is required to authenticate to allow requests.  Required authentication
+     * fressness is specified by timeout below.
+     *
+     */
+    bool userAuthenticationRequired;
+
+    /**
+     * Timeout specifies the amount of time, in milliseconds, for which a user authentication (see
+     * above) is valid, if userAuthenticationRequired is set to true.  If userAuthenticationRequired
+     * is true and timout is zero then authentication is required for each reader session.
+     *
+     * If userAuthenticationRequired is false, timeout must be zero.
+     */
+    uint64_t timeoutMillis;
+
+    /**
+     * secureUserId must be non-zero if userAuthenticationRequired is true.
+     * It is not related to any Android user ID or UID, but is created in the
+     * Gatekeeper application in the secure environment.
+     */
+    uint64_t secureUserId;
+
+    /**
+     * The mac is used to authenticate the access control profile.  It contains:
+     *
+     *      AES-GCM-ENC(storageKey, R, {}, AccessControlProfile)
+     *
+     *  where AccessControlProfile is the CBOR map:
+     *
+     *      AccessControlProfile = {
+     *          "id": uint,
+     *          ? "readerCertificate" : bstr,
+     *          ? (
+     *              "userAuthenticationRequired" : bool,
+     *              "timeoutMillis" : uint,
+     *              "secureUserId" : uint
+     *          )
+     *      }
+     */
+    vec<uint8_t> mac;
+};
diff --git a/identity/1.0/vts/OWNERS b/identity/1.0/vts/OWNERS
new file mode 100644
index 0000000..6969910
--- /dev/null
+++ b/identity/1.0/vts/OWNERS
@@ -0,0 +1,2 @@
+swillden@google.com
+zeuthen@google.com
diff --git a/identity/1.0/vts/functional/Android.bp b/identity/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..03b49de
--- /dev/null
+++ b/identity/1.0/vts/functional/Android.bp
@@ -0,0 +1,36 @@
+//
+// 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.
+//
+
+cc_test {
+    name: "VtsHalIdentityCredentialTargetTest",
+    defaults: ["VtsHalTargetTestDefaults"],
+    srcs: [
+        "VtsHalIdentityCredentialTargetTest.cpp",
+    ],
+    static_libs: [
+        "android.hardware.identity@1.0",
+        "android.hardware.identity-support-lib",
+        "android.hardware.keymaster@4.0",
+        "libcppbor",
+    ],
+    shared_libs: [
+        "libcrypto",
+    ],
+    test_suites: [
+        "general-tests",
+        "vts-core",
+    ],
+}
diff --git a/identity/1.0/vts/functional/VtsHalIdentityCredentialTargetTest.cpp b/identity/1.0/vts/functional/VtsHalIdentityCredentialTargetTest.cpp
new file mode 100644
index 0000000..903e912
--- /dev/null
+++ b/identity/1.0/vts/functional/VtsHalIdentityCredentialTargetTest.cpp
@@ -0,0 +1,527 @@
+/*
+ * 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 "IdentityCredentialHidlHalTest"
+
+#include <map>
+
+#include <android-base/logging.h>
+#include <android/hardware/identity/1.0/IIdentityCredentialStore.h>
+#include <android/hardware/identity/1.0/types.h>
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+#include <gtest/gtest.h>
+#include <hidl/GtestPrinter.h>
+#include <hidl/ServiceManagement.h>
+
+using std::map;
+using std::optional;
+using std::string;
+using std::vector;
+
+namespace android {
+namespace hardware {
+namespace identity {
+namespace test {
+
+using ::android::hardware::identity::V1_0::IIdentityCredential;
+using ::android::hardware::identity::V1_0::IIdentityCredentialStore;
+using ::android::hardware::identity::V1_0::IWritableIdentityCredential;
+using ::android::hardware::identity::V1_0::Result;
+using ::android::hardware::identity::V1_0::ResultCode;
+using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
+using ::android::hardware::keymaster::V4_0::HardwareAuthToken;
+
+// ---------------------------------------------------------------------------
+// Test Data.
+// ---------------------------------------------------------------------------
+
+struct TestEntryData {
+    TestEntryData(string nameSpace, string name, vector<uint16_t> profileIds)
+        : nameSpace(nameSpace), name(name), profileIds(profileIds) {}
+
+    TestEntryData(string nameSpace, string name, const string& value, vector<uint16_t> profileIds)
+        : TestEntryData(nameSpace, name, profileIds) {
+        valueCbor = cppbor::Tstr(((const char*)value.data())).encode();
+    }
+    TestEntryData(string nameSpace, string name, const vector<uint8_t>& value,
+                  vector<uint16_t> profileIds)
+        : TestEntryData(nameSpace, name, profileIds) {
+        valueCbor = cppbor::Bstr(value).encode();
+    }
+    TestEntryData(string nameSpace, string name, bool value, vector<uint16_t> profileIds)
+        : TestEntryData(nameSpace, name, profileIds) {
+        valueCbor = cppbor::Bool(value).encode();
+    }
+    TestEntryData(string nameSpace, string name, int64_t value, vector<uint16_t> profileIds)
+        : TestEntryData(nameSpace, name, profileIds) {
+        if (value >= 0) {
+            valueCbor = cppbor::Uint(value).encode();
+        } else {
+            valueCbor = cppbor::Nint(-value).encode();
+        }
+    }
+
+    string nameSpace;
+    string name;
+    vector<uint8_t> valueCbor;
+    vector<uint16_t> profileIds;
+};
+
+struct TestProfile {
+    uint16_t id;
+    hidl_vec<uint8_t> readerCertificate;
+    bool userAuthenticationRequired;
+    uint64_t timeoutMillis;
+};
+
+/************************************
+ *   TEST DATA FOR AUTHENTICATION
+ ************************************/
+// Test authentication token for user authentication
+
+class IdentityCredentialStoreHidlTest : public ::testing::TestWithParam<std::string> {
+  public:
+    virtual void SetUp() override {
+        string serviceName = GetParam();
+        ASSERT_FALSE(serviceName.empty());
+        credentialStore_ = IIdentityCredentialStore::getService(serviceName);
+        ASSERT_NE(credentialStore_, nullptr);
+
+        credentialStore_->getHardwareInformation(
+                [&](const Result& result, const hidl_string& credentialStoreName,
+                    const hidl_string& credentialStoreAuthorName, uint32_t chunkSize,
+                    bool /* isDirectAccess */,
+                    const hidl_vec<hidl_string> /* supportedDocTypes */) {
+                    EXPECT_EQ("", result.message);
+                    ASSERT_EQ(ResultCode::OK, result.code);
+                    ASSERT_GT(credentialStoreName.size(), 0u);
+                    ASSERT_GT(credentialStoreAuthorName.size(), 0u);
+                    ASSERT_GE(chunkSize, 256u);  // Chunk sizes < APDU buffer won't be supported
+                    dataChunkSize_ = chunkSize;
+                });
+    }
+    virtual void TearDown() override {}
+
+    uint32_t dataChunkSize_ = 0;
+
+    sp<IIdentityCredentialStore> credentialStore_;
+};
+
+TEST_P(IdentityCredentialStoreHidlTest, HardwareConfiguration) {
+    credentialStore_->getHardwareInformation(
+            [&](const Result& result, const hidl_string& credentialStoreName,
+                const hidl_string& credentialStoreAuthorName, uint32_t chunkSize,
+                bool /* isDirectAccess */, const hidl_vec<hidl_string> /* supportedDocTypes */) {
+                EXPECT_EQ("", result.message);
+                ASSERT_EQ(ResultCode::OK, result.code);
+                ASSERT_GT(credentialStoreName.size(), 0u);
+                ASSERT_GT(credentialStoreAuthorName.size(), 0u);
+                ASSERT_GE(chunkSize, 256u);  // Chunk sizes < APDU buffer won't be supported
+            });
+}
+
+TEST_P(IdentityCredentialStoreHidlTest, createAndRetrieveCredential) {
+    // First, generate a key-pair for the reader since its public key will be
+    // part of the request data.
+    optional<vector<uint8_t>> readerKeyPKCS8 = support::createEcKeyPair();
+    ASSERT_TRUE(readerKeyPKCS8);
+    optional<vector<uint8_t>> readerPublicKey =
+            support::ecKeyPairGetPublicKey(readerKeyPKCS8.value());
+    optional<vector<uint8_t>> readerKey = support::ecKeyPairGetPrivateKey(readerKeyPKCS8.value());
+    string serialDecimal = "1234";
+    string issuer = "Android Open Source Project";
+    string subject = "Android IdentityCredential VTS Test";
+    time_t validityNotBefore = time(nullptr);
+    time_t validityNotAfter = validityNotBefore + 365 * 24 * 3600;
+    optional<vector<uint8_t>> readerCertificate = support::ecPublicKeyGenerateCertificate(
+            readerPublicKey.value(), readerKey.value(), serialDecimal, issuer, subject,
+            validityNotBefore, validityNotAfter);
+    ASSERT_TRUE(readerCertificate);
+
+    // Make the portrait image really big (just shy of 256 KiB) to ensure that
+    // the chunking code gets exercised.
+    vector<uint8_t> portraitImage;
+    portraitImage.resize(256 * 1024 - 10);
+    for (size_t n = 0; n < portraitImage.size(); n++) {
+        portraitImage[n] = (uint8_t)n;
+    }
+
+    // Access control profiles:
+    const vector<TestProfile> testProfiles = {// Profile 0 (reader authentication)
+                                              {0, readerCertificate.value(), false, 0},
+                                              // Profile 1 (no authentication)
+                                              {1, {}, false, 0}};
+
+    HardwareAuthToken authToken = {};
+
+    // Here's the actual test data:
+    const vector<TestEntryData> testEntries = {
+            {"PersonalData", "Last name", string("Turing"), vector<uint16_t>{0, 1}},
+            {"PersonalData", "Birth date", string("19120623"), vector<uint16_t>{0, 1}},
+            {"PersonalData", "First name", string("Alan"), vector<uint16_t>{0, 1}},
+            {"PersonalData", "Home address", string("Maida Vale, London, England"),
+             vector<uint16_t>{0}},
+            {"Image", "Portrait image", portraitImage, vector<uint16_t>{0, 1}},
+    };
+    const vector<uint16_t> testEntriesEntryCounts = {static_cast<uint16_t>(testEntries.size() - 1),
+                                                     1u};
+
+    string cborPretty;
+    sp<IWritableIdentityCredential> writableCredential;
+
+    hidl_vec<uint8_t> empty{0};
+
+    string docType = "org.iso.18013-5.2019.mdl";
+    bool testCredential = true;
+    Result result;
+    credentialStore_->createCredential(
+            docType, testCredential,
+            [&](const Result& _result, const sp<IWritableIdentityCredential>& _writableCredential) {
+                result = _result;
+                writableCredential = _writableCredential;
+            });
+    EXPECT_EQ("", result.message);
+    ASSERT_EQ(ResultCode::OK, result.code);
+    ASSERT_NE(writableCredential, nullptr);
+
+    string challenge = "attestationChallenge";
+    vector<uint8_t> attestationChallenge(challenge.begin(), challenge.end());
+    vector<uint8_t> attestationCertificate;
+    writableCredential->getAttestationCertificate(
+            attestationChallenge,
+            [&](const Result& _result, const hidl_vec<uint8_t>& _attestationCertificate) {
+                result = _result;
+                attestationCertificate = _attestationCertificate;
+            });
+    EXPECT_EQ("", result.message);
+    ASSERT_EQ(ResultCode::OK, result.code);
+
+    writableCredential->startPersonalization(testProfiles.size(), testEntriesEntryCounts,
+                                             [&](const Result& _result) { result = _result; });
+    EXPECT_EQ("", result.message);
+    ASSERT_EQ(ResultCode::OK, result.code);
+
+    vector<SecureAccessControlProfile> returnedSecureProfiles;
+    for (const auto& testProfile : testProfiles) {
+        SecureAccessControlProfile profile;
+        writableCredential->addAccessControlProfile(
+                testProfile.id, testProfile.readerCertificate,
+                testProfile.userAuthenticationRequired, testProfile.timeoutMillis,
+                0,  // secureUserId
+                [&](const Result& _result, const SecureAccessControlProfile& _profile) {
+                    result = _result;
+                    profile = _profile;
+                });
+        EXPECT_EQ("", result.message);
+        ASSERT_EQ(ResultCode::OK, result.code);
+        ASSERT_EQ(testProfile.id, profile.id);
+        ASSERT_EQ(testProfile.readerCertificate, profile.readerCertificate);
+        ASSERT_EQ(testProfile.userAuthenticationRequired, profile.userAuthenticationRequired);
+        ASSERT_EQ(testProfile.timeoutMillis, profile.timeoutMillis);
+        ASSERT_EQ(support::kAesGcmTagSize + support::kAesGcmIvSize, profile.mac.size());
+        returnedSecureProfiles.push_back(profile);
+    }
+
+    // Uses TestEntryData* pointer as key and values are the encrypted blobs. This
+    // is a little hacky but it works well enough.
+    map<const TestEntryData*, vector<vector<uint8_t>>> encryptedBlobs;
+
+    for (const auto& entry : testEntries) {
+        vector<vector<uint8_t>> chunks = support::chunkVector(entry.valueCbor, dataChunkSize_);
+
+        writableCredential->beginAddEntry(entry.profileIds, entry.nameSpace, entry.name,
+                                          entry.valueCbor.size(),
+                                          [&](const Result& _result) { result = _result; });
+        EXPECT_EQ("", result.message);
+        ASSERT_EQ(ResultCode::OK, result.code);
+
+        vector<vector<uint8_t>> encryptedChunks;
+        for (const auto& chunk : chunks) {
+            writableCredential->addEntryValue(
+                    chunk, [&](const Result& result, hidl_vec<uint8_t> encryptedContent) {
+                        EXPECT_EQ("", result.message);
+                        ASSERT_EQ(ResultCode::OK, result.code);
+                        ASSERT_GT(encryptedContent.size(), 0u);
+                        encryptedChunks.push_back(encryptedContent);
+                    });
+        }
+        encryptedBlobs[&entry] = encryptedChunks;
+    }
+
+    vector<uint8_t> credentialData;
+    vector<uint8_t> proofOfProvisioningSignature;
+    writableCredential->finishAddingEntries(
+            [&](const Result& _result, const hidl_vec<uint8_t>& _credentialData,
+                const hidl_vec<uint8_t>& _proofOfProvisioningSignature) {
+                result = _result;
+                credentialData = _credentialData;
+                proofOfProvisioningSignature = _proofOfProvisioningSignature;
+            });
+    EXPECT_EQ("", result.message);
+    ASSERT_EQ(ResultCode::OK, result.code);
+
+    optional<vector<uint8_t>> proofOfProvisioning =
+            support::coseSignGetPayload(proofOfProvisioningSignature);
+    ASSERT_TRUE(proofOfProvisioning);
+    cborPretty = support::cborPrettyPrint(proofOfProvisioning.value(), 32, {"readerCertificate"});
+    EXPECT_EQ(
+            "[\n"
+            "  'ProofOfProvisioning',\n"
+            "  'org.iso.18013-5.2019.mdl',\n"
+            "  [\n"
+            "    {\n"
+            "      'id' : 0,\n"
+            "      'readerCertificate' : <not printed>,\n"
+            "    },\n"
+            "    {\n"
+            "      'id' : 1,\n"
+            "    },\n"
+            "  ],\n"
+            "  {\n"
+            "    'PersonalData' : [\n"
+            "      {\n"
+            "        'name' : 'Last name',\n"
+            "        'value' : 'Turing',\n"
+            "        'accessControlProfiles' : [0, 1, ],\n"
+            "      },\n"
+            "      {\n"
+            "        'name' : 'Birth date',\n"
+            "        'value' : '19120623',\n"
+            "        'accessControlProfiles' : [0, 1, ],\n"
+            "      },\n"
+            "      {\n"
+            "        'name' : 'First name',\n"
+            "        'value' : 'Alan',\n"
+            "        'accessControlProfiles' : [0, 1, ],\n"
+            "      },\n"
+            "      {\n"
+            "        'name' : 'Home address',\n"
+            "        'value' : 'Maida Vale, London, England',\n"
+            "        'accessControlProfiles' : [0, ],\n"
+            "      },\n"
+            "    ],\n"
+            "    'Image' : [\n"
+            "      {\n"
+            "        'name' : 'Portrait image',\n"
+            "        'value' : <bstr size=262134 sha1=941e372f654d86c32d88fae9e41b706afbfd02bb>,\n"
+            "        'accessControlProfiles' : [0, 1, ],\n"
+            "      },\n"
+            "    ],\n"
+            "  },\n"
+            "  true,\n"
+            "]",
+            cborPretty);
+
+    optional<vector<uint8_t>> credentialPubKey =
+            support::certificateChainGetTopMostKey(attestationCertificate);
+    ASSERT_TRUE(credentialPubKey);
+    EXPECT_TRUE(support::coseCheckEcDsaSignature(proofOfProvisioningSignature,
+                                                 {},  // Additional data
+                                                 credentialPubKey.value()));
+    writableCredential = nullptr;
+
+    // Now that the credential has been provisioned, read it back and check the
+    // correct data is returned.
+    sp<IIdentityCredential> credential;
+    credentialStore_->getCredential(
+            credentialData, [&](const Result& _result, const sp<IIdentityCredential>& _credential) {
+                result = _result;
+                credential = _credential;
+            });
+    EXPECT_EQ("", result.message);
+    ASSERT_EQ(ResultCode::OK, result.code);
+    ASSERT_NE(credential, nullptr);
+
+    optional<vector<uint8_t>> readerEphemeralKeyPair = support::createEcKeyPair();
+    ASSERT_TRUE(readerEphemeralKeyPair);
+    optional<vector<uint8_t>> readerEphemeralPublicKey =
+            support::ecKeyPairGetPublicKey(readerEphemeralKeyPair.value());
+    credential->setReaderEphemeralPublicKey(readerEphemeralPublicKey.value(),
+                                            [&](const Result& _result) { result = _result; });
+    EXPECT_EQ("", result.message);
+    ASSERT_EQ(ResultCode::OK, result.code);
+
+    vector<uint8_t> ephemeralKeyPair;
+    credential->createEphemeralKeyPair(
+            [&](const Result& _result, const hidl_vec<uint8_t>& _ephemeralKeyPair) {
+                result = _result;
+                ephemeralKeyPair = _ephemeralKeyPair;
+            });
+    EXPECT_EQ("", result.message);
+    ASSERT_EQ(ResultCode::OK, result.code);
+    optional<vector<uint8_t>> ephemeralPublicKey = support::ecKeyPairGetPublicKey(ephemeralKeyPair);
+
+    // Calculate requestData field and sign it with the reader key.
+    auto [getXYSuccess, ephX, ephY] = support::ecPublicKeyGetXandY(ephemeralPublicKey.value());
+    ASSERT_TRUE(getXYSuccess);
+    cppbor::Map deviceEngagement = cppbor::Map().add("ephX", ephX).add("ephY", ephY);
+    vector<uint8_t> deviceEngagementBytes = deviceEngagement.encode();
+    vector<uint8_t> eReaderPubBytes = cppbor::Tstr("ignored").encode();
+    cppbor::Array sessionTranscript = cppbor::Array()
+                                              .add(cppbor::Semantic(24, deviceEngagementBytes))
+                                              .add(cppbor::Semantic(24, eReaderPubBytes));
+    vector<uint8_t> sessionTranscriptBytes = sessionTranscript.encode();
+
+    vector<uint8_t> itemsRequestBytes =
+            cppbor::Map("nameSpaces",
+                        cppbor::Map()
+                                .add("PersonalData", cppbor::Map()
+                                                             .add("Last name", false)
+                                                             .add("Birth date", false)
+                                                             .add("First name", false)
+                                                             .add("Home address", true))
+                                .add("Image", cppbor::Map().add("Portrait image", false)))
+                    .encode();
+    cborPretty = support::cborPrettyPrint(itemsRequestBytes, 32, {"EphemeralPublicKey"});
+    EXPECT_EQ(
+            "{\n"
+            "  'nameSpaces' : {\n"
+            "    'PersonalData' : {\n"
+            "      'Last name' : false,\n"
+            "      'Birth date' : false,\n"
+            "      'First name' : false,\n"
+            "      'Home address' : true,\n"
+            "    },\n"
+            "    'Image' : {\n"
+            "      'Portrait image' : false,\n"
+            "    },\n"
+            "  },\n"
+            "}",
+            cborPretty);
+    vector<uint8_t> dataToSign = cppbor::Array()
+                                         .add("ReaderAuthentication")
+                                         .add(sessionTranscript.clone())
+                                         .add(cppbor::Semantic(24, itemsRequestBytes))
+                                         .encode();
+    optional<vector<uint8_t>> readerSignature =
+            support::coseSignEcDsa(readerKey.value(), {},  // content
+                                   dataToSign,             // detached content
+                                   readerCertificate.value());
+    ASSERT_TRUE(readerSignature);
+
+    credential->startRetrieval(returnedSecureProfiles, authToken, itemsRequestBytes,
+                               sessionTranscriptBytes, readerSignature.value(),
+                               testEntriesEntryCounts,
+                               [&](const Result& _result) { result = _result; });
+    EXPECT_EQ("", result.message);
+    ASSERT_EQ(ResultCode::OK, result.code);
+
+    for (const auto& entry : testEntries) {
+        credential->startRetrieveEntryValue(entry.nameSpace, entry.name, entry.valueCbor.size(),
+                                            entry.profileIds,
+                                            [&](const Result& _result) { result = _result; });
+        EXPECT_EQ("", result.message);
+        ASSERT_EQ(ResultCode::OK, result.code);
+
+        auto it = encryptedBlobs.find(&entry);
+        ASSERT_NE(it, encryptedBlobs.end());
+        const vector<vector<uint8_t>>& encryptedChunks = it->second;
+
+        vector<uint8_t> content;
+        for (const auto& encryptedChunk : encryptedChunks) {
+            vector<uint8_t> chunk;
+            credential->retrieveEntryValue(
+                    encryptedChunk, [&](const Result& _result, const hidl_vec<uint8_t>& _chunk) {
+                        result = _result;
+                        chunk = _chunk;
+                    });
+            EXPECT_EQ("", result.message);
+            ASSERT_EQ(ResultCode::OK, result.code);
+            content.insert(content.end(), chunk.begin(), chunk.end());
+        }
+        EXPECT_EQ(content, entry.valueCbor);
+    }
+
+    // Generate the key that will be used to sign AuthenticatedData.
+    vector<uint8_t> signingKeyBlob;
+    vector<uint8_t> signingKeyCertificate;
+    credential->generateSigningKeyPair([&](const Result& _result,
+                                           const hidl_vec<uint8_t> _signingKeyBlob,
+                                           const hidl_vec<uint8_t> _signingKeyCertificate) {
+        result = _result;
+        signingKeyBlob = _signingKeyBlob;
+        signingKeyCertificate = _signingKeyCertificate;
+    });
+    EXPECT_EQ("", result.message);
+    ASSERT_EQ(ResultCode::OK, result.code);
+
+    vector<uint8_t> mac;
+    vector<uint8_t> deviceNameSpacesBytes;
+    credential->finishRetrieval(signingKeyBlob,
+                                [&](const Result& _result, const hidl_vec<uint8_t> _mac,
+                                    const hidl_vec<uint8_t> _deviceNameSpacesBytes) {
+                                    result = _result;
+                                    mac = _mac;
+                                    deviceNameSpacesBytes = _deviceNameSpacesBytes;
+                                });
+    EXPECT_EQ("", result.message);
+    ASSERT_EQ(ResultCode::OK, result.code);
+    cborPretty = support::cborPrettyPrint(deviceNameSpacesBytes, 32, {});
+    ASSERT_EQ(
+            "{\n"
+            "  'PersonalData' : {\n"
+            "    'Last name' : 'Turing',\n"
+            "    'Birth date' : '19120623',\n"
+            "    'First name' : 'Alan',\n"
+            "    'Home address' : 'Maida Vale, London, England',\n"
+            "  },\n"
+            "  'Image' : {\n"
+            "    'Portrait image' : <bstr size=262134 "
+            "sha1=941e372f654d86c32d88fae9e41b706afbfd02bb>,\n"
+            "  },\n"
+            "}",
+            cborPretty);
+    // The data that is MACed is ["DeviceAuthentication", sessionTranscriptBytes, docType,
+    // deviceNameSpacesBytes] so build up that structure
+    cppbor::Array deviceAuthentication;
+    deviceAuthentication.add("DeviceAuthentication");
+    deviceAuthentication.add(sessionTranscript.clone());
+    deviceAuthentication.add(docType);
+    deviceAuthentication.add(cppbor::Semantic(24, deviceNameSpacesBytes));
+    vector<uint8_t> encodedDeviceAuthentication = deviceAuthentication.encode();
+    optional<vector<uint8_t>> signingPublicKey =
+            support::certificateChainGetTopMostKey(signingKeyCertificate);
+    EXPECT_TRUE(signingPublicKey);
+
+    // Derive the key used for MACing.
+    optional<vector<uint8_t>> readerEphemeralPrivateKey =
+            support::ecKeyPairGetPrivateKey(readerEphemeralKeyPair.value());
+    optional<vector<uint8_t>> sharedSecret =
+            support::ecdh(signingPublicKey.value(), readerEphemeralPrivateKey.value());
+    ASSERT_TRUE(sharedSecret);
+    vector<uint8_t> salt = {0x00};
+    vector<uint8_t> info = {};
+    optional<vector<uint8_t>> derivedKey = support::hkdf(sharedSecret.value(), salt, info, 32);
+    ASSERT_TRUE(derivedKey);
+    optional<vector<uint8_t>> calculatedMac =
+            support::coseMac0(derivedKey.value(), {},        // payload
+                              encodedDeviceAuthentication);  // detached content
+    ASSERT_TRUE(calculatedMac);
+    EXPECT_EQ(mac, calculatedMac);
+}
+
+INSTANTIATE_TEST_SUITE_P(PerInstance, IdentityCredentialStoreHidlTest,
+                         testing::ValuesIn(android::hardware::getAllHalInstanceNames(
+                                 IIdentityCredentialStore::descriptor)),
+                         android::hardware::PrintInstanceNameToString);
+
+}  // namespace test
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
