/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
 * Copyright (c) 2017-2022, Regents of the University of California.
 *
 * This file is part of ndncert, a certificate management system based on NDN.
 *
 * ndncert is free software: you can redistribute it and/or modify it under the terms
 * of the GNU General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * ndncert is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received copies of the GNU General Public License along with
 * ndncert, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 *
 * See AUTHORS.md for complete list of ndncert authors and contributors.
 */

#include "detail/crypto-helpers.hpp"

#include <boost/endian/conversion.hpp>

#include <ndn-cxx/encoding/buffer-stream.hpp>
#include <ndn-cxx/security/transform/base64-decode.hpp>
#include <ndn-cxx/security/transform/base64-encode.hpp>
#include <ndn-cxx/security/transform/buffer-source.hpp>
#include <ndn-cxx/security/transform/stream-sink.hpp>
#include <ndn-cxx/util/random.hpp>

#include <openssl/ec.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <openssl/kdf.h>
#include <openssl/pem.h>

#include <cstring>

namespace ndncert {

ECDHState::ECDHState()
{
  auto EC_NID = NID_X9_62_prime256v1;
  // params context
  EVP_PKEY_CTX* ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, nullptr);
  EVP_PKEY_paramgen_init(ctx_params);
  EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx_params, EC_NID);
  // generate params
  EVP_PKEY* params = nullptr;
  EVP_PKEY_paramgen(ctx_params, &params);
  // key generation context
  EVP_PKEY_CTX* ctx_keygen = EVP_PKEY_CTX_new(params, nullptr);
  EVP_PKEY_keygen_init(ctx_keygen);
  auto resultCode = EVP_PKEY_keygen(ctx_keygen, &m_privkey);
  EVP_PKEY_CTX_free(ctx_keygen);
  EVP_PKEY_free(params);
  EVP_PKEY_CTX_free(ctx_params);
  if (resultCode <= 0) {
    NDN_THROW(std::runtime_error("Error in initiating ECDH"));
  }
}

ECDHState::~ECDHState()
{
  if (m_privkey != nullptr) {
    EVP_PKEY_free(m_privkey);
  }
}

const std::vector <uint8_t>&
ECDHState::getSelfPubKey()
{
  auto privECKey = EVP_PKEY_get1_EC_KEY(m_privkey);
  auto ecPoint = EC_KEY_get0_public_key(privECKey);
  auto group = EC_KEY_get0_group(privECKey);
  auto requiredBufLen = EC_POINT_point2oct(group, ecPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, nullptr);
  m_pubKey.resize(requiredBufLen);
  auto resultCode = EC_POINT_point2oct(group, ecPoint, POINT_CONVERSION_UNCOMPRESSED,
                                       m_pubKey.data(), requiredBufLen, nullptr);
  EC_KEY_free(privECKey);
  if (resultCode == 0) {
    NDN_THROW(std::runtime_error("Error in getting EC Public Key in the format of octet string"));
  }
  return m_pubKey;
}

