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/prf/hkdf_prf_key_manager.h"
18
19 #include <memory>
20 #include <sstream>
21 #include <string>
22 #include <utility>
23
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "absl/status/status.h"
27 #include "tink/subtle/common_enums.h"
28 #include "tink/subtle/prf/hkdf_streaming_prf.h"
29 #include "tink/subtle/prf/prf_set_util.h"
30 #include "tink/util/input_stream_util.h"
31 #include "tink/util/istream_input_stream.h"
32 #include "tink/util/secret_data.h"
33 #include "tink/util/test_matchers.h"
34 #include "proto/common.pb.h"
35
36 namespace crypto {
37 namespace tink {
38
39 namespace {
40
41 using ::crypto::tink::test::IsOk;
42 using ::crypto::tink::test::StatusIs;
43 using ::crypto::tink::util::StatusOr;
44 using ::google::crypto::tink::HkdfPrfKey;
45 using ::google::crypto::tink::HkdfPrfKeyFormat;
46 using ::testing::Eq;
47 using ::testing::HasSubstr;
48 using ::testing::Not;
49 using ::testing::SizeIs;
50
TEST(HkdfPrfKeyManagerTest,Basics)51 TEST(HkdfPrfKeyManagerTest, Basics) {
52 EXPECT_THAT(HkdfPrfKeyManager().get_version(), Eq(0));
53 EXPECT_THAT(HkdfPrfKeyManager().get_key_type(),
54 Eq("type.googleapis.com/google.crypto.tink.HkdfPrfKey"));
55 EXPECT_THAT(HkdfPrfKeyManager().key_material_type(),
56 Eq(google::crypto::tink::KeyData::SYMMETRIC));
57 }
58
TEST(HkdfPrfKeyManagerTest,ValidateEmptyKey)59 TEST(HkdfPrfKeyManagerTest, ValidateEmptyKey) {
60 EXPECT_THAT(HkdfPrfKeyManager().ValidateKey(HkdfPrfKey()),
61 StatusIs(absl::StatusCode::kInvalidArgument));
62 }
63
TEST(HkdfPrfKeyManagerTest,ValidateValid32ByteKey)64 TEST(HkdfPrfKeyManagerTest, ValidateValid32ByteKey) {
65 HkdfPrfKey key;
66 key.set_version(0);
67 key.set_key_value("01234567890123456789012345678901");
68 key.mutable_params()->set_hash(::google::crypto::tink::SHA256);
69 EXPECT_THAT(HkdfPrfKeyManager().ValidateKey(key), IsOk());
70 }
71
TEST(HkdfPrfKeyManagerTest,ValidateValidSha512Key)72 TEST(HkdfPrfKeyManagerTest, ValidateValidSha512Key) {
73 HkdfPrfKey key;
74 key.set_version(0);
75 key.set_key_value("01234567890123456789012345678901");
76 key.mutable_params()->set_hash(::google::crypto::tink::SHA512);
77 EXPECT_THAT(HkdfPrfKeyManager().ValidateKey(key), IsOk());
78 }
79
TEST(HkdfPrfKeyManagerTest,ValidateValid33ByteKey)80 TEST(HkdfPrfKeyManagerTest, ValidateValid33ByteKey) {
81 HkdfPrfKey key;
82 key.set_version(0);
83 key.set_key_value("012345678901234567890123456789012");
84 key.mutable_params()->set_hash(::google::crypto::tink::SHA256);
85 EXPECT_THAT(HkdfPrfKeyManager().ValidateKey(key), IsOk());
86 }
87
TEST(HkdfPrfKeyManagerTest,ValidateValidKeyWithSalt)88 TEST(HkdfPrfKeyManagerTest, ValidateValidKeyWithSalt) {
89 HkdfPrfKey key;
90 key.set_version(0);
91 key.set_key_value("01234567890123456789012345678901");
92 key.mutable_params()->set_hash(::google::crypto::tink::SHA256);
93 key.mutable_params()->set_salt("12345");
94 EXPECT_THAT(HkdfPrfKeyManager().ValidateKey(key), IsOk());
95 }
96
TEST(HkdfPrfKeyManagerTest,InvalidKeySizes31Bytes)97 TEST(HkdfPrfKeyManagerTest, InvalidKeySizes31Bytes) {
98 HkdfPrfKey key;
99 key.set_version(0);
100 key.set_key_value("0123456789012345678901234567890");
101 EXPECT_THAT(HkdfPrfKeyManager().ValidateKey(key),
102 StatusIs(absl::StatusCode::kInvalidArgument));
103 }
104
TEST(HkdfPrfKeyManagerTest,InvalidKeySha1)105 TEST(HkdfPrfKeyManagerTest, InvalidKeySha1) {
106 HkdfPrfKey key;
107 key.set_version(0);
108 key.set_key_value("01234567890123456789012345678901");
109 key.mutable_params()->set_hash(::google::crypto::tink::SHA1);
110 EXPECT_THAT(HkdfPrfKeyManager().ValidateKey(key),
111 StatusIs(absl::StatusCode::kInvalidArgument));
112 }
113
TEST(HkdfPrfKeyManagerTest,InvalidKeyVersion)114 TEST(HkdfPrfKeyManagerTest, InvalidKeyVersion) {
115 HkdfPrfKey key;
116 key.set_version(1);
117 key.set_key_value("01234567890123456789012345678901");
118 key.mutable_params()->set_hash(::google::crypto::tink::SHA256);
119 EXPECT_THAT(HkdfPrfKeyManager().ValidateKey(key),
120 StatusIs(absl::StatusCode::kInvalidArgument));
121 }
122
TEST(HkdfPrfKeyManagerTest,ValidateEmptyKeyFormat)123 TEST(HkdfPrfKeyManagerTest, ValidateEmptyKeyFormat) {
124 EXPECT_THAT(HkdfPrfKeyManager().ValidateKeyFormat(HkdfPrfKeyFormat()),
125 StatusIs(absl::StatusCode::kInvalidArgument));
126 }
127
TEST(HkdfPrfKeyManagerTest,ValidateValid32ByteKeyFormat)128 TEST(HkdfPrfKeyManagerTest, ValidateValid32ByteKeyFormat) {
129 HkdfPrfKeyFormat key_format;
130 key_format.set_key_size(32);
131 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA256);
132 EXPECT_THAT(HkdfPrfKeyManager().ValidateKeyFormat(key_format), IsOk());
133 }
134
TEST(HkdfPrfKeyManagerTest,ValidateValidSha512KeyFormat)135 TEST(HkdfPrfKeyManagerTest, ValidateValidSha512KeyFormat) {
136 HkdfPrfKeyFormat key_format;
137 key_format.set_key_size(32);
138 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA512);
139 EXPECT_THAT(HkdfPrfKeyManager().ValidateKeyFormat(key_format), IsOk());
140 }
141
TEST(HkdfPrfKeyManagerTest,ValidateValid33ByteKeyFormat)142 TEST(HkdfPrfKeyManagerTest, ValidateValid33ByteKeyFormat) {
143 HkdfPrfKeyFormat key_format;
144 key_format.set_key_size(33);
145 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA256);
146 EXPECT_THAT(HkdfPrfKeyManager().ValidateKeyFormat(key_format), IsOk());
147 }
148
TEST(HkdfPrfKeyManagerTest,ValidateValidKeyFormatWithSalt)149 TEST(HkdfPrfKeyManagerTest, ValidateValidKeyFormatWithSalt) {
150 HkdfPrfKeyFormat key_format;
151 key_format.set_key_size(32);
152 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA256);
153 key_format.mutable_params()->set_salt("abcdef");
154 EXPECT_THAT(HkdfPrfKeyManager().ValidateKeyFormat(key_format), IsOk());
155 }
156
TEST(HkdfPrfKeyManagerTest,InvalidKeyFormatSha1)157 TEST(HkdfPrfKeyManagerTest, InvalidKeyFormatSha1) {
158 HkdfPrfKeyFormat key_format;
159 key_format.set_key_size(32);
160 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA1);
161 EXPECT_THAT(HkdfPrfKeyManager().ValidateKeyFormat(key_format),
162 StatusIs(absl::StatusCode::kInvalidArgument));
163 }
164
TEST(HkdfPrfKeyManagerTest,ValidateInvalid31ByteKeyFormat)165 TEST(HkdfPrfKeyManagerTest, ValidateInvalid31ByteKeyFormat) {
166 HkdfPrfKeyFormat key_format;
167 key_format.set_key_size(31);
168 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA256);
169 EXPECT_THAT(HkdfPrfKeyManager().ValidateKeyFormat(key_format),
170 StatusIs(absl::StatusCode::kInvalidArgument));
171 }
172
TEST(HkdfPrfKeyManagerTest,CreateKey)173 TEST(HkdfPrfKeyManagerTest, CreateKey) {
174 HkdfPrfKeyFormat key_format;
175 key_format.set_key_size(32);
176 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA256);
177 auto key_or = HkdfPrfKeyManager().CreateKey(key_format);
178 ASSERT_THAT(key_or, IsOk());
179 EXPECT_THAT(key_or.value().key_value(), SizeIs(32));
180 EXPECT_THAT(key_or.value().params().hash(),
181 Eq(::google::crypto::tink::SHA256));
182 EXPECT_THAT(key_or.value().params().salt(), Eq(""));
183 EXPECT_THAT(key_or.value().version(), Eq(0));
184 }
185
TEST(HkdfPrfKeyManagerTest,CreateKeyDifferetSize)186 TEST(HkdfPrfKeyManagerTest, CreateKeyDifferetSize) {
187 HkdfPrfKeyFormat key_format;
188 key_format.set_key_size(77);
189 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA256);
190 auto key_or = HkdfPrfKeyManager().CreateKey(key_format);
191 ASSERT_THAT(key_or, IsOk());
192 EXPECT_THAT(key_or.value().key_value(), SizeIs(77));
193 }
194
TEST(HkdfPrfKeyManagerTest,CreateKeyDifferetHash)195 TEST(HkdfPrfKeyManagerTest, CreateKeyDifferetHash) {
196 HkdfPrfKeyFormat key_format;
197 key_format.set_key_size(32);
198 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA512);
199 auto key_or = HkdfPrfKeyManager().CreateKey(key_format);
200 ASSERT_THAT(key_or, IsOk());
201 EXPECT_THAT(key_or.value().params().hash(),
202 Eq(::google::crypto::tink::SHA512));
203 }
204
TEST(HkdfPrfKeyManagerTest,CreateKeyDifferetSalt)205 TEST(HkdfPrfKeyManagerTest, CreateKeyDifferetSalt) {
206 HkdfPrfKeyFormat key_format;
207 key_format.set_key_size(32);
208 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA512);
209 key_format.mutable_params()->set_salt("saltstring");
210 auto key_or = HkdfPrfKeyManager().CreateKey(key_format);
211 ASSERT_THAT(key_or, IsOk());
212 EXPECT_THAT(key_or.value().params().salt(), Eq("saltstring"));
213 }
214
TEST(HkdfPrfKeyManagerTest,CreatePrf)215 TEST(HkdfPrfKeyManagerTest, CreatePrf) {
216 HkdfPrfKeyFormat key_format;
217 key_format.set_key_size(32);
218 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA256);
219 key_format.mutable_params()->set_salt("salt string");
220 auto key_or = HkdfPrfKeyManager().CreateKey(key_format);
221 ASSERT_THAT(key_or, IsOk());
222
223 StatusOr<std::unique_ptr<StreamingPrf>> prf_or =
224 HkdfPrfKeyManager().GetPrimitive<StreamingPrf>(key_or.value());
225
226 ASSERT_THAT(prf_or, IsOk());
227
228 StatusOr<std::unique_ptr<StreamingPrf>> direct_prf =
229 subtle::HkdfStreamingPrf::New(
230 subtle::SHA256,
231 util::SecretDataFromStringView(key_or.value().key_value()),
232 "salt string");
233
234 ASSERT_THAT(direct_prf, IsOk());
235
236 std::unique_ptr<InputStream> input =
237 prf_or.value()->ComputePrf("input string");
238 std::unique_ptr<InputStream> direct_input =
239 direct_prf.value()->ComputePrf("input string");
240
241 auto output_or = ReadBytesFromStream(100, input.get());
242 auto direct_output_or = ReadBytesFromStream(100, direct_input.get());
243
244 ASSERT_THAT(output_or, IsOk());
245 ASSERT_THAT(direct_output_or, IsOk());
246 EXPECT_THAT(output_or.value(), Eq(direct_output_or.value()));
247 }
248
TEST(HkdfPrfKeyManagerTest,DeriveKey)249 TEST(HkdfPrfKeyManagerTest, DeriveKey) {
250 HkdfPrfKeyFormat format;
251 format.set_key_size(32);
252 format.set_version(0);
253 format.mutable_params()->set_hash(::google::crypto::tink::SHA256);
254
255 util::IstreamInputStream input_stream{
256 absl::make_unique<std::stringstream>("0123456789abcdef0123456789abcdef")};
257
258 StatusOr<HkdfPrfKey> key_or =
259 HkdfPrfKeyManager().DeriveKey(format, &input_stream);
260 ASSERT_THAT(key_or, IsOk());
261 EXPECT_THAT(key_or.value().key_value(),
262 Eq("0123456789abcdef0123456789abcdef"));
263 EXPECT_THAT(key_or.value().params().hash(), Eq(format.params().hash()));
264 }
265
TEST(HmacPrfKeyManagerTest,DeriveKeyNotEnoughRandomness)266 TEST(HmacPrfKeyManagerTest, DeriveKeyNotEnoughRandomness) {
267 HkdfPrfKeyFormat format;
268 format.set_key_size(32);
269 format.set_version(0);
270 format.mutable_params()->set_hash(::google::crypto::tink::SHA256);
271
272 util::IstreamInputStream input_stream{
273 absl::make_unique<std::stringstream>("0123456789abcdef")};
274
275 ASSERT_THAT(HkdfPrfKeyManager().DeriveKey(format, &input_stream).status(),
276 Not(IsOk()));
277 }
278
TEST(HmacPrfKeyManagerTest,DeriveKeyWrongVersion)279 TEST(HmacPrfKeyManagerTest, DeriveKeyWrongVersion) {
280 HkdfPrfKeyFormat format;
281 format.set_key_size(32);
282 format.set_version(1);
283 format.mutable_params()->set_hash(::google::crypto::tink::SHA256);
284
285 util::IstreamInputStream input_stream{
286 absl::make_unique<std::stringstream>("0123456789abcdef0123456789abcdef")};
287
288 ASSERT_THAT(
289 HkdfPrfKeyManager().DeriveKey(format, &input_stream).status(),
290 StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("version")));
291 }
292
TEST(HkdfPrfKeyManagerTest,CreatePrfSet)293 TEST(HkdfPrfKeyManagerTest, CreatePrfSet) {
294 HkdfPrfKeyFormat key_format;
295 key_format.set_key_size(32);
296 key_format.mutable_params()->set_hash(::google::crypto::tink::SHA256);
297 key_format.mutable_params()->set_salt("salt string");
298 auto key_or = HkdfPrfKeyManager().CreateKey(key_format);
299 ASSERT_THAT(key_or, IsOk());
300
301 StatusOr<std::unique_ptr<Prf>> prf_or =
302 HkdfPrfKeyManager().GetPrimitive<Prf>(key_or.value());
303
304 ASSERT_THAT(prf_or, IsOk());
305
306 StatusOr<std::unique_ptr<StreamingPrf>> direct_streaming_prf =
307 subtle::HkdfStreamingPrf::New(
308 subtle::SHA256,
309 util::SecretDataFromStringView(key_or.value().key_value()),
310 "salt string");
311
312 ASSERT_THAT(direct_streaming_prf, IsOk());
313 auto direct_prf = subtle::CreatePrfFromStreamingPrf(
314 std::move(direct_streaming_prf.value()));
315
316 util::StatusOr<std::string> output_or =
317 prf_or.value()->Compute("input string", 100);
318 util::StatusOr<std::string> direct_output_or =
319 direct_prf->Compute("input string", 100);
320
321 ASSERT_THAT(output_or, IsOk());
322 ASSERT_THAT(direct_output_or, IsOk());
323 EXPECT_THAT(output_or.value(), Eq(direct_output_or.value()));
324 }
325
326 } // namespace
327 } // namespace tink
328 } // namespace crypto
329