/******************************************************************************
 *
 *  Copyright 2008-2012 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/******************************************************************************
 *
 *  This file contains the implementation of the AES128 and AES CMAC algorithm.
 *
 ******************************************************************************/

#include <algorithm>

#include "crypto_toolbox/aes.h"
#include "crypto_toolbox/crypto_toolbox.h"

namespace bluetooth {
namespace crypto_toolbox {

namespace {

typedef struct {
  uint8_t* text;
  uint16_t len;
  uint16_t round;
} tCMAC_CB;

thread_local tCMAC_CB cmac_cb;

/* Rb for AES-128 as block cipher, LSB as [0] */
Octet16 const_Rb{0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

/** utility function to do an biteise exclusive-OR of two bit strings of the
 * length of OCTET16_LEN. Result is stored in first argument.
 */
static void xor_128(Octet16* a, const Octet16& b) {
  // CHECK(a);
  uint8_t i, *aa = a->data();
  const uint8_t* bb = b.data();

  for (i = 0; i < OCTET16_LEN; i++) {
    aa[i] = aa[i] ^ bb[i];
  }
}
}  // namespace

/* This function computes AES_128(key, message) */
Octet16 aes_128(const Octet16& key, const Octet16& message) {
  Octet16 key_reversed;
  Octet16 message_reversed;
  Octet16 output;

  std::reverse_copy(key.begin(), key.end(), key_reversed.begin());
  std::reverse_copy(message.begin(), message.end(), message_reversed.begin());

  aes_context ctx;
  aes_set_key(key_reversed.data(), key_reversed.size(), &ctx);
  aes_encrypt(message_reversed.data(), output.data(), &ctx);

  std::reverse(output.begin(), output.end());
  return output;
}

/** utility function to padding the given text to be a 128 bits data. The
 * parameter dest is input and output parameter, it must point to a
 * OCTET16_LEN memory space; where include length bytes valid data. */
static void padding(Octet16* dest, uint8_t length) {
  uint8_t i, *p = dest->data();
  /* original last block */
  for (i = length; i < OCTET16_LEN; i++) p[OCTET16_LEN - i - 1] = (i == length) ? 0x80 : 0;
}

/** utility function to left shift one bit for a 128 bits value. */
static void leftshift_onebit(uint8_t* input, uint8_t* output) {
  uint8_t i, overflow = 0, next_overflow = 0;
  /* input[0] is LSB */
  for (i = 0; i < OCTET16_LEN; i++) {
    next_overflow = (input[i] & 0x80) ? 1 : 0;
    output[i] = (input[i] << 1) | overflow;
    overflow = next_overflow;
  }
  return;
}

/** This function is the calculation of block cipher using AES-128. */
static Octet16 cmac_aes_k_calculate(const Octet16& key) {
  Octet16 output;
  Octet16 x{0};  // zero initialized

  uint8_t i = 1;
  while (i <= cmac_cb.round) {
    /* Mi' := Mi (+) X  */
    xor_128((Octet16*)&cmac_cb.text[(cmac_cb.round - i) * OCTET16_LEN], x);

    output = aes_128(key, &cmac_cb.text[(cmac_cb.round - i) * OCTET16_LEN], OCTET16_LEN);
    x = output;
    i++;
  }

  return output;
}

/** This function proceeed to prepare the last block of message Mn depending on
 * the size of the message.
 */
static void cmac_prepare_last_block(const Octet16& k1, const Octet16& k2) {
  //    uint8_t     x[16] = {0};
  bool flag;

  /* last block is a complete block set flag to 1 */
  flag = ((cmac_cb.len % OCTET16_LEN) == 0 && cmac_cb.len != 0) ? true : false;

  if (flag) { /* last block is complete block */
    xor_128((Octet16*)&cmac_cb.text[0], k1);
  } else /* padding then xor with k2 */
  {
    padding((Octet16*)&cmac_cb.text[0], (uint8_t)(cmac_cb.len % 16));

    xor_128((Octet16*)&cmac_cb.text[0], k2);
  }
}

/** This is the function to generate the two subkeys.
 * |key| is CMAC key, expect SRK when used by SMP.
 */
static void cmac_generate_subkey(const Octet16& key) {
  Octet16 zero{};
  Octet16 p = aes_128(key, zero.data(), OCTET16_LEN);

  Octet16 k1, k2;
  uint8_t* pp = p.data();

  /* If MSB(L) = 0, then K1 = L << 1 */
  if ((pp[OCTET16_LEN - 1] & 0x80) != 0) {
    /* Else K1 = ( L << 1 ) (+) Rb */
    leftshift_onebit(pp, k1.data());
    xor_128(&k1, const_Rb);
  } else {
    leftshift_onebit(pp, k1.data());
  }

  if ((k1[OCTET16_LEN - 1] & 0x80) != 0) {
    /* K2 =  (K1 << 1) (+) Rb */
    leftshift_onebit(k1.data(), k2.data());
    xor_128(&k2, const_Rb);
  } else {
    /* If MSB(K1) = 0, then K2 = K1 << 1 */
    leftshift_onebit(k1.data(), k2.data());
  }

  cmac_prepare_last_block(k1, k2);
}

/** key - CMAC key in little endian order
 *  input - text to be signed in little endian byte order.
 *  length - length of the input in byte.
 */
Octet16 aes_cmac(const Octet16& key, const uint8_t* input, uint16_t length) {
  uint32_t len;
  uint16_t diff;
  /* n is number of rounds */
  uint16_t n = (length + OCTET16_LEN - 1) / OCTET16_LEN;

  if (n == 0) n = 1;
  len = n * OCTET16_LEN;

  /* allocate a memory space of multiple of 16 bytes to hold text  */
  cmac_cb.text = (uint8_t*)alloca(len);
  cmac_cb.round = n;
  diff = len - length;

  if (input != NULL && length > 0) {
    memcpy(&cmac_cb.text[diff], input, (int)length);
    cmac_cb.len = length;
  } else {
    cmac_cb.len = 0;
  }

  /* prepare calculation for subkey s and last block of data */
  cmac_generate_subkey(key);
  /* start calculation */
  Octet16 signature = cmac_aes_k_calculate(key);

  /* clean up */
  memset(&cmac_cb, 0, sizeof(tCMAC_CB));
  // cmac_cb.text is auto-freed by alloca

  return signature;
}

}  // namespace crypto_toolbox
}  // namespace bluetooth