const std::vector<uint8_t>&
ECDHState::deriveSecret(const std::vector <uint8_t>& peerKey)
{
  // prepare self private key
  auto privECKey = EVP_PKEY_get1_EC_KEY(m_privkey);
  auto group = EC_KEY_get0_group(privECKey);
  EC_KEY_free(privECKey);
  // prepare the peer public key
  auto peerPoint = EC_POINT_new(group);
  EC_POINT_oct2point(group, peerPoint, peerKey.data(), peerKey.size(), nullptr);
  EC_KEY* ecPeerkey = EC_KEY_new();
  EC_KEY_set_group(ecPeerkey, group);
  EC_KEY_set_public_key(ecPeerkey, peerPoint);
  EVP_PKEY* evpPeerkey = EVP_PKEY_new();
  EVP_PKEY_set1_EC_KEY(evpPeerkey, ecPeerkey);
  EC_KEY_free(ecPeerkey);
  EC_POINT_free(peerPoint);
  // ECDH context
  EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(m_privkey, nullptr);
  // Initialize
  EVP_PKEY_derive_init(ctx);
  // Provide the peer public key
  EVP_PKEY_derive_set_peer(ctx, evpPeerkey);
  // Determine buffer length for shared secret
  size_t secretLen = 0;
  EVP_PKEY_derive(ctx, nullptr, &secretLen);
  m_secret.resize(secretLen);
  // Derive the shared secret
  auto resultCode = EVP_PKEY_derive(ctx, m_secret.data(), &secretLen);
  EVP_PKEY_CTX_free(ctx);
  EVP_PKEY_free(evpPeerkey);
  if (resultCode == 0) {
    NDN_THROW(std::runtime_error("Error when calling ECDH"));
  }
  return m_secret;

//  // prepare self private key
//  auto privECKey = EVP_PKEY_get1_EC_KEY(m_privkey);
//  if (privECKey == nullptr) {
//    NDN_THROW(std::runtime_error("Cannot not get key when calling EVP_PKEY_get1_EC_KEY()"));
//  }
//  auto group = EC_KEY_get0_group(privECKey);
//  EC_KEY_free(privECKey);
//  // prepare the peer public key
//  auto peerPoint = EC_POINT_new(group);
//  if (peerPoint == nullptr) {
//    NDN_THROW(std::runtime_error("Cannot create the EC_POINT for peer key when calling EC_POINT_new()"));
//  }
//  if (EC_POINT_oct2point(group, peerPoint, peerKey.data(), peerKey.size(), nullptr) == 0) {
//    EC_POINT_free(peerPoint);
//    NDN_THROW(std::runtime_error("Cannot convert peer's key into a EC point when calling EC_POINT_oct2point()"));
//  }
//  EC_KEY* ecPeerkey = EC_KEY_new();
//  if (ecPeerkey == nullptr) {
//    EC_POINT_free(peerPoint);
//    NDN_THROW(std::runtime_error("Cannot create EC_KEY for peer key when calling EC_KEY_new()"));
//  }
//  if (EC_KEY_set_group(ecPeerkey, group) != 1) {
//    EC_POINT_free(peerPoint);
//    NDN_THROW(std::runtime_error("Cannot set group for peer key's EC_KEY when calling EC_KEY_set_group()"));
//  }
//  if (EC_KEY_set_public_key(ecPeerkey, peerPoint) == 0) {
//    EC_KEY_free(ecPeerkey);
//    EC_POINT_free(peerPoint);
//    NDN_THROW(
//      std::runtime_error("Cannot initialize peer EC_KEY with the EC_POINT when calling EC_KEY_set_public_key()"));
//  }
//  EVP_PKEY* evpPeerkey = EVP_PKEY_new();
//  if (EVP_PKEY_set1_EC_KEY(evpPeerkey, ecPeerkey) == 0) {
//    EC_KEY_free(ecPeerkey);
//    EC_POINT_free(peerPoint);
//    NDN_THROW(std::runtime_error("Cannot create EVP_PKEY for peer key when calling EVP_PKEY_new()"));
//  }
//  EC_KEY_free(ecPeerkey);
//  EC_POINT_free(peerPoint);
//  // ECDH context
//  EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(m_privkey, nullptr);
//  if (ctx == nullptr) {
//    EVP_PKEY_free(evpPeerkey);
//    NDN_THROW(std::runtime_error("Cannot create context for ECDH when calling EVP_PKEY_CTX_new()"));
//  }
//  // Initialize
//  if (1 != EVP_PKEY_derive_init(ctx)) {
//    EVP_PKEY_CTX_free(ctx);
//    EVP_PKEY_free(evpPeerkey);
//    NDN_THROW(std::runtime_error("Cannot initialize context for ECDH when calling EVP_PKEY_derive_init()"));
//  }
//  // Provide the peer public key
//  if (1 != EVP_PKEY_derive_set_peer(ctx, evpPeerkey)) {
//    EVP_PKEY_CTX_free(ctx);
//    EVP_PKEY_free(evpPeerkey);
//    NDN_THROW(std::runtime_error("Cannot set peer key for ECDH when calling EVP_PKEY_derive_set_peer()"));
//  }
//  // Determine buffer length for shared secret
//  size_t secretLen = 0;
//  if (1 != EVP_PKEY_derive(ctx, nullptr, &secretLen)) {
//    EVP_PKEY_CTX_free(ctx);
//    EVP_PKEY_free(evpPeerkey);
//    NDN_THROW(std::runtime_error("Cannot determine the needed buffer length when calling EVP_PKEY_derive()"));
//  }
//  m_secret.resize(secretLen);
//  // Derive the shared secret
//  if (1 != (EVP_PKEY_derive(ctx, m_secret.data(), &secretLen))) {
//    EVP_PKEY_CTX_free(ctx);
//    EVP_PKEY_free(evpPeerkey);
//    NDN_THROW(std::runtime_error("Cannot derive ECDH secret when calling EVP_PKEY_derive()"));
//  }
//  EVP_PKEY_CTX_free(ctx);
//  EVP_PKEY_free(evpPeerkey);
//  return m_secret;
}

