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] }; 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. φDESFace.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Andrew Birrell 16-Mar-82 8:36:51 Michael D. Schroeder, October 30, 1981 3:11 PM Levin, May 26, 1983 4:20 pm Russ Atkinson (RRA) February 19, 1985 2:10:27 pm PST Doug Wyatt, February 22, 1985 1:41:13 pm PST Public types and constants Key and IV generation and conversion Returns pseudo-random or random key (depending on available hardware), with odd parity Canonical conversion of characters into key; Parity bits are set to odd parity. Forces parity bits of keyP^ to odd parity Single-block encryption and decryption Encryption and decryption of runs of blocks "from" and "to" must be totally disjoint or fully congruent! For speed, try to align them on quad-word boundaries. There are three modes: ECB, CBC and CBCCheck. "ECB" = Electronic Code Book: No state kept between 64-bit blocks. "CBC" = Cipher Block Chaining: 64-bits of state kept between blocks. This state is XOR'd with the next incoming clear text block before encryption. seed is the 64-bit initial value of this state. Encryption: to[0] _ Encrypt[from[0] XOR seed^] to[i] = Encrypt[from[i] XOR to[i-1]] Decryption: to[0] = Decrypt[from^[0]] XOR seed^ to[i] = Decrypt[from^[i]] XOR from^[i-1] "CBCCheck" = CBC with checksum: When encrypting: Let chk = 64-bit XOR of from^[0] through from^[nBlks-1]. to[0] _ Encrypt[from[0] XOR seed^] to[i] = Encrypt[from[i] XOR to[i-1]] to[nBlks-1] _ Encrypt[chk XOR to[nBlks-2]] The inverse operation is performed on decryption. Thus after decryption, to[nBlks-1] should hold its initial value. If any cipher text is modified by an intruder, this is likely to alter decrypted to[nBlks-1]: for any change to cipher text, each bit in to[nBlks-1] is altered with probability 1/2. So if the client can verify N bits of to[nBlks-1], he can detect modified cipher text with probability (1 - 2^-N). Key parity bad; may be raised by any en- or de- cryption proc. Calculate CBC checksum function; "from" is undisturbed. Internal types and procedures Κ,˜codešœ ™ Kšœ Οmœ1™™>—K˜š  œžœžœ˜@Kšžœ2˜8K˜—š  œžœžœ˜@Kšžœ2˜8K˜—š  œžœžœžœ˜JKšžœ9˜?K˜—š  œžœžœžœ˜JKšžœ9˜?K˜—š œžœžœžœ˜OKšžœ>˜DK˜—š œžœžœžœ˜OKšžœ>˜DK˜—K˜š  œžœžœžœžœ žœ˜ZKšžœžœžœ˜SKšœ7™7K˜——K™šœ™K˜Kšœ žœžœ˜-Kšœžœžœ"˜4K˜Kš  œžœžœžœžœ žœ>žœžœžœžœžœ˜–—K˜Kšžœ˜—…—@b