123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- // Copyright (c) 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 CRYPTO_UNEXPORTABLE_KEY_H_
- #define CRYPTO_UNEXPORTABLE_KEY_H_
- #include <memory>
- #include "crypto/crypto_export.h"
- #include "crypto/signature_verifier.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- 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.
- // Tests: ECDSA_SHA256 via ScopedMockUnexportableSigningKeyForTesting.
- class CRYPTO_EXPORT UnexportableSigningKey {
- public:
- virtual ~UnexportableSigningKey();
- // Algorithm returns the algorithm of the key in this object.
- virtual SignatureVerifier::SignatureAlgorithm Algorithm() const = 0;
- // GetSubjectPublicKeyInfo returns an SPKI that contains the public key of
- // this object.
- virtual std::vector<uint8_t> GetSubjectPublicKeyInfo() const = 0;
- // GetWrappedKey returns the encrypted private key of this object. It is
- // encrypted to a key that is kept in hardware and the unencrypted private
- // key never exists in the CPU's memory.
- //
- // A wrapped key may be used with a future instance of this code to recreate
- // the key so long as it's running on the same computer.
- //
- // Note: it is possible to export this wrapped key off machine, but it must be
- // sealed with an AEAD first. The wrapped key may contain machine identifiers
- // and other values that you wouldn't want to export. Additionally
- // |UnexportableKeyProvider::FromWrappedSigningKey| should not be presented
- // attacked-controlled input and the AEAD would serve to authenticate the
- // wrapped key.
- virtual std::vector<uint8_t> GetWrappedKey() const = 0;
- // SignSlowly returns a signature of |data|, or |nullopt| if an error occurs
- // during signing.
- //
- // Note: this may take a second or more to run.
- virtual absl::optional<std::vector<uint8_t>> SignSlowly(
- base::span<const uint8_t> data) = 0;
- };
- // UnexportableKeyProvider creates |UnexportableSigningKey|s.
- class CRYPTO_EXPORT UnexportableKeyProvider {
- public:
- virtual ~UnexportableKeyProvider();
- // SelectAlgorithm returns which signature algorithm from
- // |acceptable_algorithms| would be used if |acceptable_algorithms| was passed
- // to |GenerateSigningKeySlowly|.
- virtual absl::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
- base::span<const SignatureVerifier::SignatureAlgorithm>
- acceptable_algorithms) = 0;
- // GenerateSigningKeySlowly creates a new opaque signing key in hardware. The
- // first supported value of |acceptable_algorithms| determines the type of the
- // key. Returns nullptr if no supported hardware exists, if no value in
- // |acceptable_algorithms| is supported, or if there was an error creating the
- // key.
- //
- // Note: this may take one or two seconds to run.
- virtual std::unique_ptr<UnexportableSigningKey> GenerateSigningKeySlowly(
- base::span<const SignatureVerifier::SignatureAlgorithm>
- acceptable_algorithms) = 0;
- // FromWrappedSigningKey creates an |UnexportableSigningKey| from
- // |wrapped_key|, which must have resulted from calling |GetWrappedKey| on a
- // previous instance of |UnexportableSigningKey|. Returns nullptr if
- // |wrapped_key| cannot be imported.
- //
- // Note: this may take up to a second.
- //
- // Note: do not call this with attacker-controlled data. The underlying
- // interfaces to the secure hardware may not be robust. See |GetWrappedKey|.
- virtual std::unique_ptr<UnexportableSigningKey> FromWrappedSigningKeySlowly(
- base::span<const uint8_t> wrapped_key) = 0;
- };
- // 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();
- #if BUILDFLAG(IS_WIN)
- // MeasureTPMAvailability records UMA metrics of TPM availability.
- CRYPTO_EXPORT void MeasureTPMAvailabilityWin();
- #endif // BUILDFLAG(IS_WIN)
- namespace internal {
- CRYPTO_EXPORT void SetUnexportableKeyProviderForTesting(
- std::unique_ptr<UnexportableKeyProvider> (*func)());
- } // namespace internal
- } // namespace crypto
- #endif // CRYPTO_UNEXPORTABLE_KEY_H_
|