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; -- 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; 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]; 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; RETURN[RPCInternal.EntryGenerate[level, iv, caller, callee, convKey, authenticator]]; }; }. ψNamesGVAuthImpl.Mesa Copyright c 1985, 1986 by Xerox Corporation. All rights reserved. Last modified by Swinehart, May 9, 1986 11:48:58 am PDT for A talking to B using key CK, contains: {KY}KB, spare, { {CK}KB, spare, time, A }KY . The keys are single cipher blocks. Preliminaries Here's the authenticate portion Here's the linkage to the RPC data structures. Swinehart, May 9, 1986 11:41:17 am PDT Convert to new communications package changes to: DIRECTORY, NamesGVAuthImpl, StartConversation Κƒ˜šœ™Icodešœ Οmœ7™BJšœ7™7—J˜šΟk ˜ JšœžœSžœ˜sJšœžœ5˜BJ˜ Jšœžœ ˜JšžœžœY˜bJšœ žœY˜jJ˜J˜—šœž ˜Jšžœžœ ˜0Jšžœ˜J˜Jšœžœžœ˜,Jšœž œ"˜A—J˜šœžœ˜0Jšœ*™*Jšœ-™-Jšœ"™"JšΟc:˜:—J˜š œžœžœž œžœ˜5Jšœ˜JšœŸ˜6Jšœ˜JšœŸ˜6Jšœ žœžœ˜Jšœ˜—J˜šΟnœžœžœ˜Jš œžœžœžœžœ˜cJšžœ žœ˜0J˜J˜Jšœ žœ˜™ šœžœžœ˜.Jšžœ˜Jšžœ˜#JšžœŸ œžœ˜;—šžœ*ž˜0Jšžœ#˜(—šžœ*ž˜0Jšžœ#˜(——šœ™šžœ1ž˜;Jšœ žœžœ$˜8Jšœžœžœ˜7Jšœžœžœ˜7Jšœ žœ˜Jšžœžœ˜—šžœ#ž˜-Jšœ žœžœ$˜8Jšœžœžœ˜7Jšœžœ˜"Jšžœžœ˜—J˜Jšœžœ)˜<šž˜Jšœ"Ÿ œ˜,Jš œ žœžœžœžœ˜KJšœ$˜$Jšœ.˜.Jšœ˜Jšœ:˜:Jšœ˜šœ˜Jšœžœ˜Jšœžœ˜—šœ(˜(Jšœ˜Jšœžœ˜Jšœžœ˜Jšœ˜—šœ˜Jšœžœ˜Jšœžœ˜—Jšžœ˜——šœ.™.JšžœO˜U—J˜—J˜™&K™%Kšœ Οr-™9—K™—…— rν