diff --git a/current.txt b/current.txt
index 932c6e9..ec8e591 100644
--- a/current.txt
+++ b/current.txt
@@ -640,6 +640,10 @@
 ce8dbe76eb9ee94b46ef98f725be992e760a5751073d4f4912484026541371f3 android.hardware.health@2.1::IHealth
 26f04510a0b57aba5167c5c0a7c2f077c2acbb98b81902a072517829fd9fd67f android.hardware.health@2.1::IHealthInfoCallback
 db47f4ceceb1f06c656f39caa70c557b0f8471ef59fd58611bea667ffca20101 android.hardware.health@2.1::types
+0589e410f519e36514e7ece18f283f022df0f70efd2c12821d822f67f74aba98 android.hardware.identity@1.0::types
+bbeee9604128ede83ee755b67e73b5ad29e6e1dbac9ec41fea6ffe2745b0c50a android.hardware.identity@1.0::IIdentityCredential
+96ce8aad80f4c476f25261f790d357c117e79e18474c7dadd850dac704bbe65e android.hardware.identity@1.0::IIdentityCredentialStore
+6e1e28a96c90ba78d47257faea3f3bb4e6360affbbfa5822f0dc31211f9266ff android.hardware.identity@1.0::IWritableIdentityCredential
 c228aaa27f66c48e147159a4f4996c5273191fece1b08de31bd171c61334855e android.hardware.keymaster@4.1::IKeymasterDevice
 adb0efdf1462e9b2e742c0dcadd598666aac551f178be06e755bfcdf5797abd0 android.hardware.keymaster@4.1::IOperation
 7a04ea5595ed418ca3e91c28b8bd7353dd988be9be7b0c8c9e64fb4b77bd4523 android.hardware.keymaster@4.1::types
diff --git a/drm/1.2/vts/functional/drm_hal_common.cpp b/drm/1.2/vts/functional/drm_hal_common.cpp
index bfffbe8..71e29ec 100644
--- a/drm/1.2/vts/functional/drm_hal_common.cpp
+++ b/drm/1.2/vts/functional/drm_hal_common.cpp
@@ -118,7 +118,7 @@
     }
 
     // If drm scheme not installed skip subsequent tests
