#include "fullSpec.h"
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <fcntl.h>
#include <dos.h>
#include <dir.h>


#define IGNORE 0
#define RETRY  1
#define ABORT  2
#define BREAK  3
#define PlainDataLen   24000
#define CipherDataLen  24000

int handler(int errval,int ax,int bp,int si);

unsigned long cipherDataLen,plainDataLen;
BYTE *point;
BYTE wrkspc[60];
BYTE errmsg[256];
BYTE filename[256];
BYTE be_filename[256];
BYTE pathlogerr[256];
BYTE cipherKey[100];
BYTE decryptedMacKey[100];
BYTE macResult[100];
BYTE macResulth[100];
BYTE mode[2];

#include "alg-fst.c"
#include "api-fst.c"
#include "encdec.c"
#include "enckeys.c"
#include "encmac.c"
#include "hashcomp.c"
#include "maccomp.c"
#include "psswd.c"

void Hexa_To_Byte(char *, BYTE *);
void Byte_To_Hexa(BYTE *);

main(int argc, char *argv[])
{
  char drive[8];
  char dir[256];
  char file[16];
  char ext[8];

  point = errmsg;

  strcpy(filename,argv[1]);
  strcpy(mode,argv[2]);

  fnsplit(filename, drive, dir, file, ext);

  /* be_filename */
  fnmerge(be_filename, drive, dir, file, ".be");
  /*printf("be_filename: %s\n", be_filename);*/
  /* pathlogerr */
  fnmerge(pathlogerr, drive, dir, file, ".err");
  /*printf("pathlogerr: %s\n", pathlogerr);*/
  unlink(pathlogerr);

  Hexa_To_Byte(argv[3], decryptedMacKey);
  CalculMac(filename);
  Byte_To_Hexa(macResulth);

  if((mode[0] == 'w') ||  (mode[0] == 'W'))
  {
    Wmac(be_filename, macResulth);
    return(1);
  }
  else
  {
    if(!Cmac(be_filename, macResulth))
    {
      sprintf(errmsg,"Bad macResult '%s'", be_filename);
      Erreur(point);
    }
  }
}
/****************************************************************************/
/*             F I C H I E R     D E S    E R R E U R S                     */
Erreur(char *msg)
{
  FILE *fps;

  fps = fopen(pathlogerr,"a");
  fputs(msg,fps);
  fclose(fps);
  exit(0);
}

/*****************************************************************************/
Wmac(char *_filename, BYTE _Bffer[100])
{
  int fd;

  unlink(_filename);
  if((fd = open(_filename,O_CREAT | O_RDWR | O_BINARY,0x0100 | 0x0080)) == -1)
  {
    sprintf(errmsg,"error opening %s", _filename);
    Erreur(point);
  }

  write(fd,_Bffer,strlen(_Bffer));
  close(fd);
}

/*****************************************************************************/
Cmac(char *_filename, BYTE _Bffer[100])
{
  BYTE Bffer[17];
  int fd;

  if((fd = open(_filename,O_RDWR | O_BINARY,0x0100 | 0x0080)) == -1)
  {
    sprintf(errmsg,"error opening %s", _filename);
    Erreur(point);
  }

  read(fd,Bffer,16);
  close(fd);

  Bffer[16] = '\0';

  return(!memcmp(Bffer, _Bffer, 16));
}

/*****************************************************************************/
/*****************************************************************************/
error_win(int numerror)
{
 int retval;

  while(1)
  {
    switch(numerror)
    {
      case 0 :
         retval = RETRY;
         break;
      case 2 :
         retval = RETRY;
         break;
      default: retval = BREAK;
    }
    return(retval);
  }
}
/****************************************************************************/
int handler(int errval,int ax,int bp,int si)
{
   unsigned di;
   int drive;
   int errorno;

   di= _DI;
   if (ax < 0)
       hardretn(ABORT);

/* erreur disquette */
   errorno = di & 0x00FF;
   hardresume(error_win(errorno));
   return ABORT;
}

/****************************************************************************/
CalculMac(char *_filename)
{
  register int x, n, i, Carry,j;
  int  handel_Read;
  BYTE plainData [PlainDataLen];
  BYTE cipherData[CipherDataLen];
  BYTE Buffer [1050];
  j = 0;
  plainData[j] = 0x00;

  handel_Read = open(_filename, O_RDWR | O_BINARY,0x0100 | 0x0080);
  if(handel_Read == -1)
  {
    sprintf(errmsg,"Erreur d'ouverture du fichier %s\n",_filename);
    Erreur(point);
  }
  while((Carry = read(handel_Read,Buffer,1024)) != NULL)
   {
    computeMac (macResult, macResultLen, Buffer, Carry, decryptedMacKey);
    for(i = 0; i < macResultLen;i++,j++)
      plainData[j] = macResult[i];
   }
  plainData[j] = 0x00;
  close(handel_Read);

  computeMac(macResult, macResultLen, plainData, j, decryptedMacKey);
}

/*****************************************************************************/
void Hexa_To_Byte(char *_in, BYTE *_out)
/*****************************************************************************/
{
  BYTE Bffer[100],C1,C2;
  int i,j,n,Carry;

  strcpy(Bffer,_in);

  for ( i = 0 ; i <  64 ; i++)
  {
    if(Bffer[i] < 58) Bffer[i] -= 48;
    else              Bffer[i] -= 55;
  }

  for(i = 0, j = 0; j < 32 / 2; j++)
  {
    _out[j]   = Bffer[i++] << 4;
    _out[j]   = Bffer[i++] | _out[j];
  }
  _out[j] = 0x00;
}

/*****************************************************************************/
void Byte_To_Hexa(BYTE *_Bffer)
/*****************************************************************************/
{
  BYTE Cai[3];
  int i;

  _Bffer[0] = 0x00;
  for(i = 0; i < macResultLen;i++)
  {
    sprintf(Cai, "%02X",(unsigned char) macResult[i]);
    strcat(_Bffer,Cai);
  }
}
