
	opt	D-			
	
; Assembly settings should be executable.  Change D- to D+ for debugging
; and use M+ to expand MACROs into listing during debugging
; compiled DEVPAC software (works on all versions).
 
;******************************************************************
;*								  *
;* Data Encryption program by Steve Meredith 1991.  The program   *
;* prevents unauthorised reading or use of a file.  Encryption    *
;* does not support FASTMEM (ie. Extra memory).                   *
;* Assembled with DEVPAC 1 or 2.                  		  *
;*								  *
;* Letters, questions and general stuff to me at :		  *
;*	74 Pemberton Road, Winstanley, Wigan, WN3 6DA, UK	  *			 
;* or   28 Seaton Street, Middlesbrough, Cleveland, TS1 3NQ, UK	  *
;******************************************************************

;----- DOS calls --------------------

_LVOOpen	EQU	-30 
_LVOClose	EQU	-36 
_LVORead	EQU	-42 
_LVOWrite	EQU	-48 
_LVOOutput	EQU	-60 
_LVOLock	EQU	-84 
_LVOUnLock	EQU	-90 
_LVOExamine	EQU	-102 
_LVOInfo	EQU	-114

;----- EXEC calls -------------------

_LVOAllocMem	EQU	-198 
_LVOFreeMem	EQU	-210 
_LVOOpenLibrary		EQU	-552
_LVOCloseLibrary	EQU	-414 

;----- MISC Equates -----------------

_SysBase	EQU	4
MEMF_CHIP	EQU	1<<1
MEMF_CLEAR	EQU	1<<16
MODE_OLDFILE	EQU	1005
MODE_NEWFILE	EQU	1006

;----- PRINT Macro equates ----------

Free		EQU 2
Exit            EQU 1
Comeback        EQU 0

;----- CALL EXEC MACRO --------------

CALLEXEC MACRO
	move.l	(_SysBase).w,a6
	jsr	_LVO\1(a6)
	ENDM

;----- CALL DOS MACRO ---------------

CALLDOS	MACRO
	move.l	_DOSBase,a6
	jsr	_LVO\1(a6)
	ENDM

;----- PRINT TEXT MACRO -------------

PRINT MACRO
	CALLDOS	Output
	move.l	#\1,d2
	move.l	#53,d3
	CALLDOS Write
	move.b	#\2,d0
	cmp.b	#Exit,d0
	beq	clib
	cmp.b	#Free,d0
	beq	FreeMemory
	ENDM

;----- MAIN PROGRAM BEGINS HERE -----

Open_Dos_Lib
	move.l	a0,a4
	move.l	d0,a0
  	move.l	#dosname,a1
	CALLEXEC OpenLibrary		; Open library
	tst.l	d0
	beq	Quit			; Whoops, error.
	move.l	d0,_DOSBase		; Ok. Keep DOSBase
	move.l	a4,a0
	
Check_Input
	move.b	(a0),d0			; Check if user just presses
	cmp.b	#$0a,d0			; [RETURN]
	bne.s	Split_Args
	PRINT	UsageTxt,Comeback
	PRINT	UsageTxt2,Exit		; Print usage and quit

Split_Args
	PRINT	Working,Comeback
	move.l	a4,a0
	bsr	StringSplit		; Get password
	move.l	d1,PassWORD
	lea.l	2(a0),a0
	bsr	StringSplit		; Get passcode
	move.l	d1,PassCODE
	lea.l	2(a0),a0
	move.l	a0,FileName		; Get filename

FindSpc	lea.l	1(a0),a0		; NULL terminate filename
	cmp.b	#$0A,(a0)
	bne	FindSpc
	move.b	#0,(a0)

Get_Lock
	move.l	FileName,d1		; Check if file exists
	move.l	#-2,d2
	CALLDOS Lock	
	move.l	d0,MyLock

	
Alloc_InfoMem
	move.l	#256,d0
	move.l	#MEMF_CHIP!MEMF_CLEAR,d1 ; I want CHIP memory
	CALLEXEC AllocMem 		 ;
	tst.l	d0			 ;
	bne.s	Get_DiskInfo		 ; Successful
	PRINT	NoMemory,Exit
	
