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