/* * 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 #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 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 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