Get_DiskInfo			; Check WRITEPROTECT ENABLED
	move.l	d0,TOP
	move.l	d0,d2
	move.l	MyLock,d1
	CALLDOS Info
	move.l	TOP,a1
	move.l	8(a1),a1
	move.l	a1,d0
	cmp.b	#$52,d0		; Check ENABLED
	beq.s	Get_FileInfo
	move.l	TOP,a1
	move.l	#256,d0		; Size of memory allocated
	moveq	#0,d1
	CALLEXEC FreeMem	
	move.l	MyLock,d1
	CALLDOS UnLock
	PRINT	DiskErr,Exit	; WRITE PROTECTED exit

Get_FileInfo			; Get information on file
	move.l	TOP,a5
	move.l	MyLock,d1
	move.l	a5,d2
	CALLDOS Examine

Free_Lock
	move.l	MyLock,d1
	CALLDOS UnLock

Get_Size
	move.l	124(a5),a5
	move.l	a5,FileSize	; Get filesize

Free_InfoMem
	move.l	TOP,a1
	move.l	#256,d0		; Size of memory allocated
	moveq	#0,d1
	CALLEXEC FreeMem	

Allocate_Memory
	move.l	FileSize,d0
	add.b	#$10,d0
	move.l	d0,TotalSize
	move.l	#MEMF_CHIP!MEMF_CLEAR,d1 ; I want CHIP memory
	CALLEXEC AllocMem 		 ;
	tst.l	d0			 ;
	bne	MemOK			 ; Successful
	PRINT	NoMemory,Exit
	
MemOK	move.l	d0,TOP			; Set save block addresses
	add	#16,d0			;
	move.l	d0,MIDDLE		;
	add	#16,d0			;
	move.l	d0,BOTTOM		;
	
; ***** OPEN DATAFILE *****
	move.l	#0,d0
	move.l	FileName,d1		; Filename address to d1
	move.l	#MODE_OLDFILE,d2	; 
	CALLDOS Open			; 		
	tst.l	d0
	bne	Readfle
	PRINT	Error1,Free		; Couldn't get file handle
	
; ***** READ DATAFILE INTO ALLOCATED MEMORY (at MIDDLE address) *****

Readfle	move.l	d0,FHandle	
	move.l	MIDDLE,d2		; Allocated-memory space  to d2		
	move.l	FileSize,d3		; File size to d3
	CALLDOS Read			; Read data
	move.l	d0,FileSize
	
	move.l	MIDDLE,a1		; Old or New file?
	cmp.l	#'Cryp',(a1)
	beq	CheckPass		; old file, check pass
	
PrepNew	PRINT	NewTxt,Comeback
	move.l	TOP,a1
	move.l	#'Cryp',(a1)+
	move.l	#'t-2 ',(a1)+
	move.l	#'(c) ',(a1)+
	lea.l	PassWORD,a2		; Create diskcode
	move.l	(a2),d1
	lea.l	PassCODE,a2
	move.l	(a2),d2
	EOR.l	d1,d2
	not.l	d2
	move.l	d2,(a1)
	move.l	MIDDLE,CryptAddress
	move.l	TOP,FileAddress
	move.b	#$10,ExtraBytes
	bra	Cr_DeCrypt
	
CheckPass
	lea.l	12(a1),a1
	move.l	(a1),d0
	lea.l	PassCODE,a1
	move.l	(a1),d1
	EOR.l	d1,d0
	not.l	d0
	lea.l	PassWORD,a1
	move.l	(a1),d1
	cmp.l	d1,d0
	beq	PassOK
	move.l	FHandle,d1		; FILEHANDLE to d1
	CALLDOS Close			; Close file
	PRINT   UnAuth,Free		; Wrong code! exit.
	
PassOK	PRINT	OldTxt,Comeback
	add.l	#-$10,FileSize
	move.l  BOTTOM,CryptAddress
	move.l	BOTTOM,FileAddress
	
Cr_DeCrypt
	lea.l	PassWORD,a1
	move.l	(a1),d2
	not.l	d2
	move.l	CryptAddress,a1
	move.l	FileSize,d0
