xref: /aosp_15_r20/external/tink/cc/keyderivation/internal/prf_based_deriver_key_manager.h (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 #ifndef TINK_KEYDERIVATION_INTERNAL_PRF_BASED_DERIVER_KEY_MANAGER_H_
18 #define TINK_KEYDERIVATION_INTERNAL_PRF_BASED_DERIVER_KEY_MANAGER_H_
19 
20 #include <memory>
21 #include <string>
22 #include <utility>
23 
24 #include "absl/memory/memory.h"
25 #include "absl/status/status.h"
26 #include "absl/strings/str_cat.h"
27 #include "tink/keyderivation/internal/prf_based_deriver.h"
28 #include "tink/keyderivation/keyset_deriver.h"
29 #include "proto/prf_based_deriver.pb.h"
30 #include "proto/tink.pb.h"
31 
32 namespace crypto {
33 namespace tink {
34 namespace internal {
35 
36 class PrfBasedDeriverKeyManager
37     : public KeyTypeManager<google::crypto::tink::PrfBasedDeriverKey,
38                             google::crypto::tink::PrfBasedDeriverKeyFormat,
39                             List<KeysetDeriver>> {
40  public:
41   class KeysetDeriverFactory : public PrimitiveFactory<KeysetDeriver> {
Create(const google::crypto::tink::PrfBasedDeriverKey & key)42     crypto::tink::util::StatusOr<std::unique_ptr<KeysetDeriver>> Create(
43         const google::crypto::tink::PrfBasedDeriverKey& key) const override {
44       return internal::PrfBasedDeriver::New(
45           key.prf_key(), key.params().derived_key_template());
46     }
47   };
48 
PrfBasedDeriverKeyManager()49   PrfBasedDeriverKeyManager()
50       : KeyTypeManager(absl::make_unique<
51                        PrfBasedDeriverKeyManager::KeysetDeriverFactory>()) {}
52 
53   // Returns the version of this key manager.
get_version()54   uint32_t get_version() const override { return 0; }
55 
key_material_type()56   google::crypto::tink::KeyData::KeyMaterialType key_material_type()
57       const override {
58     return google::crypto::tink::KeyData::SYMMETRIC;
59   }
60 
get_key_type()61   const std::string& get_key_type() const override { return key_type_; }
62 
ValidateKey(const google::crypto::tink::PrfBasedDeriverKey & key)63   crypto::tink::util::Status ValidateKey(
64       const google::crypto::tink::PrfBasedDeriverKey& key) const override {
65     crypto::tink::util::Status status =
66         ValidateVersion(key.version(), get_version());
67     if (!status.ok()) return status;
68     if (!key.has_prf_key()) {
69       return crypto::tink::util::Status(absl::StatusCode::kInvalidArgument,
70                                         "key.prf_key() must be set");
71     }
72     if (!key.params().has_derived_key_template()) {
73       return crypto::tink::util::Status(
74           absl::StatusCode::kInvalidArgument,
75           "key.params().derived_key_template() must be set");
76     }
77     return util::OkStatus();
78   }
79 
ValidateKeyFormat(const google::crypto::tink::PrfBasedDeriverKeyFormat & key_format)80   crypto::tink::util::Status ValidateKeyFormat(
81       const google::crypto::tink::PrfBasedDeriverKeyFormat& key_format)
82       const override {
83     if (!key_format.has_prf_key_template()) {
84       return crypto::tink::util::Status(absl::StatusCode::kInvalidArgument,
85                                         "key.prf_key_template() must be set");
86     }
87     if (!key_format.params().has_derived_key_template()) {
88       return crypto::tink::util::Status(
89           absl::StatusCode::kInvalidArgument,
90           "key_format.params().derived_key_template() must be set");
91     }
92     return util::OkStatus();
93   }
94 
95   crypto::tink::util::StatusOr<google::crypto::tink::PrfBasedDeriverKey>
CreateKey(const google::crypto::tink::PrfBasedDeriverKeyFormat & key_format)96   CreateKey(const google::crypto::tink::PrfBasedDeriverKeyFormat& key_format)
97       const override {
98     crypto::tink::util::StatusOr<std::unique_ptr<google::crypto::tink::KeyData>>
99         prf_key = CreateKeyData(key_format.prf_key_template());
100     if (!prf_key.ok()) return prf_key.status();
101 
102     // Java and Go implementations perform additional verification by getting a
103     // StreamingPrf primitive from the registry and trying to derive
104     // `key_format.params().derived_key_template()` with a fake salt. This is
105     // currently not possible in C++.
106 
107     google::crypto::tink::PrfBasedDeriverKey key;
108     key.set_version(get_version());
109     *key.mutable_params()->mutable_derived_key_template() =
110         key_format.params().derived_key_template();
111     *key.mutable_prf_key() = **std::move(prf_key);
112     return key;
113   }
114 
115  protected:
116   virtual crypto::tink::util::StatusOr<
117       std::unique_ptr<google::crypto::tink::KeyData>>
CreateKeyData(const google::crypto::tink::KeyTemplate & key_template)118   CreateKeyData(const google::crypto::tink::KeyTemplate& key_template) const {
119     return Registry::NewKeyData(key_template);
120   }
121 
122  private:
123   const std::string key_type_ =
124       absl::StrCat(kTypeGoogleapisCom,
125                    google::crypto::tink::PrfBasedDeriverKey().GetTypeName());
126 };
127 
128 }  // namespace internal
129 }  // namespace tink
130 }  // namespace crypto
131 
132 #endif  // TINK_KEYDERIVATION_INTERNAL_PRF_BASED_DERIVER_KEY_MANAGER_H_
133