1 // Copyright 2023 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 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
7 #pragma allow_unsafe_buffers
8 #endif
9
10 #include "base/check.h"
11 #include "build/build_config.h"
12 #include "crypto/sha2.h"
13 #include "crypto/signature_verifier.h"
14 #include "crypto/unexportable_key.h"
15 #include "third_party/boringssl/src/include/openssl/bn.h"
16 #include "third_party/boringssl/src/include/openssl/bytestring.h"
17 #include "third_party/boringssl/src/include/openssl/ec.h"
18 #include "third_party/boringssl/src/include/openssl/ec_key.h"
19 #include "third_party/boringssl/src/include/openssl/ecdsa.h"
20 #include "third_party/boringssl/src/include/openssl/evp.h"
21 #include "third_party/boringssl/src/include/openssl/obj.h"
22 #include "third_party/boringssl/src/include/openssl/rsa.h"
23
24 #if BUILDFLAG(IS_MAC)
25 #include "base/notreached.h"
26 #endif // BUILDFLAG(IS_MAC)
27
28 namespace crypto {
29
30 namespace {
31
CBBToVector(const CBB * cbb)32 std::vector<uint8_t> CBBToVector(const CBB* cbb) {
33 return std::vector<uint8_t>(CBB_data(cbb), CBB_data(cbb) + CBB_len(cbb));
34 }
35
36 class SoftwareECDSA : public UnexportableSigningKey {
37 public:
SoftwareECDSA(bssl::UniquePtr<EC_KEY> key)38 explicit SoftwareECDSA(bssl::UniquePtr<EC_KEY> key) : key_(std::move(key)) {}
39 ~SoftwareECDSA() override = default;
40
Algorithm() const41 SignatureVerifier::SignatureAlgorithm Algorithm() const override {
42 return SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256;
43 }
44
GetSubjectPublicKeyInfo() const45 std::vector<uint8_t> GetSubjectPublicKeyInfo() const override {
46 bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
47 CHECK(EVP_PKEY_set1_EC_KEY(pkey.get(), key_.get()));
48
49 bssl::ScopedCBB cbb;
50 CHECK(CBB_init(cbb.get(), /*initial_capacity=*/128) &&
51 EVP_marshal_public_key(cbb.get(), pkey.get()));
52 return CBBToVector(cbb.get());
53 }
54
GetWrappedKey() const55 std::vector<uint8_t> GetWrappedKey() const override {
56 bssl::ScopedCBB cbb;
57 CHECK(
58 CBB_init(cbb.get(), /*initial_capacity=*/128) &&
59 EC_KEY_marshal_private_key(cbb.get(), key_.get(),
60 EC_PKEY_NO_PARAMETERS | EC_PKEY_NO_PUBKEY));
61 return CBBToVector(cbb.get());
62 }
63
SignSlowly(base::span<const uint8_t> data)64 std::optional<std::vector<uint8_t>> SignSlowly(
65 base::span<const uint8_t> data) override {
66 std::vector<uint8_t> ret(ECDSA_size(key_.get()));
67 std::array<uint8_t, kSHA256Length> digest = SHA256Hash(data);
68 unsigned int ret_size;
69 CHECK(ECDSA_sign(0, digest.data(), digest.size(), ret.data(), &ret_size,
70 key_.get()));
71 ret.resize(ret_size);
72 return ret;
73 }
74
75 #if BUILDFLAG(IS_MAC)
GetSecKeyRef() const76 SecKeyRef GetSecKeyRef() const override { NOTREACHED(); }
77 #endif // BUILDFLAG(IS_MAC)
78
79 private:
80 bssl::UniquePtr<EC_KEY> key_;
81 };
82
83 class SoftwareRSA : public UnexportableSigningKey {
84 public:
SoftwareRSA(bssl::UniquePtr<RSA> key)85 explicit SoftwareRSA(bssl::UniquePtr<RSA> key) : key_(std::move(key)) {}
86 ~SoftwareRSA() override = default;
87
Algorithm() const88 SignatureVerifier::SignatureAlgorithm Algorithm() const override {
89 return SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256;
90 }
91
GetSubjectPublicKeyInfo() const92 std::vector<uint8_t> GetSubjectPublicKeyInfo() const override {
93 bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
94 CHECK(EVP_PKEY_set1_RSA(pkey.get(), key_.get()));
95
96 bssl::ScopedCBB cbb;
97 CHECK(CBB_init(cbb.get(), /*initial_capacity=*/384) &&
98 EVP_marshal_public_key(cbb.get(), pkey.get()));
99 return CBBToVector(cbb.get());
100 }
101
GetWrappedKey() const102 std::vector<uint8_t> GetWrappedKey() const override {
103 bssl::ScopedCBB cbb;
104 CHECK(CBB_init(cbb.get(), 384) &&
105 RSA_marshal_private_key(cbb.get(), key_.get()));
106 return CBBToVector(cbb.get());
107 }
108
SignSlowly(base::span<const uint8_t> data)109 std::optional<std::vector<uint8_t>> SignSlowly(
110 base::span<const uint8_t> data) override {
111 std::vector<uint8_t> ret(RSA_size(key_.get()));
112 std::array<uint8_t, kSHA256Length> digest = SHA256Hash(data);
113 unsigned int ret_size;
114 CHECK(RSA_sign(NID_sha256, digest.data(), digest.size(), ret.data(),
115 &ret_size, key_.get()));
116 ret.resize(ret_size);
117 return ret;
118 }
119
120 #if BUILDFLAG(IS_MAC)
GetSecKeyRef() const121 SecKeyRef GetSecKeyRef() const override { NOTREACHED(); }
122 #endif // BUILDFLAG(IS_MAC)
123
124 private:
125 bssl::UniquePtr<RSA> key_;
126 };
127
128 class SoftwareProvider : public UnexportableKeyProvider {
129 public:
130 ~SoftwareProvider() override = default;
131
SelectAlgorithm(base::span<const SignatureVerifier::SignatureAlgorithm> acceptable_algorithms)132 std::optional<SignatureVerifier::SignatureAlgorithm> SelectAlgorithm(
133 base::span<const SignatureVerifier::SignatureAlgorithm>
134 acceptable_algorithms) override {
135 for (auto algo : acceptable_algorithms) {
136 switch (algo) {
137 case SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256:
138 case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256:
139 return algo;
140 case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA1:
141 case SignatureVerifier::SignatureAlgorithm::RSA_PSS_SHA256:
142 continue; // Not supported
143 }
144 }
145
146 return std::nullopt;
147 }
148
GenerateSigningKeySlowly(base::span<const SignatureVerifier::SignatureAlgorithm> acceptable_algorithms)149 std::unique_ptr<UnexportableSigningKey> GenerateSigningKeySlowly(
150 base::span<const SignatureVerifier::SignatureAlgorithm>
151 acceptable_algorithms) override {
152 if (!SelectAlgorithm(acceptable_algorithms)) {
153 return nullptr;
154 }
155
156 for (auto algo : acceptable_algorithms) {
157 switch (algo) {
158 case SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256: {
159 bssl::UniquePtr<EC_KEY> key(
160 EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
161 CHECK(EC_KEY_generate_key(key.get()));
162 return std::make_unique<SoftwareECDSA>(std::move(key));
163 }
164
165 case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256: {
166 bssl::UniquePtr<RSA> key(RSA_new());
167 bssl::UniquePtr<BIGNUM> e(BN_new());
168 BN_set_word(e.get(), RSA_F4);
169 RSA_generate_key_ex(key.get(), 2048, e.get(), nullptr);
170 return std::make_unique<SoftwareRSA>(std::move(key));
171 }
172 case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA1:
173 case SignatureVerifier::SignatureAlgorithm::RSA_PSS_SHA256:
174 continue; // Not supported
175 }
176 }
177
178 return nullptr;
179 }
180
FromWrappedSigningKeySlowly(base::span<const uint8_t> wrapped_key)181 std::unique_ptr<UnexportableSigningKey> FromWrappedSigningKeySlowly(
182 base::span<const uint8_t> wrapped_key) override {
183 { // Try to parse ECDSA
184 CBS cbs;
185 CBS_init(&cbs, wrapped_key.data(), wrapped_key.size());
186 bssl::UniquePtr<EC_GROUP> p256(
187 EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
188 bssl::UniquePtr<EC_KEY> key(EC_KEY_parse_private_key(&cbs, p256.get()));
189 if (key && CBS_len(&cbs) == 0) {
190 return std::make_unique<SoftwareECDSA>(std::move(key));
191 }
192 }
193
194 { // Try RSA
195 CBS cbs;
196 CBS_init(&cbs, wrapped_key.data(), wrapped_key.size());
197 bssl::UniquePtr<RSA> key(RSA_parse_private_key(&cbs));
198 if (key && CBS_len(&cbs) == 0) {
199 return std::make_unique<SoftwareRSA>(std::move(key));
200 }
201 }
202
203 return nullptr;
204 }
205
DeleteSigningKeySlowly(base::span<const uint8_t> wrapped_key)206 bool DeleteSigningKeySlowly(base::span<const uint8_t> wrapped_key) override {
207 // Unexportable software keys are stateless.
208 return true;
209 }
210 };
211
212 } // namespace
213
214 std::unique_ptr<UnexportableKeyProvider>
GetSoftwareUnsecureUnexportableKeyProvider()215 GetSoftwareUnsecureUnexportableKeyProvider() {
216 return std::make_unique<SoftwareProvider>();
217 }
218
219 } // namespace crypto
220