diff --git a/identity/aidl/default/Android.bp b/identity/aidl/default/Android.bp
index a124b1e..7c68aee 100644
--- a/identity/aidl/default/Android.bp
+++ b/identity/aidl/default/Android.bp
@@ -32,6 +32,7 @@
     static_libs: [
         "libbase",
         "libcppbor_external",
+        "libcppcose_rkp",
         "libutils",
         "libsoft_attestation_cert",
         "libkeymaster_portable",
@@ -92,6 +93,7 @@
     static_libs: [
         "libbase",
         "libcppbor_external",
+        "libcppcose_rkp",
         "libutils",
         "libsoft_attestation_cert",
         "libkeymaster_portable",
diff --git a/identity/aidl/vts/Android.bp b/identity/aidl/vts/Android.bp
index 3592d3e..61d15d2 100644
--- a/identity/aidl/vts/Android.bp
+++ b/identity/aidl/vts/Android.bp
@@ -35,6 +35,7 @@
     ],
     static_libs: [
         "libcppbor_external",
+        "libcppcose_rkp",
         "libkeymaster_portable",
         "libpuresoftkeymasterdevice",
         "android.hardware.keymaster@4.0",
diff --git a/identity/support/Android.bp b/identity/support/Android.bp
index 774bc40..db1a945 100644
--- a/identity/support/Android.bp
+++ b/identity/support/Android.bp
@@ -35,6 +35,7 @@
         "android.hardware.keymaster@4.0",
         "libcrypto",
         "libbase",
+        "libcppcose_rkp",
         "libhidlbase",
         "libhardware",
         "libkeymaster_portable",
diff --git a/security/keymint/aidl/default/Android.bp b/security/keymint/aidl/default/Android.bp
index ebdc9b7..1187717 100644
--- a/security/keymint/aidl/default/Android.bp
+++ b/security/keymint/aidl/default/Android.bp
@@ -62,7 +62,7 @@
         "android.hardware.security.keymint-V1-ndk_platform",
         "libbinder_ndk",
         "libcppbor_external",
-        "libcppcose",
+        "libcppcose_rkp",
         "libcrypto",
         "libkeymaster_portable",
         "libkeymint",
diff --git a/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp b/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
index 5b02729..6007663 100644
--- a/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
+++ b/security/keymint/aidl/default/RemotelyProvisionedComponent.cpp
@@ -23,7 +23,7 @@
 #include <cppbor_parse.h>
 
 #include <KeyMintUtils.h>
-#include <cppcose/cppcose.h>
+#include <keymaster/cppcose/cppcose.h>
 #include <keymaster/keymaster_configuration.h>
 #include <remote_prov/remote_prov_utils.h>
 
@@ -46,18 +46,8 @@
 
 namespace {
 
-// Hard-coded set of acceptable public keys that can act as roots of EEK chains.
-inline const vector<bytevec> kAuthorizedEekRoots = {
-        // TODO(drysdale): replace this random value with real root pubkey(s).
-        {0x5c, 0xea, 0x4b, 0xd2, 0x31, 0x27, 0x15, 0x5e, 0x62, 0x94, 0x70,
-         0x53, 0x94, 0x43, 0x0f, 0x9a, 0x89, 0xd5, 0xc5, 0x0f, 0x82, 0x9b,
-         0xcd, 0x10, 0xe0, 0x79, 0xef, 0xf3, 0xfa, 0x40, 0xeb, 0x0a},
-};
-
 constexpr auto STATUS_FAILED = RemotelyProvisionedComponent::STATUS_FAILED;
-constexpr auto STATUS_INVALID_EEK = RemotelyProvisionedComponent::STATUS_INVALID_EEK;
-constexpr auto STATUS_INVALID_MAC = RemotelyProvisionedComponent::STATUS_INVALID_MAC;
-constexpr uint32_t kAffinePointLength = 32;
+
 struct AStatusDeleter {
     void operator()(AStatus* p) { AStatus_delete(p); }
 };
@@ -125,167 +115,10 @@
     std::optional<T> value_;
 };
 
-StatusOr<std::pair<bytevec /* EEK pub */, bytevec /* EEK ID */>> validateAndExtractEekPubAndId(
-        bool testMode, const bytevec& endpointEncryptionCertChain) {
-    auto [item, newPos, errMsg] = cppbor::parse(endpointEncryptionCertChain);
-
-    if (!item || !item->asArray()) {
-        return Status("Error parsing EEK chain" + errMsg);
-    }
-
-    const cppbor::Array* certArr = item->asArray();
-    bytevec lastPubKey;
-    for (int i = 0; i < certArr->size(); ++i) {
-        auto cosePubKey = verifyAndParseCoseSign1(testMode, certArr->get(i)->asArray(),
-                                                  std::move(lastPubKey), bytevec{} /* AAD */);
-        if (!cosePubKey) {
-            return Status(STATUS_INVALID_EEK,
-                          "Failed to validate EEK chain: " + cosePubKey.moveMessage());
-        }
-        lastPubKey = *std::move(cosePubKey);
-
-        // In prod mode the first pubkey should match a well-known Google public key.
-        if (!testMode && i == 0 &&
-            std::find(kAuthorizedEekRoots.begin(), kAuthorizedEekRoots.end(), lastPubKey) ==
-                    kAuthorizedEekRoots.end()) {
-            return Status(STATUS_INVALID_EEK, "Unrecognized root of EEK chain");
-        }
-    }
-
-    auto eek = CoseKey::parseX25519(lastPubKey, true /* requireKid */);
-    if (!eek) return Status(STATUS_INVALID_EEK, "Failed to get EEK: " + eek.moveMessage());
-
-    return std::make_pair(eek->getBstrValue(CoseKey::PUBKEY_X).value(),
-                          eek->getBstrValue(CoseKey::KEY_ID).value());
-}
-
-StatusOr<bytevec /* pubkeys */> validateAndExtractPubkeys(bool testMode,
-                                                          const vector<MacedPublicKey>& keysToSign,
-                                                          const bytevec& macKey) {
-    auto pubKeysToMac = cppbor::Array();
-    for (auto& keyToSign : keysToSign) {
-        auto [macedKeyItem, _, coseMacErrMsg] = cppbor::parse(keyToSign.macedKey);
-        if (!macedKeyItem || !macedKeyItem->asArray() ||
-            macedKeyItem->asArray()->size() != kCoseMac0EntryCount) {
-            return Status("Invalid COSE_Mac0 structure");
-        }
-
-        auto protectedParms = macedKeyItem->asArray()->get(kCoseMac0ProtectedParams)->asBstr();
-        auto unprotectedParms = macedKeyItem->asArray()->get(kCoseMac0UnprotectedParams)->asMap();
-        auto payload = macedKeyItem->asArray()->get(kCoseMac0Payload)->asBstr();
-        auto tag = macedKeyItem->asArray()->get(kCoseMac0Tag)->asBstr();
-        if (!protectedParms || !unprotectedParms || !payload || !tag) {
-            return Status("Invalid COSE_Mac0 contents");
-        }
-
-        auto [protectedMap, __, errMsg] = cppbor::parse(protectedParms);
-        if (!protectedMap || !protectedMap->asMap()) {
-            return Status("Invalid Mac0 protected: " + errMsg);
-        }
-        auto& algo = protectedMap->asMap()->get(ALGORITHM);
-        if (!algo || !algo->asInt() || algo->asInt()->value() != HMAC_256) {
-            return Status("Unsupported Mac0 algorithm");
-        }
-
-        auto pubKey = CoseKey::parse(payload->value(), EC2, ES256, P256);
-        if (!pubKey) return Status(pubKey.moveMessage());
-
-        bool testKey = static_cast<bool>(pubKey->getMap().get(CoseKey::TEST_KEY));
-        if (testMode && !testKey) {
-            return Status(BnRemotelyProvisionedComponent::STATUS_PRODUCTION_KEY_IN_TEST_REQUEST,
-                          "Production key in test request");
-        } else if (!testMode && testKey) {
-            return Status(BnRemotelyProvisionedComponent::STATUS_TEST_KEY_IN_PRODUCTION_REQUEST,
-                          "Test key in production request");
-        }
-
-        auto macTag = generateCoseMac0Mac(macKey, {} /* external_aad */, payload->value());
-        if (!macTag) return Status(STATUS_INVALID_MAC, macTag.moveMessage());
-        if (macTag->size() != tag->value().size() ||
-            CRYPTO_memcmp(macTag->data(), tag->value().data(), macTag->size()) != 0) {
-            return Status(STATUS_INVALID_MAC, "MAC tag mismatch");
-        }
-
-        pubKeysToMac.add(pubKey->moveMap());
-    }
-
-    return pubKeysToMac.encode();
-}
-
-StatusOr<std::pair<bytevec, bytevec>> buildCosePublicKeyFromKmCert(
-        const keymaster_blob_t* km_cert) {
-    if (km_cert == nullptr) {
-        return Status(STATUS_FAILED, "km_cert is a nullptr");
-    }
-    const uint8_t* temp = km_cert->data;
-    X509* cert = d2i_X509(NULL, &temp, km_cert->data_length);
-    if (cert == nullptr) {
-        return Status(STATUS_FAILED, "d2i_X509 returned null when attempting to get the cert.");
-    }
-    EVP_PKEY* pubKey = X509_get_pubkey(cert);
-    if (pubKey == nullptr) {
-        return Status(STATUS_FAILED, "Boringssl failed to get the public key from the cert");
-    }
-    EC_KEY* ecKey = EVP_PKEY_get0_EC_KEY(pubKey);
-    if (ecKey == nullptr) {
-        return Status(STATUS_FAILED,
-                      "The key in the certificate returned from GenerateKey is not "
-                      "an EC key.");
-    }
-    const EC_POINT* jacobian_coords = EC_KEY_get0_public_key(ecKey);
-    BIGNUM x;
-    BIGNUM y;
-    BN_CTX* ctx = BN_CTX_new();
-    if (ctx == nullptr) {
-        return Status(STATUS_FAILED, "Memory allocation failure for BN_CTX");
-    }
-    if (!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ecKey), jacobian_coords, &x, &y,
-                                             ctx)) {
-        return Status(STATUS_FAILED, "Failed to get affine coordinates");
-    }
-    bytevec x_bytestring(kAffinePointLength);
-    bytevec y_bytestring(kAffinePointLength);
-    if (BN_bn2binpad(&x, x_bytestring.data(), kAffinePointLength) != kAffinePointLength) {
-        return Status(STATUS_FAILED, "Wrote incorrect number of bytes for x coordinate");
-    }
-    if (BN_bn2binpad(&y, y_bytestring.data(), kAffinePointLength) != kAffinePointLength) {
-        return Status(STATUS_FAILED, "Wrote incorrect number of bytes for y coordinate");
-    }
-    BN_CTX_free(ctx);
-    return std::make_pair(x_bytestring, y_bytestring);
-}
-
-cppbor::Array buildCertReqRecipients(const bytevec& pubkey, const bytevec& kid) {
-    return cppbor::Array()                   // Array of recipients
-            .add(cppbor::Array()             // Recipient
-                         .add(cppbor::Map()  // Protected
-                                      .add(ALGORITHM, ECDH_ES_HKDF_256)
-                                      .canonicalize()
-                                      .encode())
-                         .add(cppbor::Map()  // Unprotected
-                                      .add(COSE_KEY, cppbor::Map()
-                                                             .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
-                                                             .add(CoseKey::CURVE, cppcose::X25519)
-                                                             .add(CoseKey::PUBKEY_X, pubkey)
-                                                             .canonicalize())
-                                      .add(KEY_ID, kid)
-                                      .canonicalize())
-                         .add(cppbor::Null()));  // No ciphertext
-}
-
-static keymaster_key_param_t kKeyMintEcdsaP256Params[] = {
-        Authorization(TAG_PURPOSE, KM_PURPOSE_ATTEST_KEY),
-        Authorization(TAG_ALGORITHM, KM_ALGORITHM_EC), Authorization(TAG_KEY_SIZE, 256),
-        Authorization(TAG_DIGEST, KM_DIGEST_SHA_2_256),
-        Authorization(TAG_EC_CURVE, KM_EC_CURVE_P_256), Authorization(TAG_NO_AUTH_REQUIRED),
-        // The certificate generated by KM will be discarded, these values don't matter.
-        Authorization(TAG_CERTIFICATE_NOT_BEFORE, 0), Authorization(TAG_CERTIFICATE_NOT_AFTER, 0)};
-
 }  // namespace
 
 RemotelyProvisionedComponent::RemotelyProvisionedComponent(
         std::shared_ptr<keymint::AndroidKeyMintDevice> keymint) {
-    std::tie(devicePrivKey_, bcc_) = generateBcc();
     impl_ = keymint->getKeymasterImpl();
 }
 
