// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#include "aes_modes.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "aes.h"
#include "crypto.h"

#ifdef USE_BORING_SSL
char crypto_lib[10] = "BoringSSL";
#else
char crypto_lib[10] = "OpenSSL";
#endif

static int check_block(const unsigned char *actual,
                       const unsigned char *expected, const int print) {
  for (int i = 0; i < 16; i++) {
    if (actual[i] != expected[i]) {
      if (print) {
        printf("ERROR: block mismatch. Found %#x, expected %#x\n", actual[i],
               expected[i]);
      }
      return 1;
    }
  }

  return 0;
}

static int crypto_compare(const unsigned char *cipher_text,
                          const unsigned char *iv,
                          const unsigned char *plain_text, int len,
                          const unsigned char *key, int key_len,
                          crypto_mode_t mode) {
  const unsigned char *data_in;
  int ret_len;
  int ret_len_exp = len;

  // Enc
  unsigned char *data_out =
      (unsigned char *)malloc(ret_len_exp * sizeof(unsigned char));
  if (data_out == NULL) {
    printf("ERROR: malloc() failed\n");
    return 1;
  }
  data_in = plain_text;

  ret_len = crypto_encrypt(data_out, iv, data_in, len, key, key_len, mode);
  if (ret_len != ret_len_exp) {
    printf("ERROR: ret_len = %i, expected %i. Aborting now\n", ret_len,
           ret_len_exp);
    return 1;
  }

  for (int j = 0; j < len / 16; ++j) {
    if (!check_block(&data_out[j * 16], &cipher_text[j * 16], 1)) {
      printf("SUCCESS: %s encrypt output matches NIST example cipher text\n",
             crypto_lib);
    } else {
      printf(
          "ERROR: %s encrypt output does not match NIST example cipher text\n",
          crypto_lib);
      printf("Input: \t\t");
      aes_print_block(&data_in[j * 16], 16);
      printf("Output: \t");
      aes_print_block(&data_out[j * 16], 16);
      printf("Expected: \t");
      aes_print_block(&cipher_text[j * 16], 16);
      return 1;
    }
  }

  // Dec
  unsigned char *data_in_dec =
      (unsigned char *)malloc(ret_len_exp * sizeof(unsigned char));
  if (data_in_dec == NULL) {
    printf("ERROR: malloc() failed\n");
    return 1;
  }
  for (int j = 0; j < ret_len; ++j) {
    data_in_dec[j] = data_out[j];
  }

  ret_len =
      crypto_decrypt(data_out, iv, data_in_dec, ret_len, key, key_len, mode);
  if (ret_len != len) {
    printf("ERROR: ret_len = %i, expected %i. Aborting now\n", ret_len, len);
    return 1;
  }

  for (int j = 0; j < len / 16; ++j) {
    if (!check_block(&data_out[j * 16], &plain_text[j * 16], 1)) {
      printf("SUCCESS: %s decrypt output matches NIST example plain text\n",
             crypto_lib);
    } else {
      printf(
          "ERROR: %s decrypt output does not match NIST example plain text\n",
          crypto_lib);
      printf("Input: \t\t");
      aes_print_block(&data_in_dec[j * 16], 16);
      printf("Output: \t");
      aes_print_block(&data_out[j * 16], 16);
      printf("Expected: \t");
      aes_print_block(&plain_text[j * 16], 16);
      return 1;
    }
  }

  free(data_out);
  free(data_in_dec);

  return 0;
}

