<> <> <> <> <> <> <> DESFace: DEFINITIONS = BEGIN <> Block: TYPE = ARRAY [0 .. 3] OF WORD; -- plain or cipher text block Blocks: TYPE = LONG POINTER TO ARRAY OF Block; Key: TYPE = PACKED ARRAY [0 .. 7] OF MACHINE DEPENDENT RECORD [b: [0 .. 127], p: [0 .. 1]]; nullKey: Key = ALL[[b:0, p:0]]; -- Note that this has incorrect parity IV: TYPE = Block; -- Initialization vector for CBC <<>> <> GetRandomIV: PROC RETURNS [IV]; <<>> GetRandomKey: PROC RETURNS [Key]; <> MakeKey: PROC [source: LONG STRING] RETURNS [Key]; <> CorrectParity: PROC [keyP: LONG POINTER TO Key]; <> <<>> <> EncryptBlock: PROC [key: Key, from, to: LONG POINTER TO Block] = INLINE { CryptData[@key, 1, LOOPHOLE[from], LOOPHOLE[to], encrypt, ecb, NIL] }; DecryptBlock: PROC [key: Key, from, to: LONG POINTER TO Block] = INLINE { CryptData[@key, 1, LOOPHOLE[from], LOOPHOLE[to], decrypt, ecb, NIL] }; <<>> <<>> <> <<"from" and "to" must be totally disjoint or fully congruent! For speed, try to align them on quad-word boundaries.>> <> <<"ECB" = Electronic Code Book:>> <> <<"CBC" = Cipher Block Chaining:>> <<64-bits of state kept between blocks. >> <> <> <> <> <> <> <> <> <<"CBCCheck" = CBC with checksum:>> <> <> <> <> <> <> BadKey: ERROR; <> ECBEncrypt: PROC [key: Key, nBlks: CARDINAL, from, to: Blocks] = INLINE {CryptData[@key, nBlks, from, to, encrypt, ecb]}; ECBDecrypt: PROC [key: Key, nBlks: CARDINAL, from, to: Blocks] = INLINE {CryptData[@key, nBlks, from, to, decrypt, ecb]}; CBCEncrypt: PROC [key: Key, nBlks: CARDINAL, from, to: Blocks, seed: IV] = INLINE {CryptData[@key, nBlks, from, to, encrypt, cbc, @seed]}; CBCDecrypt: PROC [key: Key, nBlks: CARDINAL, from, to: Blocks, seed: IV] = INLINE {CryptData[@key, nBlks, from, to, decrypt, cbc, @seed]}; CBCCheckEncrypt: PROC [key: Key, nBlks: CARDINAL, from, to: Blocks, seed: IV] = INLINE {CryptData[@key, nBlks, from, to, encrypt, cbcCheck, @seed]}; CBCCheckDecrypt: PROC [key: Key, nBlks: CARDINAL, from, to: Blocks, seed: IV] = INLINE {CryptData[@key, nBlks, from, to, decrypt, cbcCheck, @seed]}; Checksum: PROC [key: Key, nBlks: CARDINAL, from: Blocks, seed: IV] RETURNS[newSeed: IV] = INLINE {CryptData[@key, nBlks, from, NIL, encrypt, checksum, @seed]; RETURN[seed]}; <> <<>> <> Direction: PRIVATE TYPE = {encrypt, decrypt}; Mode: PRIVATE TYPE = {ecb, cbc, cbcCheck, checksum}; CryptData: PRIVATE PROC [keyP: POINTER TO Key, nBlks: CARDINAL, from, to: Blocks, direction: Direction, mode: Mode, seedP: LONG POINTER TO IV _ NIL]; END.