// Copyright 2018 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/subtle/xchacha20_poly1305_boringssl.h"

#include <cstdint>
#include <string>
#include <vector>

#include "openssl/err.h"
#include "openssl/evp.h"
#include "tink/aead.h"
#include "tink/subtle/random.h"
#include "tink/subtle/subtle_util.h"
#include "tink/subtle/subtle_util_boringssl.h"
#include "tink/util/errors.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"

namespace crypto {
namespace tink {
namespace subtle {

namespace {
const bool IsValidKeySize(uint32_t size_in_bytes) {
  return size_in_bytes == 32;
}
}  // namespace

util::StatusOr<std::unique_ptr<Aead>> XChacha20Poly1305BoringSsl::New(
    util::SecretData key) {
  auto status = internal::CheckFipsCompatibility<XChacha20Poly1305BoringSsl>();
  if (!status.ok()) return status;

  if (!IsValidKeySize(key.size())) {
    return util::Status(util::error::INVALID_ARGUMENT, "Invalid key size");
  }

  const EVP_AEAD* cipher = EVP_aead_xchacha20_poly1305();
  if (cipher == nullptr) {
    return util::Status(util::error::INTERNAL, "Failed to get EVP_AEAD");
  }
  return std::unique_ptr<Aead>(
      new XChacha20Poly1305BoringSsl(std::move(key), cipher));
}

util::StatusOr<std::string> XChacha20Poly1305BoringSsl::Encrypt(
    absl::string_view plaintext, absl::string_view additional_data) const {
  bssl::UniquePtr<EVP_AEAD_CTX> ctx(
      EVP_AEAD_CTX_new(aead_, reinterpret_cast<const uint8_t*>(key_.data()),
                       key_.size(), kTagSize));
  if (ctx.get() == nullptr) {
    return util::Status(util::error::INTERNAL,
                        "could not initialize EVP_AEAD_CTX");
  }

  // BoringSSL expects a non-null pointer for plaintext and additional_data,
  // regardless of whether the size is 0.
  plaintext = SubtleUtilBoringSSL::EnsureNonNull(plaintext);
  additional_data = SubtleUtilBoringSSL::EnsureNonNull(additional_data);

  const std::string nonce = Random::GetRandomBytes(kNonceSize);
  if (nonce.size() != kNonceSize) {
    return util::Status(util::error::INTERNAL,
                        "Failed to get enough random bytes for nonce");
  }

  size_t ciphertext_size = nonce.size() + plaintext.size() + kTagSize;

  // Write the nonce in the output buffer.
  std::string ct = nonce;
  ResizeStringUninitialized(&ct, ciphertext_size);
  size_t written = nonce.size();

  // Encrypt the plaintext and store it after the nonce.
  size_t out_len = 0;
  int ret = EVP_AEAD_CTX_seal(
      ctx.get(), reinterpret_cast<uint8_t*>(&ct[written]), &out_len,
      ciphertext_size - written, reinterpret_cast<const uint8_t*>(nonce.data()),
      nonce.size(), reinterpret_cast<const uint8_t*>(plaintext.data()),
      plaintext.size(),
      reinterpret_cast<const uint8_t*>(additional_data.data()),
      additional_data.size());
  if (ret != 1) {
    return util::Status(util::error::INTERNAL, "EVP_AEAD_CTX_seal failed");
  }
  written += out_len;

  // Verify that all the expected data has been written.
  if (written != ciphertext_size) {
    return util::Status(util::error::INTERNAL, "Incorrect ciphertext size");
  }
  return ct;
}

util::StatusOr<std::string> XChacha20Poly1305BoringSsl::Decrypt(
    absl::string_view ciphertext, absl::string_view additional_data) const {
  // BoringSSL expects a non-null pointer for additional_data,
  // regardless of whether the size is 0.
  additional_data = SubtleUtilBoringSSL::EnsureNonNull(additional_data);

  if (ciphertext.size() < kNonceSize + kTagSize) {
    return util::Status(util::error::INVALID_ARGUMENT, "Ciphertext too short");
  }

  bssl::UniquePtr<EVP_AEAD_CTX> ctx(
      EVP_AEAD_CTX_new(aead_, reinterpret_cast<const uint8_t*>(key_.data()),
                       key_.size(), kTagSize));
  if (ctx.get() == nullptr) {
    return util::Status(util::error::INTERNAL,
                        "could not initialize EVP_AEAD_CTX");
  }

  std::string out;
  size_t out_size = ciphertext.size() - kNonceSize - kTagSize;
  ResizeStringUninitialized(&out, out_size);

  absl::string_view nonce = ciphertext.substr(0, kNonceSize);
  absl::string_view encrypted =
      ciphertext.substr(kNonceSize, out_size + kTagSize);

  size_t len = 0;
  int ret = EVP_AEAD_CTX_open(
      ctx.get(), reinterpret_cast<uint8_t*>(&out[0]), &len, out_size,
      reinterpret_cast<const uint8_t*>(nonce.data()), nonce.size(),
      reinterpret_cast<const uint8_t*>(encrypted.data()), encrypted.size(),
      reinterpret_cast<const uint8_t*>(additional_data.data()),
      additional_data.size());
  if (ret != 1) {
    return util::Status(util::error::INTERNAL, "EVP_AEAD_CTX_open failed");
  }

  if (len != out_size) {
    return util::Status(util::error::INTERNAL, "Incorrect output size");
  }

  return out;
}

}  // namespace subtle
}  // namespace tink
}  // namespace crypto
