// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "peridot/bin/ledger/encryption/primitives/encrypt.h"

#include <openssl/aead.h>
#include <zircon/syscalls.h>

namespace encryption {

bool AES128GCMSIVEncrypt(rng::Random* random, fxl::StringView key,
                         fxl::StringView data, std::string* output) {
  if (key.size() != 16) {
    return false;
  }

  const EVP_AEAD* algorithm = EVP_aead_aes_128_gcm_siv();

  const size_t kNonceOffset = 0;
  const size_t kNonceSize = EVP_AEAD_nonce_length(algorithm);
  const size_t kTagOffset = kNonceOffset + kNonceSize;
  const size_t kTagSize = EVP_AEAD_max_tag_len(algorithm);
  const size_t kEncryptedDataOffset = kTagOffset + kTagSize;

  bssl::ScopedEVP_AEAD_CTX ctx;
  if (!EVP_AEAD_CTX_init_with_direction(
          ctx.get(), algorithm, reinterpret_cast<const uint8_t*>(key.data()),
          key.size(), EVP_AEAD_DEFAULT_TAG_LENGTH, evp_aead_seal)) {
    return false;
  }
  std::string result;
  result.resize(kEncryptedDataOffset + data.size() +
                EVP_AEAD_max_overhead(algorithm));
  uint8_t* result_as_int8_ptr = reinterpret_cast<uint8_t*>(&result[0]);

  // Generate seed.
  random->Draw(&result[0], EVP_AEAD_nonce_length(algorithm));

  size_t out_len;
  if (EVP_AEAD_CTX_seal(
          ctx.get(), &result_as_int8_ptr[kEncryptedDataOffset], &out_len,
          data.size() + EVP_AEAD_max_overhead(algorithm),
          &result_as_int8_ptr[kNonceOffset], kNonceSize,
          reinterpret_cast<const uint8_t*>(data.data()), data.size(),
          &result_as_int8_ptr[kTagOffset], kTagSize) == 0) {
    return false;
  }
  result.resize(kEncryptedDataOffset + out_len);
  output->swap(result);
  return true;
}

bool AES128GCMSIVDecrypt(fxl::StringView key, fxl::StringView encrypted_data,
                         std::string* output) {
  if (key.size() != 16) {
    return false;
  }

  const EVP_AEAD* algorithm = EVP_aead_aes_128_gcm_siv();

  const size_t kNonceOffset = 0;
  const size_t kNonceSize = EVP_AEAD_nonce_length(algorithm);
  const size_t kTagOffset = kNonceOffset + kNonceSize;
  const size_t kTagSize = EVP_AEAD_max_tag_len(algorithm);
  const size_t kEncryptedDataOffset = kTagOffset + kTagSize;
  if (encrypted_data.size() < kEncryptedDataOffset) {
    return false;
  }
  const size_t kEncryptedDataSize =
      encrypted_data.size() - kEncryptedDataOffset;

  bssl::ScopedEVP_AEAD_CTX ctx;
  if (!EVP_AEAD_CTX_init_with_direction(
          ctx.get(), algorithm, reinterpret_cast<const uint8_t*>(key.data()),
          key.size(), EVP_AEAD_DEFAULT_TAG_LENGTH, evp_aead_open)) {
    return false;
  }

  const uint8_t* encrypted_data_as_uint8_ptr =
      reinterpret_cast<const uint8_t*>(encrypted_data.data());

  std::string result;
  result.resize(kEncryptedDataSize);

  size_t out_len;
  if (EVP_AEAD_CTX_open(
          ctx.get(), reinterpret_cast<uint8_t*>(&result[0]), &out_len,
          result.size(), &encrypted_data_as_uint8_ptr[kNonceOffset], kNonceSize,
          &encrypted_data_as_uint8_ptr[kEncryptedDataOffset],
          kEncryptedDataSize, &encrypted_data_as_uint8_ptr[kTagOffset],
          kTagSize) == 0) {
    return false;
  }

  result.resize(out_len);
  output->swap(result);
  return true;
}

}  // namespace encryption
