1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 ///////////////////////////////////////////////////////////////////////////////
16
17 #include "deterministic_aead_impl.h"
18
19 #include <string>
20
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "tink/binary_keyset_writer.h"
24 #include "tink/cleartext_keyset_handle.h"
25 #include "tink/daead/deterministic_aead_config.h"
26 #include "tink/daead/deterministic_aead_key_templates.h"
27 #include "proto/testing_api.grpc.pb.h"
28
29 namespace crypto {
30 namespace tink {
31 namespace {
32
33 using ::crypto::tink::BinaryKeysetWriter;
34 using ::crypto::tink::CleartextKeysetHandle;
35 using ::crypto::tink::DeterministicAeadKeyTemplates;
36
37 using ::testing::Eq;
38 using ::testing::IsEmpty;
39 using ::tink_testing_api::DeterministicAeadDecryptRequest;
40 using ::tink_testing_api::DeterministicAeadDecryptResponse;
41 using ::tink_testing_api::DeterministicAeadEncryptRequest;
42 using ::tink_testing_api::DeterministicAeadEncryptResponse;
43
44 using crypto::tink::KeysetHandle;
45 using google::crypto::tink::KeyTemplate;
46 using tink_testing_api::CreationRequest;
47 using tink_testing_api::CreationResponse;
48
ValidKeyset()49 std::string ValidKeyset() {
50 const KeyTemplate& key_template = DeterministicAeadKeyTemplates::Aes256Siv();
51 auto handle_result = KeysetHandle::GenerateNew(key_template);
52 EXPECT_TRUE(handle_result.ok());
53 std::stringbuf keyset;
54 auto writer_result =
55 BinaryKeysetWriter::New(absl::make_unique<std::ostream>(&keyset));
56 EXPECT_TRUE(writer_result.ok());
57
58 auto status = CleartextKeysetHandle::Write(writer_result.value().get(),
59 *handle_result.value());
60 EXPECT_TRUE(status.ok());
61 return keyset.str();
62 }
63
64 class DeterministicAeadImplTest : public ::testing::Test {
65 protected:
SetUpTestSuite()66 static void SetUpTestSuite() {
67 ASSERT_TRUE(DeterministicAeadConfig::Register().ok());
68 }
69 };
70
TEST_F(DeterministicAeadImplTest,CreateSuccess)71 TEST_F(DeterministicAeadImplTest, CreateSuccess) {
72 tink_testing_api::DeterministicAeadImpl aead;
73 std::string keyset = ValidKeyset();
74 CreationRequest request;
75 request.mutable_annotated_keyset()->set_serialized_keyset(keyset);
76 CreationResponse response;
77
78 EXPECT_TRUE(aead.Create(nullptr, &request, &response).ok());
79 EXPECT_THAT(response.err(), IsEmpty());
80 }
81
TEST_F(DeterministicAeadImplTest,CreateAeadFails)82 TEST_F(DeterministicAeadImplTest, CreateAeadFails) {
83 tink_testing_api::DeterministicAeadImpl aead;
84 CreationRequest request;
85 request.mutable_annotated_keyset()->set_serialized_keyset("bad keyset");
86 CreationResponse response;
87
88 EXPECT_TRUE(aead.Create(nullptr, &request, &response).ok());
89 EXPECT_THAT(response.err(), Not(IsEmpty()));
90 }
91
TEST_F(DeterministicAeadImplTest,EncryptDecryptSuccess)92 TEST_F(DeterministicAeadImplTest, EncryptDecryptSuccess) {
93 tink_testing_api::DeterministicAeadImpl daead;
94 std::string keyset = ValidKeyset();
95 DeterministicAeadEncryptRequest enc_request;
96 enc_request.mutable_annotated_keyset()->set_serialized_keyset(keyset);
97 enc_request.set_plaintext("Plain text");
98 enc_request.set_associated_data("ad");
99 DeterministicAeadEncryptResponse enc_response;
100
101 EXPECT_TRUE(
102 daead.EncryptDeterministically(nullptr, &enc_request, &enc_response)
103 .ok());
104 EXPECT_THAT(enc_response.err(), IsEmpty());
105
106 DeterministicAeadDecryptRequest dec_request;
107 dec_request.mutable_annotated_keyset()->set_serialized_keyset(keyset);
108 dec_request.set_ciphertext(enc_response.ciphertext());
109 dec_request.set_associated_data("ad");
110 DeterministicAeadDecryptResponse dec_response;
111
112 EXPECT_TRUE(
113 daead.DecryptDeterministically(nullptr, &dec_request, &dec_response)
114 .ok());
115 EXPECT_THAT(dec_response.err(), IsEmpty());
116 EXPECT_THAT(dec_response.plaintext(), Eq("Plain text"));
117 }
118
TEST_F(DeterministicAeadImplTest,EncryptBadKeysetFail)119 TEST_F(DeterministicAeadImplTest, EncryptBadKeysetFail) {
120 tink_testing_api::DeterministicAeadImpl daead;
121 DeterministicAeadEncryptRequest enc_request;
122 enc_request.mutable_annotated_keyset()->set_serialized_keyset("bad keyset");
123 enc_request.set_plaintext("Plain text");
124 enc_request.set_associated_data("ad");
125 DeterministicAeadEncryptResponse enc_response;
126
127 EXPECT_FALSE(
128 daead.EncryptDeterministically(nullptr, &enc_request, &enc_response)
129 .ok());
130 }
131
TEST_F(DeterministicAeadImplTest,DecryptBadCiphertextFail)132 TEST_F(DeterministicAeadImplTest, DecryptBadCiphertextFail) {
133 tink_testing_api::DeterministicAeadImpl daead;
134 std::string keyset = ValidKeyset();
135 DeterministicAeadDecryptRequest dec_request;
136 dec_request.mutable_annotated_keyset()->set_serialized_keyset(keyset);
137 dec_request.set_ciphertext("bad ciphertext");
138 dec_request.set_associated_data("ad");
139 DeterministicAeadDecryptResponse dec_response;
140
141 EXPECT_TRUE(
142 daead.DecryptDeterministically(nullptr, &dec_request, &dec_response)
143 .ok());
144 EXPECT_THAT(dec_response.err(), Not(IsEmpty()));
145 }
146
147 } // namespace
148 } // namespace tink
149 } // namespace crypto
150