summaryrefslogtreecommitdiff
path: root/chromium/crypto
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2022-09-07 13:12:05 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2022-11-09 10:02:59 +0000
commit33fc33aa94d4add0878ec30dc818e34e1dd3cc2a (patch)
treef6af110909c79b2759136554f1143d8b0572af0a /chromium/crypto
parent7d2c5d177e9813077a621df8d18c0deda73099b3 (diff)
downloadqtwebengine-chromium-33fc33aa94d4add0878ec30dc818e34e1dd3cc2a.tar.gz
BASELINE: Update Chromium to 104.0.5112.120
Change-Id: I5d2726c2ab018d75d055739b6ba64317904f05bb Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/438935 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/crypto')
-rw-r--r--chromium/crypto/BUILD.gn23
-rw-r--r--chromium/crypto/encryptor.cc15
-rw-r--r--chromium/crypto/encryptor_unittest.cc63
-rw-r--r--chromium/crypto/hmac.cc1
-rw-r--r--chromium/crypto/nss_util.cc16
-rw-r--r--chromium/crypto/p224_spake.cc1
-rw-r--r--chromium/crypto/scoped_mock_unexportable_key_provider.cc1
-rw-r--r--chromium/crypto/unexportable_key.cc68
-rw-r--r--chromium/crypto/unexportable_key.h5
9 files changed, 156 insertions, 37 deletions
diff --git a/chromium/crypto/BUILD.gn b/chromium/crypto/BUILD.gn
index 8811a0cca47..69594cbd135 100644
--- a/chromium/crypto/BUILD.gn
+++ b/chromium/crypto/BUILD.gn
@@ -57,7 +57,6 @@ component("crypto") {
]
deps = [
- ":platform",
"//base",
"//base/third_party/dynamic_annotations",
]
@@ -128,6 +127,7 @@ component("crypto") {
"nss_util_internal.h",
]
deps += [ "//build:chromeos_buildflags" ]
+ configs += [ "//build/config/linux/nss" ]
}
if (is_chromeos_ash) {
@@ -168,11 +168,11 @@ test("crypto_unittests") {
"nss_key_util_unittest.cc",
"nss_util_unittest.cc",
]
+ configs += [ "//build/config/linux/nss" ]
}
deps = [
":crypto",
- ":platform",
":test_support",
"//base",
"//base/test:run_all_unittests",
@@ -194,6 +194,7 @@ static_library("test_support") {
"scoped_test_nss_db.cc",
"scoped_test_nss_db.h",
]
+ configs += [ "//build/config/linux/nss" ]
}
if (is_chromeos_ash) {
@@ -207,24 +208,6 @@ static_library("test_support") {
deps = [
":crypto",
- ":platform",
"//base",
]
}
-
-# This target historically abstracted between different cryptography and TLS
-# libraries. Now we always use //third_party/boringssl for cryptography and TLS.
-# On Linux and Chrome OS, we additionally use //build/config/linux/nss for some
-# certificate-related platform integration points. Depend on one or both of the
-# individual targets instead of this one.
-#
-# TODO(https://crbug.com/1275165): Remove this target.
-group("platform") {
- public_deps = [ "//third_party/boringssl" ]
-
- # Link in NSS if it is used for the platform certificate library
- # (use_nss_certs).
- if (use_nss_certs) {
- public_configs = [ "//build/config/linux/nss" ]
- }
-}
diff --git a/chromium/crypto/encryptor.cc b/chromium/crypto/encryptor.cc
index 0d21db3365f..ea12e719aa3 100644
--- a/chromium/crypto/encryptor.cc
+++ b/chromium/crypto/encryptor.cc
@@ -64,24 +64,20 @@ bool Encryptor::Init(const SymmetricKey* key,
}
bool Encryptor::Encrypt(base::StringPiece plaintext, std::string* ciphertext) {
- CHECK(!plaintext.empty() || mode_ == CBC);
return CryptString(/*do_encrypt=*/true, plaintext, ciphertext);
}
bool Encryptor::Encrypt(base::span<const uint8_t> plaintext,
std::vector<uint8_t>* ciphertext) {
- CHECK(!plaintext.empty() || mode_ == CBC);
return CryptBytes(/*do_encrypt=*/true, plaintext, ciphertext);
}
bool Encryptor::Decrypt(base::StringPiece ciphertext, std::string* plaintext) {
- CHECK(!ciphertext.empty());
return CryptString(/*do_encrypt=*/false, ciphertext, plaintext);
}
bool Encryptor::Decrypt(base::span<const uint8_t> ciphertext,
std::vector<uint8_t>* plaintext) {
- CHECK(!ciphertext.empty());
return CryptBytes(/*do_encrypt=*/false, ciphertext, plaintext);
}
@@ -102,18 +98,13 @@ bool Encryptor::SetCounter(base::span<const uint8_t> counter) {
bool Encryptor::CryptString(bool do_encrypt,
base::StringPiece input,
std::string* output) {
- size_t out_size = MaxOutput(do_encrypt, input.size());
- CHECK_GT(out_size + 1, out_size); // Overflow
- std::string result;
- uint8_t* out_ptr =
- reinterpret_cast<uint8_t*>(base::WriteInto(&result, out_size + 1));
-
+ std::string result(MaxOutput(do_encrypt, input.size()), '\0');
absl::optional<size_t> len =
(mode_ == CTR)
? CryptCTR(do_encrypt, base::as_bytes(base::make_span(input)),
- base::make_span(out_ptr, out_size))
+ base::as_writable_bytes(base::make_span(result)))
: Crypt(do_encrypt, base::as_bytes(base::make_span(input)),
- base::make_span(out_ptr, out_size));
+ base::as_writable_bytes(base::make_span(result)));
if (!len)
return false;
diff --git a/chromium/crypto/encryptor_unittest.cc b/chromium/crypto/encryptor_unittest.cc
index 93f8447d711..fec60f5050e 100644
--- a/chromium/crypto/encryptor_unittest.cc
+++ b/chromium/crypto/encryptor_unittest.cc
@@ -9,6 +9,7 @@
#include <memory>
#include <string>
+#include "base/containers/span.h"
#include "base/strings/string_number_conversions.h"
#include "crypto/symmetric_key.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -466,7 +467,7 @@ TEST(EncryptorTest, UnsupportedIV) {
EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
}
-TEST(EncryptorTest, EmptyEncrypt) {
+TEST(EncryptorTest, EmptyEncryptCBC) {
std::string key = "128=SixteenBytes";
std::string iv = "Sweet Sixteen IV";
std::string plaintext;
@@ -477,7 +478,7 @@ TEST(EncryptorTest, EmptyEncrypt) {
ASSERT_TRUE(sym_key.get());
crypto::Encryptor encryptor;
- // The IV must be exactly as long a the cipher block size.
+ // The IV must be exactly as long as the cipher block size.
EXPECT_EQ(16U, iv.size());
EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
@@ -485,6 +486,64 @@ TEST(EncryptorTest, EmptyEncrypt) {
EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
ciphertext.size()));
+
+ std::string decrypted;
+ EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
+ EXPECT_EQ(decrypted, plaintext);
+
+ // Decrypting the empty string should fail. Our formulation of CBC expects a
+ // full block of padding for CBC.
+ EXPECT_FALSE(encryptor.Decrypt(std::string(), &decrypted));
+
+ // Repeat the test with the byte-based API.
+ EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
+ std::vector<uint8_t> ciphertext_bytes;
+ EXPECT_TRUE(
+ encryptor.Encrypt(base::span<const uint8_t>(), &ciphertext_bytes));
+ EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext_bytes));
+
+ std::vector<uint8_t> decrypted_bytes;
+ EXPECT_TRUE(encryptor.Decrypt(ciphertext_bytes, &decrypted_bytes));
+ EXPECT_EQ(decrypted_bytes.size(), 0u);
+
+ // Decrypting the empty string should fail. Our formulation of CBC expects a
+ // full block of padding for CBC.
+ EXPECT_FALSE(
+ encryptor.Decrypt(base::span<const uint8_t>(), &decrypted_bytes));
+}
+
+TEST(EncryptorTest, EmptyEncryptCTR) {
+ std::string key = "128=SixteenBytes";
+ std::string iv = "Sweet Sixteen IV";
+ std::string plaintext;
+ std::string expected_ciphertext;
+
+ std::unique_ptr<crypto::SymmetricKey> sym_key(
+ crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
+ ASSERT_TRUE(sym_key.get());
+
+ crypto::Encryptor encryptor;
+ EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CTR, ""));
+ ASSERT_TRUE(encryptor.SetCounter(iv));
+
+ std::string ciphertext;
+ EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
+ EXPECT_EQ(expected_ciphertext, ciphertext);
+
+ std::string decrypted;
+ EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
+ EXPECT_EQ(decrypted, plaintext);
+
+ // Repeat the test with the byte-based API.
+ ASSERT_TRUE(encryptor.SetCounter(iv));
+ std::vector<uint8_t> ciphertext_bytes;
+ EXPECT_TRUE(
+ encryptor.Encrypt(base::span<const uint8_t>(), &ciphertext_bytes));
+ EXPECT_EQ(ciphertext_bytes.size(), 0u);
+
+ std::vector<uint8_t> decrypted_bytes;
+ EXPECT_TRUE(encryptor.Decrypt(base::span<const uint8_t>(), &decrypted_bytes));
+ EXPECT_EQ(decrypted_bytes.size(), 0u);
}
TEST(EncryptorTest, CipherTextNotMultipleOfBlockSize) {
diff --git a/chromium/crypto/hmac.cc b/chromium/crypto/hmac.cc
index ca7c0f5c587..093dfbd5ff2 100644
--- a/chromium/crypto/hmac.cc
+++ b/chromium/crypto/hmac.cc
@@ -10,6 +10,7 @@
#include <string>
#include "base/check.h"
+#include "base/check_op.h"
#include "base/notreached.h"
#include "base/stl_util.h"
#include "crypto/openssl_util.h"
diff --git a/chromium/crypto/nss_util.cc b/chromium/crypto/nss_util.cc
index 084cd2fd792..32ec5b1e58c 100644
--- a/chromium/crypto/nss_util.cc
+++ b/chromium/crypto/nss_util.cc
@@ -147,7 +147,21 @@ class NSSInitSingleton {
const std::string modspec =
base::StringPrintf("configDir='sql:%s' tokenDescription='%s'",
path.value().c_str(), description.c_str());
- PK11SlotInfo* db_slot_info = SECMOD_OpenUserDB(modspec.c_str());
+
+ // TODO(crbug.com/1163303): Presumably there's a race condition with
+ // session_manager around creating/opening the software NSS database. The
+ // retry loop is a temporary workaround that should at least reduce the
+ // amount of failures until a proper fix is implemented.
+ PK11SlotInfo* db_slot_info = nullptr;
+ int attempts_counter = 0;
+ for (; !db_slot_info && (attempts_counter < 10); ++attempts_counter) {
+ db_slot_info = SECMOD_OpenUserDB(modspec.c_str());
+ }
+ if (db_slot_info && (attempts_counter > 1)) {
+ LOG(ERROR) << "Opening persistent database failed "
+ << attempts_counter - 1 << " times before succeeding";
+ }
+
if (db_slot_info) {
if (PK11_NeedUserInit(db_slot_info))
PK11_InitPin(db_slot_info, nullptr, nullptr);
diff --git a/chromium/crypto/p224_spake.cc b/chromium/crypto/p224_spake.cc
index 7ed66b6c6e4..cdbbd9afa98 100644
--- a/chromium/crypto/p224_spake.cc
+++ b/chromium/crypto/p224_spake.cc
@@ -11,6 +11,7 @@
#include <algorithm>
+#include "base/check_op.h"
#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "crypto/random.h"
diff --git a/chromium/crypto/scoped_mock_unexportable_key_provider.cc b/chromium/crypto/scoped_mock_unexportable_key_provider.cc
index 823b2a47733..7a2f36208e6 100644
--- a/chromium/crypto/scoped_mock_unexportable_key_provider.cc
+++ b/chromium/crypto/scoped_mock_unexportable_key_provider.cc
@@ -4,6 +4,7 @@
#include <vector>
+#include "base/check.h"
#include "crypto/scoped_mock_unexportable_key_provider.h"
#include "crypto/sha2.h"
#include "crypto/signature_verifier.h"
diff --git a/chromium/crypto/unexportable_key.cc b/chromium/crypto/unexportable_key.cc
index 97224a09e28..c735638d0e1 100644
--- a/chromium/crypto/unexportable_key.cc
+++ b/chromium/crypto/unexportable_key.cc
@@ -4,11 +4,24 @@
#include "crypto/unexportable_key.h"
+#include "base/bind.h"
#include "base/check.h"
#include "build/build_config.h"
+#if BUILDFLAG(IS_WIN)
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
+#include "base/timer/elapsed_timer.h"
+#endif // BUILDFLAG(IS_WIN)
+
namespace crypto {
+namespace {
+std::unique_ptr<UnexportableKeyProvider> (*g_mock_provider)() = nullptr;
+} // namespace
+
UnexportableSigningKey::~UnexportableSigningKey() = default;
UnexportableKeyProvider::~UnexportableKeyProvider() = default;
@@ -16,8 +29,6 @@ UnexportableKeyProvider::~UnexportableKeyProvider() = default;
std::unique_ptr<UnexportableKeyProvider> GetUnexportableKeyProviderWin();
#endif
-static std::unique_ptr<UnexportableKeyProvider> (*g_mock_provider)() = nullptr;
-
std::unique_ptr<UnexportableKeyProvider> GetUnexportableKeyProvider() {
if (g_mock_provider) {
return g_mock_provider();
@@ -30,6 +41,59 @@ std::unique_ptr<UnexportableKeyProvider> GetUnexportableKeyProvider() {
#endif
}
+#if BUILDFLAG(IS_WIN)
+void MeasureTPMAvailabilityWin() {
+ // Measure the fraction of Windows machines that have TPMs, and what the best
+ // supported algorithm is.
+ base::ThreadPool::PostTask(
+ // GetUnexportableKeyProvider can call functions that take the global
+ // loader lock, so although BEST_EFFORT makes it low priority to start,
+ // once it starts it must run in a foreground thread to avoid priority
+ // inversions.
+ FROM_HERE,
+ {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
+ base::ThreadPolicy::MUST_USE_FOREGROUND},
+ base::BindOnce([]() {
+ // Note that values here are used in a recorded histogram. Don't change
+ // the values of existing members.
+ enum TPMSupport {
+ kNone = 0,
+ kRSA = 1,
+ kECDSA = 2,
+ kMaxValue = 2,
+ };
+
+ TPMSupport result = TPMSupport::kNone;
+ std::unique_ptr<UnexportableKeyProvider> provider =
+ GetUnexportableKeyProvider();
+ if (provider) {
+ const SignatureVerifier::SignatureAlgorithm kAllAlgorithms[] = {
+ SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256,
+ SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256,
+ };
+ auto algo = provider->SelectAlgorithm(kAllAlgorithms);
+ if (algo) {
+ switch (*algo) {
+ case SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256:
+ result = TPMSupport::kECDSA;
+ break;
+ case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA256:
+ result = TPMSupport::kRSA;
+ break;
+ case SignatureVerifier::SignatureAlgorithm::RSA_PKCS1_SHA1:
+ case SignatureVerifier::SignatureAlgorithm::RSA_PSS_SHA256:
+ // Not supported for this metric.
+ break;
+ }
+ }
+ }
+ // This metric was previously named Crypto.TPMSupport but that expired,
+ // so using a new name to avoid mixing up with old data.
+ base::UmaHistogramEnumeration("Crypto.TPMSupport2", result);
+ }));
+}
+#endif // BUILDFLAG(IS_WIN)
+
namespace internal {
void SetUnexportableKeyProviderForTesting(
diff --git a/chromium/crypto/unexportable_key.h b/chromium/crypto/unexportable_key.h
index 2a59c4143ff..2e352e47361 100644
--- a/chromium/crypto/unexportable_key.h
+++ b/chromium/crypto/unexportable_key.h
@@ -94,6 +94,11 @@ class CRYPTO_EXPORT UnexportableKeyProvider {
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(