xref: /aosp_15_r20/external/tink/cc/subtle/stateful_cmac_boringssl_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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 
17 #include "tink/subtle/stateful_cmac_boringssl.h"
18 
19 #include <cstddef>
20 #include <memory>
21 #include <string>
22 #include <vector>
23 
24 #include "gmock/gmock.h"
25 #include "gtest/gtest.h"
26 #include "absl/memory/memory.h"
27 #include "absl/status/status.h"
28 #include "absl/strings/escaping.h"
29 #include "absl/strings/string_view.h"
30 #include "tink/subtle/common_enums.h"
31 #include "tink/subtle/mac/stateful_mac.h"
32 #include "tink/subtle/wycheproof_util.h"
33 #include "tink/util/secret_data.h"
34 #include "tink/util/status.h"
35 #include "tink/util/statusor.h"
36 #include "tink/util/test_matchers.h"
37 
38 namespace crypto {
39 namespace tink {
40 namespace subtle {
41 namespace {
42 
43 constexpr size_t kTagSize = 16;
44 constexpr size_t kSmallTagSize = 10;
45 
46 constexpr absl::string_view kKeyHex = "000102030405060708090a0b0c0d0e0f";
47 constexpr absl::string_view kData = "Some data to test.";
48 constexpr absl::string_view kCmacOnEmptyInputRegularTagSizeHex =
49     "97dd6e5a882cbd564c39ae7d1c5a31aa";
50 constexpr absl::string_view kCmacOnEmptyInputSmallTagSizeHex =
51     "97dd6e5a882cbd564c39";
52 constexpr absl::string_view kCmacOnDataRegularTagSizeHex =
53     "c856e183e8dee9bb99402d54c34f3222";
54 constexpr absl::string_view kCmacOnDataSmallTagSizeHex = "c856e183e8dee9bb9940";
55 
56 using ::crypto::tink::test::IsOk;
57 using ::crypto::tink::test::IsOkAndHolds;
58 using ::testing::Not;
59 using ::testing::TestWithParam;
60 using ::testing::ValuesIn;
61 
TEST(StatefulCmacBoringSslTest,CmacEmptyInputRegularTagSize)62 TEST(StatefulCmacBoringSslTest, CmacEmptyInputRegularTagSize) {
63   util::SecretData key =
64       util::SecretDataFromStringView(absl::HexStringToBytes(kKeyHex));
65   util::StatusOr<std::unique_ptr<StatefulMac>> cmac =
66       StatefulCmacBoringSsl::New(kTagSize, key);
67   ASSERT_THAT(cmac, IsOk());
68   EXPECT_THAT(
69       (*cmac)->Finalize(),
70       IsOkAndHolds(absl::HexStringToBytes(kCmacOnEmptyInputRegularTagSizeHex)));
71 }
72 
TEST(StatefulCmacBoringSslTest,CmacEmptyInputSmallTag)73 TEST(StatefulCmacBoringSslTest, CmacEmptyInputSmallTag) {
74   util::SecretData key =
75       util::SecretDataFromStringView(absl::HexStringToBytes(kKeyHex));
76   util::StatusOr<std::unique_ptr<StatefulMac>> cmac =
77       StatefulCmacBoringSsl::New(kSmallTagSize, key);
78   ASSERT_THAT(cmac, IsOk());
79   EXPECT_THAT(
80       (*cmac)->Finalize(),
81       IsOkAndHolds(absl::HexStringToBytes(kCmacOnEmptyInputSmallTagSizeHex)));
82 }
83 
TEST(StatefulCmacBoringSslTest,CmacSomeDataRegularTagSize)84 TEST(StatefulCmacBoringSslTest, CmacSomeDataRegularTagSize) {
85   util::SecretData key =
86       util::SecretDataFromStringView(absl::HexStringToBytes(kKeyHex));
87   util::StatusOr<std::unique_ptr<StatefulMac>> cmac =
88       StatefulCmacBoringSsl::New(kTagSize, key);
89   ASSERT_THAT(cmac, IsOk());
90   EXPECT_THAT((*cmac)->Update(kData), IsOk());
91   EXPECT_THAT(
92       (*cmac)->Finalize(),
93       IsOkAndHolds(absl::HexStringToBytes(kCmacOnDataRegularTagSizeHex)));
94 }
95 
TEST(StatefulCmacBoringSslTest,CmacSomeDataSmallTag)96 TEST(StatefulCmacBoringSslTest, CmacSomeDataSmallTag) {
97   util::SecretData key =
98       util::SecretDataFromStringView(absl::HexStringToBytes(kKeyHex));
99   util::StatusOr<std::unique_ptr<StatefulMac>> cmac =
100       StatefulCmacBoringSsl::New(kSmallTagSize, key);
101   ASSERT_THAT(cmac, IsOk());
102   EXPECT_THAT((*cmac)->Update(kData), IsOk());
103   EXPECT_THAT((*cmac)->Finalize(),
104               IsOkAndHolds(absl::HexStringToBytes(kCmacOnDataSmallTagSizeHex)));
105 }
106 
TEST(StatefulCmacBoringSslTest,CmacMultipleUpdatesSameAsOneForWholeInputRegularTagSize)107 TEST(StatefulCmacBoringSslTest,
108      CmacMultipleUpdatesSameAsOneForWholeInputRegularTagSize) {
109   util::SecretData key =
110       util::SecretDataFromStringView(absl::HexStringToBytes(kKeyHex));
111   util::StatusOr<std::unique_ptr<StatefulMac>> cmac =
112       StatefulCmacBoringSsl::New(kTagSize, key);
113   ASSERT_THAT(cmac, IsOk());
114   for (const std::string &token : {"Some ", "data ", "to ", "test."}) {
115     EXPECT_THAT((*cmac)->Update(token), IsOk());
116   }
117   EXPECT_THAT(
118       (*cmac)->Finalize(),
119       IsOkAndHolds(absl::HexStringToBytes(kCmacOnDataRegularTagSizeHex)));
120 }
121 
TEST(StatefulCmacBoringSslTest,CmacMultipleUpdatesSameAsOneForWholeInputSmallTagSize)122 TEST(StatefulCmacBoringSslTest,
123      CmacMultipleUpdatesSameAsOneForWholeInputSmallTagSize) {
124   util::SecretData key =
125       util::SecretDataFromStringView(absl::HexStringToBytes(kKeyHex));
126   util::StatusOr<std::unique_ptr<StatefulMac>> cmac =
127       StatefulCmacBoringSsl::New(kSmallTagSize, key);
128   ASSERT_THAT(cmac, IsOk());
129   for (const std::string &token : {"Some ", "data ", "to ", "test."}) {
130     EXPECT_THAT((*cmac)->Update(token), IsOk());
131   }
132   EXPECT_THAT((*cmac)->Finalize(),
133               IsOkAndHolds(absl::HexStringToBytes(kCmacOnDataSmallTagSizeHex)));
134 }
135 
TEST(StatefulCmacFactoryTest,FactoryGeneratesValidInstances)136 TEST(StatefulCmacFactoryTest, FactoryGeneratesValidInstances) {
137   auto factory = absl::make_unique<StatefulCmacBoringSslFactory>(
138       kTagSize,
139       util::SecretDataFromStringView(absl::HexStringToBytes(kKeyHex)));
140   util::StatusOr<std::unique_ptr<StatefulMac>> cmac = factory->Create();
141   ASSERT_THAT(cmac, IsOk());
142   EXPECT_THAT((*cmac)->Update(kData), IsOk());
143   EXPECT_THAT(
144       (*cmac)->Finalize(),
145       IsOkAndHolds(absl::HexStringToBytes(kCmacOnDataRegularTagSizeHex)));
146 }
147 
148 struct StatefulCmacTestVector {
149   std::string key;
150   std::string msg;
151   std::string tag;
152   std::string id;
153   std::string expected_result;
154 };
155 
156 // Reads the Wycheproof test vectors for AES-CMAC.
GetWycheproofCmakeTestVectors()157 std::vector<StatefulCmacTestVector> GetWycheproofCmakeTestVectors() {
158   std::unique_ptr<rapidjson::Document> root =
159       WycheproofUtil::ReadTestVectors("aes_cmac_test.json");
160   std::vector<StatefulCmacTestVector> test_vectors;
161   for (const rapidjson::Value &test_group : (*root)["testGroups"].GetArray()) {
162     // Ignore test vectors of invalid key sizes; valid sizes are {16, 32} bytes.
163     int key_size_bits = test_group["keySize"].GetInt();
164     if (key_size_bits != 128 && key_size_bits != 256) {
165       continue;
166     }
167     for (const rapidjson::Value &test : test_group["tests"].GetArray()) {
168       test_vectors.push_back({
169           /*key=*/WycheproofUtil::GetBytes(test["key"]),
170           /*msg=*/WycheproofUtil::GetBytes(test["msg"]),
171           /*tag=*/WycheproofUtil::GetBytes(test["tag"]),
172           /*id=*/absl::StrCat(test["tcId"].GetInt()),
173           /*expected_result=*/test["result"].GetString(),
174       });
175     }
176   }
177   return test_vectors;
178 }
179 
180 using StatefulCmacBoringSslWycheproofTest =
181     TestWithParam<StatefulCmacTestVector>;
182 
TEST_P(StatefulCmacBoringSslWycheproofTest,WycheproofTest)183 TEST_P(StatefulCmacBoringSslWycheproofTest, WycheproofTest) {
184   StatefulCmacTestVector test_vector = GetParam();
185 
186   util::SecretData key =
187       util::SecretDataFromStringView(absl::HexStringToBytes(kKeyHex));
188   util::StatusOr<std::unique_ptr<StatefulMac>> cmac =
189       StatefulCmacBoringSsl::New(
190           test_vector.tag.length(),
191           util::SecretDataFromStringView(test_vector.key));
192   ASSERT_THAT(cmac, IsOk());
193   EXPECT_THAT((*cmac)->Update(test_vector.msg), IsOk());
194 
195   if (test_vector.expected_result == "invalid") {
196     EXPECT_THAT((*cmac)->Finalize(), Not(IsOkAndHolds(test_vector.tag)));
197   } else {
198     EXPECT_THAT((*cmac)->Finalize(), IsOkAndHolds(test_vector.tag));
199   }
200 }
201 
202 INSTANTIATE_TEST_SUITE_P(StatefulCmacBoringSslWycheproofTest,
203                          StatefulCmacBoringSslWycheproofTest,
204                          ValuesIn(GetWycheproofCmakeTestVectors()));
205 
206 }  // namespace
207 }  // namespace subtle
208 }  // namespace tink
209 }  // namespace crypto
210