diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index fde6b57..efdff2b 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -37,3 +37,40 @@
         "libutils",
     ],
 }
+
+cc_library {
+    name: "libkeymint_remote_prov_support",
+    vendor_available: true,
+    srcs: [
+        "remote_prov_utils.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    shared_libs: [
+        "libcppcose",
+        "libcppbor_external",
+        "libcrypto",
+    ],
+}
+
+cc_library {
+    name: "libcppcose",
+    vendor_available: true,
+    srcs: [
+        "cppcose.cpp",
+    ],
+    export_include_dirs: [
+        "include",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+        "libcppbor_external",
+        "libcrypto",
+        "liblog",
+    ],
+    static_libs: [
+        // TODO(swillden): Remove keymint NDK
+        "android.hardware.security.keymint-unstable-ndk_platform",
+    ],
+}
diff --git a/security/keymint/support/cppcose.cpp b/security/keymint/support/cppcose.cpp
new file mode 100644
index 0000000..c626ade
--- /dev/null
+++ b/security/keymint/support/cppcose.cpp
@@ -0,0 +1,467 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#include <cppcose/cppcose.h>
+
+#include <stdio.h>
+#include <iostream>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+#include <openssl/err.h>
+
+namespace cppcose {
+
+namespace {
+
+ErrMsgOr<bssl::UniquePtr<EVP_CIPHER_CTX>> aesGcmInitAndProcessAad(const bytevec& key,
+                                                                  const bytevec& nonce,
+                                                                  const bytevec& aad,
+                                                                  bool encrypt) {
+    if (key.size() != kAesGcmKeySize) return "Invalid key size";
+
+    bssl::UniquePtr<EVP_CIPHER_CTX> ctx(EVP_CIPHER_CTX_new());
+    if (!ctx) return "Failed to allocate cipher context";
+
+    if (!EVP_CipherInit_ex(ctx.get(), EVP_aes_256_gcm(), nullptr /* engine */, key.data(),
+                           nonce.data(), encrypt ? 1 : 0)) {
+        return "Failed to initialize cipher";
+    }
+
+    int outlen;
+    if (!aad.empty() && !EVP_CipherUpdate(ctx.get(), nullptr /* out; null means AAD */, &outlen,
+                                          aad.data(), aad.size())) {
+        return "Failed to process AAD";
+    }
+
+    return std::move(ctx);
+}
+
+}  // namespace
+
+ErrMsgOr<bytevec> generateCoseMac0Mac(const bytevec& macKey, const bytevec& externalAad,
+                                      const bytevec& payload) {
+    auto macStructure = cppbor::Array()
+                                .add("MAC0")
+                                .add(cppbor::Map().add(ALGORITHM, HMAC_256).canonicalize().encode())
+                                .add(externalAad)
+                                .add(payload)
+                                .encode();
+
+    bytevec macTag(SHA256_DIGEST_LENGTH);
+    uint8_t* out = macTag.data();
+    unsigned int outLen;
+    out = HMAC(EVP_sha256(),                              //
+               macKey.data(), macKey.size(),              //
+               macStructure.data(), macStructure.size(),  //
+               out, &outLen);
+
+    assert(out != nullptr && outLen == macTag.size());
+    if (out == nullptr || outLen != macTag.size()) {
+        return "Error computing public key MAC";
+    }
+
+    return macTag;
+}
+
+ErrMsgOr<cppbor::Array> constructCoseMac0(const bytevec& macKey, const bytevec& externalAad,
+                                          const bytevec& payload) {
+    auto tag = generateCoseMac0Mac(macKey, externalAad, payload);
+    if (!tag) return tag.moveMessage();
+
+    return cppbor::Array()
+            .add(cppbor::Map().add(ALGORITHM, HMAC_256).canonicalize().encode())
+            .add(cppbor::Bstr() /* unprotected */)
+            .add(payload)
+            .add(tag.moveValue());
+}
+
+ErrMsgOr<bytevec /* payload */> parseCoseMac0(const cppbor::Item* macItem) {
+    auto mac = macItem ? macItem->asArray() : nullptr;
+    if (!mac || mac->size() != kCoseMac0EntryCount) {
+        return "Invalid COSE_Mac0";
+    }
+
+    auto protectedParms = mac->get(kCoseMac0ProtectedParams)->asBstr();
+    auto unprotectedParms = mac->get(kCoseMac0UnprotectedParams)->asBstr();
+    auto payload = mac->get(kCoseMac0Payload)->asBstr();
+    auto tag = mac->get(kCoseMac0Tag)->asBstr();
+    if (!protectedParms || !unprotectedParms || !payload || !tag) {
+        return "Invalid COSE_Mac0 contents";
+    }
+
+    return payload->value();
+}
+
+ErrMsgOr<bytevec /* payload */> verifyAndParseCoseMac0(const cppbor::Item* macItem,
+                                                       const bytevec& macKey) {
+    auto mac = macItem ? macItem->asArray() : nullptr;
+    if (!mac || mac->size() != kCoseMac0EntryCount) {
+        return "Invalid COSE_Mac0";
+    }
+
+    auto protectedParms = mac->get(kCoseMac0ProtectedParams)->asBstr();
+    auto unprotectedParms = mac->get(kCoseMac0UnprotectedParams)->asBstr();
+    auto payload = mac->get(kCoseMac0Payload)->asBstr();
+    auto tag = mac->get(kCoseMac0Tag)->asBstr();
+    if (!protectedParms || !unprotectedParms || !payload || !tag) {
+        return "Invalid COSE_Mac0 contents";
+    }
+
+    auto [protectedMap, _, errMsg] = cppbor::parse(protectedParms);
+    if (!protectedMap || !protectedMap->asMap()) {
+        return "Invalid Mac0 protected: " + errMsg;
+    }
+    auto& algo = protectedMap->asMap()->get(ALGORITHM);
+    if (!algo || !algo->asInt() || algo->asInt()->value() != HMAC_256) {
+        return "Unsupported Mac0 algorithm";
+    }
+
+    auto macTag = generateCoseMac0Mac(macKey, {} /* external_aad */, payload->value());
+    if (!macTag) return macTag.moveMessage();
+
+    if (macTag->size() != tag->value().size() ||
+        CRYPTO_memcmp(macTag->data(), tag->value().data(), macTag->size()) != 0) {
+        return "MAC tag mismatch";
+    }
+
+    return payload->value();
+}
+
+ErrMsgOr<bytevec> createCoseSign1Signature(const bytevec& key, const bytevec& protectedParams,
+                                           const bytevec& payload, const bytevec& aad) {
+    bytevec signatureInput = cppbor::Array()
+                                     .add("Signature1")  //
+                                     .add(protectedParams)
+                                     .add(aad)
+                                     .add(payload)
+                                     .encode();
+
+    if (key.size() != ED25519_PRIVATE_KEY_LEN) return "Invalid signing key";
+    bytevec signature(ED25519_SIGNATURE_LEN);
+    if (!ED25519_sign(signature.data(), signatureInput.data(), signatureInput.size(), key.data())) {
+        return "Signing failed";
+    }
+
+    return signature;
+}
+
+ErrMsgOr<cppbor::Array> constructCoseSign1(const bytevec& key, cppbor::Map protectedParams,
+                                           const bytevec& payload, const bytevec& aad) {
+    bytevec protParms = protectedParams.add(ALGORITHM, EDDSA).canonicalize().encode();
+    auto signature = createCoseSign1Signature(key, protParms, payload, aad);
+    if (!signature) return signature.moveMessage();
+
+    return cppbor::Array()
+            .add(protParms)
+            .add(bytevec{} /* unprotected parameters */)
+            .add(payload)
+            .add(*signature);
+}
+
+ErrMsgOr<cppbor::Array> constructCoseSign1(const bytevec& key, const bytevec& payload,
+                                           const bytevec& aad) {
+    return constructCoseSign1(key, {} /* protectedParams */, payload, aad);
+}
+
+ErrMsgOr<bytevec> verifyAndParseCoseSign1(bool ignoreSignature, const cppbor::Array* coseSign1,
+                                          const bytevec& signingCoseKey, const bytevec& aad) {
+    if (!coseSign1 || coseSign1->size() != kCoseSign1EntryCount) {
+        return "Invalid COSE_Sign1";
+    }
+
+    const cppbor::Bstr* protectedParams = coseSign1->get(kCoseSign1ProtectedParams)->asBstr();
+    const cppbor::Bstr* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asBstr();
+    const cppbor::Bstr* payload = coseSign1->get(kCoseSign1Payload)->asBstr();
+    const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
+
+    if (!protectedParams || !unprotectedParams || !payload || !signature) {
+        return "Invalid COSE_Sign1";
+    }
+
+    auto [parsedProtParams, _, errMsg] = cppbor::parse(protectedParams);
+    if (!parsedProtParams) {
+        return errMsg + " when parsing protected params.";
+    }
+    if (!parsedProtParams->asMap()) {
+        return "Protected params must be a map";
+    }
+
+    auto& algorithm = parsedProtParams->asMap()->get(ALGORITHM);
+    if (!algorithm || !algorithm->asInt() || algorithm->asInt()->value() != EDDSA) {
+        return "Unsupported signature algorithm";
+    }
+
+    if (!ignoreSignature) {
+        bool selfSigned = signingCoseKey.empty();
+        auto key = CoseKey::parseEd25519(selfSigned ? payload->value() : signingCoseKey);
+        if (!key) return "Bad signing key: " + key.moveMessage();
+
+        bytevec signatureInput = cppbor::Array()
+                                         .add("Signature1")
+                                         .add(*protectedParams)
+                                         .add(aad)
+                                         .add(*payload)
+                                         .encode();
+
+        if (!ED25519_verify(signatureInput.data(), signatureInput.size(), signature->value().data(),
+                            key->getBstrValue(CoseKey::PUBKEY_X)->data())) {
+            return "Signature verification failed";
+        }
+    }
+
+    return payload->value();
+}
+
+ErrMsgOr<bytevec> createCoseEncryptCiphertext(const bytevec& key, const bytevec& nonce,
+                                              const bytevec& protectedParams,
+                                              const bytevec& plaintextPayload, const bytevec& aad) {
+    auto ciphertext = aesGcmEncrypt(key, nonce,
+                                    cppbor::Array()                // Enc strucure as AAD
+                                            .add("Encrypt")        // Context
+                                            .add(protectedParams)  // Protected
+                                            .add(aad)              // External AAD
+                                            .encode(),
+                                    plaintextPayload);
+
+    if (!ciphertext) return ciphertext.moveMessage();
+    return ciphertext.moveValue();
+}
+
+ErrMsgOr<cppbor::Array> constructCoseEncrypt(const bytevec& key, const bytevec& nonce,
+                                             const bytevec& plaintextPayload, const bytevec& aad,
+                                             cppbor::Array recipients) {
+    auto encryptProtectedHeader = cppbor::Map()  //
+                                          .add(ALGORITHM, AES_GCM_256)
+                                          .canonicalize()
+                                          .encode();
+
+    auto ciphertext =
+            createCoseEncryptCiphertext(key, nonce, encryptProtectedHeader, plaintextPayload, aad);
+    if (!ciphertext) return ciphertext.moveMessage();
+
+    return cppbor::Array()
+            .add(encryptProtectedHeader)                       // Protected
+            .add(cppbor::Map().add(IV, nonce).canonicalize())  // Unprotected
+            .add(*ciphertext)                                  // Payload
+            .add(std::move(recipients));
+}
+
+ErrMsgOr<std::pair<bytevec /* pubkey */, bytevec /* key ID */>> getSenderPubKeyFromCoseEncrypt(
+        const cppbor::Item* coseEncrypt) {
+    if (!coseEncrypt || !coseEncrypt->asArray() ||
+        coseEncrypt->asArray()->size() != kCoseEncryptEntryCount) {
+        return "Invalid COSE_Encrypt";
+    }
+
+    auto& recipients = coseEncrypt->asArray()->get(kCoseEncryptRecipients);
+    if (!recipients || !recipients->asArray() || recipients->asArray()->size() != 1) {
+        return "Invalid recipients list";
+    }
+
+    auto& recipient = recipients->asArray()->get(0);
+    if (!recipient || !recipient->asArray() || recipient->asArray()->size() != 3) {
+        return "Invalid COSE_recipient";
+    }
+
+    auto& ciphertext = recipient->asArray()->get(2);
+    if (!ciphertext->asSimple() || !ciphertext->asSimple()->asNull()) {
+        return "Unexpected value in recipients ciphertext field " +
+               cppbor::prettyPrint(ciphertext.get());
+    }
+
+    auto& protParms = recipient->asArray()->get(0);
+    if (!protParms || !protParms->asBstr()) return "Invalid protected params";
+    auto [parsedProtParms, _, errMsg] = cppbor::parse(protParms->asBstr());
+    if (!parsedProtParms) return "Failed to parse protected params: " + errMsg;
+    if (!parsedProtParms->asMap()) return "Invalid protected params";
+
+    auto& algorithm = parsedProtParms->asMap()->get(ALGORITHM);
+    if (!algorithm || !algorithm->asInt() || algorithm->asInt()->value() != ECDH_ES_HKDF_256) {
+        return "Invalid algorithm";
+    }
+
+    auto& unprotParms = recipient->asArray()->get(1);
+    if (!unprotParms || !unprotParms->asMap()) return "Invalid unprotected params";
+
+    auto& senderCoseKey = unprotParms->asMap()->get(COSE_KEY);
+    if (!senderCoseKey || !senderCoseKey->asMap()) return "Invalid sender COSE_Key";
+
+    auto& keyType = senderCoseKey->asMap()->get(CoseKey::KEY_TYPE);
+    if (!keyType || !keyType->asInt() || keyType->asInt()->value() != OCTET_KEY_PAIR) {
+        return "Invalid key type";
+    }
+
+    auto& curve = senderCoseKey->asMap()->get(CoseKey::CURVE);
+    if (!curve || !curve->asInt() || curve->asInt()->value() != X25519) {
+        return "Unsupported curve";
+    }
+
+    auto& pubkey = senderCoseKey->asMap()->get(CoseKey::PUBKEY_X);
+    if (!pubkey || !pubkey->asBstr() ||
+        pubkey->asBstr()->value().size() != X25519_PUBLIC_VALUE_LEN) {
+        return "Invalid X25519 public key";
+    }
+
+    auto& key_id = unprotParms->asMap()->get(KEY_ID);
+    if (key_id && key_id->asBstr()) {
+        return std::make_pair(pubkey->asBstr()->value(), key_id->asBstr()->value());
+    }
+
+    // If no key ID, just return an empty vector.
+    return std::make_pair(pubkey->asBstr()->value(), bytevec{});
+}
+
+ErrMsgOr<bytevec> decryptCoseEncrypt(const bytevec& key, const cppbor::Item* coseEncrypt,
+                                     const bytevec& external_aad) {
+    if (!coseEncrypt || !coseEncrypt->asArray() ||
+        coseEncrypt->asArray()->size() != kCoseEncryptEntryCount) {
+        return "Invalid COSE_Encrypt";
+    }
+
+    auto& protParms = coseEncrypt->asArray()->get(kCoseEncryptProtectedParams);
+    auto& unprotParms = coseEncrypt->asArray()->get(kCoseEncryptUnprotectedParams);
+    auto& ciphertext = coseEncrypt->asArray()->get(kCoseEncryptPayload);
+    auto& recipients = coseEncrypt->asArray()->get(kCoseEncryptRecipients);
+
+    if (!protParms || !protParms->asBstr() || !unprotParms || !ciphertext || !recipients) {
+        return "Invalid COSE_Encrypt";
+    }
+
+    auto [parsedProtParams, _, errMsg] = cppbor::parse(protParms->asBstr()->value());
+    if (!parsedProtParams) {
+        return errMsg + " when parsing protected params.";
+    }
+    if (!parsedProtParams->asMap()) {
+        return "Protected params must be a map";
+    }
+
+    auto& algorithm = parsedProtParams->asMap()->get(ALGORITHM);
+    if (!algorithm || !algorithm->asInt() || algorithm->asInt()->value() != AES_GCM_256) {
+        return "Unsupported encryption algorithm";
+    }
+
+    if (!unprotParms->asMap() || unprotParms->asMap()->size() != 1) {
+        return "Invalid unprotected params";
+    }
+
+    auto& nonce = unprotParms->asMap()->get(IV);
+    if (!nonce || !nonce->asBstr() || nonce->asBstr()->value().size() != kAesGcmNonceLength) {
+        return "Invalid nonce";
+    }
+
+    if (!ciphertext->asBstr()) return "Invalid ciphertext";
+
+    auto aad = cppbor::Array()                             // Enc strucure as AAD
+                       .add("Encrypt")                     // Context
+                       .add(protParms->asBstr()->value())  // Protected
+                       .add(external_aad)                  // External AAD
+                       .encode();
+
+    return aesGcmDecrypt(key, nonce->asBstr()->value(), aad, ciphertext->asBstr()->value());
+}
+
+ErrMsgOr<bytevec> x25519_HKDF_DeriveKey(const bytevec& pubKeyA, const bytevec& privKeyA,
+                                        const bytevec& pubKeyB, bool senderIsA) {
+    bytevec rawSharedKey(X25519_SHARED_KEY_LEN);
+    if (!::X25519(rawSharedKey.data(), privKeyA.data(), pubKeyB.data())) {
+        return "ECDH operation failed";
+    }
+
+    bytevec kdfContext = cppbor::Array()
+                                 .add(AES_GCM_256)
+                                 .add(cppbor::Array()  // Sender Info
+                                              .add(cppbor::Bstr("client"))
+                                              .add(bytevec{} /* nonce */)
+                                              .add(senderIsA ? pubKeyA : pubKeyB))
+                                 .add(cppbor::Array()  // Recipient Info
+                                              .add(cppbor::Bstr("server"))
+                                              .add(bytevec{} /* nonce */)
+                                              .add(senderIsA ? pubKeyB : pubKeyA))
+                                 .add(cppbor::Array()           // SuppPubInfo
+                                              .add(128)         // output key length
+                                              .add(bytevec{}))  // protected
+                                 .encode();
+
+    bytevec retval(SHA256_DIGEST_LENGTH);
+    bytevec salt{};
+    if (!HKDF(retval.data(), retval.size(),              //
+              EVP_sha256(),                              //
+              rawSharedKey.data(), rawSharedKey.size(),  //
+              salt.data(), salt.size(),                  //
+              kdfContext.data(), kdfContext.size())) {
+        return "ECDH HKDF failed";
+    }
+
+    return retval;
+}
+
+ErrMsgOr<bytevec> aesGcmEncrypt(const bytevec& key, const bytevec& nonce, const bytevec& aad,
+                                const bytevec& plaintext) {
+    auto ctx = aesGcmInitAndProcessAad(key, nonce, aad, true /* encrypt */);
+    if (!ctx) return ctx.moveMessage();
+
+    bytevec ciphertext(plaintext.size() + kAesGcmTagSize);
+    int outlen;
+    if (!EVP_CipherUpdate(ctx->get(), ciphertext.data(), &outlen, plaintext.data(),
+                          plaintext.size())) {
+        return "Failed to encrypt plaintext";
+    }
+    assert(plaintext.size() == outlen);
+
+    if (!EVP_CipherFinal_ex(ctx->get(), ciphertext.data() + outlen, &outlen)) {
+        return "Failed to finalize encryption";
+    }
+    assert(outlen == 0);
+
+    if (!EVP_CIPHER_CTX_ctrl(ctx->get(), EVP_CTRL_GCM_GET_TAG, kAesGcmTagSize,
+                             ciphertext.data() + plaintext.size())) {
+        return "Failed to retrieve tag";
+    }
+
+    return ciphertext;
+}
+
+ErrMsgOr<bytevec> aesGcmDecrypt(const bytevec& key, const bytevec& nonce, const bytevec& aad,
+                                const bytevec& ciphertextWithTag) {
+    auto ctx = aesGcmInitAndProcessAad(key, nonce, aad, false /* encrypt */);
+    if (!ctx) return ctx.moveMessage();
+
+    if (ciphertextWithTag.size() < kAesGcmTagSize) return "Missing tag";
+
+    bytevec plaintext(ciphertextWithTag.size() - kAesGcmTagSize);
+    int outlen;
+    if (!EVP_CipherUpdate(ctx->get(), plaintext.data(), &outlen, ciphertextWithTag.data(),
+                          ciphertextWithTag.size() - kAesGcmTagSize)) {
+        return "Failed to decrypt plaintext";
+    }
+    assert(plaintext.size() == outlen);
+
+    bytevec tag(ciphertextWithTag.end() - kAesGcmTagSize, ciphertextWithTag.end());
+    if (!EVP_CIPHER_CTX_ctrl(ctx->get(), EVP_CTRL_GCM_SET_TAG, kAesGcmTagSize, tag.data())) {
+        return "Failed to set tag: " + std::to_string(ERR_peek_last_error());
+    }
+
+    if (!EVP_CipherFinal_ex(ctx->get(), nullptr, &outlen)) {
+        return "Failed to finalize encryption";
+    }
+    assert(outlen == 0);
+
+    return plaintext;
+}
+
+}  // namespace cppcose
diff --git a/security/keymint/support/include/cppcose/cppcose.h b/security/keymint/support/include/cppcose/cppcose.h
new file mode 100644
index 0000000..a936bfd
--- /dev/null
+++ b/security/keymint/support/include/cppcose/cppcose.h
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#pragma once
+
+#include <memory>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include <cppbor.h>
+#include <cppbor_parse.h>
+
+#include <openssl/cipher.h>
+#include <openssl/curve25519.h>
+#include <openssl/digest.h>
+#include <openssl/hkdf.h>
+#include <openssl/hmac.h>
+#include <openssl/mem.h>
+#include <openssl/sha.h>
+
+namespace cppcose {
+
+using bytevec = std::vector<uint8_t>;
+
+constexpr int kCoseSign1EntryCount = 4;
+constexpr int kCoseSign1ProtectedParams = 0;
+constexpr int kCoseSign1UnprotectedParams = 1;
+constexpr int kCoseSign1Payload = 2;
+constexpr int kCoseSign1Signature = 3;
+
+constexpr int kCoseMac0EntryCount = 4;
+constexpr int kCoseMac0ProtectedParams = 0;
+constexpr int kCoseMac0UnprotectedParams = 1;
+constexpr int kCoseMac0Payload = 2;
+constexpr int kCoseMac0Tag = 3;
+
+constexpr int kCoseEncryptEntryCount = 4;
+constexpr int kCoseEncryptProtectedParams = 0;
+constexpr int kCoseEncryptUnprotectedParams = 1;
+constexpr int kCoseEncryptPayload = 2;
+constexpr int kCoseEncryptRecipients = 3;
+
+enum Label : int {
+    ALGORITHM = 1,
+    KEY_ID = 4,
+    IV = 5,
+    COSE_KEY = -1,
+};
+
+enum CoseKeyAlgorithm : int {
+    AES_GCM_256 = 3,
+    HMAC_256 = 5,
+    ES256 = -7,  // ECDSA with SHA-256
+    EDDSA = -8,
+    ECDH_ES_HKDF_256 = -25,
+};
+
+enum CoseKeyCurve : int { P256 = 1, X25519 = 4, ED25519 = 6 };
+enum CoseKeyType : int { OCTET_KEY_PAIR = 1, EC2 = 2, SYMMETRIC_KEY = 4 };
+enum CoseKeyOps : int { SIGN = 1, VERIFY = 2, ENCRYPT = 3, DECRYPT = 4 };
+
+constexpr int kAesGcmNonceLength = 12;
+constexpr int kAesGcmTagSize = 16;
+constexpr int kAesGcmKeySize = 32;
+
+template <typename T>
+class ErrMsgOr {
+  public:
+    ErrMsgOr(std::string errMsg) : errMsg_(std::move(errMsg)) {}
+    ErrMsgOr(const char* errMsg) : errMsg_(errMsg) {}
+    ErrMsgOr(T val) : value_(std::move(val)) {}
+
+    operator bool() const { return value_.has_value(); }
+
+    T* operator->() & {
+        assert(value_);
+        return &value_.value();
+    }
+    T& operator*() & {
+        assert(value_);
+        return value_.value();
+    };
+    T&& operator*() && {
+        assert(value_);
+        return std::move(value_).value();
+    };
+
+    const std::string& message() { return errMsg_; }
+    std::string moveMessage() { return std::move(errMsg_); }
+
+    T moveValue() {
+        assert(value_);
+        return std::move(value_).value();
+    }
+
+  private:
+    std::string errMsg_;
+    std::optional<T> value_;
+};
+
+class CoseKey {
+  public:
+    CoseKey() {}
+    CoseKey(const CoseKey&) = delete;
+    CoseKey(CoseKey&&) = default;
+
+    enum Label : int {
+        KEY_TYPE = 1,
+        KEY_ID = 2,
+        ALGORITHM = 3,
+        KEY_OPS = 4,
+        CURVE = -1,
+        PUBKEY_X = -2,
+        PUBKEY_Y = -3,
+        PRIVATE_KEY = -4,
+        TEST_KEY = -70000  // Application-defined
+    };
+
+    static ErrMsgOr<CoseKey> parse(const bytevec& coseKey) {
+        auto [parsedKey, _, errMsg] = cppbor::parse(coseKey);
+        if (!parsedKey) return errMsg + " when parsing key";
+        if (!parsedKey->asMap()) return "CoseKey must be a map";
+        return CoseKey(static_cast<cppbor::Map*>(parsedKey.release()));
+    }
+
+    static ErrMsgOr<CoseKey> parse(const bytevec& coseKey, CoseKeyType expectedKeyType,
+                                   CoseKeyAlgorithm expectedAlgorithm, CoseKeyCurve expectedCurve) {
+        auto key = parse(coseKey);
+        if (!key) return key;
+
+        if (!key->checkIntValue(CoseKey::KEY_TYPE, expectedKeyType) ||
+            !key->checkIntValue(CoseKey::ALGORITHM, expectedAlgorithm) ||
+            !key->checkIntValue(CoseKey::CURVE, expectedCurve)) {
+            return "Unexpected key type:";
+        }
+
+        return key;
+    }
+
+    static ErrMsgOr<CoseKey> parseEd25519(const bytevec& coseKey) {
+        auto key = parse(coseKey, OCTET_KEY_PAIR, EDDSA, ED25519);
+        if (!key) return key;
+
+        auto& pubkey = key->getMap().get(PUBKEY_X);
+        if (!pubkey || !pubkey->asBstr() ||
+            pubkey->asBstr()->value().size() != ED25519_PUBLIC_KEY_LEN) {
+            return "Invalid Ed25519 public key";
+        }
+
+        return key;
+    }
+
+    static ErrMsgOr<CoseKey> parseX25519(const bytevec& coseKey, bool requireKid) {
+        auto key = parse(coseKey, OCTET_KEY_PAIR, ECDH_ES_HKDF_256, X25519);
+        if (!key) return key;
+
+        auto& pubkey = key->getMap().get(PUBKEY_X);
+        if (!pubkey || !pubkey->asBstr() ||
+            pubkey->asBstr()->value().size() != X25519_PUBLIC_VALUE_LEN) {
+            return "Invalid X25519 public key";
+        }
+
+        auto& kid = key->getMap().get(KEY_ID);
+        if (requireKid && (!kid || !kid->asBstr())) {
+            return "Missing KID";
+        }
+
+        return key;
+    }
+
+    static ErrMsgOr<CoseKey> parseP256(const bytevec& coseKey) {
+        auto key = parse(coseKey, EC2, ES256, P256);
+        if (!key) return key;
+
+        auto& pubkey_x = key->getMap().get(PUBKEY_X);
+        auto& pubkey_y = key->getMap().get(PUBKEY_Y);
+        if (!pubkey_x || !pubkey_y || !pubkey_x->asBstr() || !pubkey_y->asBstr() ||
+            pubkey_x->asBstr()->value().size() != 32 || pubkey_y->asBstr()->value().size() != 32) {
+            return "Invalid P256 public key";
+        }
+
+        return key;
+    }
+
+    std::optional<int> getIntValue(Label label) {
+        const auto& value = key_->get(label);
+        if (!value || !value->asInt()) return {};
+        return value->asInt()->value();
+    }
+
+    std::optional<bytevec> getBstrValue(Label label) {
+        const auto& value = key_->get(label);
+        if (!value || !value->asBstr()) return {};
+        return value->asBstr()->value();
+    }
+
+    const cppbor::Map& getMap() const { return *key_; }
+    cppbor::Map&& moveMap() { return std::move(*key_); }
+
+    bool checkIntValue(Label label, int expectedValue) {
+        const auto& value = key_->get(label);
+        return value && value->asInt() && value->asInt()->value() == expectedValue;
+    }
+
+    void add(Label label, int value) { key_->add(label, value); }
+    void add(Label label, bytevec value) { key_->add(label, std::move(value)); }
+
+    bytevec encode() { return key_->canonicalize().encode(); }
+
+  private:
+    CoseKey(cppbor::Map* parsedKey) : key_(parsedKey) {}
+
+    // This is the full parsed key structure.
+    std::unique_ptr<cppbor::Map> key_;
+};
+
+ErrMsgOr<bytevec> generateCoseMac0Mac(const bytevec& macKey, const bytevec& externalAad,
+                                      const bytevec& payload);
+ErrMsgOr<cppbor::Array> constructCoseMac0(const bytevec& macKey, const bytevec& externalAad,
+                                          const bytevec& payload);
+ErrMsgOr<bytevec /* payload */> parseCoseMac0(const cppbor::Item* macItem);
+ErrMsgOr<bytevec /* payload */> verifyAndParseCoseMac0(const cppbor::Item* macItem,
+                                                       const bytevec& macKey);
+
+ErrMsgOr<bytevec> createCoseSign1Signature(const bytevec& key, const bytevec& protectedParams,
+                                           const bytevec& payload, const bytevec& aad);
+ErrMsgOr<cppbor::Array> constructCoseSign1(const bytevec& key, const bytevec& payload,
+                                           const bytevec& aad);
+ErrMsgOr<cppbor::Array> constructCoseSign1(const bytevec& key, cppbor::Map extraProtectedFields,
+                                           const bytevec& payload, const bytevec& aad);
+/**
+ * Verify and parse a COSE_Sign1 message, returning the payload.
+ *
+ * @param ignoreSignature indicates whether signature verification should be skipped.  If true, no
+ *        verification of the signature will be done.
+ *
+ * @param coseSign1 is the COSE_Sign1 to verify and parse.
+ *
+ * @param signingCoseKey is a CBOR-encoded COSE_Key to use to verify the signature.  The bytevec may
+ *        be empty, in which case the function assumes that coseSign1's payload is the COSE_Key to
+ *        use, i.e. that coseSign1 is a self-signed "certificate".
+ */
+ErrMsgOr<bytevec /* payload */> verifyAndParseCoseSign1(bool ignoreSignature,
+                                                        const cppbor::Array* coseSign1,
+                                                        const bytevec& signingCoseKey,
+                                                        const bytevec& aad);
+
+ErrMsgOr<bytevec> createCoseEncryptCiphertext(const bytevec& key, const bytevec& nonce,
+                                              const bytevec& protectedParams, const bytevec& aad);
+ErrMsgOr<cppbor::Array> constructCoseEncrypt(const bytevec& key, const bytevec& nonce,
+                                             const bytevec& plaintextPayload, const bytevec& aad,
+                                             cppbor::Array recipients);
+ErrMsgOr<std::pair<bytevec /* pubkey */, bytevec /* key ID */>> getSenderPubKeyFromCoseEncrypt(
+        const cppbor::Item* encryptItem);
+inline ErrMsgOr<std::pair<bytevec /* pubkey */, bytevec /* key ID */>>
+getSenderPubKeyFromCoseEncrypt(const std::unique_ptr<cppbor::Item>& encryptItem) {
+    return getSenderPubKeyFromCoseEncrypt(encryptItem.get());
+}
+
+ErrMsgOr<bytevec /* plaintextPayload */> decryptCoseEncrypt(const bytevec& key,
+                                                            const cppbor::Item* encryptItem,
+                                                            const bytevec& aad);
+
+ErrMsgOr<bytevec> x25519_HKDF_DeriveKey(const bytevec& senderPubKey, const bytevec& senderPrivKey,
+                                        const bytevec& recipientPubKey, bool senderIsA);
+
+ErrMsgOr<bytevec /* ciphertextWithTag */> aesGcmEncrypt(const bytevec& key, const bytevec& nonce,
+                                                        const bytevec& aad,
+                                                        const bytevec& plaintext);
+ErrMsgOr<bytevec /* plaintext */> aesGcmDecrypt(const bytevec& key, const bytevec& nonce,
+                                                const bytevec& aad,
+                                                const bytevec& ciphertextWithTag);
+
+}  // namespace cppcose
diff --git a/security/keymint/support/include/remote_prov/remote_prov_utils.h b/security/keymint/support/include/remote_prov/remote_prov_utils.h
new file mode 100644
index 0000000..5e205a2
--- /dev/null
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -0,0 +1,60 @@
+/*
+ * 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 <vector>
+
+#include <cppcose/cppcose.h>
+
+namespace aidl::android::hardware::security::keymint::remote_prov {
+
+using bytevec = std::vector<uint8_t>;
+using namespace cppcose;
+
+extern bytevec kTestMacKey;
+
+/**
+ * Generates random bytes.
+ */
+bytevec randomBytes(size_t numBytes);
+
+struct EekChain {
+    bytevec chain;
+    bytevec last_pubkey;
+    bytevec last_privkey;
+};
+
+/**
+ * Generates an X25518 EEK with the specified eekId and an Ed25519 chain of the
+ * specified length. All keys are generated randomly.
+ */
+ErrMsgOr<EekChain> generateEekChain(size_t length, const bytevec& eekId);
+
+struct BccEntryData {
+    bytevec pubKey;
+};
+
+/**
+ * Validates the provided CBOR-encoded BCC, returning a vector of BccEntryData
+ * structs containing the BCC entry contents.  If an entry contains no firmware
+ * digest, the corresponding BccEntryData.firmwareDigest will have length zero
+ * (there's no way to distinguish between an empty and missing firmware digest,
+ * which seems fine).
+ */
+ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc);
+
+}  // namespace aidl::android::hardware::security::keymint::remote_prov
diff --git a/security/keymint/support/remote_prov_utils.cpp b/security/keymint/support/remote_prov_utils.cpp
new file mode 100644
index 0000000..111cb30
--- /dev/null
+++ b/security/keymint/support/remote_prov_utils.cpp
@@ -0,0 +1,169 @@
+/*
+ * 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 <remote_prov/remote_prov_utils.h>
+
+#include <openssl/rand.h>
+
+#include <cppbor.h>
+
+namespace aidl::android::hardware::security::keymint::remote_prov {
+
+bytevec kTestMacKey(32 /* count */, 0 /* byte value */);
+
+bytevec randomBytes(size_t numBytes) {
+    bytevec retval(numBytes);
+    RAND_bytes(retval.data(), numBytes);
+    return retval;
+}
+
+ErrMsgOr<EekChain> generateEekChain(size_t length, const bytevec& eekId) {
+    auto eekChain = cppbor::Array();
+
+    bytevec prev_priv_key;
+    for (size_t i = 0; i < length - 1; ++i) {
+        bytevec pub_key(ED25519_PUBLIC_KEY_LEN);
+        bytevec priv_key(ED25519_PRIVATE_KEY_LEN);
+
+        ED25519_keypair(pub_key.data(), priv_key.data());
+
+        // The first signing key is self-signed.
+        if (prev_priv_key.empty()) prev_priv_key = priv_key;
+
+        auto coseSign1 = constructCoseSign1(prev_priv_key,
+                                            cppbor::Map() /* payload CoseKey */
+                                                    .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
+                                                    .add(CoseKey::ALGORITHM, EDDSA)
+                                                    .add(CoseKey::CURVE, ED25519)
+                                                    .add(CoseKey::PUBKEY_X, pub_key)
+                                                    .canonicalize()
+                                                    .encode(),
+                                            {} /* AAD */);
+        if (!coseSign1) return coseSign1.moveMessage();
+        eekChain.add(coseSign1.moveValue());
+    }
+
+    bytevec pub_key(X25519_PUBLIC_VALUE_LEN);
+    bytevec priv_key(X25519_PRIVATE_KEY_LEN);
+    X25519_keypair(pub_key.data(), priv_key.data());
+
+    auto coseSign1 = constructCoseSign1(prev_priv_key,
+                                        cppbor::Map() /* payload CoseKey */
+                                                .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
+                                                .add(CoseKey::KEY_ID, eekId)
+                                                .add(CoseKey::ALGORITHM, ECDH_ES_HKDF_256)
+                                                .add(CoseKey::CURVE, cppcose::X25519)
+                                                .add(CoseKey::PUBKEY_X, pub_key)
+                                                .canonicalize()
+                                                .encode(),
+                                        {} /* AAD */);
+    if (!coseSign1) return coseSign1.moveMessage();
+    eekChain.add(coseSign1.moveValue());
+
+    return EekChain{eekChain.encode(), pub_key, priv_key};
+}
+
+ErrMsgOr<bytevec> verifyAndParseCoseSign1Cwt(bool ignoreSignature, const cppbor::Array* coseSign1,
+                                             const bytevec& signingCoseKey, const bytevec& aad) {
+    if (!coseSign1 || coseSign1->size() != kCoseSign1EntryCount) {
+        return "Invalid COSE_Sign1";
+    }
+
+    const cppbor::Bstr* protectedParams = coseSign1->get(kCoseSign1ProtectedParams)->asBstr();
+    const cppbor::Bstr* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asBstr();
+    const cppbor::Bstr* payload = coseSign1->get(kCoseSign1Payload)->asBstr();
+    const cppbor::Bstr* signature = coseSign1->get(kCoseSign1Signature)->asBstr();
+
+    if (!protectedParams || !unprotectedParams || !payload || !signature) {
+        return "Invalid COSE_Sign1";
+    }
+
+    auto [parsedProtParams, _, errMsg] = cppbor::parse(protectedParams);
+    if (!parsedProtParams) {
+        return errMsg + " when parsing protected params.";
+    }
+    if (!parsedProtParams->asMap()) {
+        return "Protected params must be a map";
+    }
+
+    auto& algorithm = parsedProtParams->asMap()->get(ALGORITHM);
+    if (!algorithm || !algorithm->asInt() || algorithm->asInt()->value() != EDDSA) {
+        return "Unsupported signature algorithm";
+    }
+
+    // TODO(jbires): Handle CWTs as the CoseSign1 payload in a less hacky way. Since the CWT payload
+    //               is extremely remote provisioning specific, probably just make a separate
+    //               function there.
+    auto [parsedPayload, __, payloadErrMsg] = cppbor::parse(payload);
+    if (!parsedPayload) return payloadErrMsg + " when parsing key";
+    if (!parsedPayload->asMap()) return "CWT must be a map";
+    auto serializedKey = parsedPayload->asMap()->get(-4670552)->clone();
+    if (!serializedKey || !serializedKey->asBstr()) return "Could not find key entry";
+
+    if (!ignoreSignature) {
+        bool selfSigned = signingCoseKey.empty();
+        auto key = CoseKey::parseEd25519(selfSigned ? serializedKey->asBstr()->value()
+                                                    : signingCoseKey);
+        if (!key) return "Bad signing key: " + key.moveMessage();
+
+        bytevec signatureInput = cppbor::Array()
+                                         .add("Signature1")
+                                         .add(*protectedParams)
+                                         .add(aad)
+                                         .add(*payload)
+                                         .encode();
+
+        if (!ED25519_verify(signatureInput.data(), signatureInput.size(), signature->value().data(),
+                            key->getBstrValue(CoseKey::PUBKEY_X)->data())) {
+            return "Signature verification failed";
+        }
+    }
+
+    return serializedKey->asBstr()->value();
+}
+ErrMsgOr<std::vector<BccEntryData>> validateBcc(const cppbor::Array* bcc) {
+    if (!bcc || bcc->size() == 0) return "Invalid BCC";
+
+    std::vector<BccEntryData> result;
+
+    bytevec prevKey;
+    // TODO(jbires): Actually process the pubKey at the start of the new bcc entry
+    for (size_t i = 1; i < bcc->size(); ++i) {
+        const cppbor::Array* entry = bcc->get(i)->asArray();
+        if (!entry || entry->size() != kCoseSign1EntryCount) {
+            return "Invalid BCC entry " + std::to_string(i) + ": " + prettyPrint(entry);
+        }
+        auto payload = verifyAndParseCoseSign1Cwt(false /* ignoreSignature */, entry,
+                                                  std::move(prevKey), bytevec{} /* AAD */);
+        if (!payload) {
+            return "Failed to verify entry " + std::to_string(i) + ": " + payload.moveMessage();
+        }
+
+        auto& certProtParms = entry->get(kCoseSign1ProtectedParams);
+        if (!certProtParms || !certProtParms->asBstr()) return "Invalid prot params";
+        auto [parsedProtParms, _, errMsg] = cppbor::parse(certProtParms->asBstr()->value());
+        if (!parsedProtParms || !parsedProtParms->asMap()) return "Invalid prot params";
+
+        result.push_back(BccEntryData{*payload});
+
+        // This entry's public key is the signing key for the next entry.
+        prevKey = payload.moveValue();
+    }
+
+    return result;
+}
+
+}  // namespace aidl::android::hardware::security::keymint::remote_prov
