blob: 2a59c4143ff2e5cbdd5128034d13d62af8c9cede [file] [log] [blame]
Adam Langley979ee872021-03-12 02:47:191// Copyright (c) 2021 The Chromium Authors. All rights reserved.
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
Adam Langley979ee872021-03-12 02:47:1910#include "crypto/crypto_export.h"
11#include "crypto/signature_verifier.h"
Anton Bikineeva3f961db2021-05-15 17:56:1212#include "third_party/abseil-cpp/absl/types/optional.h"
Adam Langley979ee872021-03-12 02:47:1913
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.
20class CRYPTO_EXPORT UnexportableSigningKey {
21 public:
22 virtual ~UnexportableSigningKey();
23
24 // Algorithm returns the algorithm of the key in this object.
25 virtual SignatureVerifier::SignatureAlgorithm Algorithm() const = 0;
26
27 // GetSubjectPublicKeyInfo returns an SPKI that contains the public key of
28 // this object.
29 virtual std::vector<uint8_t> GetSubjectPublicKeyInfo() const = 0;
30
31 // GetWrappedKey returns the encrypted private key of this object. It is
32 // encrypted to a key that is kept in hardware and the unencrypted private
33 // key never exists in the CPU's memory.
34 //
35 // A wrapped key may be used with a future instance of this code to recreate
36 // the key so long as it's running on the same computer.
37 //
38 // Note: it is possible to export this wrapped key off machine, but it must be
39 // sealed with an AEAD first. The wrapped key may contain machine identifiers
40 // and other values that you wouldn't want to export. Additionally
41 // |UnexportableKeyProvider::FromWrappedSigningKey| should not be presented
42 // attacked-controlled input and the AEAD would serve to authenticate the
43 // wrapped key.
44 virtual std::vector<uint8_t> GetWrappedKey() const = 0;
45
46 // SignSlowly returns a signature of |data|, or |nullopt| if an error occurs
47 // during signing.
48 //
49 // Note: this may take a second or more to run.
Anton Bikineeva3f961db2021-05-15 17:56:1250 virtual absl::optional<std::vector<uint8_t>> SignSlowly(
Adam Langley979ee872021-03-12 02:47:1951 base::span<const uint8_t> data) = 0;
52};
53
54// UnexportableKeyProvider creates |UnexportableSigningKey|s.
55class CRYPTO_EXPORT UnexportableKeyProvider {
56 public:
57 virtual ~UnexportableKeyProvider();
58
59 // SelectAlgorithm returns which signature algorithm from
60 // |acceptable_algorithms| would be used if |acceptable_algorithms| was passed
61 // to |GenerateSigningKeySlowly|.
Anton Bikineeva3f961db2021-05-15 17:56:1262 virtual absl::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
Adam Langley979ee872021-03-12 02:47:1963 base::span<const SignatureVerifier::SignatureAlgorithm>
64 acceptable_algorithms) = 0;
65
66 // GenerateSigningKeySlowly creates a new opaque signing key in hardware. The
67 // first supported value of |acceptable_algorithms| determines the type of the
68 // key. Returns nullptr if no supported hardware exists, if no value in
69 // |acceptable_algorithms| is supported, or if there was an error creating the
70 // key.
71 //
72 // Note: this may take one or two seconds to run.
73 virtual std::unique_ptr<UnexportableSigningKey> GenerateSigningKeySlowly(
74 base::span<const SignatureVerifier::SignatureAlgorithm>
75 acceptable_algorithms) = 0;
76
77 // FromWrappedSigningKey creates an |UnexportableSigningKey| from
78 // |wrapped_key|, which must have resulted from calling |GetWrappedKey| on a
79 // previous instance of |UnexportableSigningKey|. Returns nullptr if
80 // |wrapped_key| cannot be imported.
81 //
82 // Note: this may take up to a second.
83 //
84 // Note: do not call this with attacker-controlled data. The underlying
85 // interfaces to the secure hardware may not be robust. See |GetWrappedKey|.
86 virtual std::unique_ptr<UnexportableSigningKey> FromWrappedSigningKeySlowly(
87 base::span<const uint8_t> wrapped_key) = 0;
88};
89
90// GetUnexportableKeyProvider returns an |UnexportableKeyProvider|
91// for the current platform, or nullptr if there isn't one. This can be called
92// from any thread but, in tests, but be sequenced with
93// |SetUnexportableSigningKeyProvider|.
94CRYPTO_EXPORT std::unique_ptr<UnexportableKeyProvider>
95GetUnexportableKeyProvider();
96
Adam Langley979ee872021-03-12 02:47:1997namespace internal {
98
99CRYPTO_EXPORT void SetUnexportableKeyProviderForTesting(
100 std::unique_ptr<UnexportableKeyProvider> (*func)());
101
102} // namespace internal
103
104} // namespace crypto
105
106#endif // CRYPTO_UNEXPORTABLE_KEY_H_