DIRECTORY BasicTime USING [ GetClockPulses ], DESFace, Basics USING [ BITXOR ]; DESDummy: MONITOR IMPORTS Basics, BasicTime EXPORTS DESFace SHARES DESFace = { OPEN DESFace; Words4: TYPE = MACHINE DEPENDENT RECORD[w1, w2, w3, w4: WORD]; XOR64: PROC[a, b, out: LONG POINTER] = INLINE { OPEN aLP: LOOPHOLE[a, LONG POINTER TO Words4], bLP: LOOPHOLE[b, LONG POINTER TO Words4], outP: LOOPHOLE[out, LONG POINTER TO Words4]; outP.w1 _ Basics.BITXOR[aLP.w1, bLP.w1]; outP.w2 _ Basics.BITXOR[aLP.w2, bLP.w2]; outP.w3 _ Basics.BITXOR[aLP.w3, bLP.w3]; outP.w4 _ Basics.BITXOR[aLP.w4, bLP.w4]; }; Words2: TYPE = MACHINE DEPENDENT RECORD[w1, w2: WORD]; XOR32: PROC[a, b: LONG UNSPECIFIED, out: POINTER] = INLINE { OPEN aP: LOOPHOLE[a, Words2], bP: LOOPHOLE[b, Words2], outP: LOOPHOLE[out, POINTER TO Words2]; outP.w1 _ Basics.BITXOR[aP.w1, bP.w1]; outP.w2 _ Basics.BITXOR[aP.w2, bP.w2]; }; cachedKey: Key; noKeyCached: BOOLEAN _ TRUE; BadKey: PUBLIC ERROR = CODE; checkingForParity: BOOL _ TRUE; InternalizeKey: ENTRY PROC [keyP: POINTER TO Key] = { IF noKeyCached OR cachedKey # keyP^ THEN { IF checkingForParity THEN FOR i: CARDINAL IN [0..7] DO IF keyP[i].p # parityTable[keyP[i].b] THEN RETURN WITH ERROR BadKey; ENDLOOP; cachedKey _ keyP^; noKeyCached _ FALSE; }; }; NotImplemented: ERROR = CODE; CryptData: PUBLIC PROC [keyP: POINTER TO Key, nBlks: CARDINAL, from, to: Blocks, direction: Direction, mode: Mode, seedP: LONG POINTER TO IV _ NIL] = { newSeed: IV; IF mode = checksum THEN ERROR NotImplemented; IF mode = cbcCheck AND direction = encrypt AND nBlks > 0 THEN FOR blk: CARDINAL IN [0..nBlks-1) DO XOR64[@from[nBlks-1], @from[blk], @from[nBlks-1]]; ENDLOOP; InternalizeKey[keyP]; FOR blk: CARDINAL IN [0 .. nBlks) DO IF mode#ecb THEN IF direction=encrypt THEN XOR64[@from[blk], seedP, @from[blk]] ELSE newSeed _ from[blk]; XOR64[keyP, @from[blk], @to[blk]]; IF mode#ecb THEN IF direction=encrypt THEN seedP _ @to[blk] ELSE {XOR64[@to[blk], seedP, @to[blk]]; seedP^ _ newSeed}; ENDLOOP; IF mode = cbcCheck AND direction = decrypt AND nBlks > 0 THEN { FOR blk: CARDINAL IN [0..nBlks-1) DO XOR64[@to[nBlks-1], @to[blk], @to[nBlks-1]]; ENDLOOP; } }; randomSeed: Block _ [1,2,3,4]; GetRandomIV: PUBLIC PROC RETURNS [iv: IV] = { prevSeed: Block _ randomSeed; pulse1: POINTER TO LONG CARDINAL = LOOPHOLE[@randomSeed[0]]; pulse2: POINTER TO LONG CARDINAL = LOOPHOLE[@randomSeed[2]]; seedKey: POINTER TO Key = LOOPHOLE[@randomSeed]; pulse1^ _ pulse1^ + BasicTime.GetClockPulses[]; XOR32[pulse2^, BasicTime.GetClockPulses[], pulse2]; CorrectParity[seedKey]; CryptData[keyP: seedKey, nBlks: 1, from: LOOPHOLE[LONG[@prevSeed], Blocks], to: LOOPHOLE[LONG[@iv], Blocks], direction: encrypt, mode: ecb, seedP: NIL]; }; GetRandomKey: PUBLIC PROC RETURNS [k: Key] = { k _ LOOPHOLE[GetRandomIV[]]; CorrectParity[@k]; }; MakeKey: PUBLIC PROC [source: LONG STRING] RETURNS [key: Key] = { key _ nullKey; FOR i: CARDINAL IN [0..source.length) DO j: CARDINAL = i MOD 8; c: CHARACTER = IF source[i] IN ['A..'Z] THEN 'a + (source[i]-'A) ELSE source[i]; key[j].b _ Basics.BITXOR[LOOPHOLE[c, [0 .. 127]], key[j].b]; ENDLOOP; CorrectParity[@key]; }; parityTable: PACKED ARRAY [0..127] OF [0..1] _ [ 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 ]; CorrectParity: PUBLIC PROC[keyP: LONG POINTER TO Key] = { FOR i: CARDINAL IN [0 .. 7] DO keyP[i].p _ parityTable[keyP[i].b]; ENDLOOP; }; [] _ GetRandomKey[]; }. όDESDummy.mesa - Dummy implementation of DES (used by RPCRuntime) Copyright c 1985 by Xerox Corporation. All rights reserved. Andrew Birrell, September 7, 1983 4:45 pm Bob Hagmann February 11, 1985 10:13:49 am PST Russ Atkinson (RRA) February 13, 1985 12:28:51 pm PST Turn this to false to avoid the BadKey error. This is to allow servers that are not prepared to handle this to continue to function (more or less). Of course, the best thing to do is to handle this error and do "the right thing." Ideally, this should use a true random number generator User interface routine to construct a 64 bit key from an ASCII string. "key" is an array that holds the 64 bit key. Note: every eighth bit of "key" is an odd parity bit for the preceeding seven bits. ΚE˜codešœ@™@Kšœ Οmœ1™K˜š Οnœžœ žœžœžœ˜/šž˜Kš œžœžœžœžœ ˜)Kš œžœžœžœžœ ˜)Kš œžœžœžœžœ ˜,—Kšœžœ˜(Kšœžœ˜(Kšœžœ˜(Kšœžœ˜(Kšœ˜K˜—Kš œžœžœž œžœ žœ˜6K˜š Ÿœžœžœž œžœžœ˜<šž˜Kšœžœ ˜Kšœžœ ˜Kšœžœžœžœ ˜'—Kšœžœ˜&Kšœžœ˜&Kšœ˜K˜K˜—K˜Kšœ žœžœ˜K˜Kšœžœžœžœ˜šœžœžœ˜Kšœη™η—K˜š Ÿœžœžœžœžœ ˜5šžœ žœžœ˜*šžœž˜šžœžœžœž˜Kš žœ$žœžœžœžœ˜DKšžœ˜——K˜Kšœžœ˜Kšœ˜—Kšœ˜K˜—Kšœžœžœ˜K˜šŸ œžœžœžœžœ žœ=žœžœžœžœžœ˜—K˜Kšœ žœ˜ K˜Kšžœžœžœ˜-K˜šžœžœžœ ž˜=šžœžœžœ ž˜$Kšœ2˜2Kšžœ˜—K˜—K˜šžœžœžœž˜$šžœ ž˜šžœ˜Kšžœ%˜)Kšžœ˜——K˜"šžœ ž˜šžœ˜Kšžœ˜Kšžœ6˜:——Kšžœ˜K˜—šžœžœžœ žœ˜?šžœžœžœ ž˜$Kšœ,˜,Kšžœ˜—Kšœ˜—Kšœ˜K˜K˜—K˜K˜š Ÿ œžœžœžœžœ˜-Kšœ7™7K˜Kš œžœžœžœžœžœ˜