chromium/crypto/unexportable_key.h

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CRYPTO_UNEXPORTABLE_KEY_H_
#define CRYPTO_UNEXPORTABLE_KEY_H_

#include <memory>
#include <optional>

#include "build/build_config.h"
#include "crypto/crypto_export.h"
#include "crypto/signature_verifier.h"

#if BUILDFLAG(IS_MAC)
#import <Security/Security.h>
#endif  // BUILDFLAG(IS_MAC)

namespace crypto {

// UnexportableSigningKey provides a hardware-backed signing oracle on platforms
// that support it. Current support is:
//   Windows: RSA_PKCS1_SHA256 via TPM 1.2+ and ECDSA_SHA256 via TPM 2.0.
//   macOS: ECDSA_SHA256 via the Secure Enclave.
//   Tests: ECDSA_SHA256 via ScopedMockUnexportableSigningKeyForTesting.
//
// See also //components/unexportable_keys for a higher-level key management
// API.
class CRYPTO_EXPORT UnexportableSigningKey {};

// UnexportableKeyProvider creates |UnexportableSigningKey|s.
class CRYPTO_EXPORT UnexportableKeyProvider {};

// This is an experimental API as it uses an unofficial Windows API.
// The current implementation is here to gather metrics only. It should not be
// used outside of metrics gathering without knowledge of crypto OWNERS.
//
// UnexportableSigningKey provides a software-backed signing oracle based in a
// specialized virtual machine on platforms that support it. Current support is:
//   Windows: RSA_PKCS1_SHA256 and ECDSA_SHA256.
//
// These keys differs from UnexportableSigningKey in several ways:
// - They are backed not by hardware, but by a specialized limited virtual
// machine resistant to attacks.
// - The latency of operations are expected to be about 100 times less, making
// them much more practical in cases that would otherwise disrupt the user
// experience.
// - The keys are stored in the virtual machine by name, this namespace is
// shared by all applications and there is a limited number of available keys
// (~65k from testing).
//
// For more info see:
// https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/credential-guard
class CRYPTO_EXPORT VirtualUnexportableSigningKey {};

// VirtualUnexportableKeyProvider creates |VirtualUnexportableSigningKey|s.
class CRYPTO_EXPORT VirtualUnexportableKeyProvider {};

// GetUnexportableKeyProvider returns an |UnexportableKeyProvider|
// for the current platform, or nullptr if there isn't one. This can be called
// from any thread but, in tests, but be sequenced with
// |SetUnexportableSigningKeyProvider|.
CRYPTO_EXPORT std::unique_ptr<UnexportableKeyProvider>
GetUnexportableKeyProvider(UnexportableKeyProvider::Config config);

// GetVirtualUnexportableKeyProvider_DO_NOT_USE_METRICS_ONLY returns a
// |VirtualUnexportableKeyProvider| for the current platform, or nullptr if
// there isn't one. This should currently only be used for metrics gathering.
CRYPTO_EXPORT std::unique_ptr<VirtualUnexportableKeyProvider>
GetVirtualUnexportableKeyProvider_DO_NOT_USE_METRICS_ONLY();

// `GetSoftwareUnsecureUnexportableKeyProvider()` returns a mock software
// implementation of `UnexportableKeyProvider` that can be used on platforms
// that do not have a native secure implementation.
// This should be used for development purposes only since these keys are not
// backed by hardware and are not stored securely.
CRYPTO_EXPORT std::unique_ptr<UnexportableKeyProvider>
GetSoftwareUnsecureUnexportableKeyProvider();

namespace internal {

CRYPTO_EXPORT bool HasScopedUnexportableKeyProvider();

CRYPTO_EXPORT void SetUnexportableKeyProviderForTesting(
    std::unique_ptr<UnexportableKeyProvider> (*func)());

}  // namespace internal

}  // namespace crypto

#endif  // CRYPTO_UNEXPORTABLE_KEY_H_