.title jtscramble ; Copyright (c) 1993, 1994, 1995, 1996 Glenn C. Everhart ; All Rights Reserved ; JT authorize scrambler generator. ; Glenn C. Everhart ; Embodies code to generate the "authentication" part of ; our ACEs in an image, rather than straight DCL, to keep it a ; bit harder to reverse engineer. .library /sys$library:lib.mlb/ $fabdef $namdef $acedef $atrdef $fibdef ; .if ndf,evax .macro .jsb_entry in,out ;entry in out .endm .endc ; auth - ; call: r0,r1 = security info ; r2,r3 = file ID ; (r11)key; ucb ptr in r5 ; output in r0,r1 = auth string auth: .jsb_entry input=,output= ; simple minded scrambler movl (r10),r0 movl 4(r10),r1 ;get security info movl (r9),r2 ;get file id movl 4(r9),r3 xorl2 r3,r0 xorl2 r2,r1 xorl2 0(r11),r0 xorl2 4(r11),r1 ;bunch of xors to scramble ; now xor once more with a constant xorl2 #^x5218fba2,r0 xorl2 #^xaba7126c,r1 ; Xors are too simple. since this represents a security risk, we need a ; more reasonable authentication cipher. Adding some random bits in and ; crossing between 32 bit halves should help some...so go ahead and ; do the messup. Same as in jtdriver... ; The final FFSs make the result not simple combinatorics of the ; pieces, so should make the thing harder to break. pushl r0 pushl r1 ashl #3,r0,r0 addl2 r0,r1 addl2 r2,r1 ; (sp) is old r1 ;4(sp) is old r0 addl2 r1,4(sp) movzwl 5(r11),r1 addl2 r1,4(sp) movl (sp),r1 ;get old r1 ashl #5,r1,r1 addl2 r3,r1 addl2 r1,(sp) ;mix up r1 movzwl 1(r11),r1 addl2 r1,(sp) ;for weirdness use a couple ffs's ffs #0,#32,(sp),r1 addl2 r1,4(sp) ffs #0,#32,4(sp),r1 addl2 r1,(sp) popl r1 popl r0 movl r0,(r8)+ movl r1,(r8) ;return result rsb ; call jtscr(sekey,secinfo,fid,auth) ; outputs auth. .entry jtscr,^m movl 4(ap),r11 ;sec key info movl 8(ap),r10 ;security info (priv mask or ident) movl 12(ap),r9 ;file id movl 16(ap),r8 ;where to store info at end jsb auth ;produce the scramble movl #1,r0 ret ;getfid(fab,fidadr) .globl getfid .entry getfid,^m ; Get FID and return to arg 2 buffer. Arg1 = fab addr movl 4(ap),r2 ;get fab address movl fab$l_nam(r2),r3 ;get nam blk address movl 8(ap),r4 ;output pid address movab nam$w_fid(r3),r3 ;point at 6 bytes of fid movl (r3)+,(r4)+ ;store pid movw (r3)+,(r4)+ ;(6 bytes) ret .psect dat2 iosb: .long 0,0 lpct: .long 0 vchn: .long 0 gcelit: .ascii /GCEV/ ;special literal rtnst: .long 0 ;return status ainbf: .blkb 4 ;hdr here .blkl 1 ;my "call dmn" flg or 0 gcetgt: .long 0 ;will be "GCEV" for my ACEs .blkl 224 ;data .blkl 8 ;safety fid: .long 0,0 ;file id scratch storage ; scratch FIB to read acl with an entry at a time myfib: .long fibfid: .blkw 3 ;fid fibdid: .blkw 3 ;did fibctx: .long 0 ;wc context .long 0 ;nmctl/exctl .long 0,0,0,0,0,0 fibacx: .long 0 ;acl context fibast: .long 0 ;acl status fibgst: .long 0 ;status myfibl=.-myfib-2 ;size ; descriptors for io$_access mf3tp1: .word 255 .word atr$c_addaclent .globl myfdsc myfdsc: mfdsc: .long myfibl .address myfib ;open by file id ; Itemlist to get old ace, delete it, add replacement one. myil3: .word 255 ;length of itemlist item .word atr$c_fndacetyp ;find ace .address uace ;of our type myin2: .word 255 .word atr$c_delaclent ;delete an acl entry... .address uace ;namely the old one ; locs to zero if the ace is empty now (0 in byte 16) .long 0 uace: .blkb 256 ;copy of our ACE .psect cod2 ; redacl(fid,myacebuf,vchn) ; fid = 8 bytes ; myacebuf = 256 byte buffer p1=4 p2=8 p3=12 .entry redacl,^m movzwl @p3(ap),vchn ;get channel bleq 999$ ;skip if illegal movq @p1(ap),fibfid ;get the file id bsbw getace ;if r0=1 on return, we got an ACE, copy to caller, else he zeroes it blbc r0,999$ ;on error just return to caller pushl r0 ;preserve success status movc3 #255,ainbf,@p2(ap) ;copy ace to user buffer popl r0 999$: ret ; getace - Entry to read an ACL for our ACE (if any) (used where ; the ACL is too long so we can't tell if our ACE is there or not.) getace: .jsb_entry output= clrl lpct clrl fibacx ;init acl context clrl fibast clrl fibctx ;init fib context clrl fibdid ;clear the DID... clrw fibdid+4 ;...fid all out pushr #^m movc5 #0,fibctx,#0,#48,fibctx ;clr fib generally past fid 100$: movab myil3,r7 ;address of itemlist incl lpct cmpl lpct,#250 ;max tries (got to terminate somewhere) bgeq 200$ ;if over this then exit ; processed here again, though it may be processed in other entries. $qiow_s efn=#0,chan=vchn,iosb=iosb,func=#io$_access,p1=mfdsc,p5=r7 movl iosb,r6 ;get result for debug blbc r6,200$ ;exit on error/end blbc fibast,200$ ;exit on ast status err blbc r0,200$ ;on qio call or i/o status cmpl gcelit,gcetgt ;our entry? beql 300$ ;if eql yes... brb 100$ ;else no, look some more 200$: popr #^m movl #2,r0 ;flag error to caller rsb 300$: popr #^m movl #1,r0 ;flag NO error to caller rsb .end