-    if (!drmFactory->isCryptoSchemeSupported(getVendorUUID())) {
+    if (drmFactory.get() == nullptr || !drmFactory->isCryptoSchemeSupported(getVendorUUID())) {
         vendorModule->setInstalled(false);
         return;
     }
diff --git a/drm/1.2/vts/functional/drm_hal_test.cpp b/drm/1.2/vts/functional/drm_hal_test.cpp
index 37ecc25..5e1dfed 100644
--- a/drm/1.2/vts/functional/drm_hal_test.cpp
+++ b/drm/1.2/vts/functional/drm_hal_test.cpp
@@ -52,6 +52,7 @@
  * Ensure drm factory supports module UUID Scheme
  */
 TEST_P(DrmHalTest, VendorUuidSupported) {
+    RETURN_IF_SKIPPED;
     auto res = drmFactory->isCryptoSchemeSupported_1_2(getVendorUUID(), kVideoMp4, kSwSecureCrypto);
     ALOGI("kVideoMp4 = %s res %d", kVideoMp4, (bool)res);
     EXPECT_TRUE(res);
@@ -61,6 +62,7 @@
  * Ensure drm factory doesn't support an invalid scheme UUID
  */
 TEST_P(DrmHalTest, InvalidPluginNotSupported) {
+    RETURN_IF_SKIPPED;
     const uint8_t kInvalidUUID[16] = {
         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80,
         0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80};
@@ -71,6 +73,7 @@
  * Ensure drm factory doesn't support an empty UUID
  */
 TEST_P(DrmHalTest, EmptyPluginUUIDNotSupported) {
+    RETURN_IF_SKIPPED;
     hidl_array<uint8_t, 16> emptyUUID;
     memset(emptyUUID.data(), 0, 16);
     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported_1_2(emptyUUID, kVideoMp4, kSwSecureCrypto));
@@ -80,6 +83,7 @@
  * Ensure drm factory doesn't support an invalid mime type
  */
 TEST_P(DrmHalTest, BadMimeNotSupported) {
+    RETURN_IF_SKIPPED;
     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported_1_2(getVendorUUID(), kBadMime, kSwSecureCrypto));
 }
 
@@ -133,6 +137,7 @@
  * A get key request should fail if no sessionId is provided
  */
 TEST_P(DrmHalTest, GetKeyRequestNoSession) {
+    RETURN_IF_SKIPPED;
     SessionId invalidSessionId;
     hidl_vec<uint8_t> initData;
     KeyedVector optionalParameters;
@@ -150,6 +155,7 @@
  * invalid mime type
  */
 TEST_P(DrmHalTest, GetKeyRequestBadMime) {
+    RETURN_IF_SKIPPED;
     auto sessionId = openSession();
     hidl_vec<uint8_t> initData;
     KeyedVector optionalParameters;
@@ -186,6 +192,7 @@
  * Test drm plugin offline key support
  */
 TEST_P(DrmHalTest, OfflineLicenseTest) {
+    RETURN_IF_SKIPPED;
     auto sessionId = openSession();
     hidl_vec<uint8_t> keySetId = loadKeys(sessionId, KeyType::OFFLINE);
 
@@ -225,6 +232,7 @@
  * Test drm plugin offline key state
  */
 TEST_P(DrmHalTest, OfflineLicenseStateTest) {
+    RETURN_IF_SKIPPED;
     auto sessionId = openSession();
     DrmHalVTSVendorModule_V1::ContentConfiguration content = getContent(KeyType::OFFLINE);
     hidl_vec<uint8_t> keySetId = loadKeys(sessionId, content, KeyType::OFFLINE);
@@ -249,6 +257,7 @@
  * Negative offline license test. Remove empty keySetId
  */
 TEST_P(DrmHalTest, RemoveEmptyKeySetId) {
+    RETURN_IF_SKIPPED;
     KeySetId emptyKeySetId;
     Status err = drmPlugin->removeOfflineLicense(emptyKeySetId);
     EXPECT_EQ(Status::BAD_VALUE, err);
@@ -258,6 +267,7 @@
  * Negative offline license test. Get empty keySetId state
  */
 TEST_P(DrmHalTest, GetEmptyKeySetIdState) {
+    RETURN_IF_SKIPPED;
     KeySetId emptyKeySetId;
     auto res = drmPlugin->getOfflineLicenseState(emptyKeySetId, checkKeySetIdState<Status::BAD_VALUE, OfflineLicenseState::UNKNOWN>);
     EXPECT_OK(res);
@@ -267,6 +277,7 @@
  * Test that the plugin returns valid connected and max HDCP levels
  */
 TEST_P(DrmHalTest, GetHdcpLevels) {
+    RETURN_IF_SKIPPED;
     auto res = drmPlugin->getHdcpLevels_1_2(
             [&](StatusV1_2 status, const HdcpLevel &connectedLevel,
                 const HdcpLevel &maxLevel) {
@@ -421,6 +432,7 @@
  * Ensure clearkey drm factory doesn't support security level higher than supported
  */
 TEST_P(DrmHalClearkeyTest, BadLevelNotSupported) {
+    RETURN_IF_SKIPPED;
     const SecurityLevel kHwSecureAll = SecurityLevel::HW_SECURE_ALL;
     EXPECT_FALSE(drmFactory->isCryptoSchemeSupported_1_2(getVendorUUID(), kVideoMp4, kHwSecureAll));
 }
@@ -429,6 +441,7 @@
  * Test resource contention during attempt to generate key request
  */
 TEST_P(DrmHalClearkeyTest, GetKeyRequestResourceContention) {
+    RETURN_IF_SKIPPED;
     Status status = drmPlugin->setPropertyString(kDrmErrorTestKey, kDrmErrorResourceContention);
     EXPECT_EQ(Status::OK, status);
     auto sessionId = openSession();
@@ -450,6 +463,7 @@
  * Test clearkey plugin offline key with mock error
  */
 TEST_P(DrmHalClearkeyTest, OfflineLicenseInvalidState) {
+    RETURN_IF_SKIPPED;
     auto sessionId = openSession();
     hidl_vec<uint8_t> keySetId = loadKeys(sessionId, KeyType::OFFLINE);
     Status status = drmPlugin->setPropertyString(kDrmErrorTestKey, kDrmErrorInvalidState);
@@ -471,6 +485,7 @@
  * Test SessionLostState is triggered on error
  */
 TEST_P(DrmHalClearkeyTest, SessionLostState) {
+    RETURN_IF_SKIPPED;
     sp<DrmHalPluginListener> listener = new DrmHalPluginListener();
     auto res = drmPlugin->setListener(listener);
     EXPECT_OK(res);
@@ -491,6 +506,7 @@
  * Negative decrypt test. Decrypt with invalid key.
  */
 TEST_P(DrmHalClearkeyTest, DecryptWithEmptyKey) {
+    RETURN_IF_SKIPPED;
     vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
     const Pattern noPattern = {0, 0};
     const uint32_t kClearBytes = 512;
@@ -528,6 +544,7 @@
  * Negative decrypt test. Decrypt with a key exceeds AES_BLOCK_SIZE.
  */
 TEST_P(DrmHalClearkeyTest, DecryptWithKeyTooLong) {
+    RETURN_IF_SKIPPED;
     vector<uint8_t> iv(AES_BLOCK_SIZE, 0);
     const Pattern noPattern = {0, 0};
     const uint32_t kClearBytes = 512;
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
diff --git a/identity/support/Android.bp b/identity/support/Android.bp
new file mode 100644
index 0000000..38dc10b
--- /dev/null
+++ b/identity/support/Android.bp
@@ -0,0 +1,103 @@
+// 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_library {
+    name: "android.hardware.identity-support-lib",
+    vendor_available: true,
+    srcs: [
+        "src/IdentityCredentialSupport.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    shared_libs: [
+        "android.hardware.identity@1.0",
+        "libcrypto",
+        "libbase",
+        "libhidlbase",
+        "libhardware",
+    ],
+    static_libs: [
+        "libcppbor",
+    ],
+}
+
+cc_test {
+    name: "android.hardware.identity-support-lib-test",
+    srcs: [
+        "tests/IdentityCredentialSupportTest.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.identity-support-lib",
+        "android.hardware.identity@1.0",
+        "libcrypto",
+        "libbase",
+        "libhidlbase",
+        "libhardware",
+    ],
+    static_libs: [
+        "libcppbor",
+        "libgmock",
+    ],
+    test_suites: ["general-tests"],
+}
+
+// --
+
+cc_library {
+    name: "libcppbor",
+    vendor_available: true,
+    host_supported: true,
+    srcs: [
+        "src/cppbor.cpp",
+        "src/cppbor_parse.cpp",
+    ],
+    export_include_dirs: [
+        "include/cppbor",
+    ],
+    shared_libs: [
+        "libbase",
+    ],
+}
+
+cc_test {
+    name: "cppbor_test",
+    srcs: [
+        "tests/cppbor_test.cpp",
+    ],
+    shared_libs: [
+        "libcppbor",
+        "libbase",
+    ],
+    static_libs: [
+        "libgmock",
+    ],
+    test_suites: ["general-tests"],
+}
+
+cc_test_host {
+    name: "cppbor_host_test",
+    srcs: [
+        "tests/cppbor_test.cpp",
+    ],
+    shared_libs: [
+        "libcppbor",
+        "libbase",
+    ],
+    static_libs: [
+        "libgmock",
+    ],
+    test_suites: ["general-tests"],
+}
diff --git a/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
new file mode 100644
index 0000000..485571a
--- /dev/null
+++ b/identity/support/include/android/hardware/identity/support/IdentityCredentialSupport.h
@@ -0,0 +1,303 @@
+/*
+ * 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 IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
+#define IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
+
+#include <cstdint>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include <android/hardware/identity/1.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace identity {
+namespace support {
+
+using ::std::optional;
+using ::std::string;
+using ::std::tuple;
+using ::std::vector;
+
+using ::android::hardware::identity::V1_0::Result;
+using ::android::hardware::identity::V1_0::ResultCode;
+using ::android::hardware::identity::V1_0::SecureAccessControlProfile;
+
+// ---------------------------------------------------------------------------
+// Miscellaneous utilities.
+// ---------------------------------------------------------------------------
+
+// Dumps the data in |data| to stderr. The written data will be of the following
+// form for the call hexdump("signature", data) where |data| is of size 71:
+//
+//   signature: dumping 71 bytes
+//   0000  30 45 02 21 00 ac c6 12 60 56 a2 e9 ee 16 be 14  0E.!....`V......
+//   0010  69 7f c4 00 95 8c e8 55 1f 22 de 34 0b 08 8a 3b  i......U.".4...;
+//   0020  a0 56 54 05 07 02 20 58 77 d9 8c f9 eb 41 df fd  .VT... Xw....A..
+//   0030  c1 a3 14 e0 bf b0 a2 c5 0c b6 85 8c 4a 0d f9 2b  ............J..+
+//   0040  b7 8f d2 1d 9b 11 ac                             .......
+//
+// This should only be used for debugging.
+void hexdump(const string& name, const vector<uint8_t>& data);
+
+string encodeHex(const string& str);
+
+string encodeHex(const vector<uint8_t>& data);
+
+string encodeHex(const uint8_t* data, size_t dataLen);
+
+optional<vector<uint8_t>> decodeHex(const string& hexEncoded);
+
+// ---------------------------------------------------------------------------
+// CBOR utilities.
+// ---------------------------------------------------------------------------
+
+// Returns pretty-printed CBOR for |value|.
+//
+// Only valid CBOR should be passed to this function.
+//
+// If a byte-string is larger than |maxBStrSize| its contents will not be
+// printed, instead the value of the form "<bstr size=1099016
+// sha1=ef549cca331f73dfae2090e6a37c04c23f84b07b>" will be printed. Pass zero
+// for |maxBStrSize| to disable this.
+//
+// The |mapKeysToNotPrint| parameter specifies the name of map values
+// to not print. This is useful for unit tests.
+string cborPrettyPrint(const vector<uint8_t>& encodedCbor, size_t maxBStrSize = 32,
+                       const vector<string>& mapKeysToNotPrint = {});
+
+// ---------------------------------------------------------------------------
+// Crypto functionality / abstraction.
+// ---------------------------------------------------------------------------
+
+constexpr size_t kAesGcmIvSize = 12;
+constexpr size_t kAesGcmTagSize = 16;
+constexpr size_t kAes128GcmKeySize = 16;
+
+// Returns |numBytes| bytes of random data.
+optional<vector<uint8_t>> getRandom(size_t numBytes);
+
+// Calculates the SHA-256 of |data|.
+vector<uint8_t> sha256(const vector<uint8_t>& data);
+
+// Decrypts |encryptedData| using |key| and |additionalAuthenticatedData|,
+// returns resulting plaintext. The format of |encryptedData| must
+// be as specified in the encryptAes128Gcm() function.
+optional<vector<uint8_t>> decryptAes128Gcm(const vector<uint8_t>& key,
+                                           const vector<uint8_t>& encryptedData,
+                                           const vector<uint8_t>& additionalAuthenticatedData);
+
+// Encrypts |data| with |key| and |additionalAuthenticatedData| using |nonce|,
+// returns the resulting (nonce || ciphertext || tag).
+optional<vector<uint8_t>> encryptAes128Gcm(const vector<uint8_t>& key, const vector<uint8_t>& nonce,
+                                           const vector<uint8_t>& data,
+                                           const vector<uint8_t>& additionalAuthenticatedData);
+
+// ---------------------------------------------------------------------------
+// EC crypto functionality / abstraction (only supports P-256).
+// ---------------------------------------------------------------------------
+
+// Creates an 256-bit EC key using the NID_X9_62_prime256v1 curve, returns the
+// PKCS#8 encoded key-pair.
+//
+optional<vector<uint8_t>> createEcKeyPair();
+
+// For an EC key |keyPair| encoded in PKCS#8 format, extracts the public key in
+// uncompressed point form.
+//
+optional<vector<uint8_t>> ecKeyPairGetPublicKey(const vector<uint8_t>& keyPair);
+
+// For an EC key |keyPair| encoded in PKCS#8 format, extracts the private key as
+// an EC uncompressed key.
+//
+optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair);
+
+// For an EC key |keyPair| encoded in PKCS#8 format, creates a PKCS#12 structure
+// with the key-pair (not using a password to encrypt the data). The public key
+// in the created structure is included as a certificate, using the given fields
+// |serialDecimal|, |issuer|, |subject|, |validityNotBefore|, and
+// |validityNotAfter|.
+//
+optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, const string& name,
+                                             const string& serialDecimal, const string& issuer,
+                                             const string& subject, time_t validityNotBefore,
+                                             time_t validityNotAfter);
+
+// Signs |data| with |key| (which must be in the format returned by
+// ecKeyPairGetPrivateKey()). Signature is returned and will be in DER format.
+//
+optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data);
+
+// Calculates the HMAC with SHA-256 for |data| using |key|. The calculated HMAC
+// is returned and will be 32 bytes.
+//
+optional<vector<uint8_t>> hmacSha256(const vector<uint8_t>& key, const vector<uint8_t>& data);
+
+// Checks that |signature| (in DER format) is a valid signature of |digest|,
+// made with |publicKey| (which must be in the format returned by
+// ecKeyPairGetPublicKey()).
+//
+bool checkEcDsaSignature(const vector<uint8_t>& digest, const vector<uint8_t>& signature,
+                         const vector<uint8_t>& publicKey);
+
+// Extracts the public-key from the top-most certificate in |certificateChain|
+// (which should be a concatenated chain of DER-encoded X.509 certificates).
+//
+// The returned public key will be in the same format as returned by
+// ecKeyPairGetPublicKey().
+//
+optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain);
+
+// Generates a X.509 certificate for |publicKey| (which must be in the format
+// returned by ecKeyPairGetPublicKey()).
+//
+// The certificate is signed by |signingKey| (which must be in the format
+// returned by ecKeyPairGetPrivateKey())
+//
+optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
+        const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey,
+        const string& serialDecimal, const string& issuer, const string& subject,
+        time_t validityNotBefore, time_t validityNotAfter);
+
+// Performs Elliptic-curve Diffie-Helman using |publicKey| (which must be in the
+// format returned by ecKeyPairGetPublicKey()) and |privateKey| (which must be
+// in the format returned by ecKeyPairGetPrivateKey()).
+//
+// On success, the computed shared secret is returned.
+//
+optional<vector<uint8_t>> ecdh(const vector<uint8_t>& publicKey, const vector<uint8_t>& privateKey);
+
+// Key derivation function using SHA-256, conforming to RFC 5869.
+//
+// On success, the derived key is returned.
+//
+optional<vector<uint8_t>> hkdf(const vector<uint8_t>& sharedSecret, const vector<uint8_t>& salt,
+                               const vector<uint8_t>& info, size_t size);
+
+// Returns the X and Y coordinates from |publicKey| (which must be in the format
+// returned by ecKeyPairGetPublicKey()).
+//
+// Success is indicated by the first value in the returned tuple. If successful,
+// the returned coordinates will be in uncompressed form.
+//
+tuple<bool, vector<uint8_t>, vector<uint8_t>> ecPublicKeyGetXandY(const vector<uint8_t>& publicKey);
+
+// Concatenates all certificates into |certificateChain| together into a
+// single bytestring.
+//
+// This is the reverse operation of certificateChainSplit().
+vector<uint8_t> certificateChainJoin(const vector<vector<uint8_t>>& certificateChain);
+
+// Splits all the certificates in a single bytestring into individual
+// certificates.
+//
+// Returns nothing if |certificateChain| contains invalid data.
+//
+// This is the reverse operation of certificateChainJoin().
+optional<vector<vector<uint8_t>>> certificateChainSplit(const vector<uint8_t>& certificateChain);
+
+// Validates that the certificate chain is valid. In particular, checks that each
+// certificate in the chain is signed by the public key in the following certificate.
+//
+// Returns false if |certificateChain| failed validation or if each certificate
+// is not signed by its successor.
+//
+bool certificateChainValidate(const vector<uint8_t>& certificateChain);
+
+// Signs |data| and |detachedContent| with |key| (which must be in the format
+// returned by ecKeyPairGetPrivateKey()).
+//
+// On success, the Signature is returned and will be in COSE_Sign1 format.
+//
+// If |certificateChain| is non-empty it's included in the 'x5chain'
+// protected header element (as as described in'draft-ietf-cose-x509-04').
+//
+optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data,
+                                        const vector<uint8_t>& detachedContent,
+                                        const vector<uint8_t>& certificateChain);
+
+// Checks that |signatureCoseSign1| (in COSE_Sign1 format) is a valid signature
+// made with |public_key| (which must be in the format returned by
+// ecKeyPairGetPublicKey()) where |detachedContent| is the detached content.
+//
+bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1,
+                             const vector<uint8_t>& detachedContent,
+                             const vector<uint8_t>& publicKey);
+
+// Extracts the payload from a COSE_Sign1.
+optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1);
+
+// Extracts the X.509 certificate chain, if present. Returns the data as a
+// concatenated chain of DER-encoded X.509 certificates
+//
+// Returns nothing if there is no 'x5chain' element or an error occurs.
+//
+optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1);
+
+// MACs |data| and |detachedContent| with |key| (which can be any sequence of
+// bytes).
+//
+// If successful, the MAC is returned and will be in COSE_Mac0 format.
+//
+optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data,
+                                   const vector<uint8_t>& detachedContent);
+
+// ---------------------------------------------------------------------------
+// Platform abstraction.
+// ---------------------------------------------------------------------------
+
+// Returns the hardware-bound AES-128 key.
+const vector<uint8_t>& getHardwareBoundKey();
+
+// ---------------------------------------------------------------------------
+// Utility functions specific to IdentityCredential.
+// ---------------------------------------------------------------------------
+
+// Returns a reference to a Result with code OK and empty message.
+const Result& resultOK();
+
+// Returns a new Result with the given code and message.
+Result result(ResultCode code, const char* format, ...) __attribute__((format(printf, 2, 3)));
+
+// Splits the given bytestring into chunks. If the given vector is smaller or equal to
+// |maxChunkSize| a vector with |content| as the only element is returned. Otherwise
+// |content| is split into N vectors each of size |maxChunkSize| except the final element
+// may be smaller than |maxChunkSize|.
+vector<vector<uint8_t>> chunkVector(const vector<uint8_t>& content, size_t maxChunkSize);
+
+// Calculates the MAC for |profile| using |storageKey|.
+optional<vector<uint8_t>> secureAccessControlProfileCalcMac(
+        const SecureAccessControlProfile& profile, const vector<uint8_t>& storageKey);
+
+// Checks authenticity of the MAC in |profile| using |storageKey|.
+bool secureAccessControlProfileCheckMac(const SecureAccessControlProfile& profile,
+                                        const vector<uint8_t>& storageKey);
+
+// Returns the testing AES-128 key where all bits are set to 0.
+const vector<uint8_t>& getTestHardwareBoundKey();
+
+// Creates the AdditionalData CBOR used in the addEntryValue() HIDL method.
+vector<uint8_t> entryCreateAdditionalData(const string& nameSpace, const string& name,
+                                          const vector<uint16_t> accessControlProfileIds);
+
+}  // namespace support
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
+
+#endif  // IDENTITY_SUPPORT_INCLUDE_IDENTITY_CREDENTIAL_UTILS_H_
diff --git a/identity/support/include/cppbor/README.md b/identity/support/include/cppbor/README.md
new file mode 100644
index 0000000..723bfcf
--- /dev/null
+++ b/identity/support/include/cppbor/README.md
@@ -0,0 +1,216 @@
+CppBor: A Modern C++ CBOR Parser and Generator
+==============================================
+
+CppBor provides a natural and easy-to-use syntax for constructing and
+parsing CBOR messages.  It does not (yet) support all features of
+CBOR, nor (yet) support validation against CDDL schemata, though both
+are planned.  CBOR features that aren't supported include:
+
+* Indefinite length values
+* Semantic tagging
+* Floating point
+
+CppBor requires C++-17.
+
+## CBOR representation
+
+CppBor represents CBOR data items as instances of the `Item` class or,
+more precisely, as instances of subclasses of `Item`, since `Item` is a
+pure interface.  The subclasses of `Item` correspond almost one-to-one
+with CBOR major types, and are named to match the CDDL names to which
+they correspond.  They are:
+
+* `Uint` corresponds to major type 0, and can hold unsigned integers
+  up through (2^64 - 1).
+* `Nint` corresponds to major type 1.  It can only hold values from -1
+  to -(2^63 - 1), since it's internal representation is an int64_t.
+  This can be fixed, but it seems unlikely that applications will need
+  the omitted range from -(2^63) to (2^64 - 1), since it's
+  inconvenient to represent them in many programming languages.
+* `Int` is an abstract base of `Uint` and `Nint` that facilitates
+  working with all signed integers representable with int64_t.
+* `Bstr` corresponds to major type 2, a byte string.
+* `Tstr` corresponds to major type 3, a text string.
+* `Array` corresponds to major type 4, an Array.  It holds a
+  variable-length array of `Item`s.
+* `Map` corresponds to major type 5, a Map.  It holds a
+  variable-length array of pairs of `Item`s.
+* `Simple` corresponds to major type 7.  It's an abstract class since
+  items require more specific type.
+* `Bool` is the only currently-implemented subclass of `Simple`.
+
+Note that major type 6, semantic tag, is not yet implemented.
+
+In practice, users of CppBor will rarely use most of these classes
+when generating CBOR encodings.  This is because CppBor provides
+straightforward conversions from the obvious normal C++ types.
+Specifically, the following conversions are provided in appropriate
+contexts:
+
+* Signed and unsigned integers convert to `Uint` or `Nint`, as
+  appropriate.
+* `std::string`, `std::string_view`, `const char*` and
+  `std::pair<char iterator, char iterator>` convert to `Tstr`.
+* `std::vector<uint8_t>`, `std::pair<uint8_t iterator, uint8_t
+  iterator>` and `std::pair<uint8_t*, size_t>` convert to `Bstr`.
+* `bool` converts to `Bool`.
+
+## CBOR generation
+
+### Complete tree generation
+
+The set of `encode` methods in `Item` provide the interface for
+producing encoded CBOR.  The basic process for "complete tree"
+generation (as opposed to "incremental" generation, which is discussed
+below) is to construct an `Item` which models the data to be encoded,
+and then call one of the `encode` methods, whichever is convenient for
+the encoding destination.  A trivial example:
+
+```
+cppbor::Uint val(0);
+std::vector<uint8_t> encoding = val.encode();
+```
+
+    It's relatively rare that single values are encoded as above.  More often, the
+    "root" data item will be an `Array` or `Map` which contains a more complex structure.For example
+    :
+
+``` using cppbor::Map;
+using cppbor::Array;
+
+std::vector<uint8_t> vec =  // ...
+    Map val("key1", Array(Map("key_a", 99 "key_b", vec), "foo"), "key2", true);
+std::vector<uint8_t> encoding = val.encode();
+```
+
+This creates a map with two entries, with `Tstr` keys "Outer1" and
+"Outer2", respectively.  The "Outer1" entry has as its value an
+`Array` containing a `Map` and a `Tstr`.  The "Outer2" entry has a
+`Bool` value.
+
+This example demonstrates how automatic conversion of C++ types to
+CppBor `Item` subclass instances is done.  Where the caller provides a
+C++ or C string, a `Tstr` entry is added.  Where the caller provides
+an integer literal or variable, a `Uint` or `Nint` is added, depending
+on whether the value is positive or negative.
+
+As an alternative, a more fluent-style API is provided for building up
+structures.  For example:
+
+```
+using cppbor::Map;
+using cppbor::Array;
+
+std::vector<uint8_t> vec =  // ...
+    Map val();
+val.add("key1", Array().add(Map().add("key_a", 99).add("key_b", vec)).add("foo")).add("key2", true);
+std::vector<uint8_t> encoding = val.encode();
+```
+
+    An advantage of this interface over the constructor -
+    based creation approach above is that it need not be done all at once
+        .The `add` methods return a reference to the object added to to allow calls to be chained,
+    but chaining is not necessary; calls can be made
+sequentially, as the data to add is available.
+
+#### `encode` methods
+
+There are several variations of `Item::encode`, all of which
+accomplish the same task but output the encoded data in different
+ways, and with somewhat different performance characteristics.  The
+provided options are:
+
+* `bool encode(uint8\_t** pos, const uint8\_t* end)` encodes into the
+  buffer referenced by the range [`*pos`, end).  `*pos` is moved.  If
+  the encoding runs out of buffer space before finishing, the method
+  returns false.  This is the most efficient way to encode, into an
+  already-allocated buffer.
+* `void encode(EncodeCallback encodeCallback)` calls `encodeCallback`
+  for each encoded byte.  It's the responsibility of the implementor
+  of the callback to behave safely in the event that the output buffer
+  (if applicable) is exhausted.  This is less efficient than the prior
+  method because it imposes an additional function call for each byte.
+* `template </*...*/> void encode(OutputIterator i)`
+  encodes into the provided iterator.  SFINAE ensures that the
+  template doesn't match for non-iterators.  The implementation
+  actually uses the callback-based method, plus has whatever overhead
+  the iterator adds.
+* `std::vector<uint8_t> encode()` creates a new std::vector, reserves
+  sufficient capacity to hold the encoding, and inserts the encoded
+  bytes with a std::pushback_iterator and the previous method.
+* `std::string toString()` does the same as the previous method, but
+  returns a string instead of a vector.
+
+### Incremental generation
+
+Incremental generation requires deeper understanding of CBOR, because
+the library can't do as much to ensure that the output is valid.  The
+basic tool for intcremental generation is the `encodeHeader`
+function.  There are two variations, one which writes into a buffer,
+and one which uses a callback.  Both simply write out the bytes of a
+header.  To construct the same map as in the above examples,
+incrementally, one might write:
+
+```
+using namespace cppbor;  // For example brevity
+
+std::vector encoding;
+auto iter = std::back_inserter(result);
+encodeHeader(MAP, 2 /* # of map entries */, iter);
+std::string s = "key1";
+encodeHeader(TSTR, s.size(), iter);
+std::copy(s.begin(), s.end(), iter);
+encodeHeader(ARRAY, 2 /* # of array entries */, iter);
+Map().add("key_a", 99).add("key_b", vec).encode(iter)
+s = "foo";
+encodeHeader(TSTR, foo.size(), iter);
+std::copy(s.begin(), s.end(), iter);
+s = "key2";
+encodeHeader(TSTR, foo.size(), iter);
+std::copy(s.begin(), s.end(), iter);
+encodeHeader(SIMPLE, TRUE, iter);
+```
+
+As the above example demonstrates, the styles can be mixed -- Note the
+creation and encoding of the inner Map using the fluent style.
+
+## Parsing
+
+CppBor also supports parsing of encoded CBOR data, with the same
+feature set as encoding.  There are two basic approaches to parsing,
+"full" and "stream"
+
+### Full parsing
+
+Full parsing means completely parsing a (possibly-compound) data
+item from a byte buffer.  The `parse` functions that do not take a
+`ParseClient` pointer do this.  They return a `ParseResult` which is a
+tuple of three values:
+
+* std::unique_ptr<Item> that points to the parsed item, or is nullptr
+  if there was a parse error.
+* const uint8_t* that points to the byte after the end of the decoded
+  item, or to the first unparseable byte in the event of an error.
+* std::string that is empty on success or contains an error message if
+  a parse error occurred.
+
+Assuming a successful parse, you can then use `Item::type()` to
+discover the type of the parsed item (e.g. MAP), and then use the
+appropriate `Item::as*()` method (e.g. `Item::asMap()`) to get a
+pointer to an interface which allows you to retrieve specific values.
+
+### Stream parsing
+
+Stream parsing is more complex, but more flexible.  To use
+StreamParsing, you must create your own subclass of `ParseClient` and
+call one of the `parse` functions that accepts it.  See the
+`ParseClient` methods docstrings for details.
+
+One unusual feature of stream parsing is that the `ParseClient`
+callback methods not only provide the parsed Item, but also pointers
+to the portion of the buffer that encode that Item.  This is useful
+if, for example, you want to find an element inside of a structure,
+and then copy the encoding of that sub-structure, without bothering to
+parse the rest.
+
+The full parser is implemented with the stream parser.
diff --git a/identity/support/include/cppbor/cppbor.h b/identity/support/include/cppbor/cppbor.h
new file mode 100644
index 0000000..a755db1
--- /dev/null
+++ b/identity/support/include/cppbor/cppbor.h
@@ -0,0 +1,827 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <functional>
+#include <iterator>
+#include <memory>
+#include <numeric>
+#include <string>
+#include <vector>
+
+namespace cppbor {
+
+enum MajorType : uint8_t {
+    UINT = 0 << 5,
+    NINT = 1 << 5,
+    BSTR = 2 << 5,
+    TSTR = 3 << 5,
+    ARRAY = 4 << 5,
+    MAP = 5 << 5,
+    SEMANTIC = 6 << 5,
+    SIMPLE = 7 << 5,
+};
+
+enum SimpleType {
+    BOOLEAN,
+    NULL_T,  // Only two supported, as yet.
+};
+
+enum SpecialAddlInfoValues : uint8_t {
+    FALSE = 20,
+    TRUE = 21,
+    NULL_V = 22,
+    ONE_BYTE_LENGTH = 24,
+    TWO_BYTE_LENGTH = 25,
+    FOUR_BYTE_LENGTH = 26,
+    EIGHT_BYTE_LENGTH = 27,
+};
+
+class Item;
+class Uint;
+class Nint;
+class Int;
+class Tstr;
+class Bstr;
+class Simple;
+class Bool;
+class Array;
+class Map;
+class Null;
+class Semantic;
+
+/**
+ * Returns the size of a CBOR header that contains the additional info value addlInfo.
+ */
+size_t headerSize(uint64_t addlInfo);
+
+/**
+ * Encodes a CBOR header with the specified type and additional info into the range [pos, end).
+ * Returns a pointer to one past the last byte written, or nullptr if there isn't sufficient space
+ * to write the header.
+ */
+uint8_t* encodeHeader(MajorType type, uint64_t addlInfo, uint8_t* pos, const uint8_t* end);
+
+using EncodeCallback = std::function<void(uint8_t)>;
+
+/**
+ * Encodes a CBOR header with the specified type and additional info, passing each byte in turn to
+ * encodeCallback.
+ */
+void encodeHeader(MajorType type, uint64_t addlInfo, EncodeCallback encodeCallback);
+
+/**
+ * Encodes a CBOR header with the specified type and additional info, writing each byte to the
+ * provided OutputIterator.
+ */
+template <typename OutputIterator,
+          typename = std::enable_if_t<std::is_base_of_v<
+                  std::output_iterator_tag,
+                  typename std::iterator_traits<OutputIterator>::iterator_category>>>
+void encodeHeader(MajorType type, uint64_t addlInfo, OutputIterator iter) {
+    return encodeHeader(type, addlInfo, [&](uint8_t v) { *iter++ = v; });
+}
+
+/**
+ * Item represents a CBOR-encodeable data item.  Item is an abstract interface with a set of virtual
+ * methods that allow encoding of the item or conversion to the appropriate derived type.
+ */
+class Item {
+  public:
+    virtual ~Item() {}
+
+    /**
+     * Returns the CBOR type of the item.
+     */
+    virtual MajorType type() const = 0;
+
+    // These methods safely downcast an Item to the appropriate subclass.
+    virtual const Int* asInt() const { return nullptr; }
+    virtual const Uint* asUint() const { return nullptr; }
+    virtual const Nint* asNint() const { return nullptr; }
+    virtual const Tstr* asTstr() const { return nullptr; }
+    virtual const Bstr* asBstr() const { return nullptr; }
+    virtual const Simple* asSimple() const { return nullptr; }
+    virtual const Map* asMap() const { return nullptr; }
+    virtual const Array* asArray() const { return nullptr; }
+    virtual const Semantic* asSemantic() const { return nullptr; }
+
+    /**
+     * Returns true if this is a "compound" item, i.e. one that contains one or more other items.
+     */
+    virtual bool isCompound() const { return false; }
+
+    bool operator==(const Item& other) const&;
+    bool operator!=(const Item& other) const& { return !(*this == other); }
+
+    /**
+     * Returns the number of bytes required to encode this Item into CBOR.  Note that if this is a
+     * complex Item, calling this method will require walking the whole tree.
+     */
+    virtual size_t encodedSize() const = 0;
+
+    /**
+     * Encodes the Item into buffer referenced by range [*pos, end).  Returns a pointer to one past
+     * the last position written.  Returns nullptr if there isn't enough space to encode.
+     */
+    virtual uint8_t* encode(uint8_t* pos, const uint8_t* end) const = 0;
+
+    /**
+     * Encodes the Item by passing each encoded byte to encodeCallback.
+     */
+    virtual void encode(EncodeCallback encodeCallback) const = 0;
+
+    /**
+     * Clones the Item
+     */
+    virtual std::unique_ptr<Item> clone() const = 0;
+
+    /**
+     * Encodes the Item into the provided OutputIterator.
+     */
+    template <typename OutputIterator,
+              typename = typename std::iterator_traits<OutputIterator>::iterator_category>
+    void encode(OutputIterator i) const {
+        return encode([&](uint8_t v) { *i++ = v; });
+    }
+
+    /**
+     * Encodes the Item into a new std::vector<uint8_t>.
+     */
+    std::vector<uint8_t> encode() const {
+        std::vector<uint8_t> retval;
+        retval.reserve(encodedSize());
+        encode(std::back_inserter(retval));
+        return retval;
+    }
+
+    /**
+     * Encodes the Item into a new std::string.
+     */
+    std::string toString() const {
+        std::string retval;
+        retval.reserve(encodedSize());
+        encode([&](uint8_t v) { retval.push_back(v); });
+        return retval;
+    }
+
+    /**
+     * Encodes only the header of the Item.
+     */
+    inline uint8_t* encodeHeader(uint64_t addlInfo, uint8_t* pos, const uint8_t* end) const {
+        return ::cppbor::encodeHeader(type(), addlInfo, pos, end);
+    }
+
+    /**
+     * Encodes only the header of the Item.
+     */
+    inline void encodeHeader(uint64_t addlInfo, EncodeCallback encodeCallback) const {
+        ::cppbor::encodeHeader(type(), addlInfo, encodeCallback);
+    }
+};
+
+/**
+ * Int is an abstraction that allows Uint and Nint objects to be manipulated without caring about
+ * the sign.
+ */
+class Int : public Item {
+  public:
+    bool operator==(const Int& other) const& { return value() == other.value(); }
+
+    virtual int64_t value() const = 0;
+
+    const Int* asInt() const override { return this; }
+};
+
+/**
+ * Uint is a concrete Item that implements CBOR major type 0.
+ */
+class Uint : public Int {
+  public:
+    static constexpr MajorType kMajorType = UINT;
+
+    explicit Uint(uint64_t v) : mValue(v) {}
+
+    bool operator==(const Uint& other) const& { return mValue == other.mValue; }
+
+    MajorType type() const override { return kMajorType; }
+    const Uint* asUint() const override { return this; }
+
+    size_t encodedSize() const override { return headerSize(mValue); }
+
+    int64_t value() const override { return mValue; }
+    uint64_t unsignedValue() const { return mValue; }
+
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
+        return encodeHeader(mValue, pos, end);
+    }
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(mValue, encodeCallback);
+    }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Uint>(mValue); }
+
+  private:
+    uint64_t mValue;
+};
+
+/**
+ * Nint is a concrete Item that implements CBOR major type 1.
+
+ * Note that it is incapable of expressing the full range of major type 1 values, becaue it can only
+ * express values that fall into the range [std::numeric_limits<int64_t>::min(), -1].  It cannot
+ * express values in the range [std::numeric_limits<int64_t>::min() - 1,
+ * -std::numeric_limits<uint64_t>::max()].
+ */
+class Nint : public Int {
+  public:
+    static constexpr MajorType kMajorType = NINT;
+
+    explicit Nint(int64_t v);
+
+    bool operator==(const Nint& other) const& { return mValue == other.mValue; }
+
+    MajorType type() const override { return kMajorType; }
+    const Nint* asNint() const override { return this; }
+    size_t encodedSize() const override { return headerSize(addlInfo()); }
+
+    int64_t value() const override { return mValue; }
+
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
+        return encodeHeader(addlInfo(), pos, end);
+    }
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(addlInfo(), encodeCallback);
+    }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Nint>(mValue); }
+
+  private:
+    uint64_t addlInfo() const { return -1ll - mValue; }
+
+    int64_t mValue;
+};
+
+/**
+ * Bstr is a concrete Item that implements major type 2.
+ */
+class Bstr : public Item {
+  public:
+    static constexpr MajorType kMajorType = BSTR;
+
+    // Construct from a vector
+    explicit Bstr(std::vector<uint8_t> v) : mValue(std::move(v)) {}
+
+    // Construct from a string
+    explicit Bstr(const std::string& v)
+        : mValue(reinterpret_cast<const uint8_t*>(v.data()),
+                 reinterpret_cast<const uint8_t*>(v.data()) + v.size()) {}
+
+    // Construct from a pointer/size pair
+    explicit Bstr(const std::pair<const uint8_t*, size_t>& buf)
+        : mValue(buf.first, buf.first + buf.second) {}
+
+    // Construct from a pair of iterators
+    template <typename I1, typename I2,
+              typename = typename std::iterator_traits<I1>::iterator_category,
+              typename = typename std::iterator_traits<I2>::iterator_category>
+    explicit Bstr(const std::pair<I1, I2>& pair) : mValue(pair.first, pair.second) {}
+
+    // Construct from an iterator range.
+    template <typename I1, typename I2,
+              typename = typename std::iterator_traits<I1>::iterator_category,
+              typename = typename std::iterator_traits<I2>::iterator_category>
+    Bstr(I1 begin, I2 end) : mValue(begin, end) {}
+
+    bool operator==(const Bstr& other) const& { return mValue == other.mValue; }
+
+    MajorType type() const override { return kMajorType; }
+    const Bstr* asBstr() const override { return this; }
+    size_t encodedSize() const override { return headerSize(mValue.size()) + mValue.size(); }
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override;
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(mValue.size(), encodeCallback);
+        encodeValue(encodeCallback);
+    }
+
+    const std::vector<uint8_t>& value() const { return mValue; }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Bstr>(mValue); }
+
+  private:
+    void encodeValue(EncodeCallback encodeCallback) const;
+
+    std::vector<uint8_t> mValue;
+};
+
+/**
+ * Bstr is a concrete Item that implements major type 3.
+ */
+class Tstr : public Item {
+  public:
+    static constexpr MajorType kMajorType = TSTR;
+
+    // Construct from a string
+    explicit Tstr(std::string v) : mValue(std::move(v)) {}
+
+    // Construct from a string_view
+    explicit Tstr(const std::string_view& v) : mValue(v) {}
+
+    // Construct from a C string
+    explicit Tstr(const char* v) : mValue(std::string(v)) {}
+
+    // Construct from a pair of iterators
+    template <typename I1, typename I2,
+              typename = typename std::iterator_traits<I1>::iterator_category,
+              typename = typename std::iterator_traits<I2>::iterator_category>
+    explicit Tstr(const std::pair<I1, I2>& pair) : mValue(pair.first, pair.second) {}
+
+    // Construct from an iterator range
+    template <typename I1, typename I2,
+              typename = typename std::iterator_traits<I1>::iterator_category,
+              typename = typename std::iterator_traits<I2>::iterator_category>
+    Tstr(I1 begin, I2 end) : mValue(begin, end) {}
+
+    bool operator==(const Tstr& other) const& { return mValue == other.mValue; }
+
+    MajorType type() const override { return kMajorType; }
+    const Tstr* asTstr() const override { return this; }
+    size_t encodedSize() const override { return headerSize(mValue.size()) + mValue.size(); }
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override;
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(mValue.size(), encodeCallback);
+        encodeValue(encodeCallback);
+    }
+
+    const std::string& value() const { return mValue; }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Tstr>(mValue); }
+
+  private:
+    void encodeValue(EncodeCallback encodeCallback) const;
+
+    std::string mValue;
+};
+
+/**
+ * CompoundItem is an abstract Item that provides common functionality for Items that contain other
+ * items, i.e. Arrays (CBOR type 4) and Maps (CBOR type 5).
+ */
+class CompoundItem : public Item {
+  public:
+    bool operator==(const CompoundItem& other) const&;
+
+    virtual size_t size() const { return mEntries.size(); }
+
+    bool isCompound() const override { return true; }
+
+    size_t encodedSize() const override {
+        return std::accumulate(mEntries.begin(), mEntries.end(), headerSize(size()),
+                               [](size_t sum, auto& entry) { return sum + entry->encodedSize(); });
+    }
+
+    using Item::encode;  // Make base versions visible.
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override;
+    void encode(EncodeCallback encodeCallback) const override;
+
+    virtual uint64_t addlInfo() const = 0;
+
+  protected:
+    std::vector<std::unique_ptr<Item>> mEntries;
+};
+
+/*
+ * Array is a concrete Item that implements CBOR major type 4.
+ *
+ * Note that Arrays are not copyable.  This is because copying them is expensive and making them
+ * move-only ensures that they're never copied accidentally.  If you actually want to copy an Array,
+ * use the clone() method.
+ */
+class Array : public CompoundItem {
+  public:
+    static constexpr MajorType kMajorType = ARRAY;
+
+    Array() = default;
+    Array(const Array& other) = delete;
+    Array(Array&&) = default;
+    Array& operator=(const Array&) = delete;
+    Array& operator=(Array&&) = default;
+
+    /**
+     * Construct an Array from a variable number of arguments of different types.  See
+     * details::makeItem below for details on what types may be provided.  In general, this accepts
+     * all of the types you'd expect and doest the things you'd expect (integral values are addes as
+     * Uint or Nint, std::string and char* are added as Tstr, bools are added as Bool, etc.).
+     */
+    template <typename... Args, typename Enable>
+    Array(Args&&... args);
+
+    /**
+     * Append a single element to the Array, of any compatible type.
+     */
+    template <typename T>
+    Array& add(T&& v) &;
+    template <typename T>
+    Array&& add(T&& v) &&;
+
+    const std::unique_ptr<Item>& operator[](size_t index) const { return mEntries[index]; }
+    std::unique_ptr<Item>& operator[](size_t index) { return mEntries[index]; }
+
+    MajorType type() const override { return kMajorType; }
+    const Array* asArray() const override { return this; }
+
+    virtual std::unique_ptr<Item> clone() const override;
+
+    uint64_t addlInfo() const override { return size(); }
+};
+
+/*
+ * Map is a concrete Item that implements CBOR major type 5.
+ *
+ * Note that Maps are not copyable.  This is because copying them is expensive and making them
+ * move-only ensures that they're never copied accidentally.  If you actually want to copy a
+ * Map, use the clone() method.
+ */
+class Map : public CompoundItem {
+  public:
+    static constexpr MajorType kMajorType = MAP;
+
+    Map() = default;
+    Map(const Map& other) = delete;
+    Map(Map&&) = default;
+    Map& operator=(const Map& other) = delete;
+    Map& operator=(Map&&) = default;
+
+    /**
+     * Construct a Map from a variable number of arguments of different types.  An even number of
+     * arguments must be provided (this is verified statically). See details::makeItem below for
+     * details on what types may be provided.  In general, this accepts all of the types you'd
+     * expect and doest the things you'd expect (integral values are addes as Uint or Nint,
+     * std::string and char* are added as Tstr, bools are added as Bool, etc.).
+     */
+    template <typename... Args, typename Enable>
+    Map(Args&&... args);
+
+    /**
+     * Append a key/value pair to the Map, of any compatible types.
+     */
+    template <typename Key, typename Value>
+    Map& add(Key&& key, Value&& value) &;
+    template <typename Key, typename Value>
+    Map&& add(Key&& key, Value&& value) &&;
+
+    size_t size() const override {
+        assertInvariant();
+        return mEntries.size() / 2;
+    }
+
+    template <typename Key, typename Enable>
+    std::pair<std::unique_ptr<Item>&, bool> get(Key key);
+
+    std::pair<const std::unique_ptr<Item>&, const std::unique_ptr<Item>&> operator[](
+            size_t index) const {
+        assertInvariant();
+        return {mEntries[index * 2], mEntries[index * 2 + 1]};
+    }
+
+    std::pair<std::unique_ptr<Item>&, std::unique_ptr<Item>&> operator[](size_t index) {
+        assertInvariant();
+        return {mEntries[index * 2], mEntries[index * 2 + 1]};
+    }
+
+    MajorType type() const override { return kMajorType; }
+    const Map* asMap() const override { return this; }
+
+    virtual std::unique_ptr<Item> clone() const override;
+
+    uint64_t addlInfo() const override { return size(); }
+
+  private:
+    void assertInvariant() const;
+};
+
+class Semantic : public CompoundItem {
+  public:
+    static constexpr MajorType kMajorType = SEMANTIC;
+
+    template <typename T>
+    explicit Semantic(uint64_t value, T&& child);
+
+    Semantic(const Semantic& other) = delete;
+    Semantic(Semantic&&) = default;
+    Semantic& operator=(const Semantic& other) = delete;
+    Semantic& operator=(Semantic&&) = default;
+
+    size_t size() const override {
+        assertInvariant();
+        return 1;
+    }
+
+    size_t encodedSize() const override {
+        return std::accumulate(mEntries.begin(), mEntries.end(), headerSize(mValue),
+                               [](size_t sum, auto& entry) { return sum + entry->encodedSize(); });
+    }
+
+    MajorType type() const override { return kMajorType; }
+    const Semantic* asSemantic() const override { return this; }
+
+    const std::unique_ptr<Item>& child() const {
+        assertInvariant();
+        return mEntries[0];
+    }
+
+    std::unique_ptr<Item>& child() {
+        assertInvariant();
+        return mEntries[0];
+    }
+
+    uint64_t value() const { return mValue; }
+
+    uint64_t addlInfo() const override { return value(); }
+
+    virtual std::unique_ptr<Item> clone() const override {
+        assertInvariant();
+        return std::make_unique<Semantic>(mValue, mEntries[0]->clone());
+    }
+
+  protected:
+    Semantic() = default;
+    Semantic(uint64_t value) : mValue(value) {}
+    uint64_t mValue;
+
+  private:
+    void assertInvariant() const;
+};
+
+/**
+ * Simple is abstract Item that implements CBOR major type 7.  It is intended to be subclassed to
+ * create concrete Simple types.  At present only Bool is provided.
+ */
+class Simple : public Item {
+  public:
+    static constexpr MajorType kMajorType = SIMPLE;
+
+    bool operator==(const Simple& other) const&;
+
+    virtual SimpleType simpleType() const = 0;
+    MajorType type() const override { return kMajorType; }
+
+    const Simple* asSimple() const override { return this; }
+
+    virtual const Bool* asBool() const { return nullptr; };
+    virtual const Null* asNull() const { return nullptr; };
+};
+
+/**
+ * Bool is a concrete type that implements CBOR major type 7, with additional item values for TRUE
+ * and FALSE.
+ */
+class Bool : public Simple {
+  public:
+    static constexpr SimpleType kSimpleType = BOOLEAN;
+
+    explicit Bool(bool v) : mValue(v) {}
+
+    bool operator==(const Bool& other) const& { return mValue == other.mValue; }
+
+    SimpleType simpleType() const override { return kSimpleType; }
+    const Bool* asBool() const override { return this; }
+
+    size_t encodedSize() const override { return 1; }
+
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
+        return encodeHeader(mValue ? TRUE : FALSE, pos, end);
+    }
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(mValue ? TRUE : FALSE, encodeCallback);
+    }
+
+    bool value() const { return mValue; }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Bool>(mValue); }
+
+  private:
+    bool mValue;
+};
+
+/**
+ * Null is a concrete type that implements CBOR major type 7, with additional item value for NULL
+ */
+class Null : public Simple {
+  public:
+    static constexpr SimpleType kSimpleType = NULL_T;
+
+    explicit Null() {}
+
+    SimpleType simpleType() const override { return kSimpleType; }
+    const Null* asNull() const override { return this; }
+
+    size_t encodedSize() const override { return 1; }
+
+    using Item::encode;
+    uint8_t* encode(uint8_t* pos, const uint8_t* end) const override {
+        return encodeHeader(NULL_V, pos, end);
+    }
+    void encode(EncodeCallback encodeCallback) const override {
+        encodeHeader(NULL_V, encodeCallback);
+    }
+
+    virtual std::unique_ptr<Item> clone() const override { return std::make_unique<Null>(); }
+};
+
+template <typename T>
+std::unique_ptr<T> downcastItem(std::unique_ptr<Item>&& v) {
+    static_assert(std::is_base_of_v<Item, T> && !std::is_abstract_v<T>,
+                  "returned type is not an Item or is an abstract class");
+    if (v && T::kMajorType == v->type()) {
+        if constexpr (std::is_base_of_v<Simple, T>) {
+            if (T::kSimpleType != v->asSimple()->simpleType()) {
+                return nullptr;
+            }
+        }
+        return std::unique_ptr<T>(static_cast<T*>(v.release()));
+    } else {
+        return nullptr;
+    }
+}
+
+/**
+ * Details. Mostly you shouldn't have to look below, except perhaps at the docstring for makeItem.
+ */
+namespace details {
+
+template <typename T, typename V, typename Enable = void>
+struct is_iterator_pair_over : public std::false_type {};
+
+template <typename I1, typename I2, typename V>
+struct is_iterator_pair_over<
+        std::pair<I1, I2>, V,
+        typename std::enable_if_t<std::is_same_v<V, typename std::iterator_traits<I1>::value_type>>>
+    : public std::true_type {};
+
+template <typename T, typename V, typename Enable = void>
+struct is_unique_ptr_of_subclass_of_v : public std::false_type {};
+
+template <typename T, typename P>
+struct is_unique_ptr_of_subclass_of_v<T, std::unique_ptr<P>,
+                                      typename std::enable_if_t<std::is_base_of_v<T, P>>>
+    : public std::true_type {};
+
+/* check if type is one of std::string (1), std::string_view (2), null-terminated char* (3) or pair
+ *     of iterators (4)*/
+template <typename T, typename Enable = void>
+struct is_text_type_v : public std::false_type {};
+
+template <typename T>
+struct is_text_type_v<
+        T, typename std::enable_if_t<
+                   /* case 1 */  //
+                   std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, std::string>
+                   /* case 2 */  //
+                   || std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>, std::string_view>
+                   /* case 3 */                                                 //
+                   || std::is_same_v<std::remove_cv_t<std::decay_t<T>>, char*>  //
+                   || std::is_same_v<std::remove_cv_t<std::decay_t<T>>, const char*>
+                   /* case 4 */
+                   || details::is_iterator_pair_over<T, char>::value>> : public std::true_type {};
+
+/**
+ * Construct a unique_ptr<Item> from many argument types. Accepts:
+ *
+ * (a) booleans;
+ * (b) integers, all sizes and signs;
+ * (c) text strings, as defined by is_text_type_v above;
+ * (d) byte strings, as std::vector<uint8_t>(d1), pair of iterators (d2) or pair<uint8_t*, size_T>
+ *     (d3); and
+ * (e) Item subclass instances, including Array and Map.  Items may be provided by naked pointer
+ *     (e1), unique_ptr (e2), reference (e3) or value (e3).  If provided by reference or value, will
+ *     be moved if possible.  If provided by pointer, ownership is taken.
+ * (f) null pointer;
+ */
+template <typename T>
+std::unique_ptr<Item> makeItem(T v) {
+    Item* p = nullptr;
+    if constexpr (/* case a */ std::is_same_v<T, bool>) {
+        p = new Bool(v);
+    } else if constexpr (/* case b */ std::is_integral_v<T>) {  // b
+        if (v < 0) {
+            p = new Nint(v);
+        } else {
+            p = new Uint(static_cast<uint64_t>(v));
+        }
+    } else if constexpr (/* case c */  //
+                         details::is_text_type_v<T>::value) {
+        p = new Tstr(v);
+    } else if constexpr (/* case d1 */  //
+                         std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>,
+                                        std::vector<uint8_t>>
+                         /* case d2 */  //
+                         || details::is_iterator_pair_over<T, uint8_t>::value
+                         /* case d3 */  //
+                         || std::is_same_v<std::remove_cv_t<std::remove_reference_t<T>>,
+                                           std::pair<uint8_t*, size_t>>) {
+        p = new Bstr(v);
+    } else if constexpr (/* case e1 */  //
+                         std::is_pointer_v<T> &&
+                         std::is_base_of_v<Item, std::remove_pointer_t<T>>) {
+        p = v;
+    } else if constexpr (/* case e2 */  //
+                         details::is_unique_ptr_of_subclass_of_v<Item, T>::value) {
+        p = v.release();
+    } else if constexpr (/* case e3 */  //
+                         std::is_base_of_v<Item, T>) {
+        p = new T(std::move(v));
+    } else if constexpr (/* case f */ std::is_null_pointer_v<T>) {
+        p = new Null();
+    } else {
+        // It's odd that this can't be static_assert(false), since it shouldn't be evaluated if one
+        // of the above ifs matches.  But static_assert(false) always triggers.
+        static_assert(std::is_same_v<T, bool>, "makeItem called with unsupported type");
+    }
+    return std::unique_ptr<Item>(p);
+}
+
+}  // namespace details
+
+template <typename... Args,
+          /* Prevent use as copy ctor */ typename = std::enable_if_t<
+                  (sizeof...(Args)) != 1 ||
+                  !(std::is_same_v<Array, std::remove_cv_t<std::remove_reference_t<Args>>> || ...)>>
+Array::Array(Args&&... args) {
+    mEntries.reserve(sizeof...(args));
+    (mEntries.push_back(details::makeItem(std::forward<Args>(args))), ...);
+}
+
+template <typename T>
+Array& Array::add(T&& v) & {
+    mEntries.push_back(details::makeItem(std::forward<T>(v)));
+    return *this;
+}
+
+template <typename T>
+Array&& Array::add(T&& v) && {
+    mEntries.push_back(details::makeItem(std::forward<T>(v)));
+    return std::move(*this);
+}
+
+template <typename... Args,
+          /* Prevent use as copy ctor */ typename = std::enable_if_t<(sizeof...(Args)) != 1>>
+Map::Map(Args&&... args) {
+    static_assert((sizeof...(Args)) % 2 == 0, "Map must have an even number of entries");
+    mEntries.reserve(sizeof...(args));
+    (mEntries.push_back(details::makeItem(std::forward<Args>(args))), ...);
+}
+
+template <typename Key, typename Value>
+Map& Map::add(Key&& key, Value&& value) & {
+    mEntries.push_back(details::makeItem(std::forward<Key>(key)));
+    mEntries.push_back(details::makeItem(std::forward<Value>(value)));
+    return *this;
+}
+
+template <typename Key, typename Value>
+Map&& Map::add(Key&& key, Value&& value) && {
+    this->add(std::forward<Key>(key), std::forward<Value>(value));
+    return std::move(*this);
+}
+
+template <typename Key, typename = std::enable_if_t<std::is_integral_v<Key> ||
+                                                    details::is_text_type_v<Key>::value>>
+std::pair<std::unique_ptr<Item>&, bool> Map::get(Key key) {
+    assertInvariant();
+    auto keyItem = details::makeItem(key);
+    for (size_t i = 0; i < mEntries.size(); i += 2) {
+        if (*keyItem == *mEntries[i]) {
+            return {mEntries[i + 1], true};
+        }
+    }
+    return {keyItem, false};
+}
+
+template <typename T>
+Semantic::Semantic(uint64_t value, T&& child) : mValue(value) {
+    mEntries.reserve(1);
+    mEntries.push_back(details::makeItem(std::forward<T>(child)));
+}
+
+}  // namespace cppbor
diff --git a/identity/support/include/cppbor/cppbor_parse.h b/identity/support/include/cppbor/cppbor_parse.h
new file mode 100644
index 0000000..66cd5a3
--- /dev/null
+++ b/identity/support/include/cppbor/cppbor_parse.h
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "cppbor.h"
+
+namespace cppbor {
+
+using ParseResult = std::tuple<std::unique_ptr<Item> /* result */, const uint8_t* /* newPos */,
+                               std::string /* errMsg */>;
+
+/**
+ * Parse the first CBOR data item (possibly compound) from the range [begin, end).
+ *
+ * Returns a tuple of Item pointer, buffer pointer and error message.  If parsing is successful, the
+ * Item pointer is non-null, the buffer pointer points to the first byte after the
+ * successfully-parsed item and the error message string is empty.  If parsing fails, the Item
+ * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
+ * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
+ * too large for the remining buffer, etc.) and the string contains an error message describing the
+ * problem encountered.
+ */
+ParseResult parse(const uint8_t* begin, const uint8_t* end);
+
+/**
+ * Parse the first CBOR data item (possibly compound) from the byte vector.
+ *
+ * Returns a tuple of Item pointer, buffer pointer and error message.  If parsing is successful, the
+ * Item pointer is non-null, the buffer pointer points to the first byte after the
+ * successfully-parsed item and the error message string is empty.  If parsing fails, the Item
+ * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
+ * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
+ * too large for the remining buffer, etc.) and the string contains an error message describing the
+ * problem encountered.
+ */
+inline ParseResult parse(const std::vector<uint8_t>& encoding) {
+    return parse(encoding.data(), encoding.data() + encoding.size());
+}
+
+/**
+ * Parse the first CBOR data item (possibly compound) from the range [begin, begin + size).
+ *
+ * Returns a tuple of Item pointer, buffer pointer and error message.  If parsing is successful, the
+ * Item pointer is non-null, the buffer pointer points to the first byte after the
+ * successfully-parsed item and the error message string is empty.  If parsing fails, the Item
+ * pointer is null, the buffer pointer points to the first byte that was unparseable (the first byte
+ * of a data item header that is malformed in some way, e.g. an invalid value, or a length that is
+ * too large for the remining buffer, etc.) and the string contains an error message describing the
+ * problem encountered.
+ */
+inline ParseResult parse(const uint8_t* begin, size_t size) {
+    return parse(begin, begin + size);
+}
+
+class ParseClient;
+
+/**
+ * Parse the CBOR data in the range [begin, end) in streaming fashion, calling methods on the
+ * provided ParseClient when elements are found.
+ */
+void parse(const uint8_t* begin, const uint8_t* end, ParseClient* parseClient);
+
+/**
+ * Parse the CBOR data in the vector in streaming fashion, calling methods on the
+ * provided ParseClient when elements are found.
+ */
+inline void parse(const std::vector<uint8_t>& encoding, ParseClient* parseClient) {
+    return parse(encoding.data(), encoding.data() + encoding.size(), parseClient);
+}
+
+/**
+ * A pure interface that callers of the streaming parse functions must implement.
+ */
+class ParseClient {
+  public:
+    virtual ~ParseClient() {}
+
+    /**
+     * Called when an item is found.  The Item pointer points to the found item; use type() and
+     * the appropriate as*() method to examine the value.  hdrBegin points to the first byte of the
+     * header, valueBegin points to the first byte of the value and end points one past the end of
+     * the item.  In the case of header-only items, such as integers, and compound items (ARRAY,
+     * MAP or SEMANTIC) whose end has not yet been found, valueBegin and end are equal and point to
+     * the byte past the header.
+     *
+     * Note that for compound types (ARRAY, MAP, and SEMANTIC), the Item will have no content.  For
+     * Map and Array items, the size() method will return a correct value, but the index operators
+     * are unsafe, and the object cannot be safely compared with another Array/Map.
+     *
+     * The method returns a ParseClient*.  In most cases "return this;" will be the right answer,
+     * but a different ParseClient may be returned, which the parser will begin using. If the method
+     * returns nullptr, parsing will be aborted immediately.
+     */
+    virtual ParseClient* item(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
+                              const uint8_t* valueBegin, const uint8_t* end) = 0;
+
+    /**
+     * Called when the end of a compound item (MAP or ARRAY) is found.  The item argument will be
+     * the same one passed to the item() call -- and may be empty if item() moved its value out.
+     * hdrBegin, valueBegin and end point to the beginning of the item header, the beginning of the
+     * first contained value, and one past the end of the last contained value, respectively.
+     *
+     * Note that the Item will have no content.
+     *
+     * As with item(), itemEnd() can change the ParseClient by returning a different one, or end the
+     * parsing by returning nullptr;
+     */
+    virtual ParseClient* itemEnd(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
+                                 const uint8_t* valueBegin, const uint8_t* end) = 0;
+
+    /**
+     * Called when parsing encounters an error.  position is set to the first unparsed byte (one
+     * past the last successfully-parsed byte) and errorMessage contains an message explaining what
+     * sort of error occurred.
+     */
+    virtual void error(const uint8_t* position, const std::string& errorMessage) = 0;
+};
+
+}  // namespace cppbor
diff --git a/identity/support/src/IdentityCredentialSupport.cpp b/identity/support/src/IdentityCredentialSupport.cpp
new file mode 100644
index 0000000..7d93a4b
--- /dev/null
+++ b/identity/support/src/IdentityCredentialSupport.cpp
@@ -0,0 +1,1815 @@
+/*
+ * 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 "IdentityCredentialSupport"
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#define _POSIX_C_SOURCE 199309L
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <time.h>
+#include <iomanip>
+
+#include <openssl/aes.h>
+#include <openssl/bn.h>
+#include <openssl/crypto.h>
+#include <openssl/ec.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/hkdf.h>
+#include <openssl/hmac.h>
+#include <openssl/objects.h>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include <openssl/rand.h>
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+
+#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+namespace android {
+namespace hardware {
+namespace identity {
+namespace support {
+
+using ::std::pair;
+using ::std::unique_ptr;
+
+// ---------------------------------------------------------------------------
+// Miscellaneous utilities.
+// ---------------------------------------------------------------------------
+
+void hexdump(const string& name, const vector<uint8_t>& data) {
+    fprintf(stderr, "%s: dumping %zd bytes\n", name.c_str(), data.size());
+    size_t n, m, o;
+    for (n = 0; n < data.size(); n += 16) {
+        fprintf(stderr, "%04zx  ", n);
+        for (m = 0; m < 16 && n + m < data.size(); m++) {
+            fprintf(stderr, "%02x ", data[n + m]);
+        }
+        for (o = m; o < 16; o++) {
+            fprintf(stderr, "   ");
+        }
+        fprintf(stderr, " ");
+        for (m = 0; m < 16 && n + m < data.size(); m++) {
+            int c = data[n + m];
+            fprintf(stderr, "%c", isprint(c) ? c : '.');
+        }
+        fprintf(stderr, "\n");
+    }
+    fprintf(stderr, "\n");
+}
+
+string encodeHex(const uint8_t* data, size_t dataLen) {
+    static const char hexDigits[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
+                                       '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+    string ret;
+    ret.resize(dataLen * 2);
+    for (size_t n = 0; n < dataLen; n++) {
+        uint8_t byte = data[n];
+        ret[n * 2 + 0] = hexDigits[byte >> 4];
+        ret[n * 2 + 1] = hexDigits[byte & 0x0f];
+    }
+
+    return ret;
+}
+
+string encodeHex(const string& str) {
+    return encodeHex(reinterpret_cast<const uint8_t*>(str.data()), str.size());
+}
+
+string encodeHex(const vector<uint8_t>& data) {
+    return encodeHex(data.data(), data.size());
+}
+
+// Returns -1 on error, otherwise an integer in the range 0 through 15, both inclusive.
+int parseHexDigit(char hexDigit) {
+    if (hexDigit >= '0' && hexDigit <= '9') {
+        return int(hexDigit) - '0';
+    } else if (hexDigit >= 'a' && hexDigit <= 'f') {
+        return int(hexDigit) - 'a' + 10;
+    } else if (hexDigit >= 'A' && hexDigit <= 'F') {
+        return int(hexDigit) - 'A' + 10;
+    }
+    return -1;
+}
+
+optional<vector<uint8_t>> decodeHex(const string& hexEncoded) {
+    vector<uint8_t> out;
+    size_t hexSize = hexEncoded.size();
+    if ((hexSize & 1) != 0) {
+        LOG(ERROR) << "Size of data cannot be odd";
+        return {};
+    }
+
+    out.resize(hexSize / 2);
+    for (size_t n = 0; n < hexSize / 2; n++) {
+        int upperNibble = parseHexDigit(hexEncoded[n * 2]);
+        int lowerNibble = parseHexDigit(hexEncoded[n * 2 + 1]);
+        if (upperNibble == -1 || lowerNibble == -1) {
+            LOG(ERROR) << "Invalid hex digit at position " << n;
+            return {};
+        }
+        out[n] = (upperNibble << 4) + lowerNibble;
+    }
+
+    return out;
+}
+
+// ---------------------------------------------------------------------------
+// CBOR utilities.
+// ---------------------------------------------------------------------------
+
+static bool cborAreAllElementsNonCompound(const cppbor::CompoundItem* compoundItem) {
+    if (compoundItem->type() == cppbor::ARRAY) {
+        const cppbor::Array* array = compoundItem->asArray();
+        for (size_t n = 0; n < array->size(); n++) {
+            const cppbor::Item* entry = (*array)[n].get();
+            switch (entry->type()) {
+                case cppbor::ARRAY:
+                case cppbor::MAP:
+                    return false;
+                default:
+                    break;
+            }
+        }
+    } else {
+        const cppbor::Map* map = compoundItem->asMap();
+        for (size_t n = 0; n < map->size(); n++) {
+            auto [keyEntry, valueEntry] = (*map)[n];
+            switch (keyEntry->type()) {
+                case cppbor::ARRAY:
+                case cppbor::MAP:
+                    return false;
+                default:
+                    break;
+            }
+            switch (valueEntry->type()) {
+                case cppbor::ARRAY:
+                case cppbor::MAP:
+                    return false;
+                default:
+                    break;
+            }
+        }
+    }
+    return true;
+}
+
+static bool cborPrettyPrintInternal(const cppbor::Item* item, string& out, size_t indent,
+                                    size_t maxBStrSize, const vector<string>& mapKeysToNotPrint) {
+    char buf[80];
+
+    string indentString(indent, ' ');
+
+    switch (item->type()) {
+        case cppbor::UINT:
+            snprintf(buf, sizeof(buf), "%" PRIu64, item->asUint()->unsignedValue());
+            out.append(buf);
+            break;
+
+        case cppbor::NINT:
+            snprintf(buf, sizeof(buf), "%" PRId64, item->asNint()->value());
+            out.append(buf);
+            break;
+
+        case cppbor::BSTR: {
+            const cppbor::Bstr* bstr = item->asBstr();
+            const vector<uint8_t>& value = bstr->value();
+            if (value.size() > maxBStrSize) {
+                unsigned char digest[SHA_DIGEST_LENGTH];
+                SHA_CTX ctx;
+                SHA1_Init(&ctx);
+                SHA1_Update(&ctx, value.data(), value.size());
+                SHA1_Final(digest, &ctx);
+                char buf2[SHA_DIGEST_LENGTH * 2 + 1];
+                for (size_t n = 0; n < SHA_DIGEST_LENGTH; n++) {
+                    snprintf(buf2 + n * 2, 3, "%02x", digest[n]);
+                }
+                snprintf(buf, sizeof(buf), "<bstr size=%zd sha1=%s>", value.size(), buf2);
+                out.append(buf);
+            } else {
+                out.append("{");
+                for (size_t n = 0; n < value.size(); n++) {
+                    if (n > 0) {
+                        out.append(", ");
+                    }
+                    snprintf(buf, sizeof(buf), "0x%02x", value[n]);
+                    out.append(buf);
+                }
+                out.append("}");
+            }
+        } break;
+
+        case cppbor::TSTR:
+            out.append("'");
+            {
+                // TODO: escape "'" characters
+                out.append(item->asTstr()->value().c_str());
+            }
+            out.append("'");
+            break;
+
+        case cppbor::ARRAY: {
+            const cppbor::Array* array = item->asArray();
+            if (array->size() == 0) {
+                out.append("[]");
+            } else if (cborAreAllElementsNonCompound(array)) {
+                out.append("[");
+                for (size_t n = 0; n < array->size(); n++) {
+                    if (!cborPrettyPrintInternal((*array)[n].get(), out, indent + 2, maxBStrSize,
+                                                 mapKeysToNotPrint)) {
+                        return false;
+                    }
+                    out.append(", ");
+                }
+                out.append("]");
+            } else {
+                out.append("[\n" + indentString);
+                for (size_t n = 0; n < array->size(); n++) {
+                    out.append("  ");
+                    if (!cborPrettyPrintInternal((*array)[n].get(), out, indent + 2, maxBStrSize,
+                                                 mapKeysToNotPrint)) {
+                        return false;
+                    }
+                    out.append(",\n" + indentString);
+                }
+                out.append("]");
+            }
+        } break;
+
+        case cppbor::MAP: {
+            const cppbor::Map* map = item->asMap();
+
+            if (map->size() == 0) {
+                out.append("{}");
+            } else {
+                out.append("{\n" + indentString);
+                for (size_t n = 0; n < map->size(); n++) {
+                    out.append("  ");
+
+                    auto [map_key, map_value] = (*map)[n];
+
+                    if (!cborPrettyPrintInternal(map_key.get(), out, indent + 2, maxBStrSize,
+                                                 mapKeysToNotPrint)) {
+                        return false;
+                    }
+                    out.append(" : ");
+                    if (map_key->type() == cppbor::TSTR &&
+                        std::find(mapKeysToNotPrint.begin(), mapKeysToNotPrint.end(),
+                                  map_key->asTstr()->value()) != mapKeysToNotPrint.end()) {
+                        out.append("<not printed>");
+                    } else {
+                        if (!cborPrettyPrintInternal(map_value.get(), out, indent + 2, maxBStrSize,
+                                                     mapKeysToNotPrint)) {
+                            return false;
+                        }
+                    }
+                    out.append(",\n" + indentString);
+                }
+                out.append("}");
+            }
+        } break;
+
+        case cppbor::SEMANTIC: {
+            const cppbor::Semantic* semantic = item->asSemantic();
+            snprintf(buf, sizeof(buf), "tag %" PRIu64 " ", semantic->value());
+            out.append(buf);
+            cborPrettyPrintInternal(semantic->child().get(), out, indent, maxBStrSize,
+                                    mapKeysToNotPrint);
+        } break;
+
+        case cppbor::SIMPLE:
+            const cppbor::Bool* asBool = item->asSimple()->asBool();
+            const cppbor::Null* asNull = item->asSimple()->asNull();
+            if (asBool != nullptr) {
+                out.append(asBool->value() ? "true" : "false");
+            } else if (asNull != nullptr) {
+                out.append("null");
+            } else {
+                LOG(ERROR) << "Only boolean/null is implemented for SIMPLE";
+                return false;
+            }
+            break;
+    }
+
+    return true;
+}
+
+string cborPrettyPrint(const vector<uint8_t>& encodedCbor, size_t maxBStrSize,
+                       const vector<string>& mapKeysToNotPrint) {
+    auto [item, _, message] = cppbor::parse(encodedCbor);
+    if (item == nullptr) {
+        LOG(ERROR) << "Data to pretty print is not valid CBOR: " << message;
+        return "";
+    }
+
+    string out;
+    cborPrettyPrintInternal(item.get(), out, 0, maxBStrSize, mapKeysToNotPrint);
+    return out;
+}
+
+// ---------------------------------------------------------------------------
+// Crypto functionality / abstraction.
+// ---------------------------------------------------------------------------
+
+struct EVP_CIPHER_CTX_Deleter {
+    void operator()(EVP_CIPHER_CTX* ctx) const {
+        if (ctx != nullptr) {
+            EVP_CIPHER_CTX_free(ctx);
+        }
+    }
+};
+
+using EvpCipherCtxPtr = unique_ptr<EVP_CIPHER_CTX, EVP_CIPHER_CTX_Deleter>;
+
+// bool getRandom(size_t numBytes, vector<uint8_t>& output) {
+optional<vector<uint8_t>> getRandom(size_t numBytes) {
+    vector<uint8_t> output;
+    output.resize(numBytes);
+    if (RAND_bytes(output.data(), numBytes) != 1) {
+        LOG(ERROR) << "RAND_bytes: failed getting " << numBytes << " random";
+        return {};
+    }
+    return output;
+}
+
+optional<vector<uint8_t>> decryptAes128Gcm(const vector<uint8_t>& key,
+                                           const vector<uint8_t>& encryptedData,
+                                           const vector<uint8_t>& additionalAuthenticatedData) {
+    int cipherTextSize = int(encryptedData.size()) - kAesGcmIvSize - kAesGcmTagSize;
+    if (cipherTextSize < 0) {
+        LOG(ERROR) << "encryptedData too small";
+        return {};
+    }
+    unsigned char* nonce = (unsigned char*)encryptedData.data();
+    unsigned char* cipherText = nonce + kAesGcmIvSize;
+    unsigned char* tag = cipherText + cipherTextSize;
+
+    vector<uint8_t> plainText;
+    plainText.resize(cipherTextSize);
+
+    auto ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new());
+    if (ctx.get() == nullptr) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_new: failed";
+        return {};
+    }
+
+    if (EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, NULL, NULL) != 1) {
+        LOG(ERROR) << "EVP_DecryptInit_ex: failed";
+        return {};
+    }
+
+    if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, kAesGcmIvSize, NULL) != 1) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting nonce length";
+        return {};
+    }
+
+    if (EVP_DecryptInit_ex(ctx.get(), NULL, NULL, (unsigned char*)key.data(), nonce) != 1) {
+        LOG(ERROR) << "EVP_DecryptInit_ex: failed";
+        return {};
+    }
+
+    int numWritten;
+    if (additionalAuthenticatedData.size() > 0) {
+        if (EVP_DecryptUpdate(ctx.get(), NULL, &numWritten,
+                              (unsigned char*)additionalAuthenticatedData.data(),
+                              additionalAuthenticatedData.size()) != 1) {
+            LOG(ERROR) << "EVP_DecryptUpdate: failed for additionalAuthenticatedData";
+            return {};
+        }
+        if ((size_t)numWritten != additionalAuthenticatedData.size()) {
+            LOG(ERROR) << "EVP_DecryptUpdate: Unexpected outl=" << numWritten << " (expected "
+                       << additionalAuthenticatedData.size() << ") for additionalAuthenticatedData";
+            return {};
+        }
+    }
+
+    if (EVP_DecryptUpdate(ctx.get(), (unsigned char*)plainText.data(), &numWritten, cipherText,
+                          cipherTextSize) != 1) {
+        LOG(ERROR) << "EVP_DecryptUpdate: failed";
+        return {};
+    }
+    if (numWritten != cipherTextSize) {
+        LOG(ERROR) << "EVP_DecryptUpdate: Unexpected outl=" << numWritten << " (expected "
+                   << cipherTextSize << ")";
+        return {};
+    }
+
+    if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kAesGcmTagSize, tag)) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting expected tag";
+        return {};
+    }
+
+    int ret = EVP_DecryptFinal_ex(ctx.get(), (unsigned char*)plainText.data() + numWritten,
+                                  &numWritten);
+    if (ret != 1) {
+        LOG(ERROR) << "EVP_DecryptFinal_ex: failed";
+        return {};
+    }
+    if (numWritten != 0) {
+        LOG(ERROR) << "EVP_DecryptFinal_ex: Unexpected non-zero outl=" << numWritten;
+        return {};
+    }
+
+    return plainText;
+}
+
+optional<vector<uint8_t>> encryptAes128Gcm(const vector<uint8_t>& key, const vector<uint8_t>& nonce,
+                                           const vector<uint8_t>& data,
+                                           const vector<uint8_t>& additionalAuthenticatedData) {
+    if (key.size() != kAes128GcmKeySize) {
+        LOG(ERROR) << "key is not kAes128GcmKeySize bytes";
+        return {};
+    }
+    if (nonce.size() != kAesGcmIvSize) {
+        LOG(ERROR) << "nonce is not kAesGcmIvSize bytes";
+        return {};
+    }
+
+    // The result is the nonce (kAesGcmIvSize bytes), the ciphertext, and
+    // finally the tag (kAesGcmTagSize bytes).
+    vector<uint8_t> encryptedData;
+    encryptedData.resize(data.size() + kAesGcmIvSize + kAesGcmTagSize);
+    unsigned char* noncePtr = (unsigned char*)encryptedData.data();
+    unsigned char* cipherText = noncePtr + kAesGcmIvSize;
+    unsigned char* tag = cipherText + data.size();
+    memcpy(noncePtr, nonce.data(), kAesGcmIvSize);
+
+    auto ctx = EvpCipherCtxPtr(EVP_CIPHER_CTX_new());
+    if (ctx.get() == nullptr) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_new: failed";
+        return {};
+    }
+
+    if (EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_gcm(), NULL, NULL, NULL) != 1) {
+        LOG(ERROR) << "EVP_EncryptInit_ex: failed";
+        return {};
+    }
+
+    if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_IVLEN, kAesGcmIvSize, NULL) != 1) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed setting nonce length";
+        return {};
+    }
+
+    if (EVP_EncryptInit_ex(ctx.get(), NULL, NULL, (unsigned char*)key.data(),
+                           (unsigned char*)nonce.data()) != 1) {
+        LOG(ERROR) << "EVP_EncryptInit_ex: failed";
+        return {};
+    }
+
+    int numWritten;
+    if (additionalAuthenticatedData.size() > 0) {
+        if (EVP_EncryptUpdate(ctx.get(), NULL, &numWritten,
+                              (unsigned char*)additionalAuthenticatedData.data(),
+                              additionalAuthenticatedData.size()) != 1) {
+            LOG(ERROR) << "EVP_EncryptUpdate: failed for additionalAuthenticatedData";
+            return {};
+        }
+        if ((size_t)numWritten != additionalAuthenticatedData.size()) {
+            LOG(ERROR) << "EVP_EncryptUpdate: Unexpected outl=" << numWritten << " (expected "
+                       << additionalAuthenticatedData.size() << ") for additionalAuthenticatedData";
+            return {};
+        }
+    }
+
+    if (data.size() > 0) {
+        if (EVP_EncryptUpdate(ctx.get(), cipherText, &numWritten, (unsigned char*)data.data(),
+                              data.size()) != 1) {
+            LOG(ERROR) << "EVP_EncryptUpdate: failed";
+            return {};
+        }
+        if ((size_t)numWritten != data.size()) {
+            LOG(ERROR) << "EVP_EncryptUpdate: Unexpected outl=" << numWritten << " (expected "
+                       << data.size() << ")";
+            return {};
+        }
+    }
+
+    if (EVP_EncryptFinal_ex(ctx.get(), cipherText + numWritten, &numWritten) != 1) {
+        LOG(ERROR) << "EVP_EncryptFinal_ex: failed";
+        return {};
+    }
+    if (numWritten != 0) {
+        LOG(ERROR) << "EVP_EncryptFinal_ex: Unexpected non-zero outl=" << numWritten;
+        return {};
+    }
+
+    if (EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kAesGcmTagSize, tag) != 1) {
+        LOG(ERROR) << "EVP_CIPHER_CTX_ctrl: failed getting tag";
+        return {};
+    }
+
+    return encryptedData;
+}
+
+struct EC_KEY_Deleter {
+    void operator()(EC_KEY* key) const {
+        if (key != nullptr) {
+            EC_KEY_free(key);
+        }
+    }
+};
+using EC_KEY_Ptr = unique_ptr<EC_KEY, EC_KEY_Deleter>;
+
+struct EVP_PKEY_Deleter {
+    void operator()(EVP_PKEY* key) const {
+        if (key != nullptr) {
+            EVP_PKEY_free(key);
+        }
+    }
+};
+using EVP_PKEY_Ptr = unique_ptr<EVP_PKEY, EVP_PKEY_Deleter>;
+
+struct EVP_PKEY_CTX_Deleter {
+    void operator()(EVP_PKEY_CTX* ctx) const {
+        if (ctx != nullptr) {
+            EVP_PKEY_CTX_free(ctx);
+        }
+    }
+};
+using EVP_PKEY_CTX_Ptr = unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_Deleter>;
+
+struct EC_GROUP_Deleter {
+    void operator()(EC_GROUP* group) const {
+        if (group != nullptr) {
+            EC_GROUP_free(group);
+        }
+    }
+};
+using EC_GROUP_Ptr = unique_ptr<EC_GROUP, EC_GROUP_Deleter>;
+
+struct EC_POINT_Deleter {
+    void operator()(EC_POINT* point) const {
+        if (point != nullptr) {
+            EC_POINT_free(point);
+        }
+    }
+};
+
+using EC_POINT_Ptr = unique_ptr<EC_POINT, EC_POINT_Deleter>;
+
+struct ECDSA_SIG_Deleter {
+    void operator()(ECDSA_SIG* sig) const {
+        if (sig != nullptr) {
+            ECDSA_SIG_free(sig);
+        }
+    }
+};
+using ECDSA_SIG_Ptr = unique_ptr<ECDSA_SIG, ECDSA_SIG_Deleter>;
+
+struct X509_Deleter {
+    void operator()(X509* x509) const {
+        if (x509 != nullptr) {
+            X509_free(x509);
+        }
+    }
+};
+using X509_Ptr = unique_ptr<X509, X509_Deleter>;
+
+struct PKCS12_Deleter {
+    void operator()(PKCS12* pkcs12) const {
+        if (pkcs12 != nullptr) {
+            PKCS12_free(pkcs12);
+        }
+    }
+};
+using PKCS12_Ptr = unique_ptr<PKCS12, PKCS12_Deleter>;
+
+struct BIGNUM_Deleter {
+    void operator()(BIGNUM* bignum) const {
+        if (bignum != nullptr) {
+            BN_free(bignum);
+        }
+    }
+};
+using BIGNUM_Ptr = unique_ptr<BIGNUM, BIGNUM_Deleter>;
+
+struct ASN1_INTEGER_Deleter {
+    void operator()(ASN1_INTEGER* value) const {
+        if (value != nullptr) {
+            ASN1_INTEGER_free(value);
+        }
+    }
+};
+using ASN1_INTEGER_Ptr = unique_ptr<ASN1_INTEGER, ASN1_INTEGER_Deleter>;
+
+struct ASN1_TIME_Deleter {
+    void operator()(ASN1_TIME* value) const {
+        if (value != nullptr) {
+            ASN1_TIME_free(value);
+        }
+    }
+};
+using ASN1_TIME_Ptr = unique_ptr<ASN1_TIME, ASN1_TIME_Deleter>;
+
+struct X509_NAME_Deleter {
+    void operator()(X509_NAME* value) const {
+        if (value != nullptr) {
+            X509_NAME_free(value);
+        }
+    }
+};
+using X509_NAME_Ptr = unique_ptr<X509_NAME, X509_NAME_Deleter>;
+
+vector<uint8_t> certificateChainJoin(const vector<vector<uint8_t>>& certificateChain) {
+    vector<uint8_t> ret;
+    for (const vector<uint8_t>& certificate : certificateChain) {
+        ret.insert(ret.end(), certificate.begin(), certificate.end());
+    }
+    return ret;
+}
+
+optional<vector<vector<uint8_t>>> certificateChainSplit(const vector<uint8_t>& certificateChain) {
+    const unsigned char* pStart = (unsigned char*)certificateChain.data();
+    const unsigned char* p = pStart;
+    const unsigned char* pEnd = p + certificateChain.size();
+    vector<vector<uint8_t>> certificates;
+    while (p < pEnd) {
+        size_t begin = p - pStart;
+        auto x509 = X509_Ptr(d2i_X509(nullptr, &p, pEnd - p));
+        size_t next = p - pStart;
+        if (x509 == nullptr) {
+            LOG(ERROR) << "Error parsing X509 certificate";
+            return {};
+        }
+        vector<uint8_t> cert =
+                vector<uint8_t>(certificateChain.begin() + begin, certificateChain.begin() + next);
+        certificates.push_back(std::move(cert));
+    }
+    return certificates;
+}
+
+static bool parseX509Certificates(const vector<uint8_t>& certificateChain,
+                                  vector<X509_Ptr>& parsedCertificates) {
+    const unsigned char* p = (unsigned char*)certificateChain.data();
+    const unsigned char* pEnd = p + certificateChain.size();
+    parsedCertificates.resize(0);
+    while (p < pEnd) {
+        auto x509 = X509_Ptr(d2i_X509(nullptr, &p, pEnd - p));
+        if (x509 == nullptr) {
+            LOG(ERROR) << "Error parsing X509 certificate";
+            return false;
+        }
+        parsedCertificates.push_back(std::move(x509));
+    }
+    return true;
+}
+
+// TODO: Right now the only check we perform is to check that each certificate
+//       is signed by its successor. We should - but currently don't - also check
+//       things like valid dates etc.
+//
+//       It would be nice to use X509_verify_cert() instead of doing our own thing.
+//
+bool certificateChainValidate(const vector<uint8_t>& certificateChain) {
+    vector<X509_Ptr> certs;
+
+    if (!parseX509Certificates(certificateChain, certs)) {
+        LOG(ERROR) << "Error parsing X509 certificates";
+        return false;
+    }
+
+    if (certs.size() == 1) {
+        return true;
+    }
+
+    for (size_t n = 1; n < certs.size(); n++) {
+        const X509_Ptr& keyCert = certs[n - 1];
+        const X509_Ptr& signingCert = certs[n];
+        EVP_PKEY_Ptr signingPubkey(X509_get_pubkey(signingCert.get()));
+        if (X509_verify(keyCert.get(), signingPubkey.get()) != 1) {
+            LOG(ERROR) << "Error validating cert at index " << n - 1
+                       << " is signed by its successor";
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool checkEcDsaSignature(const vector<uint8_t>& digest, const vector<uint8_t>& signature,
+                         const vector<uint8_t>& publicKey) {
+    const unsigned char* p = (unsigned char*)signature.data();
+    auto sig = ECDSA_SIG_Ptr(d2i_ECDSA_SIG(nullptr, &p, signature.size()));
+    if (sig.get() == nullptr) {
+        LOG(ERROR) << "Error decoding DER encoded signature";
+        return false;
+    }
+
+    auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
+    if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
+        1) {
+        LOG(ERROR) << "Error decoding publicKey";
+        return false;
+    }
+    auto ecKey = EC_KEY_Ptr(EC_KEY_new());
+    auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (ecKey.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return false;
+    }
+    if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
+        LOG(ERROR) << "Error setting group";
+        return false;
+    }
+    if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
+        LOG(ERROR) << "Error setting point";
+        return false;
+    }
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
+        LOG(ERROR) << "Error setting key";
+        return false;
+    }
+
+    int rc = ECDSA_do_verify(digest.data(), digest.size(), sig.get(), ecKey.get());
+    if (rc != 1) {
+        LOG(ERROR) << "Error verifying signature (rc=" << rc << ")";
+        return false;
+    }
+
+    return true;
+}
+
+vector<uint8_t> sha256(const vector<uint8_t>& data) {
+    vector<uint8_t> ret;
+    ret.resize(SHA256_DIGEST_LENGTH);
+    SHA256_CTX ctx;
+    SHA256_Init(&ctx);
+    SHA256_Update(&ctx, data.data(), data.size());
+    SHA256_Final((unsigned char*)ret.data(), &ctx);
+    return ret;
+}
+
+optional<vector<uint8_t>> signEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data) {
+    auto bn = BIGNUM_Ptr(BN_bin2bn(key.data(), key.size(), nullptr));
+    if (bn.get() == nullptr) {
+        LOG(ERROR) << "Error creating BIGNUM";
+        return {};
+    }
+
+    auto ec_key = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+    if (EC_KEY_set_private_key(ec_key.get(), bn.get()) != 1) {
+        LOG(ERROR) << "Error setting private key from BIGNUM";
+        return {};
+    }
+
+    auto digest = sha256(data);
+    ECDSA_SIG* sig = ECDSA_do_sign(digest.data(), digest.size(), ec_key.get());
+    if (sig == nullptr) {
+        LOG(ERROR) << "Error signing digest";
+        return {};
+    }
+    size_t len = i2d_ECDSA_SIG(sig, nullptr);
+    vector<uint8_t> signature;
+    signature.resize(len);
+    unsigned char* p = (unsigned char*)signature.data();
+    i2d_ECDSA_SIG(sig, &p);
+    ECDSA_SIG_free(sig);
+    return signature;
+}
+
+optional<vector<uint8_t>> hmacSha256(const vector<uint8_t>& key, const vector<uint8_t>& data) {
+    HMAC_CTX ctx;
+    HMAC_CTX_init(&ctx);
+    if (HMAC_Init_ex(&ctx, key.data(), key.size(), EVP_sha256(), nullptr /* impl */) != 1) {
+        LOG(ERROR) << "Error initializing HMAC_CTX";
+        return {};
+    }
+    if (HMAC_Update(&ctx, data.data(), data.size()) != 1) {
+        LOG(ERROR) << "Error updating HMAC_CTX";
+        return {};
+    }
+    vector<uint8_t> hmac;
+    hmac.resize(32);
+    unsigned int size = 0;
+    if (HMAC_Final(&ctx, hmac.data(), &size) != 1) {
+        LOG(ERROR) << "Error finalizing HMAC_CTX";
+        return {};
+    }
+    if (size != 32) {
+        LOG(ERROR) << "Expected 32 bytes from HMAC_Final, got " << size;
+        return {};
+    }
+    return hmac;
+}
+
+optional<vector<uint8_t>> createEcKeyPair() {
+    auto ec_key = EC_KEY_Ptr(EC_KEY_new());
+    auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    if (ec_key.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return {};
+    }
+
+    if (EC_KEY_set_group(ec_key.get(), group.get()) != 1 ||
+        EC_KEY_generate_key(ec_key.get()) != 1 || EC_KEY_check_key(ec_key.get()) < 0) {
+        LOG(ERROR) << "Error generating key";
+        return {};
+    }
+
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get()) != 1) {
+        LOG(ERROR) << "Error getting private key";
+        return {};
+    }
+
+    int size = i2d_PrivateKey(pkey.get(), nullptr);
+    if (size == 0) {
+        LOG(ERROR) << "Error generating public key encoding";
+        return {};
+    }
+    vector<uint8_t> keyPair;
+    keyPair.resize(size);
+    unsigned char* p = keyPair.data();
+    i2d_PrivateKey(pkey.get(), &p);
+    return keyPair;
+}
+
+optional<vector<uint8_t>> ecKeyPairGetPublicKey(const vector<uint8_t>& keyPair) {
+    const unsigned char* p = (const unsigned char*)keyPair.data();
+    auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
+    if (pkey.get() == nullptr) {
+        LOG(ERROR) << "Error parsing keyPair";
+        return {};
+    }
+
+    auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (ecKey.get() == nullptr) {
+        LOG(ERROR) << "Failed getting EC key";
+        return {};
+    }
+
+    auto ecGroup = EC_KEY_get0_group(ecKey.get());
+    auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
+    int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
+                                  nullptr);
+    if (size == 0) {
+        LOG(ERROR) << "Error generating public key encoding";
+        return {};
+    }
+
+    vector<uint8_t> publicKey;
+    publicKey.resize(size);
+    EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
+                       publicKey.size(), nullptr);
+    return publicKey;
+}
+
+optional<vector<uint8_t>> ecKeyPairGetPrivateKey(const vector<uint8_t>& keyPair) {
+    const unsigned char* p = (const unsigned char*)keyPair.data();
+    auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
+    if (pkey.get() == nullptr) {
+        LOG(ERROR) << "Error parsing keyPair";
+        return {};
+    }
+
+    auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (ecKey.get() == nullptr) {
+        LOG(ERROR) << "Failed getting EC key";
+        return {};
+    }
+
+    const BIGNUM* bignum = EC_KEY_get0_private_key(ecKey.get());
+    if (bignum == nullptr) {
+        LOG(ERROR) << "Error getting bignum from private key";
+        return {};
+    }
+    vector<uint8_t> privateKey;
+    privateKey.resize(BN_num_bytes(bignum));
+    BN_bn2bin(bignum, privateKey.data());
+    return privateKey;
+}
+
+optional<vector<uint8_t>> ecKeyPairGetPkcs12(const vector<uint8_t>& keyPair, const string& name,
+                                             const string& serialDecimal, const string& issuer,
+                                             const string& subject, time_t validityNotBefore,
+                                             time_t validityNotAfter) {
+    const unsigned char* p = (const unsigned char*)keyPair.data();
+    auto pkey = EVP_PKEY_Ptr(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &p, keyPair.size()));
+    if (pkey.get() == nullptr) {
+        LOG(ERROR) << "Error parsing keyPair";
+        return {};
+    }
+
+    auto x509 = X509_Ptr(X509_new());
+    if (!x509.get()) {
+        LOG(ERROR) << "Error creating X509 certificate";
+        return {};
+    }
+
+    if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
+        LOG(ERROR) << "Error setting version to 3";
+        return {};
+    }
+
+    if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
+        LOG(ERROR) << "Error setting public key";
+        return {};
+    }
+
+    BIGNUM* bignumSerial = nullptr;
+    if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
+        LOG(ERROR) << "Error parsing serial";
+        return {};
+    }
+    auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
+    auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
+    if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
+        LOG(ERROR) << "Error setting serial";
+        return {};
+    }
+
+    auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
+    if (x509Issuer.get() == nullptr ||
+        X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
+                                   (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
+                                   0 /* set */) != 1 ||
+        X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
+        LOG(ERROR) << "Error setting issuer";
+        return {};
+    }
+
+    auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
+    if (x509Subject.get() == nullptr ||
+        X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
+                                   (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
+                                   0 /* set */) != 1 ||
+        X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
+        LOG(ERROR) << "Error setting subject";
+        return {};
+    }
+
+    auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
+    if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
+        LOG(ERROR) << "Error setting notBefore";
+        return {};
+    }
+
+    auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
+    if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
+        LOG(ERROR) << "Error setting notAfter";
+        return {};
+    }
+
+    if (X509_sign(x509.get(), pkey.get(), EVP_sha256()) == 0) {
+        LOG(ERROR) << "Error signing X509 certificate";
+        return {};
+    }
+
+    // Ideally we wouldn't encrypt it (we're only using this function for
+    // sending a key-pair over binder to the Android app) but BoringSSL does not
+    // support this: from pkcs8_x509.c in BoringSSL: "In OpenSSL, -1 here means
+    // to use no encryption, which we do not currently support."
+    //
+    // Passing nullptr as |pass|, though, means "no password". So we'll do that.
+    // Compare with the receiving side - CredstoreIdentityCredential.java - where
+    // an empty char[] is passed as the password.
+    //
+    auto pkcs12 = PKCS12_Ptr(PKCS12_create(nullptr, name.c_str(), pkey.get(), x509.get(),
+                                           nullptr,  // ca
+                                           0,        // nid_key
+                                           0,        // nid_cert
+                                           0,        // iter,
+                                           0,        // mac_iter,
+                                           0));      // keytype
+    if (pkcs12.get() == nullptr) {
+        char buf[128];
+        long errCode = ERR_get_error();
+        ERR_error_string_n(errCode, buf, sizeof buf);
+        LOG(ERROR) << "Error creating PKCS12, code " << errCode << ": " << buf;
+        return {};
+    }
+
+    unsigned char* buffer = nullptr;
+    int length = i2d_PKCS12(pkcs12.get(), &buffer);
+    if (length < 0) {
+        LOG(ERROR) << "Error encoding PKCS12";
+        return {};
+    }
+    vector<uint8_t> pkcs12Bytes;
+    pkcs12Bytes.resize(length);
+    memcpy(pkcs12Bytes.data(), buffer, length);
+    OPENSSL_free(buffer);
+
+    return pkcs12Bytes;
+}
+
+optional<vector<uint8_t>> ecPublicKeyGenerateCertificate(
+        const vector<uint8_t>& publicKey, const vector<uint8_t>& signingKey,
+        const string& serialDecimal, const string& issuer, const string& subject,
+        time_t validityNotBefore, time_t validityNotAfter) {
+    auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
+    if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
+        1) {
+        LOG(ERROR) << "Error decoding publicKey";
+        return {};
+    }
+    auto ecKey = EC_KEY_Ptr(EC_KEY_new());
+    auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (ecKey.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return {};
+    }
+    if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
+        LOG(ERROR) << "Error setting group";
+        return {};
+    }
+    if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
+        LOG(ERROR) << "Error setting point";
+        return {};
+    }
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
+        LOG(ERROR) << "Error setting key";
+        return {};
+    }
+
+    auto bn = BIGNUM_Ptr(BN_bin2bn(signingKey.data(), signingKey.size(), nullptr));
+    if (bn.get() == nullptr) {
+        LOG(ERROR) << "Error creating BIGNUM for private key";
+        return {};
+    }
+    auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+    if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
+        LOG(ERROR) << "Error setting private key from BIGNUM";
+        return {};
+    }
+    auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
+        LOG(ERROR) << "Error setting private key";
+        return {};
+    }
+
+    auto x509 = X509_Ptr(X509_new());
+    if (!x509.get()) {
+        LOG(ERROR) << "Error creating X509 certificate";
+        return {};
+    }
+
+    if (!X509_set_version(x509.get(), 2 /* version 3, but zero-based */)) {
+        LOG(ERROR) << "Error setting version to 3";
+        return {};
+    }
+
+    if (X509_set_pubkey(x509.get(), pkey.get()) != 1) {
+        LOG(ERROR) << "Error setting public key";
+        return {};
+    }
+
+    BIGNUM* bignumSerial = nullptr;
+    if (BN_dec2bn(&bignumSerial, serialDecimal.c_str()) == 0) {
+        LOG(ERROR) << "Error parsing serial";
+        return {};
+    }
+    auto bignumSerialPtr = BIGNUM_Ptr(bignumSerial);
+    auto asnSerial = ASN1_INTEGER_Ptr(BN_to_ASN1_INTEGER(bignumSerial, nullptr));
+    if (X509_set_serialNumber(x509.get(), asnSerial.get()) != 1) {
+        LOG(ERROR) << "Error setting serial";
+        return {};
+    }
+
+    auto x509Issuer = X509_NAME_Ptr(X509_NAME_new());
+    if (x509Issuer.get() == nullptr ||
+        X509_NAME_add_entry_by_txt(x509Issuer.get(), "CN", MBSTRING_ASC,
+                                   (const uint8_t*)issuer.c_str(), issuer.size(), -1 /* loc */,
+                                   0 /* set */) != 1 ||
+        X509_set_issuer_name(x509.get(), x509Issuer.get()) != 1) {
+        LOG(ERROR) << "Error setting issuer";
+        return {};
+    }
+
+    auto x509Subject = X509_NAME_Ptr(X509_NAME_new());
+    if (x509Subject.get() == nullptr ||
+        X509_NAME_add_entry_by_txt(x509Subject.get(), "CN", MBSTRING_ASC,
+                                   (const uint8_t*)subject.c_str(), subject.size(), -1 /* loc */,
+                                   0 /* set */) != 1 ||
+        X509_set_subject_name(x509.get(), x509Subject.get()) != 1) {
+        LOG(ERROR) << "Error setting subject";
+        return {};
+    }
+
+    auto asnNotBefore = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotBefore));
+    if (asnNotBefore.get() == nullptr || X509_set_notBefore(x509.get(), asnNotBefore.get()) != 1) {
+        LOG(ERROR) << "Error setting notBefore";
+        return {};
+    }
+
+    auto asnNotAfter = ASN1_TIME_Ptr(ASN1_TIME_set(nullptr, validityNotAfter));
+    if (asnNotAfter.get() == nullptr || X509_set_notAfter(x509.get(), asnNotAfter.get()) != 1) {
+        LOG(ERROR) << "Error setting notAfter";
+        return {};
+    }
+
+    if (X509_sign(x509.get(), privPkey.get(), EVP_sha256()) == 0) {
+        LOG(ERROR) << "Error signing X509 certificate";
+        return {};
+    }
+
+    unsigned char* buffer = nullptr;
+    int length = i2d_X509(x509.get(), &buffer);
+    if (length < 0) {
+        LOG(ERROR) << "Error DER encoding X509 certificate";
+        return {};
+    }
+
+    vector<uint8_t> certificate;
+    certificate.resize(length);
+    memcpy(certificate.data(), buffer, length);
+    OPENSSL_free(buffer);
+    return certificate;
+}
+
+optional<vector<uint8_t>> ecdh(const vector<uint8_t>& publicKey,
+                               const vector<uint8_t>& privateKey) {
+    auto group = EC_GROUP_Ptr(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+    auto point = EC_POINT_Ptr(EC_POINT_new(group.get()));
+    if (EC_POINT_oct2point(group.get(), point.get(), publicKey.data(), publicKey.size(), nullptr) !=
+        1) {
+        LOG(ERROR) << "Error decoding publicKey";
+        return {};
+    }
+    auto ecKey = EC_KEY_Ptr(EC_KEY_new());
+    auto pkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (ecKey.get() == nullptr || pkey.get() == nullptr) {
+        LOG(ERROR) << "Memory allocation failed";
+        return {};
+    }
+    if (EC_KEY_set_group(ecKey.get(), group.get()) != 1) {
+        LOG(ERROR) << "Error setting group";
+        return {};
+    }
+    if (EC_KEY_set_public_key(ecKey.get(), point.get()) != 1) {
+        LOG(ERROR) << "Error setting point";
+        return {};
+    }
+    if (EVP_PKEY_set1_EC_KEY(pkey.get(), ecKey.get()) != 1) {
+        LOG(ERROR) << "Error setting key";
+        return {};
+    }
+
+    auto bn = BIGNUM_Ptr(BN_bin2bn(privateKey.data(), privateKey.size(), nullptr));
+    if (bn.get() == nullptr) {
+        LOG(ERROR) << "Error creating BIGNUM for private key";
+        return {};
+    }
+    auto privEcKey = EC_KEY_Ptr(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+    if (EC_KEY_set_private_key(privEcKey.get(), bn.get()) != 1) {
+        LOG(ERROR) << "Error setting private key from BIGNUM";
+        return {};
+    }
+    auto privPkey = EVP_PKEY_Ptr(EVP_PKEY_new());
+    if (EVP_PKEY_set1_EC_KEY(privPkey.get(), privEcKey.get()) != 1) {
+        LOG(ERROR) << "Error setting private key";
+        return {};
+    }
+
+    auto ctx = EVP_PKEY_CTX_Ptr(EVP_PKEY_CTX_new(privPkey.get(), NULL));
+    if (ctx.get() == nullptr) {
+        LOG(ERROR) << "Error creating context";
+        return {};
+    }
+
+    if (EVP_PKEY_derive_init(ctx.get()) != 1) {
+        LOG(ERROR) << "Error initializing context";
+        return {};
+    }
+
+    if (EVP_PKEY_derive_set_peer(ctx.get(), pkey.get()) != 1) {
+        LOG(ERROR) << "Error setting peer";
+        return {};
+    }
+
+    /* Determine buffer length for shared secret */
+    size_t secretLen = 0;
+    if (EVP_PKEY_derive(ctx.get(), NULL, &secretLen) != 1) {
+        LOG(ERROR) << "Error determing length of shared secret";
+        return {};
+    }
+    vector<uint8_t> sharedSecret;
+    sharedSecret.resize(secretLen);
+
+    if (EVP_PKEY_derive(ctx.get(), sharedSecret.data(), &secretLen) != 1) {
+        LOG(ERROR) << "Error deriving shared secret";
+        return {};
+    }
+    return sharedSecret;
+}
+
+optional<vector<uint8_t>> hkdf(const vector<uint8_t>& sharedSecret, const vector<uint8_t>& salt,
+                               const vector<uint8_t>& info, size_t size) {
+    vector<uint8_t> derivedKey;
+    derivedKey.resize(size);
+    if (HKDF(derivedKey.data(), derivedKey.size(), EVP_sha256(), sharedSecret.data(),
+             sharedSecret.size(), salt.data(), salt.size(), info.data(), info.size()) != 1) {
+        LOG(ERROR) << "Error deriving key";
+        return {};
+    }
+    return derivedKey;
+}
+
+void removeLeadingZeroes(vector<uint8_t>& vec) {
+    while (vec.size() >= 1 && vec[0] == 0x00) {
+        vec.erase(vec.begin());
+    }
+}
+
+tuple<bool, vector<uint8_t>, vector<uint8_t>> ecPublicKeyGetXandY(
+        const vector<uint8_t>& publicKey) {
+    if (publicKey.size() != 65 || publicKey[0] != 0x04) {
+        LOG(ERROR) << "publicKey is not in the expected format";
+        return std::make_tuple(false, vector<uint8_t>(), vector<uint8_t>());
+    }
+    vector<uint8_t> x, y;
+    x.resize(32);
+    y.resize(32);
+    memcpy(x.data(), publicKey.data() + 1, 32);
+    memcpy(y.data(), publicKey.data() + 33, 32);
+
+    removeLeadingZeroes(x);
+    removeLeadingZeroes(y);
+
+    return std::make_tuple(true, x, y);
+}
+
+optional<vector<uint8_t>> certificateChainGetTopMostKey(const vector<uint8_t>& certificateChain) {
+    vector<X509_Ptr> certs;
+    if (!parseX509Certificates(certificateChain, certs)) {
+        return {};
+    }
+    if (certs.size() < 1) {
+        LOG(ERROR) << "No certificates in chain";
+        return {};
+    }
+
+    int algoId = OBJ_obj2nid(certs[0]->cert_info->key->algor->algorithm);
+    if (algoId != NID_X9_62_id_ecPublicKey) {
+        LOG(ERROR) << "Expected NID_X9_62_id_ecPublicKey, got " << OBJ_nid2ln(algoId);
+        return {};
+    }
+
+    auto pkey = EVP_PKEY_Ptr(X509_get_pubkey(certs[0].get()));
+    if (pkey.get() == nullptr) {
+        LOG(ERROR) << "No public key";
+        return {};
+    }
+
+    auto ecKey = EC_KEY_Ptr(EVP_PKEY_get1_EC_KEY(pkey.get()));
+    if (ecKey.get() == nullptr) {
+        LOG(ERROR) << "Failed getting EC key";
+        return {};
+    }
+
+    auto ecGroup = EC_KEY_get0_group(ecKey.get());
+    auto ecPoint = EC_KEY_get0_public_key(ecKey.get());
+    int size = EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0,
+                                  nullptr);
+    if (size == 0) {
+        LOG(ERROR) << "Error generating public key encoding";
+        return {};
+    }
+    vector<uint8_t> publicKey;
+    publicKey.resize(size);
+    EC_POINT_point2oct(ecGroup, ecPoint, POINT_CONVERSION_UNCOMPRESSED, publicKey.data(),
+                       publicKey.size(), nullptr);
+    return publicKey;
+}
+
+// ---------------------------------------------------------------------------
+// COSE Utility Functions
+// ---------------------------------------------------------------------------
+
+vector<uint8_t> coseBuildToBeSigned(const vector<uint8_t>& encodedProtectedHeaders,
+                                    const vector<uint8_t>& data,
+                                    const vector<uint8_t>& detachedContent) {
+    cppbor::Array sigStructure;
+    sigStructure.add("Signature1");
+    sigStructure.add(encodedProtectedHeaders);
+
+    // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
+    // so external_aad is the empty bstr
+    vector<uint8_t> emptyExternalAad;
+    sigStructure.add(emptyExternalAad);
+
+    // Next field is the payload, independently of how it's transported (RFC
+    // 8152 section 4.4). Since our API specifies only one of |data| and
+    // |detachedContent| can be non-empty, it's simply just the non-empty one.
+    if (data.size() > 0) {
+        sigStructure.add(data);
+    } else {
+        sigStructure.add(detachedContent);
+    }
+    return sigStructure.encode();
+}
+
+vector<uint8_t> coseEncodeHeaders(const cppbor::Map& protectedHeaders) {
+    if (protectedHeaders.size() == 0) {
+        cppbor::Bstr emptyBstr(vector<uint8_t>({}));
+        return emptyBstr.encode();
+    }
+    return protectedHeaders.encode();
+}
+
+// From https://tools.ietf.org/html/rfc8152
+const int COSE_LABEL_ALG = 1;
+const int COSE_LABEL_X5CHAIN = 33;  // temporary identifier
+
+// From "COSE Algorithms" registry
+const int COSE_ALG_ECDSA_256 = -7;
+const int COSE_ALG_HMAC_256_256 = 5;
+
+bool ecdsaSignatureCoseToDer(const vector<uint8_t>& ecdsaCoseSignature,
+                             vector<uint8_t>& ecdsaDerSignature) {
+    if (ecdsaCoseSignature.size() != 64) {
+        LOG(ERROR) << "COSE signature length is " << ecdsaCoseSignature.size() << ", expected 64";
+        return false;
+    }
+
+    auto rBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data(), 32, nullptr));
+    if (rBn.get() == nullptr) {
+        LOG(ERROR) << "Error creating BIGNUM for r";
+        return false;
+    }
+
+    auto sBn = BIGNUM_Ptr(BN_bin2bn(ecdsaCoseSignature.data() + 32, 32, nullptr));
+    if (sBn.get() == nullptr) {
+        LOG(ERROR) << "Error creating BIGNUM for s";
+        return false;
+    }
+
+    ECDSA_SIG sig;
+    sig.r = rBn.get();
+    sig.s = sBn.get();
+
+    size_t len = i2d_ECDSA_SIG(&sig, nullptr);
+    ecdsaDerSignature.resize(len);
+    unsigned char* p = (unsigned char*)ecdsaDerSignature.data();
+    i2d_ECDSA_SIG(&sig, &p);
+
+    return true;
+}
+
+bool ecdsaSignatureDerToCose(const vector<uint8_t>& ecdsaDerSignature,
+                             vector<uint8_t>& ecdsaCoseSignature) {
+    ECDSA_SIG* sig;
+    const unsigned char* p = ecdsaDerSignature.data();
+    sig = d2i_ECDSA_SIG(nullptr, &p, ecdsaDerSignature.size());
+    if (sig == nullptr) {
+        LOG(ERROR) << "Error decoding DER signature";
+        return false;
+    }
+
+    ecdsaCoseSignature.clear();
+    ecdsaCoseSignature.resize(64);
+    if (BN_bn2binpad(sig->r, ecdsaCoseSignature.data(), 32) != 32) {
+        LOG(ERROR) << "Error encoding r";
+        return false;
+    }
+    if (BN_bn2binpad(sig->s, ecdsaCoseSignature.data() + 32, 32) != 32) {
+        LOG(ERROR) << "Error encoding s";
+        return false;
+    }
+    return true;
+}
+
+optional<vector<uint8_t>> coseSignEcDsa(const vector<uint8_t>& key, const vector<uint8_t>& data,
+                                        const vector<uint8_t>& detachedContent,
+                                        const vector<uint8_t>& certificateChain) {
+    cppbor::Map unprotectedHeaders;
+    cppbor::Map protectedHeaders;
+
+    if (data.size() > 0 && detachedContent.size() > 0) {
+        LOG(ERROR) << "data and detachedContent cannot both be non-empty";
+        return {};
+    }
+
+    protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_ECDSA_256);
+
+    if (certificateChain.size() != 0) {
+        optional<vector<vector<uint8_t>>> certs = support::certificateChainSplit(certificateChain);
+        if (!certs) {
+            LOG(ERROR) << "Error splitting certificate chain";
+            return {};
+        }
+        if (certs.value().size() == 1) {
+            unprotectedHeaders.add(COSE_LABEL_X5CHAIN, certs.value()[0]);
+        } else {
+            cppbor::Array certArray;
+            for (const vector<uint8_t>& cert : certs.value()) {
+                certArray.add(cert);
+            }
+            unprotectedHeaders.add(COSE_LABEL_X5CHAIN, std::move(certArray));
+        }
+    }
+
+    vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
+    vector<uint8_t> toBeSigned =
+            coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
+
+    optional<vector<uint8_t>> derSignature = signEcDsa(key, toBeSigned);
+    if (!derSignature) {
+        LOG(ERROR) << "Error signing toBeSigned data";
+        return {};
+    }
+    vector<uint8_t> coseSignature;
+    if (!ecdsaSignatureDerToCose(derSignature.value(), coseSignature)) {
+        LOG(ERROR) << "Error converting ECDSA signature from DER to COSE format";
+        return {};
+    }
+
+    cppbor::Array coseSign1;
+    coseSign1.add(encodedProtectedHeaders);
+    coseSign1.add(std::move(unprotectedHeaders));
+    if (data.size() == 0) {
+        cppbor::Null nullValue;
+        coseSign1.add(std::move(nullValue));
+    } else {
+        coseSign1.add(data);
+    }
+    coseSign1.add(coseSignature);
+    vector<uint8_t> signatureCoseSign1;
+    signatureCoseSign1 = coseSign1.encode();
+    return signatureCoseSign1;
+}
+
+bool coseCheckEcDsaSignature(const vector<uint8_t>& signatureCoseSign1,
+                             const vector<uint8_t>& detachedContent,
+                             const vector<uint8_t>& publicKey) {
+    auto [item, _, message] = cppbor::parse(signatureCoseSign1);
+    if (item == nullptr) {
+        LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
+        return false;
+    }
+    const cppbor::Array* array = item->asArray();
+    if (array == nullptr) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array";
+        return false;
+    }
+    if (array->size() != 4) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
+        return false;
+    }
+
+    const cppbor::Bstr* encodedProtectedHeadersBstr = (*array)[0]->asBstr();
+    ;
+    if (encodedProtectedHeadersBstr == nullptr) {
+        LOG(ERROR) << "Value for encodedProtectedHeaders is not a bstr";
+        return false;
+    }
+    const vector<uint8_t> encodedProtectedHeaders = encodedProtectedHeadersBstr->value();
+
+    const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
+    if (unprotectedHeaders == nullptr) {
+        LOG(ERROR) << "Value for unprotectedHeaders is not a map";
+        return false;
+    }
+
+    vector<uint8_t> data;
+    const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
+    if (payloadAsSimple != nullptr) {
+        if (payloadAsSimple->asNull() == nullptr) {
+            LOG(ERROR) << "Value for payload is not null or a bstr";
+            return false;
+        }
+    } else {
+        const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
+        if (payloadAsBstr == nullptr) {
+            LOG(ERROR) << "Value for payload is not null or a bstr";
+            return false;
+        }
+        data = payloadAsBstr->value();  // TODO: avoid copy
+    }
+
+    if (data.size() > 0 && detachedContent.size() > 0) {
+        LOG(ERROR) << "data and detachedContent cannot both be non-empty";
+        return false;
+    }
+
+    const cppbor::Bstr* signatureBstr = (*array)[3]->asBstr();
+    if (signatureBstr == nullptr) {
+        LOG(ERROR) << "Value for signature is a bstr";
+        return false;
+    }
+    const vector<uint8_t>& coseSignature = signatureBstr->value();
+
+    vector<uint8_t> derSignature;
+    if (!ecdsaSignatureCoseToDer(coseSignature, derSignature)) {
+        LOG(ERROR) << "Error converting ECDSA signature from COSE to DER format";
+        return false;
+    }
+
+    vector<uint8_t> toBeSigned =
+            coseBuildToBeSigned(encodedProtectedHeaders, data, detachedContent);
+    if (!checkEcDsaSignature(support::sha256(toBeSigned), derSignature, publicKey)) {
+        LOG(ERROR) << "Signature check failed";
+        return false;
+    }
+    return true;
+}
+
+optional<vector<uint8_t>> coseSignGetPayload(const vector<uint8_t>& signatureCoseSign1) {
+    auto [item, _, message] = cppbor::parse(signatureCoseSign1);
+    if (item == nullptr) {
+        LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
+        return {};
+    }
+    const cppbor::Array* array = item->asArray();
+    if (array == nullptr) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array";
+        return {};
+    }
+    if (array->size() != 4) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
+        return {};
+    }
+
+    vector<uint8_t> data;
+    const cppbor::Simple* payloadAsSimple = (*array)[2]->asSimple();
+    if (payloadAsSimple != nullptr) {
+        if (payloadAsSimple->asNull() == nullptr) {
+            LOG(ERROR) << "Value for payload is not null or a bstr";
+            return {};
+        }
+        // payload is null, so |data| should be empty (as it is)
+    } else {
+        const cppbor::Bstr* payloadAsBstr = (*array)[2]->asBstr();
+        if (payloadAsBstr == nullptr) {
+            LOG(ERROR) << "Value for payload is not null or a bstr";
+            return {};
+        }
+        // Copy payload into |data|
+        data = payloadAsBstr->value();
+    }
+
+    return data;
+}
+
+optional<vector<uint8_t>> coseSignGetX5Chain(const vector<uint8_t>& signatureCoseSign1) {
+    auto [item, _, message] = cppbor::parse(signatureCoseSign1);
+    if (item == nullptr) {
+        LOG(ERROR) << "Passed-in COSE_Sign1 is not valid CBOR: " << message;
+        return {};
+    }
+    const cppbor::Array* array = item->asArray();
+    if (array == nullptr) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array";
+        return {};
+    }
+    if (array->size() != 4) {
+        LOG(ERROR) << "Value for COSE_Sign1 is not an array of size 4";
+        return {};
+    }
+
+    const cppbor::Map* unprotectedHeaders = (*array)[1]->asMap();
+    if (unprotectedHeaders == nullptr) {
+        LOG(ERROR) << "Value for unprotectedHeaders is not a map";
+        return {};
+    }
+
+    for (size_t n = 0; n < unprotectedHeaders->size(); n++) {
+        auto [keyItem, valueItem] = (*unprotectedHeaders)[n];
+        const cppbor::Int* number = keyItem->asInt();
+        if (number == nullptr) {
+            LOG(ERROR) << "Key item in top-level map is not a number";
+            return {};
+        }
+        int label = number->value();
+        if (label == COSE_LABEL_X5CHAIN) {
+            const cppbor::Bstr* bstr = valueItem->asBstr();
+            if (bstr != nullptr) {
+                return bstr->value();
+            }
+            const cppbor::Array* array = valueItem->asArray();
+            if (array != nullptr) {
+                vector<uint8_t> certs;
+                for (size_t m = 0; m < array->size(); m++) {
+                    const cppbor::Bstr* bstr = ((*array)[m])->asBstr();
+                    if (bstr == nullptr) {
+                        LOG(ERROR) << "Item in x5chain array is not a bstr";
+                        return {};
+                    }
+                    const vector<uint8_t>& certValue = bstr->value();
+                    certs.insert(certs.end(), certValue.begin(), certValue.end());
+                }
+                return certs;
+            }
+            LOG(ERROR) << "Value for x5chain label is not a bstr or array";
+            return {};
+        }
+    }
+    LOG(ERROR) << "Did not find x5chain label in unprotected headers";
+    return {};
+}
+
+vector<uint8_t> coseBuildToBeMACed(const vector<uint8_t>& encodedProtectedHeaders,
+                                   const vector<uint8_t>& data,
+                                   const vector<uint8_t>& detachedContent) {
+    cppbor::Array macStructure;
+    macStructure.add("MAC0");
+    macStructure.add(encodedProtectedHeaders);
+
+    // We currently don't support Externally Supplied Data (RFC 8152 section 4.3)
+    // so external_aad is the empty bstr
+    vector<uint8_t> emptyExternalAad;
+    macStructure.add(emptyExternalAad);
+
+    // Next field is the payload, independently of how it's transported (RFC
+    // 8152 section 4.4). Since our API specifies only one of |data| and
+    // |detachedContent| can be non-empty, it's simply just the non-empty one.
+    if (data.size() > 0) {
+        macStructure.add(data);
+    } else {
+        macStructure.add(detachedContent);
+    }
+
+    return macStructure.encode();
+}
+
+optional<vector<uint8_t>> coseMac0(const vector<uint8_t>& key, const vector<uint8_t>& data,
+                                   const vector<uint8_t>& detachedContent) {
+    cppbor::Map unprotectedHeaders;
+    cppbor::Map protectedHeaders;
+
+    if (data.size() > 0 && detachedContent.size() > 0) {
+        LOG(ERROR) << "data and detachedContent cannot both be non-empty";
+        return {};
+    }
+
+    protectedHeaders.add(COSE_LABEL_ALG, COSE_ALG_HMAC_256_256);
+
+    vector<uint8_t> encodedProtectedHeaders = coseEncodeHeaders(protectedHeaders);
+    vector<uint8_t> toBeMACed = coseBuildToBeMACed(encodedProtectedHeaders, data, detachedContent);
+
+    optional<vector<uint8_t>> mac = hmacSha256(key, toBeMACed);
+    if (!mac) {
+        LOG(ERROR) << "Error MACing toBeMACed data";
+        return {};
+    }
+
+    cppbor::Array array;
+    array.add(encodedProtectedHeaders);
+    array.add(std::move(unprotectedHeaders));
+    if (data.size() == 0) {
+        cppbor::Null nullValue;
+        array.add(std::move(nullValue));
+    } else {
+        array.add(data);
+    }
+    array.add(mac.value());
+    return array.encode();
+}
+
+// ---------------------------------------------------------------------------
+// Platform abstraction.
+// ---------------------------------------------------------------------------
+
+// This is not a very random HBK but that's OK because this is the SW
+// implementation where it can't be kept secret.
+vector<uint8_t> hardwareBoundKey = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
+
+const vector<uint8_t>& getHardwareBoundKey() {
+    return hardwareBoundKey;
+}
+
+// ---------------------------------------------------------------------------
+// Utility functions specific to IdentityCredential.
+// ---------------------------------------------------------------------------
+
+Result okResult{ResultCode::OK, ""};
+
+const Result& resultOK() {
+    return okResult;
+}
+
+Result result(ResultCode code, const char* format, ...) {
+    va_list ap;
+    va_start(ap, format);
+    string str;
+    android::base::StringAppendV(&str, format, ap);
+    va_end(ap);
+    return Result{code, str};
+}
+
+vector<vector<uint8_t>> chunkVector(const vector<uint8_t>& content, size_t maxChunkSize) {
+    vector<vector<uint8_t>> ret;
+
+    size_t contentSize = content.size();
+    if (contentSize <= maxChunkSize) {
+        ret.push_back(content);
+        return ret;
+    }
+
+    size_t numChunks = (contentSize + maxChunkSize - 1) / maxChunkSize;
+
+    size_t pos = 0;
+    for (size_t n = 0; n < numChunks; n++) {
+        size_t size = contentSize - pos;
+        if (size > maxChunkSize) {
+            size = maxChunkSize;
+        }
+        auto begin = content.begin() + pos;
+        auto end = content.begin() + pos + size;
+        ret.emplace_back(vector<uint8_t>(begin, end));
+        pos += maxChunkSize;
+    }
+
+    return ret;
+}
+
+vector<uint8_t> secureAccessControlProfileEncodeCbor(const SecureAccessControlProfile& profile) {
+    cppbor::Map map;
+    map.add("id", profile.id);
+
+    if (profile.readerCertificate.size() > 0) {
+        map.add("readerCertificate", cppbor::Bstr(profile.readerCertificate));
+    }
+
+    if (profile.userAuthenticationRequired) {
+        map.add("userAuthenticationRequired", profile.userAuthenticationRequired);
+        map.add("timeoutMillis", profile.timeoutMillis);
+        map.add("secureUserId", profile.secureUserId);
+    }
+
+    return map.encode();
+}
+
+optional<vector<uint8_t>> secureAccessControlProfileCalcMac(
+        const SecureAccessControlProfile& profile, const vector<uint8_t>& storageKey) {
+    vector<uint8_t> cborData = secureAccessControlProfileEncodeCbor(profile);
+
+    optional<vector<uint8_t>> nonce = getRandom(12);
+    if (!nonce) {
+        return {};
+    }
+    optional<vector<uint8_t>> macO = encryptAes128Gcm(storageKey, nonce.value(), {}, cborData);
+    if (!macO) {
+        return {};
+    }
+    return macO.value();
+}
+
+bool secureAccessControlProfileCheckMac(const SecureAccessControlProfile& profile,
+                                        const vector<uint8_t>& storageKey) {
+    vector<uint8_t> cborData = secureAccessControlProfileEncodeCbor(profile);
+
+    if (profile.mac.size() < kAesGcmIvSize) {
+        return false;
+    }
+    vector<uint8_t> nonce =
+            vector<uint8_t>(profile.mac.begin(), profile.mac.begin() + kAesGcmIvSize);
+    optional<vector<uint8_t>> mac = encryptAes128Gcm(storageKey, nonce, {}, cborData);
+    if (!mac) {
+        return false;
+    }
+    if (mac.value() != vector<uint8_t>(profile.mac)) {
+        return false;
+    }
+    return true;
+}
+
+vector<uint8_t> testHardwareBoundKey = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+const vector<uint8_t>& getTestHardwareBoundKey() {
+    return testHardwareBoundKey;
+}
+
+vector<uint8_t> entryCreateAdditionalData(const string& nameSpace, const string& name,
+                                          const vector<uint16_t> accessControlProfileIds) {
+    cppbor::Map map;
+    map.add("Namespace", nameSpace);
+    map.add("Name", name);
+
+    cppbor::Array acpIds;
+    for (auto id : accessControlProfileIds) {
+        acpIds.add(id);
+    }
+    map.add("AccessControlProfileIds", std::move(acpIds));
+    return map.encode();
+}
+
+}  // namespace support
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
diff --git a/identity/support/src/cppbor.cpp b/identity/support/src/cppbor.cpp
new file mode 100644
index 0000000..d289985
--- /dev/null
+++ b/identity/support/src/cppbor.cpp
@@ -0,0 +1,225 @@
+/*
+ * 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.
+ */
+
+#include "cppbor.h"
+#include "cppbor_parse.h"
+
+#define LOG_TAG "CppBor"
+#include <android-base/logging.h>
+
+namespace cppbor {
+
+namespace {
+
+template <typename T, typename Iterator, typename = std::enable_if<std::is_unsigned<T>::value>>
+Iterator writeBigEndian(T value, Iterator pos) {
+    for (unsigned i = 0; i < sizeof(value); ++i) {
+        *pos++ = static_cast<uint8_t>(value >> (8 * (sizeof(value) - 1)));
+        value = static_cast<T>(value << 8);
+    }
+    return pos;
+}
+
+template <typename T, typename = std::enable_if<std::is_unsigned<T>::value>>
+void writeBigEndian(T value, std::function<void(uint8_t)>& cb) {
+    for (unsigned i = 0; i < sizeof(value); ++i) {
+        cb(static_cast<uint8_t>(value >> (8 * (sizeof(value) - 1))));
+        value = static_cast<T>(value << 8);
+    }
+}
+
+}  // namespace
+
+size_t headerSize(uint64_t addlInfo) {
+    if (addlInfo < ONE_BYTE_LENGTH) return 1;
+    if (addlInfo <= std::numeric_limits<uint8_t>::max()) return 2;
+    if (addlInfo <= std::numeric_limits<uint16_t>::max()) return 3;
+    if (addlInfo <= std::numeric_limits<uint32_t>::max()) return 5;
+    return 9;
+}
+
+uint8_t* encodeHeader(MajorType type, uint64_t addlInfo, uint8_t* pos, const uint8_t* end) {
+    size_t sz = headerSize(addlInfo);
+    if (end - pos < static_cast<ssize_t>(sz)) return nullptr;
+    switch (sz) {
+        case 1:
+            *pos++ = type | static_cast<uint8_t>(addlInfo);
+            return pos;
+        case 2:
+            *pos++ = type | ONE_BYTE_LENGTH;
+            *pos++ = static_cast<uint8_t>(addlInfo);
+            return pos;
+        case 3:
+            *pos++ = type | TWO_BYTE_LENGTH;
+            return writeBigEndian(static_cast<uint16_t>(addlInfo), pos);
+        case 5:
+            *pos++ = type | FOUR_BYTE_LENGTH;
+            return writeBigEndian(static_cast<uint32_t>(addlInfo), pos);
+        case 9:
+            *pos++ = type | EIGHT_BYTE_LENGTH;
+            return writeBigEndian(addlInfo, pos);
+        default:
+            CHECK(false);  // Impossible to get here.
+            return nullptr;
+    }
+}
+
+void encodeHeader(MajorType type, uint64_t addlInfo, EncodeCallback encodeCallback) {
+    size_t sz = headerSize(addlInfo);
+    switch (sz) {
+        case 1:
+            encodeCallback(type | static_cast<uint8_t>(addlInfo));
+            break;
+        case 2:
+            encodeCallback(type | ONE_BYTE_LENGTH);
+            encodeCallback(static_cast<uint8_t>(addlInfo));
+            break;
+        case 3:
+            encodeCallback(type | TWO_BYTE_LENGTH);
+            writeBigEndian(static_cast<uint16_t>(addlInfo), encodeCallback);
+            break;
+        case 5:
+            encodeCallback(type | FOUR_BYTE_LENGTH);
+            writeBigEndian(static_cast<uint32_t>(addlInfo), encodeCallback);
+            break;
+        case 9:
+            encodeCallback(type | EIGHT_BYTE_LENGTH);
+            writeBigEndian(addlInfo, encodeCallback);
+            break;
+        default:
+            CHECK(false);  // Impossible to get here.
+    }
+}
+
+bool Item::operator==(const Item& other) const& {
+    if (type() != other.type()) return false;
+    switch (type()) {
+        case UINT:
+            return *asUint() == *(other.asUint());
+        case NINT:
+            return *asNint() == *(other.asNint());
+        case BSTR:
+            return *asBstr() == *(other.asBstr());
+        case TSTR:
+            return *asTstr() == *(other.asTstr());
+        case ARRAY:
+            return *asArray() == *(other.asArray());
+        case MAP:
+            return *asMap() == *(other.asMap());
+        case SIMPLE:
+            return *asSimple() == *(other.asSimple());
+        case SEMANTIC:
+            return *asSemantic() == *(other.asSemantic());
+        default:
+            CHECK(false);  // Impossible to get here.
+            return false;
+    }
+}
+
+Nint::Nint(int64_t v) : mValue(v) {
+    CHECK(v < 0) << "Only negative values allowed";
+}
+
+bool Simple::operator==(const Simple& other) const& {
+    if (simpleType() != other.simpleType()) return false;
+
+    switch (simpleType()) {
+        case BOOLEAN:
+            return *asBool() == *(other.asBool());
+        case NULL_T:
+            return true;
+        default:
+            CHECK(false);  // Impossible to get here.
+            return false;
+    }
+}
+
+uint8_t* Bstr::encode(uint8_t* pos, const uint8_t* end) const {
+    pos = encodeHeader(mValue.size(), pos, end);
+    if (!pos || end - pos < static_cast<ptrdiff_t>(mValue.size())) return nullptr;
+    return std::copy(mValue.begin(), mValue.end(), pos);
+}
+
+void Bstr::encodeValue(EncodeCallback encodeCallback) const {
+    for (auto c : mValue) {
+        encodeCallback(c);
+    }
+}
+
+uint8_t* Tstr::encode(uint8_t* pos, const uint8_t* end) const {
+    pos = encodeHeader(mValue.size(), pos, end);
+    if (!pos || end - pos < static_cast<ptrdiff_t>(mValue.size())) return nullptr;
+    return std::copy(mValue.begin(), mValue.end(), pos);
+}
+
+void Tstr::encodeValue(EncodeCallback encodeCallback) const {
+    for (auto c : mValue) {
+        encodeCallback(static_cast<uint8_t>(c));
+    }
+}
+
+bool CompoundItem::operator==(const CompoundItem& other) const& {
+    return type() == other.type()             //
+           && addlInfo() == other.addlInfo()  //
+           // Can't use vector::operator== because the contents are pointers.  std::equal lets us
+           // provide a predicate that does the dereferencing.
+           && std::equal(mEntries.begin(), mEntries.end(), other.mEntries.begin(),
+                         [](auto& a, auto& b) -> bool { return *a == *b; });
+}
+
+uint8_t* CompoundItem::encode(uint8_t* pos, const uint8_t* end) const {
+    pos = encodeHeader(addlInfo(), pos, end);
+    if (!pos) return nullptr;
+    for (auto& entry : mEntries) {
+        pos = entry->encode(pos, end);
+        if (!pos) return nullptr;
+    }
+    return pos;
+}
+
+void CompoundItem::encode(EncodeCallback encodeCallback) const {
+    encodeHeader(addlInfo(), encodeCallback);
+    for (auto& entry : mEntries) {
+        entry->encode(encodeCallback);
+    }
+}
+
+void Map::assertInvariant() const {
+    CHECK(mEntries.size() % 2 == 0);
+}
+
+std::unique_ptr<Item> Map::clone() const {
+    assertInvariant();
+    auto res = std::make_unique<Map>();
+    for (size_t i = 0; i < mEntries.size(); i += 2) {
+        res->add(mEntries[i]->clone(), mEntries[i + 1]->clone());
+    }
+    return res;
+}
+
+std::unique_ptr<Item> Array::clone() const {
+    auto res = std::make_unique<Array>();
+    for (size_t i = 0; i < mEntries.size(); i++) {
+        res->add(mEntries[i]->clone());
+    }
+    return res;
+}
+
+void Semantic::assertInvariant() const {
+    CHECK(mEntries.size() == 1);
+}
+
+}  // namespace cppbor
diff --git a/identity/support/src/cppbor_parse.cpp b/identity/support/src/cppbor_parse.cpp
new file mode 100644
index 0000000..c9ebb8a
--- /dev/null
+++ b/identity/support/src/cppbor_parse.cpp
@@ -0,0 +1,351 @@
+/*
+ * 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.
+ */
+
+#include "cppbor_parse.h"
+
+#include <sstream>
+#include <stack>
+
+#define LOG_TAG "CppBor"
+#include <android-base/logging.h>
+
+namespace cppbor {
+
+namespace {
+
+std::string insufficientLengthString(size_t bytesNeeded, size_t bytesAvail,
+                                     const std::string& type) {
+    std::stringstream errStream;
+    errStream << "Need " << bytesNeeded << " byte(s) for " << type << ", have " << bytesAvail
+              << ".";
+    return errStream.str();
+}
+
+template <typename T, typename = std::enable_if_t<std::is_unsigned_v<T>>>
+std::tuple<bool, uint64_t, const uint8_t*> parseLength(const uint8_t* pos, const uint8_t* end,
+                                                       ParseClient* parseClient) {
+    if (pos + sizeof(T) > end) {
+        parseClient->error(pos - 1, insufficientLengthString(sizeof(T), end - pos, "length field"));
+        return {false, 0, pos};
+    }
+
+    const uint8_t* intEnd = pos + sizeof(T);
+    T result = 0;
+    do {
+        result = static_cast<T>((result << 8) | *pos++);
+    } while (pos < intEnd);
+    return {true, result, pos};
+}
+
+std::tuple<const uint8_t*, ParseClient*> parseRecursively(const uint8_t* begin, const uint8_t* end,
+                                                          ParseClient* parseClient);
+
+std::tuple<const uint8_t*, ParseClient*> handleUint(uint64_t value, const uint8_t* hdrBegin,
+                                                    const uint8_t* hdrEnd,
+                                                    ParseClient* parseClient) {
+    std::unique_ptr<Item> item = std::make_unique<Uint>(value);
+    return {hdrEnd,
+            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
+}
+
+std::tuple<const uint8_t*, ParseClient*> handleNint(uint64_t value, const uint8_t* hdrBegin,
+                                                    const uint8_t* hdrEnd,
+                                                    ParseClient* parseClient) {
+    if (value > std::numeric_limits<int64_t>::max()) {
+        parseClient->error(hdrBegin, "NINT values that don't fit in int64_t are not supported.");
+        return {hdrBegin, nullptr /* end parsing */};
+    }
+    std::unique_ptr<Item> item = std::make_unique<Nint>(-1 - static_cast<uint64_t>(value));
+    return {hdrEnd,
+            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
+}
+
+std::tuple<const uint8_t*, ParseClient*> handleBool(uint64_t value, const uint8_t* hdrBegin,
+                                                    const uint8_t* hdrEnd,
+                                                    ParseClient* parseClient) {
+    std::unique_ptr<Item> item = std::make_unique<Bool>(value == TRUE);
+    return {hdrEnd,
+            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
+}
+
+std::tuple<const uint8_t*, ParseClient*> handleNull(const uint8_t* hdrBegin, const uint8_t* hdrEnd,
+                                                    ParseClient* parseClient) {
+    std::unique_ptr<Item> item = std::make_unique<Null>();
+    return {hdrEnd,
+            parseClient->item(item, hdrBegin, hdrEnd /* valueBegin */, hdrEnd /* itemEnd */)};
+}
+
+template <typename T>
+std::tuple<const uint8_t*, ParseClient*> handleString(uint64_t length, const uint8_t* hdrBegin,
+                                                      const uint8_t* valueBegin, const uint8_t* end,
+                                                      const std::string& errLabel,
+                                                      ParseClient* parseClient) {
+    if (end - valueBegin < static_cast<ssize_t>(length)) {
+        parseClient->error(hdrBegin, insufficientLengthString(length, end - valueBegin, errLabel));
+        return {hdrBegin, nullptr /* end parsing */};
+    }
+
+    std::unique_ptr<Item> item = std::make_unique<T>(valueBegin, valueBegin + length);
+    return {valueBegin + length,
+            parseClient->item(item, hdrBegin, valueBegin, valueBegin + length)};
+}
+
+class IncompleteItem {
+  public:
+    virtual ~IncompleteItem() {}
+    virtual void add(std::unique_ptr<Item> item) = 0;
+};
+
+class IncompleteArray : public Array, public IncompleteItem {
+  public:
+    IncompleteArray(size_t size) : mSize(size) {}
+
+    // We return the "complete" size, rather than the actual size.
+    size_t size() const override { return mSize; }
+
+    void add(std::unique_ptr<Item> item) override {
+        mEntries.reserve(mSize);
+        mEntries.push_back(std::move(item));
+    }
+
+  private:
+    size_t mSize;
+};
+
+class IncompleteMap : public Map, public IncompleteItem {
+  public:
+    IncompleteMap(size_t size) : mSize(size) {}
+
+    // We return the "complete" size, rather than the actual size.
+    size_t size() const override { return mSize; }
+
+    void add(std::unique_ptr<Item> item) override {
+        mEntries.reserve(mSize * 2);
+        mEntries.push_back(std::move(item));
+    }
+
+  private:
+    size_t mSize;
+};
+
+class IncompleteSemantic : public Semantic, public IncompleteItem {
+  public:
+    IncompleteSemantic(uint64_t value) : Semantic(value) {}
+
+    // We return the "complete" size, rather than the actual size.
+    size_t size() const override { return 1; }
+
+    void add(std::unique_ptr<Item> item) override {
+        mEntries.reserve(1);
+        mEntries.push_back(std::move(item));
+    }
+};
+
+std::tuple<const uint8_t*, ParseClient*> handleEntries(size_t entryCount, const uint8_t* hdrBegin,
+                                                       const uint8_t* pos, const uint8_t* end,
+                                                       const std::string& typeName,
+                                                       ParseClient* parseClient) {
+    while (entryCount > 0) {
+        --entryCount;
+        if (pos == end) {
+            parseClient->error(hdrBegin, "Not enough entries for " + typeName + ".");
+            return {hdrBegin, nullptr /* end parsing */};
+        }
+        std::tie(pos, parseClient) = parseRecursively(pos, end, parseClient);
+        if (!parseClient) return {hdrBegin, nullptr};
+    }
+    return {pos, parseClient};
+}
+
+std::tuple<const uint8_t*, ParseClient*> handleCompound(
+        std::unique_ptr<Item> item, uint64_t entryCount, const uint8_t* hdrBegin,
+        const uint8_t* valueBegin, const uint8_t* end, const std::string& typeName,
+        ParseClient* parseClient) {
+    parseClient =
+            parseClient->item(item, hdrBegin, valueBegin, valueBegin /* don't know the end yet */);
+    if (!parseClient) return {hdrBegin, nullptr};
+
+    const uint8_t* pos;
+    std::tie(pos, parseClient) =
+            handleEntries(entryCount, hdrBegin, valueBegin, end, typeName, parseClient);
+    if (!parseClient) return {hdrBegin, nullptr};
+
+    return {pos, parseClient->itemEnd(item, hdrBegin, valueBegin, pos)};
+}
+
+std::tuple<const uint8_t*, ParseClient*> parseRecursively(const uint8_t* begin, const uint8_t* end,
+                                                          ParseClient* parseClient) {
+    const uint8_t* pos = begin;
+
+    MajorType type = static_cast<MajorType>(*pos & 0xE0);
+    uint8_t tagInt = *pos & 0x1F;
+    ++pos;
+
+    bool success = true;
+    uint64_t addlData;
+    if (tagInt < ONE_BYTE_LENGTH || tagInt > EIGHT_BYTE_LENGTH) {
+        addlData = tagInt;
+    } else {
+        switch (tagInt) {
+            case ONE_BYTE_LENGTH:
+                std::tie(success, addlData, pos) = parseLength<uint8_t>(pos, end, parseClient);
+                break;
+
+            case TWO_BYTE_LENGTH:
+                std::tie(success, addlData, pos) = parseLength<uint16_t>(pos, end, parseClient);
+                break;
+
+            case FOUR_BYTE_LENGTH:
+                std::tie(success, addlData, pos) = parseLength<uint32_t>(pos, end, parseClient);
+                break;
+
+            case EIGHT_BYTE_LENGTH:
+                std::tie(success, addlData, pos) = parseLength<uint64_t>(pos, end, parseClient);
+                break;
+
+            default:
+                CHECK(false);  //  It's impossible to get here
+                break;
+        }
+    }
+
+    if (!success) return {begin, nullptr};
+
+    switch (type) {
+        case UINT:
+            return handleUint(addlData, begin, pos, parseClient);
+
+        case NINT:
+            return handleNint(addlData, begin, pos, parseClient);
+
+        case BSTR:
+            return handleString<Bstr>(addlData, begin, pos, end, "byte string", parseClient);
+
+        case TSTR:
+            return handleString<Tstr>(addlData, begin, pos, end, "text string", parseClient);
+
+        case ARRAY:
+            return handleCompound(std::make_unique<IncompleteArray>(addlData), addlData, begin, pos,
+                                  end, "array", parseClient);
+
+        case MAP:
+            return handleCompound(std::make_unique<IncompleteMap>(addlData), addlData * 2, begin,
+                                  pos, end, "map", parseClient);
+
+        case SEMANTIC:
+            return handleCompound(std::make_unique<IncompleteSemantic>(addlData), 1, begin, pos,
+                                  end, "semantic", parseClient);
+
+        case SIMPLE:
+            switch (addlData) {
+                case TRUE:
+                case FALSE:
+                    return handleBool(addlData, begin, pos, parseClient);
+                case NULL_V:
+                    return handleNull(begin, pos, parseClient);
+            }
+    }
+    CHECK(false);  // Impossible to get here.
+    return {};
+}
+
+class FullParseClient : public ParseClient {
+  public:
+    virtual ParseClient* item(std::unique_ptr<Item>& item, const uint8_t*, const uint8_t*,
+                              const uint8_t* end) override {
+        if (mParentStack.empty() && !item->isCompound()) {
+            // This is the first and only item.
+            mTheItem = std::move(item);
+            mPosition = end;
+            return nullptr;  //  We're done.
+        }
+
+        if (item->isCompound()) {
+            // Starting a new compound data item, i.e. a new parent.  Save it on the parent stack.
+            // It's safe to save a raw pointer because the unique_ptr is guaranteed to stay in
+            // existence until the corresponding itemEnd() call.
+            assert(dynamic_cast<CompoundItem*>(item.get()));
+            mParentStack.push(static_cast<CompoundItem*>(item.get()));
+            return this;
+        } else {
+            appendToLastParent(std::move(item));
+            return this;
+        }
+    }
+
+    virtual ParseClient* itemEnd(std::unique_ptr<Item>& item, const uint8_t*, const uint8_t*,
+                                 const uint8_t* end) override {
+        CHECK(item->isCompound() && item.get() == mParentStack.top());
+        mParentStack.pop();
+
+        if (mParentStack.empty()) {
+            mTheItem = std::move(item);
+            mPosition = end;
+            return nullptr;  // We're done
+        } else {
+            appendToLastParent(std::move(item));
+            return this;
+        }
+    }
+
+    virtual void error(const uint8_t* position, const std::string& errorMessage) override {
+        mPosition = position;
+        mErrorMessage = errorMessage;
+    }
+
+    std::tuple<std::unique_ptr<Item> /* result */, const uint8_t* /* newPos */,
+               std::string /* errMsg */>
+    parseResult() {
+        std::unique_ptr<Item> p = std::move(mTheItem);
+        return {std::move(p), mPosition, std::move(mErrorMessage)};
+    }
+
+  private:
+    void appendToLastParent(std::unique_ptr<Item> item) {
+        auto parent = mParentStack.top();
+        assert(dynamic_cast<IncompleteItem*>(parent));
+        if (parent->type() == ARRAY) {
+            static_cast<IncompleteArray*>(parent)->add(std::move(item));
+        } else if (parent->type() == MAP) {
+            static_cast<IncompleteMap*>(parent)->add(std::move(item));
+        } else if (parent->type() == SEMANTIC) {
+            static_cast<IncompleteSemantic*>(parent)->add(std::move(item));
+        } else {
+            CHECK(false);  // Impossible to get here.
+        }
+    }
+
+    std::unique_ptr<Item> mTheItem;
+    std::stack<CompoundItem*> mParentStack;
+    const uint8_t* mPosition = nullptr;
+    std::string mErrorMessage;
+};
+
+}  // anonymous namespace
+
+void parse(const uint8_t* begin, const uint8_t* end, ParseClient* parseClient) {
+    parseRecursively(begin, end, parseClient);
+}
+
+std::tuple<std::unique_ptr<Item> /* result */, const uint8_t* /* newPos */,
+           std::string /* errMsg */>
+parse(const uint8_t* begin, const uint8_t* end) {
+    FullParseClient parseClient;
+    parse(begin, end, &parseClient);
+    return parseClient.parseResult();
+}
+
+}  // namespace cppbor
diff --git a/identity/support/tests/IdentityCredentialSupportTest.cpp b/identity/support/tests/IdentityCredentialSupportTest.cpp
new file mode 100644
index 0000000..c356549
--- /dev/null
+++ b/identity/support/tests/IdentityCredentialSupportTest.cpp
@@ -0,0 +1,446 @@
+/*
+ * 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.
+ */
+
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <android/hardware/identity/support/IdentityCredentialSupport.h>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+using std::optional;
+using std::string;
+using std::vector;
+
+namespace android {
+namespace hardware {
+namespace identity {
+
+TEST(IdentityCredentialSupport, encodeHex) {
+    EXPECT_EQ("", support::encodeHex(vector<uint8_t>({})));
+    EXPECT_EQ("01", support::encodeHex(vector<uint8_t>({1})));
+    EXPECT_EQ("000102030405060708090a0b0c0d0e0f10",
+              support::encodeHex(
+                      vector<uint8_t>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})));
+    EXPECT_EQ("0102ffe060", support::encodeHex(vector<uint8_t>({1, 2, 255, 224, 96})));
+}
+
+TEST(IdentityCredentialSupport, decodeHex) {
+    EXPECT_EQ(vector<uint8_t>({}), support::decodeHex(""));
+    EXPECT_EQ(vector<uint8_t>({1}), support::decodeHex("01"));
+
+    EXPECT_EQ(vector<uint8_t>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}),
+              support::decodeHex("000102030405060708090a0b0c0d0e0f10"));
+
+    EXPECT_FALSE(support::decodeHex("0g"));
+    EXPECT_FALSE(support::decodeHex("0"));
+    EXPECT_FALSE(support::decodeHex("012"));
+}
+
+TEST(IdentityCredentialSupport, CborPrettyPrint) {
+    EXPECT_EQ("'Some text'", support::cborPrettyPrint(cppbor::Tstr("Some text").encode()));
+
+    EXPECT_EQ("''", support::cborPrettyPrint(cppbor::Tstr("").encode()));
+
+    EXPECT_EQ("{0x01, 0x00, 0x02, 0xf0, 0xff, 0x40}",
+              support::cborPrettyPrint(
+                      cppbor::Bstr(vector<uint8_t>({1, 0, 2, 240, 255, 64})).encode()));
+
+    EXPECT_EQ("{}", support::cborPrettyPrint(cppbor::Bstr(vector<uint8_t>()).encode()));
+
+    EXPECT_EQ("true", support::cborPrettyPrint(cppbor::Bool(true).encode()));
+
+    EXPECT_EQ("false", support::cborPrettyPrint(cppbor::Bool(false).encode()));
+
+    EXPECT_EQ("42", support::cborPrettyPrint(cppbor::Uint(42).encode()));
+
+    EXPECT_EQ("9223372036854775807",  // 0x7fff ffff ffff ffff
+              support::cborPrettyPrint(cppbor::Uint(std::numeric_limits<int64_t>::max()).encode()));
+
+    EXPECT_EQ("-42", support::cborPrettyPrint(cppbor::Nint(-42).encode()));
+
+    EXPECT_EQ("-9223372036854775808",  // -0x8000 0000 0000 0000
+              support::cborPrettyPrint(cppbor::Nint(std::numeric_limits<int64_t>::min()).encode()));
+}
+
+TEST(IdentityCredentialSupport, CborPrettyPrintCompound) {
+    cppbor::Array array = cppbor::Array("foo", "bar", "baz");
+    EXPECT_EQ("['foo', 'bar', 'baz', ]", support::cborPrettyPrint(array.encode()));
+
+    cppbor::Map map = cppbor::Map().add("foo", 42).add("bar", 43).add("baz", 44);
+    EXPECT_EQ(
+            "{\n"
+            "  'foo' : 42,\n"
+            "  'bar' : 43,\n"
+            "  'baz' : 44,\n"
+            "}",
+            support::cborPrettyPrint(map.encode()));
+
+    cppbor::Array array2 = cppbor::Array(cppbor::Tstr("Some text"), cppbor::Nint(-42));
+    EXPECT_EQ("['Some text', -42, ]", support::cborPrettyPrint(array2.encode()));
+
+    cppbor::Map map2 = cppbor::Map().add(42, "foo").add(43, "bar").add(44, "baz");
+    EXPECT_EQ(
+            "{\n"
+            "  42 : 'foo',\n"
+            "  43 : 'bar',\n"
+            "  44 : 'baz',\n"
+            "}",
+            support::cborPrettyPrint(map2.encode()));
+
+    cppbor::Array deeplyNestedArrays =
+            cppbor::Array(cppbor::Array(cppbor::Array("a", "b", "c")),
+                          cppbor::Array(cppbor::Array("d", "e", cppbor::Array("f", "g"))));
+    EXPECT_EQ(
+            "[\n"
+            "  ['a', 'b', 'c', ],\n"
+            "  [\n    'd',\n"
+            "    'e',\n"
+            "    ['f', 'g', ],\n"
+            "  ],\n"
+            "]",
+            support::cborPrettyPrint(deeplyNestedArrays.encode()));
+
+    EXPECT_EQ(
+            "[\n"
+            "  {0x0a, 0x0b},\n"
+            "  'foo',\n"
+            "  42,\n"
+            "  ['foo', 'bar', 'baz', ],\n"
+            "  {\n"
+            "    'foo' : 42,\n"
+            "    'bar' : 43,\n"
+            "    'baz' : 44,\n"
+            "  },\n"
+            "  {\n"
+            "    'deep1' : ['Some text', -42, ],\n"
+            "    'deep2' : {\n"
+            "      42 : 'foo',\n"
+            "      43 : 'bar',\n"
+            "      44 : 'baz',\n"
+            "    },\n"
+            "  },\n"
+            "]",
+            support::cborPrettyPrint(cppbor::Array(cppbor::Bstr(vector<uint8_t>{10, 11}),
+                                                   cppbor::Tstr("foo"), cppbor::Uint(42),
+                                                   std::move(array), std::move(map),
+                                                   (cppbor::Map()
+                                                            .add("deep1", std::move(array2))
+                                                            .add("deep2", std::move(map2))))
+                                             .encode()));
+}
+
+TEST(IdentityCredentialSupport, Signatures) {
+    vector<uint8_t> data = {1, 2, 3};
+
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    optional<vector<uint8_t>> signature = support::signEcDsa(privKey.value(), data);
+    ASSERT_TRUE(
+            support::checkEcDsaSignature(support::sha256(data), signature.value(), pubKey.value()));
+
+    // Manipulate the signature, check that verification fails.
+    vector<uint8_t> modifiedSignature = signature.value();
+    modifiedSignature[0] ^= 0xff;
+    ASSERT_FALSE(
+            support::checkEcDsaSignature(support::sha256(data), modifiedSignature, pubKey.value()));
+
+    // Manipulate the data being checked, check that verification fails.
+    vector<uint8_t> modifiedDigest = support::sha256(data);
+    modifiedDigest[0] ^= 0xff;
+    ASSERT_FALSE(support::checkEcDsaSignature(modifiedDigest, signature.value(), pubKey.value()));
+}
+
+string replaceLine(const string& str, ssize_t lineNumber, const string& replacement) {
+    vector<string> lines;
+    std::istringstream f(str);
+    string s;
+    while (std::getline(f, s, '\n')) {
+        lines.push_back(s);
+    }
+
+    size_t numLines = lines.size();
+    if (lineNumber < 0) {
+        lineNumber = numLines - (-lineNumber);
+    }
+
+    string ret;
+    size_t n = 0;
+    for (const string& line : lines) {
+        if (n == lineNumber) {
+            ret += replacement + "\n";
+        } else {
+            ret += line + "\n";
+        }
+        n++;
+    }
+    return ret;
+}
+
+TEST(IdentityCredentialSupport, CoseSignatures) {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    vector<uint8_t> data = {1, 2, 3};
+    optional<vector<uint8_t>> coseSign1 = support::coseSignEcDsa(
+            privKey.value(), data, {} /* detachedContent */, {} /* x5chain */);
+    ASSERT_TRUE(support::coseCheckEcDsaSignature(coseSign1.value(), {} /* detachedContent */,
+                                                 pubKey.value()));
+
+    optional<vector<uint8_t>> payload = support::coseSignGetPayload(coseSign1.value());
+    ASSERT_TRUE(payload);
+    ASSERT_EQ(data, payload.value());
+
+    // Finally, check that |coseSign1| are the bytes of a valid COSE_Sign1 message
+    string out = support::cborPrettyPrint(coseSign1.value());
+    out = replaceLine(out, -2, "  [] // Signature Removed");
+    EXPECT_EQ(
+            "[\n"
+            "  {0xa1, 0x01, 0x26},\n"  // Bytes of {1:-7} 1 is 'alg' label and -7 is "ECDSA 256"
+            "  {},\n"
+            "  {0x01, 0x02, 0x03},\n"
+            "  [] // Signature Removed\n"
+            "]\n",
+            out);
+}
+
+TEST(IdentityCredentialSupport, CoseSignaturesAdditionalData) {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    vector<uint8_t> detachedContent = {1, 2, 3};
+    optional<vector<uint8_t>> coseSign1 = support::coseSignEcDsa(privKey.value(), {} /* data */,
+                                                                 detachedContent, {} /* x5chain */);
+    ASSERT_TRUE(
+            support::coseCheckEcDsaSignature(coseSign1.value(), detachedContent, pubKey.value()));
+
+    optional<vector<uint8_t>> payload = support::coseSignGetPayload(coseSign1.value());
+    ASSERT_TRUE(payload);
+    ASSERT_EQ(0, payload.value().size());
+
+    // Finally, check that |coseSign1| are the bytes of a valid COSE_Sign1 message
+    string out = support::cborPrettyPrint(coseSign1.value());
+    out = replaceLine(out, -2, "  [] // Signature Removed");
+    EXPECT_EQ(
+            "[\n"
+            "  {0xa1, 0x01, 0x26},\n"  // Bytes of {1:-7} 1 is 'alg' label and -7 is "ECDSA 256"
+            "  {},\n"
+            "  null,\n"
+            "  [] // Signature Removed\n"
+            "]\n",
+            out);
+}
+
+vector<uint8_t> generateCertChain(size_t numCerts) {
+    vector<vector<uint8_t>> certs;
+
+    for (size_t n = 0; n < numCerts; n++) {
+        optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+        optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+        optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+
+        optional<vector<uint8_t>> cert = support::ecPublicKeyGenerateCertificate(
+                pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0);
+        certs.push_back(cert.value());
+    }
+    return support::certificateChainJoin(certs);
+}
+
+TEST(IdentityCredentialSupport, CoseSignaturesX5ChainWithSingleCert) {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    vector<uint8_t> certChain = generateCertChain(1);
+    optional<vector<vector<uint8_t>>> splitCerts = support::certificateChainSplit(certChain);
+    ASSERT_EQ(1, splitCerts.value().size());
+
+    vector<uint8_t> detachedContent = {1, 2, 3};
+    optional<vector<uint8_t>> coseSign1 =
+            support::coseSignEcDsa(privKey.value(), {} /* data */, detachedContent, certChain);
+    ASSERT_TRUE(
+            support::coseCheckEcDsaSignature(coseSign1.value(), detachedContent, pubKey.value()));
+
+    optional<vector<uint8_t>> payload = support::coseSignGetPayload(coseSign1.value());
+    ASSERT_TRUE(payload);
+    ASSERT_EQ(0, payload.value().size());
+
+    optional<vector<uint8_t>> certsRecovered = support::coseSignGetX5Chain(coseSign1.value());
+    EXPECT_EQ(certsRecovered.value(), certChain);
+}
+
+TEST(IdentityCredentialSupport, CoseSignaturesX5ChainWithMultipleCerts) {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    vector<uint8_t> certChain = generateCertChain(5);
+    optional<vector<vector<uint8_t>>> splitCerts = support::certificateChainSplit(certChain);
+    ASSERT_EQ(5, splitCerts.value().size());
+
+    vector<uint8_t> detachedContent = {1, 2, 3};
+    optional<vector<uint8_t>> coseSign1 =
+            support::coseSignEcDsa(privKey.value(), {} /* data */, detachedContent, certChain);
+    ASSERT_TRUE(
+            support::coseCheckEcDsaSignature(coseSign1.value(), detachedContent, pubKey.value()));
+
+    optional<vector<uint8_t>> payload = support::coseSignGetPayload(coseSign1.value());
+    ASSERT_TRUE(payload);
+    ASSERT_EQ(0, payload.value().size());
+
+    optional<vector<uint8_t>> certsRecovered = support::coseSignGetX5Chain(coseSign1.value());
+    EXPECT_EQ(certsRecovered.value(), certChain);
+}
+
+TEST(IdentityCredentialSupport, CertificateChain) {
+    optional<vector<uint8_t>> keyPair = support::createEcKeyPair();
+    ASSERT_TRUE(keyPair);
+    optional<vector<uint8_t>> privKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(privKey);
+    optional<vector<uint8_t>> pubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(pubKey);
+
+    optional<vector<uint8_t>> cert = support::ecPublicKeyGenerateCertificate(
+            pubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0);
+
+    optional<vector<uint8_t>> extractedPubKey =
+            support::certificateChainGetTopMostKey(cert.value());
+    ASSERT_TRUE(extractedPubKey);
+    ASSERT_EQ(pubKey.value(), extractedPubKey.value());
+
+    // We expect to the chain returned by ecPublicKeyGenerateCertificate() to only have a
+    // single element
+    optional<vector<vector<uint8_t>>> splitCerts = support::certificateChainSplit(cert.value());
+    ASSERT_EQ(1, splitCerts.value().size());
+    ASSERT_EQ(splitCerts.value()[0], cert.value());
+
+    optional<vector<uint8_t>> otherKeyPair = support::createEcKeyPair();
+    ASSERT_TRUE(otherKeyPair);
+    optional<vector<uint8_t>> otherPrivKey = support::ecKeyPairGetPrivateKey(keyPair.value());
+    ASSERT_TRUE(otherPrivKey);
+    optional<vector<uint8_t>> otherPubKey = support::ecKeyPairGetPublicKey(keyPair.value());
+    ASSERT_TRUE(otherPubKey);
+    optional<vector<uint8_t>> otherCert = support::ecPublicKeyGenerateCertificate(
+            otherPubKey.value(), privKey.value(), "0001", "someIssuer", "someSubject", 0, 0);
+
+    // Now both cert and otherCert are two distinct certificates. Let's make a
+    // chain and check that certificateChainSplit() works as expected.
+    ASSERT_NE(cert.value(), otherCert.value());
+    const vector<vector<uint8_t>> certs2 = {cert.value(), otherCert.value()};
+    vector<uint8_t> certs2combined = support::certificateChainJoin(certs2);
+    ASSERT_EQ(certs2combined.size(), cert.value().size() + otherCert.value().size());
+    optional<vector<vector<uint8_t>>> splitCerts2 = support::certificateChainSplit(certs2combined);
+    ASSERT_EQ(certs2, splitCerts2.value());
+}
+
+vector<uint8_t> strToVec(const string& str) {
+    vector<uint8_t> ret;
+    size_t size = str.size();
+    ret.resize(size);
+    memcpy(ret.data(), str.data(), size);
+    return ret;
+}
+
+// Test vector from https://en.wikipedia.org/wiki/HMAC
+TEST(IdentityCredentialSupport, hmacSha256) {
+    vector<uint8_t> key = strToVec("key");
+    vector<uint8_t> data = strToVec("The quick brown fox jumps over the lazy dog");
+
+    vector<uint8_t> expected =
+            support::decodeHex("f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8")
+                    .value();
+
+    optional<vector<uint8_t>> hmac = support::hmacSha256(key, data);
+    ASSERT_TRUE(hmac);
+    ASSERT_EQ(expected, hmac.value());
+}
+
+// See also CoseMac0 test in UtilUnitTest.java inside cts/tests/tests/identity/
+TEST(IdentityCredentialSupport, CoseMac0) {
+    vector<uint8_t> key;
+    key.resize(32);
+    vector<uint8_t> data = {0x10, 0x11, 0x12, 0x13};
+    vector<uint8_t> detachedContent = {};
+
+    optional<vector<uint8_t>> mac = support::coseMac0(key, data, detachedContent);
+    ASSERT_TRUE(mac);
+
+    EXPECT_EQ(
+            "[\n"
+            "  {0xa1, 0x01, 0x05},\n"
+            "  {},\n"
+            "  {0x10, 0x11, 0x12, 0x13},\n"
+            "  {0x6c, 0xec, 0xb5, 0x6a, 0xc9, 0x5c, 0xae, 0x3b, 0x41, 0x13, 0xde, 0xa4, 0xd8, "
+            "0x86, 0x5c, 0x28, 0x2c, 0xd5, 0xa5, 0x13, 0xff, 0x3b, 0xd1, 0xde, 0x70, 0x5e, 0xbb, "
+            "0xe2, 0x2d, 0x42, 0xbe, 0x53},\n"
+            "]",
+            support::cborPrettyPrint(mac.value()));
+}
+
+TEST(IdentityCredentialSupport, CoseMac0DetachedContent) {
+    vector<uint8_t> key;
+    key.resize(32);
+    vector<uint8_t> data = {};
+    vector<uint8_t> detachedContent = {0x10, 0x11, 0x12, 0x13};
+
+    optional<vector<uint8_t>> mac = support::coseMac0(key, data, detachedContent);
+    ASSERT_TRUE(mac);
+
+    // Same HMAC as in CoseMac0 test, only difference is that payload is null.
+    EXPECT_EQ(
+            "[\n"
+            "  {0xa1, 0x01, 0x05},\n"
+            "  {},\n"
+            "  null,\n"
+            "  {0x6c, 0xec, 0xb5, 0x6a, 0xc9, 0x5c, 0xae, 0x3b, 0x41, 0x13, 0xde, 0xa4, 0xd8, "
+            "0x86, 0x5c, 0x28, 0x2c, 0xd5, 0xa5, 0x13, 0xff, 0x3b, 0xd1, 0xde, 0x70, 0x5e, 0xbb, "
+            "0xe2, 0x2d, 0x42, 0xbe, 0x53},\n"
+            "]",
+            support::cborPrettyPrint(mac.value()));
+}
+
+}  // namespace identity
+}  // namespace hardware
+}  // namespace android
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/identity/support/tests/cppbor_test.cpp b/identity/support/tests/cppbor_test.cpp
new file mode 100644
index 0000000..3eb5598
--- /dev/null
+++ b/identity/support/tests/cppbor_test.cpp
@@ -0,0 +1,1013 @@
+/*
+ * 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.
+ */
+
+#include <iomanip>
+#include <sstream>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "cppbor.h"
+#include "cppbor_parse.h"
+
+using namespace cppbor;
+using namespace std;
+
+using ::testing::_;
+using ::testing::AllOf;
+using ::testing::ByRef;
+using ::testing::InSequence;
+using ::testing::IsNull;
+using ::testing::NotNull;
+using ::testing::Return;
+using ::testing::Truly;
+using ::testing::Unused;
+
+string hexDump(const string& str) {
+    stringstream s;
+    for (auto c : str) {
+        s << setfill('0') << setw(2) << hex << (static_cast<unsigned>(c) & 0xff);
+    }
+    return s.str();
+}
+
+TEST(SimpleValueTest, UnsignedValueSizes) {
+    // Check that unsigned integers encode to correct lengths, and that encodedSize() is correct.
+    vector<pair<uint64_t /* value */, size_t /* expected encoded size */>> testCases{
+            {0, 1},
+            {1, 1},
+            {23, 1},
+            {24, 2},
+            {255, 2},
+            {256, 3},
+            {65535, 3},
+            {65536, 5},
+            {4294967295, 5},
+            {4294967296, 9},
+            {std::numeric_limits<uint64_t>::max(), 9},
+    };
+    for (auto& testCase : testCases) {
+        Uint val(testCase.first);
+        EXPECT_EQ(testCase.second, val.encodedSize()) << "Wrong size for value " << testCase.first;
+        EXPECT_EQ(val.encodedSize(), val.toString().size())
+                << "encodedSize and encoding disagree for value " << testCase.first;
+    }
+}
+
+TEST(SimpleValueTest, UnsignedValueEncodings) {
+    EXPECT_EQ("\x00"s, Uint(0u).toString());
+    EXPECT_EQ("\x01"s, Uint(1u).toString());
+    EXPECT_EQ("\x0a"s, Uint(10u).toString());
+    EXPECT_EQ("\x17"s, Uint(23u).toString());
+    EXPECT_EQ("\x18\x18"s, Uint(24u).toString());
+    EXPECT_EQ("\x18\x19"s, Uint(25u).toString());
+    EXPECT_EQ("\x18\x64"s, Uint(100u).toString());
+    EXPECT_EQ("\x19\x03\xe8"s, Uint(1000u).toString());
+    EXPECT_EQ("\x1a\x00\x0f\x42\x40"s, Uint(1000000u).toString());
+    EXPECT_EQ("\x1b\x00\x00\x00\xe8\xd4\xa5\x10\x00"s, Uint(1000000000000u).toString());
+    EXPECT_EQ("\x1B\x7f\xff\xff\xff\xff\xff\xff\xff"s,
+              Uint(std::numeric_limits<int64_t>::max()).toString());
+}
+
+TEST(SimpleValueTest, NegativeValueEncodings) {
+    EXPECT_EQ("\x20"s, Nint(-1).toString());
+    EXPECT_EQ("\x28"s, Nint(-9).toString());
+    EXPECT_EQ("\x29"s, Nint(-10).toString());
+    EXPECT_EQ("\x36"s, Nint(-23).toString());
+    EXPECT_EQ("\x37"s, Nint(-24).toString());
+    EXPECT_EQ("\x38\x18"s, Nint(-25).toString());
+    EXPECT_EQ("\x38\x62"s, Nint(-99).toString());
+    EXPECT_EQ("\x38\x63"s, Nint(-100).toString());
+    EXPECT_EQ("\x39\x03\xe6"s, Nint(-999).toString());
+    EXPECT_EQ("\x39\x03\xe7"s, Nint(-1000).toString());
+    EXPECT_EQ("\x3a\x00\x0f\x42\x3F"s, Nint(-1000000).toString());
+    EXPECT_EQ("\x3b\x00\x00\x00\xe8\xd4\xa5\x0f\xff"s, Nint(-1000000000000).toString());
+    EXPECT_EQ("\x3B\x7f\xff\xff\xff\xff\xff\xff\xff"s,
+              Nint(std::numeric_limits<int64_t>::min()).toString());
+}
+
+TEST(SimpleValueDeathTest, NegativeValueEncodings) {
+    EXPECT_DEATH(Nint(0), "");
+    EXPECT_DEATH(Nint(1), "");
+}
+
+TEST(SimpleValueTest, BooleanEncodings) {
+    EXPECT_EQ("\xf4"s, Bool(false).toString());
+    EXPECT_EQ("\xf5"s, Bool(true).toString());
+}
+
+TEST(SimpleValueTest, ByteStringEncodings) {
+    EXPECT_EQ("\x40", Bstr("").toString());
+    EXPECT_EQ("\x41\x61", Bstr("a").toString());
+    EXPECT_EQ("\x41\x41", Bstr("A").toString());
+    EXPECT_EQ("\x44\x49\x45\x54\x46", Bstr("IETF").toString());
+    EXPECT_EQ("\x42\x22\x5c", Bstr("\"\\").toString());
+    EXPECT_EQ("\x42\xc3\xbc", Bstr("\xc3\xbc").toString());
+    EXPECT_EQ("\x43\xe6\xb0\xb4", Bstr("\xe6\xb0\xb4").toString());
+    EXPECT_EQ("\x44\xf0\x90\x85\x91", Bstr("\xf0\x90\x85\x91").toString());
+    EXPECT_EQ("\x44\x01\x02\x03\x04", Bstr("\x01\x02\x03\x04").toString());
+    EXPECT_EQ("\x44\x40\x40\x40\x40", Bstr("@@@@").toString());
+}
+
+TEST(SimpleValueTest, TextStringEncodings) {
+    EXPECT_EQ("\x60"s, Tstr("").toString());
+    EXPECT_EQ("\x61\x61"s, Tstr("a").toString());
+    EXPECT_EQ("\x61\x41"s, Tstr("A").toString());
+    EXPECT_EQ("\x64\x49\x45\x54\x46"s, Tstr("IETF").toString());
+    EXPECT_EQ("\x62\x22\x5c"s, Tstr("\"\\").toString());
+    EXPECT_EQ("\x62\xc3\xbc"s, Tstr("\xc3\xbc").toString());
+    EXPECT_EQ("\x63\xe6\xb0\xb4"s, Tstr("\xe6\xb0\xb4").toString());
+    EXPECT_EQ("\x64\xf0\x90\x85\x91"s, Tstr("\xf0\x90\x85\x91").toString());
+    EXPECT_EQ("\x64\x01\x02\x03\x04"s, Tstr("\x01\x02\x03\x04").toString());
+}
+
+TEST(IsIteratorPairOverTest, All) {
+    EXPECT_TRUE((
+            details::is_iterator_pair_over<pair<string::iterator, string::iterator>, char>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<string::const_iterator, string::iterator>,
+                                                char>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<string::iterator, string::const_iterator>,
+                                                char>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<char*, char*>, char>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<const char*, char*>, char>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<char*, const char*>, char>::value));
+    EXPECT_FALSE((details::is_iterator_pair_over<pair<string::iterator, string::iterator>,
+                                                 uint8_t>::value));
+    EXPECT_FALSE((details::is_iterator_pair_over<pair<char*, char*>, uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<
+                 pair<vector<uint8_t>::iterator, vector<uint8_t>::iterator>, uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<
+                 pair<vector<uint8_t>::const_iterator, vector<uint8_t>::iterator>,
+                 uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<
+                 pair<vector<uint8_t>::iterator, vector<uint8_t>::const_iterator>,
+                 uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<uint8_t*, uint8_t*>, uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<const uint8_t*, uint8_t*>, uint8_t>::value));
+    EXPECT_TRUE((details::is_iterator_pair_over<pair<uint8_t*, const uint8_t*>, uint8_t>::value));
+    EXPECT_FALSE((details::is_iterator_pair_over<
+                  pair<vector<uint8_t>::iterator, vector<uint8_t>::iterator>, char>::value));
+    EXPECT_FALSE((details::is_iterator_pair_over<pair<uint8_t*, const uint8_t*>, char>::value));
+}
+
+TEST(MakeEntryTest, Boolean) {
+    EXPECT_EQ("\xf4"s, details::makeItem(false)->toString());
+}
+
+TEST(MakeEntryTest, Integers) {
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint8_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint16_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint32_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<uint64_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int8_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int16_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int32_t>(0))->toString());
+    EXPECT_EQ("\x00"s, details::makeItem(static_cast<int64_t>(0))->toString());
+    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int8_t>(-1))->toString());
+    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int16_t>(-1))->toString());
+    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int32_t>(-1))->toString());
+    EXPECT_EQ("\x20"s, details::makeItem(static_cast<int64_t>(-1))->toString());
+
+    EXPECT_EQ("\x1b\xff\xff\xff\xff\xff\xff\xff\xff"s,
+              details::makeItem(static_cast<uint64_t>(std::numeric_limits<uint64_t>::max()))
+                      ->toString());
+}
+
+TEST(MakeEntryTest, StdStrings) {
+    string s1("hello");
+    const string s2("hello");
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s1)->toString());  // copy of string
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s,
+              details::makeItem(s2)->toString());  // copy of const string
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s,
+              details::makeItem(std::move(s1))->toString());  // move string
+    EXPECT_EQ(0U, s1.size());                                 // Prove string was moved, not copied.
+}
+
+TEST(MakeEntryTest, StdStringViews) {
+    string_view s1("hello");
+    const string_view s2("hello");
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s1)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s2)->toString());
+}
+
+TEST(MakeEntryTest, CStrings) {
+    char s1[] = "hello";
+    const char s2[] = "hello";
+    const char* s3 = "hello";
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s1)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s2)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(s3)->toString());
+}
+
+TEST(MakeEntryTest, StringIteratorPairs) {
+    // Use iterators from string to prove that "real" iterators work
+    string s1 = "hello"s;
+    pair<string::iterator, string::iterator> p1 = make_pair(s1.begin(), s1.end());
+
+    const pair<string::iterator, string::iterator> p2 = p1;
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p1)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p2)->toString());
+
+    // Use char*s  as iterators
+    const char* s2 = "hello";
+    pair p3 = make_pair(s2, s2 + 5);
+    const pair p4 = p3;
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p3)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(p4)->toString());
+}
+
+TEST(MakeEntryTest, ByteStrings) {
+    vector<uint8_t> v1 = {0x00, 0x01, 0x02};
+    const vector<uint8_t> v2 = {0x00, 0x01, 0x02};
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(v1)->toString());  // copy of vector
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(v2)->toString());  // copy of const vector
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(std::move(v1))->toString());  // move vector
+    EXPECT_EQ(0U, v1.size());  // Prove vector was moved, not copied.
+}
+
+TEST(MakeEntryTest, ByteStringIteratorPairs) {
+    using vec = vector<uint8_t>;
+    using iter = vec::iterator;
+    vec v1 = {0x00, 0x01, 0x02};
+    pair<iter, iter> p1 = make_pair(v1.begin(), v1.end());
+    const pair<iter, iter> p2 = make_pair(v1.begin(), v1.end());
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p1)->toString());
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p2)->toString());
+
+    // Use uint8_t*s as iterators
+    uint8_t v2[] = {0x00, 0x01, 0x02};
+    uint8_t* v3 = v2;
+    pair<uint8_t*, uint8_t*> p3 = make_pair(v2, v2 + 3);
+    const pair<uint8_t*, uint8_t*> p4 = make_pair(v2, v2 + 3);
+    pair<uint8_t*, uint8_t*> p5 = make_pair(v3, v3 + 3);
+    const pair<uint8_t*, uint8_t*> p6 = make_pair(v3, v3 + 3);
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p3)->toString());
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p4)->toString());
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p5)->toString());
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(p6)->toString());
+}
+
+TEST(MakeEntryTest, ByteStringBuffers) {
+    uint8_t v1[] = {0x00, 0x01, 0x02};
+    EXPECT_EQ("\x43\x00\x01\x02"s, details::makeItem(make_pair(v1, 3))->toString());
+}
+
+TEST(MakeEntryTest, ItemPointer) {
+    Uint* p1 = new Uint(0);
+    EXPECT_EQ("\x00"s, details::makeItem(p1)->toString());
+    EXPECT_EQ("\x60"s, details::makeItem(new Tstr(string()))->toString());
+}
+
+TEST(MakeEntryTest, ItemReference) {
+    Tstr str("hello"s);
+    Tstr& strRef = str;
+    const Tstr& strConstRef = str;
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(str)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(strRef)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(strConstRef)->toString());
+    EXPECT_EQ("\x65\x68\x65\x6c\x6c\x6f"s, details::makeItem(std::move(str))->toString());
+    EXPECT_EQ("\x60"s, details::makeItem(str)->toString());  // Prove that it moved
+
+    EXPECT_EQ("\x00"s, details::makeItem(Uint(0))->toString());
+
+    EXPECT_EQ("\x43\x00\x01\x02"s,
+              details::makeItem(Bstr(vector<uint8_t>{0x00, 0x01, 0x02}))->toString());
+
+    EXPECT_EQ("\x80"s, details::makeItem(Array())->toString());
+    EXPECT_EQ("\xa0"s, details::makeItem(Map())->toString());
+}
+
+TEST(CompoundValueTest, ArrayOfInts) {
+    EXPECT_EQ("\x80"s, Array().toString());
+    Array(Uint(0)).toString();
+
+    EXPECT_EQ("\x81\x00"s, Array(Uint(0U)).toString());
+    EXPECT_EQ("\x82\x00\x01"s, Array(Uint(0), Uint(1)).toString());
+    EXPECT_EQ("\x83\x00\x01\x38\x62"s, Array(Uint(0), Uint(1), Nint(-99)).toString());
+
+    EXPECT_EQ("\x81\x00"s, Array(0).toString());
+    EXPECT_EQ("\x82\x00\x01"s, Array(0, 1).toString());
+    EXPECT_EQ("\x83\x00\x01\x38\x62"s, Array(0, 1, -99).toString());
+}
+
+TEST(CompoundValueTest, MapOfInts) {
+    EXPECT_EQ("\xA0"s, Map().toString());
+    EXPECT_EQ("\xA1\x00\x01"s, Map(Uint(0), Uint(1)).toString());
+    // Maps with an odd number of arguments will fail to compile.  Uncomment the next lines to test.
+    // EXPECT_EQ("\xA1\x00"s, Map(Int(0)).toString());
+    // EXPECT_EQ("\xA1\x00\x01\x02"s, Map(Int(0), Int(1), Int(2)).toString());
+}
+
+TEST(CompoundValueTest, MixedArray) {
+    vector<uint8_t> vec = {3, 2, 1};
+    EXPECT_EQ("\x84\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
+              Array(Uint(1), Nint(-1), Bstr(vec), Tstr("hello")).toString());
+
+    EXPECT_EQ("\x84\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
+              Array(1, -1, vec, "hello").toString());
+}
+
+TEST(CompoundValueTest, MixedMap) {
+    vector<uint8_t> vec = {3, 2, 1};
+    EXPECT_EQ("\xA2\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
+              Map(Uint(1), Nint(-1), Bstr(vec), Tstr("hello")).toString());
+
+    EXPECT_EQ("\xA2\x01\x20\x43\x03\x02\x01\x65\x68\x65\x6C\x6C\x6F"s,
+              Map(1, -1, vec, "hello").toString());
+}
+
+TEST(CompoundValueTest, NestedStructures) {
+    vector<uint8_t> vec = {3, 2, 1};
+
+    string expectedEncoding =
+            "\xA2\x66\x4F\x75\x74\x65\x72\x31\x82\xA2\x66\x49\x6E\x6E\x65\x72\x31\x18\x63\x66\x49"
+            "\x6E"
+            "\x6E\x65\x72\x32\x43\x03\x02\x01\x63\x66\x6F\x6F\x66\x4F\x75\x74\x65\x72\x32\x0A"s;
+
+    // Do it with explicitly-created Items
+    EXPECT_EQ(expectedEncoding,
+              Map(Tstr("Outer1"),
+                  Array(  //
+                          Map(Tstr("Inner1"), Uint(99), Tstr("Inner2"), Bstr(vec)), Tstr("foo")),
+                  Tstr("Outer2"),  //
+                  Uint(10))
+                      .toString());
+    EXPECT_EQ(3U, vec.size());
+
+    // Now just use convertible types
+    EXPECT_EQ(expectedEncoding, Map("Outer1",
+                                    Array(Map("Inner1", 99,  //
+                                              "Inner2", vec),
+                                          "foo"),
+                                    "Outer2", 10)
+                                        .toString());
+    EXPECT_EQ(3U, vec.size());
+
+    // Finally, do it with the .add() method.  This is slightly less efficient, but has the
+    // advantage you can build a structure up incrementally, or somewhat fluently if you like.
+    // First, fluently.
+    EXPECT_EQ(expectedEncoding, Map().add("Outer1", Array().add(Map()  //
+                                                                        .add("Inner1", 99)
+                                                                        .add("Inner2", vec))
+                                                            .add("foo"))
+                                        .add("Outer2", 10)
+                                        .toString());
+    EXPECT_EQ(3U, vec.size());
+
+    // Next, more incrementally
+    Array arr;
+    arr.add(Map()  //
+                    .add("Inner1", 99)
+                    .add("Inner2", vec))
+            .add("foo");
+    EXPECT_EQ(3U, vec.size());
+
+    Map m;
+    m.add("Outer1", std::move(arr));  // Moving is necessary; Map and Array cannot be copied.
+    m.add("Outer2", 10);
+    auto s = m.toString();
+    EXPECT_EQ(expectedEncoding, s);
+}
+
+TEST(EncodingMethodsTest, AllVariants) {
+    Map map;
+    map.add("key1", Array().add(Map()  //
+                                        .add("key_a", 9999999)
+                                        .add("key_b", std::vector<uint8_t>{0x01, 0x02, 0x03})
+                                        .add("key_c", std::numeric_limits<uint64_t>::max())
+                                        .add("key_d", std::numeric_limits<int16_t>::min()))
+                            .add("foo"))
+            .add("key2", true);
+
+    std::vector<uint8_t> buf;
+    buf.resize(map.encodedSize());
+
+    EXPECT_EQ(buf.data() + buf.size(), map.encode(buf.data(), buf.data() + buf.size()));
+
+    EXPECT_EQ(buf, map.encode());
+
+    std::vector<uint8_t> buf2;
+    map.encode(std::back_inserter(buf2));
+    EXPECT_EQ(buf, buf2);
+
+    auto iter = buf.begin();
+    map.encode([&](uint8_t c) { EXPECT_EQ(c, *iter++); });
+}
+
+TEST(EncodingMethodsTest, UintWithTooShortBuf) {
+    Uint val(100000);
+    vector<uint8_t> buf(val.encodedSize() - 1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+}
+
+TEST(EncodingMethodsTest, TstrWithTooShortBuf) {
+    Tstr val("01234567890123456789012345"s);
+    vector<uint8_t> buf(1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+
+    buf.resize(val.encodedSize() - 1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+}
+
+TEST(EncodingMethodsTest, BstrWithTooShortBuf) {
+    Bstr val("01234567890123456789012345"s);
+    vector<uint8_t> buf(1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+
+    buf.resize(val.encodedSize() - 1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+}
+
+TEST(EncodingMethodsTest, ArrayWithTooShortBuf) {
+    Array val("a", 5, -100);
+
+    std::vector<uint8_t> buf(val.encodedSize() - 1);
+    EXPECT_EQ(nullptr, val.encode(buf.data(), buf.data() + buf.size()));
+}
+
+TEST(EncodingMethodsTest, MapWithTooShortBuf) {
+    Map map;
+    map.add("key1", Array().add(Map()  //
+                                        .add("key_a", 99)
+                                        .add("key_b", std::vector<uint8_t>{0x01, 0x02, 0x03}))
+                            .add("foo"))
+            .add("key2", true);
+
+    std::vector<uint8_t> buf(map.encodedSize() - 1);
+    EXPECT_EQ(nullptr, map.encode(buf.data(), buf.data() + buf.size()));
+}
+
+TEST(EqualityTest, Uint) {
+    Uint val(99);
+    EXPECT_EQ(val, Uint(99));
+
+    EXPECT_NE(val, Uint(98));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("99"));
+    EXPECT_NE(val, Bool(false));
+    EXPECT_NE(val, Array(99, 1));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Nint) {
+    Nint val(-1);
+    EXPECT_EQ(val, Nint(-1));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("99"));
+    EXPECT_NE(val, Bool(false));
+    EXPECT_NE(val, Array(99));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Tstr) {
+    Tstr val("99");
+    EXPECT_EQ(val, Tstr("99"));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("98"));
+    EXPECT_NE(val, Bstr("99"));
+    EXPECT_NE(val, Bool(false));
+    EXPECT_NE(val, Array(99, 1));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Bstr) {
+    Bstr val("99");
+    EXPECT_EQ(val, Bstr("99"));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("98"));
+    EXPECT_NE(val, Bool(false));
+    EXPECT_NE(val, Array(99, 1));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Bool) {
+    Bool val(false);
+    EXPECT_EQ(val, Bool(false));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("98"));
+    EXPECT_NE(val, Bool(true));
+    EXPECT_NE(val, Array(99, 1));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Array) {
+    Array val(99, 1);
+    EXPECT_EQ(val, Array(99, 1));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("98"));
+    EXPECT_NE(val, Bool(true));
+    EXPECT_NE(val, Array(99, 2));
+    EXPECT_NE(val, Array(98, 1));
+    EXPECT_NE(val, Array(99, 1, 2));
+    EXPECT_NE(val, Map(99, 1));
+}
+
+TEST(EqualityTest, Map) {
+    Map val(99, 1);
+    EXPECT_EQ(val, Map(99, 1));
+
+    EXPECT_NE(val, Uint(99));
+    EXPECT_NE(val, Nint(-1));
+    EXPECT_NE(val, Nint(-4));
+    EXPECT_NE(val, Tstr("99"));
+    EXPECT_NE(val, Bstr("98"));
+    EXPECT_NE(val, Bool(true));
+    EXPECT_NE(val, Array(99, 1));
+    EXPECT_NE(val, Map(99, 2));
+    EXPECT_NE(val, Map(99, 1, 99, 2));
+}
+
+TEST(ConvertTest, Uint) {
+    unique_ptr<Item> item = details::makeItem(10);
+
+    EXPECT_EQ(UINT, item->type());
+    EXPECT_NE(nullptr, item->asInt());
+    EXPECT_NE(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ(10, item->asInt()->value());
+    EXPECT_EQ(10, item->asUint()->value());
+}
+
+TEST(ConvertTest, Nint) {
+    unique_ptr<Item> item = details::makeItem(-10);
+
+    EXPECT_EQ(NINT, item->type());
+    EXPECT_NE(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_NE(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ(-10, item->asInt()->value());
+    EXPECT_EQ(-10, item->asNint()->value());
+}
+
+TEST(ConvertTest, Tstr) {
+    unique_ptr<Item> item = details::makeItem("hello");
+
+    EXPECT_EQ(TSTR, item->type());
+    EXPECT_EQ(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_NE(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ("hello"s, item->asTstr()->value());
+}
+
+TEST(ConvertTest, Bstr) {
+    vector<uint8_t> vec{0x23, 0x24, 0x22};
+    unique_ptr<Item> item = details::makeItem(vec);
+
+    EXPECT_EQ(BSTR, item->type());
+    EXPECT_EQ(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_NE(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ(vec, item->asBstr()->value());
+}
+
+TEST(ConvertTest, Bool) {
+    unique_ptr<Item> item = details::makeItem(false);
+
+    EXPECT_EQ(SIMPLE, item->type());
+    EXPECT_EQ(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_NE(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ(BOOLEAN, item->asSimple()->simpleType());
+    EXPECT_NE(nullptr, item->asSimple()->asBool());
+
+    EXPECT_FALSE(item->asSimple()->asBool()->value());
+}
+
+TEST(ConvertTest, Map) {
+    unique_ptr<Item> item(new Map);
+
+    EXPECT_EQ(MAP, item->type());
+    EXPECT_EQ(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_NE(nullptr, item->asMap());
+    EXPECT_EQ(nullptr, item->asArray());
+
+    EXPECT_EQ(0U, item->asMap()->size());
+}
+
+TEST(ConvertTest, Array) {
+    unique_ptr<Item> item(new Array);
+
+    EXPECT_EQ(ARRAY, item->type());
+    EXPECT_EQ(nullptr, item->asInt());
+    EXPECT_EQ(nullptr, item->asUint());
+    EXPECT_EQ(nullptr, item->asNint());
+    EXPECT_EQ(nullptr, item->asTstr());
+    EXPECT_EQ(nullptr, item->asBstr());
+    EXPECT_EQ(nullptr, item->asSimple());
+    EXPECT_EQ(nullptr, item->asMap());
+    EXPECT_NE(nullptr, item->asArray());
+
+    EXPECT_EQ(0U, item->asArray()->size());
+}
+
+class MockParseClient : public ParseClient {
+  public:
+    MOCK_METHOD4(item, ParseClient*(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
+                                    const uint8_t* valueBegin, const uint8_t* end));
+    MOCK_METHOD4(itemEnd, ParseClient*(std::unique_ptr<Item>& item, const uint8_t* hdrBegin,
+                                       const uint8_t* valueBegin, const uint8_t* end));
+    MOCK_METHOD2(error, void(const uint8_t* position, const std::string& errorMessage));
+};
+
+MATCHER_P(IsType, value, std::string("Type ") + (negation ? "doesn't match" : "matches")) {
+    return arg->type() == value;
+}
+
+MATCHER_P(MatchesItem, value, "") {
+    return arg && *arg == value;
+}
+
+MATCHER_P(IsArrayOfSize, value, "") {
+    return arg->type() == ARRAY && arg->asArray()->size() == value;
+}
+
+MATCHER_P(IsMapOfSize, value, "") {
+    return arg->type() == MAP && arg->asMap()->size() == value;
+}
+
+TEST(StreamParseTest, Uint) {
+    MockParseClient mpc;
+
+    Uint val(100);
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encEnd, encEnd)).WillOnce(Return(&mpc));
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(_, _)).Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Nint) {
+    MockParseClient mpc;
+
+    Nint val(-10);
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encEnd, encEnd)).WillOnce(Return(&mpc));
+
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(_, _)).Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Bool) {
+    MockParseClient mpc;
+
+    Bool val(true);
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encEnd, encEnd)).WillOnce(Return(&mpc));
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(_, _)).Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Tstr) {
+    MockParseClient mpc;
+
+    Tstr val("Hello");
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encBegin + 1, encEnd)).WillOnce(Return(&mpc));
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(_, _)).Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Bstr) {
+    MockParseClient mpc;
+
+    Bstr val("Hello");
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    EXPECT_CALL(mpc, item(MatchesItem(val), encBegin, encBegin + 1, encEnd)).WillOnce(Return(&mpc));
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(_, _)).Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Array) {
+    MockParseClient mpc;
+
+    Array val("Hello", 4, Array(-9, "Goodbye"), std::numeric_limits<uint64_t>::max());
+    ASSERT_NE(val[2]->asArray(), nullptr);
+    const Array& interior = *(val[2]->asArray());
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    {
+        InSequence s;
+        const uint8_t* pos = encBegin;
+        EXPECT_CALL(mpc, item(IsArrayOfSize(val.size()), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[0])), pos, pos + 1, pos + 6))
+                .WillOnce(Return(&mpc));
+        pos += 6;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[1])), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        const uint8_t* innerArrayBegin = pos;
+        EXPECT_CALL(mpc, item(IsArrayOfSize(interior.size()), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[0])), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[1])), pos, pos + 1, pos + 8))
+                .WillOnce(Return(&mpc));
+        pos += 8;
+        EXPECT_CALL(mpc, itemEnd(IsArrayOfSize(interior.size()), innerArrayBegin,
+                                 innerArrayBegin + 1, pos))
+                .WillOnce(Return(&mpc));
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[3])), pos, pos + 9, pos + 9))
+                .WillOnce(Return(&mpc));
+        EXPECT_CALL(mpc, itemEnd(IsArrayOfSize(val.size()), encBegin, encBegin + 1, encEnd))
+                .WillOnce(Return(&mpc));
+    }
+
+    EXPECT_CALL(mpc, error(_, _))  //
+            .Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Map) {
+    MockParseClient mpc;
+
+    Map val("Hello", 4, Array(-9, "Goodbye"), std::numeric_limits<uint64_t>::max());
+    ASSERT_NE(val[1].first->asArray(), nullptr);
+    const Array& interior = *(val[1].first->asArray());
+    auto encoded = val.encode();
+    uint8_t* encBegin = encoded.data();
+    uint8_t* encEnd = encoded.data() + encoded.size();
+
+    {
+        InSequence s;
+        const uint8_t* pos = encBegin;
+        EXPECT_CALL(mpc, item(_, pos, pos + 1, pos + 1)).WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[0].first)), pos, pos + 1, pos + 6))
+                .WillOnce(Return(&mpc));
+        pos += 6;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[0].second)), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        const uint8_t* innerArrayBegin = pos;
+        EXPECT_CALL(mpc, item(IsArrayOfSize(interior.size()), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[0])), pos, pos + 1, pos + 1))
+                .WillOnce(Return(&mpc));
+        ++pos;
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*interior[1])), pos, pos + 1, pos + 8))
+                .WillOnce(Return(&mpc));
+        pos += 8;
+        EXPECT_CALL(mpc, itemEnd(IsArrayOfSize(interior.size()), innerArrayBegin,
+                                 innerArrayBegin + 1, pos))
+                .WillOnce(Return(&mpc));
+        EXPECT_CALL(mpc, item(MatchesItem(ByRef(*val[1].second)), pos, pos + 9, pos + 9))
+                .WillOnce(Return(&mpc));
+        EXPECT_CALL(mpc, itemEnd(IsMapOfSize(val.size()), encBegin, encBegin + 1, encEnd))
+                .WillOnce(Return(&mpc));
+    }
+
+    EXPECT_CALL(mpc, error(_, _))  //
+            .Times(0);
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(StreamParseTest, Semantic) {
+    MockParseClient mpc;
+
+    vector<uint8_t> encoded;
+    auto iter = back_inserter(encoded);
+    encodeHeader(SEMANTIC, 0, iter);
+    Uint(999).encode(iter);
+
+    EXPECT_CALL(mpc, item(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, itemEnd(_, _, _, _)).Times(0);
+    EXPECT_CALL(mpc, error(encoded.data(), "Semantic tags not supported"));
+
+    parse(encoded.data(), encoded.data() + encoded.size(), &mpc);
+}
+
+TEST(FullParserTest, Uint) {
+    Uint val(10);
+
+    auto [item, pos, message] = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(val));
+}
+
+TEST(FullParserTest, Nint) {
+    Nint val(-10);
+
+    auto [item, pos, message] = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(val));
+
+    vector<uint8_t> minNint = {0x3B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+    std::tie(item, pos, message) = parse(minNint);
+    EXPECT_THAT(item, NotNull());
+    EXPECT_EQ(item->asNint()->value(), std::numeric_limits<int64_t>::min());
+}
+
+TEST(FullParserTest, NintOutOfRange) {
+    vector<uint8_t> outOfRangeNint = {0x3B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+    auto [item, pos, message] = parse(outOfRangeNint);
+    EXPECT_THAT(item, IsNull());
+    EXPECT_EQ(pos, outOfRangeNint.data());
+    EXPECT_EQ(message, "NINT values that don't fit in int64_t are not supported.");
+}
+
+TEST(FullParserTest, Tstr) {
+    Tstr val("Hello");
+
+    auto [item, pos, message] = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(val));
+}
+
+TEST(FullParserTest, Bstr) {
+    Bstr val("\x00\x01\0x02"s);
+
+    auto [item, pos, message] = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(val));
+}
+
+TEST(FullParserTest, Array) {
+    Array val("hello", -4, 3);
+
+    auto encoded = val.encode();
+    auto [item, pos, message] = parse(encoded);
+    EXPECT_THAT(item, MatchesItem(ByRef(val)));
+    EXPECT_EQ(pos, encoded.data() + encoded.size());
+    EXPECT_EQ("", message);
+
+    // We've already checked it all, but walk it just for fun.
+    ASSERT_NE(nullptr, item->asArray());
+    const Array& arr = *(item->asArray());
+    ASSERT_EQ(arr[0]->type(), TSTR);
+    EXPECT_EQ(arr[0]->asTstr()->value(), "hello");
+}
+
+TEST(FullParserTest, Map) {
+    Map val("hello", -4, 3, Bstr("hi"));
+
+    auto [item, pos, message] = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(ByRef(val)));
+}
+
+TEST(FullParserTest, Complex) {
+    vector<uint8_t> vec = {0x01, 0x02, 0x08, 0x03};
+    Map val("Outer1",
+            Array(Map("Inner1", 99,  //
+                      "Inner2", vec),
+                  "foo"),
+            "Outer2", 10);
+
+    std::unique_ptr<Item> item;
+    const uint8_t* pos;
+    std::string message;
+    std::tie(item, pos, message) = parse(val.encode());
+    EXPECT_THAT(item, MatchesItem(ByRef(val)));
+}
+
+TEST(FullParserTest, IncompleteUint) {
+    Uint val(1000);
+
+    auto encoding = val.encode();
+    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 1);
+    EXPECT_EQ(nullptr, item.get());
+    EXPECT_EQ(encoding.data(), pos);
+    EXPECT_EQ("Need 2 byte(s) for length field, have 1.", message);
+}
+
+TEST(FullParserTest, IncompleteString) {
+    Tstr val("hello");
+
+    auto encoding = val.encode();
+    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 2);
+    EXPECT_EQ(nullptr, item.get());
+    EXPECT_EQ(encoding.data(), pos);
+    EXPECT_EQ("Need 5 byte(s) for text string, have 3.", message);
+}
+
+TEST(FullParserTest, ArrayWithInsufficientEntries) {
+    Array val(1, 2, 3, 4);
+
+    auto encoding = val.encode();
+    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 1);
+    EXPECT_EQ(nullptr, item.get());
+    EXPECT_EQ(encoding.data(), pos);
+    EXPECT_EQ("Not enough entries for array.", message);
+}
+
+TEST(FullParserTest, ArrayWithTruncatedEntry) {
+    Array val(1, 2, 3, 400000);
+
+    auto encoding = val.encode();
+    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 1);
+    EXPECT_EQ(nullptr, item.get());
+    EXPECT_EQ(encoding.data() + encoding.size() - 5, pos);
+    EXPECT_EQ("Need 4 byte(s) for length field, have 3.", message);
+}
+
+TEST(FullParserTest, MapWithTruncatedEntry) {
+    Map val(1, 2, 300000, 4);
+
+    auto encoding = val.encode();
+    auto [item, pos, message] = parse(encoding.data(), encoding.size() - 2);
+    EXPECT_EQ(nullptr, item.get());
+    EXPECT_EQ(encoding.data() + 3, pos);
+    EXPECT_EQ("Need 4 byte(s) for length field, have 3.", message);
+}
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    return RUN_ALL_TESTS();
+}
diff --git a/tv/tuner/1.0/IFilter.hal b/tv/tuner/1.0/IFilter.hal
index 94e3c0c..567971f 100644
--- a/tv/tuner/1.0/IFilter.hal
+++ b/tv/tuner/1.0/IFilter.hal
@@ -120,12 +120,13 @@
      * presented by file descripor in the handle as released.
      *
      * @param avMemory A handle associated to the memory for audio or video.
+     * @param avDataId An Id provides additional information for AV data.
      * @return result Result status of the operation.
      *         SUCCESS if successful,
      *         INVALID_ARGUMENT if failed for wrong parameter.
      *         UNKNOWN_ERROR if failed for other reasons.
      */
-    releaseAvHandle(handle avMemory) generates (Result result);
+    releaseAvHandle(handle avMemory, uint64_t avDataId) generates (Result result);
 
     /**
      * Set the filter's data source.
diff --git a/tv/tuner/1.0/ITuner.hal b/tv/tuner/1.0/ITuner.hal
index 2712c13..ba183f1 100644
--- a/tv/tuner/1.0/ITuner.hal
+++ b/tv/tuner/1.0/ITuner.hal
@@ -123,4 +123,21 @@
      * @return lnb the newly created Lnb interface.
      */
     openLnbById(LnbId lnbId) generates (Result result, ILnb lnb);
+
+    /**
+     * Create a new instance of Lnb given a LNB name.
+     *
+     * It is used by the client to create a LNB instance for external device.
+     *
+     * @param lnbName the name for an external LNB to be opened. The app
+     *        provides the name. Frammework doesn't depend on the name, instead
+     *        use lnbId return from this call.
+     * @return result Result status of the operation.
+     *         SUCCESS if successful,
+     *         UNAVAILABLE if no resource.
+     *         UNKNOWN_ERROR if creation failed for other reasons.
+     * @return lnbId the id of the LNB to be opened.
+     * @return lnb the newly created Lnb interface.
+     */
+    openLnbByName(string lnbName) generates (Result result, LnbId lnbId, ILnb lnb);
 };
diff --git a/tv/tuner/1.0/default/Filter.cpp b/tv/tuner/1.0/default/Filter.cpp
index b3160fc..54d0952 100644
--- a/tv/tuner/1.0/default/Filter.cpp
+++ b/tv/tuner/1.0/default/Filter.cpp
@@ -120,7 +120,7 @@
     return Result::SUCCESS;
 }
 
-Return<Result> Filter::releaseAvHandle(const hidl_handle& /*avMemory*/) {
+Return<Result> Filter::releaseAvHandle(const hidl_handle& /*avMemory*/, uint64_t /*avDataId*/) {
     ALOGV("%s", __FUNCTION__);
 
     return Result::SUCCESS;
diff --git a/tv/tuner/1.0/default/Filter.h b/tv/tuner/1.0/default/Filter.h
index d397f73..0dc992a 100644
--- a/tv/tuner/1.0/default/Filter.h
+++ b/tv/tuner/1.0/default/Filter.h
@@ -70,7 +70,7 @@
 
     virtual Return<Result> flush() override;
 
-    virtual Return<Result> releaseAvHandle(const hidl_handle& avMemory) override;
+    virtual Return<Result> releaseAvHandle(const hidl_handle& avMemory, uint64_t avDataId) override;
 
     virtual Return<Result> close() override;
 
diff --git a/tv/tuner/1.0/default/Tuner.cpp b/tv/tuner/1.0/default/Tuner.cpp
index c143d61..c6017f0 100644
--- a/tv/tuner/1.0/default/Tuner.cpp
+++ b/tv/tuner/1.0/default/Tuner.cpp
@@ -139,6 +139,15 @@
     return mFrontends[frontendId];
 }
 
+Return<void> Tuner::openLnbByName(const hidl_string& /*lnbName*/, openLnbByName_cb _hidl_cb) {
+    ALOGV("%s", __FUNCTION__);
+
+    sp<ILnb> lnb = new Lnb();
+
+    _hidl_cb(Result::SUCCESS, 1234, lnb);
+    return Void();
+}
+
 void Tuner::setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId) {
     mFrontendToDemux[frontendId] = demuxId;
 }
diff --git a/tv/tuner/1.0/default/Tuner.h b/tv/tuner/1.0/default/Tuner.h
index 96da257..7a8a919 100644
--- a/tv/tuner/1.0/default/Tuner.h
+++ b/tv/tuner/1.0/default/Tuner.h
@@ -55,6 +55,9 @@
 
     virtual Return<void> openLnbById(LnbId lnbId, openLnbById_cb _hidl_cb) override;
 
+    virtual Return<void> openLnbByName(const hidl_string& lnbName,
+                                       openLnbByName_cb _hidl_cb) override;
+
     sp<Frontend> getFrontendById(uint32_t frontendId);
 
     void setFrontendAsDemuxSource(uint32_t frontendId, uint32_t demuxId);
diff --git a/tv/tuner/1.0/types.hal b/tv/tuner/1.0/types.hal
index 8e36616..3afe37d 100644
--- a/tv/tuner/1.0/types.hal
+++ b/tv/tuner/1.0/types.hal
@@ -537,6 +537,16 @@
 };
 
 /**
+ *   VCM mode in DVBS.
+ */
+@export
+enum FrontendDvbsVcmMode : uint32_t {
+    UNDEFINED,
+    AUTO,
+    MANUAL,
+};
+
+/**
  *  Signal Settings for an DVBS Frontend.
  */
 struct FrontendDvbsSettings {
@@ -561,6 +571,8 @@
     uint32_t inputStreamId;
 
     FrontendDvbsStandard standard;
+
+    FrontendDvbsVcmMode vcmMode;
 };
 
 /**
@@ -961,7 +973,7 @@
     /**
      * hardware is able to detect and set Modulation automatically
      */
-    AUTO = 1 << 5,
+    AUTO = 1 << 0,
     MOD_BPSK = 1 << 1,
     MOD_QPSK = 1 << 2,
     MOD_8PSK = 1 << 3,
@@ -1106,7 +1118,7 @@
 
     bitfield<FrontendIsdbtBandwidth> bandwidthCap;
 
-    bitfield<FrontendIsdbtModulation> constellationCap;
+    bitfield<FrontendIsdbtModulation> modulationCap;
 
     bitfield<FrontendIsdbtCoderate> coderateCap;
 
@@ -1231,6 +1243,11 @@
      */
     SYMBOL_RATE,
     /**
+     * Locked HIERARCHY for DVBT2 frontend.
+     */
+    HIERARCHY,
+    ANALOG_TYPE,
+    /**
      * Locked Plp Ids for DVBT2 frontend.
      */
     PLP_IDS,
@@ -1275,14 +1292,18 @@
     uint8_t progressPercent;
 
     /**
-     * Signal frequency in Hertz
+     * Signal frequencies in Hertz
      */
-    uint32_t frequency;
+    vec<uint32_t> frequencies;
 
     /**
      * Symbols per second
      */
-    uint32_t symbolRate;
+    vec<uint32_t> symbolRates;
+
+    FrontendDvbtHierarchy hierarchy;
+
+    FrontendAnalogType analogType;
 
     vec<uint8_t> plpIds;
 
@@ -1290,10 +1311,12 @@
 
     vec<uint16_t> inputStreamIds;
 
-    safe_union standard {
+    safe_union Standard {
         FrontendDvbsStandard sStd;
 
         FrontendDvbtStandard tStd;
+
+        FrontendAnalogSifStandard sifStd;
     } std;
 
     /**
@@ -2020,19 +2043,15 @@
 };
 
 /**
- * Index type to be used in the filter for record
+ * Start Code Index type to be used in the filter for record
  */
 @export
-enum DemuxRecordIndexType : uint32_t {
+enum DemuxRecordScIndexType : uint32_t {
     /**
-     * Don't use index
+     * Don't use SC index
      */
     NONE,
     /**
-     * Use TS index
-     */
-    TS,
-    /**
      * Use Start Code index
      */
     SC,
@@ -2046,15 +2065,16 @@
  *  Filter Settings for Record data.
  */
 struct DemuxFilterRecordSettings {
-    DemuxRecordIndexType indexType;
+    bitfield<DemuxTsIndex> tsIndexMask;
 
-    safe_union IndexMask {
-        bitfield<DemuxTsIndex> tsIndexMask;
+    DemuxRecordScIndexType scIndexType;
 
-        bitfield<DemuxScIndex> scIndexMask;
+    safe_union ScIndexMask {
 
-        bitfield<DemuxScHevcIndex> scHevcIndexMask;
-    } indexMask;
+        bitfield<DemuxScIndex> sc;
+
+        bitfield<DemuxScHevcIndex> scHevc;
+    } scIndexMask;
 };
 
 /**
@@ -2399,6 +2419,12 @@
     uint32_t dataLength;
 
     /**
+     *  The offset in the memory block which is shared among multiple
+     *  MediaEvents.
+     */
+    uint32_t offset;
+
+    /**
      * A handle associated to the memory where audio or video data stays.
      */
     handle avMemory;
@@ -2409,6 +2435,12 @@
     bool isSecureMemory;
 
     /**
+     * An Id is used by HAL to provide additional information for AV data.
+     * For secure audio, it's the audio handle used by Audio Track.
+     */
+    uint64_t avDataId;
+
+    /**
      * MPU sequence number of filtered data (only for MMTP)
      */
     uint32_t mpuSequenceNumber;
@@ -2448,16 +2480,17 @@
 struct DemuxFilterTsRecordEvent {
     DemuxPid pid;
 
+    bitfield<DemuxTsIndex> tsIndexMask;
+
     /**
      * Indexes of record output
      */
-    safe_union IndexMask {
-        bitfield<DemuxTsIndex> tsIndexMask;
+    safe_union ScIndexMask {
 
-        bitfield<DemuxScIndex> scIndexMask;
+        bitfield<DemuxScIndex> sc;
 
-        bitfield<DemuxScHevcIndex> scHevcIndexMask;
-    } indexMask;
+        bitfield<DemuxScHevcIndex> scHevc;
+    } scIndexMask;
 
     /**
      * Byte number from beginning of the filter's output
