blob: 92df42ffd30d6b4fd359c14b13d3883dea9af4db [file] [log] [blame]
/*
* Copyright 2018 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "rtc_base/openssl_key_derivation_hkdf.h"
#include <utility>
#include "test/gmock.h"
namespace rtc {
namespace {
// Validates that a basic valid call works correctly.
TEST(OpenSSLKeyDerivationHKDF, DerivationBasicTest) {
rtc::Buffer secret(32);
rtc::Buffer salt(32);
rtc::Buffer label(32);
const size_t derived_key_byte_size = 16;
OpenSSLKeyDerivationHKDF hkdf;
auto key_or = hkdf.DeriveKey(secret, salt, label, derived_key_byte_size);
EXPECT_TRUE(key_or.has_value());
ZeroOnFreeBuffer<uint8_t> key = std::move(key_or.value());
EXPECT_EQ(derived_key_byte_size, key.size());
}
// Derivation fails if output is too small.
TEST(OpenSSLKeyDerivationHKDF, DerivationFailsIfOutputIsTooSmall) {
rtc::Buffer secret(32);
rtc::Buffer salt(32);
rtc::Buffer label(32);
const size_t derived_key_byte_size = 15;
OpenSSLKeyDerivationHKDF hkdf;
auto key_or = hkdf.DeriveKey(secret, salt, label, derived_key_byte_size);
EXPECT_FALSE(key_or.has_value());
}
// Derivation fails if output is too large.
TEST(OpenSSLKeyDerivationHKDF, DerivationFailsIfOutputIsTooLarge) {
rtc::Buffer secret(32);
rtc::Buffer salt(32);
rtc::Buffer label(32);
const size_t derived_key_byte_size = 256 * 32;
OpenSSLKeyDerivationHKDF hkdf;
auto key_or = hkdf.DeriveKey(secret, salt, label, derived_key_byte_size);
EXPECT_FALSE(key_or.has_value());
}
// Validates that too little key material causes a failure.
TEST(OpenSSLKeyDerivationHKDF, DerivationFailsWithInvalidSecret) {
rtc::Buffer secret(15);
rtc::Buffer salt(32);
rtc::Buffer label(32);
const size_t derived_key_byte_size = 16;
OpenSSLKeyDerivationHKDF hkdf;
auto key_or_0 = hkdf.DeriveKey(secret, salt, label, derived_key_byte_size);
EXPECT_FALSE(key_or_0.has_value());
auto key_or_1 = hkdf.DeriveKey(nullptr, salt, label, derived_key_byte_size);
EXPECT_FALSE(key_or_1.has_value());
rtc::Buffer secret_empty;
auto key_or_2 =
hkdf.DeriveKey(secret_empty, salt, label, derived_key_byte_size);
EXPECT_FALSE(key_or_2.has_value());
}
// Validates that HKDF works without a salt being set.
TEST(OpenSSLKeyDerivationHKDF, DerivationWorksWithNoSalt) {
rtc::Buffer secret(32);
rtc::Buffer label(32);
const size_t derived_key_byte_size = 16;
OpenSSLKeyDerivationHKDF hkdf;
auto key_or = hkdf.DeriveKey(secret, nullptr, label, derived_key_byte_size);
EXPECT_TRUE(key_or.has_value());
}
// Validates that a label is required to work correctly.
TEST(OpenSSLKeyDerivationHKDF, DerivationRequiresLabel) {
rtc::Buffer secret(32);
rtc::Buffer salt(32);
rtc::Buffer label(1);
const size_t derived_key_byte_size = 16;
OpenSSLKeyDerivationHKDF hkdf;
auto key_or_0 = hkdf.DeriveKey(secret, salt, label, derived_key_byte_size);
EXPECT_TRUE(key_or_0.has_value());
ZeroOnFreeBuffer<uint8_t> key = std::move(key_or_0.value());
EXPECT_EQ(key.size(), derived_key_byte_size);
auto key_or_1 = hkdf.DeriveKey(secret, salt, nullptr, derived_key_byte_size);
EXPECT_FALSE(key_or_1.has_value());
}
} // namespace
} // namespace rtc