// boost test header
#include <boost/test/unit_test.hpp>

// the crypto header
#include "utils/Cryptography.h"

// mock HAL
#include "ModuleFixture.hpp"

#include <string.h>

// test message, key and vectors
// from https://www.rfc-editor.org/rfc/rfc4493.html#section-4

static const unsigned char msg[64] = {
  0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
  0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
  0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
  0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
  0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
  0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
  0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
  0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
};

static unsigned char key[16] = {
  0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
  0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
};

static const unsigned char testVectEx1[] = {
  0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
  0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46
};

static const unsigned char testVectEx2[] = {
  0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
  0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c
};

static const unsigned char testVectEx3[] = {
  0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
  0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27
};

static const unsigned char testVectEx4[] = {
  0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
  0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe
};

static RadioLibSoftwareAES128 RadioLibAES128Instance;

BOOST_FIXTURE_TEST_SUITE(suite_Crypto, ModuleFixture)

BOOST_FIXTURE_TEST_CASE(Crypto_CMAC, ModuleFixture) {
  BOOST_TEST_MESSAGE("--- Test Crypto::CMAC ---");
  uint8_t cmac[RADIOLIB_AES128_BLOCK_SIZE];
  size_t testLen;

  BOOST_TEST_MESSAGE("--- Test Crypto::CMAC RFC 4493 chapter 4 Example 1: len = 0 ---");
  testLen = 0;
  hal->aes128 = &RadioLibAES128Instance;
  hal->aes128->init(key);
  hal->aes128->generateCMAC(msg, testLen, cmac);
  BOOST_TEST(memcmp(cmac, testVectEx1, RADIOLIB_AES128_BLOCK_SIZE) == 0);

  BOOST_TEST_MESSAGE("--- Test Crypto::CMAC RFC 4493 chapter 4 Example 2: len = 16 ---");
  testLen = 16;
  hal->aes128->init(key);
  hal->aes128->generateCMAC(msg, testLen, cmac);
  BOOST_TEST(memcmp(cmac, testVectEx2, RADIOLIB_AES128_BLOCK_SIZE) == 0);


  BOOST_TEST_MESSAGE("--- Test Crypto::CMAC RFC 4493 chapter 4 Example 2: len = 40 ---");
  testLen = 40;
  hal->aes128->init(key);
  hal->aes128->generateCMAC(msg, testLen, cmac);
  BOOST_TEST(memcmp(cmac, testVectEx3, RADIOLIB_AES128_BLOCK_SIZE) == 0);

  BOOST_TEST_MESSAGE("--- Test Crypto::CMAC RFC 4493 chapter 4 Example 2: len = 64 ---");
  testLen = 64;
  hal->aes128->init(key);
  hal->aes128->generateCMAC(msg, testLen, cmac);
  BOOST_TEST(memcmp(cmac, testVectEx4, RADIOLIB_AES128_BLOCK_SIZE) == 0);
}

BOOST_AUTO_TEST_SUITE_END()
