home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
PASCAL
/
ENDECR
/
ENDECR.PAS
Wrap
Pascal/Delphi Source File
|
1992-04-13
|
8KB
|
232 lines
{$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 { Parameters wrong }
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.$$$'); { Rename the file to be encrypted }
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 (FilePos(KeyFile) + BytesRead) > KeyFileSize then
seek(KeyFile,0);
BlockRead(KeyFile,KeyBuffer^,BytesRead,BytesRead);
CodeBuffer(BytesRead);
finished := BytesRead < BufferSize;
BlockWrite(NewFile,buffer^,BytesRead);
if IOResult <> 0 then halt(5);
until finished;
{$I+}
end; { Main }
begin
Initialise;
Main;
end.