diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-20 13:40:20 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-22 12:41:23 +0000 |
commit | 7961cea6d1041e3e454dae6a1da660b453efd238 (patch) | |
tree | c0eeb4a9ff9ba32986289c1653d9608e53ccb444 /chromium/crypto | |
parent | b7034d0803538058e5c9d904ef03cf5eab34f6ef (diff) | |
download | qtwebengine-chromium-7961cea6d1041e3e454dae6a1da660b453efd238.tar.gz |
BASELINE: Update Chromium to 78.0.3904.130
Change-Id: If185e0c0061b3437531c97c9c8c78f239352a68b
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/crypto')
-rw-r--r-- | chromium/crypto/aead.cc | 163 | ||||
-rw-r--r-- | chromium/crypto/aead.h | 43 | ||||
-rw-r--r-- | chromium/crypto/aead_unittest.cc | 25 | ||||
-rw-r--r-- | chromium/crypto/hkdf.cc | 13 | ||||
-rw-r--r-- | chromium/crypto/hkdf.h | 7 | ||||
-rw-r--r-- | chromium/crypto/nss_util.cc | 10 | ||||
-rw-r--r-- | chromium/crypto/sha2.cc | 7 | ||||
-rw-r--r-- | chromium/crypto/sha2.h | 14 |
8 files changed, 215 insertions, 67 deletions
diff --git a/chromium/crypto/aead.cc b/chromium/crypto/aead.cc index be6ea52b451..012752b3385 100644 --- a/chromium/crypto/aead.cc +++ b/chromium/crypto/aead.cc @@ -15,7 +15,7 @@ namespace crypto { -Aead::Aead(AeadAlgorithm algorithm) : key_(nullptr) { +Aead::Aead(AeadAlgorithm algorithm) { EnsureOpenSSLInit(); switch (algorithm) { case AES_128_CTR_HMAC_SHA256: @@ -32,88 +32,93 @@ Aead::Aead(AeadAlgorithm algorithm) : key_(nullptr) { Aead::~Aead() = default; -void Aead::Init(const std::string* key) { +void Aead::Init(base::span<const uint8_t> key) { DCHECK(!key_); - DCHECK_EQ(KeyLength(), key->size()); + DCHECK_EQ(KeyLength(), key.size()); key_ = key; } +static base::span<const uint8_t> ToSpan(base::StringPiece sp) { + return base::as_bytes(base::make_span(sp)); +} + +void Aead::Init(const std::string* key) { + Init(ToSpan(*key)); +} + +std::vector<uint8_t> Aead::Seal( + base::span<const uint8_t> plaintext, + base::span<const uint8_t> nonce, + base::span<const uint8_t> additional_data) const { + const size_t max_output_length = + EVP_AEAD_max_overhead(aead_) + plaintext.size(); + CHECK(max_output_length >= plaintext.size()); + std::vector<uint8_t> ret; + ret.resize(max_output_length); + + size_t output_length; + CHECK(Seal(plaintext, nonce, additional_data, ret.data(), &output_length, + max_output_length)); + ret.resize(output_length); + return ret; +} + bool Aead::Seal(base::StringPiece plaintext, base::StringPiece nonce, base::StringPiece additional_data, std::string* ciphertext) const { - DCHECK(key_); - DCHECK_EQ(NonceLength(), nonce.size()); - EVP_AEAD_CTX ctx; - - if (!EVP_AEAD_CTX_init(&ctx, aead_, - reinterpret_cast<const uint8_t*>(key_->data()), - key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) { - return false; - } - - std::string result; const size_t max_output_length = EVP_AEAD_max_overhead(aead_) + plaintext.size(); - size_t output_length; + CHECK(max_output_length + 1 >= plaintext.size()); uint8_t* out_ptr = reinterpret_cast<uint8_t*>( - base::WriteInto(&result, max_output_length + 1)); - - if (!EVP_AEAD_CTX_seal( - &ctx, out_ptr, &output_length, max_output_length, - reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(), - reinterpret_cast<const uint8_t*>(plaintext.data()), plaintext.size(), - reinterpret_cast<const uint8_t*>(additional_data.data()), - additional_data.size())) { - EVP_AEAD_CTX_cleanup(&ctx); + base::WriteInto(ciphertext, max_output_length + 1)); + + size_t output_length; + if (!Seal(ToSpan(plaintext), ToSpan(nonce), ToSpan(additional_data), out_ptr, + &output_length, max_output_length)) { + ciphertext->clear(); return false; } - DCHECK_LE(output_length, max_output_length); - result.resize(output_length); + ciphertext->resize(output_length); + return true; +} - ciphertext->swap(result); - EVP_AEAD_CTX_cleanup(&ctx); +base::Optional<std::vector<uint8_t>> Aead::Open( + base::span<const uint8_t> ciphertext, + base::span<const uint8_t> nonce, + base::span<const uint8_t> additional_data) const { + const size_t max_output_length = ciphertext.size(); + std::vector<uint8_t> ret; + ret.resize(max_output_length); - return true; + size_t output_length; + if (!Open(ciphertext, nonce, additional_data, ret.data(), &output_length, + max_output_length)) { + return base::nullopt; + } + + ret.resize(output_length); + return ret; } bool Aead::Open(base::StringPiece ciphertext, base::StringPiece nonce, base::StringPiece additional_data, std::string* plaintext) const { - DCHECK(key_); - EVP_AEAD_CTX ctx; - - if (!EVP_AEAD_CTX_init(&ctx, aead_, - reinterpret_cast<const uint8_t*>(key_->data()), - key_->size(), EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr)) { - return false; - } - - std::string result; const size_t max_output_length = ciphertext.size(); - size_t output_length; + CHECK(max_output_length + 1 > max_output_length); uint8_t* out_ptr = reinterpret_cast<uint8_t*>( - base::WriteInto(&result, max_output_length + 1)); - - if (!EVP_AEAD_CTX_open( - &ctx, out_ptr, &output_length, max_output_length, - reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(), - reinterpret_cast<const uint8_t*>(ciphertext.data()), - ciphertext.size(), - reinterpret_cast<const uint8_t*>(additional_data.data()), - additional_data.size())) { - EVP_AEAD_CTX_cleanup(&ctx); + base::WriteInto(plaintext, max_output_length + 1)); + + size_t output_length; + if (!Open(ToSpan(ciphertext), ToSpan(nonce), ToSpan(additional_data), out_ptr, + &output_length, max_output_length)) { + plaintext->clear(); return false; } - DCHECK_LE(output_length, max_output_length); - result.resize(output_length); - - plaintext->swap(result); - EVP_AEAD_CTX_cleanup(&ctx); - + plaintext->resize(output_length); return true; } @@ -125,4 +130,50 @@ size_t Aead::NonceLength() const { return EVP_AEAD_nonce_length(aead_); } +bool Aead::Seal(base::span<const uint8_t> plaintext, + base::span<const uint8_t> nonce, + base::span<const uint8_t> additional_data, + uint8_t* out, + size_t* output_length, + size_t max_output_length) const { + DCHECK(key_); + DCHECK_EQ(NonceLength(), nonce.size()); + bssl::ScopedEVP_AEAD_CTX ctx; + + if (!EVP_AEAD_CTX_init(ctx.get(), aead_, key_->data(), key_->size(), + EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr) || + !EVP_AEAD_CTX_seal(ctx.get(), out, output_length, max_output_length, + nonce.data(), nonce.size(), plaintext.data(), + plaintext.size(), additional_data.data(), + additional_data.size())) { + return false; + } + + DCHECK_LE(*output_length, max_output_length); + return true; +} + +bool Aead::Open(base::span<const uint8_t> plaintext, + base::span<const uint8_t> nonce, + base::span<const uint8_t> additional_data, + uint8_t* out, + size_t* output_length, + size_t max_output_length) const { + DCHECK(key_); + DCHECK_EQ(NonceLength(), nonce.size()); + bssl::ScopedEVP_AEAD_CTX ctx; + + if (!EVP_AEAD_CTX_init(ctx.get(), aead_, key_->data(), key_->size(), + EVP_AEAD_DEFAULT_TAG_LENGTH, nullptr) || + !EVP_AEAD_CTX_open(ctx.get(), out, output_length, max_output_length, + nonce.data(), nonce.size(), plaintext.data(), + plaintext.size(), additional_data.data(), + additional_data.size())) { + return false; + } + + DCHECK_LE(*output_length, max_output_length); + return true; +} + } // namespace crypto diff --git a/chromium/crypto/aead.h b/chromium/crypto/aead.h index 5802c7ef561..7a855fd71ec 100644 --- a/chromium/crypto/aead.h +++ b/chromium/crypto/aead.h @@ -6,9 +6,13 @@ #define CRYPTO_AEAD_H_ #include <stddef.h> +#include <stdint.h> #include <string> +#include <vector> +#include "base/containers/span.h" +#include "base/optional.h" #include "base/strings/string_piece.h" #include "crypto/crypto_export.h" @@ -16,22 +20,41 @@ struct evp_aead_st; namespace crypto { -// This class exposes the AES-128-CTR-HMAC-SHA256 and AES_256_GCM AEAD. +// This class exposes the AES-128-CTR-HMAC-SHA256 and AES_256_GCM AEAD. Note +// that there are two versions of most methods: an historical version based +// around |StringPiece| and a more modern version that takes |base::span|. +// Prefer the latter in new code. class CRYPTO_EXPORT Aead { public: enum AeadAlgorithm { AES_128_CTR_HMAC_SHA256, AES_256_GCM, AES_256_GCM_SIV }; explicit Aead(AeadAlgorithm algorithm); - + Aead(const Aead&) = delete; + Aead& operator=(const Aead&) = delete; ~Aead(); + // Note that Init keeps a reference to the data pointed to by |key| thus that + // data must outlive this object. + void Init(base::span<const uint8_t> key); + + // Note that Init keeps a reference to the data pointed to by |key| thus that + // data must outlive this object. void Init(const std::string* key); + std::vector<uint8_t> Seal(base::span<const uint8_t> plaintext, + base::span<const uint8_t> nonce, + base::span<const uint8_t> additional_data) const; + bool Seal(base::StringPiece plaintext, base::StringPiece nonce, base::StringPiece additional_data, std::string* ciphertext) const; + base::Optional<std::vector<uint8_t>> Open( + base::span<const uint8_t> ciphertext, + base::span<const uint8_t> nonce, + base::span<const uint8_t> additional_data) const; + bool Open(base::StringPiece ciphertext, base::StringPiece nonce, base::StringPiece additional_data, @@ -42,7 +65,21 @@ class CRYPTO_EXPORT Aead { size_t NonceLength() const; private: - const std::string* key_; + bool Seal(base::span<const uint8_t> plaintext, + base::span<const uint8_t> nonce, + base::span<const uint8_t> additional_data, + uint8_t* out, + size_t* output_length, + size_t max_output_length) const; + + bool Open(base::span<const uint8_t> ciphertext, + base::span<const uint8_t> nonce, + base::span<const uint8_t> additional_data, + uint8_t* out, + size_t* output_length, + size_t max_output_length) const; + + base::Optional<base::span<const uint8_t>> key_; const evp_aead_st* aead_; }; diff --git a/chromium/crypto/aead_unittest.cc b/chromium/crypto/aead_unittest.cc index 1af24e77009..50b73dc494f 100644 --- a/chromium/crypto/aead_unittest.cc +++ b/chromium/crypto/aead_unittest.cc @@ -37,6 +37,31 @@ TEST_P(AeadTest, SealOpen) { EXPECT_EQ(plaintext, decrypted); } +TEST_P(AeadTest, SealOpenSpan) { + crypto::Aead::AeadAlgorithm alg = GetParam(); + crypto::Aead aead(alg); + std::vector<uint8_t> key(aead.KeyLength(), 0u); + aead.Init(key); + std::vector<uint8_t> nonce(aead.NonceLength(), 0u); + static constexpr uint8_t kPlaintext[] = "plaintext"; + static constexpr uint8_t kAdditionalData[] = "additional data input"; + std::vector<uint8_t> ciphertext = + aead.Seal(kPlaintext, nonce, kAdditionalData); + EXPECT_LT(sizeof(kPlaintext), ciphertext.size()); + + base::Optional<std::vector<uint8_t>> decrypted = + aead.Open(ciphertext, nonce, kAdditionalData); + ASSERT_TRUE(decrypted); + ASSERT_EQ(decrypted->size(), sizeof(kPlaintext)); + ASSERT_EQ(0, memcmp(decrypted->data(), kPlaintext, sizeof(kPlaintext))); + + std::vector<uint8_t> wrong_key(aead.KeyLength(), 1u); + crypto::Aead aead_wrong_key(alg); + aead_wrong_key.Init(wrong_key); + decrypted = aead_wrong_key.Open(ciphertext, nonce, kAdditionalData); + EXPECT_FALSE(decrypted); +} + TEST_P(AeadTest, SealOpenWrongKey) { crypto::Aead::AeadAlgorithm alg = GetParam(); crypto::Aead aead(alg); diff --git a/chromium/crypto/hkdf.cc b/chromium/crypto/hkdf.cc index e2d367cdd29..e32576252f0 100644 --- a/chromium/crypto/hkdf.cc +++ b/chromium/crypto/hkdf.cc @@ -31,4 +31,17 @@ std::string HkdfSha256(base::StringPiece secret, return key; } +std::vector<uint8_t> HkdfSha256(base::span<const uint8_t> secret, + base::span<const uint8_t> salt, + base::span<const uint8_t> info, + size_t derived_key_size) { + std::vector<uint8_t> ret; + ret.resize(derived_key_size); + int result = + ::HKDF(ret.data(), derived_key_size, EVP_sha256(), secret.data(), + secret.size(), salt.data(), salt.size(), info.data(), info.size()); + DCHECK(result); + return ret; +} + } // namespace crypto diff --git a/chromium/crypto/hkdf.h b/chromium/crypto/hkdf.h index f0d7a50e84f..6d927ab6c28 100644 --- a/chromium/crypto/hkdf.h +++ b/chromium/crypto/hkdf.h @@ -9,6 +9,7 @@ #include <string> +#include "base/containers/span.h" #include "base/strings/string_piece.h" #include "crypto/crypto_export.h" @@ -20,6 +21,12 @@ std::string HkdfSha256(base::StringPiece secret, base::StringPiece info, size_t derived_key_size); +CRYPTO_EXPORT +std::vector<uint8_t> HkdfSha256(base::span<const uint8_t> secret, + base::span<const uint8_t> salt, + base::span<const uint8_t> info, + size_t derived_key_size); + } // namespace crypto #endif // CRYPTO_HKDF_H_ diff --git a/chromium/crypto/nss_util.cc b/chromium/crypto/nss_util.cc index 97d6648f3a2..a46d60b2c0b 100644 --- a/chromium/crypto/nss_util.cc +++ b/chromium/crypto/nss_util.cc @@ -319,9 +319,10 @@ class NSSInitSingleton { std::unique_ptr<TPMModuleAndSlot> tpm_args( new TPMModuleAndSlot(chaps_module_)); TPMModuleAndSlot* tpm_args_ptr = tpm_args.get(); - base::PostTaskWithTraitsAndReply( + base::PostTaskAndReply( FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&NSSInitSingleton::InitializeTPMTokenInThreadPool, system_slot_id, tpm_args_ptr), base::BindOnce(&NSSInitSingleton::OnInitializedTPMTokenAndSystemSlot, @@ -482,9 +483,10 @@ class NSSInitSingleton { std::unique_ptr<TPMModuleAndSlot> tpm_args( new TPMModuleAndSlot(chaps_module_)); TPMModuleAndSlot* tpm_args_ptr = tpm_args.get(); - base::PostTaskWithTraitsAndReply( + base::PostTaskAndReply( FROM_HERE, - {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, + {base::ThreadPool(), base::MayBlock(), + base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, base::BindOnce(&NSSInitSingleton::InitializeTPMTokenInThreadPool, slot_id, tpm_args_ptr), base::BindOnce(&NSSInitSingleton::OnInitializedTPMForChromeOSUser, diff --git a/chromium/crypto/sha2.cc b/chromium/crypto/sha2.cc index aa1b6d0d069..cde2a977efc 100644 --- a/chromium/crypto/sha2.cc +++ b/chromium/crypto/sha2.cc @@ -10,9 +10,16 @@ #include "base/stl_util.h" #include "crypto/secure_hash.h" +#include "third_party/boringssl/src/include/openssl/sha.h" namespace crypto { +std::array<uint8_t, kSHA256Length> SHA256Hash(base::span<const uint8_t> input) { + std::array<uint8_t, kSHA256Length> digest; + ::SHA256(input.data(), input.size(), digest.data()); + return digest; +} + void SHA256HashString(base::StringPiece str, void* output, size_t len) { std::unique_ptr<SecureHash> ctx(SecureHash::Create(SecureHash::SHA256)); ctx->Update(str.data(), str.length()); diff --git a/chromium/crypto/sha2.h b/chromium/crypto/sha2.h index f41224ee8d5..1852bdee0dc 100644 --- a/chromium/crypto/sha2.h +++ b/chromium/crypto/sha2.h @@ -7,8 +7,10 @@ #include <stddef.h> +#include <array> #include <string> +#include "base/containers/span.h" #include "base/strings/string_piece.h" #include "crypto/crypto_export.h" @@ -20,6 +22,14 @@ namespace crypto { static const size_t kSHA256Length = 32; // Length in bytes of a SHA-256 hash. +// Computes the SHA-256 hash of |input|. +CRYPTO_EXPORT std::array<uint8_t, kSHA256Length> SHA256Hash( + base::span<const uint8_t> input); + +// Convenience version of the above that returns the result in a 32-byte +// string. +CRYPTO_EXPORT std::string SHA256HashString(base::StringPiece str); + // Computes the SHA-256 hash of the input string 'str' and stores the first // 'len' bytes of the hash in the output buffer 'output'. If 'len' > 32, // only 32 bytes (the full hash) are stored in the 'output' buffer. @@ -27,10 +37,6 @@ CRYPTO_EXPORT void SHA256HashString(base::StringPiece str, void* output, size_t len); -// Convenience version of the above that returns the result in a 32-byte -// string. -CRYPTO_EXPORT std::string SHA256HashString(base::StringPiece str); - } // namespace crypto #endif // CRYPTO_SHA2_H_ |