1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "crypto/kdf.h"
6
7 #include <array>
8 #include <string>
9
10 #include "base/containers/span.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 using KDFTest = ::testing::Test;
15
TEST(KDFTest,Pbkdf2HmacSha1KnownAnswers)16 TEST(KDFTest, Pbkdf2HmacSha1KnownAnswers) {
17 struct TestCase {
18 std::string password;
19 std::string salt;
20 crypto::kdf::Pbkdf2HmacSha1Params params;
21 size_t len;
22 const char* result;
23 };
24
25 // RFC 6070 test vectors:
26 constexpr auto cases = std::to_array<TestCase>({
27 {"password", "salt", {1}, 20, "0c60c80f961f0e71f3a9b524af6012062fe037a6"},
28 {"password", "salt", {2}, 20, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"},
29 });
30
31 for (const auto& c : cases) {
32 std::vector<uint8_t> key(c.len);
33 crypto::kdf::DeriveKeyPbkdf2HmacSha1(
34 c.params, base::as_byte_span(c.password), base::as_byte_span(c.salt),
35 key, crypto::SubtlePassKey::ForTesting());
36
37 std::vector<uint8_t> result_bytes(c.len);
38 ASSERT_TRUE(base::HexStringToSpan(c.result, result_bytes));
39 EXPECT_EQ(key, result_bytes);
40 }
41 }
42
TEST(KDFTest,ScryptKnownAnswers)43 TEST(KDFTest, ScryptKnownAnswers) {
44 struct TestCase {
45 std::string password;
46 std::string salt;
47 crypto::kdf::ScryptParams params;
48 size_t len;
49 const char* result;
50 };
51
52 // RFC 7914 test vectors - note that RFC 7914 does not specify
53 // max_memory_bytes so we just pass 0 here and let BoringSSL figure it out for
54 // us.
55 constexpr auto cases = std::to_array<TestCase>({
56 {"password",
57 "NaCl",
58 {.cost = 1024, .block_size = 8, .parallelization = 16},
59 64,
60 "fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b373162"
61 "2eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640"},
62 });
63
64 for (const auto& c : cases) {
65 std::vector<uint8_t> key(c.len);
66 crypto::kdf::DeriveKeyScrypt(c.params, base::as_byte_span(c.password),
67 base::as_byte_span(c.salt), key,
68 crypto::SubtlePassKey::ForTesting());
69
70 std::vector<uint8_t> result_bytes(c.len);
71 ASSERT_TRUE(base::HexStringToSpan(c.result, result_bytes));
72 EXPECT_EQ(key, result_bytes);
73 }
74 }
75
TEST(KDFTest,InvalidScryptParameters)76 TEST(KDFTest, InvalidScryptParameters) {
77 constexpr auto cases = std::to_array<crypto::kdf::ScryptParams>({
78 // cost parameter is not a power of 2
79 {.cost = 1023, .block_size = 8, .parallelization = 16},
80 // TODO: others, after we document the exact constraints
81 });
82
83 for (const auto& c : cases) {
84 std::vector<uint8_t> key(64);
85 EXPECT_DEATH_IF_SUPPORTED(
86 crypto::kdf::DeriveKeyScrypt(c, base::as_byte_span("password"),
87 base::as_byte_span("NaCl"), key,
88 crypto::SubtlePassKey::ForTesting()),
89 "");
90 }
91 }
92