home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Multimedia & CD-ROM 3
/
mmcd03-jun1995-cd.iso
/
utils
/
various
/
utils-1
/
encrypt.asm
< prev
next >
Wrap
Assembly Source File
|
1991-06-24
|
13KB
|
270 lines
;****************************************************************************
; ENCRYPT encrypts a data file using a variation on the Vernam cipher
; technique, which XORs each character of a message with each character
; of a password. Its syntax is:
;
; ENCRYPT [d:][path]filename "password"
;
; where "file1" is the name of the file to be encrypted and "password" is
; the password used to encrypt the file. The password must be enclosed in
; quotation marks and may be as long as the command line permits.
;
; Files are unencrypted by passing them through ENCRYPT again with the
; same password. If a password is forgotten, there is no way to recover
; the original file short of manually breaking the code.
;****************************************************************************
code segment
assume cs:code,ds:code
org 100h
begin: jmp main
helpmsg db "Encrypts a file for data security.",13,10,13,10
db "ENCRYPT [d:][path]filename ",22h,"password",22h
db 13,10,13,10
db " filename Name of the file to be encrypted",13,10
db " password Password used for encryption",13,10
db 13,10
db "To unencrypt a file, run it through ENCRYPT again "
db "with the same password.",13,10,"$"
errmsg1 db "Syntax: ENCRYPT [d:][path]filename "
db 22h,"password",22h,13,10,"$"
errmsg2 db "File not found or path invalid",13,10,"$"
errmsg3 db "File could not be opened for reading",13,10,"$"
errmsg4 db "File could not be opened for writing",13,10,"$"
errmsg5 db "File read error",13,10,"$"
errmsg6 db "File write error",13,10,"$"
errmsg7 db "Disk full error",13,10,"$"
errmsg8 db "Not enough memory",13,10,"$"
filename dw ? ;Address of file name
r_handle dw ? ;File handle for reading
w_handle dw ? ;File handle for writing
password dw ? ;Password address
count dw ? ;Password length
blocksize dw ? ;Block size for file I/O
bytesread dw ? ;Bytes read from input file
;****************************************************************************
; Procedure MAIN
;****************************************************************************
main proc near
cld ;Clear direction flag
mov si,81h ;Point SI to command line
call scanhelp ;Scan for "/?" switch
jnc checkmem ;Branch if not found
mov ah,09h ;Display help text and exit
mov dx,offset helpmsg ; with ERRORLEVEL=0
int 21h
mov ax,4C00h
int 21h
checkmem: mov dx,offset errmsg8 ;Make sure there's enough
cmp sp,0A000h ; memory to run the
ja parse ; program
error: mov ah,09h ;Display error message and
int 21h ; exit with ERRORLEVEL=1
mov ax,4C01h
int 21h
;
; Parse the command line.
;
parse: call findchar ;Find first parameter
jnc parse2 ;Branch if found
error1: mov dx,offset errmsg1 ;Error if not
jmp error
parse2: cmp byte ptr [si],22h ;Error if quotation mark
je error1
mov filename,si ;Save address
call finddelim ;Find end of string
jc error1 ;Error if end of line
mov byte ptr [si],0 ;Convert to ASCIIZ
inc si ;Advance SI
call findchar ;Find next parameter
jc error1 ;Error if end of line
cmp byte ptr [si],22h ;Error if NOT quotation
jne error1 ; mark this time
inc si ;Skip quotation mark
mov password,si ;Save address
sub cx,cx ;Initialize counter
readnext: lodsb ;Find the closing quotation
cmp al,0Dh ; mark and exit on error
je error1 ; if end of line is
cmp al,22h ; encountered first
je quotefound
inc cx
jmp readnext
quotefound: jcxz error1 ;Error if length is 0
mov count,cx ;Save password length
;
; Open the file with separate handles for reading and writing.
;
mov ax,3D00h ;Open the file for reading
mov dx,filename ; using DOS function 3DH
int 21h
mov r_handle,ax ;Save file handle
jnc open ;Continue if no error
mov dx,offset errmsg3 ;Determine what the error
cmp ax,2 ; was and point DX to the
jb goto_error ; appropriate error
cmp ax,3 ; message
ja goto_error
mov dx,offset errmsg2
goto_error: jmp error ;Exit on error
open: mov ax,3D01h ;Open the file for writing
mov dx,filename ; using DOS function 3Dh
int 21h
mov w_handle,ax ;Save file handle
mov dx,offset errmsg4 ;Branch on error
jc error
;
; Read the file, encrypt it, and write it back out to disk.
;
mov ax,8000h ;Compute block size for
sub dx,dx ; file I/O
div count ;Quotient in AX
mul count ;Product in AX (<8000H)
mov blocksize,ax ;Save block size
readblock: mov ah,3Fh ;Read one block using
mov bx,r_handle ; DOS function 3FH
mov cx,blocksize
mov dx,offset buffer
int 21h
mov dx,offset errmsg5
jc goto_error ;Error if call failed
jcxz exit ;Done if zero bytes read
mov bytesread,ax ;Save bytes read count
call encrypt ;Encrypt the block
mov ah,40h ;Write one block using
mov bx,w_handle ; DOS function 40H
mov cx,bytesread
mov dx,offset buffer
int 21h
mov dx,offset errmsg6
jc goto_error ;Error if call failed
cmp ax,bytesread ;Proceed if bytes written
je check ; equals bytes read
mov dx,offset errmsg7 ;Queue up "Disk full"
jmp error ; message and exit
check: mov ax,bytesread ;Loop back for more if
cmp ax,blocksize ; bytes read is less
jnb readblock ; than bytes requested
;
; Close file handles and exit.
;
exit: mov ah,3Eh ;Close the read handle
mov bx,r_handle
int 21h
mov ah,3Eh ;Close the write handle
mov bx,w_handle
int 21h
mov ax,4C00h ;Exit with ERRORLEVEL=0
int 21
main endp
;****************************************************************************
; FINDCHAR advances SI to the next non-space or non-comma character.
; On return, carry set indicates EOL was encountered.
;****************************************************************************
findchar proc near
lodsb ;Get the next character
cmp al,20h ;Loop if space
je findchar
cmp al,2Ch ;Loop if comma
je findchar
dec si ;Point SI to the character
cmp al,0Dh ;Exit with carry set if end
je eol ; of line is reached
clc ;Clear carry and exit
ret
eol: stc ;Set carry and exit
ret
findchar endp
;****************************************************************************
; FINDDELIM advances SI to the next space or comma character. On return,
; carry set indicates EOL was encountered.
;****************************************************************************
finddelim proc near
lodsb ;Get the next character
cmp al,20h ;Exit if space
je fd_exit
cmp al,2Ch ;Exit if comma
je fd_exit
cmp al,0Dh ;Loop back for more if end
jne finddelim ; of line isn't reached
dec si ;Set carry and exit
stc
ret
fd_exit: dec si ;Clear carry and exit
clc
ret
finddelim endp
;****************************************************************************
; SCANHELP scans the command line for a /? switch. If found, carry returns
; set and SI contains its offset. If not found, carry returns clear.
;****************************************************************************
scanhelp proc near
push si ;Save SI
scanloop: lodsb ;Get a character
cmp al,0Dh ;Exit if end of line
je scan_exit
cmp al,"?" ;Loop if not "?"
jne scanloop
cmp byte ptr [si-2],"/" ;Loop if not "/"
jne scanloop
add sp,2 ;Clear the stack
sub si,2 ;Adjust SI
stc ;Set carry and exit
ret
scan_exit: pop si ;Restore SI
clc ;Clear carry and exit
ret
scanhelp endp
;****************************************************************************
; ENCRYPT encrypts a block of data using an XOR algorithm.
;****************************************************************************
encrypt proc near
mov di,offset buffer ;Point DI to buffer
mov si,password ;Point SI to password
mov cx,bytesread ;Initialize CX with count
enloop: lodsb ;Get password character
cmp al,22h ;Branch if not a quotation
jne notquote ; mark
mov si,password ;Reset BX to start of
lodsb ; start of password
notquote: xor [di],al ;Encrypt the character
inc di ;Advance buffer pointer
loop enloop ;Loop until done
ret
encrypt endp
buffer = $ ;File I/O buffer
code ends
end begin