xref: /aosp_15_r20/external/tink/cc/subtle/prf/prf_set_util_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 #include "tink/subtle/prf/prf_set_util.h"
17 
18 #include <functional>
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/memory/memory.h"
27 #include "absl/status/status.h"
28 #include "absl/strings/string_view.h"
29 #include "tink/input_stream.h"
30 #include "tink/subtle/prf/streaming_prf.h"
31 #include "tink/util/istream_input_stream.h"
32 #include "tink/util/status.h"
33 #include "tink/util/test_matchers.h"
34 
35 namespace crypto {
36 namespace tink {
37 namespace subtle {
38 namespace {
39 
40 using ::crypto::tink::test::IsOk;
41 using ::testing::_;
42 using ::testing::AnyNumber;
43 using ::testing::DefaultValue;
44 using ::testing::Eq;
45 using ::testing::NiceMock;
46 using ::testing::Not;
47 using ::testing::Return;
48 using ::testing::StrEq;
49 
50 class MockPrf : public Prf {
51  public:
52   MOCK_METHOD(util::StatusOr<std::string>, Compute,
53               (absl::string_view input, size_t output_length), (const));
54 };
55 
56 class MockStatefulMac : public StatefulMac {
57  public:
58   MOCK_METHOD(util::Status, Update, (absl::string_view data), (override));
59   MOCK_METHOD(util::StatusOr<std::string>, Finalize, (), (override));
60 };
61 
62 class FakeStatefulMacFactory : public StatefulMacFactory {
63  public:
FakeStatefulMacFactory(util::Status update_status,util::StatusOr<std::string> finalize_result)64   FakeStatefulMacFactory(util::Status update_status,
65                          util::StatusOr<std::string> finalize_result)
66       : update_status_(update_status), finalize_result_(finalize_result) {}
Create() const67   util::StatusOr<std::unique_ptr<StatefulMac>> Create() const override {
68     auto mac_mock = absl::make_unique<NiceMock<MockStatefulMac>>();
69     ON_CALL(*mac_mock, Update(_)).WillByDefault(Return(update_status_));
70     ON_CALL(*mac_mock, Finalize()).WillByDefault(Return(finalize_result_));
71     std::unique_ptr<StatefulMac> result = std::move(mac_mock);
72     return std::move(result);
73   }
74 
75  private:
76   util::Status update_status_;
77   util::StatusOr<std::string> finalize_result_;
78 };
79 
80 class MockStreamingPrf : public StreamingPrf {
81  public:
82   MOCK_METHOD(std::unique_ptr<InputStream>, ComputePrf,
83               (absl::string_view input), (const));
84 };
85 
GetInputStreamForString(const std::string & input)86 std::unique_ptr<InputStream> GetInputStreamForString(const std::string& input) {
87   return absl::make_unique<util::IstreamInputStream>(
88       absl::make_unique<std::stringstream>(input));
89 }
90 
91 class PrfFromStatefulMacFactoryTest : public ::testing::Test {
92  protected:
SetUpWithResult(util::Status update_status,util::StatusOr<std::string> finalize_result)93   void SetUpWithResult(util::Status update_status,
94                        util::StatusOr<std::string> finalize_result) {
95     prf_ = CreatePrfFromStatefulMacFactory(
96         absl::make_unique<FakeStatefulMacFactory>(update_status,
97                                                   finalize_result));
98   }
prf()99   Prf* prf() { return prf_.get(); }
100 
101  private:
102   std::unique_ptr<Prf> prf_;
103 };
104 
TEST_F(PrfFromStatefulMacFactoryTest,ComputePrf)105 TEST_F(PrfFromStatefulMacFactoryTest, ComputePrf) {
106   SetUpWithResult(util::OkStatus(), std::string("mock_stateful_mac"));
107   auto output_result = prf()->Compute("test_input", 5);
108   ASSERT_TRUE(output_result.ok()) << output_result.status();
109   EXPECT_THAT(output_result.value(), StrEq("mock_"));
110 }
111 
TEST_F(PrfFromStatefulMacFactoryTest,ComputePrfUpdateFails)112 TEST_F(PrfFromStatefulMacFactoryTest, ComputePrfUpdateFails) {
113   SetUpWithResult(util::Status(absl::StatusCode::kInternal, "UpdateFailed"),
114                   std::string("mock_stateful_mac"));
115   auto output_result = prf()->Compute("test_input", 5);
116   EXPECT_FALSE(output_result.ok());
117   EXPECT_THAT(output_result.status().message(), Eq("UpdateFailed"));
118 }
119 
TEST_F(PrfFromStatefulMacFactoryTest,ComputePrfFinalizeFails)120 TEST_F(PrfFromStatefulMacFactoryTest, ComputePrfFinalizeFails) {
121   SetUpWithResult(util::OkStatus(),
122                   util::Status(absl::StatusCode::kInternal, "FinalizeFailed"));
123   auto output_result = prf()->Compute("test_input", 5);
124   EXPECT_FALSE(output_result.ok());
125   EXPECT_THAT(output_result.status().message(), Eq("FinalizeFailed"));
126 }
127 
TEST_F(PrfFromStatefulMacFactoryTest,ComputePrfTooMuchOutputRequested)128 TEST_F(PrfFromStatefulMacFactoryTest, ComputePrfTooMuchOutputRequested) {
129   SetUpWithResult(util::OkStatus(), std::string("mock_stateful_mac"));
130   auto output_result = prf()->Compute("test_input", 100);
131   EXPECT_FALSE(output_result.ok());
132 }
133 
134 class PrfFromStreamingPrfTest : public ::testing::Test {
135  protected:
SetUp()136   void SetUp() override {
137     auto streaming_prf = absl::make_unique<NiceMock<MockStreamingPrf>>();
138     DefaultValue<std::unique_ptr<InputStream>>::SetFactory(
139         [] { return GetInputStreamForString("output"); });
140     EXPECT_CALL(*streaming_prf, ComputePrf(Eq("input"))).Times(AnyNumber());
141     prf_ = CreatePrfFromStreamingPrf(std::move(streaming_prf));
142   }
prf()143   Prf* prf() { return prf_.get(); }
144 
145  private:
146   std::unique_ptr<Prf> prf_;
147 };
148 
TEST_F(PrfFromStreamingPrfTest,ComputePrfBasic)149 TEST_F(PrfFromStreamingPrfTest, ComputePrfBasic) {
150   auto output_result = prf()->Compute("input", 5);
151   ASSERT_THAT(output_result, IsOk());
152   EXPECT_THAT(output_result.value(), StrEq("outpu"));
153 }
154 
TEST_F(PrfFromStreamingPrfTest,ComputeTwice)155 TEST_F(PrfFromStreamingPrfTest, ComputeTwice) {
156   auto output_result = prf()->Compute("input", 5);
157   ASSERT_THAT(output_result, IsOk());
158   EXPECT_THAT(output_result.value(), StrEq("outpu"));
159   output_result = prf()->Compute("input", 5);
160   ASSERT_THAT(output_result, IsOk());
161   EXPECT_THAT(output_result.value(), StrEq("outpu"));
162 }
163 
TEST_F(PrfFromStreamingPrfTest,ComputeSubstring)164 TEST_F(PrfFromStreamingPrfTest, ComputeSubstring) {
165   auto output_result = prf()->Compute("input", 5);
166   ASSERT_THAT(output_result, IsOk());
167   EXPECT_THAT(output_result.value(), StrEq("outpu"));
168   output_result = prf()->Compute("input", 6);
169   ASSERT_THAT(output_result, IsOk());
170   EXPECT_THAT(output_result.value(), StrEq("output"));
171   output_result = prf()->Compute("input", 2);
172   ASSERT_THAT(output_result, IsOk());
173   EXPECT_THAT(output_result.value(), StrEq("ou"));
174 }
175 
TEST_F(PrfFromStreamingPrfTest,ComputeTooMuch)176 TEST_F(PrfFromStreamingPrfTest, ComputeTooMuch) {
177   auto output_result = prf()->Compute("input", 5);
178   ASSERT_THAT(output_result, IsOk());
179   EXPECT_THAT(output_result.value(), StrEq("outpu"));
180   output_result = prf()->Compute("input", 100);
181   EXPECT_THAT(output_result, Not(IsOk()))
182       << "Output should not be okay, too much output requested";
183 }
184 
185 }  // namespace
186 }  // namespace subtle
187 }  // namespace tink
188 }  // namespace crypto
189