title crypt search monsym,macsym .requi des extern des,sed,setkey .requi hax:error extern fatal ;;; Version marker (for .fbusw). mark: exp ; Our name ver: exp 1 ; Current version ;;; Registers. ;;; We know that AC15 and AC16 are safe the from des library routines. ;;; Chose one of 'ptr' and 'addr'. ;;; 'ptr' use 4-bit byte pointers to fetch and restore the 64-bit ;;; sequences and is four times slower than 'addr', which uses ;;; move/shift/mask instructions. This should make the choice easy but ;;; since 99% of the running time is spent in the dec/sed routines ;;; the actual speed profit is 5-10% (and 'addr' about 200 words longer). ;ptr=15 ; A little smaller addr=15 ; A little faster count=16 ; Loop counter for encr p=17 ; PDL as usual ;;; Flags in AC0. $encr=1 ; We are encrypting $decr=2 ; We are decrypting ;;; Useful instructions. ;;; Minimum. define min (ac,e) < camle ac,e move ac,e > ;;; Minimum immediate. define mini (ac,e) < caile ac,e movei ac,e > ;;; Varia. ijfn: block 1 ; Input file. ojfn: block 1 ; Output file. cryp: block 1 ; Address to des or sed. pdl: block key: block 2 ; For rkey. keytab: block 40 ; The keytable, set up by setkey. ;;; Paging stuff. fpag=5 ; First page # in process pspc=<770-fpag+1> ; # of pages available (leave some to DDT) pim: block 1 ; # pages currently in map pcnt: block 1 ; # of crypted pages so far filep: block 1 ; # of first mapped file page ;;; FDB stuff. fdbfst=.fbbyv ; First word of FDB fdb: block > define fbpgc (ac) < hrrz ac,fdb > ; Get page count define fbsiz (ac) < move ac,fdb+1 > ; Get byte count define fbbsz (ac) < move ac,fdb > ; Get byte size word define fbusw (ac) < move ac,fdb+fdbsz-1> ; Get user-settable word ;;; Main entry. crypt: reset% move p,[iowd pdlen,pdl] ;; Get encryption/decryption option. setzm 0 hrroi 1,[asciz /e or d :/] psout% pbin% cain 1,"e" tro $encr cain 1,"d" tro $decr trnn $encr movei 2,des trnn $decr movei 2,sed movem 2,cryp pbin% ;cr pbin% ;lf ;; Input file. hrroi 1,[asciz /Input: /] psout% move 1,[gj%old!gj%fns!gj%sht] move 2,[.priin,,.priou] gtjfn% ; Get input file. ercal fatal hrrzm 1,ijfn move 2,[of%rd!of%nwt] openf% ; Open it. ercal fatal call ifdb ;; Output file hrroi 1,[asciz /Output: /] psout% move 1,[gj%fou!gj%fns!gj%sht] move 2,[.priin,,.priou] gtjfn% ercal fatal hrrzm 1,ojfn move 2,[of%wr!of%nwt] openf% ercal fatal call rkey ; Get the key dmove 1,key movei 3,keytab call setkey ; Set up the keytable call encr ; {En,De}crypt ;; Set the output file bytesize and bytecount, and close the files. move 1,ijfn closf% ; Close input file ercal fatal move 1,ojfn hll 1,[co%nrj] closf% ; Close output file but keep JFN ercal fatal call ofdb ; Set FDB data in for output file. move 1,ojfn rljfn% ; Release the output JFN. ercal fatal haltf% jrst .-1 ;;; The {En,De}cryption loop. encr: setzm pcnt ; Clear page count setzm filep ; Clear file page # encr1: call mfil ; Map part of the file ret ; Nothing more ifdef ptr ]> ifdef addr > move count,pim imuli count,440 ; # of 64-bit seqs encr2: sojl count,[ call ufil ; Done. Map onto output file jrst encr1 ] call gett ; Get 64 bits movei 3,keytab call @cryp ; {En,De}crypt call putt ; Write the scrambled bits back jrst encr2 ;;; Read up to 9 7-bit characters into key. rkey: hrroi 1,[asciz /Key: /] psout% move 2,[point 7,key] movei 3,^d9 setzm key ; Padded with zero setzm key+1 rkey1: pbin% cain 1,.chcrt jrst rkey2 idpb 1,2 sojg 3,rkey1 rkey2: pbin% caie 1,.chlfd jrst rkey2 ret ;;; Get 64 bits from ptr/addr into AC1-AC2. ;;; Fast and hairy version. ifdef addr < ;;; A short get. define getsht(l,a) < lshc 1,l ret > ;;; A long get. define getlng(l1,l2) < lshc 1,l1 move 3,2(addr) lsh 3,l2 ior 2,3 ret > ;;; The get. gett: dmove 1,(addr) move 3,addr andi 3,17 jrst @[ get00 get01 getzz get03 getzz get05 getzz get07 get10 getzz get12 getzz get14 getzz get16 getzz ](3) get00: ret get01: getlng(34,-10) get03: getlng(24,-20) get05: getlng(14,-30) get07: getsht(04,1) get10: getlng(40,-04) get12: getlng(30,-14) get14: getlng(20,-24) get16: getsht(10,2) getzz: hrroi 1,[asciz /Impossible dispatch in get /] psout% haltf% jrst .-1 > ;;; A slow and simple version. ifdef ptr < gett: movei 3,^d16 move 4,[point 4,1] move 5,ptr get1: ildb 6,5 idpb 6,4 sojg 3,get1 ret > ;;; Put 64 bits at ptr/addr from AC1-AC2. ;;; A fast and hairy version. ifdef addr < ;;; A long put. define putlng(l1,m1,l2,m2) < move 3,2 lsh 3,l2 move 4,2(addr) and 4,[m2] ior 3,4 movem 3,2(addr) lshc 1,l1 move 4,0(addr) and 4,[m1] ior 1,4 dmovem 1,0(addr) addi addr,2 ret > ;;; The put. putt: move 3,addr andi 3,17 jrst @[ put00 put01 putzz put03 putzz put05 putzz put07 put10 putzz put12 putzz put14 putzz put16 putzz ](3) put00: move 3,1(addr) andi 3,377 ior 2,3 dmovem 1,0(addr) addi addr,1 ret put01: putlng(-34,<777777,,777400>,10,<000000,,177777>) put03: putlng(-24,<777777,,600000>,20,<000077,,777777>) put05: putlng(-14,<777700,,000000>,30,<037777,,777777>) put07: lshc 1,-04 move 3,0(addr) and 3,[740000,,000000] ior 1,3 move 3,1(addr) andi 3,17 ior 2,3 dmovem 1,0(addr) addi addr,1 ret put10: putlng(-40,<777777,,777760>,04,<000000,,007777>) put12: putlng(-30,<777777,,770000>,14,<000003,,777777>) put14: putlng(-20,<777774,,000000>,24,<001777,,777777>) put16: lshc 1,-10 move 3,0(addr) and 3,[776000,,000000] ior 1,3 dmovem 1,0(addr) addi addr,2 ret putzz: hrroi 1,[asciz /Impossible dispatch in put /] psout% haltf% jrst .-1 > ;;; A slow and simple version. ifdef ptr < putt: movei 3,^d16 move 4,[point 4,1] put1: ildb 5,4 idpb 5,ptr sojg 3,put1 ret > ;;; Map file. mfil: fbpgc 3 ; # of pages in file camg 3,pcnt ret ; Return +1 if nothing more mini 3,pspc ; # of free pages in process move 1,filep hrl 1,ijfn ffufp% ; Find first used file page ercal fatal hrrzm 1,filep movs 1,1 ffffp% ; Find first free file page hrrz 1,1 sub 1,filep ; # of contiguous pages min 3,1 movem 3,pim hll 3,[pm%cnt!pm%rd!pm%wr!pm%cpy] move 2,[.fhslf,,fpag] move 1,filep hrl 1,ijfn pmap% aos (p) ; Return +2 if mapped ret ;;; Map onto file. ufil: move 1,[.fhslf,,fpag] movs 2,ojfn hrr 2,filep ; File's starting page move 3,pim ; # of pages currently in process addm 3,pcnt ; Update # of (soon) finished pages addm 3,filep hll 3,[pm%cnt] pmap% ret ;;; Get some info about the input file and check the user-setable word. ifdb: move 1,ijfn move 2,[fdbsz,,fdbfst] movei 3,fdb gtfdb% trnn $decr jrst [ fbusw 1 ; Encrypting skipn 1 ret trz 1,77 ; Ignore version # camn 1,mark jrst [ hrroi 1,[asciz /?File is already encrypted/] hrroi 3,[asciz /?Continue to encrypt anyway/] call iferrs haltf% ret ] hrroi 1,[asciz /?File's .fbusw is already set to: /] fbusw 2 hrroi 3,[asciz /?Continue will not keep this in the output file/] call iferru haltf% ret ] fbusw 1 ; Decrypting trz 1,77 ; Ignore version # came 1,mark jrst [ hrroi 1,[asciz /?File is not marked as encrypted/] hrroi 3,[asciz /?Continue to decrypt anyway/] call iferrs haltf% ret ] fbusw 1 andi 1,77 ; Check version # came 1,ver jrst [ move 2,1 hrroi 1,[asciz /?File is encrypted with another version of crypt: /] hrroi 3,[asciz /?Continue to decrypt anyway/] call iferrv haltf% ret ] ret ;;; Set some data on the output file and check and set the user-settabel word. ofdb: move 1,ojfn hll 1,[fld(.fbbyv,cf%dsp)] move 2,[fb%bsz] fbbsz 3 chfdb% ; Set byte size hll 1,[fld(.fbsiz,cf%dsp)] setom 2 fbsiz 3 chfdb% ; Set byte count trnn $encr ret ; Decrypting, don't set .fbusw hll 1,[fld(.fbusw,cf%dsp)] setom 2 move 3,mark ; Merge our name... ior 3,ver ; ...and version # chfdb% ret ;;; Print error messages for ifdb. ;;; AC1: Byte pointer to string1 (iferrs,iferru,iferrv) ;;; AC2: Number (iferru,iferrv) ;;; AC3: Byte pointer to string2 (iferrs,iferru,iferrv) iferrs: psout% ; String1 call crlf move 1,3 psout% ; String2 jrst crlf iferru: psout% ; String1 move 4,2 move 5,3 movei 1,.priou ; Octal,,Octal # hlrz 2,2 move 3,[no%mag!no%lfl!no%zro!fld(6,no%col)!fld(^d8,no%rdx)] nout% ercal fatal movei 1,"," pbout% pbout% movei 1,.priou hrrz 2,4 nout% ercal fatal call crlf move 1,5 psout% ; String2 jrst crlf iferrv: psout% ; String1 move 4,3 movei 1,.priou ; Decimal # move 3,[no%mag!fld(3,no%col)!fld(^d10,no%rdx)] nout% ercal fatal call crlf move 1,4 psout% ; String2 jrst crlf ;;; Print a CRLF on .priou . crlf: push p,1 movei 1,.chcrt pbout% movei 1,.chlfd pbout% pop p,1 ret end crypt .../PEM