From 33fc33aa94d4add0878ec30dc818e34e1dd3cc2a Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 7 Sep 2022 13:12:05 +0200 Subject: 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 --- chromium/crypto/BUILD.gn | 23 +------- chromium/crypto/encryptor.cc | 15 +---- chromium/crypto/encryptor_unittest.cc | 63 +++++++++++++++++++- chromium/crypto/hmac.cc | 1 + chromium/crypto/nss_util.cc | 16 ++++- chromium/crypto/p224_spake.cc | 1 + .../scoped_mock_unexportable_key_provider.cc | 1 + chromium/crypto/unexportable_key.cc | 68 +++++++++++++++++++++- chromium/crypto/unexportable_key.h | 5 ++ 9 files changed, 156 insertions(+), 37 deletions(-) (limited to 'chromium/crypto') 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 plaintext, std::vector* 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 ciphertext, std::vector* plaintext) { - CHECK(!ciphertext.empty()); return CryptBytes(/*do_encrypt=*/false, ciphertext, plaintext); } @@ -102,18 +98,13 @@ bool Encryptor::SetCounter(base::span 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(base::WriteInto(&result, out_size + 1)); - + std::string result(MaxOutput(do_encrypt, input.size()), '\0'); absl::optional 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 #include +#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 ciphertext_bytes; + EXPECT_TRUE( + encryptor.Encrypt(base::span(), &ciphertext_bytes)); + EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext_bytes)); + + std::vector 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(), &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 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 ciphertext_bytes; + EXPECT_TRUE( + encryptor.Encrypt(base::span(), &ciphertext_bytes)); + EXPECT_EQ(ciphertext_bytes.size(), 0u); + + std::vector decrypted_bytes; + EXPECT_TRUE(encryptor.Decrypt(base::span(), &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 #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 +#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 +#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 (*g_mock_provider)() = nullptr; +} // namespace + UnexportableSigningKey::~UnexportableSigningKey() = default; UnexportableKeyProvider::~UnexportableKeyProvider() = default; @@ -16,8 +29,6 @@ UnexportableKeyProvider::~UnexportableKeyProvider() = default; std::unique_ptr GetUnexportableKeyProviderWin(); #endif -static std::unique_ptr (*g_mock_provider)() = nullptr; - std::unique_ptr GetUnexportableKeyProvider() { if (g_mock_provider) { return g_mock_provider(); @@ -30,6 +41,59 @@ std::unique_ptr 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 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 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( -- cgit v1.2.1