1 // Copyright 2021 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CRYPTO_UNEXPORTABLE_KEY_H_ 6 #define CRYPTO_UNEXPORTABLE_KEY_H_ 7 8 #include <memory> 9 10 #include "crypto/crypto_export.h" 11 #include "crypto/signature_verifier.h" 12 #include "third_party/abseil-cpp/absl/types/optional.h" 13 14 namespace crypto { 15 16 // UnexportableSigningKey provides a hardware-backed signing oracle on platforms 17 // that support it. Current support is: 18 // Windows: RSA_PKCS1_SHA256 via TPM 1.2+ and ECDSA_SHA256 via TPM 2.0. 19 // Tests: ECDSA_SHA256 via ScopedMockUnexportableSigningKeyForTesting. 20 // 21 // See also //components/unexportable_keys for a higher-level key management 22 // API. 23 class CRYPTO_EXPORT UnexportableSigningKey { 24 public: 25 virtual ~UnexportableSigningKey(); 26 27 // Algorithm returns the algorithm of the key in this object. 28 virtual SignatureVerifier::SignatureAlgorithm Algorithm() const = 0; 29 30 // GetSubjectPublicKeyInfo returns an SPKI that contains the public key of 31 // this object. 32 virtual std::vector<uint8_t> GetSubjectPublicKeyInfo() const = 0; 33 34 // GetWrappedKey returns the encrypted private key of this object. It is 35 // encrypted to a key that is kept in hardware and the unencrypted private 36 // key never exists in the CPU's memory. 37 // 38 // A wrapped key may be used with a future instance of this code to recreate 39 // the key so long as it's running on the same computer. 40 // 41 // Note: it is possible to export this wrapped key off machine, but it must be 42 // sealed with an AEAD first. The wrapped key may contain machine identifiers 43 // and other values that you wouldn't want to export. Additionally 44 // |UnexportableKeyProvider::FromWrappedSigningKey| should not be presented 45 // attacked-controlled input and the AEAD would serve to authenticate the 46 // wrapped key. 47 virtual std::vector<uint8_t> GetWrappedKey() const = 0; 48 49 // SignSlowly returns a signature of |data|, or |nullopt| if an error occurs 50 // during signing. 51 // 52 // Note: this may take a second or more to run. 53 virtual absl::optional<std::vector<uint8_t>> SignSlowly( 54 base::span<const uint8_t> data) = 0; 55 }; 56 57 // UnexportableKeyProvider creates |UnexportableSigningKey|s. 58 class CRYPTO_EXPORT UnexportableKeyProvider { 59 public: 60 virtual ~UnexportableKeyProvider(); 61 62 // SelectAlgorithm returns which signature algorithm from 63 // |acceptable_algorithms| would be used if |acceptable_algorithms| was passed 64 // to |GenerateSigningKeySlowly|. 65 virtual absl::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm( 66 base::span<const SignatureVerifier::SignatureAlgorithm> 67 acceptable_algorithms) = 0; 68 69 // GenerateSigningKeySlowly creates a new opaque signing key in hardware. The 70 // first supported value of |acceptable_algorithms| determines the type of the 71 // key. Returns nullptr if no supported hardware exists, if no value in 72 // |acceptable_algorithms| is supported, or if there was an error creating the 73 // key. 74 // 75 // Note: this may take one or two seconds to run. 76 virtual std::unique_ptr<UnexportableSigningKey> GenerateSigningKeySlowly( 77 base::span<const SignatureVerifier::SignatureAlgorithm> 78 acceptable_algorithms) = 0; 79 80 // FromWrappedSigningKey creates an |UnexportableSigningKey| from 81 // |wrapped_key|, which must have resulted from calling |GetWrappedKey| on a 82 // previous instance of |UnexportableSigningKey|. Returns nullptr if 83 // |wrapped_key| cannot be imported. 84 // 85 // Note: this may take up to a second. 86 // 87 // Note: do not call this with attacker-controlled data. The underlying 88 // interfaces to the secure hardware may not be robust. See |GetWrappedKey|. 89 virtual std::unique_ptr<UnexportableSigningKey> FromWrappedSigningKeySlowly( 90 base::span<const uint8_t> wrapped_key) = 0; 91 }; 92 93 // This is an experimental API as it uses an unofficial Windows API. 94 // The current implementation is here to gather metrics only. It should not be 95 // used outside of metrics gathering without knowledge of crypto OWNERS. 96 // 97 // UnexportableSigningKey provides a software-backed signing oracle based in a 98 // specialized virtual machine on platforms that support it. Current support is: 99 // Windows: RSA_PKCS1_SHA256 and ECDSA_SHA256. 100 // 101 // These keys differs from UnexportableSigningKey in several ways: 102 // - They are backed not by hardware, but by a specialized limited virtual 103 // machine resistant to attacks. 104 // - The latency of operations are expected to be about 100 times less, making 105 // them much more practical in cases that would otherwise disrupt the user 106 // experience. 107 // - The keys are stored in the virtual machine by name, this namespace is 108 // shared by all applications and there is a limited number of available keys 109 // (~65k from testing). 110 // 111 // For more info see: 112 // https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/credential-guard 113 class CRYPTO_EXPORT VirtualUnexportableSigningKey { 114 public: 115 virtual ~VirtualUnexportableSigningKey(); 116 117 // Algorithm returns the algorithm of the key in this object. 118 virtual SignatureVerifier::SignatureAlgorithm Algorithm() const = 0; 119 120 // GetSubjectPublicKeyInfo returns an SPKI that contains the public key of 121 // this object. 122 virtual std::vector<uint8_t> GetSubjectPublicKeyInfo() const = 0; 123 124 // GetKeyName may be used with a future instance of this code to recreate 125 // the key so long as it's running on the same computer. 126 // 127 // Note: All local applications can enumerate all keys on device and 128 // recreate them. Private keys can also be exported with the first HANDLE 129 // after creation. 130 virtual std::string GetKeyName() const = 0; 131 132 // Sign returns a signature of |data|, or |nullopt| if an error occurs 133 // during signing. 134 // 135 // Note: this is expected to be under 10ms. 136 virtual absl::optional<std::vector<uint8_t>> Sign( 137 base::span<const uint8_t> data) = 0; 138 139 // Deletes the key from storage in the virtual machine. As the virtual machine 140 // has limited storage shared by all applications it is important to delete 141 // keys no longer in use. 142 virtual bool DeleteKey() = 0; 143 }; 144 145 // VirtualUnexportableKeyProvider creates |VirtualUnexportableSigningKey|s. 146 class CRYPTO_EXPORT VirtualUnexportableKeyProvider { 147 public: 148 virtual ~VirtualUnexportableKeyProvider(); 149 150 // SelectAlgorithm returns which signature algorithm from 151 // |acceptable_algorithms| would be used if |acceptable_algorithms| was passed 152 // to |GenerateSigningKeySlowly|. 153 virtual absl::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm( 154 base::span<const SignatureVerifier::SignatureAlgorithm> 155 acceptable_algorithms) = 0; 156 157 // GenerateSigningKey creates a new opaque signing key in a virtual machine. 158 // The first supported value of |acceptable_algorithms| determines the type of 159 // the key. Returns nullptr if it is not supported in the operating system, 160 // if no value in |acceptable_algorithms| is supported, or if there was an 161 // error creating the key. 162 // As the namespace is shared between all applications care should be taken to 163 // use a name that will not already be used by other applications. If a new 164 // key is created with the same name as a current key the creation will fail. 165 // Do not create a key with NULL or empty string as the name. 166 // 167 // Note: This may take milliseconds to run. 168 virtual std::unique_ptr<VirtualUnexportableSigningKey> GenerateSigningKey( 169 base::span<const SignatureVerifier::SignatureAlgorithm> 170 acceptable_algorithms, 171 std::string name) = 0; 172 173 // FromKeyName creates an |UnexportableSigningKey| from |name|, which is the 174 // name used to create the key. Returns nullptr if |name| cannot be imported. 175 // 176 // Note: This may take milliseconds to run. 177 virtual std::unique_ptr<VirtualUnexportableSigningKey> FromKeyName( 178 std::string name) = 0; 179 }; 180 181 // GetUnexportableKeyProvider returns an |UnexportableKeyProvider| 182 // for the current platform, or nullptr if there isn't one. This can be called 183 // from any thread but, in tests, but be sequenced with 184 // |SetUnexportableSigningKeyProvider|. 185 CRYPTO_EXPORT std::unique_ptr<UnexportableKeyProvider> 186 GetUnexportableKeyProvider(); 187 188 // GetVirtualUnexportableKeyProvider_DO_NOT_USE_METRICS_ONLY returns a 189 // |VirtualUnexportableKeyProvider| for the current platform, or nullptr if 190 // there isn't one. This should currently only be used for metrics gathering. 191 CRYPTO_EXPORT std::unique_ptr<VirtualUnexportableKeyProvider> 192 GetVirtualUnexportableKeyProvider_DO_NOT_USE_METRICS_ONLY(); 193 194 namespace internal { 195 196 CRYPTO_EXPORT void SetUnexportableKeyProviderForTesting( 197 std::unique_ptr<UnexportableKeyProvider> (*func)()); 198 199 } // namespace internal 200 201 } // namespace crypto 202 203 #endif // CRYPTO_UNEXPORTABLE_KEY_H_ 204