void
hmacSha256(const uint8_t* data, size_t dataLen,
           const uint8_t* key, size_t keyLen,
           uint8_t* result)
{
  auto ret = HMAC(EVP_sha256(), key, keyLen, data, dataLen, result, nullptr);
  if (ret == nullptr) {
    NDN_THROW(std::runtime_error("Error computing HMAC when calling HMAC()"));
  }
}

size_t
hkdf(const uint8_t* secret, size_t secretLen, const uint8_t* salt,
     size_t saltLen, uint8_t* output, size_t outputLen,
     const uint8_t* info, size_t infoLen)
{
  EVP_PKEY_CTX* pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr);
  EVP_PKEY_derive_init(pctx);
  EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256());
  EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, saltLen);
  EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, secretLen);
  EVP_PKEY_CTX_add1_hkdf_info(pctx, info, infoLen);
  size_t outLen = outputLen;
  auto resultCode = EVP_PKEY_derive(pctx, output, &outLen);
  EVP_PKEY_CTX_free(pctx);
  if (resultCode == 0) {
    NDN_THROW(std::runtime_error("Error when calling HKDF"));
  }
  return outLen;

//  if (EVP_PKEY_derive_init(pctx) <= 0) {
//    EVP_PKEY_CTX_free(pctx);
//    NDN_THROW(std::runtime_error("HKDF: Cannot init ctx when calling EVP_PKEY_derive_init()"));
//  }
//  if (EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()) <= 0) {
//    EVP_PKEY_CTX_free(pctx);
//    NDN_THROW(std::runtime_error("HKDF: Cannot set md when calling EVP_PKEY_CTX_set_hkdf_md()"));
//  }
//  if (EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt, saltLen) <= 0) {
//    EVP_PKEY_CTX_free(pctx);
//    NDN_THROW(std::runtime_error("HKDF: Cannot set salt when calling EVP_PKEY_CTX_set1_hkdf_salt()"));
//  }
//  if (EVP_PKEY_CTX_set1_hkdf_key(pctx, secret, secretLen) <= 0) {
//    EVP_PKEY_CTX_free(pctx);
//    NDN_THROW(std::runtime_error("HKDF: Cannot set secret when calling EVP_PKEY_CTX_set1_hkdf_key()"));
//  }
//  if (EVP_PKEY_CTX_add1_hkdf_info(pctx, info, infoLen) <= 0) {
//    EVP_PKEY_CTX_free(pctx);
//    NDN_THROW(std::runtime_error("HKDF: Cannot set info when calling EVP_PKEY_CTX_add1_hkdf_info()"));
//  }
//  size_t outLen = outputLen;
//  if (EVP_PKEY_derive(pctx, output, &outLen) <= 0) {
//    EVP_PKEY_CTX_free(pctx);
//    NDN_THROW(std::runtime_error("HKDF: Cannot derive result when calling EVP_PKEY_derive()"));
//  }
}

size_t
aesGcm128Encrypt(const uint8_t* plaintext, size_t plaintextLen, const uint8_t* associated, size_t associatedLen,
                 const uint8_t* key, const uint8_t* iv, uint8_t* ciphertext, uint8_t* tag)
{
  int len = 0;
  size_t ciphertextLen = 0;
  EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
  EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr);
  EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, nullptr);
  EVP_EncryptInit_ex(ctx, nullptr, nullptr, key, iv);
  EVP_EncryptUpdate(ctx, nullptr, &len, associated, associatedLen);
  EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintextLen);
  ciphertextLen = len;
  EVP_EncryptFinal_ex(ctx, ciphertext + len, &len);
  auto resultCode = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag);
  EVP_CIPHER_CTX_free(ctx);
  if (resultCode == 0) {
    NDN_THROW(std::runtime_error("Error in encryption plaintext with AES GCM"));
  }
  return ciphertextLen;

