1 // Copyright 2017 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 "tink/aead/aes_gcm_key_manager.h"
18
19 #include <stdint.h>
20
21 #include <memory>
22 #include <sstream>
23 #include <string>
24
25 #include "gmock/gmock.h"
26 #include "gtest/gtest.h"
27 #include "absl/memory/memory.h"
28 #include "absl/status/status.h"
29 #include "tink/aead.h"
30 #include "tink/aead/cord_aead.h"
31 #include "tink/aead/internal/cord_aes_gcm_boringssl.h"
32 #include "tink/subtle/aead_test_util.h"
33 #include "tink/subtle/aes_gcm_boringssl.h"
34 #include "tink/util/istream_input_stream.h"
35 #include "tink/util/secret_data.h"
36 #include "tink/util/status.h"
37 #include "tink/util/statusor.h"
38 #include "tink/util/test_matchers.h"
39 #include "proto/aes_gcm.pb.h"
40 #include "proto/tink.pb.h"
41
42 namespace crypto {
43 namespace tink {
44
45 namespace {
46
47 using ::crypto::tink::internal::CordAesGcmBoringSsl;
48 using ::crypto::tink::test::IsOk;
49 using ::crypto::tink::test::StatusIs;
50 using ::crypto::tink::util::IstreamInputStream;
51 using ::crypto::tink::util::StatusOr;
52 using ::google::crypto::tink::AesGcmKey;
53 using ::google::crypto::tink::AesGcmKeyFormat;
54 using ::testing::Eq;
55 using ::testing::HasSubstr;
56
TEST(AesGcmKeyManagerTest,Basics)57 TEST(AesGcmKeyManagerTest, Basics) {
58 EXPECT_THAT(AesGcmKeyManager().get_version(), Eq(0));
59 EXPECT_THAT(AesGcmKeyManager().get_key_type(),
60 Eq("type.googleapis.com/google.crypto.tink.AesGcmKey"));
61 EXPECT_THAT(AesGcmKeyManager().key_material_type(),
62 Eq(google::crypto::tink::KeyData::SYMMETRIC));
63 }
64
TEST(AesGcmKeyManagerTest,ValidateEmptyKey)65 TEST(AesGcmKeyManagerTest, ValidateEmptyKey) {
66 EXPECT_THAT(AesGcmKeyManager().ValidateKey(AesGcmKey()),
67 StatusIs(absl::StatusCode::kInvalidArgument));
68 }
69
TEST(AesGcmKeyManagerTest,ValidateValid16ByteKey)70 TEST(AesGcmKeyManagerTest, ValidateValid16ByteKey) {
71 AesGcmKey key;
72 key.set_version(0);
73 key.set_key_value("0123456789abcdef");
74 EXPECT_THAT(AesGcmKeyManager().ValidateKey(key), IsOk());
75 }
76
TEST(AesGcmKeyManagerTest,ValidateValid32ByteKey)77 TEST(AesGcmKeyManagerTest, ValidateValid32ByteKey) {
78 AesGcmKey key;
79 key.set_version(0);
80 key.set_key_value("01234567890123456789012345678901");
81 EXPECT_THAT(AesGcmKeyManager().ValidateKey(key), IsOk());
82 }
83
TEST(AesGcmKeyManagerTest,InvalidKeySizes15Bytes)84 TEST(AesGcmKeyManagerTest, InvalidKeySizes15Bytes) {
85 AesGcmKey key;
86 key.set_version(0);
87 key.set_key_value("0123456789abcde");
88 EXPECT_THAT(AesGcmKeyManager().ValidateKey(key),
89 StatusIs(absl::StatusCode::kInvalidArgument));
90 }
91
TEST(AesGcmKeyManagerTest,InvalidKeySizes17Bytes)92 TEST(AesGcmKeyManagerTest, InvalidKeySizes17Bytes) {
93 AesGcmKey key;
94 key.set_version(0);
95 key.set_key_value("0123456789abcdefg");
96 EXPECT_THAT(AesGcmKeyManager().ValidateKey(key),
97 StatusIs(absl::StatusCode::kInvalidArgument));
98 }
99
TEST(AesGcmKeyManagerTest,InvalidKeySizes24Bytes)100 TEST(AesGcmKeyManagerTest, InvalidKeySizes24Bytes) {
101 AesGcmKey key;
102 key.set_version(0);
103 key.set_key_value("01234567890123");
104 EXPECT_THAT(AesGcmKeyManager().ValidateKey(key),
105 StatusIs(absl::StatusCode::kInvalidArgument));
106 }
107
TEST(AesGcmKeyManagerTest,InvalidKeySizes31Bytes)108 TEST(AesGcmKeyManagerTest, InvalidKeySizes31Bytes) {
109 AesGcmKey key;
110 key.set_version(0);
111 key.set_key_value("0123456789012345678901234567890");
112 EXPECT_THAT(AesGcmKeyManager().ValidateKey(key),
113 StatusIs(absl::StatusCode::kInvalidArgument));
114 }
115
TEST(AesGcmKeyManagerTest,InvalidKeySizes33Bytes)116 TEST(AesGcmKeyManagerTest, InvalidKeySizes33Bytes) {
117 AesGcmKey key;
118 key.set_version(0);
119 key.set_key_value("012345678901234567890123456789012");
120 EXPECT_THAT(AesGcmKeyManager().ValidateKey(key),
121 StatusIs(absl::StatusCode::kInvalidArgument));
122 }
123
TEST(AesGcmKeyManagerTest,ValidateKeyFormat)124 TEST(AesGcmKeyManagerTest, ValidateKeyFormat) {
125 AesGcmKeyFormat format;
126
127 format.set_key_size(0);
128 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(format),
129 StatusIs(absl::StatusCode::kInvalidArgument));
130
131 format.set_key_size(1);
132 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(format),
133 StatusIs(absl::StatusCode::kInvalidArgument));
134
135 format.set_key_size(15);
136 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(format),
137 StatusIs(absl::StatusCode::kInvalidArgument));
138
139 format.set_key_size(16);
140 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(format), IsOk());
141
142 format.set_key_size(17);
143 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(format),
144 StatusIs(absl::StatusCode::kInvalidArgument));
145
146 format.set_key_size(31);
147 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(format),
148 StatusIs(absl::StatusCode::kInvalidArgument));
149
150 format.set_key_size(32);
151 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(format), IsOk());
152
153 format.set_key_size(33);
154 EXPECT_THAT(AesGcmKeyManager().ValidateKeyFormat(format),
155 StatusIs(absl::StatusCode::kInvalidArgument));
156 }
157
TEST(AesGcmKeyManagerTest,Create16ByteKey)158 TEST(AesGcmKeyManagerTest, Create16ByteKey) {
159 AesGcmKeyFormat format;
160 format.set_key_size(16);
161
162 StatusOr<AesGcmKey> key_or = AesGcmKeyManager().CreateKey(format);
163
164 ASSERT_THAT(key_or, IsOk());
165 EXPECT_THAT(key_or.value().key_value().size(), Eq(format.key_size()));
166 }
167
TEST(AesGcmKeyManagerTest,Create32ByteKey)168 TEST(AesGcmKeyManagerTest, Create32ByteKey) {
169 AesGcmKeyFormat format;
170 format.set_key_size(32);
171
172 StatusOr<AesGcmKey> key_or = AesGcmKeyManager().CreateKey(format);
173
174 ASSERT_THAT(key_or, IsOk());
175 EXPECT_THAT(key_or.value().key_value().size(), Eq(format.key_size()));
176 }
177
TEST(AesGcmKeyManagerTest,CreateAead)178 TEST(AesGcmKeyManagerTest, CreateAead) {
179 AesGcmKeyFormat format;
180 format.set_key_size(32);
181 StatusOr<AesGcmKey> key_or = AesGcmKeyManager().CreateKey(format);
182 ASSERT_THAT(key_or, IsOk());
183
184 StatusOr<std::unique_ptr<Aead>> aead_or =
185 AesGcmKeyManager().GetPrimitive<Aead>(key_or.value());
186
187 ASSERT_THAT(aead_or, IsOk());
188
189 StatusOr<std::unique_ptr<Aead>> boring_ssl_aead_or =
190 subtle::AesGcmBoringSsl::New(
191 util::SecretDataFromStringView(key_or.value().key_value()));
192 ASSERT_THAT(boring_ssl_aead_or, IsOk());
193
194 ASSERT_THAT(EncryptThenDecrypt(*aead_or.value(), *boring_ssl_aead_or.value(),
195 "message", "aad"),
196 IsOk());
197 }
198
TEST(AesGcmKeyManagerTest,CreateCordAead)199 TEST(AesGcmKeyManagerTest, CreateCordAead) {
200 AesGcmKeyFormat format;
201 format.set_key_size(32);
202 StatusOr<AesGcmKey> key_or = AesGcmKeyManager().CreateKey(format);
203 ASSERT_THAT(key_or, IsOk());
204
205 StatusOr<std::unique_ptr<CordAead>> aead_or =
206 AesGcmKeyManager().GetPrimitive<CordAead>(key_or.value());
207
208 ASSERT_THAT(aead_or, IsOk());
209
210 StatusOr<std::unique_ptr<CordAead>> boring_ssl_aead_or =
211 CordAesGcmBoringSsl::New(
212 util::SecretDataFromStringView(key_or.value().key_value()));
213 ASSERT_THAT(boring_ssl_aead_or, IsOk());
214
215 ASSERT_THAT(EncryptThenDecrypt(*aead_or.value(), *boring_ssl_aead_or.value(),
216 "message", "aad"),
217 IsOk());
218 }
219
TEST(AesGcmKeyManagerTest,DeriveShortKey)220 TEST(AesGcmKeyManagerTest, DeriveShortKey) {
221 AesGcmKeyFormat format;
222 format.set_key_size(16);
223 format.set_version(0);
224
225 IstreamInputStream input_stream{
226 absl::make_unique<std::stringstream>("0123456789abcdefghijklmnop")};
227
228 StatusOr<AesGcmKey> key_or =
229 AesGcmKeyManager().DeriveKey(format, &input_stream);
230 ASSERT_THAT(key_or, IsOk());
231 EXPECT_THAT(key_or.value().key_value(), Eq("0123456789abcdef"));
232 }
233
TEST(AesGcmKeyManagerTest,DeriveLongKey)234 TEST(AesGcmKeyManagerTest, DeriveLongKey) {
235 AesGcmKeyFormat format;
236 format.set_key_size(32);
237 format.set_version(0);
238
239 IstreamInputStream input_stream{absl::make_unique<std::stringstream>(
240 "0123456789abcdef0123456789abcdefXXX")};
241
242 StatusOr<AesGcmKey> key_or =
243 AesGcmKeyManager().DeriveKey(format, &input_stream);
244 ASSERT_THAT(key_or, IsOk());
245 EXPECT_THAT(key_or.value().key_value(),
246 Eq("0123456789abcdef0123456789abcdef"));
247 }
248
TEST(AesGcmKeyManagerTest,DeriveKeyNotEnoughRandomness)249 TEST(AesGcmKeyManagerTest, DeriveKeyNotEnoughRandomness) {
250 AesGcmKeyFormat format;
251 format.set_key_size(16);
252 format.set_version(0);
253
254 IstreamInputStream input_stream{
255 absl::make_unique<std::stringstream>("0123456789")};
256
257 ASSERT_THAT(AesGcmKeyManager().DeriveKey(format, &input_stream).status(),
258 StatusIs(absl::StatusCode::kInvalidArgument));
259 }
260
TEST(AesGcmKeyManagerTest,DeriveKeyWrongVersion)261 TEST(AesGcmKeyManagerTest, DeriveKeyWrongVersion) {
262 AesGcmKeyFormat format;
263 format.set_key_size(16);
264 format.set_version(1);
265
266 IstreamInputStream input_stream{
267 absl::make_unique<std::stringstream>("0123456789abcdefghijklmnop")};
268
269 ASSERT_THAT(
270 AesGcmKeyManager().DeriveKey(format, &input_stream).status(),
271 StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("version")));
272 }
273
274 } // namespace
275 } // namespace tink
276 } // namespace crypto
277