[ZT] Refactor SigningKeyPair

- Moved all signing key pair management logic into a new device_trust/key_management directory.
- Split out PersistenceDelegate, NetworkDelegate and installer code into their own sub-directories.
- SigningKeyPair is now an object that represents a read-only version of the key and which can only be created with valid signing key information (i.e. instances will always have a valid key inside).
- Created a KeyRotationManager to handle the rotation + upload of new keys.
- Updated all usages and tests.

Bug: b/203402488
Change-Id: I2ddb5eda210fde1e73d19c1d4b45a40477d69699
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3228937
Commit-Queue: Sebastien Lalancette <seblalancette@chromium.org>
Reviewed-by: Greg Thompson <grt@chromium.org>
Reviewed-by: Roger Tawa <rogerta@chromium.org>
Cr-Commit-Position: refs/heads/main@{#933888}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 2015b92..7e332d0 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -5646,7 +5646,8 @@
       "//chrome/browser/enterprise/connectors/device_trust/attestation/common/proto:attestation_ca_proto",
       "//chrome/browser/enterprise/connectors/device_trust/attestation/common/proto:google_key_proto",
       "//chrome/browser/enterprise/connectors/device_trust/attestation/common/proto:interface_proto",
-      "//chrome/browser/enterprise/connectors/device_trust/attestation/desktop:elevated_command_support",
+      "//chrome/browser/enterprise/connectors/device_trust/key_management/core",
+      "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence",
     ]
   }
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.cc
index 59b86696..938fb0cb 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.cc
@@ -8,10 +8,6 @@
 
 AttestationService::~AttestationService() = default;
 
-void AttestationService::StampReport(DeviceTrustReportEvent& report) {
-  // No-op by default.
-}
-
 bool AttestationService::RotateSigningKey(const std::string& nonce) {
   return false;
 }
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.h b/chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.h
index 3a7d5b6..b5a9538 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.h
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.h
@@ -13,8 +13,6 @@
 
 namespace enterprise_connectors {
 
-class DeviceTrustReportEvent;
-
 // Interface for classes in charge of building challenge-responses to enable
 // handshake between Chrome, an IdP and Verified Access.
 class AttestationService {
@@ -31,9 +29,6 @@
       std::unique_ptr<SignalsType> signals,
       AttestationCallback callback) = 0;
 
-  // Applies, if any, updates to a `report` about to be sent.
-  virtual void StampReport(DeviceTrustReportEvent& report);
-
   // Rotate the key used to sign in challenge response.
   virtual bool RotateSigningKey(const std::string& nonce);
 };
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/common/mock_attestation_service.h b/chrome/browser/enterprise/connectors/device_trust/attestation/common/mock_attestation_service.h
index 3fe6b7d..8846c3f7 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/common/mock_attestation_service.h
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/common/mock_attestation_service.h
@@ -5,6 +5,8 @@
 #ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_COMMON_MOCK_ATTESTATION_SERVICE_H_
 #define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_COMMON_MOCK_ATTESTATION_SERVICE_H_
 
+#include <string>
+
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.h"
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/signals_type.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -25,7 +27,7 @@
                std::unique_ptr<SignalsType>,
                AttestationCallback),
               (override));
-  MOCK_METHOD1(StampReport, void(DeviceTrustReportEvent&));
+  MOCK_METHOD(bool, RotateSigningKey, (const std::string&), (override));
 };
 
 }  // namespace test
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/BUILD.gn
deleted file mode 100644
index e1b9a2d..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/BUILD.gn
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2021 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This code is required to implement the device trust rotate key elevated
-# command.  It lives within its own target so that the code can be shared
-# by the //chrome/installer/setup:setup and //chrome/browser:browser targets.
-source_set("elevated_command_support") {
-  public = [
-    "ec_signing_key.h",
-    "signing_key_pair.h",
-  ]
-
-  sources = [
-    "ec_signing_key.cc",
-    "signing_key_pair.cc",
-  ]
-
-  deps = [ "//net" ]
-
-  public_deps = [
-    "//base",
-    "//components/policy/proto",
-    "//crypto",
-  ]
-
-  if (is_win) {
-    sources += [ "signing_key_pair_win.cc" ]
-    deps += [
-      "//chrome/installer/util:with_no_strings",
-      "//components/winhttp",
-      "//url",
-    ]
-  }
-
-  if (is_mac) {
-    sources += [ "signing_key_pair_mac.cc" ]
-  }
-
-  if (is_linux) {
-    sources += [ "signing_key_pair_linux.cc" ]
-  }
-}
-
-source_set("test_support") {
-  testonly = true
-  public = [
-    "memory_signing_key_pair.h",
-    "scoped_tpm_signing_key_pair.h",
-  ]
-
-  sources = [
-    "memory_signing_key_pair.cc",
-    "scoped_tpm_signing_key_pair.cc",
-  ]
-
-  public_deps = [
-    ":elevated_command_support",
-    "//components/policy/proto",
-    "//crypto:test_support",
-    "//url",
-  ]
-
-  deps = [
-    "//base",
-    "//crypto",
-  ]
-}
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.cc
index 81c67a2..aff088d 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.cc
@@ -17,7 +17,7 @@
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_utils.h"
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/proto/device_trust_attestation_ca.pb.h"
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/crypto_utility.h"
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h"
 #include "components/enterprise/browser/controller/browser_dm_token_storage.h"
 #include "components/enterprise/common/proto/device_trust_report_event.pb.h"
 #include "components/policy/core/common/cloud/device_management_service.h"
@@ -71,11 +71,13 @@
 }  // namespace
 
 DesktopAttestationService::DesktopAttestationService(
-    std::unique_ptr<SigningKeyPair> key_pair,
-    policy::DeviceManagementService* device_management_service)
-    : key_pair_(std::move(key_pair)),
-      device_management_service_(device_management_service) {
-  DCHECK(key_pair_);
+    policy::DeviceManagementService* device_management_service,
+    std::unique_ptr<KeyPersistenceDelegate> key_persistence_delegate)
+    : device_management_service_(device_management_service),
+      key_persistence_delegate_(std::move(key_persistence_delegate)) {
+  DCHECK(device_management_service_);
+  DCHECK(key_persistence_delegate_);
+  key_pair_ = SigningKeyPair::Create(key_persistence_delegate_.get());
 }
 
 DesktopAttestationService::~DesktopAttestationService() = default;
@@ -92,9 +94,10 @@
 }
 
 std::string DesktopAttestationService::ExportPublicKey() {
-  std::vector<uint8_t> public_key_info;
-  if (!key_pair_->ExportPublicKey(&public_key_info))
+  if (!key_pair_ || !key_pair_->key()) {
     return std::string();
+  }
+  auto public_key_info = key_pair_->key()->GetSubjectPublicKeyInfo();
   return std::string(public_key_info.begin(), public_key_info.end());
 }
 
@@ -216,13 +219,6 @@
 #endif  // BUILDFLAG(IS_WIN)
 }
 
-void DesktopAttestationService::StampReport(DeviceTrustReportEvent& report) {
-  auto* credential = report.mutable_attestation_credential();
-  credential->set_format(
-      DeviceTrustReportEvent::Credential::EC_NID_X9_62_PRIME256V1_PUBLIC_DER);
-  credential->set_credential(ExportPublicKey());
-}
-
 std::string
 DesktopAttestationService::VerifyChallengeAndMaybeCreateChallengeResponse(
     const std::string& serialized_signed_data,
@@ -338,11 +334,23 @@
                                                   std::string* response) {
   SignedData signed_data;
   signed_data.set_data(data);
-  std::string signature;
-  if (!key_pair_->SignMessage(data, signed_data.mutable_signature())) {
+
+  absl::optional<std::vector<uint8_t>> signature;
+  if (key_pair_ && key_pair_->key()) {
+    signature =
+        key_pair_->key()->SignSlowly(base::as_bytes(base::make_span(data)));
+  } else {
+    LOG(ERROR) << __func__ << ": Failed, no key to sign data.";
+    return false;
+  }
+
+  if (signature.has_value()) {
+    signed_data.set_signature(signature->data(), signature->size());
+  } else {
     LOG(ERROR) << __func__ << ": Failed to sign data.";
     return false;
   }
+
   if (!signed_data.SerializeToString(response)) {
     LOG(ERROR) << __func__ << ": Failed to serialize signed data.";
     return false;
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.h b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.h
index 69f99e16..1f059c62 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.h
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service.h
@@ -11,6 +11,8 @@
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.h"
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/google_keys.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace policy {
 class DeviceManagementService;
@@ -20,8 +22,8 @@
 
 class DeviceTrustSignals;
 class EncryptedData;
+class KeyPersistenceDelegate;
 class KeyInfo;
-class SigningKeyPair;
 
 // This class is in charge of handling the key pair used for attestation. Also
 // provides the methods needed in the handshake between Chrome, an IdP and
@@ -29,8 +31,8 @@
 class DesktopAttestationService : public AttestationService {
  public:
   explicit DesktopAttestationService(
-      std::unique_ptr<SigningKeyPair> key_pair,
-      policy::DeviceManagementService* device_management_service);
+      policy::DeviceManagementService* device_management_service,
+      std::unique_ptr<KeyPersistenceDelegate> key_persistence_delegate);
   ~DesktopAttestationService() override;
 
   // Export the public key of `key_pair_` in SubjectPublicKeyInfo format.
@@ -47,7 +49,6 @@
       const std::string& challenge,
       std::unique_ptr<DeviceTrustSignals> signals,
       AttestationCallback callback) override;
-  void StampReport(DeviceTrustReportEvent& report) override;
   bool RotateSigningKey(const std::string& nonce) override;
 
  private:
@@ -80,8 +81,9 @@
       const std::string& challenge_response_proto);
 
   GoogleKeys google_keys_;
-  std::unique_ptr<enterprise_connectors::SigningKeyPair> key_pair_;
   policy::DeviceManagementService* device_management_service_;
+  std::unique_ptr<KeyPersistenceDelegate> key_persistence_delegate_;
+  absl::optional<SigningKeyPair> key_pair_;
 
   base::WeakPtrFactory<DesktopAttestationService> weak_factory_{this};
 };
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc
index e74e177..fd55576 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc
@@ -8,8 +8,10 @@
 
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_utils.h"
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/proto/device_trust_attestation_ca.pb.h"
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/memory_signing_key_pair.h"
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.h"
 #include "components/enterprise/common/proto/device_trust_report_event.pb.h"
 #include "components/policy/core/common/cloud/mock_device_management_service.h"
 #include "content/public/test/browser_task_environment.h"
@@ -44,14 +46,16 @@
   void SetUp() override {
     testing::Test::SetUp();
 
-    // Make sure a signing key exists for the tests. This won't actual require
-    // admin rights because of MemorySigningKeyPair.
-    auto key_pair = test::CreateInMemorySigningKeyPair(nullptr, nullptr);
-    ASSERT_TRUE(key_pair->RotateWithAdminRights(GURL("dmserver.com"),
-                                                "fake_dm_token", "nonce"));
+    // ScopedKeyPersistenceDelegateFactory creates mocked persistence delegates
+    // that already mimic the existence of a TPM key provider and stored key.
+    auto mock_persistence_delegate =
+        persistence_delegate_factory_.CreateMockedDelegate();
+    mock_persistence_delegate_ = mock_persistence_delegate.get();
+    EXPECT_CALL(*mock_persistence_delegate_, LoadKeyPair());
+    EXPECT_CALL(*mock_persistence_delegate_, GetTpmBackedKeyProvider());
 
     attestation_service_ = std::make_unique<DesktopAttestationService>(
-        std::move(key_pair), &dm_service_);
+        &dm_service_, std::move(mock_persistence_delegate));
   }
 
   DesktopAttestationService* attestation_service() {
@@ -63,7 +67,8 @@
   testing::StrictMock<policy::MockJobCreationHandler> job_creation_handler_;
   policy::FakeDeviceManagementService dm_service_{&job_creation_handler_};
   std::unique_ptr<DesktopAttestationService> attestation_service_;
-  test::ScopedMemorySigningKeyPairPersistence persistence_scope_;
+  test::ScopedKeyPersistenceDelegateFactory persistence_delegate_factory_;
+  test::MockKeyPersistenceDelegate* mock_persistence_delegate_;
 };
 
 TEST_F(DesktopAttestationServiceTest, BuildChallengeResponse) {
@@ -93,20 +98,4 @@
   EXPECT_NE(signed_data.signature(), std::string());
 }
 
-// Tests that StampReport properly adds the credentials to the proto.
-TEST_F(DesktopAttestationServiceTest, StampReport) {
-  DeviceTrustReportEvent report;
-
-  attestation_service()->StampReport(report);
-
-  ASSERT_TRUE(report.has_attestation_credential());
-  ASSERT_TRUE(report.attestation_credential().has_credential());
-
-  const auto& credential = report.attestation_credential();
-  EXPECT_EQ(credential.credential(), attestation_service()->ExportPublicKey());
-  EXPECT_EQ(
-      credential.format(),
-      DeviceTrustReportEvent::Credential::EC_NID_X9_62_PRIME256V1_PUBLIC_DER);
-}
-
 }  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/memory_signing_key_pair.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/memory_signing_key_pair.cc