//  if (!(ctx = EVP_CIPHER_CTX_new())) {
//    NDN_THROW(std::runtime_error("Cannot create and initialise the context when calling EVP_CIPHER_CTX_new()"));
//  }
//  if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot initialize the encryption operation when calling EVP_EncryptInit_ex()"));
//  }
//  if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, nullptr)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot set IV length when calling EVP_CIPHER_CTX_ctrl()"));
//  }
//  if (1 != EVP_EncryptInit_ex(ctx, nullptr, nullptr, key, iv)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot initialize key and IV when calling EVP_EncryptInit_ex()"));
//  }
//  if (1 != EVP_EncryptUpdate(ctx, nullptr, &len, associated, associatedLen)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot set associated authentication data when calling EVP_EncryptUpdate()"));
//  }
//  if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintextLen)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot encrypt when calling EVP_EncryptUpdate()"));
//  }
//  ciphertextLen = len;
//  if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot finalise the encryption when calling EVP_EncryptFinal_ex()"));
//  }
//  ciphertextLen += len;
//  if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot get tag when calling EVP_CIPHER_CTX_ctrl()"));
//  }
}

size_t
aesGcm128Decrypt(const uint8_t* ciphertext, size_t ciphertextLen, const uint8_t* associated, size_t associatedLen,
                 const uint8_t* tag, const uint8_t* key, const uint8_t* iv, uint8_t* plaintext)
{
  int len = 0;
  size_t plaintextLen = 0;
  EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new();
  EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr);
  EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, nullptr);
  EVP_DecryptInit_ex(ctx, nullptr, nullptr, key, iv);
  EVP_DecryptUpdate(ctx, nullptr, &len, associated, associatedLen);
  EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertextLen);
  plaintextLen = len;
  EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, const_cast<void*>(reinterpret_cast<const void*>(tag)));
  auto resultCode = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
  plaintextLen += len;
  EVP_CIPHER_CTX_free(ctx);
  if (resultCode == 0) {
    NDN_THROW(std::runtime_error("Error in decrypting ciphertext with AES GCM"));
  }
  return plaintextLen;

//  if (!(ctx = EVP_CIPHER_CTX_new())) {
//    NDN_THROW(std::runtime_error("Cannot create and initialise the context when calling EVP_CIPHER_CTX_new()"));
//  }
//  if (!EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), nullptr, nullptr, nullptr)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot initialise the decryption operation when calling EVP_DecryptInit_ex()"));
//  }
//  if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 12, nullptr)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot set IV length when calling EVP_CIPHER_CTX_ctrl"));
//  }
//  if (!EVP_DecryptInit_ex(ctx, nullptr, nullptr, key, iv)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot initialise key and IV when calling EVP_DecryptInit_ex()"));
//  }
//  if (!EVP_DecryptUpdate(ctx, nullptr, &len, associated, associatedLen)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot set associated authentication data when calling EVP_EncryptUpdate()"));
//  }
//  if (!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertextLen)) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot decrypt when calling EVP_DecryptUpdate()"));
//  }
//  plaintextLen = len;
//  if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, const_cast<void*>(reinterpret_cast<const void*>(tag)))) {
//    EVP_CIPHER_CTX_free(ctx);
//    NDN_THROW(std::runtime_error("Cannot set tag value when calling EVP_CIPHER_CTX_ctrl()"));
//  }
}

#ifndef NDNCERT_HAVE_TESTS
static
#endif
uint32_t
loadBigU32(const uint8_t* src) noexcept
{
#if BOOST_VERSION >= 107100
  return boost::endian::endian_load<uint32_t, 4, boost::endian::order::big>(src);
#else
  uint32_t dest;
  std::memcpy(reinterpret_cast<uint8_t*>(&dest), src, sizeof(dest));
  return boost::endian::big_to_native(dest);
#endif
}

#ifndef NDNCERT_HAVE_TESTS
static
#endif
void
storeBigU32(uint8_t* dest, uint32_t src) noexcept
{
#if BOOST_VERSION >= 107100
  boost::endian::endian_store<uint32_t, 4, boost::endian::order::big>(dest, src);
#else
  boost::endian::native_to_big_inplace(src);
  std::memcpy(dest, reinterpret_cast<const uint8_t*>(&src), sizeof(src));
#endif
}

