/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
 * Copyright (c) 2014-2018, Regents of the University of California
 *
 * This file is part of NAC (Name-Based Access Control for NDN).
 * See AUTHORS.md for complete list of NAC authors and contributors.
 *
 * NAC 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.
 *
 * NAC 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 a copy of the GNU General Public License along with
 * NAC, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "algo/aes.hpp"

#include "boost-test.hpp"
#include <algorithm>

namespace ndn {
namespace nac {
namespace algo {
namespace tests {

const uint8_t key[] = {0xdd, 0x60, 0x77, 0xec, 0xa9, 0x6b, 0x23, 0x1b,
                       0x40, 0x6b, 0x5a, 0xf8, 0x7d, 0x3d, 0x55, 0x32};

// plaintext: AES-Encrypt-Test
const uint8_t plaintext[] = { 0x41, 0x45, 0x53, 0x2d, 0x45, 0x6e, 0x63, 0x72,
                              0x79, 0x70, 0x74, 0x2d, 0x54, 0x65, 0x73, 0x74};

// const uint8_t ciphertext_ecb[] = {0xcb, 0xe5, 0x6a, 0x80, 0x41, 0x24, 0x58, 0x23, 0x84, 0x14, 0x15,
//                                   0x61, 0x80, 0xb9, 0x5e, 0xbd, 0xce, 0x32, 0xb4, 0xbe, 0xbc, 0x91,
//                                   0x31, 0xd6, 0x19, 0x00, 0x80, 0x8b, 0xfa, 0x00, 0x05, 0x9c};

const uint8_t initvector[] = {0x6f, 0x53, 0x7a, 0x65, 0x58, 0x6c, 0x65, 0x75,
                              0x44, 0x4c, 0x77, 0x35, 0x58, 0x63, 0x78, 0x6e};

const uint8_t ciphertext_cbc_iv[] = {0xb7, 0x19, 0x5a, 0xbb, 0x23, 0xbf, 0x92, 0xb0,
                                     0x95, 0xae, 0x74, 0xe9, 0xad, 0x72, 0x7c, 0x28,
                                     0x6e, 0xc6, 0x73, 0xb5, 0x0b, 0x1a, 0x9e, 0xb9,
                                     0x4d, 0xc5, 0xbd, 0x8b, 0x47, 0x1f, 0x43, 0x00};

BOOST_AUTO_TEST_SUITE(TestAesAlgorithm)

BOOST_AUTO_TEST_CASE(EncryptionDecryption)
{
  AesKeyParams params;
  EncryptParams eparams(tlv::AlgorithmAesEcb, 16);

  DecryptKey<Aes> decryptKey(Buffer(key, sizeof(key)));
  EncryptKey<Aes> encryptKey = Aes::deriveEncryptKey(decryptKey.getKeyBits());

  // check if loading key and key derivation
  BOOST_CHECK_EQUAL_COLLECTIONS(encryptKey.getKeyBits().begin(),
                                encryptKey.getKeyBits().end(),
                                key, key + sizeof(key));
  BOOST_CHECK_EQUAL_COLLECTIONS(decryptKey.getKeyBits().begin(),
                                decryptKey.getKeyBits().end(),
                                key, key + sizeof(key));

  // Comment out the test of AES_ECB because NAC no longer supports CBC.
  // Compared with ECB, CBC is more secure.

  // // encrypt data in AES_ECB
  // Buffer cipherBuf = Aes::encrypt(key, sizeof(key), plaintext, sizeof(plaintext), eparams);
  // BOOST_CHECK_EQUAL_COLLECTIONS(cipherBuf.begin(),
  //                               cipherBuf.end(),
  //                               ciphertext_ecb,
  //                               ciphertext_ecb + sizeof(ciphertext_ecb));

  // // decrypt data in AES_ECB
  // Buffer recvBuf = Aes::decrypt(key, sizeof(key), cipherBuf.data(), cipherBuf.size(), eparams);
  // BOOST_CHECK_EQUAL_COLLECTIONS(recvBuf.begin(),
  //                               recvBuf.end(),
  //                               plaintext,
  //                               plaintext + sizeof(plaintext));

  // encrypt/decrypt data in AES_CBC with auto-generated IV
  eparams.setAlgorithmType(tlv::AlgorithmAesCbc);
  Buffer cipherBuf = Aes::encrypt(key, sizeof(key), plaintext, sizeof(plaintext), eparams);
  Buffer recvBuf = Aes::decrypt(key, sizeof(key), cipherBuf.data(), cipherBuf.size(), eparams);
  BOOST_CHECK_EQUAL_COLLECTIONS(recvBuf.begin(), recvBuf.end(),
                                plaintext, plaintext + sizeof(plaintext));

  // encrypt data in AES_CBC with specified IV
  eparams.setIV(initvector, 16);
  cipherBuf = Aes::encrypt(key, sizeof(key), plaintext, sizeof(plaintext), eparams);
  BOOST_CHECK_EQUAL_COLLECTIONS(cipherBuf.begin(), cipherBuf.end(),
                                ciphertext_cbc_iv, ciphertext_cbc_iv + sizeof(ciphertext_cbc_iv));

  // decrypt data in AES_CBC with specified IV
  recvBuf = Aes::decrypt(key, sizeof(key), cipherBuf.data(), cipherBuf.size(), eparams);
  BOOST_CHECK_EQUAL_COLLECTIONS(recvBuf.begin(), recvBuf.end(),
                                plaintext, plaintext + sizeof(plaintext));
}

BOOST_AUTO_TEST_SUITE_END()

} // namespace tests
} // namespace algo
} // namespace nac
} // namespace ndn
