xref: /aosp_15_r20/external/tink/cc/aead/aes_gcm_key_manager.h (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2017 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 #ifndef TINK_AEAD_AES_GCM_KEY_MANAGER_H_
17 #define TINK_AEAD_AES_GCM_KEY_MANAGER_H_
18 
19 #include <stdint.h>
20 
21 #include <memory>
22 #include <string>
23 #include <utility>
24 
25 #include "absl/memory/memory.h"
26 #include "absl/status/status.h"
27 #include "absl/strings/str_cat.h"
28 #include "absl/strings/string_view.h"
29 #include "tink/aead.h"
30 #include "tink/aead/cord_aead.h"
31 #include "tink/aead/internal/cord_aes_gcm_boringssl.h"
32 #include "tink/core/key_type_manager.h"
33 #include "tink/core/template_util.h"
34 #include "tink/input_stream.h"
35 #include "tink/internal/fips_utils.h"
36 #include "tink/subtle/aes_gcm_boringssl.h"
37 #include "tink/subtle/random.h"
38 #include "tink/util/constants.h"
39 #include "tink/util/input_stream_util.h"
40 #include "tink/util/secret_data.h"
41 #include "tink/util/status.h"
42 #include "tink/util/statusor.h"
43 #include "tink/util/validation.h"
44 #include "proto/aes_gcm.pb.h"
45 #include "proto/tink.pb.h"
46 
47 namespace crypto {
48 namespace tink {
49 
50 class AesGcmKeyManager
51     : public KeyTypeManager<google::crypto::tink::AesGcmKey,
52                             google::crypto::tink::AesGcmKeyFormat,
53                             List<Aead, CordAead>> {
54  public:
55   class AeadFactory : public PrimitiveFactory<Aead> {
Create(const google::crypto::tink::AesGcmKey & key)56     crypto::tink::util::StatusOr<std::unique_ptr<Aead>> Create(
57         const google::crypto::tink::AesGcmKey& key) const override {
58       auto aes_gcm_result = subtle::AesGcmBoringSsl::New(
59           util::SecretDataFromStringView(key.key_value()));
60       if (!aes_gcm_result.ok()) return aes_gcm_result.status();
61       return {std::move(aes_gcm_result.value())};
62     }
63   };
64   class CordAeadFactory : public PrimitiveFactory<CordAead> {
Create(const google::crypto::tink::AesGcmKey & key)65     crypto::tink::util::StatusOr<std::unique_ptr<CordAead>> Create(
66         const google::crypto::tink::AesGcmKey& key) const override {
67       auto cord_aes_gcm_result =
68           crypto::tink::internal::CordAesGcmBoringSsl::New(
69               util::SecretDataFromStringView(key.key_value()));
70       if (!cord_aes_gcm_result.ok()) return cord_aes_gcm_result.status();
71       return {std::move(cord_aes_gcm_result.value())};
72     }
73   };
74 
AesGcmKeyManager()75   AesGcmKeyManager()
76       : KeyTypeManager(absl::make_unique<AesGcmKeyManager::AeadFactory>(),
77                        absl::make_unique<AesGcmKeyManager::CordAeadFactory>()) {
78   }
79 
80   // Returns the version of this key manager.
get_version()81   uint32_t get_version() const override { return 0; }
82 
key_material_type()83   google::crypto::tink::KeyData::KeyMaterialType key_material_type()
84       const override {
85     return google::crypto::tink::KeyData::SYMMETRIC;
86   }
87 
get_key_type()88   const std::string& get_key_type() const override { return key_type_; }
89 
ValidateKey(const google::crypto::tink::AesGcmKey & key)90   crypto::tink::util::Status ValidateKey(
91       const google::crypto::tink::AesGcmKey& key) const override {
92     crypto::tink::util::Status status =
93         ValidateVersion(key.version(), get_version());
94     if (!status.ok()) return status;
95     return ValidateAesKeySize(key.key_value().size());
96   }
97 
ValidateKeyFormat(const google::crypto::tink::AesGcmKeyFormat & key_format)98   crypto::tink::util::Status ValidateKeyFormat(
99       const google::crypto::tink::AesGcmKeyFormat& key_format) const override {
100     return ValidateAesKeySize(key_format.key_size());
101   }
102 
CreateKey(const google::crypto::tink::AesGcmKeyFormat & key_format)103   crypto::tink::util::StatusOr<google::crypto::tink::AesGcmKey> CreateKey(
104       const google::crypto::tink::AesGcmKeyFormat& key_format) const override {
105     google::crypto::tink::AesGcmKey key;
106     key.set_version(get_version());
107     key.set_key_value(
108         crypto::tink::subtle::Random::GetRandomBytes(key_format.key_size()));
109     return key;
110   }
111 
DeriveKey(const google::crypto::tink::AesGcmKeyFormat & key_format,InputStream * input_stream)112   crypto::tink::util::StatusOr<google::crypto::tink::AesGcmKey> DeriveKey(
113       const google::crypto::tink::AesGcmKeyFormat& key_format,
114       InputStream* input_stream) const override {
115     crypto::tink::util::Status status =
116         ValidateVersion(key_format.version(), get_version());
117     if (!status.ok()) return status;
118 
119     crypto::tink::util::StatusOr<std::string> randomness =
120         ReadBytesFromStream(key_format.key_size(), input_stream);
121     if (!randomness.ok()) {
122       if (randomness.status().code() == absl::StatusCode::kOutOfRange) {
123         return crypto::tink::util::Status(
124             absl::StatusCode::kInvalidArgument,
125             "Could not get enough pseudorandomness from input stream");
126       }
127       return randomness.status();
128     }
129     google::crypto::tink::AesGcmKey key;
130     key.set_version(get_version());
131     key.set_key_value(randomness.value());
132     return key;
133   }
134 
FipsStatus()135   internal::FipsCompatibility FipsStatus() const override {
136     return internal::FipsCompatibility::kRequiresBoringCrypto;
137   }
138 
139  private:
140   const std::string key_type_ = absl::StrCat(
141       kTypeGoogleapisCom, google::crypto::tink::AesGcmKey().GetTypeName());
142 };
143 
144 }  // namespace tink
145 }  // namespace crypto
146 
147 #endif  // TINK_AEAD_AES_GCM_KEY_MANAGER_H_
148