diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-10-24 11:30:15 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-10-30 12:56:19 +0000 |
commit | 6036726eb981b6c4b42047513b9d3f4ac865daac (patch) | |
tree | 673593e70678e7789766d1f732eb51f613a2703b /chromium/crypto | |
parent | 466052c4e7c052268fd931888cd58961da94c586 (diff) | |
download | qtwebengine-chromium-6036726eb981b6c4b42047513b9d3f4ac865daac.tar.gz |
BASELINE: Update Chromium to 70.0.3538.78
Change-Id: Ie634710bf039e26c1957f4ae45e101bd4c434ae7
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/crypto')
-rw-r--r-- | chromium/crypto/BUILD.gn | 2 | ||||
-rw-r--r-- | chromium/crypto/encryptor_unittest.cc | 10 | ||||
-rw-r--r-- | chromium/crypto/nss_util.cc | 2 | ||||
-rw-r--r-- | chromium/crypto/symmetric_key.cc | 66 | ||||
-rw-r--r-- | chromium/crypto/symmetric_key.h | 25 | ||||
-rw-r--r-- | chromium/crypto/symmetric_key_unittest.cc | 240 |
6 files changed, 208 insertions, 137 deletions
diff --git a/chromium/crypto/BUILD.gn b/chromium/crypto/BUILD.gn index 1097db5148c..f8c9ba87446 100644 --- a/chromium/crypto/BUILD.gn +++ b/chromium/crypto/BUILD.gn @@ -217,6 +217,6 @@ group("platform") { # (use_nss_certs). if (use_nss_certs) { public_configs = [ ":platform_config" ] - public_configs += [ "//third_party/nss:system_nss_no_ssl_config" ] + public_configs += [ "//build/config/linux/nss:system_nss_no_ssl_config" ] } } diff --git a/chromium/crypto/encryptor_unittest.cc b/chromium/crypto/encryptor_unittest.cc index 2294bdb173e..76178dcb119 100644 --- a/chromium/crypto/encryptor_unittest.cc +++ b/chromium/crypto/encryptor_unittest.cc @@ -16,7 +16,7 @@ TEST(EncryptorTest, EncryptDecrypt) { std::unique_ptr<crypto::SymmetricKey> key( - crypto::SymmetricKey::DeriveKeyFromPassword( + crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2( crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256)); EXPECT_TRUE(key.get()); @@ -40,27 +40,27 @@ TEST(EncryptorTest, EncryptDecrypt) { TEST(EncryptorTest, DecryptWrongKey) { std::unique_ptr<crypto::SymmetricKey> key( - crypto::SymmetricKey::DeriveKeyFromPassword( + crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2( crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256)); EXPECT_TRUE(key.get()); // A wrong key that can be detected by implementations that validate every // byte in the padding. std::unique_ptr<crypto::SymmetricKey> wrong_key( - crypto::SymmetricKey::DeriveKeyFromPassword( + crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2( crypto::SymmetricKey::AES, "wrongword", "sweetest", 1000, 256)); EXPECT_TRUE(wrong_key.get()); // A wrong key that can't be detected by any implementation. The password // "wrongword;" would also work. std::unique_ptr<crypto::SymmetricKey> wrong_key2( - crypto::SymmetricKey::DeriveKeyFromPassword( + crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2( crypto::SymmetricKey::AES, "wrongword+", "sweetest", 1000, 256)); EXPECT_TRUE(wrong_key2.get()); // A wrong key that can be detected by all implementations. std::unique_ptr<crypto::SymmetricKey> wrong_key3( - crypto::SymmetricKey::DeriveKeyFromPassword( + crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2( crypto::SymmetricKey::AES, "wrongwordx", "sweetest", 1000, 256)); EXPECT_TRUE(wrong_key3.get()); diff --git a/chromium/crypto/nss_util.cc b/chromium/crypto/nss_util.cc index 30ca5a61a16..afeb5ca2376 100644 --- a/chromium/crypto/nss_util.cc +++ b/chromium/crypto/nss_util.cc @@ -29,7 +29,7 @@ #include "base/memory/ptr_util.h" #include "base/path_service.h" #include "base/strings/stringprintf.h" -#include "base/task_scheduler/post_task.h" +#include "base/task/post_task.h" #include "base/threading/scoped_blocking_call.h" #include "base/threading/thread_checker.h" #include "base/threading/thread_restrictions.h" diff --git a/chromium/crypto/symmetric_key.cc b/chromium/crypto/symmetric_key.cc index 55ffb72fb85..b239d22cb45 100644 --- a/chromium/crypto/symmetric_key.cc +++ b/chromium/crypto/symmetric_key.cc @@ -18,6 +18,26 @@ namespace crypto { +namespace { + +bool CheckDerivationParameters(SymmetricKey::Algorithm algorithm, + size_t key_size_in_bits) { + switch (algorithm) { + case SymmetricKey::AES: + // Whitelist supported key sizes to avoid accidentally relying on + // algorithms available in NSS but not BoringSSL and vice + // versa. Note that BoringSSL does not support AES-192. + return key_size_in_bits == 128 || key_size_in_bits == 256; + case SymmetricKey::HMAC_SHA1: + return key_size_in_bits % 8 == 0 && key_size_in_bits != 0; + } + + NOTREACHED(); + return false; +} + +} // namespace + SymmetricKey::~SymmetricKey() { std::fill(key_.begin(), key_.end(), '\0'); // Zero out the confidential key. } @@ -50,32 +70,22 @@ std::unique_ptr<SymmetricKey> SymmetricKey::GenerateRandomKey( } // static -std::unique_ptr<SymmetricKey> SymmetricKey::DeriveKeyFromPassword( +std::unique_ptr<SymmetricKey> SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2( Algorithm algorithm, const std::string& password, const std::string& salt, size_t iterations, size_t key_size_in_bits) { - DCHECK(algorithm == AES || algorithm == HMAC_SHA1); - - if (algorithm == AES) { - // Whitelist supported key sizes to avoid accidentaly relying on - // algorithms available in NSS but not BoringSSL and vice - // versa. Note that BoringSSL does not support AES-192. - if (key_size_in_bits != 128 && key_size_in_bits != 256) - return nullptr; - } + if (!CheckDerivationParameters(algorithm, key_size_in_bits)) + return nullptr; size_t key_size_in_bytes = key_size_in_bits / 8; - DCHECK_EQ(key_size_in_bits, key_size_in_bytes * 8); - - if (key_size_in_bytes == 0) - return nullptr; OpenSSLErrStackTracer err_tracer(FROM_HERE); std::unique_ptr<SymmetricKey> key(new SymmetricKey); uint8_t* key_data = reinterpret_cast<uint8_t*>( base::WriteInto(&key->key_, key_size_in_bytes + 1)); + int rv = PKCS5_PBKDF2_HMAC_SHA1( password.data(), password.length(), reinterpret_cast<const uint8_t*>(salt.data()), salt.length(), @@ -85,6 +95,34 @@ std::unique_ptr<SymmetricKey> SymmetricKey::DeriveKeyFromPassword( } // static +std::unique_ptr<SymmetricKey> SymmetricKey::DeriveKeyFromPasswordUsingScrypt( + Algorithm algorithm, + const std::string& password, + const std::string& salt, + size_t cost_parameter, + size_t block_size, + size_t parallelization_parameter, + size_t max_memory_bytes, + size_t key_size_in_bits) { + if (!CheckDerivationParameters(algorithm, key_size_in_bits)) + return nullptr; + + size_t key_size_in_bytes = key_size_in_bits / 8; + + OpenSSLErrStackTracer err_tracer(FROM_HERE); + std::unique_ptr<SymmetricKey> key(new SymmetricKey); + uint8_t* key_data = reinterpret_cast<uint8_t*>( + base::WriteInto(&key->key_, key_size_in_bytes + 1)); + + int rv = EVP_PBE_scrypt(password.data(), password.length(), + reinterpret_cast<const uint8_t*>(salt.data()), + salt.length(), cost_parameter, block_size, + parallelization_parameter, max_memory_bytes, key_data, + key_size_in_bytes); + return rv == 1 ? std::move(key) : nullptr; +} + +// static std::unique_ptr<SymmetricKey> SymmetricKey::Import(Algorithm algorithm, const std::string& raw_key) { if (algorithm == AES) { diff --git a/chromium/crypto/symmetric_key.h b/chromium/crypto/symmetric_key.h index 9803cdcf249..d802241a0a0 100644 --- a/chromium/crypto/symmetric_key.h +++ b/chromium/crypto/symmetric_key.h @@ -41,17 +41,34 @@ class CRYPTO_EXPORT SymmetricKey { // used to derive the key from the password. |key_size_in_bits| must be a // multiple of 8. The caller is responsible for deleting the returned // SymmetricKey. - static std::unique_ptr<SymmetricKey> DeriveKeyFromPassword( + static std::unique_ptr<SymmetricKey> DeriveKeyFromPasswordUsingPbkdf2( Algorithm algorithm, const std::string& password, const std::string& salt, size_t iterations, size_t key_size_in_bits); + // Derives a key from the supplied password and salt using scrypt, suitable + // for use with specified |algorithm|. Note |algorithm| is not the algorithm + // used to derive the key from the password. |cost_parameter|, |block_size|, + // and |parallelization_parameter| correspond to the parameters |N|, |r|, and + // |p| from the scrypt specification (see RFC 7914). |key_size_in_bits| must + // be a multiple of 8. The caller is responsible for deleting the returned + // SymmetricKey. + static std::unique_ptr<SymmetricKey> DeriveKeyFromPasswordUsingScrypt( + Algorithm algorithm, + const std::string& password, + const std::string& salt, + size_t cost_parameter, + size_t block_size, + size_t parallelization_parameter, + size_t max_memory_bytes, + size_t key_size_in_bits); + // Imports an array of key bytes in |raw_key|. This key may have been - // generated by GenerateRandomKey or DeriveKeyFromPassword and exported with - // key(). The key must be of suitable size for use with |algorithm|. - // The caller owns the returned SymmetricKey. + // generated by GenerateRandomKey or DeriveKeyFromPassword{Pbkdf2,Scrypt} and + // exported with key(). The key must be of suitable size for use with + // |algorithm|. The caller owns the returned SymmetricKey. static std::unique_ptr<SymmetricKey> Import(Algorithm algorithm, const std::string& raw_key); diff --git a/chromium/crypto/symmetric_key_unittest.cc b/chromium/crypto/symmetric_key_unittest.cc index 02f12e5defa..6bef6ca7383 100644 --- a/chromium/crypto/symmetric_key_unittest.cc +++ b/chromium/crypto/symmetric_key_unittest.cc @@ -40,7 +40,7 @@ TEST(SymmetricKeyTest, ImportGeneratedKey) { TEST(SymmetricKeyTest, ImportDerivedKey) { std::unique_ptr<crypto::SymmetricKey> key1( - crypto::SymmetricKey::DeriveKeyFromPassword( + crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2( crypto::SymmetricKey::HMAC_SHA1, "password", "somesalt", 1024, 160)); ASSERT_TRUE(key1); @@ -57,17 +57,31 @@ struct PBKDF2TestVector { const char* salt; unsigned int rounds; unsigned int key_size_in_bits; - const char* expected; // ASCII encoded hex bytes + const char* expected; // ASCII encoded hex bytes. }; -class SymmetricKeyDeriveKeyFromPasswordTest - : public testing::TestWithParam<PBKDF2TestVector> { +struct ScryptTestVector { + crypto::SymmetricKey::Algorithm algorithm; + const char* password; + const char* salt; + unsigned int cost_parameter; + unsigned int block_size; + unsigned int parallelization_parameter; + unsigned int key_size_in_bits; + const char* expected; // ASCII encoded hex bytes. }; -TEST_P(SymmetricKeyDeriveKeyFromPasswordTest, DeriveKeyFromPassword) { +class SymmetricKeyDeriveKeyFromPasswordUsingPbkdf2Test + : public testing::TestWithParam<PBKDF2TestVector> {}; + +class SymmetricKeyDeriveKeyFromPasswordUsingScryptTest + : public testing::TestWithParam<ScryptTestVector> {}; + +TEST_P(SymmetricKeyDeriveKeyFromPasswordUsingPbkdf2Test, + DeriveKeyFromPasswordUsingPbkdf2) { PBKDF2TestVector test_data(GetParam()); std::unique_ptr<crypto::SymmetricKey> key( - crypto::SymmetricKey::DeriveKeyFromPassword( + crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2( test_data.algorithm, test_data.password, test_data.salt, test_data.rounds, test_data.key_size_in_bits)); ASSERT_TRUE(key); @@ -79,34 +93,41 @@ TEST_P(SymmetricKeyDeriveKeyFromPasswordTest, DeriveKeyFromPassword) { raw_key.size()))); } -static const PBKDF2TestVector kTestVectors[] = { - // These tests come from - // http://www.ietf.org/id/draft-josefsson-pbkdf2-test-vectors-00.txt - { - crypto::SymmetricKey::HMAC_SHA1, - "password", - "salt", - 1, - 160, - "0c60c80f961f0e71f3a9b524af6012062fe037a6", - }, - { - crypto::SymmetricKey::HMAC_SHA1, - "password", - "salt", - 2, - 160, - "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", - }, - { - crypto::SymmetricKey::HMAC_SHA1, - "password", - "salt", - 4096, - 160, - "4b007901b765489abead49d926f721d065a429c1", - }, - // This test takes over 30s to run on the trybots. +TEST_P(SymmetricKeyDeriveKeyFromPasswordUsingScryptTest, + DeriveKeyFromPasswordUsingScrypt) { + const int kScryptMaxMemoryBytes = 128 * 1024 * 1024; // 128 MiB. + + ScryptTestVector test_data(GetParam()); + std::unique_ptr<crypto::SymmetricKey> key( + crypto::SymmetricKey::DeriveKeyFromPasswordUsingScrypt( + test_data.algorithm, test_data.password, test_data.salt, + test_data.cost_parameter, test_data.block_size, + test_data.parallelization_parameter, kScryptMaxMemoryBytes, + test_data.key_size_in_bits)); + ASSERT_TRUE(key); + + const std::string& raw_key = key->key(); + EXPECT_EQ(test_data.key_size_in_bits / 8, raw_key.size()); + EXPECT_EQ(test_data.expected, base::ToLowerASCII(base::HexEncode( + raw_key.data(), raw_key.size()))); +} + +static const PBKDF2TestVector kTestVectorsPbkdf2[] = { + // These tests come from + // http://www.ietf.org/id/draft-josefsson-pbkdf2-test-vectors-00.txt. + { + crypto::SymmetricKey::HMAC_SHA1, "password", "salt", 1, 160, + "0c60c80f961f0e71f3a9b524af6012062fe037a6", + }, + { + crypto::SymmetricKey::HMAC_SHA1, "password", "salt", 2, 160, + "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", + }, + { + crypto::SymmetricKey::HMAC_SHA1, "password", "salt", 4096, 160, + "4b007901b765489abead49d926f721d065a429c1", + }, +// This test takes over 30s to run on the trybots. #if 0 { crypto::SymmetricKey::HMAC_SHA1, @@ -118,83 +139,78 @@ static const PBKDF2TestVector kTestVectors[] = { }, #endif - // These tests come from RFC 3962, via BSD source code at - // http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/bioctl/pbkdf2.c?rev=HEAD&content-type=text/plain - { - crypto::SymmetricKey::HMAC_SHA1, - "password", - "ATHENA.MIT.EDUraeburn", - 1, - 160, - "cdedb5281bb2f801565a1122b25635150ad1f7a0", - }, - { - crypto::SymmetricKey::HMAC_SHA1, - "password", - "ATHENA.MIT.EDUraeburn", - 2, - 160, - "01dbee7f4a9e243e988b62c73cda935da05378b9", - }, - { - crypto::SymmetricKey::HMAC_SHA1, - "password", - "ATHENA.MIT.EDUraeburn", - 1200, - 160, - "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddb", - }, - { - crypto::SymmetricKey::HMAC_SHA1, - "password", - "\022" "4VxxV4\022", /* 0x1234567878563412 */ - 5, - 160, - "d1daa78615f287e6a1c8b120d7062a493f98d203", - }, - { - crypto::SymmetricKey::HMAC_SHA1, - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - "pass phrase equals block size", - 1200, - 160, - "139c30c0966bc32ba55fdbf212530ac9c5ec59f1", - }, - { - crypto::SymmetricKey::HMAC_SHA1, - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - "pass phrase exceeds block size", - 1200, - 160, - "9ccad6d468770cd51b10e6a68721be611a8b4d28", - }, - { - crypto::SymmetricKey::HMAC_SHA1, - "\360\235\204\236", /* g-clef (0xf09d849e) */ - "EXAMPLE.COMpianist", - 50, - 160, - "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0", - }, - - // Regression tests for AES keys, derived from the Linux NSS implementation. - { - crypto::SymmetricKey::AES, - "A test password", - "saltsalt", - 1, - 256, - "44899a7777f0e6e8b752f875f02044b8ac593de146de896f2e8a816e315a36de", - }, - { - crypto::SymmetricKey::AES, - "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", - "pass phrase exceeds block size", - 20, - 256, - "e0739745dc28b8721ba402e05214d2ac1eab54cf72bee1fba388297a09eb493c", - }, + // These tests come from RFC 3962, via BSD source code at + // http://www.openbsd.org/cgi-bin/cvsweb/src/sbin/bioctl/pbkdf2.c?rev=HEAD&content-type=text/plain. + { + crypto::SymmetricKey::HMAC_SHA1, "password", "ATHENA.MIT.EDUraeburn", 1, + 160, "cdedb5281bb2f801565a1122b25635150ad1f7a0", + }, + { + crypto::SymmetricKey::HMAC_SHA1, "password", "ATHENA.MIT.EDUraeburn", 2, + 160, "01dbee7f4a9e243e988b62c73cda935da05378b9", + }, + { + crypto::SymmetricKey::HMAC_SHA1, "password", "ATHENA.MIT.EDUraeburn", + 1200, 160, "5c08eb61fdf71e4e4ec3cf6ba1f5512ba7e52ddb", + }, + { + crypto::SymmetricKey::HMAC_SHA1, "password", + "\022" + "4VxxV4\022", /* 0x1234567878563412 */ + 5, 160, "d1daa78615f287e6a1c8b120d7062a493f98d203", + }, + { + crypto::SymmetricKey::HMAC_SHA1, + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "pass phrase equals block size", 1200, 160, + "139c30c0966bc32ba55fdbf212530ac9c5ec59f1", + }, + { + crypto::SymmetricKey::HMAC_SHA1, + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "pass phrase exceeds block size", 1200, 160, + "9ccad6d468770cd51b10e6a68721be611a8b4d28", + }, + { + crypto::SymmetricKey::HMAC_SHA1, + "\360\235\204\236", /* g-clef (0xf09d849e) */ + "EXAMPLE.COMpianist", 50, 160, + "6b9cf26d45455a43a5b8bb276a403b39e7fe37a0", + }, + + // Regression tests for AES keys, derived from the Linux NSS implementation. + { + crypto::SymmetricKey::AES, "A test password", "saltsalt", 1, 256, + "44899a7777f0e6e8b752f875f02044b8ac593de146de896f2e8a816e315a36de", + }, + { + crypto::SymmetricKey::AES, + "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "pass phrase exceeds block size", 20, 256, + "e0739745dc28b8721ba402e05214d2ac1eab54cf72bee1fba388297a09eb493c", + }, }; -INSTANTIATE_TEST_CASE_P(, SymmetricKeyDeriveKeyFromPasswordTest, - testing::ValuesIn(kTestVectors)); +static const ScryptTestVector kTestVectorsScrypt[] = { + // From RFC 7914, "The scrypt Password-Based Key Derivation Function", + // https://tools.ietf.org/html/rfc7914.html. The fourth test vector is + // intentionally not used, as it would make the test significantly slower, + // due to the very high cost parameter. + {crypto::SymmetricKey::HMAC_SHA1, "", "", 16, 1, 1, 512, + "77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069de" + "d0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906"}, + {crypto::SymmetricKey::HMAC_SHA1, "password", "NaCl", 1024, 8, 16, 512, + "fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92" + "e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640"}, + {crypto::SymmetricKey::HMAC_SHA1, "pleaseletmein", "SodiumChloride", 16384, + 8, 1, 512, + "7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d54329556" + "13f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887"}}; + +INSTANTIATE_TEST_CASE_P(, + SymmetricKeyDeriveKeyFromPasswordUsingPbkdf2Test, + testing::ValuesIn(kTestVectorsPbkdf2)); + +INSTANTIATE_TEST_CASE_P(, + SymmetricKeyDeriveKeyFromPasswordUsingScryptTest, + testing::ValuesIn(kTestVectorsScrypt)); |