xref: /aosp_15_r20/external/tink/cc/subtle/prf/prf_set_util.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 <memory>
19 #include <string>
20 #include <utility>
21 
22 #include "absl/memory/memory.h"
23 #include "absl/status/status.h"
24 #include "absl/strings/str_cat.h"
25 #include "tink/subtle/mac/stateful_mac.h"
26 #include "tink/util/input_stream_util.h"
27 #include "tink/util/status.h"
28 #include "tink/util/statusor.h"
29 
30 namespace crypto {
31 namespace tink {
32 namespace subtle {
33 namespace {
34 
35 class PrfFromStreamingPrf : public Prf {
36  public:
PrfFromStreamingPrf(std::unique_ptr<StreamingPrf> streaming_prf)37   explicit PrfFromStreamingPrf(std::unique_ptr<StreamingPrf> streaming_prf)
38       : streaming_prf_(std::move(streaming_prf)) {}
Compute(absl::string_view input,size_t output_length) const39   util::StatusOr<std::string> Compute(absl::string_view input,
40                                       size_t output_length) const override {
41     auto inputstream = streaming_prf_->ComputePrf(input);
42     auto output_result = ReadBytesFromStream(output_length, inputstream.get());
43     if (!output_result.ok()) {
44       return output_result.status();
45     }
46     std::string output = output_result.value();
47     return output;
48   }
49 
50  private:
51   std::unique_ptr<StreamingPrf> streaming_prf_;
52 };
53 
54 class PrfFromStatefulMacFactory : public Prf {
55  public:
PrfFromStatefulMacFactory(std::unique_ptr<StatefulMacFactory> stateful_mac_factory)56   explicit PrfFromStatefulMacFactory(
57       std::unique_ptr<StatefulMacFactory> stateful_mac_factory)
58       : stateful_mac_factory_(std::move(stateful_mac_factory)) {}
Compute(absl::string_view input,size_t output_length) const59   util::StatusOr<std::string> Compute(absl::string_view input,
60                                       size_t output_length) const override {
61     auto stateful_mac_result = stateful_mac_factory_->Create();
62     if (!stateful_mac_result.ok()) {
63       return stateful_mac_result.status();
64     }
65     auto stateful_mac = std::move(stateful_mac_result.value());
66     auto status = stateful_mac->Update(input);
67     if (!status.ok()) {
68       return status;
69     }
70     auto output_result = stateful_mac->Finalize();
71     if (!output_result.ok()) {
72       return output_result.status();
73     }
74     std::string output = std::move(output_result.value());
75     if (output.size() < output_length) {
76       return util::Status(
77           absl::StatusCode::kInvalidArgument,
78           absl::StrCat("PRF only supports outputs up to ", output.size(),
79                        " bytes, but ", output_length, " bytes were requested"));
80     }
81     return output.substr(0, output_length);
82   }
83 
84  private:
85   std::unique_ptr<StatefulMacFactory> stateful_mac_factory_;
86 };
87 
88 }  // namespace
89 
CreatePrfFromStreamingPrf(std::unique_ptr<StreamingPrf> streaming_prf)90 std::unique_ptr<Prf> CreatePrfFromStreamingPrf(
91     std::unique_ptr<StreamingPrf> streaming_prf) {
92   return absl::make_unique<PrfFromStreamingPrf>(std::move(streaming_prf));
93 }
94 
CreatePrfFromStatefulMacFactory(std::unique_ptr<StatefulMacFactory> stateful_mac_factory)95 std::unique_ptr<Prf> CreatePrfFromStatefulMacFactory(
96     std::unique_ptr<StatefulMacFactory> stateful_mac_factory) {
97   return absl::make_unique<PrfFromStatefulMacFactory>(
98       std::move(stateful_mac_factory));
99 }
100 
101 }  // namespace subtle
102 }  // namespace tink
103 }  // namespace crypto
104