@@ -294,43 +127,15 @@
 ScopedAStatus RemotelyProvisionedComponent::generateEcdsaP256KeyPair(bool testMode,
                                                                      MacedPublicKey* macedPublicKey,
                                                                      bytevec* privateKeyHandle) {
-    // TODO(jbires): The following should move from ->GenerateKey to ->GenerateRKPKey and everything
-    //              after the GenerateKey call should basically be moved into that new function call
-    //              as well once the issue with libcppbor in system/keymaster is sorted out
-    GenerateKeyRequest request(impl_->message_version());
-    request.key_description.Reinitialize(kKeyMintEcdsaP256Params,
-                                         array_length(kKeyMintEcdsaP256Params));
-    GenerateKeyResponse response(impl_->message_version());
-    impl_->GenerateKey(request, &response);
+    GenerateRkpKeyRequest request(impl_->message_version());
+    request.test_mode = testMode;
+    GenerateRkpKeyResponse response(impl_->message_version());
+    impl_->GenerateRkpKey(request, &response);
     if (response.error != KM_ERROR_OK) {
-        return km_utils::kmError2ScopedAStatus(response.error);
+        return Status(-static_cast<int32_t>(response.error), "Failure in key generation.");
     }
 
-    if (response.certificate_chain.entry_count != 1) {
-        // Error: Need the single non-signed certificate with the public key in it.
-        return Status(STATUS_FAILED,
-                      "Expected to receive a single certificate from GenerateKey. Instead got: " +
-                              std::to_string(response.certificate_chain.entry_count));
-    }
-    auto affineCoords = buildCosePublicKeyFromKmCert(response.certificate_chain.begin());
-    if (!affineCoords.isOk()) return affineCoords.moveError();
-    cppbor::Map cosePublicKeyMap = cppbor::Map()
-                                           .add(CoseKey::KEY_TYPE, EC2)
-                                           .add(CoseKey::ALGORITHM, ES256)
-                                           .add(CoseKey::CURVE, cppcose::P256)
-                                           .add(CoseKey::PUBKEY_X, affineCoords->first)
-                                           .add(CoseKey::PUBKEY_Y, affineCoords->second);
-    if (testMode) {
-        cosePublicKeyMap.add(CoseKey::TEST_KEY, cppbor::Null());
-    }
-
-    bytevec cosePublicKey = cosePublicKeyMap.canonicalize().encode();
-
-    auto macedKey = constructCoseMac0(testMode ? remote_prov::kTestMacKey : macKey_,
-                                      {} /* externalAad */, cosePublicKey);
-    if (!macedKey) return Status(macedKey.moveMessage());
-
-    macedPublicKey->macedKey = macedKey->encode();
+    macedPublicKey->macedKey = km_utils::kmBlob2vector(response.maced_public_key);
     *privateKeyHandle = km_utils::kmBlob2vector(response.key_blob);
     return ScopedAStatus::ok();
 }
