[go: nahoru, domu]

blob: f4aa85af7772dfcb25c14ad39bf82139324a2b81 [file] [log] [blame]
Avi Drissman201a9a832022-09-13 19:39:251// Copyright 2021 The Chromium Authors
Adam Langley979ee872021-03-12 02:47:192// 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
Arthur Sonzogni59ac8222023-11-10 09:46:5410#include <optional>
Adam Langley979ee872021-03-12 02:47:1911#include "crypto/crypto_export.h"
12#include "crypto/signature_verifier.h"
13
14namespace 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.
Alex Ilina06c3fa2023-01-09 11:39:5020//
21// See also //components/unexportable_keys for a higher-level key management
22// API.
Adam Langley979ee872021-03-12 02:47:1923class 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.
Arthur Sonzogni59ac8222023-11-10 09:46:5453 virtual std::optional<std::vector<uint8_t>> SignSlowly(
Adam Langley979ee872021-03-12 02:47:1954 base::span<const uint8_t> data) = 0;
55};
56
57// UnexportableKeyProvider creates |UnexportableSigningKey|s.
58class 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|.
Arthur Sonzogni59ac8222023-11-10 09:46:5465 virtual std::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
Adam Langley979ee872021-03-12 02:47:1966 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
Kristian Monsen0578176f42023-03-08 20:44:5193// 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
113class 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.
Arthur Sonzogni59ac8222023-11-10 09:46:54136 virtual std::optional<std::vector<uint8_t>> Sign(
Kristian Monsen0578176f42023-03-08 20:44:51137 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.
Rafael Cintronfa079eb2023-05-18 20:48:37142 virtual void DeleteKey() = 0;
Kristian Monsen0578176f42023-03-08 20:44:51143};
144
145// VirtualUnexportableKeyProvider creates |VirtualUnexportableSigningKey|s.
146class 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|.
Arthur Sonzogni59ac8222023-11-10 09:46:54153 virtual std::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
Kristian Monsen0578176f42023-03-08 20:44:51154 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
Adam Langley979ee872021-03-12 02:47:19181// 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|.
185CRYPTO_EXPORT std::unique_ptr<UnexportableKeyProvider>
186GetUnexportableKeyProvider();
187
Kristian Monsen0578176f42023-03-08 20:44:51188// 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.
191CRYPTO_EXPORT std::unique_ptr<VirtualUnexportableKeyProvider>
192GetVirtualUnexportableKeyProvider_DO_NOT_USE_METRICS_ONLY();
193
Alex Ilin869e4212023-07-17 23:22:26194// `GetSoftwareUnsecureUnexportableKeyProvider()` returns a mock software
195// implementation of `UnexportableKeyProvider` that can be used on platforms
196// that do not have a native secure implementation.
197// This should be used for development purposes only since these keys are not
198// backed by hardware and are not stored securely.
199CRYPTO_EXPORT std::unique_ptr<UnexportableKeyProvider>
200GetSoftwareUnsecureUnexportableKeyProvider();
201
Adam Langley979ee872021-03-12 02:47:19202namespace internal {
203
204CRYPTO_EXPORT void SetUnexportableKeyProviderForTesting(
205 std::unique_ptr<UnexportableKeyProvider> (*func)());
206
207} // namespace internal
208
209} // namespace crypto
210
211#endif // CRYPTO_UNEXPORTABLE_KEY_H_