LibCrypto+LibWeb: Refactor HKDF and PBKDF2 classes with OpenSSL

This commit is contained in:
devgianlu 2025-02-16 17:38:58 +01:00 committed by Ali Mohammad Pur
commit e90d2a5713
Notes: github-actions[bot] 2025-02-24 10:12:08 +00:00
11 changed files with 210 additions and 185 deletions

View file

@ -6,15 +6,13 @@
*/
#include <LibCrypto/Hash/HKDF.h>
#include <LibCrypto/Hash/SHA1.h>
#include <LibCrypto/Hash/SHA2.h>
#include <LibTest/TestCase.h>
TEST_CASE(test_error_extreme_output_key_length)
{
auto result = Crypto::Hash::HKDF<Crypto::Hash::SHA1>::derive_key(Optional<ReadonlyBytes>(), ReadonlyBytes(), ReadonlyBytes(), 999999);
Crypto::Hash::HKDF hkdf(Crypto::Hash::HashKind::SHA1);
auto result = hkdf.derive_key(Optional<ReadonlyBytes>(), ReadonlyBytes(), ReadonlyBytes(), 999999);
EXPECT(result.is_error());
EXPECT_EQ(result.error().string_literal(), "requested output_key_length is too large");
}
// https://www.rfc-editor.org/rfc/rfc5869#appendix-A.1
@ -35,7 +33,8 @@ TEST_CASE(test_vector_A_1)
// L = 42
size_t const output_key_length = 42;
auto result = TRY_OR_FAIL(Crypto::Hash::HKDF<Crypto::Hash::SHA256>::derive_key(Optional<ReadonlyBytes>(salt), ikm, info, output_key_length));
Crypto::Hash::HKDF hkdf(Crypto::Hash::HashKind::SHA256);
auto result = TRY_OR_FAIL(hkdf.derive_key(Optional<ReadonlyBytes>(salt), ikm, info, output_key_length));
// Intermediate value 'PRK' isn't checked explicitly. However, any bit error would have
// an avalanche effect on the output, so if the output is correct then PRK can be presumed correct, too.
u8 const expected_output_key[] = {
@ -76,7 +75,8 @@ TEST_CASE(test_vector_A_2)
static_assert(sizeof(info) == 80);
size_t const output_key_length = 82;
auto result = TRY_OR_FAIL(Crypto::Hash::HKDF<Crypto::Hash::SHA256>::derive_key(Optional<ReadonlyBytes>(salt), ikm, info, output_key_length));
Crypto::Hash::HKDF hkdf(Crypto::Hash::HashKind::SHA256);
auto result = TRY_OR_FAIL(hkdf.derive_key(Optional<ReadonlyBytes>(salt), ikm, info, output_key_length));
// Intermediate value 'PRK' isn't checked explicitly. However, any bit error would have
// an avalanche effect on the output, so if the output is correct then PRK can be presumed correct, too.
u8 const expected_output_key[] = {
@ -101,8 +101,10 @@ TEST_CASE(test_vector_A_3)
static_assert(sizeof(ikm) == 22);
size_t const output_key_length = 42;
Crypto::Hash::HKDF hkdf(Crypto::Hash::HashKind::SHA256);
// Note: This creates a salt of zero bytes.
auto result = TRY_OR_FAIL(Crypto::Hash::HKDF<Crypto::Hash::SHA256>::derive_key(Optional<ReadonlyBytes>(ReadonlyBytes()), ikm, ReadonlyBytes(), output_key_length));
auto result = TRY_OR_FAIL(hkdf.derive_key(Optional<ReadonlyBytes>(ReadonlyBytes()), ikm, ReadonlyBytes(), output_key_length));
// Intermediate value 'PRK' isn't checked explicitly. However, any bit error would have
// an avalanche effect on the output, so if the output is correct then PRK can be presumed correct, too.
u8 const expected_output_key[] = {
@ -127,7 +129,8 @@ TEST_CASE(test_vector_A_4)
u8 const info[] = { 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9 };
static_assert(sizeof(info) == 10);
auto result = TRY_OR_FAIL(Crypto::Hash::HKDF<Crypto::Hash::SHA1>::derive_key(Optional<ReadonlyBytes>(salt), ikm, info, output_key_length));
Crypto::Hash::HKDF hkdf(Crypto::Hash::HashKind::SHA1);
auto result = TRY_OR_FAIL(hkdf.derive_key(Optional<ReadonlyBytes>(salt), ikm, info, output_key_length));
// Intermediate value 'PRK' isn't checked explicitly. However, any bit error would have
// an avalanche effect on the output, so if the output is correct then PRK can be presumed correct, too.
u8 const expected_output_key[] = {
@ -168,7 +171,8 @@ TEST_CASE(test_vector_A_5)
static_assert(sizeof(info) == 80);
size_t const output_key_length = 82;
auto result = TRY_OR_FAIL(Crypto::Hash::HKDF<Crypto::Hash::SHA1>::derive_key(Optional<ReadonlyBytes>(salt), ikm, info, output_key_length));
Crypto::Hash::HKDF hkdf(Crypto::Hash::HashKind::SHA1);
auto result = TRY_OR_FAIL(hkdf.derive_key(Optional<ReadonlyBytes>(salt), ikm, info, output_key_length));
// Intermediate value 'PRK' isn't checked explicitly. However, any bit error would have
// an avalanche effect on the output, so if the output is correct then PRK can be presumed correct, too.
u8 const expected_output_key[] = {
@ -193,8 +197,10 @@ TEST_CASE(test_vector_A_6)
static_assert(sizeof(ikm) == 22);
size_t const output_key_length = 42;
Crypto::Hash::HKDF hkdf(Crypto::Hash::HashKind::SHA1);
// Note: This creates a salt of length zero.
auto result = TRY_OR_FAIL(Crypto::Hash::HKDF<Crypto::Hash::SHA1>::derive_key(Optional<ReadonlyBytes>(ReadonlyBytes()), ikm, ReadonlyBytes(), output_key_length));
auto result = TRY_OR_FAIL(hkdf.derive_key(Optional<ReadonlyBytes>(ReadonlyBytes()), ikm, ReadonlyBytes(), output_key_length));
// Intermediate value 'PRK' isn't checked explicitly. However, any bit error would have
// an avalanche effect on the output, so if the output is correct then PRK can be presumed correct, too.
u8 const expected_output_key[] = {
@ -216,8 +222,10 @@ TEST_CASE(test_vector_A_7)
static_assert(sizeof(ikm) == 22);
size_t const output_key_length = 42;
Crypto::Hash::HKDF hkdf(Crypto::Hash::HashKind::SHA1);
// Note: This creates a "None" salt.
auto result = TRY_OR_FAIL(Crypto::Hash::HKDF<Crypto::Hash::SHA1>::derive_key(Optional<ReadonlyBytes>(), ikm, ReadonlyBytes(), output_key_length));
auto result = TRY_OR_FAIL(hkdf.derive_key(Optional<ReadonlyBytes>(), ikm, ReadonlyBytes(), output_key_length));
// Intermediate value 'PRK' isn't checked explicitly. However, any bit error would have
// an avalanche effect on the output, so if the output is correct then PRK can be presumed correct, too.
u8 const expected_output_key[] = {