@@ -339,126 +144,25 @@
         bool testMode, const vector<MacedPublicKey>& keysToSign,
         const bytevec& endpointEncCertChain, const bytevec& challenge, DeviceInfo* deviceInfo,
         ProtectedData* protectedData, bytevec* keysToSignMac) {
-    auto pubKeysToSign = validateAndExtractPubkeys(testMode, keysToSign,
-                                                   testMode ? remote_prov::kTestMacKey : macKey_);
-    if (!pubKeysToSign.isOk()) return pubKeysToSign.moveError();
-
-    bytevec ephemeralMacKey = remote_prov::randomBytes(SHA256_DIGEST_LENGTH);
-
-    auto pubKeysToSignMac = generateCoseMac0Mac(ephemeralMacKey, bytevec{}, *pubKeysToSign);
-    if (!pubKeysToSignMac) return Status(pubKeysToSignMac.moveMessage());
-    *keysToSignMac = *std::move(pubKeysToSignMac);
-
-    bytevec devicePrivKey;
-    cppbor::Array bcc;
-    if (testMode) {
-        std::tie(devicePrivKey, bcc) = generateBcc();
-    } else {
-        devicePrivKey = devicePrivKey_;
-        bcc = bcc_.clone();
+    GenerateCsrRequest request(impl_->message_version());
+    request.test_mode = testMode;
+    request.num_keys = keysToSign.size();
+    request.keys_to_sign_array = new KeymasterBlob[keysToSign.size()];
+    for (int i = 0; i < keysToSign.size(); i++) {
+        request.SetKeyToSign(i, keysToSign[i].macedKey.data(), keysToSign[i].macedKey.size());
     }
+    request.SetEndpointEncCertChain(endpointEncCertChain.data(), endpointEncCertChain.size());
+    request.SetChallenge(challenge.data(), challenge.size());
+    GenerateCsrResponse response(impl_->message_version());
+    impl_->GenerateCsr(request, &response);
 
-    std::unique_ptr<cppbor::Map> deviceInfoMap = createDeviceInfo();
-    deviceInfo->deviceInfo = deviceInfoMap->encode();
-    auto signedMac = constructCoseSign1(devicePrivKey /* Signing key */,  //
-                                        ephemeralMacKey /* Payload */,
-                                        cppbor::Array() /* AAD */
-                                                .add(challenge)
-                                                .add(std::move(deviceInfoMap))
-                                                .encode());
-    if (!signedMac) return Status(signedMac.moveMessage());
-
-    bytevec ephemeralPrivKey(X25519_PRIVATE_KEY_LEN);
-    bytevec ephemeralPubKey(X25519_PUBLIC_VALUE_LEN);
-    X25519_keypair(ephemeralPubKey.data(), ephemeralPrivKey.data());
-
-    auto eek = validateAndExtractEekPubAndId(testMode, endpointEncCertChain);
-    if (!eek.isOk()) return eek.moveError();
-
-    auto sessionKey = x25519_HKDF_DeriveKey(ephemeralPubKey, ephemeralPrivKey, eek->first,
-                                            true /* senderIsA */);
-    if (!sessionKey) return Status(sessionKey.moveMessage());
-
-    auto coseEncrypted =
-            constructCoseEncrypt(*sessionKey, remote_prov::randomBytes(kAesGcmNonceLength),
-                                 cppbor::Array()  // payload
-                                         .add(signedMac.moveValue())
-                                         .add(std::move(bcc))
-                                         .encode(),
-                                 {},  // aad
-                                 buildCertReqRecipients(ephemeralPubKey, eek->second));
-
-    if (!coseEncrypted) return Status(coseEncrypted.moveMessage());
-    protectedData->protectedData = coseEncrypted->encode();
-
+    if (response.error != KM_ERROR_OK) {
+        return Status(-static_cast<int32_t>(response.error), "Failure in CSR Generation.");
+    }
+    deviceInfo->deviceInfo = km_utils::kmBlob2vector(response.device_info_blob);
+    protectedData->protectedData = km_utils::kmBlob2vector(response.protected_data_blob);
+    *keysToSignMac = km_utils::kmBlob2vector(response.keys_to_sign_mac);
     return ScopedAStatus::ok();
 }
 
-bytevec RemotelyProvisionedComponent::deriveBytesFromHbk(const string& context,
-                                                         size_t numBytes) const {
-    bytevec fakeHbk(32, 0);
-    bytevec result(numBytes);
-
-    // TODO(swillden): Figure out if HKDF can fail.  It doesn't seem like it should be able to,
-    // but the function does return an error code.
-    HKDF(result.data(), numBytes,               //
-         EVP_sha256(),                          //
-         fakeHbk.data(), fakeHbk.size(),        //
-         nullptr /* salt */, 0 /* salt len */,  //
-         reinterpret_cast<const uint8_t*>(context.data()), context.size());
-
-    return result;
-}
-
-std::unique_ptr<cppbor::Map> RemotelyProvisionedComponent::createDeviceInfo() const {
-    auto result = std::make_unique<cppbor::Map>(cppbor::Map());
-
-    // The following placeholders show how the DeviceInfo map would be populated.
-    // result->add(cppbor::Tstr("brand"), cppbor::Tstr("Google"));
-    // result->add(cppbor::Tstr("manufacturer"), cppbor::Tstr("Google"));
-    // result->add(cppbor::Tstr("product"), cppbor::Tstr("Fake"));
-    // result->add(cppbor::Tstr("model"), cppbor::Tstr("Imaginary"));
-    // result->add(cppbor::Tstr("board"), cppbor::Tstr("Chess"));
-    // result->add(cppbor::Tstr("vb_state"), cppbor::Tstr("orange"));
-    // result->add(cppbor::Tstr("bootloader_state"), cppbor::Tstr("unlocked"));
-    // result->add(cppbor::Tstr("os_version"), cppbor::Tstr("SC"));
-    // result->add(cppbor::Tstr("system_patch_level"), cppbor::Uint(20210331));
-    // result->add(cppbor::Tstr("boot_patch_level"), cppbor::Uint(20210331));
-    // result->add(cppbor::Tstr("vendor_patch_level"), cppbor::Uint(20210331));
-
-    result->canonicalize();
-    return result;
-}
-
-std::pair<bytevec /* privKey */, cppbor::Array /* BCC */>
-RemotelyProvisionedComponent::generateBcc() {
-    bytevec privKey(ED25519_PRIVATE_KEY_LEN);
-    bytevec pubKey(ED25519_PUBLIC_KEY_LEN);
-
-    ED25519_keypair(pubKey.data(), privKey.data());
-
-    auto coseKey = cppbor::Map()
-                           .add(CoseKey::KEY_TYPE, OCTET_KEY_PAIR)
-                           .add(CoseKey::ALGORITHM, EDDSA)
-                           .add(CoseKey::CURVE, ED25519)
-                           .add(CoseKey::KEY_OPS, VERIFY)
-                           .add(CoseKey::PUBKEY_X, pubKey)
-                           .canonicalize()
-                           .encode();
-    auto sign1Payload = cppbor::Map()
-                                .add(1 /* Issuer */, "Issuer")
-                                .add(2 /* Subject */, "Subject")
-                                .add(-4670552 /* Subject Pub Key */, coseKey)
-                                .add(-4670553 /* Key Usage (little-endian order) */,
-                                     std::vector<uint8_t>{0x20} /* keyCertSign = 1<<5 */)
-                                .canonicalize()
-                                .encode();
-    auto coseSign1 = constructCoseSign1(privKey,       /* signing key */
-                                        cppbor::Map(), /* extra protected */
-                                        sign1Payload, {} /* AAD */);
-    assert(coseSign1);
-
-    return {privKey, cppbor::Array().add(coseKey).add(coseSign1.moveValue())};
-}
-
 }  // namespace aidl::android::hardware::security::keymint
