/// \file main.c devCrypt main chacha20 decryption library
/// \author Henrik Herranen, VLSI Solution Oy

/// This device creates a disk that is an image of another this.
/// However, data is being decrypted using the chacha20 descryption
/// algorithm.

#include <vo_stdio.h>
#include <volink.h>     // Linker directives like DLLENTRY
#include <apploader.h>  // RunLibraryFunction etc
#include <string.h>
#include <timers.h>
#include <kernel.h>
#include <ctype.h>

#define DEFAULT_INPUT_DEVICE 'D'
#define DEFAULT_OUTPUT_DEVICE 'E'
#define DEFAULT_HEXKEY_FILE_NAME "S:MY.KEY"
char inOutDev[2] = {DEFAULT_INPUT_DEVICE, DEFAULT_OUTPUT_DEVICE};

#define HEX_KEY_SIZE 128
char hexKey[HEX_KEY_SIZE] = "+devCrypt ";

int ReadHexFile(const char *fileName) {
  int res = 1;
  FILE *fp = fopen(fileName, "rb");
  int i;
  
  if (!fp) {
    printf("E: Couldn't open hexkey file \"%s\"\n", fileName);
    goto finally;
  }

  fgets(hexKey+10, HEX_KEY_SIZE, fp);

  i = strlen(hexKey);
  while (i && isspace(hexKey[i-1])) {
    hexKey[--i] = '\0';
  }

  res = 0;
 finally:
  if (fp) {
    fclose(fp);
    fp = NULL;
  }
  return res;
}


ioresult main(char *parameters) {
  int nParam, i;
  char *p = parameters;
  int devNo = 0;
  ioresult retCode = S_ERROR;
  int hexRead = 0;

  nParam = RunProgram("ParamSpl", parameters);
  for (i=0; i<nParam; i++) {
    char firstUpperCase = *p & ~0x20;
    if (!strcmp(p, "-h")) {
      printf("Usage: LoadCrypt [inDev [outDev]] [hexName]\n"
	     "inDev\tInput device (default '%c')\n"
	     "outDev\tOutput device (default '%c')\n"
	     "hexName\tHEXKEY file name (default \"%s\")\n"
	     "-h\tShow this help\n",
	     DEFAULT_INPUT_DEVICE,
	     DEFAULT_OUTPUT_DEVICE,
	     DEFAULT_HEXKEY_FILE_NAME);
      goto finally;
    } else if (strlen(p) == 1 && devNo < 2 &&
	       firstUpperCase >= 'A' && firstUpperCase <= 'Z') {
      inOutDev[devNo++] = firstUpperCase;
    } else {
      if (ReadHexFile(p)) {
	inOutDev[1] = 0;
	goto finally;
      }
      hexRead = 1;
#if 0
    } else {
      printf("W: Unknown parameter \"%s\", ignoring\n", p);
#endif
    }
    p += strlen(p)+1;
  }

      
  if (!hexRead && ReadHexFile(DEFAULT_HEXKEY_FILE_NAME)) {
    inOutDev[1] = 0;
    goto finally;
  }

  i = strlen(hexKey);
  if (i >= HEX_KEY_SIZE - 5) {
    printf("E: Can't form string for devCrypt\n");
  }
  sprintf(hexKey+i, " %c %c", inOutDev[0], inOutDev[1]);
  printf("\n\nNOTE!\n"
	 "LoadCrypt IS MEANT FOR DEMONSTRATION PURPOSES ONLY!\n"
	 "DO NOT USE LoadCrypt IN YOUR COMMERCIAL APPLICATION!\n"
	 "It is a completely unsafe program that cannot in any way\n"
	 "hide the secret hex key that it provides to devCrypt!\n"
	 "Actually, you will see the secret key a few lines below.\n"
	 "For information on how to hide your secret key for your\n"
	 "commercial application, please contact VLSI Solution directly,\n"
	 "e.g. at sales@vlsi.fi!\n\n");
  printf("Going to run:\ndriver %s\n", hexKey);
  Delay(100);
  RunProgram("driver", hexKey);
  retCode = S_OK;
 finally:
  return retCode;
}
