-- MESA access the DES encryption facilities
-- DESFace.mesa
-- Andrew Birrell 16-Mar-82 8:36:51
-- Michael D. Schroeder, October 30, 1981 3:11 PM
DESFace: DEFINITIONS = BEGIN
-- Public types and constants
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 --
-- Key and IV generation and conversion
GetRandomIV: PROC RETURNS [IV];
GetRandomKey: PROC RETURNS [Key];
-- Returns pseudo-random or random key (depending on
-- available hardware), with odd parity --
MakeKey: PROC[ source: LONG STRING ]
RETURNS [Key];
-- Canonical conversion of characters into key;
-- Parity bits are set to odd parity. --
CorrectParity: PROC[keyP: LONG POINTER TO Key];
-- Forces parity bits of keyP↑ to odd parity --
-- Single-block encryption and decryption --
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] };
-- 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).
BadKey: ERROR;
-- Key parity bad: may be raised by any en- or de- cryption proc.
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]};
-- Calculate CBC checksum function; "from" is undisturbed. --
-- Internal types and procedures
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 --