blob: d0efc38c210131c085ed6cd9a0648be62034bd7d [file] [log] [blame]
// 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/kms_envelope_aead.h"
#include <string>
#include <vector>
#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
#include "tink/registry.h"
#include "tink/aead/aead_config.h"
#include "tink/aead/aead_key_templates.h"
#include "tink/mac/mac_key_templates.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"
#include "tink/util/test_util.h"
#include "tink/util/test_matchers.h"
#include "gtest/gtest.h"
namespace crypto {
namespace tink {
namespace {
using crypto::tink::test::IsOk;
using crypto::tink::test::StatusIs;
using crypto::tink::test::DummyAead;
using testing::HasSubstr;
TEST(KmsEnvelopeAeadTest, BasicEncryptDecrypt) {
EXPECT_THAT(AeadConfig::Register(), IsOk());
auto dek_template = AeadKeyTemplates::Aes128Eax();
std::string remote_aead_name = "kms-backed-aead";
auto remote_aead = absl::make_unique<DummyAead>(remote_aead_name);
auto aead_result = KmsEnvelopeAead::New(dek_template, std::move(remote_aead));
EXPECT_THAT(aead_result.status(), IsOk());
auto aead = std::move(aead_result.ValueOrDie());
std::string message = "Some data to encrypt.";
std::string aad = "Some data to authenticate.";
auto encrypt_result = aead->Encrypt(message, aad);
EXPECT_THAT(encrypt_result.status(), IsOk());
auto decrypt_result = aead->Decrypt(encrypt_result.ValueOrDie(), aad);
EXPECT_THAT(decrypt_result.status(), IsOk());
EXPECT_EQ(decrypt_result.ValueOrDie(), message);
}
TEST(KmsEnvelopeAeadTest, NullAead) {
auto dek_template = AeadKeyTemplates::Aes128Eax();
auto aead_result = KmsEnvelopeAead::New(dek_template, nullptr);
EXPECT_THAT(aead_result.status(), StatusIs(util::error::INVALID_ARGUMENT,
HasSubstr("non-null")));
}
TEST(KmsEnvelopeAeadTest, MissingDekKeyManager) {
Registry::Reset();
auto dek_template = AeadKeyTemplates::Aes128Eax();
std::string remote_aead_name = "kms-backed-aead";
auto remote_aead = absl::make_unique<DummyAead>(remote_aead_name);
auto aead_result = KmsEnvelopeAead::New(dek_template, std::move(remote_aead));
EXPECT_THAT(aead_result.status(), StatusIs(util::error::NOT_FOUND,
HasSubstr("AesEaxKey")));
}
TEST(KmsEnvelopeAeadTest, WrongDekPrimitive) {
EXPECT_THAT(AeadConfig::Register(), IsOk());
auto dek_template = MacKeyTemplates::HmacSha256();
std::string remote_aead_name = "kms-backed-aead";
auto remote_aead = absl::make_unique<DummyAead>(remote_aead_name);
auto aead_result = KmsEnvelopeAead::New(dek_template, std::move(remote_aead));
EXPECT_THAT(aead_result.status(),
StatusIs(util::error::INVALID_ARGUMENT,
HasSubstr("not among supported primitives")));
}
TEST(KmsEnvelopeAeadTest, DecryptionErrors) {
EXPECT_THAT(AeadConfig::Register(), IsOk());
auto dek_template = AeadKeyTemplates::Aes128Gcm();
std::string remote_aead_name = "kms-backed-aead";
auto remote_aead = absl::make_unique<DummyAead>(remote_aead_name);
auto aead_result = KmsEnvelopeAead::New(dek_template, std::move(remote_aead));
EXPECT_THAT(aead_result.status(), IsOk());
auto aead = std::move(aead_result.ValueOrDie());
std::string message = "Some data to encrypt.";
std::string aad = "Some data to authenticate.";
auto encrypt_result = aead->Encrypt(message, aad);
EXPECT_THAT(encrypt_result.status(), IsOk());
auto ct = encrypt_result.ValueOrDie();
// Empty ciphertext.
auto decrypt_result = aead->Decrypt("", aad);
EXPECT_THAT(decrypt_result.status(), StatusIs(util::error::INVALID_ARGUMENT,
HasSubstr("too short")));
// Short ciphertext.
decrypt_result = aead->Decrypt("sh", aad);
EXPECT_THAT(decrypt_result.status(), StatusIs(util::error::INVALID_ARGUMENT,
HasSubstr("too short")));
// Truncated ciphertext.
decrypt_result = aead->Decrypt(ct.substr(2), aad);
EXPECT_THAT(decrypt_result.status(), StatusIs(util::error::INVALID_ARGUMENT,
HasSubstr("invalid")));
// Corrupted ciphertext.
auto ct_copy = ct;
ct_copy[4] = 'a'; // corrupt serialized DEK.
decrypt_result = aead->Decrypt(ct_copy, aad);
EXPECT_THAT(decrypt_result.status(), StatusIs(util::error::INVALID_ARGUMENT,
HasSubstr("invalid")));
// Wrong associated data.
decrypt_result = aead->Decrypt(ct, "wrong aad");
EXPECT_THAT(decrypt_result.status(),
StatusIs(util::error::INTERNAL,
HasSubstr("Authentication failed")));
}
} // namespace
} // namespace tink
} // namespace crypto