home *** CD-ROM | disk | FTP | other *** search
- ; cipher.asm
- ;
- ; A quick low-security file encryption program, useful for deterring
- ; casual snoopers. Execution speed (8 MHz 80286, ST225 disk) is about
- ; 22000 bytes/sec.
- ;
- ; Assembly:
- ;
- ; C>masm cipher;
- ; C>link cipher;
- ; C>exe2bin cipher.exe cipher.com
- ; C>erase cipher.exe
- ;
- ; Usage:
- ;
- ; C>cipher filename.ext
- ;
- ; Drive and path names are allowed. Wildcards are not allowed.
- ; The file name must be specified completely; there is no default
- ; extension. The name of the file is not changed to indicate its
- ; plain or enciphered status.
- ;
- ; The file is enciphered in place. NO BACKUP COPY IS MADE. The
- ; easiest way to make a backup copy is to use CIPHER in a batch file
- ; with a COPY command, although this source code could also be
- ; modified to make a backup.
- ;
- ; The key is found in the environment strings, under KEYWORD.
- ; It can be set with the SET command:
- ;
- ; C>set KEYWORD=Mandarin_Orange
- ;
- ; It can be verified with the SET command:
- ;
- ; C>set
- ;
- ; This will produce a listing of the environment strings:
- ;
- ; COMSPEC=C:\COMMAND.COM
- ; PATH=D:\;C:\PCDOS330;C:\BINARY
- ; PROMPT=$t$h$h$h $n$g
- ; KEYWORD=Mandarin_Orange
- ;
- ; It can be cleared by rebooting or with the SET command:
- ;
- ; C>set KEYWORD=
- ;
-
- DEBUG equ 0
- BLOCKSIZE equ 1024
- PRNG_A equ 17257 ; Shippensburg, Pennsylvania
- PRNG_C equ 21545 ; Mount Savage, Maryland
-
- codeseg segment para public 'code'
- assume cs:codeseg,ds:codeseg,ss:codeseg,es:codeseg
-
- org 0081h
- cmd_line label byte
-
- org 0100h
- cipher proc near
-
- push cs
- pop ds ; ds = cs
-
- mov ah,30h ; get DOS version number
- int 21h
- cmp al,2
- jge look_for_keyword
-
- mov dx,offset dos_ver_msg
- jmp general_exit
-
- ; search the DOS environment for "KEYWORD=something"
- ; and use "something" to seed the random generator
-
- look_for_keyword:
- mov ax,ds:2ch ; get environment segment from PSP
- mov es,ax ; copy it to ES
- xor si,si ; start at offset = 0
-
- env_test_line:
- mov al,es:[si+1] ; peek at the next environment byte
- cmp al,0 ; is it a null?
- je key_error ; yes: we ran out of environment
-
- xor bx,bx ; clear the match counter
- mov di,offset key_marker ; point at key_marker
-
- env_test_byte:
- mov al,es:[si] ; get byte from environment
- inc si ; point to next environment byte
- mov ah,[di] ; get byte from key_marker
- inc di ; point to next key_marker byte
- cmp al,ah ; compare env byte to key_marker byte
- jne env_skip_line ; jump on mismatch
-
- inc bx ; increment match counter
- cmp bx,marker_len ; do we have enough matches?
- je env_skip_equals ; yes: jump
-
- jmp short env_test_byte ; no: keep looking
-
- key_error:
- mov dx,offset keyword_msg
- jmp general_exit
-
- ; here the current environment string is not KEYWORD
- ; skip to the beginning of the next line
-
- env_skip_line:
- mov al,es:[si] ; get byte from environment
- inc si ; point to next environment byte
- cmp al,0 ; is it a null?
- jne env_skip_line ; repeat until a null is found
-
- jmp short env_test_line ; and then go test the next line
-
- ; here es:si points to the first byte after the keyword marker
- ; scan past the '=' in the environment string
-
- env_skip_equals:
- mov al,es:[si] ; get byte from environment
- inc si ; point to next environment byte
- cmp al,0 ; end of string?
- je key_error
-
- cmp al,'=' ; find '='
- jne env_skip_equals
-
- ; here es:si points to the first byte after '='
-
- env_skip_blanks:
- mov al,es:[si] ; get byte from environment
- inc si ; point to next environment byte
- cmp al,0 ; end of string?
- je key_error
-
- cmp al,20h ; skip over controls and spaces
- jle env_skip_blanks
-
- if DEBUG
- push ax
- push dx
- mov ah,9 ; display string
- mov dx,offset key_equ_msg
- int 21h
- pop dx
- pop ax
- endif
-
- ; here es:si points to the second byte of the key string
-
- dec si ; point to first string byte
- mov seed,0 ; clear accumulator
- make_seed_loop:
- mov al,es:[si] ; get byte from environment
- inc si ; point to next environment byte
-
- cmp al,20h ; exit on null or control or space
- jle read_filename
-
- cmp al,7fh ; exit on first graphic byte
- jg read_filename
-
- if DEBUG
- push ax
- push dx
- mov ah,2 ; display character
- mov dl,al
- int 21h
- pop dx
- pop ax
- endif
-
- xor ah,ah ; clear high input byte
- shl seed,1
- shl seed,1
- shl seed,1
- add seed,ax ; accumulator += new byte
-
- jmp short make_seed_loop
-
- name_error:
- mov dx,offset name_msg
- jmp general_exit
-
- ; now get the filename from the command line
-
- read_filename:
- push cs
- pop es ; es = cs
-
- if DEBUG
- push ax
- push dx
- mov ah,9 ; display string
- mov dx,offset key_end_msg
- int 21h
- pop dx
- pop ax
- endif
-
- mov si,offset cmd_line
- skip_blanks:
- lodsb ; read a byte from command line
- cmp al,0dh ; check for end of line
- je name_error
-
- cmp al,20h ; check for blanks or controls
- jle skip_blanks
-
- ; here si points to the second byte of the filename
-
- dec si ; si = filename address
- push si ; save filename address
- skip_filename:
- lodsb ; read a byte from command line
- cmp al,20h ; exit on null or control or space
- jg skip_filename
-
- ; here si points to the second byte after the filename
-
- dec si ; point to first control or space
- mov byte ptr [si],0 ; change it to a null
-
- ; now the filename has been found and terminated
- ; call DOS to open the file
-
- mov ax,3d02h ; open file for read/write
- pop dx ; dx = filename address
- int 21h
- mov handle,ax ; store file handle
- jnc outer_loop ; carry flag indicates error
-
- mov dx,offset open_msg
- jmp general_exit
-
- outer_loop:
- mov ah,2 ; display dot on stdout
- mov dl,'.'
- int 21h
-
- mov ah,3fh ; read a block from the file
- mov bx,handle
- mov cx,BLOCKSIZE
- mov dx,offset buffer
- int 21h
- jc read_error
-
- cmp ax,0 ; if the byte count was zero,
- je close_and_quit ; then the file block was empty
-
- mov byte_count,ax ; save byte count
-
- mov cx,ax ; initialize inner loop count
- mov si,offset buffer ; si = data address
- mov di,si ; di = data address
- mov bx,PRNG_A ; bx = multiplier
- inner_loop:
- mov ax,seed
- mul bx
- add ax,PRNG_C
- mov seed,ax ; use ah for key byte
-
- lodsb ; get a data byte
- xor al,ah ; convert the data byte
- stosb ; store the data byte
-
- loop inner_loop ; repeat as necessary
-
- mov ax,4200h ; rewind to beginning of block
- mov bx,handle
- mov cx,ptr_msw
- mov dx,ptr_lsw
- int 21h
- jc seek_error
-
- mov ah,40h ; write block back to file
- mov bx,handle
- mov cx,byte_count
- mov dx,offset buffer
- int 21h
- jc write_error
-
- mov cx,byte_count ; check for write errors
- cmp ax,cx
- jne write_error
-
- cmp ax,BLOCKSIZE ; if the block was not full,
- jne close_and_quit ; then we're done
-
- add ptr_lsw,BLOCKSIZE ; find new file position
- adc ptr_msw,0
-
- jmp outer_loop ; go back for the next block
-
- write_error:
- mov dx,offset write_msg
- jmp short general_exit
-
- read_error:
- mov dx,offset read_msg
- jmp short general_exit
-
- seek_error:
- mov dx,offset seek_msg
- jmp short general_exit
-
- close_and_quit:
- mov ah,3eh ; close file
- mov bx,handle
- int 21h
-
- mov dx,offset done_msg
-
- general_exit:
- mov ah,9 ; display string
- int 21h
-
- int 20h ; return to DOS
-
- cipher endp
-
- key_marker db 'KEYWORD'
- marker_len equ $-key_marker
-
- done_msg db 'Done$'
- name_msg db 'Filename error$'
- open_msg db 'Open error$'
- read_msg db 'Read error$'
- seek_msg db 'Seek error$'
- write_msg db 'Write error$'
- keyword_msg db 'Keyword error$'
- dos_ver_msg db 'Requires DOS 2.00+$'
-
- if DEBUG
- key_equ_msg db 'DEBUG: Key = "$'
- key_end_msg db '"',0dh,0ah,'$'
- endif
-
- ptr_msw dw 0
- ptr_lsw dw 0
- handle dw 0
- seed dw 0
- byte_count dw 0
- buffer label byte ; this goes last!
-
- codeseg ends
- end cipher
-
-
-