1 // Copyright 2017 Google Inc.
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_ctr_hmac_aead_key_manager.h"
18
19 #include <stdint.h>
20
21 #include <memory>
22 #include <sstream>
23 #include <string>
24 #include <utility>
25
26 #include "gmock/gmock.h"
27 #include "gtest/gtest.h"
28 #include "absl/status/status.h"
29 #include "tink/aead.h"
30 #include "tink/subtle/aead_test_util.h"
31 #include "tink/subtle/aes_ctr_boringssl.h"
32 #include "tink/subtle/encrypt_then_authenticate.h"
33 #include "tink/subtle/hmac_boringssl.h"
34 #include "tink/subtle/ind_cpa_cipher.h"
35 #include "tink/util/enums.h"
36 #include "tink/util/istream_input_stream.h"
37 #include "tink/util/secret_data.h"
38 #include "tink/util/status.h"
39 #include "tink/util/statusor.h"
40 #include "tink/util/test_matchers.h"
41 #include "proto/aes_ctr.pb.h"
42 #include "proto/aes_ctr_hmac_aead.pb.h"
43 #include "proto/common.pb.h"
44 #include "proto/hmac.pb.h"
45 #include "proto/tink.pb.h"
46
47 namespace crypto {
48 namespace tink {
49
50 using ::crypto::tink::test::IsOk;
51 using ::crypto::tink::test::StatusIs;
52 using ::crypto::tink::util::IstreamInputStream;
53 using ::crypto::tink::util::StatusOr;
54 using ::google::crypto::tink::AesCtrHmacAeadKey;
55 using ::google::crypto::tink::AesCtrHmacAeadKeyFormat;
56 using ::google::crypto::tink::HashType;
57 using ::testing::Eq;
58 using ::testing::Not;
59 using ::testing::SizeIs;
60
61 namespace {
62
TEST(AesCtrHmacAeadKeyManagerTest,Basics)63 TEST(AesCtrHmacAeadKeyManagerTest, Basics) {
64 EXPECT_THAT(AesCtrHmacAeadKeyManager().get_version(), Eq(0));
65 EXPECT_THAT(AesCtrHmacAeadKeyManager().get_key_type(),
66 Eq("type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey"));
67 EXPECT_THAT(AesCtrHmacAeadKeyManager().key_material_type(),
68 Eq(google::crypto::tink::KeyData::SYMMETRIC));
69 }
70
TEST(AesCtrHmacAeadKeyManagerTest,ValidateEmptyKey)71 TEST(AesCtrHmacAeadKeyManagerTest, ValidateEmptyKey) {
72 EXPECT_THAT(AesCtrHmacAeadKeyManager().ValidateKey(AesCtrHmacAeadKey()),
73 StatusIs(absl::StatusCode::kInvalidArgument));
74 }
75
CreateValidKey()76 AesCtrHmacAeadKey CreateValidKey() {
77 AesCtrHmacAeadKey key;
78 key.set_version(0);
79 auto aes_ctr_key = key.mutable_aes_ctr_key();
80 aes_ctr_key->set_key_value(std::string(16, 'a'));
81 aes_ctr_key->mutable_params()->set_iv_size(12);
82 auto hmac_key = key.mutable_hmac_key();
83 hmac_key->set_key_value(std::string(16, 'b'));
84 hmac_key->mutable_params()->set_hash(HashType::SHA1);
85 hmac_key->mutable_params()->set_tag_size(10);
86 return key;
87 }
88
TEST(AesCtrHmacAeadKeyManagerTest,ValidKey)89 TEST(AesCtrHmacAeadKeyManagerTest, ValidKey) {
90 EXPECT_THAT(AesCtrHmacAeadKeyManager().ValidateKey(CreateValidKey()), IsOk());
91 }
92
TEST(AesCtrHmacAeadKeyManagerTest,AesKeySizes)93 TEST(AesCtrHmacAeadKeyManagerTest, AesKeySizes) {
94 AesCtrHmacAeadKey key = CreateValidKey();
95 for (int len = 0; len < 42; len++) {
96 key.mutable_aes_ctr_key()->set_key_value(std::string(len, 'a'));
97 if (len == 16 || len == 32) {
98 EXPECT_THAT(AesCtrHmacAeadKeyManager().ValidateKey(key), IsOk())
99 << " for length " << len;
100 } else {
101 EXPECT_THAT(AesCtrHmacAeadKeyManager().ValidateKey(key), Not(IsOk()))
102 << " for length " << len;
103 }
104 }
105 }
106
TEST(AesCtrHmacAeadKeyManagerTest,HmacKeySizes)107 TEST(AesCtrHmacAeadKeyManagerTest, HmacKeySizes) {
108 AesCtrHmacAeadKey key = CreateValidKey();
109 for (int len = 0; len < 42; len++) {
110 key.mutable_hmac_key()->set_key_value(std::string(len, 'b'));
111 if (len >= 16) {
112 EXPECT_THAT(AesCtrHmacAeadKeyManager().ValidateKey(key), IsOk())
113 << " for length " << len;
114 } else {
115 EXPECT_THAT(AesCtrHmacAeadKeyManager().ValidateKey(key), Not(IsOk()))
116 << " for length " << len;
117 }
118 }
119 }
120
CreateValidKeyFormat()121 AesCtrHmacAeadKeyFormat CreateValidKeyFormat() {
122 AesCtrHmacAeadKeyFormat key_format;
123 auto aes_ctr_key_format = key_format.mutable_aes_ctr_key_format();
124 aes_ctr_key_format->set_key_size(16);
125 aes_ctr_key_format->mutable_params()->set_iv_size(16);
126 auto hmac_key_format = key_format.mutable_hmac_key_format();
127 hmac_key_format->set_key_size(21);
128 hmac_key_format->mutable_params()->set_hash(HashType::SHA256);
129 hmac_key_format->mutable_params()->set_tag_size(16);
130 return key_format;
131 }
132
TEST(AesCtrHmacAeadKeyManagerTest,ValidateKeyFormat)133 TEST(AesCtrHmacAeadKeyManagerTest, ValidateKeyFormat) {
134 AesCtrHmacAeadKeyFormat key_format = CreateValidKeyFormat();
135 EXPECT_THAT(
136 AesCtrHmacAeadKeyManager().ValidateKeyFormat(CreateValidKeyFormat()),
137 IsOk());
138 }
139
TEST(AesCtrHmacAeadKeyManagerTest,ValidateEmptyKeyFormat)140 TEST(AesCtrHmacAeadKeyManagerTest, ValidateEmptyKeyFormat) {
141 EXPECT_THAT(
142 AesCtrHmacAeadKeyManager().ValidateKeyFormat(AesCtrHmacAeadKeyFormat()),
143 Not(IsOk()));
144 }
145
TEST(AesCtrHmacAeadKeyManagerTest,ValidateKeyFormatKeySizes)146 TEST(AesCtrHmacAeadKeyManagerTest, ValidateKeyFormatKeySizes) {
147 AesCtrHmacAeadKeyFormat key_format = CreateValidKeyFormat();
148 for (int len = 0; len < 42; ++len) {
149 key_format.mutable_aes_ctr_key_format()->set_key_size(len);
150 IstreamInputStream input_stream{absl::make_unique<std::stringstream>(
151 "0123456789abcde0123456789abcdefghijklmnopqrztuvwxyz0123456789abcde01"
152 "23456789abcdefghijklmnopqrztuvwxyz0123456789abcde0123456789abcdefghi"
153 "jklmnopqrztuvwxyz")};
154 if (len == 16 || len == 32) {
155 EXPECT_THAT(AesCtrHmacAeadKeyManager().ValidateKeyFormat(key_format),
156 IsOk())
157 << "for length " << len;
158 EXPECT_THAT(
159 AesCtrHmacAeadKeyManager().DeriveKey(key_format, &input_stream),
160 IsOk());
161 } else {
162 EXPECT_THAT(AesCtrHmacAeadKeyManager().ValidateKeyFormat(key_format),
163 Not(IsOk()))
164 << "for length " << len;
165 EXPECT_THAT(
166 AesCtrHmacAeadKeyManager().DeriveKey(key_format, &input_stream),
167 Not(IsOk()));
168 }
169 }
170 }
171
TEST(AesCtrHmacAeadKeyManagerTest,ValidateKeyFormatHmacKeySizes)172 TEST(AesCtrHmacAeadKeyManagerTest, ValidateKeyFormatHmacKeySizes) {
173 AesCtrHmacAeadKeyFormat key_format = CreateValidKeyFormat();
174 for (int len = 0; len < 42; ++len) {
175 key_format.mutable_hmac_key_format()->set_key_size(len);
176 IstreamInputStream input_stream{absl::make_unique<std::stringstream>(
177 "0123456789abcde0123456789abcdefghijklmnopqrztuvwxyz0123456789abcde01"
178 "23456789abcdefghijklmnopqrztuvwxyz0123456789abcde0123456789abcdefghi"
179 "jklmnopqrztuvwxyz")};
180 if (len >= 16) {
181 EXPECT_THAT(AesCtrHmacAeadKeyManager().ValidateKeyFormat(key_format),
182 IsOk())
183 << "for length " << len;
184 EXPECT_THAT(
185 AesCtrHmacAeadKeyManager().DeriveKey(key_format, &input_stream),
186 IsOk());
187 } else {
188 EXPECT_THAT(AesCtrHmacAeadKeyManager().ValidateKeyFormat(key_format),
189 Not(IsOk()))
190 << "for length " << len;
191 EXPECT_THAT(
192 AesCtrHmacAeadKeyManager().DeriveKey(key_format, &input_stream),
193 Not(IsOk()));
194 }
195 }
196 }
197
TEST(AesCtrHmacAeadKeyManagerTest,CreateKey)198 TEST(AesCtrHmacAeadKeyManagerTest, CreateKey) {
199 AesCtrHmacAeadKeyFormat key_format = CreateValidKeyFormat();
200 StatusOr<AesCtrHmacAeadKey> key_or =
201 AesCtrHmacAeadKeyManager().CreateKey(key_format);
202 ASSERT_THAT(key_or, IsOk());
203 const AesCtrHmacAeadKey& key = key_or.value();
204 EXPECT_THAT(AesCtrHmacAeadKeyManager().ValidateKey(key),
205 IsOk());
206 EXPECT_THAT(key.aes_ctr_key().params().iv_size(),
207 Eq(key_format.aes_ctr_key_format().params().iv_size()));
208 EXPECT_THAT(key.aes_ctr_key().key_value(),
209 SizeIs(key_format.aes_ctr_key_format().key_size()));
210 EXPECT_THAT(key.hmac_key().params().hash(),
211 Eq(key_format.hmac_key_format().params().hash()));
212 EXPECT_THAT(key.hmac_key().params().tag_size(),
213 Eq(key_format.hmac_key_format().params().tag_size()));
214 EXPECT_THAT(key.hmac_key().key_value(),
215 SizeIs(key_format.hmac_key_format().key_size()));
216 }
217
TEST(AesCtrHmacAeadKeyManagerTest,CreateAead)218 TEST(AesCtrHmacAeadKeyManagerTest, CreateAead) {
219 AesCtrHmacAeadKey key = CreateValidKey();
220
221 StatusOr<std::unique_ptr<Aead>> aead_or =
222 AesCtrHmacAeadKeyManager().GetPrimitive<Aead>(key);
223 ASSERT_THAT(aead_or, IsOk());
224
225 auto direct_aes_ctr_or = subtle::AesCtrBoringSsl::New(
226 util::SecretDataFromStringView(key.aes_ctr_key().key_value()),
227 key.aes_ctr_key().params().iv_size());
228 ASSERT_THAT(direct_aes_ctr_or, IsOk());
229
230 auto direct_hmac_or = subtle::HmacBoringSsl::New(
231 util::Enums::ProtoToSubtle(key.hmac_key().params().hash()),
232 key.hmac_key().params().tag_size(),
233 util::SecretDataFromStringView(key.hmac_key().key_value()));
234 ASSERT_THAT(direct_hmac_or, IsOk());
235
236 auto direct_aead_or = subtle::EncryptThenAuthenticate::New(
237 std::move(direct_aes_ctr_or.value()), std::move(direct_hmac_or.value()),
238 key.hmac_key().params().tag_size());
239 ASSERT_THAT(direct_aead_or, IsOk());
240
241 EXPECT_THAT(EncryptThenDecrypt(*aead_or.value(), *direct_aead_or.value(),
242 "message", "aad"),
243 IsOk());
244 }
245
TEST(AesCtrHmacAeadKeyManagerTest,Derive16ByteKey)246 TEST(AesCtrHmacAeadKeyManagerTest, Derive16ByteKey) {
247 AesCtrHmacAeadKeyFormat key_format;
248 key_format.mutable_aes_ctr_key_format()->set_key_size(16);
249 key_format.mutable_aes_ctr_key_format()->mutable_params()->set_iv_size(16);
250 key_format.mutable_hmac_key_format()->set_key_size(16);
251 key_format.mutable_hmac_key_format()->mutable_params()->set_tag_size(16);
252 key_format.mutable_hmac_key_format()->mutable_params()->set_hash(
253 google::crypto::tink::SHA256);
254 key_format.mutable_hmac_key_format()->set_version(0);
255
256 IstreamInputStream input_stream{absl::make_unique<std::stringstream>(
257 "0123456789abcde_YELLOW_SUBMARINE_EXTRA")};
258
259 StatusOr<AesCtrHmacAeadKey> derived_key =
260 AesCtrHmacAeadKeyManager().DeriveKey(key_format, &input_stream);
261 ASSERT_THAT(derived_key, IsOk());
262 EXPECT_THAT(derived_key.value().aes_ctr_key().key_value(),
263 Eq("0123456789abcde_"));
264 EXPECT_THAT(derived_key.value().hmac_key().key_value(),
265 Eq("YELLOW_SUBMARINE"));
266 EXPECT_THAT(derived_key.value().hmac_key().params().hash(),
267 key_format.hmac_key_format().params().hash());
268 EXPECT_THAT(derived_key.value().hmac_key().params().tag_size(),
269 key_format.hmac_key_format().params().tag_size());
270 EXPECT_THAT(derived_key.value().aes_ctr_key().params().iv_size(),
271 Eq(key_format.aes_ctr_key_format().params().iv_size()));
272 }
273
TEST(AesCtrHmacAeadKeyManagerTest,Derive32ByteKey)274 TEST(AesCtrHmacAeadKeyManagerTest, Derive32ByteKey) {
275 AesCtrHmacAeadKeyFormat format;
276 format.mutable_aes_ctr_key_format()->set_key_size(32);
277 format.mutable_aes_ctr_key_format()->mutable_params()->set_iv_size(16);
278 format.mutable_hmac_key_format()->set_key_size(32);
279 format.mutable_hmac_key_format()->mutable_params()->set_tag_size(16);
280 format.mutable_hmac_key_format()->mutable_params()->set_hash(
281 google::crypto::tink::SHA256);
282 format.mutable_hmac_key_format()->set_version(0);
283
284 IstreamInputStream input_stream{absl::make_unique<std::stringstream>(
285 "0123456789abcde0123456789abcdef_YELLOW_SUBMARINE_YELLOW_SUBMARIN")};
286
287 StatusOr<AesCtrHmacAeadKey> derived_key =
288 AesCtrHmacAeadKeyManager().DeriveKey(format, &input_stream);
289 ASSERT_THAT(derived_key, IsOk());
290 EXPECT_THAT(derived_key.value().aes_ctr_key().key_value(),
291 Eq("0123456789abcde0123456789abcdef_"));
292 EXPECT_THAT(derived_key.value().hmac_key().key_value(),
293 Eq("YELLOW_SUBMARINE_YELLOW_SUBMARIN"));
294 }
295
TEST(AesCtrHmacAeadKeyManagerTest,DeriveKeyNotEnoughRandomnessForAesCtrKey)296 TEST(AesCtrHmacAeadKeyManagerTest, DeriveKeyNotEnoughRandomnessForAesCtrKey) {
297 AesCtrHmacAeadKeyFormat format;
298 format.mutable_aes_ctr_key_format()->set_key_size(32);
299 format.mutable_aes_ctr_key_format()->mutable_params()->set_iv_size(16);
300 format.mutable_hmac_key_format()->set_key_size(32);
301 format.mutable_hmac_key_format()->mutable_params()->set_tag_size(16);
302 format.mutable_hmac_key_format()->mutable_params()->set_hash(
303 google::crypto::tink::SHA256);
304 format.mutable_hmac_key_format()->set_version(0);
305
306 IstreamInputStream input_stream{
307 absl::make_unique<std::stringstream>("0123456789")};
308
309 ASSERT_THAT(
310 AesCtrHmacAeadKeyManager().DeriveKey(format, &input_stream).status(),
311 StatusIs(absl::StatusCode::kInvalidArgument));
312 }
313
TEST(AesCtrHmacAeadKeyManagerTest,DeriveKeyNotEnoughRandomnessForHmacKey)314 TEST(AesCtrHmacAeadKeyManagerTest, DeriveKeyNotEnoughRandomnessForHmacKey) {
315 AesCtrHmacAeadKeyFormat format;
316 format.mutable_aes_ctr_key_format()->set_key_size(16);
317 format.mutable_aes_ctr_key_format()->mutable_params()->set_iv_size(16);
318 format.mutable_hmac_key_format()->set_key_size(32);
319 format.mutable_hmac_key_format()->mutable_params()->set_tag_size(16);
320 format.mutable_hmac_key_format()->mutable_params()->set_hash(
321 google::crypto::tink::SHA256);
322 format.mutable_hmac_key_format()->set_version(0);
323
324 IstreamInputStream input_stream{
325 absl::make_unique<std::stringstream>("YELLOW_SUBMARINE")};
326
327 ASSERT_THAT(
328 AesCtrHmacAeadKeyManager().DeriveKey(format, &input_stream).status(),
329 StatusIs(absl::StatusCode::kInvalidArgument));
330 }
331
332 } // namespace
333 } // namespace tink
334 } // namespace crypto
335