xref: /aosp_15_r20/external/tink/cc/keyderivation/internal/prf_based_deriver.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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/keyderivation/internal/prf_based_deriver.h"
18 
19 #include <memory>
20 #include <utility>
21 
22 #include "tink/cleartext_keyset_handle.h"
23 #include "tink/keyset_handle.h"
24 #include "tink/registry.h"
25 #include "tink/subtle/prf/streaming_prf.h"
26 #include "proto/tink.pb.h"
27 
28 namespace crypto {
29 namespace tink {
30 namespace internal {
31 
32 using ::google::crypto::tink::KeyData;
33 using ::google::crypto::tink::Keyset;
34 using ::google::crypto::tink::KeyStatusType;
35 using ::google::crypto::tink::KeyTemplate;
36 using ::google::crypto::tink::OutputPrefixType;
37 
New(const KeyData & prf_key,const KeyTemplate & key_template)38 util::StatusOr<std::unique_ptr<KeysetDeriver>> PrfBasedDeriver::New(
39     const KeyData& prf_key, const KeyTemplate& key_template) {
40   // Validate `prf_key`.
41   util::StatusOr<std::unique_ptr<StreamingPrf>> streaming_prf =
42       Registry::GetPrimitive<StreamingPrf>(prf_key);
43   if (!streaming_prf.ok()) {
44     return streaming_prf.status();
45   }
46 
47   // Validate `key_template`.
48   std::unique_ptr<InputStream> randomness = (*streaming_prf)->ComputePrf("s");
49   util::StatusOr<KeyData> key_data =
50       internal::RegistryImpl::GlobalInstance().DeriveKey(key_template,
51                                                          randomness.get());
52   if (!key_data.ok()) {
53     return key_data.status();
54   }
55 
56   return {absl::WrapUnique<PrfBasedDeriver>(
57       new PrfBasedDeriver(*std::move(streaming_prf), key_template))};
58 }
59 
DeriveKeyset(absl::string_view salt) const60 util::StatusOr<std::unique_ptr<KeysetHandle>> PrfBasedDeriver::DeriveKeyset(
61     absl::string_view salt) const {
62   std::unique_ptr<InputStream> randomness = streaming_prf_->ComputePrf(salt);
63 
64   util::StatusOr<KeyData> key_data =
65       crypto::tink::internal::RegistryImpl::GlobalInstance().DeriveKey(
66           key_template_, randomness.get());
67   if (!key_data.ok()) {
68     return key_data.status();
69   }
70 
71   // Fill in placeholder values for key ID, status, and output prefix type.
72   // These will be populated with the correct values in the keyset deriver
73   // factory. This is acceptable because the keyset as-is will never leave Tink,
74   // and the user only interacts via the keyset deriver factory.
75   Keyset::Key key;
76   *key.mutable_key_data() = *key_data;
77   key.set_status(KeyStatusType::UNKNOWN_STATUS);
78   key.set_key_id(0);
79   key.set_output_prefix_type(OutputPrefixType::UNKNOWN_PREFIX);
80 
81   Keyset keyset;
82   *keyset.add_key() = key;
83   keyset.set_primary_key_id(0);
84 
85   return CleartextKeysetHandle::GetKeysetHandle(keyset);
86 }
87 
88 }  // namespace internal
89 }  // namespace tink
90 }  // namespace crypto
91