xref: /aosp_15_r20/external/tink/cc/aead/aes_ctr_hmac_aead_key_manager_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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