home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / sampler0 / cipher.asm < prev    next >
Assembly Source File  |  1988-06-28  |  8KB  |  353 lines

  1. ; cipher.asm
  2. ;
  3. ; A quick low-security file encryption program, useful for deterring
  4. ; casual snoopers.  Execution speed (8 MHz 80286, ST225 disk) is about
  5. ; 22000 bytes/sec.
  6. ;
  7. ; Assembly:
  8. ;
  9. ; C>masm cipher;
  10. ; C>link cipher;
  11. ; C>exe2bin cipher.exe cipher.com
  12. ; C>erase cipher.exe
  13. ;
  14. ; Usage:
  15. ;
  16. ; C>cipher filename.ext
  17. ;
  18. ; Drive and path names are allowed.  Wildcards are not allowed.
  19. ; The file name must be specified completely; there is no default
  20. ; extension.  The name of the file is not changed to indicate its
  21. ; plain or enciphered status.
  22. ;
  23. ; The file is enciphered in place.  NO BACKUP COPY IS MADE.  The
  24. ; easiest way to make a backup copy is to use CIPHER in a batch file
  25. ; with a COPY command, although this source code could also be
  26. ; modified to make a backup.
  27. ;
  28. ; The key is found in the environment strings, under KEYWORD.
  29. ; It can be set with the SET command:
  30. ;
  31. ; C>set KEYWORD=Mandarin_Orange
  32. ;
  33. ; It can be verified with the SET command:
  34. ;
  35. ; C>set
  36. ;
  37. ; This will produce a listing of the environment strings:
  38. ;
  39. ; COMSPEC=C:\COMMAND.COM
  40. ; PATH=D:\;C:\PCDOS330;C:\BINARY
  41. ; PROMPT=$t$h$h$h $n$g
  42. ; KEYWORD=Mandarin_Orange
  43. ;
  44. ; It can be cleared by rebooting or with the SET command:
  45. ;
  46. ; C>set KEYWORD=
  47. ;
  48.  
  49. DEBUG        equ    0
  50. BLOCKSIZE    equ    1024
  51. PRNG_A        equ    17257        ; Shippensburg, Pennsylvania
  52. PRNG_C        equ    21545        ; Mount Savage, Maryland
  53.  
  54. codeseg        segment    para public 'code'
  55.         assume cs:codeseg,ds:codeseg,ss:codeseg,es:codeseg
  56.  
  57.         org    0081h
  58. cmd_line    label    byte
  59.  
  60.         org    0100h
  61. cipher        proc    near
  62.  
  63.         push    cs
  64.         pop    ds        ; ds = cs
  65.  
  66.         mov    ah,30h        ; get DOS version number
  67.         int    21h
  68.         cmp    al,2
  69.         jge    look_for_keyword
  70.  
  71.         mov    dx,offset dos_ver_msg
  72.         jmp    general_exit
  73.  
  74. ; search the DOS environment for "KEYWORD=something"
  75. ; and use "something" to seed the random generator
  76.  
  77. look_for_keyword:
  78.         mov    ax,ds:2ch    ; get environment segment from PSP
  79.         mov    es,ax        ; copy it to ES
  80.         xor    si,si        ; start at offset = 0
  81.  
  82. env_test_line:
  83.         mov    al,es:[si+1]    ; peek at the next environment byte
  84.         cmp    al,0        ; is it a null?
  85.         je    key_error    ; yes: we ran out of environment
  86.  
  87.         xor    bx,bx        ; clear the match counter
  88.         mov    di,offset key_marker ; point at key_marker
  89.  
  90. env_test_byte:
  91.         mov    al,es:[si]    ; get byte from environment
  92.         inc    si        ; point to next environment byte
  93.         mov    ah,[di]        ; get byte from key_marker
  94.         inc    di        ; point to next key_marker byte
  95.         cmp    al,ah        ; compare env byte to key_marker byte
  96.         jne    env_skip_line    ; jump on mismatch
  97.  
  98.         inc    bx        ; increment match counter
  99.         cmp    bx,marker_len    ; do we have enough matches?
  100.         je    env_skip_equals    ; yes: jump
  101.  
  102.         jmp short env_test_byte    ; no:  keep looking
  103.  
  104. key_error:
  105.         mov    dx,offset keyword_msg
  106.         jmp    general_exit
  107.  
  108. ; here the current environment string is not KEYWORD
  109. ; skip to the beginning of the next line
  110.  
  111. env_skip_line:
  112.         mov    al,es:[si]    ; get byte from environment
  113.         inc    si        ; point to next environment byte
  114.         cmp    al,0        ; is it a null?
  115.         jne    env_skip_line    ; repeat until a null is found
  116.  
  117.         jmp short env_test_line    ; and then go test the next line
  118.  
  119. ; here es:si points to the first byte after the keyword marker
  120. ; scan past the '=' in the environment string
  121.  
  122. env_skip_equals:
  123.         mov    al,es:[si]    ; get byte from environment
  124.         inc    si        ; point to next environment byte
  125.         cmp    al,0        ; end of string?
  126.         je    key_error
  127.  
  128.         cmp    al,'='        ; find '='
  129.         jne    env_skip_equals
  130.  
  131. ; here es:si points to the first byte after '='
  132.  
  133. env_skip_blanks:
  134.         mov    al,es:[si]    ; get byte from environment
  135.         inc    si        ; point to next environment byte
  136.         cmp    al,0        ; end of string?
  137.         je    key_error
  138.  
  139.         cmp    al,20h        ; skip over controls and spaces
  140.         jle    env_skip_blanks
  141.  
  142. if DEBUG
  143.         push    ax
  144.         push    dx
  145.         mov    ah,9        ; display string
  146.         mov    dx,offset key_equ_msg
  147.         int    21h
  148.         pop    dx
  149.         pop    ax
  150. endif
  151.  
  152. ; here es:si points to the second byte of the key string
  153.  
  154.         dec    si        ; point to first string byte
  155.         mov    seed,0        ; clear accumulator
  156. make_seed_loop:
  157.         mov    al,es:[si]    ; get byte from environment
  158.         inc    si        ; point to next environment byte
  159.  
  160.         cmp    al,20h        ; exit on null or control or space
  161.         jle    read_filename
  162.  
  163.         cmp    al,7fh        ; exit on first graphic byte
  164.         jg    read_filename
  165.  
  166. if DEBUG
  167.         push    ax
  168.         push    dx
  169.         mov    ah,2        ; display character
  170.         mov    dl,al
  171.         int    21h
  172.         pop    dx
  173.         pop    ax
  174. endif
  175.  
  176.         xor    ah,ah        ; clear high input byte
  177.         shl    seed,1
  178.         shl    seed,1
  179.         shl    seed,1
  180.         add    seed,ax        ; accumulator += new byte
  181.  
  182.         jmp short make_seed_loop
  183.  
  184. name_error:
  185.         mov    dx,offset name_msg
  186.         jmp    general_exit
  187.  
  188. ; now get the filename from the command line
  189.  
  190. read_filename:
  191.         push    cs
  192.         pop    es        ; es = cs
  193.  
  194. if DEBUG
  195.         push    ax
  196.         push    dx
  197.         mov    ah,9        ; display string
  198.         mov    dx,offset key_end_msg
  199.         int    21h
  200.         pop    dx
  201.         pop    ax
  202. endif
  203.  
  204.         mov    si,offset cmd_line
  205. skip_blanks:
  206.         lodsb            ; read a byte from command line
  207.         cmp    al,0dh        ; check for end of line
  208.         je    name_error
  209.  
  210.         cmp    al,20h        ; check for blanks or controls
  211.         jle    skip_blanks
  212.  
  213. ; here si points to the second byte of the filename
  214.  
  215.         dec    si        ; si = filename address
  216.         push    si        ; save filename address
  217. skip_filename:
  218.         lodsb            ; read a byte from command line
  219.         cmp    al,20h        ; exit on null or control or space
  220.         jg    skip_filename
  221.  
  222. ; here si points to the second byte after the filename
  223.  
  224.         dec    si        ; point to first control or space
  225.         mov    byte ptr [si],0    ; change it to a null
  226.  
  227. ; now the filename has been found and terminated
  228. ; call DOS to open the file
  229.  
  230.         mov    ax,3d02h    ; open file for read/write
  231.         pop    dx        ; dx = filename address
  232.         int    21h
  233.         mov    handle,ax    ; store file handle
  234.         jnc    outer_loop    ; carry flag indicates error
  235.  
  236.         mov    dx,offset open_msg
  237.         jmp    general_exit
  238.  
  239. outer_loop:
  240.         mov    ah,2        ; display dot on stdout
  241.         mov    dl,'.'
  242.         int    21h
  243.  
  244.         mov    ah,3fh        ; read a block from the file
  245.         mov    bx,handle
  246.         mov    cx,BLOCKSIZE
  247.         mov    dx,offset buffer
  248.         int    21h
  249.         jc    read_error
  250.  
  251.         cmp    ax,0        ; if the byte count was zero,
  252.         je    close_and_quit    ; then the file block was empty
  253.  
  254.         mov    byte_count,ax    ; save byte count
  255.  
  256.         mov    cx,ax        ; initialize inner loop count
  257.         mov    si,offset buffer ; si = data address
  258.         mov    di,si        ; di = data address
  259.         mov    bx,PRNG_A    ; bx = multiplier
  260. inner_loop:
  261.         mov    ax,seed
  262.         mul    bx
  263.         add    ax,PRNG_C
  264.         mov    seed,ax        ; use ah for key byte
  265.  
  266.         lodsb            ; get a data byte
  267.         xor    al,ah        ; convert the data byte
  268.         stosb            ; store the data byte
  269.  
  270.         loop    inner_loop    ; repeat as necessary
  271.  
  272.         mov    ax,4200h    ; rewind to beginning of block
  273.         mov    bx,handle
  274.         mov    cx,ptr_msw
  275.         mov    dx,ptr_lsw
  276.         int    21h
  277.         jc    seek_error
  278.  
  279.         mov    ah,40h        ; write block back to file
  280.         mov    bx,handle
  281.         mov    cx,byte_count
  282.         mov    dx,offset buffer
  283.         int    21h
  284.         jc    write_error
  285.  
  286.         mov    cx,byte_count    ; check for write errors
  287.         cmp    ax,cx
  288.         jne    write_error
  289.  
  290.         cmp    ax,BLOCKSIZE    ; if the block was not full,
  291.         jne    close_and_quit    ; then we're done
  292.  
  293.         add    ptr_lsw,BLOCKSIZE ; find new file position
  294.         adc    ptr_msw,0
  295.  
  296.         jmp    outer_loop    ; go back for the next block
  297.  
  298. write_error:
  299.         mov    dx,offset write_msg
  300.         jmp short general_exit
  301.  
  302. read_error:
  303.         mov    dx,offset read_msg
  304.         jmp short general_exit
  305.  
  306. seek_error:
  307.         mov    dx,offset seek_msg
  308.         jmp short general_exit
  309.  
  310. close_and_quit:
  311.         mov    ah,3eh        ; close file
  312.         mov    bx,handle
  313.         int    21h
  314.  
  315.         mov    dx,offset done_msg
  316.  
  317. general_exit:
  318.         mov    ah,9        ; display string
  319.         int    21h
  320.  
  321.         int    20h        ; return to DOS
  322.  
  323. cipher        endp
  324.  
  325. key_marker    db    'KEYWORD'
  326. marker_len    equ    $-key_marker
  327.  
  328. done_msg    db    'Done$'
  329. name_msg    db    'Filename error$'
  330. open_msg    db    'Open error$'
  331. read_msg    db    'Read error$'
  332. seek_msg    db    'Seek error$'
  333. write_msg    db    'Write error$'
  334. keyword_msg    db    'Keyword error$'
  335. dos_ver_msg    db    'Requires DOS 2.00+$'
  336.  
  337. if DEBUG
  338. key_equ_msg    db    'DEBUG: Key = "$'
  339. key_end_msg    db    '"',0dh,0ah,'$'
  340. endif
  341.  
  342. ptr_msw        dw    0
  343. ptr_lsw        dw    0
  344. handle        dw    0
  345. seed        dw    0
  346. byte_count    dw    0
  347. buffer        label    byte    ; this goes last!
  348.  
  349. codeseg        ends
  350.         end    cipher
  351.  
  352.  
  353.