// Copyright 2017 Google Inc.
//
// 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/hybrid/ecies_aead_hkdf_dem_helper.h"

#include <string>
#include <utility>

#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "tink/aead.h"
#include "tink/deterministic_aead.h"
#include "tink/key_manager.h"
#include "tink/registry.h"
#include "tink/util/errors.h"
#include "tink/util/protobuf_helper.h"
#include "tink/util/statusor.h"
#include "proto/aes_ctr.pb.h"
#include "proto/aes_ctr_hmac_aead.pb.h"
#include "proto/aes_gcm.pb.h"
#include "proto/aes_siv.pb.h"
#include "proto/hmac.pb.h"
#include "proto/tink.pb.h"
#include "proto/xchacha20_poly1305.pb.h"

namespace crypto {
namespace tink {
namespace {

using ::crypto::tink::subtle::AeadOrDaead;
using ::google::crypto::tink::AesCtrHmacAeadKey;
using ::google::crypto::tink::AesCtrHmacAeadKeyFormat;
using ::google::crypto::tink::AesGcmKey;
using ::google::crypto::tink::AesGcmKeyFormat;
using ::google::crypto::tink::AesSivKey;
using ::google::crypto::tink::AesSivKeyFormat;
using ::google::crypto::tink::KeyTemplate;
using ::google::crypto::tink::XChaCha20Poly1305Key;
using ::google::crypto::tink::XChaCha20Poly1305KeyFormat;

// Internal implementaton of the EciesAeadHkdfDemHelper class, paremetrized by
// the Primitive used for data encapsulation (i.e Aead or DeterministicAead).
template <class EncryptionPrimitive>
class EciesAeadHkdfDemHelperImpl : public EciesAeadHkdfDemHelper {
 public:
  static util::StatusOr<std::unique_ptr<const EciesAeadHkdfDemHelper>> New(
      const google::crypto::tink::KeyTemplate& dem_key_template,
      const DemKeyParams& key_params, const std::string& dem_type_url) {
    auto key_manager_or =
        Registry::get_key_manager<EncryptionPrimitive>(dem_type_url);
    if (!key_manager_or.ok()) {
      return ToStatusF(
          absl::StatusCode::kFailedPrecondition,
          "No manager for DEM key type '%s' found in the registry.",
          dem_type_url);
    }
    const KeyManager<EncryptionPrimitive>* key_manager = key_manager_or.value();
    return {absl::make_unique<EciesAeadHkdfDemHelperImpl<EncryptionPrimitive>>(
        key_manager, dem_key_template, key_params)};
  }

  EciesAeadHkdfDemHelperImpl(
      const KeyManager<EncryptionPrimitive>* key_manager,
      const google::crypto::tink::KeyTemplate& key_template,
      DemKeyParams key_params)
      : EciesAeadHkdfDemHelper(key_template, key_params),
        key_manager_(key_manager) {}

 protected:
  crypto::tink::util::StatusOr<
      std::unique_ptr<crypto::tink::subtle::AeadOrDaead>>
  GetAeadOrDaead(const util::SecretData& symmetric_key_value) const override {
    if (symmetric_key_value.size() != key_params_.key_size_in_bytes) {
      return util::Status(absl::StatusCode::kInternal,
                          "Wrong length of symmetric key.");
    }
    auto key_or = key_manager_->get_key_factory().NewKey(key_template_.value());
    if (!key_or.ok()) return key_or.status();
    auto key = std::move(key_or).value();
    if (!ReplaceKeyBytes(symmetric_key_value, key.get())) {
      return util::Status(absl::StatusCode::kInternal,
                          "Generation of DEM-key failed.");
    }

    util::StatusOr<std::unique_ptr<EncryptionPrimitive>> primitive_or =
        key_manager_->GetPrimitive(*key);
    ZeroKeyBytes(key.get());

    if (!primitive_or.ok()) return primitive_or.status();
    return absl::make_unique<AeadOrDaead>(std::move(primitive_or.value()));
  }

