-- Michael D. Schroeder, October 30, 1981 3:11 PM

-- MESA access the DES encryption facilities


DESDefs: DEFINITIONS = BEGIN


-- Public types and constants

Block: TYPE = ARRAY [0 .. 3] OF UNSPECIFIED;
Key: TYPE = PACKED ARRAY [0 .. 7] OF
MACHINE DEPENDENT RECORD[b: [0 .. 127], p: [0 .. 1]];

nullKey: Key = ALL[[b:0, p:0]];


-- Key generation and conversion

GetRandomKey: PROC RETURNS [Key];

MakeKey: PROC [source: LONG STRING] RETURNS [Key];

BadKey: ERROR; -- key parity bad


-- To, From must point to segments containing an integral number of Blocks
-- The segments must be totally disjoint or fully congruent!
-- For speed, try to align to and from segments on quadword boundaries.


-- Electronic Code Book.
-- No state kept between 64-bit blocks.

ECBEncrypt: PROC [ key: Key, nBlks: CARDINAL, from, to: LONG POINTER] =
INLINE {CryptData[@key, nBlks, from, to, encrypt, ecb, NIL, NIL]};

ECBDecrypt: PROC [ key: Key, nBlks: CARDINAL, from, to: LONG POINTER] =
INLINE {CryptData[@key, nBlks, from, to, decrypt, ecb, NIL, NIL]};


-- 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.

CBCEncrypt: PROC [ key: Key, seed: Block, nBlks: CARDINAL,
from, to: LONG POINTER]
RETURNS [newSeed: Block] =
INLINE {CryptData[@key, nBlks, from, to, encrypt, cbc, @seed, @newSeed];};

CBCDecrypt: PROC [ key: Key, seed: Block, nBlks: CARDINAL,
from, to: LONG POINTER]
RETURNS [newSeed: Block]=
INLINE {CryptData[@key, nBlks, from, to, decrypt, cbc, @seed, @newSeed];};


-- ???

CBCCheksum: PROC [key: Key, seed: Block, nBlks: CARDINAL,
from: LONG POINTER ] RETURNS [Key];



-- Internal types and procedures

Direction: PRIVATE TYPE = {encrypt, decrypt};
Mode: PRIVATE TYPE = {ecb, cbc};

CryptData: PRIVATE PROC [keyP: POINTER TO Key, nBlks: CARDINAL,
from, to: LONG POINTER, direction: Direction, mode: Mode,
seedP, newSeedP: LONG POINTER TO Block];

END. --DESDefs--