// 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 "src/ledger/bin/encryption/primitives/encrypt.h"

#include <zircon/syscalls.h>

#include <openssl/aead.h>

#include "src/ledger/lib/rng/random.h"
#include "third_party/abseil-cpp/absl/strings/string_view.h"

namespace encryption {

bool AES128GCMSIVEncrypt(ledger::Random* random, absl::string_view key, absl::string_view 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(absl::string_view key, absl::string_view 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