diff --git a/security/keymint/aidl/default/RemotelyProvisionedComponent.h b/security/keymint/aidl/default/RemotelyProvisionedComponent.h
index 8185e26..4b012bc 100644
--- a/security/keymint/aidl/default/RemotelyProvisionedComponent.h
+++ b/security/keymint/aidl/default/RemotelyProvisionedComponent.h
@@ -43,14 +43,6 @@
                                              std::vector<uint8_t>* keysToSignMac) override;
 
   private:
-    // TODO(swillden): Move these into an appropriate Context class.
-    std::vector<uint8_t> deriveBytesFromHbk(const std::string& context, size_t numBytes) const;
-    std::unique_ptr<cppbor::Map> createDeviceInfo() const;
-    std::pair<std::vector<uint8_t>, cppbor::Array> generateBcc();
-
-    std::vector<uint8_t> macKey_ = deriveBytesFromHbk("Key to MAC public keys", 32);
-    std::vector<uint8_t> devicePrivKey_;
-    cppbor::Array bcc_;
     std::shared_ptr<::keymaster::AndroidKeymaster> impl_;
 };
 
diff --git a/security/keymint/aidl/vts/functional/Android.bp b/security/keymint/aidl/vts/functional/Android.bp
index 6c7309e..d969dfe 100644
--- a/security/keymint/aidl/vts/functional/Android.bp
+++ b/security/keymint/aidl/vts/functional/Android.bp
@@ -43,7 +43,7 @@
         "android.hardware.security.keymint-V1-ndk_platform",
         "android.hardware.security.secureclock-V1-ndk_platform",
         "libcppbor_external",
