-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Legacy Envelope KMS AEAD parameters.
PiperOrigin-RevId: 707138646 Change-Id: I9f022b328d7b312557492a7dd1a9f25b5b43e192
- Loading branch information
1 parent
70fac47
commit 00c5899
Showing
5 changed files
with
800 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// Copyright 2024 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
#include "tink/aead/legacy_kms_envelope_aead_parameters.h" | ||
|
||
#include <memory> | ||
|
||
#include "absl/memory/memory.h" | ||
#include "absl/status/status.h" | ||
#include "absl/strings/string_view.h" | ||
#include "tink/aead/aead_parameters.h" | ||
#include "tink/aead/aes_ctr_hmac_aead_parameters.h" | ||
#include "tink/aead/aes_eax_parameters.h" | ||
#include "tink/aead/aes_gcm_parameters.h" | ||
#include "tink/aead/aes_gcm_siv_parameters.h" | ||
#include "tink/aead/xchacha20_poly1305_parameters.h" | ||
#include "tink/parameters.h" | ||
#include "tink/util/status.h" | ||
#include "tink/util/statusor.h" | ||
|
||
namespace crypto { | ||
namespace tink { | ||
namespace { | ||
|
||
util::Status ValidateDekParsingStrategy( | ||
LegacyKmsEnvelopeAeadParameters::DekParsingStrategy dek_parsing_strategy, | ||
const AeadParameters& dek_parameters) { | ||
if (dek_parsing_strategy == LegacyKmsEnvelopeAeadParameters:: | ||
DekParsingStrategy::kAssumeAesCtrHmac && | ||
typeid(dek_parameters) == typeid(AesCtrHmacAeadParameters)) { | ||
return util::OkStatus(); | ||
} | ||
if (dek_parsing_strategy == | ||
LegacyKmsEnvelopeAeadParameters::DekParsingStrategy::kAssumeAesEax && | ||
typeid(dek_parameters) == typeid(AesEaxParameters)) { | ||
return util::OkStatus(); | ||
} | ||
if (dek_parsing_strategy == | ||
LegacyKmsEnvelopeAeadParameters::DekParsingStrategy::kAssumeAesGcm && | ||
typeid(dek_parameters) == typeid(AesGcmParameters)) { | ||
return util::OkStatus(); | ||
} | ||
if (dek_parsing_strategy == LegacyKmsEnvelopeAeadParameters:: | ||
DekParsingStrategy::kAssumeAesGcmSiv && | ||
typeid(dek_parameters) == typeid(AesGcmSivParameters)) { | ||
return util::OkStatus(); | ||
} | ||
if (dek_parsing_strategy == | ||
LegacyKmsEnvelopeAeadParameters::DekParsingStrategy:: | ||
kAssumeXChaCha20Poly1305 && | ||
typeid(dek_parameters) == typeid(XChaCha20Poly1305Parameters)) { | ||
return util::OkStatus(); | ||
} | ||
return util::Status(absl::StatusCode::kInvalidArgument, | ||
"Cannot create legacy KMS Envelope AEAD parameters with " | ||
"mismatching parsing strategy and DEK parameters type."); | ||
} | ||
|
||
} // namespace | ||
|
||
util::StatusOr<LegacyKmsEnvelopeAeadParameters> | ||
LegacyKmsEnvelopeAeadParameters::Create(absl::string_view key_uri, | ||
Variant variant, | ||
DekParsingStrategy dek_parsing_strategy, | ||
const AeadParameters& dek_parameters) { | ||
if (variant != Variant::kTink && variant != Variant::kNoPrefix) { | ||
return util::Status(absl::StatusCode::kInvalidArgument, | ||
"Cannot create legacy KMS Envelope AEAD parameters " | ||
"with unknown variant."); | ||
} | ||
if (dek_parameters.HasIdRequirement()) { | ||
return util::Status(absl::StatusCode::kInvalidArgument, | ||
"DEK parameters must not have an ID requirement."); | ||
} | ||
util::Status status = | ||
ValidateDekParsingStrategy(dek_parsing_strategy, dek_parameters); | ||
if (!status.ok()) { | ||
return status; | ||
} | ||
|
||
std::unique_ptr<Parameters> cloned_dek_parameters = dek_parameters.Clone(); | ||
const AeadParameters* dek_parameters_ptr = | ||
dynamic_cast<const AeadParameters*>(cloned_dek_parameters.get()); | ||
if (dek_parameters_ptr == nullptr) { | ||
return absl::Status(absl::StatusCode::kInvalidArgument, | ||
"DEK parameters cannot be set to non-AEAD parameters."); | ||
} | ||
|
||
return LegacyKmsEnvelopeAeadParameters( | ||
key_uri, variant, dek_parsing_strategy, | ||
absl::WrapUnique(dynamic_cast<const AeadParameters*>( | ||
cloned_dek_parameters.release()))); | ||
} | ||
|
||
bool LegacyKmsEnvelopeAeadParameters::operator==( | ||
const Parameters& other) const { | ||
const LegacyKmsEnvelopeAeadParameters* that = | ||
dynamic_cast<const LegacyKmsEnvelopeAeadParameters*>(&other); | ||
if (that == nullptr) { | ||
return false; | ||
} | ||
return key_uri_ == that->key_uri_ && variant_ == that->variant_ && | ||
dek_parsing_strategy_ == that->dek_parsing_strategy_ && | ||
*dek_parameters_ == *that->dek_parameters_; | ||
} | ||
|
||
} // namespace tink | ||
} // namespace crypto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
// Copyright 2024 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
//////////////////////////////////////////////////////////////////////////////// | ||
|
||
#ifndef TINK_AEAD_LEGACY_KMS_ENVELOPE_AEAD_PARAMETERS_H_ | ||
#define TINK_AEAD_LEGACY_KMS_ENVELOPE_AEAD_PARAMETERS_H_ | ||
|
||
#include <memory> | ||
#include <string> | ||
#include <utility> | ||
|
||
#include "absl/strings/string_view.h" | ||
#include "tink/aead/aead_parameters.h" | ||
#include "tink/parameters.h" | ||
#include "tink/util/statusor.h" | ||
|
||
namespace crypto { | ||
namespace tink { | ||
|
||
// Describes the parameters of a LegacyKmsEnvelopeAeadKey. | ||
// | ||
// Usage of this key type is not recommended. Instead, we recommend to | ||
// implement the idea of this class manually, i.e., create a remote Aead object | ||
// for your KMS with an appropriate Tink extension (typically using a subclass | ||
// of `KmsClient`), and then create an envelope AEAD with | ||
// `KmsEnvelopeAead::New`. | ||
// | ||
// Known Issues: | ||
// 1. Global registration: | ||
// If a user uses a `LegacyKmsEnvelopeAeadKey`, when | ||
// the corresponding `Aead` is created, Tink looks up the `KmsClient` in a | ||
// global registry. This registry needs to store all the credentials and all | ||
// the information. This is inappropriate in many situations. | ||
// | ||
// 2. Ciphertext format: | ||
// The ciphertext format does not encode the key type of the key used. This | ||
// can lead to unexpected results if a user changes the `dekParameters` or | ||
// the `dekParsingStrategy` for the same remote key. In more details, the | ||
// ciphertext contains a Tink key proto of newly generated key, but not the | ||
// type URL. This means that if a user reuses the same remote Key with a | ||
// different key type, it will be parsed with the wrong one. | ||
// | ||
// Also, Tink does not compare the parameters of the parsed key with the | ||
// parameters specified in 'dekParameters`. For example, if the | ||
// `dekParameters` is specified as AES_128_GCM in one binary, and AES_256_GCM | ||
// in another binary, communication between the binaries succeeds in both | ||
// directions. | ||
// | ||
// 3. Ciphertext malleability: | ||
// Some KMS have malleable ciphertexts. This means that the Aeads | ||
// corresponding to these keys may be malleable. See | ||
// https://developers.google.com/tink/issues/envelope-aead-malleability | ||
class LegacyKmsEnvelopeAeadParameters : public AeadParameters { | ||
public: | ||
// Description of the output prefix prepended to the ciphertext. | ||
enum class Variant : int { | ||
// Prepends '0x01<big endian key id>' to the ciphertext. | ||
kTink = 1, | ||
// Does not prepend any prefix (i.e., keys must have no ID requirement). | ||
kNoPrefix = 2, | ||
// Added to guard from failures that may be caused by future expansions. | ||
kDoNotUseInsteadUseDefaultWhenWritingSwitchStatements = 20, | ||
}; | ||
|
||
// Specifies how the DEKs in received ciphertexts are parsed. | ||
enum class DekParsingStrategy : int { | ||
// When parsing, assume that the ciphertext was encrypted with AES-GCM. | ||
kAssumeAesGcm = 1, | ||
// When parsing, assume that the ciphertext was encrypted with | ||
// XChaCha20-Poly1305. | ||
kAssumeXChaCha20Poly1305 = 2, | ||
// When parsing, assume that the ciphertext was encrypted with AES-GCM-SIV. | ||
kAssumeAesGcmSiv = 3, | ||
// When parsing, assume that the ciphertext was encrypted with AES-CTR-HMAC. | ||
kAssumeAesCtrHmac = 4, | ||
// When parsing, assume that the ciphertext was encrypted with AES-EAX. | ||
kAssumeAesEax = 5, | ||
// Added to guard from failures that may be caused by future expansions. | ||
kDoNotUseInsteadUseDefaultWhenWritingSwitchStatements = 20, | ||
}; | ||
|
||
// Copyable and movable. | ||
LegacyKmsEnvelopeAeadParameters( | ||
const LegacyKmsEnvelopeAeadParameters& other) = default; | ||
LegacyKmsEnvelopeAeadParameters& operator=( | ||
const LegacyKmsEnvelopeAeadParameters& other) = default; | ||
LegacyKmsEnvelopeAeadParameters(LegacyKmsEnvelopeAeadParameters&& other) = | ||
default; | ||
LegacyKmsEnvelopeAeadParameters& operator=( | ||
LegacyKmsEnvelopeAeadParameters&& other) = default; | ||
|
||
static util::StatusOr<LegacyKmsEnvelopeAeadParameters> Create( | ||
absl::string_view key_uri, Variant variant, | ||
DekParsingStrategy dek_parsing_strategy, | ||
const AeadParameters& dek_parameters); | ||
|
||
const std::string& GetKeyUri() const { return key_uri_; } | ||
|
||
Variant GetVariant() const { return variant_; } | ||
|
||
// Returns strategy used when parsing encrypted keys. | ||
DekParsingStrategy GetDekParsingStrategy() const { | ||
return dek_parsing_strategy_; | ||
} | ||
|
||
const AeadParameters& GetDekParameters() const { return *dek_parameters_; } | ||
|
||
bool HasIdRequirement() const override { | ||
return variant_ != Variant::kNoPrefix; | ||
} | ||
|
||
bool operator==(const Parameters& other) const override; | ||
|
||
std::unique_ptr<Parameters> Clone() const override { | ||
return std::make_unique<LegacyKmsEnvelopeAeadParameters>(*this); | ||
} | ||
|
||
private: | ||
explicit LegacyKmsEnvelopeAeadParameters( | ||
absl::string_view key_uri, Variant variant, | ||
DekParsingStrategy dek_parsing_strategy, | ||
std::unique_ptr<const AeadParameters> dek_parameters) | ||
: key_uri_(key_uri), | ||
variant_(variant), | ||
dek_parsing_strategy_(dek_parsing_strategy), | ||
dek_parameters_(std::move(dek_parameters)) {} | ||
|
||
std::string key_uri_; | ||
Variant variant_; | ||
DekParsingStrategy dek_parsing_strategy_; | ||
std::shared_ptr<const AeadParameters> dek_parameters_; | ||
}; | ||
|
||
} // namespace tink | ||
} // namespace crypto | ||
|
||
#endif // TINK_AEAD_LEGACY_KMS_ENVELOPE_AEAD_PARAMETERS_H_ |
Oops, something went wrong.