deleted file mode 100644
index c819efa8..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/memory_signing_key_pair.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/memory_signing_key_pair.h"
-
-#include <stdint.h>
-
-#include <memory>
-#include <vector>
-
-#include "base/memory/ptr_util.h"
-#include "base/no_destructor.h"
-
-using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
-using BPKUP = enterprise_management::BrowserPublicKeyUploadResponse;
-
-namespace enterprise_connectors {
-namespace test {
-
-namespace {
-
-SigningKeyPair::KeyTrustLevel g_trust_level =
-    BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED;
-
-std::vector<uint8_t>* GetWrappedKeyStorage() {
-  static base::NoDestructor<std::vector<uint8_t>> wrapped;
-  return wrapped.get();
-}
-
-}  // namespace
-
-bool InMemorySigningKeyPairPersistenceDelegate::StoreKeyPair(
-    SigningKeyPair::KeyTrustLevel trust_level,
-    std::vector<uint8_t> wrapped) {
-  if (force_store_to_fail_)
-    return false;
-
-  g_trust_level = trust_level;
-  *GetWrappedKeyStorage() = std::move(wrapped);
-  return true;
-}
-
-SigningKeyPair::KeyInfo
-InMemorySigningKeyPairPersistenceDelegate::LoadKeyPair() {
-  return {g_trust_level, *GetWrappedKeyStorage()};
-}
-
-InMemorySigningKeyPairNetworkDelegate::InMemorySigningKeyPairNetworkDelegate() =
-    default;
-InMemorySigningKeyPairNetworkDelegate::
-    ~InMemorySigningKeyPairNetworkDelegate() = default;
-
-std::string InMemorySigningKeyPairNetworkDelegate::SendPublicKeyToDmServerSync(
-    const GURL& url,
-    const std::string& dm_token,
-    const std::string& body) {
-  ++send_count_;
-  url_ = url;
-  dm_token_ = dm_token;
-  body_ = body;
-
-  auto rc = BPKUP::SUCCESS;
-  if (!response_codes_.empty()) {
-    rc = response_codes_.front();
-    response_codes_.pop_front();
-  }
-
-  enterprise_management::DeviceManagementResponse response;
-  response.mutable_browser_public_key_upload_response()->set_response_code(rc);
-  std::string response_str;
-  response.SerializeToString(&response_str);
-  return response_str;
-}
-
-// static
-std::unique_ptr<SigningKeyPair> CreateInMemorySigningKeyPair(
-    InMemorySigningKeyPairPersistenceDelegate** pdelegate_ptr,
-    InMemorySigningKeyPairNetworkDelegate** ndelegate_ptr) {
-  auto pdelegate =
-      std::make_unique<InMemorySigningKeyPairPersistenceDelegate>();
-  auto ndelegate = std::make_unique<InMemorySigningKeyPairNetworkDelegate>();
-
-  if (pdelegate_ptr)
-    *pdelegate_ptr = pdelegate.get();
-  if (ndelegate_ptr)
-    *ndelegate_ptr = ndelegate.get();
-
-  return SigningKeyPair::CreateWithDelegates(std::move(pdelegate),
-                                             std::move(ndelegate));
-}
-
-ScopedMemorySigningKeyPairPersistence::ScopedMemorySigningKeyPairPersistence() {
-  g_trust_level = BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED;
-  GetWrappedKeyStorage()->clear();
-}
-
-ScopedMemorySigningKeyPairPersistence::
-    ~ScopedMemorySigningKeyPairPersistence() {
-  g_trust_level = BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED;
-  GetWrappedKeyStorage()->clear();
-}
-
-}  // namespace test
-}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/memory_signing_key_pair.h b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/memory_signing_key_pair.h
deleted file mode 100644
index 0345c101..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/memory_signing_key_pair.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_MEMORY_SIGNING_KEY_PAIR_H_
-#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_MEMORY_SIGNING_KEY_PAIR_H_
-
-#include <stdint.h>
-
-#include <deque>
-#include <memory>
-#include <vector>
-
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
-#include "components/policy/proto/device_management_backend.pb.h"
-#include "url/gurl.h"
-
-namespace enterprise_connectors {
-
-namespace test {
-
-// A persistence delegate that keeps keys in memory and allows the owner to
-// control whether the persistence will fail or not.  This is useful in
-// implementing MemorySigningKeyPair but can also be used in other test code
-// that wants to avoid real persistence.
-class InMemorySigningKeyPairPersistenceDelegate
-    : public SigningKeyPair::PersistenceDelegate {
- public:
-  bool StoreKeyPair(SigningKeyPair::KeyTrustLevel trust_level,
-                    std::vector<uint8_t> wrapped) override;
-  SigningKeyPair::KeyInfo LoadKeyPair() override;
-
-  void set_force_store_to_fail(bool force_store_to_fail) {
-    force_store_to_fail_ = force_store_to_fail;
-  }
-
- private:
-  bool force_store_to_fail_ = false;
-};
-
-// A network delegate that sends keys to the bit bucket but allows the owner
-// to simulate whether the network request fails or not.  This is useful in
-// implementing MemorySigningKeyPair but can also be used in other test code
-// that wants to avoid real networking.
-class InMemorySigningKeyPairNetworkDelegate
-    : public SigningKeyPair::NetworkDelegate {
- public:
-  InMemorySigningKeyPairNetworkDelegate();
-  ~InMemorySigningKeyPairNetworkDelegate() override;
-
-  std::string SendPublicKeyToDmServerSync(const GURL& url,
-                                          const std::string& dm_token,
-                                          const std::string& body) override;
-
-  void push_response_codes(
-      const std::deque<
-          enterprise_management::BrowserPublicKeyUploadResponse::ResponseCode>&
-          rcs) {
-    response_codes_.insert(response_codes_.end(), rcs.begin(), rcs.end());
-  }
-
-  int send_count() const { return send_count_; }
-  const GURL& url() const { return url_; }
-  const std::string& dm_token() const { return dm_token_; }
-  const std::string& body() const { return body_; }
-
- private:
-  std::deque<
-      enterprise_management::BrowserPublicKeyUploadResponse::ResponseCode>
-      response_codes_;
-  int send_count_ = 0;
-  GURL url_;
-  std::string dm_token_;
-  std::string body_;
-};
-
-// Creates a SigningKeyPair that stored keys in memory and that
-// simulates network requests to DM server.  The output arguments are
-// optional and return interfaces to control the behaviour of the delegates.
-// The lifetime of the control interfaces is the same as the returned
-// signing key pair.
-std::unique_ptr<SigningKeyPair> CreateInMemorySigningKeyPair(
-    InMemorySigningKeyPairPersistenceDelegate** pdelegate_ptr,
-    InMemorySigningKeyPairNetworkDelegate** nelegate_ptr);
-
-// Makes sure to clear the memory used to by InMemorySigningKeyPair*Delegates.
-// The memory is clear at both constructor and destructor time.
-class ScopedMemorySigningKeyPairPersistence {
- public:
-  ScopedMemorySigningKeyPairPersistence();
-  ~ScopedMemorySigningKeyPairPersistence();
-};
-
-}  // namespace test
-}  // namespace enterprise_connectors
-
-#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_MEMORY_SIGNING_KEY_PAIR_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/scoped_tpm_signing_key_pair.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/scoped_tpm_signing_key_pair.cc
deleted file mode 100644
index 8867177..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/scoped_tpm_signing_key_pair.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/scoped_tpm_signing_key_pair.h"
-
-#include "base/check.h"
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
-#include "crypto/signature_verifier.h"
-#include "crypto/unexportable_key.h"
-
-namespace enterprise_connectors {
-namespace test {
-
-ScopedTpmSigningKeyPair::ScopedTpmSigningKeyPair() {
-  // Generating and forcing the usage of a mocked TPM wrapped key to allow
-  // tests to skip having to rotate/store the key itself.
-  auto provider = crypto::GetUnexportableKeyProvider();
-  DCHECK(provider);
-  const crypto::SignatureVerifier::SignatureAlgorithm algorithms[] = {
-      crypto::SignatureVerifier::ECDSA_SHA256};
-  auto signing_key = provider->GenerateSigningKeySlowly(algorithms);
-  DCHECK(signing_key);
-  wrapped_key_ = signing_key->GetWrappedKey();
-  SigningKeyPair::SetTpmKeyWrappedForTesting(wrapped_key_);
-}
-
-ScopedTpmSigningKeyPair::~ScopedTpmSigningKeyPair() {
-  SigningKeyPair::ClearTpmKeyWrappedForTesting();
-}
-
-}  // namespace test
-}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/scoped_tpm_signing_key_pair.h b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/scoped_tpm_signing_key_pair.h
deleted file mode 100644
index e39704f3..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/scoped_tpm_signing_key_pair.h
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_SCOPED_TPM_SIGNING_KEY_PAIR_H_
-#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_SCOPED_TPM_SIGNING_KEY_PAIR_H_
-
-#include <stdint.h>
-
-#include <vector>
-
-#include "crypto/scoped_mock_unexportable_key_provider.h"
-
-namespace enterprise_connectors {
-namespace test {
-
-// Class used in tests to mock retrieval of TPM signing key pairs. Creating an
-// instance of this will prevent tests from having to actually store signing
-// key pairs (which requires an elevated process).
-class ScopedTpmSigningKeyPair {
- public:
-  ScopedTpmSigningKeyPair();
-  ~ScopedTpmSigningKeyPair();
-
-  // Returns the TPM wrapped key.
-  const std::vector<uint8_t>& wrapped_key() { return wrapped_key_; }
-
- private:
-  crypto::ScopedMockUnexportableKeyProvider scoped_key_provider_;
-  std::vector<uint8_t> wrapped_key_;
-};
-
-}  // namespace test
-}  // namespace enterprise_connectors
-
-#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_SCOPED_TPM_SIGNING_KEY_PAIR_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.cc
deleted file mode 100644
index 3459f84d..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.cc
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
-
-#include <stdint.h>
-
-#include <tuple>
-#include <vector>
-
-#include "base/containers/span.h"
-#include "base/memory/ptr_util.h"
-#include "base/no_destructor.h"
-#include "base/notreached.h"
-#include "base/threading/platform_thread.h"
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key.h"
-#include "crypto/unexportable_key.h"
-#include "net/base/backoff_entry.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
-#include "url/gurl.h"
-
-using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
-using BPKUP = enterprise_management::BrowserPublicKeyUploadResponse;
-
-namespace enterprise_connectors {
-
-namespace {
-
-absl::optional<std::vector<uint8_t>>& GetForcedTpmKeyStorage() {
-  static base::NoDestructor<absl::optional<std::vector<uint8_t>>> storage;
-  return *storage;
-}
-
-}  // namespace
-
-// static
-std::unique_ptr<SigningKeyPair> SigningKeyPair::Create() {
-  return CreateWithDelegates(std::make_unique<PersistenceDelegate>(),
-                             std::make_unique<NetworkDelegate>());
-}
-
-// static
-std::unique_ptr<SigningKeyPair> SigningKeyPair::CreateWithDelegates(
-    std::unique_ptr<PersistenceDelegate> persistence_delegate,
-    std::unique_ptr<NetworkDelegate> network_delegate) {
-  auto key_pair = base::WrapUnique(new SigningKeyPair(
-      std::move(persistence_delegate), std::move(network_delegate)));
-  if (key_pair)
-    key_pair->Init();
-
-  return key_pair;
-}
-
-// static
-void SigningKeyPair::SetTpmKeyWrappedForTesting(
-    const std::vector<uint8_t>& wrapped) {
-  GetForcedTpmKeyStorage().emplace(wrapped);
-}
-
-// static
-void SigningKeyPair::ClearTpmKeyWrappedForTesting() {
-  GetForcedTpmKeyStorage().reset();
-}
-
-SigningKeyPair::SigningKeyPair(
-    std::unique_ptr<PersistenceDelegate> persistence_delegate,
-    std::unique_ptr<NetworkDelegate> network_delegate)
-    : persistence_delegate_(std::move(persistence_delegate)),
-      network_delegate_(std::move(network_delegate)) {
-  DCHECK(persistence_delegate_);
-  DCHECK(network_delegate_);
-}
-
-SigningKeyPair::~SigningKeyPair() = default;
-
-void SigningKeyPair::Init() {
-  KeyTrustLevel trust_level = BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED;
-  std::vector<uint8_t> wrapped;
-
-  auto& forced_tpm_key_wrapped = GetForcedTpmKeyStorage();
-  if (forced_tpm_key_wrapped) {
-    // Test hook to make use of ScopedMockUnexportableKeyProvider with the
-    // appropriate algorithm.
-    trust_level = BPKUR::CHROME_BROWSER_TPM_KEY;
-    wrapped = forced_tpm_key_wrapped.value();
-  } else {
-    std::tie(trust_level, wrapped) = persistence_delegate_->LoadKeyPair();
-  }
-
-  if (wrapped.empty()) {
-    // No persisted key pair with a known trust level found.  This is not an
-    // error, it could be that no key has been created yet.
-    return;
-  }
-
-  switch (trust_level) {
-    case BPKUR::CHROME_BROWSER_TPM_KEY: {
-      auto provider = crypto::GetUnexportableKeyProvider();
-      if (provider) {
-        key_pair_ = provider->FromWrappedSigningKeySlowly(wrapped);
-      }
-      break;
-    }
-    case BPKUR::CHROME_BROWSER_OS_KEY: {
-      ECSigningKeyProvider provider;
-      key_pair_ = provider.FromWrappedSigningKeySlowly(wrapped);
-      break;
-    }
-    case BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED:
-      NOTREACHED();
-      return;
-  }
-
-  if (key_pair_)
-    trust_level_ = trust_level;
-}
-
-bool SigningKeyPair::SignMessage(const std::string& message,
-                                 std::string* signature) {
-  if (!key_pair_)
-    return false;
-
-  auto signature_bytes =
-      key_pair_->SignSlowly(base::as_bytes(base::make_span(message)));
-  if (signature_bytes)
-    *signature = std::string(signature_bytes->begin(), signature_bytes->end());
-
-  return signature_bytes.has_value();
-}
-
-bool SigningKeyPair::ExportPublicKey(std::vector<uint8_t>* public_key) {
-  if (!key_pair_)
-    return false;
-
-  *public_key = key_pair_->GetSubjectPublicKeyInfo();
-  return public_key->size() != 0;
-}
-
-bool SigningKeyPair::RotateWithAdminRights(const GURL& dm_server_url,
-                                           const std::string& dm_token,
-                                           const std::string& nonce) {
-  // Create a new key pair.  First try creating a TPM-backed key.  If that does
-  // not work, try a less secure type.
-  KeyTrustLevel new_trust_level = BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED;
-  auto acceptable_algorithms = {
-      crypto::SignatureVerifier::ECDSA_SHA256,
-      crypto::SignatureVerifier::RSA_PKCS1_SHA256,
-  };
-
-  std::unique_ptr<crypto::UnexportableKeyProvider> provider =
-      GetTpmBackedKeyProvider();
-  auto new_key_pair =
-      provider ? provider->GenerateSigningKeySlowly(acceptable_algorithms)
-               : nullptr;
-  if (new_key_pair) {
-    new_trust_level = BPKUR::CHROME_BROWSER_TPM_KEY;
-  } else {
-    new_trust_level = BPKUR::CHROME_BROWSER_OS_KEY;
-    ECSigningKeyProvider ec_signing_provider;
-    new_key_pair =
-        ec_signing_provider.GenerateSigningKeySlowly(acceptable_algorithms);
-  }
-  if (!new_key_pair)
-    return false;
-
-  if (!persistence_delegate_->StoreKeyPair(new_trust_level,
-                                           new_key_pair->GetWrappedKey())) {
-    return false;
-  }
-
-  enterprise_management::DeviceManagementRequest request;
-  if (!BuildUploadPublicKeyRequest(
-          new_trust_level, new_key_pair, nonce,
-          request.mutable_browser_public_key_upload_request())) {
-    return false;
-  }
-
-  std::string request_str;
-  request.SerializeToString(&request_str);
-
-  const net::BackoffEntry::Policy kBackoffPolicy{
-      .num_errors_to_ignore = 0,
-      .initial_delay_ms = 1000,
-      .multiply_factor = 2.0,
-      .jitter_factor = 0.1,
-      .maximum_backoff_ms = 5 * 60 * 1000,  // 5 min.
-      .entry_lifetime_ms = -1,
-      .always_use_initial_delay = false};
-
-  const int kMaxRetryCount = 10;
-  auto rc = BPKUP::UNDEFINED;
-  net::BackoffEntry boe(&kBackoffPolicy);
-  for (int i = 0;
-       rc == BPKUP::UNDEFINED && boe.failure_count() < kMaxRetryCount; ++i) {
-    // Wait before trying to send again, if needed.  This will not block on
-    // the first request.
-    if (boe.ShouldRejectRequest())
-      base::PlatformThread::Sleep(boe.GetTimeUntilRelease());
-
-    // Any attempt to reuse a nonce will result in an INVALID_SIGNATURE error
-    // being returned by the server.  This will cause the loop to break early.
-    std::string response_str = network_delegate_->SendPublicKeyToDmServerSync(
-        dm_server_url, dm_token, request_str);
-    enterprise_management::DeviceManagementResponse response;
-    rc = (!response_str.empty() && response.ParseFromString(response_str) &&
-          response.has_browser_public_key_upload_response() &&
-          response.browser_public_key_upload_response().has_response_code())
-             ? response.browser_public_key_upload_response().response_code()
-             : BPKUP::UNDEFINED;
-    boe.InformOfRequest(rc == BPKUP::SUCCESS);
-  }
-
-  if (rc != BPKUP::SUCCESS) {
-    // Unable to send to DM server, so restore the old key if there was one.
-    if (key_pair_) {
-      persistence_delegate_->StoreKeyPair(trust_level_,
-                                          key_pair_->GetWrappedKey());
-    }
-    return false;
-  }
-
-  key_pair_ = std::move(new_key_pair);
-  trust_level_ = new_trust_level;
-
-  return true;
-}
-
-bool SigningKeyPair::BuildUploadPublicKeyRequest(
-    KeyTrustLevel new_trust_level,
-    const std::unique_ptr<crypto::UnexportableSigningKey>& new_key_pair,
-    const std::string& nonce,
-    enterprise_management::BrowserPublicKeyUploadRequest* request) {
-  std::vector<uint8_t> pubkey = new_key_pair->GetSubjectPublicKeyInfo();
-
-  // Build the buffer to sign.  It consists of the public key of the new key
-  // pair followed by the nonce.  The nonce vector may be empty.
-  std::vector<uint8_t> buffer = pubkey;
-  buffer.insert(buffer.end(), nonce.begin(), nonce.end());
-
-  // If there is an existing key and the nonce is not empty, sign the new
-  // pubkey with it.  Otherwise sign it with the new key itself (i.e. the
-  // public key is self-signed).  This is done to handle the case of a device
-  // that is enabled for device trust and then un-enrolled server side.  When
-  // the user re-enrolls this device, the first key rotation attempt will use
-  // an empty nonce to signal this is the first public key being uploaded to
-  // DM server.  DM server expects the public key to be self signed.
-  absl::optional<std::vector<uint8_t>> signature =
-      key_pair_ && !nonce.empty() ? key_pair_->SignSlowly(buffer)
-                                  : new_key_pair->SignSlowly(buffer);
-  if (!signature.has_value())
-    return false;
-
-  request->set_public_key(pubkey.data(), pubkey.size());
-  request->set_signature(signature->data(), signature->size());
-  request->set_key_trust_level(new_trust_level);
-
-  return true;
-}
-
-}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h
deleted file mode 100644
index 700700b..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_SIGNING_KEY_PAIR_H_
-#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_SIGNING_KEY_PAIR_H_
-
-#include <stdint.h>
-
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "components/policy/proto/device_management_backend.pb.h"
-
-class GURL;
-
-namespace crypto {
-class UnexportableKeyProvider;
-class UnexportableSigningKey;
-}  // namespace crypto
-
-namespace enterprise_connectors {
-
-namespace test {
-class ScopedTpmSigningKeyPair;
-}  // namespace test
-
-// This class manages the CBCM signing key used by DeviceTrustService and
-// DeviceTrustNavigationThrottle.  It saves and loads the key from platform
-// specific storage locations and provides methods for accessing properties
-// of the key.
-//
-// The class is implemented on Windows but the work is not yet complete on
-// other desktop platforms.  Other platforms are covered by b/194387479 (Mac)
-// and b/194891140 (Linux).  Until then this code will continue to store the
-// signing key inside the profile prefs on those platforms.
-class SigningKeyPair {
- public:
-  using KeyTrustLevel =
-      enterprise_management::BrowserPublicKeyUploadRequest::KeyTrustLevel;
-
-  using KeyInfo = std::pair<KeyTrustLevel, std::vector<uint8_t>>;
-
-  // A delegate class that handles persistence of the key pair.  There is an
-  // implementation for each platform and also for tests.
-  class PersistenceDelegate {
-   public:
-    virtual ~PersistenceDelegate() = default;
-
-    // Stores the trust level and wrapped key in a platform specific location.
-    // This method requires elevation since it writes to a location that is
-    // shared by all OS users of the device.  Returns true on success.
-    virtual bool StoreKeyPair(KeyTrustLevel trust_level,
-                              std::vector<uint8_t> wrapped);
-
-    // Loads the key from a platform specific location.  Returns
-    // BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED and an empty vector if the trust level
-    // or wrapped bits could not be loaded.
-    virtual KeyInfo LoadKeyPair();
-  };
-
-  // A delegate class that handles network requests to DM server.  There is an
-  // implementation for each platform and also for tests.
-  class NetworkDelegate {
-   public:
-    virtual ~NetworkDelegate() = default;
-
-    // Sends `body`, which is a serialized DeviceManagementRequest, to DM
-    // server at `url`.  `dm_token` authn the local machine.  Only the
-    // BrowserPublicKeyUploadRequest member is expected to be initialized.
-    //
-    // The return // value is a string that can be parsed into
-    // DeviceManagementResponse.
-    virtual std::string SendPublicKeyToDmServerSync(const GURL& url,
-                                                    const std::string& dm_token,
-                                                    const std::string& body);
-  };
-
-  static std::unique_ptr<SigningKeyPair> Create();
-
-  // Factory function that creates a SigningKeyPair with specific delegates
-  // used in some tests to control SigningKeyPair behaviour.
-  static std::unique_ptr<SigningKeyPair> CreateWithDelegates(
-      std::unique_ptr<PersistenceDelegate> persistence_delegate,
-      std::unique_ptr<NetworkDelegate> network_delegate);
-
-  SigningKeyPair(const SigningKeyPair&) = delete;
-  SigningKeyPair& operator=(const SigningKeyPair&) = delete;
-  virtual ~SigningKeyPair();
-
-  // Signs `message` and with the key and returns the signature.
-  bool SignMessage(const std::string& message, std::string* signature);
-
-  // Exports the public key to `public_key` as an X.509 SubjectPublicKeyInfo
-  // block.
-  bool ExportPublicKey(std::vector<uint8_t>* public_key);
-
-  // Rotates the key pair.  If no key pair already exists, simply creates a
-  // new one.  `dm_token` the DM token to use when sending the new public key to
-  // the DM server.  This function will fail if not called with admin rights.
-  //
-  // This function makes network requests and will block until those requests
-  // complete successfully or fail (after some retrying).  This function is
-  // not meant to be called from the chrome browser but from a background
-  // utility process that does not block the user in the browser.
-  bool RotateWithAdminRights(const GURL& dm_server_url,
-                             const std::string& dm_token,
-                             const std::string& nonce) WARN_UNUSED_RESULT;
-
- protected:
-  SigningKeyPair(std::unique_ptr<PersistenceDelegate> persistence_delegate,
-                 std::unique_ptr<NetworkDelegate> network_delegate);
-
-  // Initialize the key pair by loading from persistent storage.
-  void Init();
-
- private:
-  friend class test::ScopedTpmSigningKeyPair;
-
-  // Sets a `wrapped` TPM key and force its usage in test environments.
-  static void SetTpmKeyWrappedForTesting(const std::vector<uint8_t>& wrapped);
-
-  // Clears any previously stored wrapped TPM key.
-  static void ClearTpmKeyWrappedForTesting();
-
-  // Returns the TPM-backed signing key provider for the platform if available.
-  std::unique_ptr<crypto::UnexportableKeyProvider> GetTpmBackedKeyProvider();
-
-  // Builds the protobuf message needed to tell DM server about the new public
-  // for this device.  `nonce` is an opaque binary blob and should not be
-  // treated as an ASCII or UTF-8 string.
-  bool BuildUploadPublicKeyRequest(
-      KeyTrustLevel new_trust_level,
-      const std::unique_ptr<crypto::UnexportableSigningKey>& new_key_pair,
-      const std::string& nonce,
-      enterprise_management::BrowserPublicKeyUploadRequest* request);
-
-  std::unique_ptr<crypto::UnexportableSigningKey> key_pair_;
-  KeyTrustLevel trust_level_ = enterprise_management::
-      BrowserPublicKeyUploadRequest::KEY_TRUST_LEVEL_UNSPECIFIED;
-
-  std::unique_ptr<PersistenceDelegate> persistence_delegate_;
-  std::unique_ptr<NetworkDelegate> network_delegate_;
-};
-
-}  // namespace enterprise_connectors
-
-#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_SIGNING_KEY_PAIR_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_linux.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_linux.cc
deleted file mode 100644
index bf88715..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_linux.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
-
-#include "base/notreached.h"
-#include "crypto/unexportable_key.h"
-
-using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
-
-namespace enterprise_connectors {
-
-bool SigningKeyPair::PersistenceDelegate::StoreKeyPair(
-    KeyTrustLevel trust_level,
-    std::vector<uint8_t> wrapped) {
-  NOTIMPLEMENTED();
-  return false;
-}
-
-SigningKeyPair::KeyInfo SigningKeyPair::PersistenceDelegate::LoadKeyPair() {
-  NOTIMPLEMENTED();
-  return {BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED, std::vector<uint8_t>()};
-}
-
-std::string SigningKeyPair::NetworkDelegate::SendPublicKeyToDmServerSync(
-    const GURL& url,
-    const std::string& dm_token,
-    const std::string& body) {
-  NOTIMPLEMENTED();
-  return std::string();
-}
-
-std::unique_ptr<crypto::UnexportableKeyProvider>
-SigningKeyPair::GetTpmBackedKeyProvider() {
-  return nullptr;
-}
-
-}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_mac.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_mac.cc
deleted file mode 100644
index bf88715..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_mac.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
-
-#include "base/notreached.h"
-#include "crypto/unexportable_key.h"
-
-using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
-
-namespace enterprise_connectors {
-
-bool SigningKeyPair::PersistenceDelegate::StoreKeyPair(
-    KeyTrustLevel trust_level,
-    std::vector<uint8_t> wrapped) {
-  NOTIMPLEMENTED();
-  return false;
-}
-
-SigningKeyPair::KeyInfo SigningKeyPair::PersistenceDelegate::LoadKeyPair() {
-  NOTIMPLEMENTED();
-  return {BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED, std::vector<uint8_t>()};
-}
-
-std::string SigningKeyPair::NetworkDelegate::SendPublicKeyToDmServerSync(
-    const GURL& url,
-    const std::string& dm_token,
-    const std::string& body) {
-  NOTIMPLEMENTED();
-  return std::string();
-}
-
-std::unique_ptr<crypto::UnexportableKeyProvider>
-SigningKeyPair::GetTpmBackedKeyProvider() {
-  return nullptr;
-}
-
-}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_unittest.cc
deleted file mode 100644
index 83b525e..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_unittest.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <deque>
-#include <memory>
-#include <vector>
-
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/memory_signing_key_pair.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-using BPKUP = enterprise_management::BrowserPublicKeyUploadResponse;
-
-namespace enterprise_connectors {
-
-class SigningKeyPairTest : public testing::Test {
- protected:
-  SigningKeyPair* key_pair() { return key_pair_.get(); }
-
-  void set_force_store_to_fail(bool force_store_to_fail) {
-    ppdelegate_ptr->set_force_store_to_fail(force_store_to_fail);
-  }
-
-  void push_response_codes(
-      const std::deque<BPKUP::ResponseCode>& response_codes) {
-    pndelegate_ptr->push_response_codes(response_codes);
-  }
-
-  test::InMemorySigningKeyPairNetworkDelegate* network_delegate() {
-    return pndelegate_ptr;
-  }
-
- private:
-  test::ScopedMemorySigningKeyPairPersistence persistence_scope_;
-  test::InMemorySigningKeyPairPersistenceDelegate* ppdelegate_ptr = nullptr;
-  test::InMemorySigningKeyPairNetworkDelegate* pndelegate_ptr = nullptr;
-  std::unique_ptr<SigningKeyPair> key_pair_ =
-      test::CreateInMemorySigningKeyPair(&ppdelegate_ptr, &pndelegate_ptr);
-};
-
-TEST_F(SigningKeyPairTest, NoKeyPair) {
-  // No persisted key, so there should be no public key.
-  std::vector<uint8_t> pubkey;
-  ASSERT_FALSE(key_pair()->ExportPublicKey(&pubkey));
-
-  // No persisted key, so can't sign.
-  ASSERT_FALSE(key_pair()->SignMessage("data to sign", nullptr));
-}
-
-TEST_F(SigningKeyPairTest, Rotate) {
-  // Create a new key and save it.
-  ASSERT_TRUE(key_pair()->RotateWithAdminRights(GURL("dmserver.com"),
-                                                "fake_dm_token", "nonce"));
-}
-
-TEST_F(SigningKeyPairTest, ExportAndSign) {
-  // Create a new key and save it.
-  ASSERT_TRUE(key_pair()->RotateWithAdminRights(GURL("dmserver.com"),
-                                                "fake_dm_token", "nonce"));
-
-  // Extract a pubkey should work now.
-  std::vector<uint8_t> pubkey;
-  ASSERT_TRUE(key_pair()->ExportPublicKey(&pubkey));
-  ASSERT_GT(pubkey.size(), 0u);
-
-  // Signing should work now.
-  std::string signature;
-  ASSERT_TRUE(key_pair()->SignMessage("data to sign", &signature));
-  ASSERT_GT(signature.size(), 0u);
-}
-
-TEST_F(SigningKeyPairTest, Load) {
-  // Create a new key and save it.
-  ASSERT_TRUE(key_pair()->RotateWithAdminRights(GURL("dmserver.com"),
-                                                "fake_dm_token", "nonce"));
-
-  // Extract a pubkey should work now.
-  std::vector<uint8_t> pubkey;
-  ASSERT_TRUE(key_pair()->ExportPublicKey(&pubkey));
-  ASSERT_GT(pubkey.size(), 0u);
-
-  // A new key pair should load the same key.
-  auto key_pair2 = test::CreateInMemorySigningKeyPair(nullptr, nullptr);
-  std::vector<uint8_t> pubkey2;
-  ASSERT_TRUE(key_pair2->ExportPublicKey(&pubkey2));
-  ASSERT_GT(pubkey2.size(), 0u);
-
-  ASSERT_EQ(pubkey, pubkey2);
-}
-
-TEST_F(SigningKeyPairTest, FailedSaveKeepsOldKey) {
-  // Create a new key and save it.
-  ASSERT_TRUE(key_pair()->RotateWithAdminRights(GURL("dmserver.com"),
-                                                "fake_dm_token", "nonce"));
-
-  // Extract a pubkey should work now.
-  std::vector<uint8_t> pubkey;
-  ASSERT_TRUE(key_pair()->ExportPublicKey(&pubkey));
-  ASSERT_GT(pubkey.size(), 0u);
-
-  set_force_store_to_fail(true);
-
-  ASSERT_FALSE(key_pair()->RotateWithAdminRights(GURL("dmserver.com"),
-                                                 "fake_dm_token", "nonce"));
-  std::vector<uint8_t> pubkey2;
-  ASSERT_TRUE(key_pair()->ExportPublicKey(&pubkey2));
-  ASSERT_EQ(pubkey, pubkey2);
-}
-
-TEST_F(SigningKeyPairTest, FailedNetworkKeepsOldKey) {
-  // Create a new key and save it.
-  ASSERT_TRUE(key_pair()->RotateWithAdminRights(GURL("dmserver.com"),
-                                                "fake_dm_token", "nonce"));
-
-  // Extract a pubkey should work now.
-  std::vector<uint8_t> pubkey;
-  ASSERT_TRUE(key_pair()->ExportPublicKey(&pubkey));
-  ASSERT_GT(pubkey.size(), 0u);
-
-  push_response_codes({BPKUP::INVALID_SIGNATURE});
-
-  ASSERT_FALSE(key_pair()->RotateWithAdminRights(GURL("dmserver.com"),
-                                                 "fake_dm_token", "nonce"));
-  std::vector<uint8_t> pubkey2;
-  ASSERT_TRUE(key_pair()->ExportPublicKey(&pubkey2));
-  ASSERT_EQ(pubkey, pubkey2);
-
-  // Send count should be 2: one for the initial rotate that works, and a
-  // second for the rotate that fails.
-  EXPECT_EQ(network_delegate()->send_count(), 2);
-}
-
-TEST_F(SigningKeyPairTest, RetryAndSuccessNetworkKeepsNewKey) {
-  // Create a new key and save it.
-  ASSERT_TRUE(key_pair()->RotateWithAdminRights(GURL("dmserver.com"),
-                                                "fake_dm_token", "nonce"));
-
-  // Extract a pubkey should work now.
-  std::vector<uint8_t> pubkey;
-  ASSERT_TRUE(key_pair()->ExportPublicKey(&pubkey));
-  ASSERT_GT(pubkey.size(), 0u);
-
-  push_response_codes({BPKUP::UNDEFINED, BPKUP::SUCCESS});
-
-  ASSERT_TRUE(key_pair()->RotateWithAdminRights(GURL("dmserver.com"),
-                                                "fake_dm_token", "nonce"));
-  std::vector<uint8_t> pubkey2;
-  ASSERT_TRUE(key_pair()->ExportPublicKey(&pubkey2));
-  ASSERT_NE(pubkey, pubkey2);
-
-  // Send count should be 3: one for the initial rotate that works and two
-  // more for the rotate that fails with retries.
-  EXPECT_EQ(network_delegate()->send_count(), 3);
-}
-
-TEST_F(SigningKeyPairTest, RetryAndFailedNetworkKeepsOldKey) {
-  // Create a new key and save it.
-  ASSERT_TRUE(key_pair()->RotateWithAdminRights(GURL("dmserver.com"),
-                                                "fake_dm_token", "nonce"));
-
-  // Extract a pubkey should work now.
-  std::vector<uint8_t> pubkey;
-  ASSERT_TRUE(key_pair()->ExportPublicKey(&pubkey));
-  ASSERT_GT(pubkey.size(), 0u);
-
-  push_response_codes(
-      {BPKUP::UNDEFINED, BPKUP::UNDEFINED, BPKUP::INVALID_SIGNATURE});
-
-  ASSERT_FALSE(key_pair()->RotateWithAdminRights(GURL("dmserver.com"),
-                                                 "fake_dm_token", "nonce"));
-  std::vector<uint8_t> pubkey2;
-  ASSERT_TRUE(key_pair()->ExportPublicKey(&pubkey2));
-  ASSERT_EQ(pubkey, pubkey2);
-
-  // Send count should be 4: one for the initial rotate that works and three
-  // more for the rotate that fails with retries.
-  EXPECT_EQ(network_delegate()->send_count(), 4);
-}
-
-}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_win.cc b/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_win.cc
deleted file mode 100644
index 201a2f5e..0000000
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_win.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright 2021 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
-
-#include "base/callback_helpers.h"
-#include "base/containers/flat_map.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/run_loop.h"
-#include "base/win/registry.h"
-#include "chrome/installer/util/install_util.h"
-#include "components/winhttp/network_fetcher.h"
-#include "components/winhttp/scoped_hinternet.h"
-#include "crypto/unexportable_key.h"
-
-using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
-
-namespace enterprise_connectors {
-
-namespace {
-
-SigningKeyPair::KeyInfo InvalidKeyInfo() {
-  return {BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED, std::vector<uint8_t>()};
-}
-
-}  // namespace
-
-bool SigningKeyPair::PersistenceDelegate::StoreKeyPair(
-    KeyTrustLevel trust_level,
-    std::vector<uint8_t> wrapped) {
-  base::win::RegKey key;
-  std::wstring signingkey_name;
-  std::wstring trustlevel_name;
-  std::tie(key, signingkey_name, trustlevel_name) =
-      InstallUtil::GetDeviceTrustSigningKeyLocation(
-          InstallUtil::ReadOnly(false));
-  if (!key.Valid())
-    return false;
-
-  return key.WriteValue(signingkey_name.c_str(), wrapped.data(), wrapped.size(),
-                        REG_BINARY) == ERROR_SUCCESS &&
-         key.WriteValue(trustlevel_name.c_str(), trust_level) == ERROR_SUCCESS;
-}
-
-SigningKeyPair::KeyInfo SigningKeyPair::PersistenceDelegate::LoadKeyPair() {
-  base::win::RegKey key;
-  std::wstring signingkey_name;
-  std::wstring trustlevel_name;
-  std::tie(key, signingkey_name, trustlevel_name) =
-      InstallUtil::GetDeviceTrustSigningKeyLocation(
-          InstallUtil::ReadOnly(true));
-  if (!key.Valid())
-    return InvalidKeyInfo();
-
-  DWORD trust_level_dw;
-  auto res = key.ReadValueDW(trustlevel_name.c_str(), &trust_level_dw);
-  if (res != ERROR_SUCCESS)
-    return InvalidKeyInfo();
-
-  KeyTrustLevel trust_level = BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED;
-  if (trust_level_dw == BPKUR::CHROME_BROWSER_TPM_KEY) {
-    trust_level = BPKUR::CHROME_BROWSER_TPM_KEY;
-  } else if (trust_level_dw == BPKUR::CHROME_BROWSER_OS_KEY) {
-    trust_level = BPKUR::CHROME_BROWSER_OS_KEY;
-  } else {
-    return InvalidKeyInfo();
-  }
-
-  std::vector<uint8_t> wrapped;
-  DWORD type = REG_NONE;
-  DWORD size = 0;
-  res = key.ReadValue(signingkey_name.c_str(), nullptr, &size, &type);
-  if (res == ERROR_SUCCESS && type == REG_BINARY) {
-    wrapped.resize(size);
-    res = key.ReadValue(signingkey_name.c_str(), wrapped.data(), &size, &type);
-  }
-  if (res != ERROR_SUCCESS || type != REG_BINARY)
-    return InvalidKeyInfo();
-
-  return {trust_level, wrapped};
-}
-
-std::string SigningKeyPair::NetworkDelegate::SendPublicKeyToDmServerSync(
-    const GURL& url,
-    const std::string& dm_token,
-    const std::string& body) {
-  base::flat_map<std::string, std::string> headers;
-  headers.emplace("Authorization", "GoogleDMToken token=" + dm_token);
-
-  // TODO(b/202321214): need to pass in winhttp::ProxyInfo somehow.
-  // If specified use it to create an winhttp::ProxyConfiguration instance.
-  // Otherwise create an winhttp::AutoProxyConfiguration instance.
-  auto proxy_config = base::MakeRefCounted<winhttp::ProxyConfiguration>();
-  auto session = winhttp::CreateSessionHandle(L"DeviceTrustKeyManagement",
-                                              proxy_config->access_type());
-  auto fetcher = base::MakeRefCounted<winhttp::NetworkFetcher>(session.get(),
-                                                               proxy_config);
-
-  base::RunLoop run_loop;
-  fetcher->PostRequest(url, body, std::string(), headers, base::DoNothing(),
-                       base::DoNothing(), run_loop.QuitClosure());
-  run_loop.Run();
-
-  return fetcher->GetResponseBody();
-}
-
-std::unique_ptr<crypto::UnexportableKeyProvider>
-SigningKeyPair::GetTpmBackedKeyProvider() {
-  return crypto::GetUnexportableKeyProvider();
-}
-
-}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_browsertest.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_browsertest.cc
index 1bb0d3e..49662bf 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_browsertest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_browsertest.cc
@@ -14,8 +14,8 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/enterprise/connectors/connectors_prefs.h"
 #include "chrome/browser/enterprise/connectors/connectors_service.h"
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/scoped_tpm_signing_key_pair.h"
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_features.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.h"
 #include "chrome/browser/enterprise/signals/device_info_fetcher.h"
 #include "chrome/browser/policy/chrome_browser_policy_connector.h"
 #include "chrome/browser/policy/dm_token_utils.h"
