// Copyright 2017 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.

#ifndef SRC_SECURITY_FCRYPTO_AEAD_H_
#define SRC_SECURITY_FCRYPTO_AEAD_H_

#include <stddef.h>
#include <stdint.h>
#include <zircon/types.h>

#include <memory>

#include <fbl/macros.h>

#include "src/security/fcrypto/bytes.h"
#include "src/security/fcrypto/cipher.h"
#include "src/security/fcrypto/secret.h"

// |crypto::AEAD| is an authenticated encryption and decryption cipher.  It differs from |Cipher| in
// that it incurs additional overhead to store its authentication tag, but can verify data integrity
// as a result.  The ciphertext produced by an AEAD is the same length as its plaintext, excluding
// the IV and tag.  A 64 bit nonce is used to seal plain texts, meaning a given key and IV can be
// used for at most 2^64 - 1 operations.
namespace crypto {

class __EXPORT AEAD final {
 public:
  // Algorithm enumerates the supported secret key ciphers.
  enum Algorithm {
    kUninitialized = 0,
    kAES128_GCM,
    kAES128_GCM_SIV,
  };

  AEAD();
  ~AEAD();

  // Gets the number of bytes needed for the symmetric key used by the given |aead|.
  static zx_status_t GetKeyLen(Algorithm aead, size_t* out);

  // Gets the number of bytes needed for the initialization vector (IV) used by the given
  // |aead|.
  static zx_status_t GetIVLen(Algorithm aead, size_t* out);

  // Gets the length of an authentication tag created by the given |aead|.
  static zx_status_t GetTagLen(Algorithm aead, size_t* out);

  // Sets up the AEAD to use the algorithm indicated by |aead| to encrypt data using the given
  // |key| and |iv|.
  zx_status_t InitSeal(Algorithm aead, const Secret& key, const Bytes& iv) {
    return Init(aead, key, iv, Cipher::kEncrypt);
  }

  // Sets up the AEAD to use the algorithm indicated by |aead| to decrypt data using the given
  // |key| and |iv|.
  zx_status_t InitOpen(Algorithm aead, const Secret& key, const Bytes& iv) {
    return Init(aead, key, iv, Cipher::kDecrypt);
  }

  // Encrypts data from |ptext| to |ctext|, based on the parameters set in |InitSeal|.  Saves the
  // |iv| used;  |iv| will be resized and filled automatically.  The AEAD tag is stored at the end
  // of |ctext|  This method will fail if called 2^64 or more times with the same key and IV.  The
  // second variant includes additional authenticated data in the tag calculation.
  zx_status_t Seal(const Bytes& ptext, uint64_t* out_nonce, Bytes* out_ctext) {
    return Seal(ptext, nullptr, 0, out_nonce, out_ctext);
  }
  zx_status_t Seal(const Bytes& ptext, const Bytes& aad, uint64_t* out_nonce, Bytes* out_ctext) {
    return Seal(ptext, aad.get(), aad.len(), out_nonce, out_ctext);
  }

  // Decrypts data from |ctext| to |ptext|, based on the parameters set in |InitOpen|.
  // Decryption can only succeed if the |iv| matches those produced by |Seal| and the AEAD tag is
  // included in |ctext|.  The second variant includes additional authenticated data in the tag
  // calculation.
  zx_status_t Open(uint64_t nonce, const Bytes& ctext, Bytes* out_ptext) {
    return Open(nonce, ctext, nullptr, 0, out_ptext);
  }
  zx_status_t Open(uint64_t nonce, const Bytes& ctext, const Bytes& aad, Bytes* out_ptext) {
    return Open(nonce, ctext, aad.get(), aad.len(), out_ptext);
  }

  // Clears all state from this instance.
  void Reset();

 private:
  DISALLOW_COPY_ASSIGN_AND_MOVE(AEAD);

  // Sets up the aead to encrypt or decrypt data using the given |key| based on the
  // given |direction|.
  zx_status_t Init(Algorithm aead, const Secret& key, const Bytes& iv, Cipher::Direction direction);
  zx_status_t Seal(const Bytes& ptext, const uint8_t* aad, size_t aad_len, uint64_t* out_nonce,
                   Bytes* out_ctext);
  zx_status_t Open(uint64_t nonce, const Bytes& ctext, const uint8_t* aad, size_t aad_len,
                   Bytes* out_ptext);

  // Opaque crypto implementation context.
  struct Context;

  // Opaque pointer to the crypto implementation context.
  std::unique_ptr<Context> ctx_;
  // Indicates whether configured to encrypt or decrypt.
  Cipher::Direction direction_;
  // Buffer holding initial vector.  The IV is expanded to be |uint64_t|-aligned.
  std::unique_ptr<uint64_t[]> iv_;
  // Original value of |iv_[0]|.  |Seal| will fail if |iv_[0]| wraps around to this value.
  uint64_t iv0_;
  // Size of the actual IV.
  size_t iv_len_;
  // Length of authentication tag.
  size_t tag_len_;
};
}  // namespace crypto

#endif  // SRC_SECURITY_FCRYPTO_AEAD_H_