static void
updateIv(std::vector<uint8_t>& iv, size_t payloadSize)
{
  BOOST_ASSERT(iv.size() >= 12);
  uint32_t counter = loadBigU32(&iv[8]);
  uint32_t increment = (payloadSize + 15) / 16;
  if (std::numeric_limits<uint32_t>::max() - counter <= increment) {
    NDN_THROW(std::runtime_error("Error incrementing the AES block counter: "
                                 "too many blocks have been encrypted for the same request instance"));
  }
  else {
    counter += increment;
  }
  storeBigU32(&iv[8], counter);
}

Block
encodeBlockWithAesGcm128(uint32_t tlvType, const uint8_t* key,
                         const uint8_t* payload, size_t payloadSize,
                         const uint8_t* associatedData, size_t associatedDataSize,
                         std::vector<uint8_t>& encryptionIv)
{
  // The spec of AES encrypted payload TLV used in NDNCERT:
  //   https://github.com/named-data/ndncert/wiki/NDNCERT-Protocol-0.3#242-aes-gcm-encryption
  ndn::Buffer encryptedPayload(payloadSize);
  if (encryptionIv.empty()) {
    encryptionIv.resize(12, 0);
    ndn::random::generateSecureBytes(ndn::make_span(encryptionIv).first(8));
  }

  uint8_t tag[16];
  size_t encryptedPayloadLen = aesGcm128Encrypt(payload, payloadSize, associatedData, associatedDataSize,
                                                key, encryptionIv.data(), encryptedPayload.data(), tag);

  Block content(tlvType);
  content.push_back(ndn::makeBinaryBlock(tlv::InitializationVector, encryptionIv));
  content.push_back(ndn::makeBinaryBlock(tlv::AuthenticationTag, tag));
  content.push_back(ndn::makeBinaryBlock(tlv::EncryptedPayload,
                                         ndn::make_span(encryptedPayload).first(encryptedPayloadLen)));
  content.encode();
  // update IV's counter
  updateIv(encryptionIv, payloadSize);
  return content;
}

ndn::Buffer
decodeBlockWithAesGcm128(const Block& block, const uint8_t* key,
                         const uint8_t* associatedData, size_t associatedDataSize,
                         std::vector<uint8_t>& decryptionIv, const std::vector<uint8_t>& encryptionIv)
{
  // The spec of AES encrypted payload TLV used in NDNCERT:
  //   https://github.com/named-data/ndncert/wiki/NDNCERT-Protocol-0.3#242-aes-gcm-encryption
  block.parse();
  const auto& encryptedPayloadBlock = block.get(tlv::EncryptedPayload);
  ndn::Buffer result(encryptedPayloadBlock.value_size());
  if (block.get(tlv::InitializationVector).value_size() != 12 ||
      block.get(tlv::AuthenticationTag).value_size() != 16) {
    NDN_THROW(std::runtime_error("Error when decrypting the AES Encrypted Block: "
                                 "The observed IV or Authentication Tag is of an unexpected size."));
  }
  std::vector<uint8_t> observedDecryptionIv(block.get(tlv::InitializationVector).value(),
                                            block.get(tlv::InitializationVector).value() + 12);
  if (!encryptionIv.empty()) {
    if (std::equal(observedDecryptionIv.begin(), observedDecryptionIv.begin() + 8, encryptionIv.begin())) {
      NDN_THROW(std::runtime_error("Error when decrypting the AES Encrypted Block: "
                                   "The observed IV's the random component should be different from ours."));
    }
  }
  if (!decryptionIv.empty()) {
    if (loadBigU32(&observedDecryptionIv[8]) < loadBigU32(&decryptionIv[8]) ||
        !std::equal(observedDecryptionIv.begin(), observedDecryptionIv.begin() + 8, decryptionIv.begin())) {
      NDN_THROW(std::runtime_error("Error when decrypting the AES Encrypted Block: "
                                   "The observed IV's counter should be monotonically increasing "
                                   "and the random component must be the same from the requester."));
    }
  }
  decryptionIv = observedDecryptionIv;
  auto resultLen = aesGcm128Decrypt(encryptedPayloadBlock.value(), encryptedPayloadBlock.value_size(),
                                    associatedData, associatedDataSize, block.get(tlv::AuthenticationTag).value(),
                                    key, decryptionIv.data(), result.data());
  if (resultLen != encryptedPayloadBlock.value_size()) {
    NDN_THROW(std::runtime_error("Error when decrypting the AES Encrypted Block: "
                                 "Decrypted payload is of an unexpected size."));
  }
  updateIv(decryptionIv, resultLen);
  return result;
}

} // namespace ndncert