@@ -99,7 +99,7 @@
   void SetUpOnMainThread() override {
     InProcessBrowserTest::SetUpOnMainThread();
 
-    scoped_tpm_signing_key_pair_.emplace();
+    scoped_persistence_delegate_factory_.emplace();
     enterprise_signals::DeviceInfoFetcher::SetForceStubForTesting(true);
 
     auto* browser_policy_manager =
@@ -206,7 +206,8 @@
       initial_attestation_request_;
   absl::optional<const net::test_server::HttpRequest>
       challenge_response_request_;
-  absl::optional<test::ScopedTpmSigningKeyPair> scoped_tpm_signing_key_pair_;
+  absl::optional<test::ScopedKeyPersistenceDelegateFactory>
+      scoped_persistence_delegate_factory_;
 };
 
 // Tests that the whole attestation flow occurs when navigating to an allowed
diff --git a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
index 8178006..242e763 100644
--- a/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/device_trust_service_factory.cc
@@ -8,8 +8,9 @@
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "chrome/browser/enterprise/connectors/device_trust/attestation/common/attestation_service.h"
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
 #include "chrome/browser/enterprise/connectors/device_trust/device_trust_service.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h"
 #include "chrome/browser/enterprise/connectors/device_trust/signals/signals_service.h"
 #include "chrome/browser/enterprise/connectors/device_trust/signals/signals_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
