[crypto] Add scrypt key derivation to SymmetricKey
Add a method for key derivation using the scrypt algorithm to
crypto::SymmetricKey.
Rename the pre-existing method for key derivation (which uses PBKDF2) to
clearly disambiguate between the two.
TBRing because all the changes to files not under crypto/ are a trivial
library method name change.
[email protected],[email protected],[email protected],[email protected],[email protected]
Bug: 875931
Change-Id: Iaa0b2bb0fc3ae2481733072363718cffd8811b97
Reviewed-on: https://chromium-review.googlesource.com/1181881
Commit-Queue: David Davidović <[email protected]>
Reviewed-by: David Benjamin <[email protected]>
Reviewed-by: vitaliii <[email protected]>
Cr-Commit-Position: refs/heads/master@{#586247}
diff --git a/chrome/browser/chromeos/settings/token_encryptor.cc b/chrome/browser/chromeos/settings/token_encryptor.cc
index 1965ae82..b52c89b 100644
--- a/chrome/browser/chromeos/settings/token_encryptor.cc
+++ b/chrome/browser/chromeos/settings/token_encryptor.cc
@@ -70,7 +70,7 @@
std::unique_ptr<crypto::SymmetricKey> CryptohomeTokenEncryptor::PassphraseToKey(
const std::string& passphrase,
const std::string& salt) {
- return crypto::SymmetricKey::DeriveKeyFromPassword(
+ return crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
crypto::SymmetricKey::AES, passphrase, salt, 1000, 256);
}
diff --git a/chrome/browser/signin/local_auth.cc b/chrome/browser/signin/local_auth.cc
index 5ce69c4..09af654 100644
--- a/chrome/browser/signin/local_auth.cc
+++ b/chrome/browser/signin/local_auth.cc
@@ -105,7 +105,7 @@
// Library call to create secure password hash as SymmetricKey (uses PBKDF2).
std::unique_ptr<crypto::SymmetricKey> password_key(
- crypto::SymmetricKey::DeriveKeyFromPassword(
+ crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
crypto::SymmetricKey::AES, password, salt, encoding.iteration_count,
encoding.hash_bits));
std::string password_hash = password_key->key();
diff --git a/chromeos/login/auth/authpolicy_login_helper.cc b/chromeos/login/auth/authpolicy_login_helper.cc
index cc56973..a396b86 100644
--- a/chromeos/login/auth/authpolicy_login_helper.cc
+++ b/chromeos/login/auth/authpolicy_login_helper.cc
@@ -88,7 +88,7 @@
const size_t kHmacKeySize = 32;
const size_t kKeySize = kAesKeySize + kAesIvSize + kHmacKeySize;
std::unique_ptr<crypto::SymmetricKey> key =
- crypto::SymmetricKey::DeriveKeyFromPassword(
+ crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
crypto::SymmetricKey::HMAC_SHA1, password, salt, 10000, kKeySize * 8);
if (!key) {
LOG(ERROR) << error_msg;
diff --git a/chromeos/login/auth/key.cc b/chromeos/login/auth/key.cc
index b1b9061..cd26dba1 100644
--- a/chromeos/login/auth/key.cc
+++ b/chromeos/login/auth/key.cc
@@ -85,7 +85,7 @@
}
case KEY_TYPE_SALTED_PBKDF2_AES256_1234: {
std::unique_ptr<crypto::SymmetricKey> key(
- crypto::SymmetricKey::DeriveKeyFromPassword(
+ crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
crypto::SymmetricKey::AES, secret_, salt, kNumIterations,
kKeySizeInBits));
base::Base64Encode(key->key(), &secret_);
diff --git a/chromeos/network/onc/onc_utils.cc b/chromeos/network/onc/onc_utils.cc
index df75587..1109e30 100644
--- a/chromeos/network/onc/onc_utils.cc
+++ b/chromeos/network/onc/onc_utils.cc
@@ -721,9 +721,9 @@
}
std::unique_ptr<crypto::SymmetricKey> key(
- crypto::SymmetricKey::DeriveKeyFromPassword(crypto::SymmetricKey::AES,
- passphrase, salt, iterations,
- kKeySizeInBits));
+ crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
+ crypto::SymmetricKey::AES, passphrase, salt, iterations,
+ kKeySizeInBits));
if (!base::Base64Decode(initial_vector, &initial_vector)) {
NET_LOG(ERROR) << kUnableToDecode;
diff --git a/components/os_crypt/os_crypt_linux.cc b/components/os_crypt/os_crypt_linux.cc
index 6510c68..6b9c384 100644
--- a/components/os_crypt/os_crypt_linux.cc
+++ b/components/os_crypt/os_crypt_linux.cc
@@ -121,7 +121,7 @@
// Create an encryption key from our password and salt.
std::unique_ptr<crypto::SymmetricKey> encryption_key(
- crypto::SymmetricKey::DeriveKeyFromPassword(
+ crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
crypto::SymmetricKey::AES, *password, salt, kEncryptionIterations,
kDerivedKeySizeInBits));
DCHECK(encryption_key);
diff --git a/components/os_crypt/os_crypt_mac.mm b/components/os_crypt/os_crypt_mac.mm
index 7913d5a3..c0b046c 100644
--- a/components/os_crypt/os_crypt_mac.mm
+++ b/components/os_crypt/os_crypt_mac.mm
@@ -87,10 +87,11 @@
// Create an encryption key from our password and salt. The key is
// intentionally leaked.
- cached_encryption_key = crypto::SymmetricKey::DeriveKeyFromPassword(
- crypto::SymmetricKey::AES, password, salt,
- kEncryptionIterations, kDerivedKeySizeInBits)
- .release();
+ cached_encryption_key =
+ crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
+ crypto::SymmetricKey::AES, password, salt, kEncryptionIterations,
+ kDerivedKeySizeInBits)
+ .release();
ANNOTATE_LEAKING_OBJECT_PTR(cached_encryption_key);
DCHECK(cached_encryption_key);
return cached_encryption_key;
diff --git a/components/os_crypt/os_crypt_posix.cc b/components/os_crypt/os_crypt_posix.cc
index 24a411e..9f190f7c 100644
--- a/components/os_crypt/os_crypt_posix.cc
+++ b/components/os_crypt/os_crypt_posix.cc
@@ -46,11 +46,9 @@
// Create an encryption key from our password and salt.
std::unique_ptr<crypto::SymmetricKey> encryption_key(
- crypto::SymmetricKey::DeriveKeyFromPassword(crypto::SymmetricKey::AES,
- password,
- salt,
- kEncryptionIterations,
- kDerivedKeySizeInBits));
+ crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
+ crypto::SymmetricKey::AES, password, salt, kEncryptionIterations,
+ kDerivedKeySizeInBits));
DCHECK(encryption_key.get());
return encryption_key.release();
diff --git a/components/sync/base/nigori.cc b/components/sync/base/nigori.cc
index edbad0b..7566cd2e 100644
--- a/components/sync/base/nigori.cc
+++ b/components/sync/base/nigori.cc
@@ -69,25 +69,26 @@
salt_password << username << hostname;
// Suser = PBKDF2(Username || Servername, "saltsalt", Nsalt, 8)
- std::unique_ptr<SymmetricKey> user_salt(SymmetricKey::DeriveKeyFromPassword(
- SymmetricKey::HMAC_SHA1, salt_password.str(), kSaltSalt, kSaltIterations,
- kSaltKeySizeInBits));
+ std::unique_ptr<SymmetricKey> user_salt(
+ SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
+ SymmetricKey::HMAC_SHA1, salt_password.str(), kSaltSalt,
+ kSaltIterations, kSaltKeySizeInBits));
DCHECK(user_salt);
// Kuser = PBKDF2(P, Suser, Nuser, 16)
- user_key_ = SymmetricKey::DeriveKeyFromPassword(
+ user_key_ = SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
SymmetricKey::AES, password, user_salt->key(), kUserIterations,
kDerivedKeySizeInBits);
DCHECK(user_key_);
// Kenc = PBKDF2(P, Suser, Nenc, 16)
- encryption_key_ = SymmetricKey::DeriveKeyFromPassword(
+ encryption_key_ = SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
SymmetricKey::AES, password, user_salt->key(), kEncryptionIterations,
kDerivedKeySizeInBits);
DCHECK(encryption_key_);
// Kmac = PBKDF2(P, Suser, Nmac, 16)
- mac_key_ = SymmetricKey::DeriveKeyFromPassword(
+ mac_key_ = SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
SymmetricKey::HMAC_SHA1, password, user_salt->key(), kSigningIterations,
kDerivedKeySizeInBits);
DCHECK(mac_key_);
diff --git a/crypto/encryptor_unittest.cc b/crypto/encryptor_unittest.cc
index 2294bdb..76178dcb 100644
--- a/crypto/encryptor_unittest.cc
+++ b/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, 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/crypto/symmetric_key.cc b/crypto/symmetric_key.cc
index 55ffb72f..b239d22c 100644
--- a/crypto/symmetric_key.cc
+++ b/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 @@
}
// 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 @@
}
// 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/crypto/symmetric_key.h b/crypto/symmetric_key.h
index 9803cdc..d802241 100644
--- a/crypto/symmetric_key.h
+++ b/crypto/symmetric_key.h
@@ -41,17 +41,34 @@
// 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/crypto/symmetric_key_unittest.cc b/crypto/symmetric_key_unittest.cc
index 02f12e5..6bef6ca 100644
--- a/crypto/symmetric_key_unittest.cc
+++ b/crypto/symmetric_key_unittest.cc
@@ -40,7 +40,7 @@
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 @@
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 @@
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 @@
},
#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",
- },
+ // 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",
- },
+ // 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));
diff --git a/extensions/browser/api/lock_screen_data/data_item_unittest.cc b/extensions/browser/api/lock_screen_data/data_item_unittest.cc
index a12783f..47cb9d5 100644
--- a/extensions/browser/api/lock_screen_data/data_item_unittest.cc
+++ b/extensions/browser/api/lock_screen_data/data_item_unittest.cc
@@ -114,7 +114,7 @@
std::string GenerateKey(const std::string& password) {
std::unique_ptr<crypto::SymmetricKey> key =
- crypto::SymmetricKey::DeriveKeyFromPassword(
+ crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
crypto::SymmetricKey::AES, password, "salt", 1000, 256);
if (!key) {
ADD_FAILURE() << "Failed to create symmetric key";
diff --git a/extensions/browser/api/lock_screen_data/lock_screen_value_store_migrator_impl_unittest.cc b/extensions/browser/api/lock_screen_data/lock_screen_value_store_migrator_impl_unittest.cc
index 8594ade..a42299b 100644
--- a/extensions/browser/api/lock_screen_data/lock_screen_value_store_migrator_impl_unittest.cc
+++ b/extensions/browser/api/lock_screen_data/lock_screen_value_store_migrator_impl_unittest.cc
@@ -138,7 +138,7 @@
std::string GenerateKey(const std::string& password) {
std::unique_ptr<crypto::SymmetricKey> key =
- crypto::SymmetricKey::DeriveKeyFromPassword(
+ crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
crypto::SymmetricKey::AES, password, "salt", 1000, 256);
if (!key) {
ADD_FAILURE() << "Failed to create symmetric key";
diff --git a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
index aed773f1..0efacd1 100644
--- a/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
+++ b/net/extras/sqlite/sqlite_persistent_cookie_store_unittest.cc
@@ -65,12 +65,12 @@
CookieCryptor::CookieCryptor()
: should_encrypt_(true),
- key_(
- crypto::SymmetricKey::DeriveKeyFromPassword(crypto::SymmetricKey::AES,
- "password",
- "saltiest",
- 1000,
- 256)) {
+ key_(crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
+ crypto::SymmetricKey::AES,
+ "password",
+ "saltiest",
+ 1000,
+ 256)) {
std::string iv("the iv: 16 bytes");
encryptor_.Init(key_.get(), crypto::Encryptor::CBC, iv);
}