// Copyright 2019 The Chromium 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 "cast/streaming/frame_crypto.h"

#include <random>
#include <utility>

#include "openssl/crypto.h"
#include "openssl/err.h"
#include "openssl/rand.h"
#include "util/big_endian.h"
#include "util/crypto/openssl_util.h"
#include "util/crypto/random_bytes.h"

namespace openscreen {
namespace cast {

EncryptedFrame::EncryptedFrame() {
  data = absl::Span<uint8_t>(owned_data_);
}

EncryptedFrame::~EncryptedFrame() = default;

EncryptedFrame::EncryptedFrame(EncryptedFrame&& other)
    : EncodedFrame(static_cast<EncodedFrame&&>(other)),
      owned_data_(std::move(other.owned_data_)) {
  data = absl::Span<uint8_t>(owned_data_);
  other.data = absl::Span<uint8_t>{};
}

EncryptedFrame& EncryptedFrame::operator=(EncryptedFrame&& other) {
  this->EncodedFrame::operator=(static_cast<EncodedFrame&&>(other));
  owned_data_ = std::move(other.owned_data_);
  data = absl::Span<uint8_t>(owned_data_);
  other.data = absl::Span<uint8_t>{};
  return *this;
}

FrameCrypto::FrameCrypto(const std::array<uint8_t, 16>& aes_key,
                         const std::array<uint8_t, 16>& cast_iv_mask)
    : aes_key_{}, cast_iv_mask_(cast_iv_mask) {
  // Ensure that the library has been initialized. CRYPTO_library_init() may be
  // safely called multiple times during the life of a process.
  CRYPTO_library_init();

  // Initialize the 244-byte AES_KEY struct once, here at construction time. The
  // const_cast<> is reasonable as this is a one-time-ctor-initialized value
  // that will remain constant from here onward.
  const int return_code = AES_set_encrypt_key(
      aes_key.data(), aes_key.size() * 8, const_cast<AES_KEY*>(&aes_key_));
  if (return_code != 0) {
    ClearOpenSSLERRStack(CURRENT_LOCATION);
    OSP_LOG_FATAL << "Failure when setting encryption key; unsafe to continue.";
    OSP_NOTREACHED();
  }
}

FrameCrypto::~FrameCrypto() = default;

EncryptedFrame FrameCrypto::Encrypt(const EncodedFrame& encoded_frame) const {
  EncryptedFrame result;
  encoded_frame.CopyMetadataTo(&result);
  result.owned_data_.resize(encoded_frame.data.size());
  result.data = absl::Span<uint8_t>(result.owned_data_);
  EncryptCommon(encoded_frame.frame_id, encoded_frame.data, result.data);
  return result;
}

void FrameCrypto::Decrypt(const EncryptedFrame& encrypted_frame,
                          EncodedFrame* encoded_frame) const {
  encrypted_frame.CopyMetadataTo(encoded_frame);
  // AES-CTC is symmetric. Thus, decryption back to the plaintext is the same as
  // encrypting the ciphertext; and both are the same size.
  if (encrypted_frame.data.size() < encoded_frame->data.size()) {
    encoded_frame->data = absl::Span<uint8_t>(encoded_frame->data.data(),
                                              encrypted_frame.data.size());
  }
  EncryptCommon(encrypted_frame.frame_id, encrypted_frame.data,
                encoded_frame->data);
}

void FrameCrypto::EncryptCommon(FrameId frame_id,
                                absl::Span<const uint8_t> in,
                                absl::Span<uint8_t> out) const {
  OSP_DCHECK(!frame_id.is_null());
  OSP_DCHECK_EQ(in.size(), out.size());

  // Compute the AES nonce for Cast Streaming payload encryption, which is based
  // on the |frame_id|.
  std::array<uint8_t, 16> aes_nonce{/* zero initialized */};
  static_assert(AES_BLOCK_SIZE == sizeof(aes_nonce),
                "AES_BLOCK_SIZE is not 16 bytes.");
  WriteBigEndian<uint32_t>(frame_id.lower_32_bits(), aes_nonce.data() + 8);
  for (size_t i = 0; i < aes_nonce.size(); ++i) {
    aes_nonce[i] ^= cast_iv_mask_[i];
  }

  std::array<uint8_t, 16> ecount_buf{/* zero initialized */};
  unsigned int block_offset = 0;
  AES_ctr128_encrypt(in.data(), out.data(), in.size(), &aes_key_,
                     aes_nonce.data(), ecount_buf.data(), &block_offset);
}

}  // namespace cast
}  // namespace openscreen
