home *** CD-ROM | disk | FTP | other *** search
- ;****************************************************************************
- ; 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
-