-        "libcppcose",
+        "libcppcose_rkp",
         "libkeymint_remote_prov_support",
         "libkeymint_vts_test_utils",
     ],
@@ -75,7 +75,7 @@
         "android.hardware.security.keymint-V1-ndk_platform",
         "android.hardware.security.secureclock-V1-ndk_platform",
         "libcppbor_external",
-        "libcppcose",
+        "libcppcose_rkp",
         "libgmock_ndk",
         "libkeymint_remote_prov_support",
     ],
@@ -92,20 +92,20 @@
     ],
     shared_libs: [
         "libbinder_ndk",
-        "libcppbor_external",
         "libcrypto",
-        "libkeymaster_portable",
-        "libpuresoftkeymasterdevice",
     ],
     static_libs: [
         "android.hardware.security.keymint-V1-ndk_platform",
         "android.hardware.security.secureclock-V1-ndk_platform",
-        "libcppcose",
+        "libcppbor_external",
+        "libcppcose_rkp",
         "libgmock_ndk",
+        "libkeymaster_portable",
         "libkeymint",
         "libkeymint_support",
         "libkeymint_remote_prov_support",
         "libkeymint_vts_test_utils",
+        "libpuresoftkeymasterdevice",
         "libremote_provisioner",
     ],
     test_suites: [
diff --git a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
index 3da0484..0dcc961 100644
--- a/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
+++ b/security/keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
@@ -23,12 +23,12 @@
 #include <android-base/logging.h>
 #include <android/binder_manager.h>
 #include <cppbor_parse.h>
-#include <cppcose/cppcose.h>
 #include <cutils/properties.h>
 #include <gmock/gmock.h>
 #include <openssl/mem.h>
 #include <remote_prov/remote_prov_utils.h>
 
+#include <keymaster/cppcose/cppcose.h>
 #include <keymint_support/attestation_record.h>
 #include <keymint_support/key_param_output.h>
 #include <keymint_support/keymint_utils.h>
diff --git a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
index 9e52b20..6443015 100644
--- a/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
+++ b/security/keymint/aidl/vts/functional/VtsRemotelyProvisionedComponentTests.cpp
@@ -21,8 +21,8 @@
 #include <aidl/android/hardware/security/keymint/SecurityLevel.h>
 #include <android/binder_manager.h>
 #include <cppbor_parse.h>
-#include <cppcose/cppcose.h>
 #include <gmock/gmock.h>
+#include <keymaster/cppcose/cppcose.h>
 #include <keymaster/keymaster_configuration.h>
 #include <keymint_support/authorization_set.h>
 #include <openssl/ec.h>
diff --git a/security/keymint/support/Android.bp b/security/keymint/support/Android.bp
index 4c4258b..718133a 100644
--- a/security/keymint/support/Android.bp
+++ b/security/keymint/support/Android.bp
@@ -57,25 +57,8 @@
         "include",
     ],
     shared_libs: [
-        "libcppcose",
         "libcppbor_external",
+        "libcppcose_rkp",
         "libcrypto",
     ],
 }
