1 // Copyright 2019 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_siv_key_manager.h"
18
19 #include <stdint.h>
20
21 #include <memory>
22 #include <string>
23
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "absl/status/status.h"
27 #include "tink/aead.h"
28 #include "tink/internal/ssl_util.h"
29 #include "tink/subtle/aead_test_util.h"
30 #include "tink/subtle/aes_gcm_siv_boringssl.h"
31 #include "tink/util/secret_data.h"
32 #include "tink/util/status.h"
33 #include "tink/util/statusor.h"
34 #include "tink/util/test_matchers.h"
35 #include "proto/aes_gcm_siv.pb.h"
36 #include "proto/tink.pb.h"
37
38 namespace crypto {
39 namespace tink {
40
41 namespace {
42
43 using ::crypto::tink::test::IsOk;
44 using ::crypto::tink::test::StatusIs;
45 using ::crypto::tink::util::StatusOr;
46 using ::google::crypto::tink::AesGcmSivKey;
47 using ::google::crypto::tink::AesGcmSivKeyFormat;
48 using ::testing::Eq;
49 using ::testing::Not;
50
TEST(AesGcmSivKeyManagerTest,Basics)51 TEST(AesGcmSivKeyManagerTest, Basics) {
52 EXPECT_THAT(AesGcmSivKeyManager().get_version(), Eq(0));
53 EXPECT_THAT(AesGcmSivKeyManager().get_key_type(),
54 Eq("type.googleapis.com/google.crypto.tink.AesGcmSivKey"));
55 EXPECT_THAT(AesGcmSivKeyManager().key_material_type(),
56 Eq(google::crypto::tink::KeyData::SYMMETRIC));
57 }
58
TEST(AesGcmSivKeyManagerTest,ValidateEmptyKey)59 TEST(AesGcmSivKeyManagerTest, ValidateEmptyKey) {
60 EXPECT_THAT(AesGcmSivKeyManager().ValidateKey(AesGcmSivKey()),
61 StatusIs(absl::StatusCode::kInvalidArgument));
62 }
63
TEST(AesGcmSivKeyManagerTest,ValidateValid16ByteKey)64 TEST(AesGcmSivKeyManagerTest, ValidateValid16ByteKey) {
65 AesGcmSivKey key;
66 key.set_version(0);
67 key.set_key_value("0123456789abcdef");
68 EXPECT_THAT(AesGcmSivKeyManager().ValidateKey(key), IsOk());
69 }
70
TEST(AesGcmSivKeyManagerTest,ValidateValid32ByteKey)71 TEST(AesGcmSivKeyManagerTest, ValidateValid32ByteKey) {
72 AesGcmSivKey key;
73 key.set_version(0);
74 key.set_key_value("01234567890123456789012345678901");
75 EXPECT_THAT(AesGcmSivKeyManager().ValidateKey(key), IsOk());
76 }
77
TEST(AesGcmSivKeyManagerTest,InvalidKeySizes17Bytes)78 TEST(AesGcmSivKeyManagerTest, InvalidKeySizes17Bytes) {
79 AesGcmSivKey key;
80 key.set_version(0);
81 key.set_key_value("0123456789abcdefg");
82 EXPECT_THAT(AesGcmSivKeyManager().ValidateKey(key),
83 StatusIs(absl::StatusCode::kInvalidArgument));
84 }
85
TEST(AesGcmSivKeyManagerTest,InvalidKeySizes24Bytes)86 TEST(AesGcmSivKeyManagerTest, InvalidKeySizes24Bytes) {
87 AesGcmSivKey key;
88 key.set_version(0);
89 key.set_key_value("01234567890123");
90 EXPECT_THAT(AesGcmSivKeyManager().ValidateKey(key),
91 StatusIs(absl::StatusCode::kInvalidArgument));
92 }
93
TEST(AesGcmSivKeyManagerTest,InvalidKeySizes31Bytes)94 TEST(AesGcmSivKeyManagerTest, InvalidKeySizes31Bytes) {
95 AesGcmSivKey key;
96 key.set_version(0);
97 key.set_key_value("0123456789012345678901234567890");
98 EXPECT_THAT(AesGcmSivKeyManager().ValidateKey(key),
99 StatusIs(absl::StatusCode::kInvalidArgument));
100 }
101
TEST(AesGcmSivKeyManagerTest,InvalidKeySizes33Bytes)102 TEST(AesGcmSivKeyManagerTest, InvalidKeySizes33Bytes) {
103 AesGcmSivKey key;
104 key.set_version(0);
105 key.set_key_value("012345678901234567890123456789012");
106 EXPECT_THAT(AesGcmSivKeyManager().ValidateKey(key),
107 StatusIs(absl::StatusCode::kInvalidArgument));
108 }
109
TEST(AesGcmSivKeyManagerTest,ValidateKeyFormat)110 TEST(AesGcmSivKeyManagerTest, ValidateKeyFormat) {
111 AesGcmSivKeyFormat format;
112
113 format.set_key_size(0);
114 EXPECT_THAT(AesGcmSivKeyManager().ValidateKeyFormat(format),
115 StatusIs(absl::StatusCode::kInvalidArgument));
116
117 format.set_key_size(1);
118 EXPECT_THAT(AesGcmSivKeyManager().ValidateKeyFormat(format),
119 StatusIs(absl::StatusCode::kInvalidArgument));
120
121 format.set_key_size(15);
122 EXPECT_THAT(AesGcmSivKeyManager().ValidateKeyFormat(format),
123 StatusIs(absl::StatusCode::kInvalidArgument));
124
125 format.set_key_size(16);
126 EXPECT_THAT(AesGcmSivKeyManager().ValidateKeyFormat(format), IsOk());
127
128 format.set_key_size(17);
129 EXPECT_THAT(AesGcmSivKeyManager().ValidateKeyFormat(format),
130 StatusIs(absl::StatusCode::kInvalidArgument));
131
132 format.set_key_size(31);
133 EXPECT_THAT(AesGcmSivKeyManager().ValidateKeyFormat(format),
134 StatusIs(absl::StatusCode::kInvalidArgument));
135
136 format.set_key_size(32);
137 EXPECT_THAT(AesGcmSivKeyManager().ValidateKeyFormat(format), IsOk());
138
139 format.set_key_size(33);
140 EXPECT_THAT(AesGcmSivKeyManager().ValidateKeyFormat(format),
141 StatusIs(absl::StatusCode::kInvalidArgument));
142 }
143
TEST(AesGcmSivKeyManagerTest,Create16ByteKey)144 TEST(AesGcmSivKeyManagerTest, Create16ByteKey) {
145 AesGcmSivKeyFormat format;
146 format.set_key_size(16);
147
148 StatusOr<AesGcmSivKey> key_or = AesGcmSivKeyManager().CreateKey(format);
149
150 ASSERT_THAT(key_or, IsOk());
151 EXPECT_THAT(key_or.value().key_value().size(), Eq(format.key_size()));
152 }
153
TEST(AesGcmSivKeyManagerTest,Create32ByteKey)154 TEST(AesGcmSivKeyManagerTest, Create32ByteKey) {
155 AesGcmSivKeyFormat format;
156 format.set_key_size(32);
157
158 StatusOr<AesGcmSivKey> key_or = AesGcmSivKeyManager().CreateKey(format);
159
160 ASSERT_THAT(key_or, IsOk());
161 EXPECT_THAT(key_or.value().key_value().size(), Eq(format.key_size()));
162 }
163
TEST(AesGcmSivKeyManagerTest,CreateAeadFailsWithOpenSsl)164 TEST(AesGcmSivKeyManagerTest, CreateAeadFailsWithOpenSsl) {
165 if (internal::IsBoringSsl()) {
166 GTEST_SKIP() << "OpenSSL-only test, skipping because Tink uses BoringSSL";
167 }
168 AesGcmSivKeyFormat format;
169 format.set_key_size(32);
170 StatusOr<AesGcmSivKey> key = AesGcmSivKeyManager().CreateKey(format);
171 ASSERT_THAT(key, IsOk());
172
173 EXPECT_THAT(AesGcmSivKeyManager().GetPrimitive<Aead>(*key).status(),
174 Not(IsOk()));
175 EXPECT_THAT(subtle::AesGcmSivBoringSsl::New(
176 util::SecretDataFromStringView(key->key_value()))
177 .status(),
178 Not(IsOk()));
179 }
180
TEST(AesGcmSivKeyManagerTest,CreateAeadSucceedsWithBoringSsl)181 TEST(AesGcmSivKeyManagerTest, CreateAeadSucceedsWithBoringSsl) {
182 if (!internal::IsBoringSsl()) {
183 GTEST_SKIP() << "AES-GCM-SIV is not supported when OpenSSL is used";
184 }
185 AesGcmSivKeyFormat format;
186 format.set_key_size(32);
187 StatusOr<AesGcmSivKey> key = AesGcmSivKeyManager().CreateKey(format);
188 ASSERT_THAT(key, IsOk());
189
190 StatusOr<std::unique_ptr<Aead>> aead =
191 AesGcmSivKeyManager().GetPrimitive<Aead>(*key);
192 ASSERT_THAT(aead, IsOk());
193
194 StatusOr<std::unique_ptr<Aead>> boring_ssl_aead =
195 subtle::AesGcmSivBoringSsl::New(
196 util::SecretDataFromStringView(key->key_value()));
197 ASSERT_THAT(boring_ssl_aead, IsOk());
198 EXPECT_THAT(EncryptThenDecrypt(**aead, **boring_ssl_aead, "message", "aad"),
199 IsOk());
200 }
201
202 } // namespace
203 } // namespace tink
204 } // namespace crypto
205