Crypt					; Crypt/DeCrypt datafile	
	eor.l	d2,(a1)			; Xor password with data
	add.l	#4,a1			; Encrypt every longword
	sub.l	#4,d0			; Decrement file-size counter
	tst.l	d0
	bgt.s	Crypt
	eor.l	d2,(a1)

Save	move.l	FHandle,d1
	CALLDOS Close

	move.l	FileName,d1		; Filename address to a1
	move.l	#MODE_NEWFILE,d2 	; 
	CALLDOS Open			; 		
	move.l	d0,FHandle		; Store file handle.
		
	move.l	FHandle,d1
	move.l	FileAddress,d2
	move.l	FileSize,d3
	add.b	ExtraBytes,d3
	CALLDOS Write
	move.l	FHandle,d1		; FILEHANDLE to d1
	CALLDOS Close			; Close file
	PRINT	Finished,Comeback
	
FreeMemory
	move.l	TOP,a1
	move.l	TotalSize,d0		; Size of memory allocated
	moveq	#0,d1
	CALLEXEC FreeMem	

clib	move.l	_DOSBase,a1		; Close DOS library
	CALLEXEC CloseLibrary

Quit	rts	

;*********************************************************************
;*								     *
;* Sub-routine to split users CODE and PASS words and to extend the  *
;* CODE or PASS to 4 characters if need be.			     *
;*								     *
;*********************************************************************

StringSplit
	clr.l	d2
	clr.l	d1
	move.b	(a0),-(sp)
	moveq	#3,d0
Push	lea.l	1(a0),a0
	cmp.b	#$20,(a0)
	beq	Extend
	
	move.b	(a0),-(sp)
	subq	#1,d0
	tst.b	d0
	bne	Push
	
Zoom	lea.l	1(a0),a0
	cmp.b	#$20,(a0)
	bne	Zoom
	lea.l	-1(a0),a0
	bra	Pullstk
	
Extend	lea.l	-1(a0),a0	; pad last letter to 4 character word 
Again	move.b	(a0),-(sp)
	subq	#1,d0
	tst.b	d0
	bne	Again
	
Pullstk	move.l	#0,d1		; Pull characters from stack
	move.b	(sp)+,d1
	mulu.w	#$100,d1
	move.b	(sp)+,d1
	swap.w	d1
	move.b	(sp)+,d2
	mulu.w	#$100,d2
	move.b	(sp)+,d2
	
	add.l	d2,d1		; 4 characters into d1
	rts
	
;************************* STORAGE *********************************

dosname		dc.b 	'dos.library',0
_DOSBase	dc.l	0	; DOSbase address
PassWORD	dc.l	0	;
PassCODE	dc.l	0	;
FileName	dc.l	0	;
CryptAddress	dc.l	0	;
FileAddress	dc.l	0	;
FileSize	dc.l	0	;
FHandle		dc.l	0	;
MIDDLE		dc.l	0	;
TOP		dc.l	0	;
BOTTOM		dc.l	0	;
TotalSize	dc.l	0	;
ExtraBytes	dc.b	0	;
MyLock		dc.l	0	;

DiskErr		dc.b	'Disk Error : Please Write-Enable?.                  ',10
NoMemory	dc.b	'Cant Allocate Memory - Kill External Sources/ReBoot ',10
Error1		dc.b	'Unable to open file/incorrect parameters.           ',10
UnAuth		dc.b	'Operation Aborted - Incorrect keys.                 ',10
Finished	dc.b	'Operation complete.                                 ',10
UsageTxt2	dc.b	'PassCode : MAX 4 chars in length. No FASTMEM support',10
UsageTxt	dc.b	'   Usage : Crypt [PassWord] [PassCode] [filename]   ',10
OldTxt		dc.b	'->De-Crypting file.                                 ',10
NewTxt		dc.b	'->Crypting ',27,'[3mnewfile.',27,'[0m','                         ',10
Working		dc.b	27,'[7m',10,'Encryption  by S.Meredith.',10,27,'[0m','->Checking File ',10
   
		even

