blob: 1ce3c7d9456283037245d33f805cfa50a624d49a [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "crypto/kdf.h"
#include <array>
#include <string>
#include "base/containers/span.h"
#include "base/strings/string_number_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
using KDFTest = ::testing::Test;
TEST(KDFTest, Pbkdf2HmacSha1KnownAnswers) {
struct TestCase {
std::string password;
std::string salt;
crypto::kdf::Pbkdf2HmacSha1Params params;
size_t len;
const char* result;
};
// RFC 6070 test vectors:
constexpr auto cases = std::to_array<TestCase>({
{"password", "salt", {1}, 20, "0c60c80f961f0e71f3a9b524af6012062fe037a6"},
{"password", "salt", {2}, 20, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"},
});
for (const auto& c : cases) {
std::vector<uint8_t> key(c.len);
crypto::kdf::DeriveKeyPbkdf2HmacSha1(
c.params, base::as_byte_span(c.password), base::as_byte_span(c.salt),
key, crypto::SubtlePassKey::ForTesting());
std::vector<uint8_t> result_bytes(c.len);
ASSERT_TRUE(base::HexStringToSpan(c.result, result_bytes));
EXPECT_EQ(key, result_bytes);
}
}
TEST(KDFTest, ScryptKnownAnswers) {
struct TestCase {
std::string password;
std::string salt;
crypto::kdf::ScryptParams params;
size_t len;
const char* result;
};
// RFC 7914 test vectors - note that RFC 7914 does not specify
// max_memory_bytes so we just pass 0 here and let BoringSSL figure it out for
// us.
constexpr auto cases = std::to_array<TestCase>({
{"password",
"NaCl",
{.cost = 1024, .block_size = 8, .parallelization = 16},
64,
"fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b373162"
"2eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640"},
});
for (const auto& c : cases) {
std::vector<uint8_t> key(c.len);
crypto::kdf::DeriveKeyScrypt(c.params, base::as_byte_span(c.password),
base::as_byte_span(c.salt), key,
crypto::SubtlePassKey::ForTesting());
std::vector<uint8_t> result_bytes(c.len);
ASSERT_TRUE(base::HexStringToSpan(c.result, result_bytes));
EXPECT_EQ(key, result_bytes);
}
}
TEST(KDFTest, InvalidScryptParameters) {
constexpr auto cases = std::to_array<crypto::kdf::ScryptParams>({
// cost parameter is not a power of 2
{.cost = 1023, .block_size = 8, .parallelization = 16},
// TODO: others, after we document the exact constraints
});
for (const auto& c : cases) {
std::vector<uint8_t> key(64);
EXPECT_DEATH_IF_SUPPORTED(
crypto::kdf::DeriveKeyScrypt(c, base::as_byte_span("password"),
base::as_byte_span("NaCl"), key,
crypto::SubtlePassKey::ForTesting()),
"");
}
}