int main(int argc, char *argv[]) {
  const int len = 64;
  int key_len;
  crypto_mode_t mode;
  const unsigned char *iv;
  const unsigned char *key;
  const unsigned char *cipher_text;

  /////////
  // ECB //
  /////////
  iv = kAesModesIvEcb;
  mode = kCryptoAesEcb;

  for (int i = 0; i < 3; ++i) {
    if (i == 0) {
      printf("ECB AES-128\n");
      key_len = 16;
      key = kAesModesKey128;
      cipher_text = kAesModesCipherTextEcb128;
    } else if (i == 1) {
      printf("ECB AES-192\n");
      key_len = 24;
      key = kAesModesKey192;
      cipher_text = kAesModesCipherTextEcb192;
    } else {  // i==2
      printf("ECB AES-256\n");
      key_len = 32;
      key = kAesModesKey256;
      cipher_text = kAesModesCipherTextEcb256;
    }

    if (crypto_compare(cipher_text, iv, kAesModesPlainText, len, key, key_len,
                       mode)) {
      return 1;
    }
  }

  /////////
  // CBC //
  /////////
  iv = kAesModesIvCbc;
  mode = kCryptoAesCbc;

  for (int i = 0; i < 3; ++i) {
    if (i == 0) {
      printf("CBC AES-128\n");
      key_len = 16;
      key = kAesModesKey128;
      cipher_text = kAesModesCipherTextCbc128;
    } else if (i == 1) {
      printf("CBC AES-192\n");
      key_len = 24;
      key = kAesModesKey192;
      cipher_text = kAesModesCipherTextCbc192;
    } else {  // i==2
      printf("CBC AES-256\n");
      key_len = 32;
      key = kAesModesKey256;
      cipher_text = kAesModesCipherTextCbc256;
    }

    if (crypto_compare(cipher_text, iv, kAesModesPlainText, len, key, key_len,
                       mode)) {
      return 1;
    }
  }

  /////////
  // CFB //
  /////////
  // CFB-128 to be precise.
  iv = kAesModesIvCfb;
  mode = kCryptoAesCfb;

  for (int i = 0; i < 3; ++i) {
    if (i == 0) {
      printf("CFB AES-128\n");
      key_len = 16;
      key = kAesModesKey128;
      cipher_text = kAesModesCipherTextCfb128;
    } else if (i == 1) {
      printf("CFB AES-192\n");
      key_len = 24;
      key = kAesModesKey192;
      cipher_text = kAesModesCipherTextCfb192;
    } else {  // i==2
      printf("CFB AES-256\n");
      key_len = 32;
      key = kAesModesKey256;
      cipher_text = kAesModesCipherTextCfb256;
    }

    if (crypto_compare(cipher_text, iv, kAesModesPlainText, len, key, key_len,
                       mode)) {
      return 1;
    }
  }

  /////////
  // OFB //
  /////////
  iv = kAesModesIvOfb;
  mode = kCryptoAesOfb;

  for (int i = 0; i < 3; ++i) {
    if (i == 0) {
      printf("OFB AES-128\n");
      key_len = 16;
      key = kAesModesKey128;
      cipher_text = kAesModesCipherTextOfb128;
    } else if (i == 1) {
      printf("OFB AES-192\n");
      key_len = 24;
      key = kAesModesKey192;
      cipher_text = kAesModesCipherTextOfb192;
    } else {  // i==2
      printf("OFB AES-256\n");
      key_len = 32;
      key = kAesModesKey256;
      cipher_text = kAesModesCipherTextOfb256;
    }

    if (crypto_compare(cipher_text, iv, kAesModesPlainText, len, key, key_len,
                       mode)) {
      return 1;
    }
  }

  /////////
  // CTR //
  /////////
  iv = kAesModesIvCtr;
  mode = kCryptoAesCtr;

  for (int i = 0; i < 3; ++i) {
    if (i == 0) {
      printf("CTR AES-128\n");
      key_len = 16;
      key = kAesModesKey128;
      cipher_text = kAesModesCipherTextCtr128;
    } else if (i == 1) {
      printf("CTR AES-192\n");
      key_len = 24;
      key = kAesModesKey192;
      cipher_text = kAesModesCipherTextCtr192;
    } else {  // i==2
      printf("CTR AES-256\n");
      key_len = 32;
      key = kAesModesKey256;
      cipher_text = kAesModesCipherTextCtr256;
    }

    if (crypto_compare(cipher_text, iv, kAesModesPlainText, len, key, key_len,
                       mode)) {
      return 1;
    }
  }

  return 0;
}
