NamesGVAuthImpl.Mesa
Copyright © 1985, 1986 by Xerox Corporation. All rights reserved.
Last modified by Swinehart, May 9, 1986 11:48:58 am PDT
DIRECTORY
DESFace USING [ Block, CBCCheckEncrypt, CorrectParity, EncryptBlock, GetRandomIV, GetRandomKey, IV, Key, nullKey ],
NamesGV USING [ Authenticity, GVAuthenticate, GVIsAuthenticated ],
NamesRPC,
Rope USING [ Length ],
RPC USING [ AuthenticateFailed, ConversationLevel, EncryptionKey, maxPrincipalLength, Principal ],
RPCInternal USING [ Authenticator, AuthenticatorObject, ConversationObject, CopyPrincipal, EntryGenerate ]
;
NamesGVAuthImpl:
CEDAR PROGRAM
IMPORTS DESFace, NamesGV, Rope, RPC, RPCInternal
EXPORTS NamesRPC, RPC = {
Conversation: TYPE = REF ConversationObject;
ConversationObject: PUBLIC TYPE = RPCInternal.ConversationObject;
Authenticator:
TYPE = RPCInternal.Authenticator;
for A talking to B using key CK, contains:
{KY}KB, spare, { {CK}KB, spare, time, A }KY .
The keys are single cipher blocks.
-- The rest is encrypted with CBC-check using a zero IV --
AuthenticatorLayout:
TYPE =
MACHINE
DEPENDENT
RECORD[
ky(0): DESFace.Key,
kySpare(4): DESFace.Key, -- space for larger keys! --
ck(8): DESFace.Key,
ckSpare(12): DESFace.Key, -- space for larger keys! --
time(16): LONG CARDINAL,
a(18): StringBody];
StartConversation:
PUBLIC
PROC[
caller: RPC.Principal, key: RPC.EncryptionKey, callee: RPC.Principal, level: RPC.ConversationLevel]
RETURNS[ conversation: Conversation] = TRUSTED {
authenticator: Authenticator;
convKey: DESFace.Key;
iv: DESFace.IV;
Preliminaries
nBlks:
CARDINAL =(
SIZE[AuthenticatorLayout] -
SIZE[StringBody[0]] +
SIZE[StringBody[caller.Length[]]] +
SIZE[DESFace.Block]-1 --rounding-- ) / SIZE[DESFace.Block];
IF caller.Length[] > RPC.maxPrincipalLength
THEN
ERROR RPC.AuthenticateFailed[badCaller];
IF callee.Length[] > RPC.maxPrincipalLength
THEN
ERROR RPC.AuthenticateFailed[badCallee];
Here's the authenticate portion
SELECT NamesGV.GVAuthenticate[rName: caller, key: key]
FROM
unknown => ERROR RPC.AuthenticateFailed[communications];
nonexistent => ERROR RPC.AuthenticateFailed[badCaller];
bogus, perhaps => ERROR RPC.AuthenticateFailed[badKey];
authentic => NULL;
ENDCASE => ERROR;
SELECT NamesGV.GVIsAuthenticated[callee]
FROM
unknown => ERROR RPC.AuthenticateFailed[communications];
nonexistent => ERROR RPC.AuthenticateFailed[badCallee];
bogus, perhaps, authentic => NULL;
ENDCASE => ERROR;
iv ← DESFace.GetRandomIV[];
authenticator ← NEW[RPCInternal.AuthenticatorObject[nBlks]];
BEGIN
kb: DESFace.Key ← DESFace.nullKey -- !!! --;
authRec: LONG POINTER TO AuthenticatorLayout = LOOPHOLE[@authenticator[0]];
authRec.ky ← DESFace.GetRandomKey[];
authRec.ck ← convKey ← DESFace.GetRandomKey[];
authRec.time ← 0;
RPCInternal.CopyPrincipal[from: caller, to: @(authRec.a)];
DESFace.CorrectParity[@kb];
DESFace.EncryptBlock[key: kb,
from: LOOPHOLE[@authRec.ck],
to: LOOPHOLE[@authRec.ck] ];
DESFace.CBCCheckEncrypt[key: authRec.ky,
nBlks: nBlks-2,
from: LOOPHOLE[@authRec.ck],
to: LOOPHOLE[@authRec.ck],
seed: [0,0,0,0] ];
DESFace.EncryptBlock[key: kb,
from: LOOPHOLE[@authRec.ky],
to: LOOPHOLE[@authRec.ky] ];
END;
Here's the linkage to the RPC data structures.
RETURN[RPCInternal.EntryGenerate[level, iv, caller, callee, convKey, authenticator]];
};
}.
Swinehart, May 9, 1986 11:41:17 am PDT
Convert to new communications package
changes to: DIRECTORY, NamesGVAuthImpl, StartConversation