// Copyright 2018 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// #include "tink/daead/aes_siv_key_manager.h" #include #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/status/status.h" #include "tink/deterministic_aead.h" #include "tink/util/istream_input_stream.h" #include "tink/util/secret_data.h" #include "tink/util/status.h" #include "tink/util/statusor.h" #include "tink/util/test_matchers.h" #include "proto/aes_siv.pb.h" namespace crypto { namespace tink { using ::crypto::tink::test::IsOk; using ::crypto::tink::test::StatusIs; using ::google::crypto::tink::AesSivKey; using ::google::crypto::tink::AesSivKeyFormat; using ::testing::Eq; using ::testing::HasSubstr; using ::testing::Ne; using ::testing::Not; using ::testing::SizeIs; namespace { TEST(AesSivKeyManagerTest, Basics) { EXPECT_THAT(AesSivKeyManager().get_version(), Eq(0)); EXPECT_THAT(AesSivKeyManager().get_key_type(), Eq("type.googleapis.com/google.crypto.tink.AesSivKey")); EXPECT_THAT(AesSivKeyManager().key_material_type(), Eq(google::crypto::tink::KeyData::SYMMETRIC)); } TEST(AesSivKeyManagerTest, ValidateEmptyKey) { EXPECT_THAT(AesSivKeyManager().ValidateKey(AesSivKey()), Not(IsOk())); } TEST(AesSivKeyManagerTest, ValidateEmptyKeyFormat) { EXPECT_THAT(AesSivKeyManager().ValidateKeyFormat(AesSivKeyFormat()), Not(IsOk())); } TEST(AesSivKeyManagerTest, ValidKeyFormat) { AesSivKeyFormat format; format.set_key_size(64); EXPECT_THAT(AesSivKeyManager().ValidateKeyFormat(format), IsOk()); } TEST(AesSivKeyManagerTest, ValidateKeyFormatWithWrongSizes) { AesSivKeyFormat format; for (int i = 0; i < 64; ++i) { format.set_key_size(i); EXPECT_THAT(AesSivKeyManager().ValidateKeyFormat(format), Not(IsOk())) << " for length " << i; } for (int i = 65; i <= 200; ++i) { format.set_key_size(i); EXPECT_THAT(AesSivKeyManager().ValidateKeyFormat(format), Not(IsOk())) << " for length " << i; } } TEST(AesSivKeyManagerTest, CreateKey) { AesSivKeyFormat format; format.set_key_size(64); auto key_or = AesSivKeyManager().CreateKey(format); ASSERT_THAT(key_or, IsOk()); EXPECT_THAT(key_or.value().key_value(), SizeIs(format.key_size())); EXPECT_THAT(key_or.value().version(), Eq(0)); } TEST(AesSivKeyManagerTest, CreateKeyIsValid) { AesSivKeyFormat format; format.set_key_size(64); auto key_or = AesSivKeyManager().CreateKey(format); ASSERT_THAT(key_or, IsOk()); EXPECT_THAT(AesSivKeyManager().ValidateKey(key_or.value()), IsOk()); } TEST(AesSivKeyManagerTest, MultipleCreateCallsCreateDifferentKeys) { AesSivKeyFormat format; AesSivKeyManager manager; format.set_key_size(64); auto key1_or = manager.CreateKey(format); ASSERT_THAT(key1_or, IsOk()); auto key2_or = manager.CreateKey(format); ASSERT_THAT(key2_or, IsOk()); EXPECT_THAT(key1_or.value().key_value(), Ne(key2_or.value().key_value())); } TEST(AesSivKeyManagerTest, DeriveKey) { util::IstreamInputStream input_stream{absl::make_unique( "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")}; AesSivKeyFormat format; format.set_key_size(64); format.set_version(0); auto key_or = AesSivKeyManager().DeriveKey(format, &input_stream); ASSERT_THAT(key_or, IsOk()); EXPECT_THAT(key_or.value().key_value(), SizeIs(64)); EXPECT_THAT(key_or.value().version(), Eq(0)); } TEST(AesSivKeyManagerTest, DeriveKeyFromLongSeed) { util::IstreamInputStream input_stream{absl::make_unique( "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdefXXXXX")}; AesSivKeyFormat format; format.set_key_size(64); format.set_version(0); auto key_or = AesSivKeyManager().DeriveKey(format, &input_stream); ASSERT_THAT(key_or, IsOk()); EXPECT_THAT( key_or.value().key_value(), Eq("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")); } TEST(AesSivKeyManagerTest, DeriveKeyWithoutEnoughEntropy) { AesSivKeyFormat format; format.set_key_size(64); format.set_version(0); util::IstreamInputStream input_stream{ absl::make_unique("0123456789abcdef0123456789abcdef")}; auto key_or = AesSivKeyManager().DeriveKey(format, &input_stream); ASSERT_THAT(key_or.status(), StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("pseudorandomness"))); } TEST(AesSivKeyManagerTest, DeriveKeyWrongVersion) { util::IstreamInputStream input_stream{absl::make_unique( "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")}; AesSivKeyFormat format; format.set_key_size(64); format.set_version(1); auto key_or = AesSivKeyManager().DeriveKey(format, &input_stream); ASSERT_THAT(key_or.status(), StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("version"))); } TEST(AesSivKeyManagerTest, ValidateKey) { AesSivKey key; *key.mutable_key_value() = std::string(64, 'a'); key.set_version(0); EXPECT_THAT(AesSivKeyManager().ValidateKey(key), IsOk()); } TEST(AesSivKeyManagerTest, ValidateKeyStringLength) { AesSivKey key; key.set_version(0); for (int i = 0 ; i < 64; ++i) { *key.mutable_key_value() = std::string(i, 'a'); EXPECT_THAT(AesSivKeyManager().ValidateKey(key), Not(IsOk())); } for (int i = 65 ; i <= 200; ++i) { *key.mutable_key_value() = std::string(i, 'a'); EXPECT_THAT(AesSivKeyManager().ValidateKey(key), Not(IsOk())); } } TEST(AesSivKeyManagerTest, ValidateKeyVersion) { AesSivKey key; *key.mutable_key_value() = std::string(64, 'a'); key.set_version(1); EXPECT_THAT(AesSivKeyManager().ValidateKey(key), Not(IsOk())); } TEST(AesSivKeyManagerTest, GetPrimitive) { AesSivKeyFormat format; format.set_key_size(64); auto key_or = AesSivKeyManager().CreateKey(format); ASSERT_THAT(key_or, IsOk()); auto daead_or = AesSivKeyManager().GetPrimitive(key_or.value()); ASSERT_THAT(daead_or, IsOk()); auto direct_daead_or = subtle::AesSivBoringSsl::New( util::SecretDataFromStringView(key_or.value().key_value())); ASSERT_THAT(direct_daead_or, IsOk()); auto encryption_or = daead_or.value()->EncryptDeterministically("123", "abcd"); ASSERT_THAT(encryption_or, IsOk()); auto direct_encryption_or = direct_daead_or.value()->EncryptDeterministically("123", "abcd"); ASSERT_THAT(direct_encryption_or, IsOk()); ASSERT_THAT(encryption_or.value(), Eq(direct_encryption_or.value())); } } // namespace } // namespace tink } // namespace crypto