-
-cc_library {
-    name: "libcppcose",
-    vendor_available: true,
-    host_supported: true,
-    srcs: [
-        "cppcose.cpp",
-    ],
-    export_include_dirs: [
-        "include",
-    ],
-    shared_libs: [
-        "libcppbor_external",
-        "libcrypto",
-        "liblog",
-    ],
-}
diff --git a/security/keymint/support/cppcose.cpp b/security/keymint/support/cppcose.cpp
deleted file mode 100644
index bafb2b6..0000000
--- a/security/keymint/support/cppcose.cpp
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * 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::Map() /* 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)->asMap();
-    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)->asMap();
-    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(cppbor::Map() /* 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::Map* unprotectedParams = coseSign1->get(kCoseSign1UnprotectedParams)->asMap();
-    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
deleted file mode 100644
index a936bfd..0000000
--- a/security/keymint/support/include/cppcose/cppcose.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * 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
index 5e205a2..e4261f3 100644
--- a/security/keymint/support/include/remote_prov/remote_prov_utils.h
+++ b/security/keymint/support/include/remote_prov/remote_prov_utils.h
@@ -18,7 +18,7 @@
 
 #include <vector>
 
-#include <cppcose/cppcose.h>
+#include <keymaster/cppcose/cppcose.h>
 
 namespace aidl::android::hardware::security::keymint::remote_prov {
 
