UNIT _Feistel;

 (* ********************************************************************** *)
 (*              Header Implementation for Feistel Ciphers                 *)
 (*                    Hereby distributed as OPEN SOURCE                   *)
 (*                 Copyrighted by (2001) Dutra de Lacerda                 *)
 (* ********************************************************************** *)
 (*                                                                        *)
 (* This code is Open Source in respect to the similar status of Blowfish  *)
 (* It is Copyrighted by "(2001) Dutra de Lacerda"                         *)
 (* You are allowed to use it with the usual conditions:                   *)
 (*   - Maintain this Copyright notice in the code.                        *)
 (*   - Make reference to this code, and Author, in your application.      *)
 (*   - Graciously communicate the Author your use of this code.           *)
 (*                                                                        *)
 (* ---------------------------------------------------------------------- *)
 (*                                                                        *)
 (*                           Finding the Author                           *)
 (*                           ~~~~~~~~~~~~~~~~~~                           *)
 (*  This units author can be reached via the following E-Mail addresses:  *)
 (*                                                                        *)
 (*      Via InterNet    : dulac@ip.pt                                     *)
 (*            ...and    : dutra.lacerda@mail.telepac.pt                   *)
 (*                                                                        *)
 (* ---------------------------------------------------------------------- *)
 (*                                                                        *)
 (*                          Finding New Versions                          *)
 (*                          ~~~~~~~~~~~~~~~~~~~~                          *)
 (*      My Home Site    : http://planeta.ip.pt/~ip200075                  *)
 (*            ...and    : http://www.factor-h.com                         *)
 (*                                                                        *)
 (*      Net Archives    : ftp://garbo.uwasa.fi/pc/crypt                   *)
 (*                      : ftp://garbo.uwasa.fi/pc/security                *)
 (*                      : ftp://ftp.elf.stuba.sk/pub/pc/security          *)
 (*                                                                        *)
 (* ---------------------------------------------------------------------- *)

INTERFACE

Const
  CbcByDefault = true;    { CBC ON by default for Security }
  Xl = 0;               { Xl =  Left Half = Address 0 on Block_2x32 Array }
  Xr = 1;               { Xr = Right Half = Address 1 on Block_2x32 Array }

  AtomSize      = 4;              {32 bits}
  BlockSize     = (2 * AtomSize); {2x32 bits}

{$IFDEF DEBUG}
  BufferSize    = $200;  {512}
{$ELSE}
  BufferSize    = $B000; {44k}
{$ENDIF}
  BufferAtoms   = BufferSize div AtomSize;
  BufferBlocks  = BufferSize div BlockSize;

Type
    Crypt = OBJECT
        Constructor Init( var PSW :string );
        Procedure   Build( var PSW :string ); VIRTUAL;
        Procedure   EnCrypt ( pBuf :pointer; HowMany :integer ); VIRTUAL;
        Procedure   DeCrypt ( pBuf :pointer; HowMany :integer ); VIRTUAL;
        Destructor  Done; VIRTUAL;
    PRIVATE
        Procedure AbsErr ( S :string );
    end;

type
    Atom32    = RECORD
                    Case Boolean of
                       TRUE  : (Atom :LongInt);
                       FALSE : (byte :Array[0..3] of byte);
                    end;
    PAtom32   = ^Atom32;

    Block_2x32   = Array[0..1] of Atom32;
    PBlock_2x32  = ^Block_2x32;

    Buffer_2x32  = Array[0..(BufferAtoms-1)] of Atom32;
    pBuffer_2x32 = ^Buffer_2x32;

type
    Crypt_2x32 = OBJECT (Crypt)
        Rounds          :byte;
        IV_Box          :Block_2x32;        { Inicial }
        LastBlock       :Block_2x32;        { To CBC  }
        CBC_global      :Boolean;           {Must Know}
        CBC_status      :Boolean;           {Must Know}
        Constructor Init( var PSW :string );
        Procedure   Create_IV;
        Procedure   Set_IV ( B :Block_2x32 );
        Procedure   Get_IV  ( var B :Block_2x32 );
        Procedure   Start_IV;
        Procedure   Will_use_CBC ( Choice :boolean );
        Procedure   Hold_CBC ( Choice :boolean );
        Function    CBC_is_ON :boolean;
        Destructor  Done; VIRTUAL;
    end;

IMPLEMENTATION

USES Dos;

const
{$IFDEF DEBUG}
  Debug = TRUE;
{$ELSE}
  Debug = FALSE;
{$ENDIF}

(****** Crypt *******************************************************)

    Constructor Crypt.Init ( var PSW :string );
        begin
        AbsErr('Crypt.Init');
        end;

    Procedure Crypt.Build( var PSW :string );
        begin
        AbsErr('Crypt.Build');
        end;

    Procedure   Crypt.EnCrypt ( pBuf :pointer; HowMany :integer );
        begin
        AbsErr('Crypt.EnCrypt');
        end;

    Procedure   Crypt.DeCrypt ( pBuf :pointer; HowMany :integer );
        begin
        AbsErr('Crypt.DeCrypt');
        end;

    Destructor  Crypt.Done;
        begin
        AbsErr('Crypt.Done');
        end;

    Procedure   Crypt.AbsErr( S :string );
        begin
        Writeln('ERROR! Abstract Method Called: "', S , '"');
        end;

(****** Crypt_2x32 **************************************************)

    Constructor Crypt_2x32.Init( var PSW :string );
        begin
        Will_use_CBC( CbcByDefault );
        Build( PSW );
        Create_IV;
        Start_IV;
        end;

    Procedure   Crypt_2x32.Create_IV;
        const
          DebugNum = $AAAAAAAA;
        var
          Regs : Registers;
        begin
          Hold_CBC( True );

          If not Debug then
             begin
             Regs.AH := $2A;
             MsDos(Regs);
             with Regs do   { The order is not significant, choosed to put the }
               begin        { most variable data alternated with the less one. }
               IV_Box[0].byte[0] := CL;  { Low(Year)  }
               IV_Box[0].byte[1] := CH;  { High(Year) }
               IV_Box[0].byte[2] := DL;  { Month }
               IV_Box[0].byte[3] := DH;  { Day   }
               end;         { NOTICE that IV_Box[0] alters IV_Box[1] }
             Regs.AH := $2C;
             MsDos(Regs);
             with Regs do   { The order is not significant, choosed to put the }
               begin        { most variable data alternated with the less one. }
               IV_Box[1].byte[0] := CH;  { Hour   }
               IV_Box[1].byte[1] := DL;  { Hundreds of second }
               IV_Box[1].byte[2] := CL;  { Minute }
               IV_Box[1].byte[3] := DH;  { Second }
               end;         { NOTICE that IV_Box[0] alters IV_Box[1] }
             EnCrypt( @IV_Box , 1 );
             EnCrypt( @IV_Box , 1 );
             end
          else
             Begin
             IV_Box[Xl].Atom := DebugNum;
             IV_Box[Xr].Atom := DebugNum;
             end;
        Hold_CBC( False );
        end;

    Procedure   Crypt_2x32.Start_IV;
        begin
        LastBlock[Xl].Atom := IV_Box[Xl].Atom;
        LastBlock[Xr].Atom := IV_Box[Xr].Atom;
        end;

    Procedure   Crypt_2x32.Set_IV  ( B :Block_2x32 );
        begin
        IV_Box[Xl].Atom := B[Xl].Atom;
        IV_Box[Xr].Atom := B[Xr].Atom;
        end;

    Procedure   Crypt_2x32.Get_IV ( var B :Block_2x32 );
        begin
        B[Xl].Atom := IV_Box[Xl].Atom;
        B[Xr].Atom := IV_Box[Xr].Atom;
        end;

    Procedure   Crypt_2x32.Will_use_CBC ( Choice :boolean );
        begin
        CBC_global := Choice;
        CBC_status := Choice;
        end;

    Procedure   Crypt_2x32.Hold_CBC ( Choice :boolean );
        begin
        CBC_Status := ((Not Choice) AND CBC_Global);
        end;

    Function    Crypt_2x32.CBC_is_ON :boolean;
        begin
        CBC_is_ON := CBC_Status;
        end;

    Destructor  Crypt_2x32.Done;
        begin
        end;

(****** Main UNIT ****************************************************)

begin
end.
