| // 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/aead/aes_eax_key_manager.h" |
| |
| #include "gmock/gmock.h" |
| #include "gtest/gtest.h" |
| #include "tink/aead.h" |
| #include "tink/subtle/aead_test_util.h" |
| #include "tink/util/status.h" |
| #include "tink/util/statusor.h" |
| #include "tink/util/test_matchers.h" |
| #include "proto/aes_eax.pb.h" |
| |
| namespace crypto { |
| namespace tink { |
| |
| using ::crypto::tink::test::IsOk; |
| using ::crypto::tink::util::StatusOr; |
| using ::google::crypto::tink::AesEaxKey; |
| using ::google::crypto::tink::AesEaxKeyFormat; |
| using ::testing::Eq; |
| using ::testing::Ne; |
| using ::testing::Not; |
| using ::testing::SizeIs; |
| |
| namespace { |
| |
| TEST(AesEaxKeyManagerTest, Basics) { |
| EXPECT_THAT(AesEaxKeyManager().get_version(), Eq(0)); |
| EXPECT_THAT(AesEaxKeyManager().get_key_type(), |
| Eq("type.googleapis.com/google.crypto.tink.AesEaxKey")); |
| EXPECT_THAT(AesEaxKeyManager().key_material_type(), |
| Eq(google::crypto::tink::KeyData::SYMMETRIC)); |
| } |
| |
| TEST(AesEaxKeyManagerTest, ValidateEmptyKey) { |
| EXPECT_THAT(AesEaxKeyManager().ValidateKey(AesEaxKey()), Not(IsOk())); |
| } |
| |
| TEST(AesEaxKeyManagerTest, ValidateEmptyKeyFormat) { |
| EXPECT_THAT(AesEaxKeyManager().ValidateKeyFormat(AesEaxKeyFormat()), |
| Not(IsOk())); |
| } |
| |
| TEST(AesEaxKeyManagerTest, ValidKeyFormat) { |
| AesEaxKeyFormat format; |
| format.set_key_size(32); |
| format.mutable_params()->set_iv_size(16); |
| EXPECT_THAT(AesEaxKeyManager().ValidateKeyFormat(format), IsOk()); |
| } |
| |
| TEST(AesEaxKeyManagerTest, ValidKeyFormatKeySize) { |
| AesEaxKeyFormat format; |
| format.mutable_params()->set_iv_size(16); |
| |
| for (int len = 0; len < 200; ++len) { |
| format.set_key_size(len); |
| if (len == 16 || len == 32) { |
| EXPECT_THAT(AesEaxKeyManager().ValidateKeyFormat(format), IsOk()) |
| << "for len = " << len; |
| } else { |
| EXPECT_THAT(AesEaxKeyManager().ValidateKeyFormat(format), Not(IsOk())) |
| << "for len = " << len; |
| } |
| } |
| } |
| |
| TEST(AesEaxKeyManagerTest, ValidKeyFormatIvSize) { |
| AesEaxKeyFormat format; |
| format.set_key_size(32); |
| |
| for (int iv_size = 0; iv_size < 200; ++iv_size) { |
| format.mutable_params()->set_iv_size(iv_size); |
| if (iv_size == 12 || iv_size == 16) { |
| EXPECT_THAT(AesEaxKeyManager().ValidateKeyFormat(format), IsOk()) |
| << "for iv_size = " << iv_size; |
| } else { |
| EXPECT_THAT(AesEaxKeyManager().ValidateKeyFormat(format), Not(IsOk())) |
| << "for iv_size = " << iv_size; |
| } |
| } |
| } |
| |
| TEST(AesEaxKeyManagerTest, CreateKey) { |
| AesEaxKeyFormat format; |
| format.set_key_size(32); |
| format.mutable_params()->set_iv_size(16); |
| auto key_or = AesEaxKeyManager().CreateKey(format); |
| ASSERT_THAT(key_or.status(), IsOk()); |
| EXPECT_THAT(key_or.ValueOrDie().key_value(), SizeIs(format.key_size())); |
| EXPECT_THAT(key_or.ValueOrDie().params().iv_size(), |
| Eq(format.params().iv_size())); |
| } |
| |
| TEST(AesEaxKeyManagerTest, CreateKeyIsValid) { |
| AesEaxKeyFormat format; |
| format.set_key_size(32); |
| format.mutable_params()->set_iv_size(16); |
| auto key_or = AesEaxKeyManager().CreateKey(format); |
| ASSERT_THAT(key_or.status(), IsOk()); |
| EXPECT_THAT(AesEaxKeyManager().ValidateKey(key_or.ValueOrDie()), IsOk()); |
| } |
| |
| TEST(AesEaxKeyManagerTest, MultipleCreateCallsCreateDifferentKeys) { |
| AesEaxKeyFormat format; |
| AesEaxKeyManager manager; |
| format.set_key_size(32); |
| format.mutable_params()->set_iv_size(16); |
| auto key1_or = manager.CreateKey(format); |
| ASSERT_THAT(key1_or.status(), IsOk()); |
| auto key2_or = manager.CreateKey(format); |
| ASSERT_THAT(key2_or.status(), IsOk()); |
| EXPECT_THAT(key1_or.ValueOrDie().key_value(), |
| Ne(key2_or.ValueOrDie().key_value())); |
| } |
| |
| TEST(AesEaxKeyManagerTest, ValidKey) { |
| AesEaxKey key; |
| key.set_key_value(std::string(32, 'a')); |
| key.mutable_params()->set_iv_size(16); |
| EXPECT_THAT(AesEaxKeyManager().ValidateKey(key), IsOk()); |
| } |
| |
| TEST(AesEaxKeyManagerTest, ValidateKeyKeyLength) { |
| AesEaxKey key; |
| key.mutable_params()->set_iv_size(16); |
| |
| for (int len = 0; len < 200; ++len) { |
| key.set_key_value(std::string(len, 'a')); |
| if (len == 16 || len == 32) { |
| EXPECT_THAT(AesEaxKeyManager().ValidateKey(key), IsOk()) |
| << "for len = " << len; |
| } else { |
| EXPECT_THAT(AesEaxKeyManager().ValidateKey(key), Not(IsOk())) |
| << "for len = " << len; |
| } |
| } |
| } |
| |
| TEST(AesEaxKeyManagerTest, ValidateKeyIvLength) { |
| AesEaxKey key; |
| key.set_key_value(std::string(32, 'a')); |
| |
| for (int iv_len = 0; iv_len < 200; ++iv_len) { |
| key.mutable_params()->set_iv_size(iv_len); |
| if (iv_len == 12 || iv_len == 16) { |
| EXPECT_THAT(AesEaxKeyManager().ValidateKey(key), IsOk()) |
| << "for iv_size = " << iv_len; |
| } else { |
| EXPECT_THAT(AesEaxKeyManager().ValidateKey(key), Not(IsOk())) |
| << "for iv_size = " << iv_len; |
| } |
| } |
| } |
| |
| TEST(AesGcmKeyManagerTest, CreateAead) { |
| AesEaxKeyFormat format; |
| format.set_key_size(32); |
| format.mutable_params()->set_iv_size(16); |
| StatusOr<AesEaxKey> key_or = AesEaxKeyManager().CreateKey(format); |
| ASSERT_THAT(key_or.status(), IsOk()); |
| |
| StatusOr<std::unique_ptr<Aead>> aead_or = |
| AesEaxKeyManager().GetPrimitive<Aead>(key_or.ValueOrDie()); |
| |
| ASSERT_THAT(aead_or.status(), IsOk()); |
| |
| StatusOr<std::unique_ptr<Aead>> boring_ssl_aead_or = |
| subtle::AesEaxBoringSsl::New(key_or.ValueOrDie().key_value(), |
| key_or.ValueOrDie().params().iv_size()); |
| ASSERT_THAT(boring_ssl_aead_or.status(), IsOk()); |
| |
| ASSERT_THAT(EncryptThenDecrypt(aead_or.ValueOrDie().get(), |
| boring_ssl_aead_or.ValueOrDie().get(), |
| "message", "aad"), |
| IsOk()); |
| } |
| |
| } // namespace |
| } // namespace tink |
| } // namespace crypto |