@@ -66,9 +67,10 @@
 
   std::unique_ptr<AttestationService> attestation_service =
       std::make_unique<DesktopAttestationService>(
-          SigningKeyPair::Create(),
           g_browser_process->browser_policy_connector()
-              ->device_management_service());
+              ->device_management_service(),
+          KeyPersistenceDelegateFactory::GetInstance()
+              ->CreateKeyPersistenceDelegate());
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   return new DeviceTrustService(
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/key_management/core/BUILD.gn
new file mode 100644
index 0000000..9f038619
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/BUILD.gn
@@ -0,0 +1,41 @@
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("core") {
+  public = [
+    "ec_signing_key.h",
+    "signing_key_pair.h",
+  ]
+
+  sources = [
+    "ec_signing_key.cc",
+    "signing_key_pair.cc",
+  ]
+
+  deps = [ "//base" ]
+
+  public_deps = [
+    "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence",
+    "//components/policy/proto",
+    "//crypto",
+    "//third_party/abseil-cpp:absl",
+  ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [
+    "ec_signing_key_unittest.cc",
+    "signing_key_pair_unittest.cc",
+  ]
+
+  deps = [
+    ":core",
+    "//base",
+    "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence:test_support",
+    "//crypto",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
+}
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.cc
similarity index 96%
rename from chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key.cc
rename to chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.cc
index 9e5ded7..1c7b50e5 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h"
 
 #include <memory>
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h
similarity index 80%
rename from chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key.h
rename to chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h
index 7951dba..b3df3a4 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key.h
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_EC_SIGNING_KEY_H_
-#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_EC_SIGNING_KEY_H_
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_EC_SIGNING_KEY_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_EC_SIGNING_KEY_H_
 
 #include <memory>
 #include <vector>
@@ -33,4 +33,4 @@
 
 }  // namespace enterprise_connectors
 
-#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_ATTESTATION_DESKTOP_EC_SIGNING_KEY_H_
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_EC_SIGNING_KEY_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key_unittest.cc
similarity index 96%
rename from chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key_unittest.cc
rename to chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key_unittest.cc
index be7df891..2ceabf5 100644
--- a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key_unittest.cc
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h"
 
 #include <memory>
 
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/BUILD.gn
new file mode 100644
index 0000000..16453f2
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/BUILD.gn
@@ -0,0 +1,38 @@
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("network") {
+  public = [
+    "key_network_delegate.h",
+    "key_network_delegate_factory.h",
+  ]
+
+  sources = [ "key_network_delegate_factory.cc" ]
+
+  deps = [ "//base" ]
+
+  if (is_win) {
+    sources += [
+      "win_key_network_delegate.cc",
+      "win_key_network_delegate.h",
+    ]
+    deps += [
+      "//components/winhttp",
+      "//url",
+    ]
+  }
+}
+
+source_set("test_support") {
+  testonly = true
+  public = [ "mock_key_network_delegate.h" ]
+
+  sources = [ "mock_key_network_delegate.cc" ]
+
+  public_deps = [
+    ":network",
+    "//testing/gmock",
+    "//url",
+  ]
+}
diff --git a/chrome/browser/enterprise/connectors/device_trust/attestation/desktop/DEPS b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/DEPS
similarity index 100%
rename from chrome/browser/enterprise/connectors/device_trust/attestation/desktop/DEPS
rename to chrome/browser/enterprise/connectors/device_trust/key_management/core/network/DEPS
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h
new file mode 100644
index 0000000..2dd833bb
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h
@@ -0,0 +1,33 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_KEY_NETWORK_DELEGATE_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_KEY_NETWORK_DELEGATE_H_
+
+#include <string>
+
+class GURL;
+
+namespace enterprise_connectors {
+
+// A delegate class that handles persistence of the key pair.  There is an
+// implementation for each platform and also for tests.
+class KeyNetworkDelegate {
+ public:
+  virtual ~KeyNetworkDelegate() = default;
+
+  // Sends `body`, which is a serialized DeviceManagementRequest, to DM
+  // server at `url`.  `dm_token` authn the local machine.  Only the
+  // BrowserPublicKeyUploadRequest member is expected to be initialized.
+  //
+  // The return value is a string that can be parsed into
+  // DeviceManagementResponse.
+  virtual std::string SendPublicKeyToDmServerSync(const GURL& url,
+                                                  const std::string& dm_token,
+                                                  const std::string& body) = 0;
+};
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_KEY_NETWORK_DELEGATE_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate_factory.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate_factory.cc
new file mode 100644
index 0000000..640557da
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate_factory.cc
@@ -0,0 +1,26 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate_factory.h"
+
+#include "base/notreached.h"
+#include "build/build_config.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h"
+
+#if defined(OS_WIN)
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h"
+#endif
+
+namespace enterprise_connectors {
+
+std::unique_ptr<KeyNetworkDelegate> CreateKeyNetworkDelegate() {
+#if defined(OS_WIN)
+  return std::make_unique<WinKeyNetworkDelegate>();
+#else
+  NOTREACHED();
+  return nullptr;
+#endif  // defined(OS_WIN)
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate_factory.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate_factory.h
new file mode 100644
index 0000000..e1bdf04f
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate_factory.h
@@ -0,0 +1,19 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_KEY_NETWORK_DELEGATE_FACTORY_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_KEY_NETWORK_DELEGATE_FACTORY_H_
+
+#include <memory>
+
+namespace enterprise_connectors {
+
+class KeyNetworkDelegate;
+
+// A factory function to create a NetworkDelegate.
+std::unique_ptr<KeyNetworkDelegate> CreateKeyNetworkDelegate();
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_KEY_NETWORK_DELEGATE_FACTORY_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.cc
new file mode 100644
index 0000000..153d37f
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.cc
@@ -0,0 +1,14 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h"
+
+namespace enterprise_connectors {
+namespace test {
+
+MockKeyNetworkDelegate::MockKeyNetworkDelegate() = default;
+MockKeyNetworkDelegate::~MockKeyNetworkDelegate() = default;
+
+}  // namespace test
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h
new file mode 100644
index 0000000..41eb8812
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h
@@ -0,0 +1,31 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_MOCK_KEY_NETWORK_DELEGATE_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_MOCK_KEY_NETWORK_DELEGATE_H_
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h"
+
+#include "testing/gmock/include/gmock/gmock.h"
+#include "url/gurl.h"
+
+namespace enterprise_connectors {
+namespace test {
+
+// Mocked implementation of the KeyNetworkDelegate interface.
+class MockKeyNetworkDelegate : public KeyNetworkDelegate {
+ public:
+  MockKeyNetworkDelegate();
+  ~MockKeyNetworkDelegate() override;
+
+  MOCK_METHOD(std::string,
+              SendPublicKeyToDmServerSync,
+              (const GURL&, const std::string&, const std::string&),
+              (override));
+};
+
+}  // namespace test
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_MOCK_KEY_NETWORK_DELEGATE_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.cc
new file mode 100644
index 0000000..8f300d6
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.cc
@@ -0,0 +1,44 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h"
+
+#include "base/callback_helpers.h"
+#include "base/containers/flat_map.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/run_loop.h"
+#include "components/winhttp/network_fetcher.h"
+#include "components/winhttp/scoped_hinternet.h"
+#include "url/gurl.h"
+
+namespace enterprise_connectors {
+
+WinKeyNetworkDelegate::WinKeyNetworkDelegate() = default;
+WinKeyNetworkDelegate::~WinKeyNetworkDelegate() = default;
+
+std::string WinKeyNetworkDelegate::SendPublicKeyToDmServerSync(
+    const GURL& url,
+    const std::string& dm_token,
+    const std::string& body) {
+  base::flat_map<std::string, std::string> headers;
+  headers.emplace("Authorization", "GoogleDMToken token=" + dm_token);
+
+  // TODO(b/202321214): need to pass in winhttp::ProxyInfo somehow.
+  // If specified use it to create an winhttp::ProxyConfiguration instance.
+  // Otherwise create an winhttp::AutoProxyConfiguration instance.
+  auto proxy_config = base::MakeRefCounted<winhttp::ProxyConfiguration>();
+  auto session = winhttp::CreateSessionHandle(L"DeviceTrustKeyManagement",
+                                              proxy_config->access_type());
+  auto fetcher = base::MakeRefCounted<winhttp::NetworkFetcher>(session.get(),
+                                                               proxy_config);
+
+  base::RunLoop run_loop;
+  fetcher->PostRequest(url, body, std::string(), headers, base::DoNothing(),
+                       base::DoNothing(), run_loop.QuitClosure());
+  run_loop.Run();
+
+  return fetcher->GetResponseBody();
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h
new file mode 100644
index 0000000..12524d6
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/network/win_key_network_delegate.h
@@ -0,0 +1,26 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_WIN_KEY_NETWORK_DELEGATE_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_WIN_KEY_NETWORK_DELEGATE_H_
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h"
+
+namespace enterprise_connectors {
+
+// Windows implementation of the KeyNetworkDelegate interface.
+class WinKeyNetworkDelegate : public KeyNetworkDelegate {
+ public:
+  WinKeyNetworkDelegate();
+  ~WinKeyNetworkDelegate() override;
+
+  // KeyNetworkDelegate:
+  std::string SendPublicKeyToDmServerSync(const GURL& url,
+                                          const std::string& dm_token,
+                                          const std::string& body) override;
+};
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_NETWORK_WIN_KEY_NETWORK_DELEGATE_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/BUILD.gn
new file mode 100644
index 0000000..57def1e
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/BUILD.gn
@@ -0,0 +1,66 @@
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("persistence") {
+  public = [
+    "key_persistence_delegate.h",
+    "key_persistence_delegate_factory.h",
+  ]
+
+  sources = [ "key_persistence_delegate_factory.cc" ]
+
+  deps = [ "//base" ]
+
+  public_deps = [
+    "//components/policy/proto",
+    "//crypto",
+  ]
+
+  if (is_win) {
+    sources += [
+      "win_key_persistence_delegate.cc",
+      "win_key_persistence_delegate.h",
+    ]
+    deps += [ "//chrome/installer/util:with_no_strings" ]
+  }
+
+  if (is_mac) {
+    sources += [
+      "mac_key_persistence_delegate.cc",
+      "mac_key_persistence_delegate.h",
+    ]
+  }
+
+  if (is_linux) {
+    sources += [
+      "linux_key_persistence_delegate.cc",
+      "linux_key_persistence_delegate.h",
+    ]
+  }
+}
+
+source_set("test_support") {
+  testonly = true
+  public = [
+    "mock_key_persistence_delegate.h",
+    "scoped_key_persistence_delegate_factory.h",
+  ]
+
+  sources = [
+    "mock_key_persistence_delegate.cc",
+    "scoped_key_persistence_delegate_factory.cc",
+  ]
+
+  public_deps = [
+    ":persistence",
+    "//crypto:test_support",
+    "//testing/gmock",
+    "//testing/gtest",
+  ]
+
+  deps = [
+    "//base",
+    "//crypto",
+  ]
+}
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h
new file mode 100644
index 0000000..65b5fc2
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h
@@ -0,0 +1,51 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_KEY_PERSISTENCE_DELEGATE_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_KEY_PERSISTENCE_DELEGATE_H_
+
+#include <memory>
+#include <vector>
+
+#include "components/policy/proto/device_management_backend.pb.h"
+#include "crypto/unexportable_key.h"
+
+namespace enterprise_connectors {
+
+// Interface for classes that handle persistence of the key pair. There is an
+// implementation for each platform.
+class KeyPersistenceDelegate {
+ public:
+  using KeyTrustLevel =
+      enterprise_management::BrowserPublicKeyUploadRequest::KeyTrustLevel;
+  using KeyInfo = std::pair<KeyTrustLevel, std::vector<uint8_t>>;
+  virtual ~KeyPersistenceDelegate() = default;
+
+  // Stores the trust level and wrapped key in a platform specific location.
+  // This method requires elevation since it writes to a location that is
+  // shared by all OS users of the device.  Returns true on success.
+  virtual bool StoreKeyPair(KeyTrustLevel trust_level,
+                            std::vector<uint8_t> wrapped) = 0;
+
+  // Loads the key from a platform specific location.  Returns
+  // BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED and an empty vector if the trust level
+  // or wrapped bits could not be loaded.
+  virtual KeyInfo LoadKeyPair() = 0;
+
+  // Returns the TPM-backed signing key provider for the platform if available.
+  virtual std::unique_ptr<crypto::UnexportableKeyProvider>
+  GetTpmBackedKeyProvider() = 0;
+
+ protected:
+  // Returns an invalid key info.
+  KeyInfo invalid_key_info() {
+    return {enterprise_management::BrowserPublicKeyUploadRequest::
+                KEY_TRUST_LEVEL_UNSPECIFIED,
+            std::vector<uint8_t>()};
+  }
+};
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_KEY_PERSISTENCE_DELEGATE_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.cc
new file mode 100644
index 0000000..9883ca01
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.cc
@@ -0,0 +1,67 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h"
+
+#include "base/memory/singleton.h"
+#include "base/notreached.h"
+#include "build/build_config.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h"
+
+#if defined(OS_WIN)
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.h"
+#elif defined(OS_MAC)
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.h"
+#elif defined(OS_LINUX)
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.h"
+#endif
+
+namespace enterprise_connectors {
+
+namespace {
+
+absl::optional<KeyPersistenceDelegateFactory*>& GetTestInstanceStorage() {
+  static absl::optional<KeyPersistenceDelegateFactory*> storage;
+  return storage;
+}
+
+}  // namespace
+
+// static
+KeyPersistenceDelegateFactory* KeyPersistenceDelegateFactory::GetInstance() {
+  absl::optional<KeyPersistenceDelegateFactory*>& test_instance =
+      GetTestInstanceStorage();
+  if (test_instance.has_value() && test_instance.value()) {
+    return test_instance.value();
+  }
+  return base::Singleton<KeyPersistenceDelegateFactory>::get();
+}
+
+std::unique_ptr<KeyPersistenceDelegate>
+KeyPersistenceDelegateFactory::CreateKeyPersistenceDelegate() {
+#if defined(OS_WIN)
+  return std::make_unique<WinKeyPersistenceDelegate>();
+#elif defined(OS_MAC)
+  return std::make_unique<MacKeyPersistenceDelegate>();
+#elif defined(OS_LINUX)
+  return std::make_unique<LinuxKeyPersistenceDelegate>();
+#else
+  NOTREACHED();
+  return nullptr;
+#endif
+}
+
+// static
+void KeyPersistenceDelegateFactory::SetInstanceForTesting(
+    KeyPersistenceDelegateFactory* factory) {
+  DCHECK(factory);
+  GetTestInstanceStorage().emplace(factory);
+}
+
+// static
+void KeyPersistenceDelegateFactory::ClearInstanceForTesting() {
+  GetTestInstanceStorage().reset();
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h
new file mode 100644
index 0000000..3b60d5f3
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h
@@ -0,0 +1,32 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_KEY_PERSISTENCE_DELEGATE_FACTORY_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_KEY_PERSISTENCE_DELEGATE_FACTORY_H_
+
+#include <memory>
+
+namespace enterprise_connectors {
+
+class KeyPersistenceDelegate;
+
+class KeyPersistenceDelegateFactory {
+ public:
+  virtual ~KeyPersistenceDelegateFactory() = default;
+
+  // Returns the singleton factory instance.
+  static KeyPersistenceDelegateFactory* GetInstance();
+
+  // Returns a new KeyPersistenceDelegate instance.
+  virtual std::unique_ptr<KeyPersistenceDelegate>
+  CreateKeyPersistenceDelegate();
+
+ protected:
+  static void SetInstanceForTesting(KeyPersistenceDelegateFactory* factory);
+  static void ClearInstanceForTesting();
+};
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_KEY_PERSISTENCE_DELEGATE_FACTORY_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.cc
new file mode 100644
index 0000000..11390a9
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.cc
@@ -0,0 +1,31 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.h"
+
+#include "base/notreached.h"
+
+namespace enterprise_connectors {
+
+LinuxKeyPersistenceDelegate::~LinuxKeyPersistenceDelegate() = default;
+
+bool LinuxKeyPersistenceDelegate::StoreKeyPair(
+    KeyPersistenceDelegate::KeyTrustLevel trust_level,
+    std::vector<uint8_t> wrapped) {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+KeyPersistenceDelegate::KeyInfo LinuxKeyPersistenceDelegate::LoadKeyPair() {
+  NOTIMPLEMENTED();
+  return invalid_key_info();
+}
+
+std::unique_ptr<crypto::UnexportableKeyProvider>
+LinuxKeyPersistenceDelegate::GetTpmBackedKeyProvider() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.h
new file mode 100644
index 0000000..764d8a6
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/linux_key_persistence_delegate.h
@@ -0,0 +1,27 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_LINUX_KEY_PERSISTENCE_DELEGATE_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_LINUX_KEY_PERSISTENCE_DELEGATE_H_
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h"
+
+namespace enterprise_connectors {
+
+// Linux implementation of the KeyPersistenceDelegate interface.
+class LinuxKeyPersistenceDelegate : public KeyPersistenceDelegate {
+ public:
+  ~LinuxKeyPersistenceDelegate() override;
+
+  // KeyPersistenceDelegate:
+  bool StoreKeyPair(KeyPersistenceDelegate::KeyTrustLevel trust_level,
+                    std::vector<uint8_t> wrapped) override;
+  KeyPersistenceDelegate::KeyInfo LoadKeyPair() override;
+  std::unique_ptr<crypto::UnexportableKeyProvider> GetTpmBackedKeyProvider()
+      override;
+};
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_LINUX_KEY_PERSISTENCE_DELEGATE_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.cc
new file mode 100644
index 0000000..cbb07cef
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.cc
@@ -0,0 +1,30 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.h"
+
+#include "base/notreached.h"
+
+namespace enterprise_connectors {
+
+MacKeyPersistenceDelegate::~MacKeyPersistenceDelegate() = default;
+
+bool MacKeyPersistenceDelegate::StoreKeyPair(KeyTrustLevel trust_level,
+                                             std::vector<uint8_t> wrapped) {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+KeyPersistenceDelegate::KeyInfo MacKeyPersistenceDelegate::LoadKeyPair() {
+  NOTIMPLEMENTED();
+  return invalid_key_info();
+}
+
+std::unique_ptr<crypto::UnexportableKeyProvider>
+MacKeyPersistenceDelegate::GetTpmBackedKeyProvider() {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.h
new file mode 100644
index 0000000..cc7b780d
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mac_key_persistence_delegate.h
@@ -0,0 +1,27 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_MAC_KEY_PERSISTENCE_DELEGATE_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_MAC_KEY_PERSISTENCE_DELEGATE_H_
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h"
+
+namespace enterprise_connectors {
+
+// Mac implementation of the KeyPersistenceDelegate interface.
+class MacKeyPersistenceDelegate : public KeyPersistenceDelegate {
+ public:
+  ~MacKeyPersistenceDelegate() override;
+
+  // KeyPersistenceDelegate:
+  bool StoreKeyPair(KeyPersistenceDelegate::KeyTrustLevel trust_level,
+                    std::vector<uint8_t> wrapped) override;
+  KeyPersistenceDelegate::KeyInfo LoadKeyPair() override;
+  std::unique_ptr<crypto::UnexportableKeyProvider> GetTpmBackedKeyProvider()
+      override;
+};
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_MAC_KEY_PERSISTENCE_DELEGATE_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.cc
new file mode 100644
index 0000000..db45ef9
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.cc
@@ -0,0 +1,14 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h"
+
+namespace enterprise_connectors {
+namespace test {
+
+MockKeyPersistenceDelegate::MockKeyPersistenceDelegate() = default;
+MockKeyPersistenceDelegate::~MockKeyPersistenceDelegate() = default;
+
+}  // namespace test
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h
new file mode 100644
index 0000000..a5fce03
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h
@@ -0,0 +1,35 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_MOCK_KEY_PERSISTENCE_DELEGATE_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_MOCK_KEY_PERSISTENCE_DELEGATE_H_
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace enterprise_connectors {
+namespace test {
+
+// Mock implementation of the KeyPersistenceDelegate interface.
+class MockKeyPersistenceDelegate : public KeyPersistenceDelegate {
+ public:
+  MockKeyPersistenceDelegate();
+  ~MockKeyPersistenceDelegate() override;
+
+  // KeyPersistenceDelegate:
+  MOCK_METHOD(bool,
+              StoreKeyPair,
+              (KeyPersistenceDelegate::KeyTrustLevel, std::vector<uint8_t>),
+              (override));
+  MOCK_METHOD(KeyPersistenceDelegate::KeyInfo, LoadKeyPair, (), (override));
+  MOCK_METHOD(std::unique_ptr<crypto::UnexportableKeyProvider>,
+              GetTpmBackedKeyProvider,
+              (),
+              (override));
+};
+
+}  // namespace test
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_MOCK_KEY_PERSISTENCE_DELEGATE_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.cc
new file mode 100644
index 0000000..3a007aae
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.cc
@@ -0,0 +1,57 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.h"
+
+#include "base/check.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h"
+#include "crypto/signature_verifier.h"
+#include "crypto/unexportable_key.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
+
+namespace enterprise_connectors {
+namespace test {
+
+ScopedKeyPersistenceDelegateFactory::ScopedKeyPersistenceDelegateFactory() {
+  // Generating and forcing the usage of a mocked TPM wrapped key to allow
+  // tests to skip having to rotate/store the key itself.
+  auto provider = crypto::GetUnexportableKeyProvider();
+  DCHECK(provider);
+  const crypto::SignatureVerifier::SignatureAlgorithm algorithms[] = {
+      crypto::SignatureVerifier::ECDSA_SHA256};
+  auto signing_key = provider->GenerateSigningKeySlowly(algorithms);
+  DCHECK(signing_key);
+  wrapped_key_ = signing_key->GetWrappedKey();
+
+  KeyPersistenceDelegateFactory::SetInstanceForTesting(this);
+}
+
+ScopedKeyPersistenceDelegateFactory::~ScopedKeyPersistenceDelegateFactory() {
+  KeyPersistenceDelegateFactory::ClearInstanceForTesting();
+}
+
+std::unique_ptr<MockKeyPersistenceDelegate>
+ScopedKeyPersistenceDelegateFactory::CreateMockedDelegate() {
+  auto mocked_delegate = std::make_unique<MockKeyPersistenceDelegate>();
+  ON_CALL(*mocked_delegate.get(), LoadKeyPair)
+      .WillByDefault(testing::Return(KeyPersistenceDelegate::KeyInfo(
+          BPKUR::CHROME_BROWSER_TPM_KEY, wrapped_key_)));
+  ON_CALL(*mocked_delegate.get(), GetTpmBackedKeyProvider)
+      .WillByDefault(testing::Invoke([]() {
+        // This is mocked via crypto::ScopedMockUnexportableKeyProvider.
+        return crypto::GetUnexportableKeyProvider();
+      }));
+  return mocked_delegate;
+}
+
+std::unique_ptr<KeyPersistenceDelegate>
+ScopedKeyPersistenceDelegateFactory::CreateKeyPersistenceDelegate() {
+  return CreateMockedDelegate();
+}
+
+}  // namespace test
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.h
new file mode 100644
index 0000000..c8e3606
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.h
@@ -0,0 +1,47 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_SCOPED_KEY_PERSISTENCE_DELEGATE_FACTORY_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_SCOPED_KEY_PERSISTENCE_DELEGATE_FACTORY_H_
+
+#include <stdint.h>
+
+#include <vector>
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h"
+#include "crypto/scoped_mock_unexportable_key_provider.h"
+
+namespace enterprise_connectors {
+namespace test {
+class MockKeyPersistenceDelegate;
+
+// Class used in tests to mock retrieval of TPM signing key pairs. Creating an
+// instance of this will prevent tests from having to actually store signing
+// key pairs (which requires an elevated process).
+class ScopedKeyPersistenceDelegateFactory
+    : public KeyPersistenceDelegateFactory {
+ public:
+  ScopedKeyPersistenceDelegateFactory();
+  ~ScopedKeyPersistenceDelegateFactory() override;
+
+  // Returns the TPM wrapped key.
+  const std::vector<uint8_t>& wrapped_key() { return wrapped_key_; }
+
+  // Returns a mocked instance which is already setup to mimic a TPM-backed
+  // persistence delegate (with a provider and valid key).
+  std::unique_ptr<MockKeyPersistenceDelegate> CreateMockedDelegate();
+
+  // KeyPersistenceDelegateFactory:
+  std::unique_ptr<KeyPersistenceDelegate> CreateKeyPersistenceDelegate()
+      override;
+
+ private:
+  crypto::ScopedMockUnexportableKeyProvider scoped_key_provider_;
+  std::vector<uint8_t> wrapped_key_;
+};
+
+}  // namespace test
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_SCOPED_KEY_PERSISTENCE_DELEGATE_FACTORY_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.cc
new file mode 100644
index 0000000..f0dd5a1
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.cc
@@ -0,0 +1,77 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.h"
+
+#include "base/win/registry.h"
+#include "chrome/installer/util/install_util.h"
+
+using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
+using BPKUP = enterprise_management::BrowserPublicKeyUploadResponse;
+
+namespace enterprise_connectors {
+
+WinKeyPersistenceDelegate::~WinKeyPersistenceDelegate() = default;
+
+bool WinKeyPersistenceDelegate::StoreKeyPair(
+    KeyPersistenceDelegate::KeyTrustLevel trust_level,
+    std::vector<uint8_t> wrapped) {
+  base::win::RegKey key;
+  std::wstring signingkey_name;
+  std::wstring trustlevel_name;
+  std::tie(key, signingkey_name, trustlevel_name) =
+      InstallUtil::GetDeviceTrustSigningKeyLocation(
+          InstallUtil::ReadOnly(false));
+  if (!key.Valid())
+    return false;
+
+  return key.WriteValue(signingkey_name.c_str(), wrapped.data(), wrapped.size(),
+                        REG_BINARY) == ERROR_SUCCESS &&
+         key.WriteValue(trustlevel_name.c_str(), trust_level) == ERROR_SUCCESS;
+}
+
+KeyPersistenceDelegate::KeyInfo WinKeyPersistenceDelegate::LoadKeyPair() {
+  base::win::RegKey key;
+  std::wstring signingkey_name;
+  std::wstring trustlevel_name;
+  std::tie(key, signingkey_name, trustlevel_name) =
+      InstallUtil::GetDeviceTrustSigningKeyLocation(
+          InstallUtil::ReadOnly(true));
+  if (!key.Valid())
+    return invalid_key_info();
+
+  DWORD trust_level_dw;
+  auto res = key.ReadValueDW(trustlevel_name.c_str(), &trust_level_dw);
+  if (res != ERROR_SUCCESS)
+    return invalid_key_info();
+
+  KeyTrustLevel trust_level = BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED;
+  if (trust_level_dw == BPKUR::CHROME_BROWSER_TPM_KEY) {
+    trust_level = BPKUR::CHROME_BROWSER_TPM_KEY;
+  } else if (trust_level_dw == BPKUR::CHROME_BROWSER_OS_KEY) {
+    trust_level = BPKUR::CHROME_BROWSER_OS_KEY;
+  } else {
+    return invalid_key_info();
+  }
+
+  std::vector<uint8_t> wrapped;
+  DWORD type = REG_NONE;
+  DWORD size = 0;
+  res = key.ReadValue(signingkey_name.c_str(), nullptr, &size, &type);
+  if (res == ERROR_SUCCESS && type == REG_BINARY) {
+    wrapped.resize(size);
+    res = key.ReadValue(signingkey_name.c_str(), wrapped.data(), &size, &type);
+  }
+  if (res != ERROR_SUCCESS || type != REG_BINARY)
+    return invalid_key_info();
+
+  return {trust_level, wrapped};
+}
+
+std::unique_ptr<crypto::UnexportableKeyProvider>
+WinKeyPersistenceDelegate::GetTpmBackedKeyProvider() {
+  return crypto::GetUnexportableKeyProvider();
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.h
new file mode 100644
index 0000000..dc7c0ac
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/win_key_persistence_delegate.h
@@ -0,0 +1,27 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_WIN_KEY_PERSISTENCE_DELEGATE_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_WIN_KEY_PERSISTENCE_DELEGATE_H_
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h"
+
+namespace enterprise_connectors {
+
+// Windows implementation of the KeyPersistenceDelegate interface.
+class WinKeyPersistenceDelegate : public KeyPersistenceDelegate {
+ public:
+  ~WinKeyPersistenceDelegate() override;
+
+  // KeyPersistenceDelegate:
+  bool StoreKeyPair(KeyPersistenceDelegate::KeyTrustLevel trust_level,
+                    std::vector<uint8_t> wrapped) override;
+  KeyPersistenceDelegate::KeyInfo LoadKeyPair() override;
+  std::unique_ptr<crypto::UnexportableKeyProvider> GetTpmBackedKeyProvider()
+      override;
+};
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_PERSISTENCE_WIN_KEY_PERSISTENCE_DELEGATE_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.cc
new file mode 100644
index 0000000..5147147a
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.cc
@@ -0,0 +1,68 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.h"
+
+#include "base/check.h"
+#include "base/notreached.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h"
+#include "crypto/unexportable_key.h"
+
+using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
+
+namespace enterprise_connectors {
+
+// static
+absl::optional<SigningKeyPair> SigningKeyPair::Create(
+    KeyPersistenceDelegate* persistence_delegate) {
+  DCHECK(persistence_delegate);
+
+  KeyTrustLevel trust_level = BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED;
+  std::vector<uint8_t> wrapped;
+  std::tie(trust_level, wrapped) = persistence_delegate->LoadKeyPair();
+
+  if (wrapped.empty()) {
+    // No persisted key pair with a known trust level found.  This is not an
+    // error, it could be that no key has been created yet.
+    return absl::nullopt;
+  }
+
+  std::unique_ptr<crypto::UnexportableSigningKey> key_pair;
+  switch (trust_level) {
+    case BPKUR::CHROME_BROWSER_TPM_KEY: {
+      auto provider = persistence_delegate->GetTpmBackedKeyProvider();
+      if (provider) {
+        key_pair = provider->FromWrappedSigningKeySlowly(wrapped);
+      }
+      break;
+    }
+    case BPKUR::CHROME_BROWSER_OS_KEY: {
+      ECSigningKeyProvider provider;
+      key_pair = provider.FromWrappedSigningKeySlowly(wrapped);
+      break;
+    }
+    case BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED:
+      NOTREACHED();
+      return absl::nullopt;
+  }
+
+  if (key_pair) {
+    return SigningKeyPair(std::move(key_pair), trust_level);
+  }
+  return absl::nullopt;
+}
+
+SigningKeyPair::SigningKeyPair(
+    std::unique_ptr<crypto::UnexportableSigningKey> key_pair,
+    KeyTrustLevel trust_level)
+    : key_pair_(std::move(key_pair)), trust_level_(trust_level) {
+  DCHECK(key_pair_);
+}
+
+SigningKeyPair::SigningKeyPair(SigningKeyPair&& other) = default;
+SigningKeyPair& SigningKeyPair::operator=(SigningKeyPair&& other) = default;
+
+SigningKeyPair::~SigningKeyPair() = default;
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.h b/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.h
new file mode 100644
index 0000000..16534ef
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.h
@@ -0,0 +1,60 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_SIGNING_KEY_PAIR_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_SIGNING_KEY_PAIR_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h"
+#include "components/policy/proto/device_management_backend.pb.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace crypto {
+class UnexportableSigningKey;
+}  // namespace crypto
+
+namespace enterprise_connectors {
+
+// Class in charge of using a stored signing key and providing cryptographic
+// functionality.
+class SigningKeyPair {
+ public:
+  using KeyTrustLevel =
+      enterprise_management::BrowserPublicKeyUploadRequest::KeyTrustLevel;
+
+  // Uses `persistence_delegate` to create a SigningKeyPair instance based on
+  // a key that has already been persisted on the system. Returns absl::nullopt
+  // if no key was found.
+  static absl::optional<SigningKeyPair> Create(
+      KeyPersistenceDelegate* persistence_delegate);
+
+  SigningKeyPair(std::unique_ptr<crypto::UnexportableSigningKey> key_pair,
+                 KeyTrustLevel trust_level);
+
+  SigningKeyPair(SigningKeyPair&& other);
+  SigningKeyPair& operator=(SigningKeyPair&& other);
+
+  SigningKeyPair(const SigningKeyPair&) = delete;
+  SigningKeyPair& operator=(const SigningKeyPair&) = delete;
+
+  ~SigningKeyPair();
+
+  crypto::UnexportableSigningKey* key() const {
+    return key_pair_ ? key_pair_.get() : nullptr;
+  }
+
+  KeyTrustLevel trust_level() const { return trust_level_; }
+
+ private:
+  std::unique_ptr<crypto::UnexportableSigningKey> key_pair_;
+  KeyTrustLevel trust_level_ = enterprise_management::
+      BrowserPublicKeyUploadRequest::KEY_TRUST_LEVEL_UNSPECIFIED;
+};
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_CORE_SIGNING_KEY_PAIR_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair_unittest.cc
new file mode 100644
index 0000000..e68357f
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair_unittest.cc
@@ -0,0 +1,94 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.h"
+
+#include <memory>
+#include <vector>
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.h"
+#include "crypto/unexportable_key.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using BPKUP = enterprise_management::BrowserPublicKeyUploadResponse;
+using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
+using testing::Return;
+
+namespace enterprise_connectors {
+
+namespace {
+
+void ValidateSigningKey(const absl::optional<SigningKeyPair>& key_pair,
+                        BPKUR::KeyTrustLevel expected_trust_level) {
+  ASSERT_TRUE(key_pair);
+
+  EXPECT_EQ(expected_trust_level, key_pair->trust_level());
+  ASSERT_TRUE(key_pair->key());
+
+  // Extract a pubkey should work.
+  std::vector<uint8_t> pubkey = key_pair->key()->GetSubjectPublicKeyInfo();
+  ASSERT_GT(pubkey.size(), 0u);
+
+  // Signing should work.
+  auto signed_data = key_pair->key()->SignSlowly(
+      base::as_bytes(base::make_span("data to sign")));
+  ASSERT_TRUE(signed_data.has_value());
+  ASSERT_GT(signed_data->size(), 0u);
+}
+
+}  // namespace
+
+// Tests that the SigningKeyPair::Create factory function returns nothing if no
+// key was persisted.
+TEST(SigningKeyPairTest, Create_NoKey) {
+  testing::StrictMock<test::MockKeyPersistenceDelegate>
+      mock_persistence_delegate;
+  EXPECT_CALL(mock_persistence_delegate, LoadKeyPair())
+      .WillOnce(Return(KeyPersistenceDelegate::KeyInfo(
+          BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED, std::vector<uint8_t>())));
+  EXPECT_FALSE(SigningKeyPair::Create(&mock_persistence_delegate));
+}
+
+// Tests that the SigningKeyPair::Create factory function returns a properly
+// initialized TPM-backed SigningKeyPair if a TPM-backed key was available.
+TEST(SigningKeyPairTest, Create_WithTpmKey) {
+  // The mocked factory returns mock delegates setup with TPM key pairs by
+  // default.
+  test::ScopedKeyPersistenceDelegateFactory factory;
+  auto mocked_delegate = factory.CreateMockedDelegate();
+
+  EXPECT_CALL(*mocked_delegate, LoadKeyPair());
+  EXPECT_CALL(*mocked_delegate, GetTpmBackedKeyProvider());
+
+  absl::optional<SigningKeyPair> key_pair =
+      SigningKeyPair::Create(mocked_delegate.get());
+
+  ValidateSigningKey(key_pair, BPKUR::CHROME_BROWSER_TPM_KEY);
+}
+
+// Tests that the SigningKeyPair::Create factory function returns a properly
+// initialized crypto::ECPrivateKey-backed SigningKeyPair if that is what was
+// available.
+TEST(SigningKeyPairTest, Create_WithECPrivateKey) {
+  ECSigningKeyProvider ec_key_provider;
+  auto acceptable_algorithms = {crypto::SignatureVerifier::ECDSA_SHA256};
+  auto key = ec_key_provider.GenerateSigningKeySlowly(acceptable_algorithms);
+
+  testing::StrictMock<test::MockKeyPersistenceDelegate>
+      mock_persistence_delegate;
+  EXPECT_CALL(mock_persistence_delegate, LoadKeyPair)
+      .WillOnce(Return(KeyPersistenceDelegate::KeyInfo(
+          BPKUR::CHROME_BROWSER_OS_KEY, key->GetWrappedKey())));
+
+  absl::optional<SigningKeyPair> key_pair =
+      SigningKeyPair::Create(&mock_persistence_delegate);
+
+  ValidateSigningKey(key_pair, BPKUR::CHROME_BROWSER_OS_KEY);
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/BUILD.gn b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/BUILD.gn
new file mode 100644
index 0000000..d24762e
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/BUILD.gn
@@ -0,0 +1,42 @@
+# Copyright 2021 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("installer") {
+  public = [ "key_rotation_manager.h" ]
+
+  sources = [
+    "key_rotation_manager.cc",
+    "key_rotation_manager_impl.cc",
+    "key_rotation_manager_impl.h",
+  ]
+
+  deps = [
+    "//chrome/browser/enterprise/connectors/device_trust/key_management/core",
+    "//chrome/browser/enterprise/connectors/device_trust/key_management/core/network",
+    "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence",
+    "//components/policy/proto",
+    "//crypto",
+    "//net",
+    "//third_party/abseil-cpp:absl",
+    "//url",
+  ]
+
+  public_deps = [ "//base" ]
+}
+
+source_set("unit_tests") {
+  testonly = true
+  sources = [ "key_rotation_manager_unittest.cc" ]
+
+  deps = [
+    ":installer",
+    "//chrome/browser/enterprise/connectors/device_trust/key_management/core",
+    "//chrome/browser/enterprise/connectors/device_trust/key_management/core/network:test_support",
+    "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence:test_support",
+    "//crypto",
+    "//testing/gmock",
+    "//testing/gtest",
+    "//url",
+  ]
+}
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.cc
new file mode 100644
index 0000000..881ca26
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.cc
@@ -0,0 +1,29 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h"
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate_factory.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.h"
+
+namespace enterprise_connectors {
+
+// static
+std::unique_ptr<KeyRotationManager> KeyRotationManager::Create() {
+  return std::make_unique<KeyRotationManagerImpl>(
+      CreateKeyNetworkDelegate(), KeyPersistenceDelegateFactory::GetInstance()
+                                      ->CreateKeyPersistenceDelegate());
+}
+
+// static
+std::unique_ptr<KeyRotationManager> KeyRotationManager::CreateForTesting(
+    std::unique_ptr<KeyNetworkDelegate> network_delegate,
+    std::unique_ptr<KeyPersistenceDelegate> persistence_delegate) {
+  return std::make_unique<KeyRotationManagerImpl>(
+      std::move(network_delegate), std::move(persistence_delegate));
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h
new file mode 100644
index 0000000..009ef92e
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h
@@ -0,0 +1,48 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_INSTALLER_KEY_ROTATION_MANAGER_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_INSTALLER_KEY_ROTATION_MANAGER_H_
+
+#include <memory>
+#include <string>
+
+#include "base/compiler_specific.h"
+
+class GURL;
+
+namespace enterprise_connectors {
+
+class KeyPersistenceDelegate;
+class KeyNetworkDelegate;
+
+// Interface for the object in charge of handling key rotation logic inside the
+// installer.
+class KeyRotationManager {
+ public:
+  virtual ~KeyRotationManager() = default;
+
+  static std::unique_ptr<KeyRotationManager> Create();
+
+  static std::unique_ptr<KeyRotationManager> CreateForTesting(
+      std::unique_ptr<KeyNetworkDelegate> network_delegate,
+      std::unique_ptr<KeyPersistenceDelegate> persistence_delegate);
+
+  // Rotates the key pair.  If no key pair already exists, simply creates a
+  // new one.  `dm_token` the DM token to use when sending the new public key to
+  // the DM server.  This function will fail if not called with admin rights.
+  //
+  // This function makes network requests and will block until those requests
+  // complete successfully or fail (after some retrying).  This function is
+  // not meant to be called from the chrome browser but from a background
+  // utility process that does not block the user in the browser.
+  virtual bool RotateWithAdminRights(const GURL& dm_server_url,
+                                     const std::string& dm_token,
+                                     const std::string& nonce)
+      WARN_UNUSED_RESULT = 0;
+};
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_INSTALLER_KEY_ROTATION_MANAGER_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc
new file mode 100644
index 0000000..47a3f1a9
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.cc
@@ -0,0 +1,154 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.h"
+
+#include "base/check.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h"
+#include "crypto/unexportable_key.h"
+#include "net/base/backoff_entry.h"
+#include "url/gurl.h"
+
+using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
+using BPKUP = enterprise_management::BrowserPublicKeyUploadResponse;
+
+namespace enterprise_connectors {
+
+KeyRotationManagerImpl::KeyRotationManagerImpl(
+    std::unique_ptr<KeyNetworkDelegate> network_delegate,
+    std::unique_ptr<KeyPersistenceDelegate> persistence_delegate)
+    : network_delegate_(std::move(network_delegate)),
+      persistence_delegate_(std::move(persistence_delegate)) {
+  DCHECK(network_delegate_);
+  DCHECK(persistence_delegate_);
+
+  key_pair_ = SigningKeyPair::Create(persistence_delegate_.get());
+}
+
+KeyRotationManagerImpl::~KeyRotationManagerImpl() = default;
+
+bool KeyRotationManagerImpl::RotateWithAdminRights(const GURL& dm_server_url,
+                                                   const std::string& dm_token,
+                                                   const std::string& nonce) {
+  // Create a new key pair.  First try creating a TPM-backed key.  If that does
+  // not work, try a less secure type.
+  KeyTrustLevel new_trust_level = BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED;
+  auto acceptable_algorithms = {
+      crypto::SignatureVerifier::ECDSA_SHA256,
+      crypto::SignatureVerifier::RSA_PKCS1_SHA256,
+  };
+
+  std::unique_ptr<crypto::UnexportableKeyProvider> provider =
+      persistence_delegate_->GetTpmBackedKeyProvider();
+  auto new_key_pair =
+      provider ? provider->GenerateSigningKeySlowly(acceptable_algorithms)
+               : nullptr;
+  if (new_key_pair) {
+    new_trust_level = BPKUR::CHROME_BROWSER_TPM_KEY;
+  } else {
+    new_trust_level = BPKUR::CHROME_BROWSER_OS_KEY;
+    ECSigningKeyProvider ec_signing_provider;
+    new_key_pair =
+        ec_signing_provider.GenerateSigningKeySlowly(acceptable_algorithms);
+  }
+  if (!new_key_pair)
+    return false;
+
+  if (!persistence_delegate_->StoreKeyPair(new_trust_level,
+                                           new_key_pair->GetWrappedKey())) {
+    return false;
+  }
+
+  enterprise_management::DeviceManagementRequest request;
+  if (!BuildUploadPublicKeyRequest(
+          new_trust_level, new_key_pair, nonce,
+          request.mutable_browser_public_key_upload_request())) {
+    return false;
+  }
+
+  std::string request_str;
+  request.SerializeToString(&request_str);
+
+  const net::BackoffEntry::Policy kBackoffPolicy{
+      .num_errors_to_ignore = 0,
+      .initial_delay_ms = 1000,
+      .multiply_factor = 2.0,
+      .jitter_factor = 0.1,
+      .maximum_backoff_ms = 5 * 60 * 1000,  // 5 min.
+      .entry_lifetime_ms = -1,
+      .always_use_initial_delay = false};
+
+  const int kMaxRetryCount = 10;
+  auto rc = BPKUP::UNDEFINED;
+  net::BackoffEntry boe(&kBackoffPolicy);
+  for (int i = 0;
+       rc == BPKUP::UNDEFINED && boe.failure_count() < kMaxRetryCount; ++i) {
+    // Wait before trying to send again, if needed.  This will not block on
+    // the first request.
+    if (boe.ShouldRejectRequest())
+      base::PlatformThread::Sleep(boe.GetTimeUntilRelease());
+
+    // Any attempt to reuse a nonce will result in an INVALID_SIGNATURE error
+    // being returned by the server.  This will cause the loop to break early.
+    std::string response_str = network_delegate_->SendPublicKeyToDmServerSync(
+        dm_server_url, dm_token, request_str);
+    enterprise_management::DeviceManagementResponse response;
+    rc = (!response_str.empty() && response.ParseFromString(response_str) &&
+          response.has_browser_public_key_upload_response() &&
+          response.browser_public_key_upload_response().has_response_code())
+             ? response.browser_public_key_upload_response().response_code()
+             : BPKUP::UNDEFINED;
+    boe.InformOfRequest(rc == BPKUP::SUCCESS);
+  }
+
+  if (rc != BPKUP::SUCCESS) {
+    // Unable to send to DM server, so restore the old key if there was one.
+    if (key_pair_ && key_pair_->key()) {
+      persistence_delegate_->StoreKeyPair(key_pair_->trust_level(),
+                                          key_pair_->key()->GetWrappedKey());
+    }
+    return false;
+  }
+
+  key_pair_.emplace(std::move(new_key_pair), new_trust_level);
+
+  return true;
+}
+
+bool KeyRotationManagerImpl::BuildUploadPublicKeyRequest(
+    KeyTrustLevel new_trust_level,
+    const std::unique_ptr<crypto::UnexportableSigningKey>& new_key_pair,
+    const std::string& nonce,
+    enterprise_management::BrowserPublicKeyUploadRequest* request) {
+  std::vector<uint8_t> pubkey = new_key_pair->GetSubjectPublicKeyInfo();
+
+  // Build the buffer to sign.  It consists of the public key of the new key
+  // pair followed by the nonce.  The nonce vector may be empty.
+  std::vector<uint8_t> buffer = pubkey;
+  buffer.insert(buffer.end(), nonce.begin(), nonce.end());
+
+  // If there is an existing key and the nonce is not empty, sign the new
+  // pubkey with it.  Otherwise sign it with the new key itself (i.e. the
+  // public key is self-signed).  This is done to handle the case of a device
+  // that is enabled for device trust and then un-enrolled server side.  When
+  // the user re-enrolls this device, the first key rotation attempt will use
+  // an empty nonce to signal this is the first public key being uploaded to
+  // DM server.  DM server expects the public key to be self signed.
+  absl::optional<std::vector<uint8_t>> signature =
+      key_pair_ && key_pair_->key() && !nonce.empty()
+          ? key_pair_->key()->SignSlowly(buffer)
+          : new_key_pair->SignSlowly(buffer);
+  if (!signature.has_value())
+    return false;
+
+  request->set_public_key(pubkey.data(), pubkey.size());
+  request->set_signature(signature->data(), signature->size());
+  request->set_key_trust_level(new_trust_level);
+
+  return true;
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.h b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.h
new file mode 100644
index 0000000..d3f8ffda
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_impl.h
@@ -0,0 +1,58 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_INSTALLER_KEY_ROTATION_MANAGER_IMPL_H_
+#define CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_INSTALLER_KEY_ROTATION_MANAGER_IMPL_H_
+
+#include <memory>
+#include <string>
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/signing_key_pair.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h"
+#include "components/policy/proto/device_management_backend.pb.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace crypto {
+class UnexportableSigningKey;
+}  // namespace crypto
+
+namespace enterprise_connectors {
+
+class KeyNetworkDelegate;
+class KeyPersistenceDelegate;
+
+class KeyRotationManagerImpl : public KeyRotationManager {
+ public:
+  using KeyTrustLevel =
+      enterprise_management::BrowserPublicKeyUploadRequest::KeyTrustLevel;
+
+  KeyRotationManagerImpl(
+      std::unique_ptr<KeyNetworkDelegate> network_delegate,
+      std::unique_ptr<KeyPersistenceDelegate> persistence_delegate);
+  ~KeyRotationManagerImpl() override;
+
+  // KeyRotationManager:
+  bool RotateWithAdminRights(const GURL& dm_server_url,
+                             const std::string& dm_token,
+                             const std::string& nonce) override
+      WARN_UNUSED_RESULT;
+
+ private:
+  // Builds the protobuf message needed to tell DM server about the new public
+  // for this device.  `nonce` is an opaque binary blob and should not be
+  // treated as an ASCII or UTF-8 string.
+  bool BuildUploadPublicKeyRequest(
+      KeyTrustLevel new_trust_level,
+      const std::unique_ptr<crypto::UnexportableSigningKey>& new_key_pair,
+      const std::string& nonce,
+      enterprise_management::BrowserPublicKeyUploadRequest* request);
+
+  std::unique_ptr<KeyNetworkDelegate> network_delegate_;
+  std::unique_ptr<KeyPersistenceDelegate> persistence_delegate_;
+  absl::optional<SigningKeyPair> key_pair_;
+};
+
+}  // namespace enterprise_connectors
+
+#endif  // CHROME_BROWSER_ENTERPRISE_CONNECTORS_DEVICE_TRUST_KEY_MANAGEMENT_INSTALLER_KEY_ROTATION_MANAGER_IMPL_H_
diff --git a/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc
new file mode 100644
index 0000000..4ad46050
--- /dev/null
+++ b/chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager_unittest.cc
@@ -0,0 +1,272 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h"
+
+#include <memory>
+
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/key_network_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/scoped_key_persistence_delegate_factory.h"
+#include "components/policy/proto/device_management_backend.pb.h"
+#include "crypto/unexportable_key.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "url/gurl.h"
+
+using BPKUP = enterprise_management::BrowserPublicKeyUploadResponse;
+using BPKUR = enterprise_management::BrowserPublicKeyUploadRequest;
+using testing::_;
+using testing::ByMove;
+using testing::InSequence;
+using testing::Invoke;
+using testing::Not;
+using testing::Return;
+using testing::StrictMock;
+
+namespace enterprise_connectors {
+
+using test::MockKeyNetworkDelegate;
+using test::MockKeyPersistenceDelegate;
+
+namespace {
+
+const char kNonce[] = "nonce";
+const char kDmServerUrl[] = "dmserver.example.com";
+const char kDmToken[] = "dm_token";
+
+std::string CreateResponse(BPKUP::ResponseCode response_code = BPKUP::SUCCESS) {
+  enterprise_management::DeviceManagementResponse response;
+  response.mutable_browser_public_key_upload_response()->set_response_code(
+      response_code);
+  std::string response_str;
+  response.SerializeToString(&response_str);
+  return response_str;
+}
+
+KeyPersistenceDelegate::KeyInfo CreateEmptyKeyPair() {
+  return {BPKUR::KEY_TRUST_LEVEL_UNSPECIFIED, std::vector<uint8_t>()};
+}
+
+}  // namespace
+
+// Tests a success key rotation flow when a TPM key and TPM key provider are
+// available.
+TEST(KeyRotationManagerTest, RotateWithAdminRights_Tpm_WithKey) {
+  // The factory creates instances backed by fake TPM keys.
+  test::ScopedKeyPersistenceDelegateFactory scoped_factory;
+  auto mock_persistence_delegate = scoped_factory.CreateMockedDelegate();
+  auto original_key_wrapped = scoped_factory.wrapped_key();
+
+  // The mocked delegate is already set-up to return a working TPM key and
+  // provider.
+  EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair());
+  EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider()).Times(2);
+  EXPECT_CALL(
+      *mock_persistence_delegate,
+      StoreKeyPair(BPKUR::CHROME_BROWSER_TPM_KEY, Not(original_key_wrapped)))
+      .WillOnce(Return(true));
+
+  GURL dm_server_url(kDmServerUrl);
+  auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>();
+  EXPECT_CALL(*mock_network_delegate,
+              SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _))
+      .WillOnce(Return(CreateResponse()));
+
+  auto manager = KeyRotationManager::CreateForTesting(
+      std::move(mock_network_delegate), std::move(mock_persistence_delegate));
+
+  EXPECT_TRUE(manager->RotateWithAdminRights(dm_server_url, kDmToken, kNonce));
+}
+
+// Tests a success key rotation flow when TPM key provider is available, but no
+// previous key was created.
+TEST(KeyRotationManagerTest, RotateWithAdminRights_Tpm_NoKey) {
+  // The factory creates instances backed by fake TPM keys.
+  test::ScopedKeyPersistenceDelegateFactory scoped_factory;
+  auto mock_persistence_delegate = scoped_factory.CreateMockedDelegate();
+
+  // The mocked delegate is already set-up to return a working TPM key and
+  // provider. Force it to not return a key.
+  EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair())
+      .WillOnce(Return(CreateEmptyKeyPair()));
+  EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider());
+  EXPECT_CALL(*mock_persistence_delegate,
+              StoreKeyPair(BPKUR::CHROME_BROWSER_TPM_KEY, _))
+      .WillOnce(Return(true));
+
+  GURL dm_server_url(kDmServerUrl);
+  auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>();
+  EXPECT_CALL(*mock_network_delegate,
+              SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _))
+      .WillOnce(Return(CreateResponse()));
+
+  auto manager = KeyRotationManager::CreateForTesting(
+      std::move(mock_network_delegate), std::move(mock_persistence_delegate));
+
+  EXPECT_TRUE(manager->RotateWithAdminRights(dm_server_url, kDmToken, kNonce));
+}
+
+// Tests a success key rotation flow when a TPM key provider is not available
+// and no key previously existed.
+TEST(KeyRotationManagerTest, RotateWithAdminRights_NoTpm_NoKey) {
+  auto mock_persistence_delegate =
+      std::make_unique<MockKeyPersistenceDelegate>();
+  EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair())
+      .WillOnce(Return(CreateEmptyKeyPair()));
+  EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider());
+  EXPECT_CALL(*mock_persistence_delegate,
+              StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, _))
+      .WillOnce(Return(true));
+
+  GURL dm_server_url(kDmServerUrl);
+  auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>();
+  EXPECT_CALL(*mock_network_delegate,
+              SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _))
+      .WillOnce(Return(CreateResponse()));
+
+  auto manager = KeyRotationManager::CreateForTesting(
+      std::move(mock_network_delegate), std::move(mock_persistence_delegate));
+
+  EXPECT_TRUE(manager->RotateWithAdminRights(dm_server_url, kDmToken, kNonce));
+}
+
+// Tests a success key rotation flow when a TPM key provider is not available
+// and a key previously existed.
+TEST(KeyRotationManagerTest, RotateWithAdminRights_NoTpm_WithKey) {
+  ECSigningKeyProvider ec_key_provider;
+  auto acceptable_algorithms = {crypto::SignatureVerifier::ECDSA_SHA256};
+  auto key = ec_key_provider.GenerateSigningKeySlowly(acceptable_algorithms);
+
+  auto mock_persistence_delegate =
+      std::make_unique<MockKeyPersistenceDelegate>();
+  EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair())
+      .WillOnce(Return(KeyPersistenceDelegate::KeyInfo(
+          BPKUR::CHROME_BROWSER_OS_KEY, key->GetWrappedKey())));
+  EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider());
+  EXPECT_CALL(*mock_persistence_delegate,
+              StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, _))
+      .WillOnce(Return(true));
+
+  GURL dm_server_url(kDmServerUrl);
+  auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>();
+  EXPECT_CALL(*mock_network_delegate,
+              SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _))
+      .WillOnce(Return(CreateResponse()));
+
+  auto manager = KeyRotationManager::CreateForTesting(
+      std::move(mock_network_delegate), std::move(mock_persistence_delegate));
+
+  EXPECT_TRUE(manager->RotateWithAdminRights(dm_server_url, kDmToken, kNonce));
+}
+
+// Tests a failed key rotation flow when a TPM key provider is not available
+// and a key previously existed, but storing the new key locally failed.
+TEST(KeyRotationManagerTest, RotateWithAdminRights_NoTpm_WithKey_StoreFailed) {
+  ECSigningKeyProvider ec_key_provider;
+  auto acceptable_algorithms = {crypto::SignatureVerifier::ECDSA_SHA256};
+  auto key = ec_key_provider.GenerateSigningKeySlowly(acceptable_algorithms);
+  auto original_key_wrapped = key->GetWrappedKey();
+
+  auto mock_persistence_delegate =
+      std::make_unique<MockKeyPersistenceDelegate>();
+  EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair())
+      .WillOnce(Return(KeyPersistenceDelegate::KeyInfo(
+          BPKUR::CHROME_BROWSER_OS_KEY, key->GetWrappedKey())));
+  EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider());
+  EXPECT_CALL(
+      *mock_persistence_delegate,
+      StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, Not(original_key_wrapped)))
+      .WillOnce(Return(false));
+
+  auto mock_network_delegate =
+      std::make_unique<testing::StrictMock<MockKeyNetworkDelegate>>();
+
+  auto manager = KeyRotationManager::CreateForTesting(
+      std::move(mock_network_delegate), std::move(mock_persistence_delegate));
+
+  GURL dm_server_url(kDmServerUrl);
+  EXPECT_FALSE(manager->RotateWithAdminRights(dm_server_url, kDmToken, kNonce));
+}
+
+// Tests a success key rotation flow when a TPM key provider is not available
+// and a key previously existed, and the network request transiently failed
+// twice before succeeding.
+TEST(KeyRotationManagerTest,
+     RotateWithAdminRights_NoTpm_WithKey_EventualNetworkSuccess) {
+  ECSigningKeyProvider ec_key_provider;
+  auto acceptable_algorithms = {crypto::SignatureVerifier::ECDSA_SHA256};
+  auto key = ec_key_provider.GenerateSigningKeySlowly(acceptable_algorithms);
+  auto original_key_wrapped = key->GetWrappedKey();
+
+  auto mock_persistence_delegate =
+      std::make_unique<MockKeyPersistenceDelegate>();
+  EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair())
+      .WillOnce(Return(KeyPersistenceDelegate::KeyInfo(
+          BPKUR::CHROME_BROWSER_OS_KEY, key->GetWrappedKey())));
+  EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider());
+  EXPECT_CALL(
+      *mock_persistence_delegate,
+      StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, Not(original_key_wrapped)))
+      .WillOnce(Return(true));
+
+  GURL dm_server_url(kDmServerUrl);
+  auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>();
+  EXPECT_CALL(*mock_network_delegate,
+              SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _))
+      .WillOnce(Return(CreateResponse(BPKUP::UNDEFINED)))
+      .WillOnce(Return(CreateResponse(BPKUP::SUCCESS)));
+
+  auto manager = KeyRotationManager::CreateForTesting(
+      std::move(mock_network_delegate), std::move(mock_persistence_delegate));
+
+  EXPECT_TRUE(manager->RotateWithAdminRights(dm_server_url, kDmToken, kNonce));
+}
+
+// Tests a failed key rotation flow when a TPM key provider is not available
+// and a key previously existed, and the network request transiently failed
+// twice before really failing. Also, in this case, the original key should be
+// stored back.
+TEST(KeyRotationManagerTest,
+     RotateWithAdminRights_NoTpm_WithKey_EventualNetworkFailure) {
+  ECSigningKeyProvider ec_key_provider;
+  auto acceptable_algorithms = {crypto::SignatureVerifier::ECDSA_SHA256};
+  auto key = ec_key_provider.GenerateSigningKeySlowly(acceptable_algorithms);
+  auto original_key_wrapped = key->GetWrappedKey();
+
+  InSequence s;
+
+  auto mock_persistence_delegate =
+      std::make_unique<MockKeyPersistenceDelegate>();
+  EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair())
+      .WillOnce(Return(KeyPersistenceDelegate::KeyInfo(
+          BPKUR::CHROME_BROWSER_OS_KEY, original_key_wrapped)));
+  EXPECT_CALL(*mock_persistence_delegate, GetTpmBackedKeyProvider());
+  EXPECT_CALL(
+      *mock_persistence_delegate,
+      StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, Not(original_key_wrapped)))
+      .WillOnce(Return(true));
+
+  GURL dm_server_url(kDmServerUrl);
+  auto mock_network_delegate = std::make_unique<MockKeyNetworkDelegate>();
+  EXPECT_CALL(*mock_network_delegate,
+              SendPublicKeyToDmServerSync(dm_server_url, kDmToken, _))
+      .WillOnce(Return(CreateResponse(BPKUP::UNDEFINED)))
+      .WillOnce(Return(CreateResponse(BPKUP::INVALID_SIGNATURE)));
+
+  EXPECT_CALL(*mock_persistence_delegate,
+              StoreKeyPair(BPKUR::CHROME_BROWSER_OS_KEY, original_key_wrapped))
+      .WillOnce(Return(true));
+
+  auto manager = KeyRotationManager::CreateForTesting(
+      std::move(mock_network_delegate), std::move(mock_persistence_delegate));
+
+  EXPECT_FALSE(manager->RotateWithAdminRights(dm_server_url, kDmToken, kNonce));
+}
+
+}  // namespace enterprise_connectors
diff --git a/chrome/installer/setup/BUILD.gn b/chrome/installer/setup/BUILD.gn
index 9dabfae..86d45bc1 100644
--- a/chrome/installer/setup/BUILD.gn
+++ b/chrome/installer/setup/BUILD.gn
@@ -37,7 +37,7 @@
       "//base",
       "//build:branding_buildflags",
       "//build/win:default_exe_manifest",
-      "//chrome/browser/enterprise/connectors/device_trust/attestation/desktop:elevated_command_support",
+      "//chrome/browser/enterprise/connectors/device_trust/key_management/installer",
       "//chrome/chrome_elf:constants",
       "//chrome/common:constants",
       "//chrome/install_static:install_static_util",
@@ -103,7 +103,7 @@
 
     deps = [
       "//build:branding_buildflags",
-      "//chrome/browser/enterprise/connectors/device_trust/attestation/desktop:elevated_command_support",
+      "//chrome/browser/enterprise/connectors/device_trust/key_management/installer",
       "//chrome/common:constants",
       "//chrome/common:version_header",
       "//chrome/install_static:buildflags",
@@ -162,8 +162,11 @@
       "//base/allocator:buildflags",
       "//base/test:test_support",
       "//build:branding_buildflags",
-      "//chrome/browser/enterprise/connectors/device_trust/attestation/desktop:elevated_command_support",
-      "//chrome/browser/enterprise/connectors/device_trust/attestation/desktop:test_support",
+      "//chrome/browser/enterprise/connectors/device_trust/key_management/core/network",
+      "//chrome/browser/enterprise/connectors/device_trust/key_management/core/network:test_support",
+      "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence",
+      "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence:test_support",
+      "//chrome/browser/enterprise/connectors/device_trust/key_management/installer",
       "//chrome/common:constants",
       "//chrome/common:version_header",
       "//chrome/install_static:buildflags",
diff --git a/chrome/installer/setup/DEPS b/chrome/installer/setup/DEPS
index ee2d78b..e5f723b 100644
--- a/chrome/installer/setup/DEPS
+++ b/chrome/installer/setup/DEPS
@@ -1,5 +1,5 @@
 include_rules = [
-  "+chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h",
+  "+chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h",
   "+chrome/chrome_elf/chrome_elf_constants.h",
   "+chrome/install_static",
   "+components/base32",
@@ -12,7 +12,9 @@
 
 specific_include_rules = {
   ".*_unittest\.cc": [
-    "+chrome/browser/enterprise/connectors/device_trust/attestation/desktop/memory_signing_key_pair.h",
+    "+chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h",
+    "+chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h",
+    "+chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h",
     "+chrome/chrome_elf/nt_registry/nt_registry.h",
   ],
 }
diff --git a/chrome/installer/setup/setup_main.cc b/chrome/installer/setup/setup_main.cc
index f4e7bc6..87a8027 100644
--- a/chrome/installer/setup/setup_main.cc
+++ b/chrome/installer/setup/setup_main.cc
@@ -50,7 +50,7 @@
 #include "base/win/win_util.h"
 #include "build/branding_buildflags.h"
 #include "build/build_config.h"
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h"
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_paths.h"
 #include "chrome/common/chrome_switches.h"
@@ -1164,18 +1164,19 @@
         cmd_line.GetSwitchValueASCII(installer::switches::kDmServerUrl));
     auto nonce = installer::DecodeNonceSwitchValue(
         cmd_line.GetSwitchValueASCII(installer::switches::kNonce));
-    auto key_pair = enterprise_connectors::SigningKeyPair::Create();
 
     // RotateDeviceTrustKey() expects a single threaded task runner so
     // creating one here.
     base::SingleThreadTaskExecutor executor;
 
-    *exit_code = token && nonce && dm_server_url.is_valid() &&
-                         dm_server_url.SchemeIsHTTPOrHTTPS() &&
-                         installer::RotateDeviceTrustKey(
-                             *key_pair, dm_server_url, *token, *nonce)
-                     ? installer::ROTATE_DTKEY_SUCCESS
-                     : installer::ROTATE_DTKEY_FAILED;
+    *exit_code =
+        token && nonce && dm_server_url.is_valid() &&
+                dm_server_url.SchemeIsHTTPOrHTTPS() &&
+                installer::RotateDeviceTrustKey(
+                    enterprise_connectors::KeyRotationManager::Create(),
+                    dm_server_url, *token, *nonce)
+            ? installer::ROTATE_DTKEY_SUCCESS
+            : installer::ROTATE_DTKEY_FAILED;
 #endif
   } else {
     handled = false;
diff --git a/chrome/installer/setup/setup_util.cc b/chrome/installer/setup/setup_util.cc
index 0cc7cf9..a441b7c 100644
--- a/chrome/installer/setup/setup_util.cc
+++ b/chrome/installer/setup/setup_util.cc
@@ -42,7 +42,7 @@
 #include "base/win/windows_version.h"
 #include "build/branding_buildflags.h"
 #include "build/build_config.h"
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h"
 #include "chrome/install_static/install_details.h"
 #include "chrome/install_static/install_modes.h"
 #include "chrome/install_static/install_util.h"
@@ -785,18 +785,22 @@
   return true;
 }
 
-bool RotateDeviceTrustKey(enterprise_connectors::SigningKeyPair& key_pair,
-                          const GURL& dm_server_url,
-                          const std::string& dm_token,
-                          const std::string& nonce) {
+bool RotateDeviceTrustKey(
+    std::unique_ptr<enterprise_connectors::KeyRotationManager>
+        key_rotation_manager,
+    const GURL& dm_server_url,
+    const std::string& dm_token,
+    const std::string& nonce) {
   DCHECK(install_static::IsSystemInstall());
+  DCHECK(key_rotation_manager);
 
   if (dm_token.size() > kMaxDMTokenLength) {
     LOG(ERROR) << "DMToken length out of bounds";
     return false;
   }
 
-  return key_pair.RotateWithAdminRights(dm_server_url, dm_token, nonce);
+  return key_rotation_manager->RotateWithAdminRights(dm_server_url, dm_token,
+                                                     nonce);
 }
 
 base::FilePath GetNotificationHelperPath(const base::FilePath& target_path,
diff --git a/chrome/installer/setup/setup_util.h b/chrome/installer/setup/setup_util.h
index 2beaa71..3d06dba9 100644
--- a/chrome/installer/setup/setup_util.h
+++ b/chrome/installer/setup/setup_util.h
@@ -31,7 +31,7 @@
 }  // namespace base
 
 namespace enterprise_connectors {
-class SigningKeyPair;
+class KeyRotationManager;
 }  // namespace enterprise_connectors
 
 namespace installer {
@@ -163,10 +163,12 @@
 // Rotates the device trust signing key and saves it to a global location on
 // the machine accessible to all install modes of the browser (i.e., stable and
 // all three side-by-side modes).
-bool RotateDeviceTrustKey(enterprise_connectors::SigningKeyPair& key_pair,
-                          const GURL& dm_server_url,
-                          const std::string& dm_token,
-                          const std::string& nonce);
+bool RotateDeviceTrustKey(
+    std::unique_ptr<enterprise_connectors::KeyRotationManager>
+        key_rotation_manager,
+    const GURL& dm_server_url,
+    const std::string& dm_token,
+    const std::string& nonce);
 
 // Returns the file path to notification_helper.exe (in |version| directory).
 base::FilePath GetNotificationHelperPath(const base::FilePath& target_path,
diff --git a/chrome/installer/setup/setup_util_unittest.cc b/chrome/installer/setup/setup_util_unittest.cc
index 4c94e34..5c3da57a 100644
--- a/chrome/installer/setup/setup_util_unittest.cc
+++ b/chrome/installer/setup/setup_util_unittest.cc
@@ -33,8 +33,10 @@
 #include "base/win/scoped_handle.h"
 #include "build/branding_buildflags.h"
 #include "build/build_config.h"
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/memory_signing_key_pair.h"
-#include "chrome/browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/network/mock_key_network_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/key_persistence_delegate_factory.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence/mock_key_persistence_delegate.h"
+#include "chrome/browser/enterprise/connectors/device_trust/key_management/installer/key_rotation_manager.h"
 #include "chrome/install_static/install_details.h"
 #include "chrome/install_static/install_util.h"
 #include "chrome/install_static/test/scoped_install_details.h"
@@ -631,18 +633,32 @@
   std::string token(&kTokenData[0], kExpectedSize);
   ASSERT_EQ(token.length(), kExpectedSize);
 
-  // Create a signing key pair with a real persistence delegate but with the
-  // testing network delegate used in MemorySigningKeyPair to simulate network
-  // operations.
-  auto key_pair = enterprise_connectors::SigningKeyPair::CreateWithDelegates(
-      std::make_unique<
-          enterprise_connectors::SigningKeyPair::PersistenceDelegate>(),
-      std::make_unique<enterprise_connectors::test::
-                           InMemorySigningKeyPairNetworkDelegate>());
-  ASSERT_TRUE(key_pair);
+  GURL dmserver_url("dmserver.com");
+  std::string nonce = "nonce";
 
-  ASSERT_TRUE(installer::RotateDeviceTrustKey(*key_pair, GURL("dmserver.com"),
-                                              token, "nonce"));
+  // Create a fake success response.
+  enterprise_management::DeviceManagementResponse response;
+  response.mutable_browser_public_key_upload_response()->set_response_code(
+      enterprise_management::BrowserPublicKeyUploadResponse::SUCCESS);
+  std::string response_str;
+  response.SerializeToString(&response_str);
+
+  // Trigger the key rotation with a real persistence delegate (empty) but with
+  // a mocked network delegate.
+  auto mock_network_delegate =
+      std::make_unique<enterprise_connectors::test::MockKeyNetworkDelegate>();
+  EXPECT_CALL(*mock_network_delegate,
+              SendPublicKeyToDmServerSync(dmserver_url, token, testing::_))
+      .WillOnce(testing::Return(response_str));
+
+  auto key_rotation_manager =
+      enterprise_connectors::KeyRotationManager::CreateForTesting(
+          std::move(mock_network_delegate),
+          enterprise_connectors::KeyPersistenceDelegateFactory::GetInstance()
+              ->CreateKeyPersistenceDelegate());
+
+  ASSERT_TRUE(installer::RotateDeviceTrustKey(std::move(key_rotation_manager),
+                                              dmserver_url, token, nonce));
 
   base::win::RegKey key;
   std::wstring signingkey_name;
@@ -674,11 +690,24 @@
   std::string token_too_large(installer::kMaxDMTokenLength + 1, 'x');
   ASSERT_GT(token_too_large.size(), installer::kMaxDMTokenLength);
 
-  auto key_pair = enterprise_connectors::test::CreateInMemorySigningKeyPair(
-      nullptr, nullptr);
-  ASSERT_TRUE(key_pair);
+  auto mock_network_delegate = std::make_unique<testing::StrictMock<
+      enterprise_connectors::test::MockKeyNetworkDelegate>>();
+  auto mock_persistence_delegate = std::make_unique<testing::StrictMock<
+      enterprise_connectors::test::MockKeyPersistenceDelegate>>();
+  enterprise_connectors::test::MockKeyPersistenceDelegate::KeyInfo
+      empty_key_pair = {enterprise_management::BrowserPublicKeyUploadRequest::
+                            KEY_TRUST_LEVEL_UNSPECIFIED,
+                        std::vector<uint8_t>()};
+  EXPECT_CALL(*mock_persistence_delegate, LoadKeyPair())
+      .WillOnce(testing::Return(empty_key_pair));
 
-  EXPECT_FALSE(installer::RotateDeviceTrustKey(*key_pair, GURL("dmserver.com"),
+  auto key_rotation_manager =
+      enterprise_connectors::KeyRotationManager::CreateForTesting(
+          std::move(mock_network_delegate),
+          std::move(mock_persistence_delegate));
+
+  EXPECT_FALSE(installer::RotateDeviceTrustKey(std::move(key_rotation_manager),
+                                               GURL("dmserver.com"),
                                                token_too_large, "nonce"));
 }
 
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 451f2b9..f483eae2 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -2692,7 +2692,7 @@
 
         deps += [
           "//chrome/browser/enterprise/connectors/device_trust:features",
-          "//chrome/browser/enterprise/connectors/device_trust/attestation/desktop:test_support",
+          "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence:test_support",
         ]
       }
 
@@ -7284,15 +7284,14 @@
   }
 
   if (is_linux || is_mac || is_win) {
-    sources += [
-      "../browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc",
-      "../browser/enterprise/connectors/device_trust/attestation/desktop/ec_signing_key_unittest.cc",
-      "../browser/enterprise/connectors/device_trust/attestation/desktop/signing_key_pair_unittest.cc",
-    ]
+    sources += [ "../browser/enterprise/connectors/device_trust/attestation/desktop/desktop_attestation_service_unittest.cc" ]
 
     deps += [
-      "../browser/enterprise/connectors/device_trust/attestation/desktop:elevated_command_support",
-      "../browser/enterprise/connectors/device_trust/attestation/desktop:test_support",
+      "../browser/enterprise/connectors/device_trust/key_management/core",
+      "../browser/enterprise/connectors/device_trust/key_management/core:unit_tests",
+      "../browser/enterprise/connectors/device_trust/key_management/core/persistence",
+      "../browser/enterprise/connectors/device_trust/key_management/core/persistence:test_support",
+      "../browser/enterprise/connectors/device_trust/key_management/installer:unit_tests",
       "../browser/enterprise/connectors/device_trust/signals/decorators/browser:unit_tests",
     ]
   }