1 // Copyright 2020 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 #include "tink/prf/aes_cmac_prf_key_manager.h"
17
18 #include <memory>
19 #include <sstream>
20 #include <string>
21
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24 #include "tink/subtle/aes_cmac_boringssl.h"
25 #include "tink/util/istream_input_stream.h"
26 #include "tink/util/status.h"
27 #include "tink/util/statusor.h"
28 #include "tink/util/test_matchers.h"
29 #include "proto/aes_cmac_prf.pb.h"
30
31 namespace crypto {
32 namespace tink {
33
34 namespace {
35
36 using ::crypto::tink::test::IsOk;
37 using ::google::crypto::tink::AesCmacPrfKey;
38 using ::google::crypto::tink::AesCmacPrfKeyFormat;
39 using ::testing::Eq;
40 using ::testing::Not;
41 using ::testing::SizeIs;
42 using ::testing::StrEq;
43
GetInputStreamForString(const std::string & input)44 std::unique_ptr<InputStream> GetInputStreamForString(const std::string& input) {
45 return absl::make_unique<util::IstreamInputStream>(
46 absl::make_unique<std::stringstream>(input));
47 }
48
ValidKeyFormat()49 AesCmacPrfKeyFormat ValidKeyFormat() {
50 AesCmacPrfKeyFormat format;
51 format.set_key_size(32);
52 return format;
53 }
54
TEST(AesCmacPrfKeyManagerTest,Basics)55 TEST(AesCmacPrfKeyManagerTest, Basics) {
56 EXPECT_THAT(AesCmacPrfKeyManager().get_version(), Eq(0));
57 EXPECT_THAT(AesCmacPrfKeyManager().get_key_type(),
58 Eq("type.googleapis.com/google.crypto.tink.AesCmacPrfKey"));
59 EXPECT_THAT(AesCmacPrfKeyManager().key_material_type(),
60 Eq(google::crypto::tink::KeyData::SYMMETRIC));
61 }
62
TEST(AesCmacPrfKeyManagerTest,ValidateEmptyKey)63 TEST(AesCmacPrfKeyManagerTest, ValidateEmptyKey) {
64 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKey(AesCmacPrfKey()), Not(IsOk()));
65 }
66
TEST(AesCmacPrfKeyManagerTest,ValidateEmptyKeyFormat)67 TEST(AesCmacPrfKeyManagerTest, ValidateEmptyKeyFormat) {
68 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKeyFormat(AesCmacPrfKeyFormat()),
69 Not(IsOk()));
70 }
71
TEST(AesCmacPrfKeyManagerTest,ValidateSimpleKeyFormat)72 TEST(AesCmacPrfKeyManagerTest, ValidateSimpleKeyFormat) {
73 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKeyFormat(ValidKeyFormat()),
74 IsOk());
75 }
76
TEST(AesCmacPrfKeyManagerTest,ValidateKeyFormatKeySizes)77 TEST(AesCmacPrfKeyManagerTest, ValidateKeyFormatKeySizes) {
78 AesCmacPrfKeyFormat format = ValidKeyFormat();
79
80 format.set_key_size(0);
81 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKeyFormat(format), Not(IsOk()));
82
83 format.set_key_size(1);
84 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKeyFormat(format), Not(IsOk()));
85
86 format.set_key_size(15);
87 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKeyFormat(format), Not(IsOk()));
88
89 format.set_key_size(16);
90 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKeyFormat(format), Not(IsOk()));
91
92 format.set_key_size(17);
93 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKeyFormat(format), Not(IsOk()));
94
95 format.set_key_size(31);
96 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKeyFormat(format), Not(IsOk()));
97
98 format.set_key_size(32);
99 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKeyFormat(format), IsOk());
100
101 format.set_key_size(33);
102 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKeyFormat(format), Not(IsOk()));
103 }
104
TEST(AesCmacPrfKeyManagerTest,CreateKey)105 TEST(AesCmacPrfKeyManagerTest, CreateKey) {
106 AesCmacPrfKeyFormat format = ValidKeyFormat();
107 ASSERT_THAT(AesCmacPrfKeyManager().CreateKey(format), IsOk());
108 AesCmacPrfKey key = AesCmacPrfKeyManager().CreateKey(format).value();
109 EXPECT_THAT(key.version(), Eq(0));
110 EXPECT_THAT(key.key_value(), SizeIs(format.key_size()));
111 }
112
TEST(AesCmacPrfKeyManagerTest,ValidateKey)113 TEST(AesCmacPrfKeyManagerTest, ValidateKey) {
114 AesCmacPrfKeyFormat format = ValidKeyFormat();
115 AesCmacPrfKey key = AesCmacPrfKeyManager().CreateKey(format).value();
116 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKey(key), IsOk());
117 }
118
TEST(AesCmacPrfKeyManagerTest,ValidateKeyInvalidVersion)119 TEST(AesCmacPrfKeyManagerTest, ValidateKeyInvalidVersion) {
120 AesCmacPrfKeyFormat format = ValidKeyFormat();
121 AesCmacPrfKey key = AesCmacPrfKeyManager().CreateKey(format).value();
122 key.set_version(1);
123 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKey(key), Not(IsOk()));
124 }
125
TEST(AesCmacPrfKeyManagerTest,ValidateKeyShortKey)126 TEST(AesCmacPrfKeyManagerTest, ValidateKeyShortKey) {
127 AesCmacPrfKeyFormat format = ValidKeyFormat();
128 AesCmacPrfKey key = AesCmacPrfKeyManager().CreateKey(format).value();
129 key.set_key_value("0123456789abcdef");
130 EXPECT_THAT(AesCmacPrfKeyManager().ValidateKey(key), Not(IsOk()));
131 }
132
TEST(AesCmacPrfKeyManagerTest,GetPrimitive)133 TEST(AesCmacPrfKeyManagerTest, GetPrimitive) {
134 AesCmacPrfKeyFormat format = ValidKeyFormat();
135 AesCmacPrfKey key = AesCmacPrfKeyManager().CreateKey(format).value();
136 auto manager_prf_or = AesCmacPrfKeyManager().GetPrimitive<Prf>(key);
137 ASSERT_THAT(manager_prf_or, IsOk());
138 auto prf_value_or = manager_prf_or.value()->Compute("some plaintext", 16);
139 ASSERT_THAT(prf_value_or, IsOk());
140
141 auto direct_prf_or = subtle::AesCmacBoringSsl::New(
142 util::SecretDataFromStringView(key.key_value()), 16);
143 ASSERT_THAT(direct_prf_or, IsOk());
144 auto direct_prf_value_or =
145 direct_prf_or.value()->ComputeMac("some plaintext");
146 ASSERT_THAT(direct_prf_value_or, IsOk());
147 EXPECT_THAT(direct_prf_value_or.value(), StrEq(prf_value_or.value()));
148 }
149
TEST(AesCmacPrfKeyManagerTest,DeriveKeyValid)150 TEST(AesCmacPrfKeyManagerTest, DeriveKeyValid) {
151 std::string bytes = "0123456789abcdef0123456789abcdef";
152 auto inputstream = GetInputStreamForString(bytes);
153 auto key_or =
154 AesCmacPrfKeyManager().DeriveKey(ValidKeyFormat(), inputstream.get());
155 ASSERT_THAT(key_or, IsOk());
156 AesCmacPrfKey key = key_or.value();
157 EXPECT_THAT(key.version(), Eq(AesCmacPrfKeyManager().get_version()));
158 EXPECT_THAT(key.key_value(), Eq(bytes));
159 }
160
TEST(AesCmacPrfKeyManagerTest,DeriveKeyNotEnoughRandomness)161 TEST(AesCmacPrfKeyManagerTest, DeriveKeyNotEnoughRandomness) {
162 std::string bytes = "0123456789abcdef";
163 auto inputstream = GetInputStreamForString(bytes);
164 auto key_or =
165 AesCmacPrfKeyManager().DeriveKey(ValidKeyFormat(), inputstream.get());
166 EXPECT_THAT(key_or, Not(IsOk()));
167 }
168
TEST(AesCmacPrfKeyManagerTest,DeriveKeyInvalidFormat)169 TEST(AesCmacPrfKeyManagerTest, DeriveKeyInvalidFormat) {
170 std::string bytes = "0123456789abcdef";
171 auto inputstream = GetInputStreamForString(bytes);
172 auto format = ValidKeyFormat();
173 format.set_key_size(12);
174 auto key_or = AesCmacPrfKeyManager().DeriveKey(format, inputstream.get());
175 EXPECT_THAT(key_or, Not(IsOk()));
176 }
177
TEST(AesCmacPrfKeyManagerTest,DeriveKeyInvalidVersion)178 TEST(AesCmacPrfKeyManagerTest, DeriveKeyInvalidVersion) {
179 auto format = ValidKeyFormat();
180 format.set_version(1);
181 std::string bytes = "0123456789abcdef0123456789abcdef";
182 auto inputstream = GetInputStreamForString(bytes);
183 auto key_or =
184 AesCmacPrfKeyManager().DeriveKey(format, inputstream.get());
185 EXPECT_THAT(key_or, Not(IsOk()));
186 }
187
188 } // namespace
189 } // namespace tink
190 } // namespace crypto
191