home *** CD-ROM | disk | FTP | other *** search
- {$A+,B-,D-,E+,F-,G+,I+,L-,N-,O-,R-,S-,V-,X+}
- {$M 4048,0,131040}
- Program encrypt;
-
- { Author Trevor J Carlsen - released into the public domain 1992 }
- { PO Box 568 }
- { Port Hedland }
- { Western Australia 6721 }
- { Voice +61 91 73 2026 Data +61 91 73 2569 }
- { FidoNet 3:690/644 }
-
- { Syntax: encrypt /p=PassWord /k=KeyFile /f=File }
- { Example - }
- { encrypt /p=billbloggs /k=c:\command.com /f=p:\prog\anyFile.pas }
-
- { PassWord can be any alpha-numeric sequence of AT LEAST four }
- { Characters. }
-
- { KeyFile is the full path of any File on the system that this }
- { Program runs on. This File, preferably a large one, must not }
- { be subject to changes. This is critical as it is used as a }
- { pseudo "one time pad" style key and the slightest change will }
- { render decryption invalid. }
-
- { File is the full path of the File to be encrypted or decrypted.}
-
- { notes: Running Encrypt a second time With exactly the same parameters }
- { decrypts an encrypted File. For total security the keyFile }
- { can be stored separately on a floppy. Without this keyFile or }
- { knowledge of its contents it is IMPOSSIBLE to decrypt the }
- { encrypted File. }
-
- { Parameters are Case insensitive and may be in any order and }
- { may not contain any Dos separator Characters. }
-
- Const
- BufferSize = 65520;
- Renamed : Boolean = False;
-
- Type
- buffer_ = Array[0..BufferSize - 1] of Byte;
- buffptr = ^buffer_;
- str80 = String[80];
-
- Var
- OldExitProc : Pointer;
- KeyFile,
- OldFile,
- NewFile : File;
- KeyBuffer,
- Buffer : buffptr;
- KeyFileSize,
- EncFileSize : LongInt;
- PassWord,
- KFName,
- FFName : str80;
-
- Procedure Hash(p : Pointer; numb : Byte; Var result: LongInt);
- { When originally called numb must be equal to sizeof }
- { whatever p is pointing at. if that is a String numb }
- { should be equal to length(the_String) and p should be }
- { ptr(seg(the_String),ofs(the_String)+1) }
- Var
- temp,
- w : LongInt;
- x : Byte;
-
- begin
- temp := LongInt(p^); RandSeed := temp;
- For x := 0 to (numb - 4) do begin
- w := random(maxint) * random(maxint) * random(maxint);
- temp := ((temp shr random(16)) shl random(16)) +
- w + MemL[seg(p^):ofs(p^)+x];
- end;
- result := result xor temp;
- end; { Hash }
-
- Procedure NewExitProc; Far;
- { Does the "housekeeping" necessary on Program termination }
- Var code : Integer;
- begin
- ExitProc := OldExitProc; { Reset Exit Procedure Pointer to original }
- Case ExitCode of
- 0: Writeln('Successfully encrypted or decrypted ',FFName);
- 1: begin
- Writeln('This Program requires 3 parameters -');
- Writeln(' /pPassWord');
- Writeln(' /kKeyFile (full path and name)');
- Write (' /fFile (The full path and name of the File');
- Writeln(' to be processed)');
- Writeln;
- Write ('These parameters can be in any order, are Case,');
- Writeln(' insensitive, and may not contain any spaces.');
- end;
- 2: Writeln('Could not find key File');
- 3: Writeln('Could not rename and/or open original File');
- 4: Writeln('Could not create encrypted File');
- 5: Writeln('I/O error during processing - could not Complete');
- 6: Writeln('Insufficient memory available');
- 7: begin
- Writeln('Key File is too small - aborted');
- Writeln;
- Writeln(' Key File must be at least as large as the buffer size ');
- Write (' or the size of the File to be encrypted, whatever is the');
- Writeln(' smaller.');
- end;
- 8: Writeln('PassWord must consist of at least 4 Characters');
- else { any other error }
- Writeln('Aborted With error ',ExitCode);
- end; { Case }
- if Renamed and (ExitCode <> 0) then
- Writeln(#7'WARNinG: original File''s name is now TEMP.$$$');
- {$I-}
- close(KeyFile); Code := Ioresult;
- close(NewFile); Code := Ioresult;
- close(OldFile); Code := Ioresult;
- if ExitCode = 0 then
- Erase(OldFile); Code := Ioresult;
- {$I+}
- end; { NewExitProc }
-
-
- Function Str2UpCase(Var S: String): String;
- { Converts a String S to upper Case. Valid For English. }
- Var
- x : Byte;
- begin
- Str2UpCase[0] := S[0];
- For x := 1 to length(S) do
- Str2UpCase[x] := UpCase(S[x]);
- end; { Str2UpCase }
-
- Procedure Initialise;
- Var
- CommandLine : String;
- FPos,FLen,
- KPos,KLen,
- PPos,PLen : Byte;
-
- Procedure AllocateMemory(Var p: buffptr; size: LongInt);
- begin
- if size < BufferSize then begin
- if MaxAvail < size then halt(6);
- GetMem(p,size);
- end
- else begin
- if MaxAvail < BufferSize then halt(6);
- new(p);
- end;
- end; { AllocateMemory }
-
- begin
- FillChar(OldExitProc,404,0); { Initialise all global Variables }
- FillChar(PassWord,243,32);
- ExitProc := @NewExitProc; { Set up new Exit Procedure }
- if ParamCount <> 3 then halt(1);
- CommandLine := String(ptr(PrefixSeg,$80)^)+' '; { Add trailing space }
- CommandLine := Str2UpCase(CommandLine); { Convert to upper Case }
- PPos := pos('/P=',CommandLine); { Find passWord parameter }
- KPos := pos('/K=',CommandLine); { Find keyFile parameter }
- FPos := pos('/F=',CommandLine); { Find Filename For encryption}
- if (PPos = 0) or (KPos = 0) or (FPos = 0) then Halt(1);
- FFName := copy(CommandLine,FPos+3,80);
- FFName[0] := chr(pos(' ',FFName)-1); { Correct String length }
- KFName := copy(CommandLine,KPos+3,80);
- KFName[0] := chr(pos(' ',KFName)-1);
- PassWord := copy(CommandLine,PPos+3,80);
- PassWord[0] := chr(pos(' ',PassWord)-1);
- if length(PassWord) < 4 then halt(8);
- { Create a random seed value based on the passWord }
- Hash(ptr(seg(PassWord),ofs(PassWord)+1),length(PassWord),RandSeed);
- assign(OldFile,FFName);
- {$I-}
- rename(OldFile,'TEMP.$$$');
- if Ioresult <> 0 then
- halt(3)
- else
- renamed := True;
- assign(OldFile,'TEMP.$$$');
- reset(OldFile,1);
- if Ioresult <> 0 then halt(3);
- assign(NewFile,FFName);
- reWrite(NewFile,1);
- if Ioresult <> 0 then halt(4);
- assign(KeyFile,KFName);
- reset(KeyFile,1);
- if Ioresult <> 0 then halt(2);
- EncFileSize := FileSize(OldFile);
- KeyFileSize := FileSize(KeyFile);
- if KeyFileSize > EncFileSize then
- KeyFileSize := EncFileSize;
- if Ioresult <> 0 then halt(5);
- {$I+}
- if (KeyFileSize < BufferSize) and (KeyFileSize < EncFileSize) then
- halt(7);
- AllocateMemory(buffer,EncFileSize);
- AllocateMemory(KeyBuffer,KeyFileSize);
- end; { Initialise }
-
- Procedure Main;
- Var
- BytesRead : Word;
- finished : Boolean;
-
- Procedure CodeBuffer(number: Word);
- { This is the actual encryption/decryption engine }
- Var x : Word;
- begin
- For x := 0 to number - 1 do
- buffer^[x] := buffer^[x] xor KeyBuffer^[x] xor Random(256);
- end; { CodeBuffer }
-
- begin
- {$I-}
- finished := False;
- Repeat
- BlockRead(OldFile,buffer^,BufferSize,BytesRead);
- if Ioresult <> 0 then halt(5);
- if (FilePos(KeyFile) + BytesRead) > KeyFileSize then
- seek(KeyFile,0);
- BlockRead(KeyFile,KeyBuffer^,BytesRead,BytesRead);
- if Ioresult <> 0 then halt(5);
- CodeBuffer(BytesRead);
- finished := BytesRead < BufferSize;
- BlockWrite(NewFile,buffer^,BytesRead);
- Until finished;
- end; { Main }
-
- begin
- Initialise;
- Main;
- end.