DESFace: DEFINITIONS = BEGIN Block: TYPE = ARRAY [0 .. 3] OF UNSPECIFIED; -- 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 last edited by Andrew Birrell 16-Mar-82 8:36:51 last edited by Michael D. Schroeder, October 30, 1981 3:11 PM Last Edited by: Levin, May 26, 1983 4:20 pm 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 Ê#˜Jšœ ™ Jšœ1™1Jšœ>™>J™+J˜Jšœ Ïk œ˜J˜Jšœ™˜š œœœ œ œÏc˜KJ˜—Jš œœœœœœœ˜.J˜šœœœœ ˜$Jšœ œœ˜6J˜—šœœ ž(˜GJ˜—Jšœœ ž"˜3J˜—Jšœ$™$˜JšÏn œœœœ˜J˜JšŸ œœœ˜!šœ1ž%™VJ˜—Jš Ÿœœ œœœ˜2šœO™OJ˜—Jš Ÿ œœœœœ˜0šœ)™)J˜—J˜J˜—Jšœ&™&˜š Ÿ œœœœœ ˜@Jšœœœœ˜OJ˜—š Ÿ œœœœœ ˜@Jšœœœœ˜O—J˜—Jšœ+™+˜Jšœs™sJ˜Jšœ-™-J˜šœ™Jšœ$™$—šœ™Jšœ&™&JšœN™NJšœ/™/šœ ™ Jšœ"™"Jšœ$™$—šœ ™ Jšœ#™#Jšœ(™(——šœ™šœ™Jšœ8™8Jšœ"™"Jšœ$™$Jšœ*™*—Jšœ ™ —J˜Jšœœ˜Jšœ>™>J˜šŸ œœœ˜@Jšœ2˜8J˜—šŸ œœœ˜@Jšœ2˜8J˜—šŸ œœœœ˜JJšœ9˜?J˜—šŸ œœœœ˜JJšœ9˜?J˜—šŸœœœœ˜OJšœ>˜DJ˜—šŸœœœœ˜OJšœ>˜DJ˜—J˜šŸœœœœ˜BJšœ œ˜Jšœœœ˜S—Jšœ7™7J˜J˜Jšœ™˜Jšœ œœ˜-Jšœœœ"˜4J˜šŸ œœœ˜Jšœœœ œ)˜NJš œœœœœœ˜-——J˜—Jšœ˜J˜—…—Nï