home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / filutl / scrmbl21.asm < prev    next >
Encoding:
Assembly Source File  |  1994-07-13  |  7.1 KB  |  345 lines

  1. ;         SCRAMBLE.ASM ver 2.1
  2. ;
  3. ;SCRAMBLE is a program to scramble CP/M files using an 8 byte
  4. ;password.
  5. ;
  6. ;03/14/79 Originally written by Ward Crhistensen
  7. ;
  8. ;07/13/81 Moved stack init to beginning so default stack not
  9. ;      used.     Added fix to write routine for proper
  10. ;      operation under CP/M 2.x.  Expanded Macros so program
  11. ;      may be assembled with ASM.  By Keith Petersen, W8SDZ
  12. ;
  13. ;12/30/82 Removed loop called MIXUP and MVI H,0 just before
  14. ;      it.  Comment was "Scramble awhile to mix up the
  15. ;      seed".  Loop occurred before the password was moved
  16. ;      into location, so loop had no effect on "seed".
  17. ;      Added CALL ERXIT in FINISH.  If an error had
  18. ;      occurred program would have crashed on the error
  19. ;      message itself.  Added more comments around pseudo-
  20. ;      random number generator to better understand the
  21. ;      coding.  By Bob Hageman
  22. ;
  23. MONTH    EQU    12    ;LAST..
  24. DAY    EQU    30    ;..MODIFICATION..
  25. YEAR    EQU    82    ;..DATE
  26. ;
  27. ;Scrambling is done in place, i.e. the file is modified on top
  28. ;of itself.  The same password used to scramble the file is
  29. ;used to unscramble it, using the exact same command.  This is
  30. ;because the scrambling code is exclusive-ORed with the data
  31. ;file, and two same exclusive ORs result in the original value
  32. ;being returned.
  33. ;
  34. ;Command format:
  35. ;
  36. ;    SCRAMBLE filename.type PASSWORD
  37. ;
  38. ;Where PASSWORD is any 8 character string which
  39. ;is allowable as a file name (i.e. no '.', etc).
  40. ;
  41.     ORG    100H
  42. ;
  43. ;Init local stack
  44.     LXI    H,0
  45.     DAD    SP
  46.     SHLD    STACK
  47.     LXI    SP,STACK
  48. ;
  49. ;Print sign-on message
  50.     CALL    START
  51.     DB    'SCRAMBLE.COM as of '
  52.     DB    '0'+MONTH/10
  53.     DB    '0'+MONTH MOD 10,'/'
  54.     DB    '0'+DAY/10
  55.     DB    '0'+DAY MOD 10,'/'
  56.     DB    '0'+YEAR/10
  57.     DB    '0'+YEAR MOD 10
  58.     DB    0DH,0AH,'$'
  59. ;
  60. START    POP    D    ;GET ID
  61.     MVI    C,PRINT
  62.     CALL    BDOS    ;PRINT ID
  63. ;
  64. ;Start of program execution
  65. ;
  66. ;See that the password is 8 characters
  67.     LDA    FCB2+8
  68.     CPI    ' '
  69.     JNZ    PWIS8
  70.     CALL    ERXIT
  71.     DB    '++ PASSWORD NOT 8 BYTES ++$'
  72. ;
  73. ;Save the password
  74. ;
  75. PWIS8    LXI    H,FCB2+1 ;POINT TO PASSWORD
  76.     LXI    D,PASSWD ;OUR PASSWORD AREA
  77.     LXI    B,8     ;8 CHARS
  78.     CALL    MOVER     ;MOVE IT
  79. ;
  80. ;Password is 8 bytes, now make sure no character
  81. ;is repeated more than 2 times
  82.     LXI    H,PASSWD
  83.     MVI    B,8    ;8 CHARS TO TEST
  84. ;
  85. DUPTEST CALL    CKDUP    ;ABORTS IF 3 = CHARS
  86.     INX    H    ;TO NEXT CHAR
  87.     DCR    B
  88.     JNZ    DUPTEST
  89. ;
  90. ;See that the input file exists
  91.     PUSH    B
  92.     PUSH    D
  93.     PUSH    H
  94.     MVI    C,OPEN
  95.     LXI    D,FCB
  96.     CALL    BDOS
  97.     POP    H
  98.     POP    D
  99.     POP    B
  100.     INR    A    ;OK?
  101.     JNZ    SCRAMLP ;YES, SCRAMBLE IT
  102.     CALL    ERXIT
  103.     DB    '++NO SUCH FILE++$'
  104. ;
  105. ;Read the file, scramble a sector, re-write it.
  106. ;
  107. SCRAMLP CALL    RDSECT    ;READ A SECTOR
  108.     JC    FINISH    ;EXIT LOOP IF EOF
  109.     CALL    SCRAMBL ;SCRAMBLE IT
  110.     CALL    BACKUP    ;RE-POSITION FOR WRITE
  111.     CALL    WRSECT    ;RE-WRITE THE SECTOR
  112.     JMP    SCRAMLP ;LOOP UNTIL EOF
  113. ;
  114. ;All done - on a "normal" CP/M system we wouldn't have to do
  115. ;anything because we re-wrote in place.     However, for systems
  116. ;which use sector deblocking we must explicitly close the file
  117. ;in order to flush the memory-resident disk buffers.
  118. ;
  119. FINISH    PUSH    B
  120.     PUSH    D
  121.     PUSH    H
  122.     MVI    C,CLOSE
  123.     LXI    D,FCB
  124.     CALL    BDOS
  125.     POP    H
  126.     POP    D
  127.     POP    B
  128.     INR    A    ;THIS BETTER WORK..
  129.     JNZ    EXIT
  130.     CALL    ERXIT
  131.     DB    '++ CLOSE ERROR - FILE LEFT IN '
  132.     DB    'UNKNOWN CONDITION ++$'
  133. ;
  134. ;Sector read routine
  135. ;
  136. RDSECT    PUSH    B
  137.     PUSH    D
  138.     PUSH    H
  139.     MVI    C,READ
  140.     LXI    D,FCB
  141.     CALL    BDOS
  142.     POP    H
  143.     POP    D
  144.     POP    B
  145.     ORA    A
  146.     RZ        ;ALL OK
  147. ;
  148. ;Read error or EOF
  149. ;
  150.     CPI    1    ;EOF?
  151.     STC        ;CARRY SHOWS EOF
  152.     RZ        ;RET, CARRY SET
  153.     CALL    ERXIT
  154.     DB    '++ READ ERROR - FILE MAY BE '
  155.     DB    'DESTROYED ++$'
  156. ;
  157. ;Scramble the sector
  158. ;
  159. SCRAMBL LXI    H,80H    ;POINT TO SECTOR
  160. ;
  161. SCRLP    CALL    PSEURAN ;GET PSEUDO RANDOM #
  162.     XRA    M    ;SCRAMBLE
  163.     MOV    M,A
  164.     INR    L    ;MORE IN SECTOR?
  165.     JNZ    SCRLP
  166.     RET
  167. ;
  168. ;Backup the file pointer for the re-write
  169. ;
  170. BACKUP    LDA    FCBRNO    ;GET SECTOR #
  171.     DCR    A    ;BACK UP
  172.     STA    FCBRNO
  173.     RP        ;RETURN IF OK
  174. ;
  175. ;We backed up into previous extent, will have to re-open it
  176. ;(this only works for 16k extent size systems).
  177. ;
  178.     LDA    FCBEXT    ;GET EXTENT
  179.     DCR    A    ;BACK UP 1
  180.     STA    FCBEXT
  181.     PUSH    B
  182.     PUSH    D
  183.     PUSH    H
  184.     MVI    C,OPEN    ;RE-OPEN
  185.     LXI    D,FCB
  186.     CALL    BDOS
  187.     POP    H
  188.     POP    D
  189.     POP    B
  190.     INR    A
  191.     JNZ    OPEN2OK
  192.     CALL    ERXIT
  193.     DB    '++ RE-OPENING EXTENT FAILED',0DH,0AH
  194.     DB    '++ FILE IS CLOBBERED $'
  195. ;
  196. OPEN2OK MVI    A,7FH    ;GET HI SECTOR
  197.     STA    FCBRNO
  198.     RET
  199. ;
  200. ;Write back the sector
  201. ;
  202. WRSECT    LDA    FCB+14
  203.     ANI    1FH    ;RESET S2 FLAG FOR CP/M 2.x
  204.     STA    FCB+14
  205.     PUSH    B
  206.     PUSH    D
  207.     PUSH    H
  208.     MVI    C,WRITE
  209.     LXI    D,FCB
  210.     CALL    BDOS
  211.     POP    H
  212.     POP    D
  213.     POP    B
  214.     ORA    A
  215.     RZ
  216.     CALL    ERXIT
  217.     DB    '++ WRITE ERROR - FILE CLOBBERED ++$'
  218. ;
  219. ;Get a Pseudo-Random 8 bit number using the password as a seed
  220. ;
  221. ;    For speed, this routine does no register
  222. ;    PUSHes and POPs, however HL aren't used.
  223. ;
  224. PSEURAN MVI    C,4    ;GRAB EVERY 4TH PSEU. #
  225. ;
  226. ; The following is done four times for each character in the
  227. ;file being scrambled.    After four password shifts a value is
  228. ;returned in A to the calling routine.
  229. ;
  230. PSEULP0 MVI    B,8    ;SHIFT THRU 8 BYTES
  231.     LXI    D,PASSWD
  232.     ORA    A    ;CLEAR INITIAL CARRY
  233. ;
  234. ; PSEULP1 shifts the 8 byte sequence of the password one bit to
  235. ;the right filling the left most bit with 0 (for the first of
  236. ;the four passes, after that bit may receive 0 or 1 from carry)
  237. ;and ending with the right most bit moved to the carry.
  238. ;
  239. PSEULP1 LDAX    D    ;GET A CHAR
  240.     RAR        ;SHIFT
  241.     STAX    D    ;Put shifted char back in place
  242.     INX    D    ;Point to next char
  243.     DCR    B    ;Count down
  244.     JNZ    PSEULP1
  245. ;Exclusive-OR the last few bits into the first one
  246.     DCX    D    ;BACK UP TO LAST
  247.     RAR        ;Shift the 8th byte twice more thru
  248.     RAR        ;  itself and the carry
  249.     XCHG
  250.     XRA    M    ;Mix treble shifted 8th byte in A with
  251.             ;  the single shifted 8th byte in M
  252.     RRC        ;SHIFT LO BIT INTO HI discarding the
  253.             ;  carry bit (4th shift of 8th byte)
  254.     ANI    80H    ;ISOLATE SINGLE BIT, A will contain
  255.             ;  either 80H or 00H
  256.     LXI    H,PASSWD ;GET FIRST BYTE
  257.     ORA    M    ;'OR' IN THE BIT
  258.     MOV    M,A    ;MOVE IT BACK, whatever is in A when
  259.             ;  C=0 will be the value to be XORed
  260.             ;  with the next byte in the current
  261.             ;  sector.  This value changes for each
  262.             ;  and every byte of the file.
  263.     XCHG        ;RESTORE HL
  264.     DCR    C
  265.     JNZ    PSEULP0 ;LOOP IF MORE PASSES
  266.     RET
  267. ;
  268. ;Routine to check for duplicate chars in password
  269. ;
  270. CKDUP    MVI    C,3    ;DUP CHAR COUNTER
  271.     LXI    D,PASSWD
  272.     MVI    A,8    ;CHAR COUNT
  273. ;
  274. CKDLP    PUSH    PSW    ;SAVE COUNT
  275.     LDAX    D    ;GET CHAR
  276.     CMP    M    ;DUP?
  277.     JNZ    CKNDUP
  278.     DCR    C    ;COUNT DUPS
  279.     JNZ    CKNDUP
  280.     STA    DUPCHAR ;SAVE FOR PRINT
  281.     CALL    ERXIT
  282.     DB    '++ NO CHARACTER MAY APPEAR MORE '
  283.     DB    'THAN TWICE IN THE PASSWORD.  ',0DH,0AH
  284.     DB    ''''
  285. DUPCHAR DB    $-$,''' DOES IN YOURS ++$'
  286. ;
  287. CKNDUP    INX    D
  288.     POP    PSW    ;GET COUNT
  289.     DCR    A
  290.     JNZ    CKDLP
  291.     RET        ;OK, NOT 3 DUP
  292. ;
  293. ;Move subroutines
  294. ;
  295. MOVER    MOV    A,M
  296.     STAX    D
  297.     INX    H
  298.     INX    D
  299.     DCX    B
  300.     MOV    A,B
  301.     ORA    C
  302.     JNZ    MOVER
  303.     RET
  304. ;
  305. ;Exit with error message
  306. ;
  307. MSGEXIT EQU    $    ;EXIT W/"INFORMATIONAL" MSG
  308. ERXIT    POP    D    ;GET MSG
  309.     MVI    C,PRINT
  310.     CALL    BDOS
  311. ;
  312. ;Exit, restoring stack and return
  313. ;
  314. EXIT    LHLD    STACK
  315.     SPHL
  316.     RET        ;TO CCP
  317. ;
  318. PASSWD    DS    8    ;PASSWORD KEPT HERE
  319.     DS    40H    ;STACK AREA
  320. STACK    DS    2
  321. ;
  322. ;BDOS equates
  323. ;
  324. RDCON    EQU    1
  325. WRCON    EQU    2
  326. PRINT    EQU    9
  327. CONST    EQU    11
  328. OPEN    EQU    15
  329. CLOSE    EQU    16
  330. SRCHF    EQU    17
  331. SRCHN    EQU    18
  332. ERASE    EQU    19
  333. READ    EQU    20
  334. WRITE    EQU    21
  335. MAKE    EQU    22
  336. REN    EQU    23
  337. STDMA    EQU    26
  338. BDOS    EQU    5
  339. FCB    EQU    5CH 
  340. FCB2    EQU    6CH
  341. FCBEXT    EQU    FCB+12
  342. FCBRNO    EQU    FCB+32
  343. ;
  344.     END
  345.