Skip to content

Commit

Permalink
Add Legacy Envelope KMS AEAD parameters.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 707138646
Change-Id: I9f022b328d7b312557492a7dd1a9f25b5b43e192
  • Loading branch information
ioannanedelcu authored and copybara-github committed Dec 17, 2024
1 parent 70fac47 commit 00c5899
Show file tree
Hide file tree
Showing 5 changed files with 800 additions and 0 deletions.
41 changes: 41 additions & 0 deletions tink/aead/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -817,6 +817,27 @@ cc_library(
],
)

cc_library(
name = "legacy_kms_envelope_aead_parameters",
srcs = ["legacy_kms_envelope_aead_parameters.cc"],
hdrs = ["legacy_kms_envelope_aead_parameters.h"],
include_prefix = "tink/aead",
deps = [
":aead_parameters",
":aes_ctr_hmac_aead_parameters",
":aes_eax_parameters",
":aes_gcm_parameters",
":aes_gcm_siv_parameters",
":xchacha20_poly1305_parameters",
"//tink:parameters",
"//tink/util:status",
"//tink/util:statusor",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings:string_view",
],
)

# tests

cc_test(
Expand Down Expand Up @@ -1708,3 +1729,23 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)

cc_test(
name = "legacy_kms_envelope_aead_parameters_test",
srcs = ["legacy_kms_envelope_aead_parameters_test.cc"],
deps = [
":aes_ctr_hmac_aead_parameters",
":aes_eax_parameters",
":aes_gcm_parameters",
":aes_gcm_siv_parameters",
":legacy_kms_envelope_aead_parameters",
":xchacha20_poly1305_parameters",
"//tink:parameters",
"//tink/util:statusor",
"//tink/util:test_matchers",
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings:string_view",
"@com_google_googletest//:gtest_main",
],
)
40 changes: 40 additions & 0 deletions tink/aead/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,26 @@ tink_cc_library(
tink::util::status
)

tink_cc_library(
NAME legacy_kms_envelope_aead_parameters
SRCS
legacy_kms_envelope_aead_parameters.cc
legacy_kms_envelope_aead_parameters.h
DEPS
tink::aead::aead_parameters
tink::aead::aes_ctr_hmac_aead_parameters
tink::aead::aes_eax_parameters
tink::aead::aes_gcm_parameters
tink::aead::aes_gcm_siv_parameters
tink::aead::xchacha20_poly1305_parameters
absl::memory
absl::status
absl::string_view
tink::core::parameters
tink::util::status
tink::util::statusor
)

# tests

tink_cc_test(
Expand Down Expand Up @@ -1637,3 +1657,23 @@ tink_cc_test(
tink::proto::kms_aead_cc_proto
tink::proto::tink_cc_proto
)

tink_cc_test(
NAME legacy_kms_envelope_aead_parameters_test
SRCS
legacy_kms_envelope_aead_parameters_test.cc
DEPS
tink::aead::aes_ctr_hmac_aead_parameters
tink::aead::aes_eax_parameters
tink::aead::aes_gcm_parameters
tink::aead::aes_gcm_siv_parameters
tink::aead::legacy_kms_envelope_aead_parameters
tink::aead::xchacha20_poly1305_parameters
gmock
absl::check
absl::status
absl::string_view
tink::core::parameters
tink::util::statusor
tink::util::test_matchers
)
121 changes: 121 additions & 0 deletions tink/aead/legacy_kms_envelope_aead_parameters.cc
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
149 changes: 149 additions & 0 deletions tink/aead/legacy_kms_envelope_aead_parameters.h
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_
Loading

0 comments on commit 00c5899

Please sign in to comment.