// ---------------------------------------------------------------------------
// - t_aes.cpp                                                               -
// - afnix cryptography - aes class tester module                            -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  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.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2008 amaury darsch                                   -
// ---------------------------------------------------------------------------

#include "Aes.hpp"
#include "InputOutput.hpp"
#include "InputString.hpp"
#include "OutputString.hpp"

int main (int, char**) {
  using namespace afnix;
  // FIPS-197 128 test key
  const t_byte FIPS_KEY_128 [] = {
    0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 
    0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
  };
  
  // FIPS-197 16 bytes input test
  const t_byte FIPS_TEST_BI [] = {
    0x32, 0x43, 0xF6, 0xA8, 0x88, 0x5A, 0x30, 0x8D,
    0x31, 0x31, 0x98, 0xA2, 0xE0, 0x37, 0x07, 0x34
  };

  // FIPS-197 16 bytes output result
  const t_byte FIPS_TEST_BO [] = {
    0x39, 0x25, 0x84, 0x1D, 0x02, 0xDC, 0x09, 0xFB,
    0xDC, 0x11, 0x85, 0x97, 0x19, 0x6A, 0x0B, 0x32
  };

  // create a 128 bits key
  Key key (Key::K128, FIPS_KEY_128);

  // create an AES cipher with a 128 bits key
  Aes aes (key);
  if (aes.getname () != "AES") return 1;

  // check the size normalization
  if (aes.waist (0)  != 16) return 1;
  if (aes.waist (20) != 32) return 1;
  if (aes.waist (48) != 48) return 1;

  // create 16 bytes output buffer and process
  t_byte bo[16];
  aes.process (bo, FIPS_TEST_BI);
  // check the result
  for (long i = 0; i < 16; i++) {
    if (bo[i] != FIPS_TEST_BO[i]) return 1;
  }

  // reverse the cipher, process and check
  aes.setrflg (true);
  aes.process (bo, FIPS_TEST_BO);
  // check the result
  for (long i = 0; i < 16; i++) {
    if (bo[i] != FIPS_TEST_BI[i]) return 1;
  }

  // reset the cipher to crypt mode
  aes.setrflg (false);

  // create an input string and an input-output stream
  String      ts = "hello world";
  InputString is (ts);
  InputOutput io;

  // crypt the string
  if (aes.stream (io, is) != ts.length ()) return 1;

  // reverse the cipher - this test works since the default
  // padding is made with null character so a long block
  // end up anyway to the original string
  aes.setrflg (true);
  OutputString os;
  aes.stream (os, io);
  if (os.tostring () != ts) return 1;

  // success
  return 0;
}