 private:
  const KeyManager<EncryptionPrimitive>* key_manager_;  // not owned
};

}  // namespace

util::StatusOr<EciesAeadHkdfDemHelper::DemKeyParams>
EciesAeadHkdfDemHelper::GetKeyParams(const KeyTemplate& key_template) {
  const std::string& type_url = key_template.type_url();
  if (type_url == "type.googleapis.com/google.crypto.tink.AesGcmKey") {
    AesGcmKeyFormat key_format;
    if (!key_format.ParseFromString(key_template.value())) {
      return util::Status(absl::StatusCode::kInvalidArgument,
                          "Invalid AesGcmKeyFormat in DEM key template");
    }
    return {{AES_GCM_KEY, key_format.key_size()}};
  }
  if (type_url == "type.googleapis.com/google.crypto.tink.AesCtrHmacAeadKey") {
    AesCtrHmacAeadKeyFormat key_format;
    if (!key_format.ParseFromString(key_template.value())) {
      return util::Status(absl::StatusCode::kInvalidArgument,
                          "Invalid AesCtrHmacKeyFormat in DEM key template");
    }
    uint32_t dem_key_size = key_format.aes_ctr_key_format().key_size() +
                            key_format.hmac_key_format().key_size();
    return {{AES_CTR_HMAC_AEAD_KEY, dem_key_size,
             key_format.aes_ctr_key_format().key_size()}};
  }
  if (type_url ==
      "type.googleapis.com/google.crypto.tink.XChaCha20Poly1305Key") {
    if (!XChaCha20Poly1305KeyFormat().ParseFromString(key_template.value())) {
      return util::Status(absl::StatusCode::kInvalidArgument,
                          "Invalid XChaCha20KeyFormat in DEM key template");
    }
    return {{XCHACHA20_POLY1305_KEY, 32}};
  }
  if (type_url == "type.googleapis.com/google.crypto.tink.AesSivKey") {
    AesSivKeyFormat key_format;

    if (!key_format.ParseFromString(key_template.value())) {
      return util::Status(absl::StatusCode::kInvalidArgument,
                          "Invalid AesSiveKeyFormat in DEM key template");
    }
    return {{AES_SIV_KEY, key_format.key_size()}};
  }
  return ToStatusF(absl::StatusCode::kInvalidArgument,
                   "Unsupported DEM key type '%s'.", type_url);
}

// static
util::StatusOr<std::unique_ptr<const EciesAeadHkdfDemHelper>>
EciesAeadHkdfDemHelper::New(const KeyTemplate& dem_key_template) {
  auto key_params_or = GetKeyParams(dem_key_template);
  if (!key_params_or.ok()) return key_params_or.status();
  DemKeyParams key_params = key_params_or.value();
  const std::string& dem_type_url = dem_key_template.type_url();

  if (key_params.key_type == AES_SIV_KEY) {
    return EciesAeadHkdfDemHelperImpl<DeterministicAead>::New(
        dem_key_template, key_params, dem_type_url);
  } else {
    return EciesAeadHkdfDemHelperImpl<Aead>::New(dem_key_template, key_params,
                                                 dem_type_url);
  }
}

bool EciesAeadHkdfDemHelper::ReplaceKeyBytes(
    const util::SecretData& key_bytes,
    portable_proto::MessageLite* proto) const {
  switch (key_params_.key_type) {
    case AES_GCM_KEY: {
      AesGcmKey* key = static_cast<AesGcmKey*>(proto);
      key->set_key_value(std::string(util::SecretDataAsStringView(key_bytes)));
      return true;
    }
    case AES_CTR_HMAC_AEAD_KEY: {
      AesCtrHmacAeadKey* key = static_cast<AesCtrHmacAeadKey*>(proto);
      auto aes_ctr_key = key->mutable_aes_ctr_key();
      aes_ctr_key->set_key_value(
          std::string(util::SecretDataAsStringView(key_bytes).substr(
              0, key_params_.aes_ctr_key_size_in_bytes)));
      auto hmac_key = key->mutable_hmac_key();
      hmac_key->set_key_value(
          std::string(util::SecretDataAsStringView(key_bytes).substr(
              key_params_.aes_ctr_key_size_in_bytes)));
      return true;
    }
    case XCHACHA20_POLY1305_KEY: {
      XChaCha20Poly1305Key* key = static_cast<XChaCha20Poly1305Key*>(proto);
      key->set_key_value(std::string(util::SecretDataAsStringView(key_bytes)));
      return true;
    }
    case AES_SIV_KEY: {
      AesSivKey* key = static_cast<AesSivKey*>(proto);
      key->set_key_value(std::string(util::SecretDataAsStringView(key_bytes)));
      return true;
    }
  }
  return false;
}

void EciesAeadHkdfDemHelper::ZeroKeyBytes(
    portable_proto::MessageLite* proto) const {
  switch (key_params_.key_type) {
    case AES_GCM_KEY: {
      AesGcmKey* key = static_cast<AesGcmKey*>(proto);
      std::unique_ptr<std::string> key_value =
          absl::WrapUnique(key->release_key_value());
      util::SafeZeroString(key_value.get());
      break;
    }
    case AES_CTR_HMAC_AEAD_KEY: {
      AesCtrHmacAeadKey* key = static_cast<AesCtrHmacAeadKey*>(proto);
      std::unique_ptr<std::string> aes_ctr_key_value =
          absl::WrapUnique(key->mutable_aes_ctr_key()->release_key_value());
      util::SafeZeroString(aes_ctr_key_value.get());
      std::unique_ptr<std::string> hmac_key_value =
          absl::WrapUnique(key->mutable_hmac_key()->release_key_value());
      util::SafeZeroString(hmac_key_value.get());
      break;
    }
    case XCHACHA20_POLY1305_KEY: {
      XChaCha20Poly1305Key* key = static_cast<XChaCha20Poly1305Key*>(proto);
      std::unique_ptr<std::string> key_value =
          absl::WrapUnique(key->release_key_value());
      util::SafeZeroString(key_value.get());
      break;
    }
    case AES_SIV_KEY: {
      AesSivKey* key = static_cast<AesSivKey*>(proto);
      std::unique_ptr<std::string> key_value =
          absl::WrapUnique(key->release_key_value());
      util::SafeZeroString(key_value.get());
      break;
    }
  }
}

}  // namespace tink
}  // namespace crypto
