<> <> 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 ], RPCSecurity USING [ CopyPrincipal, EntryGenerate ] ; NamesGVAuthImpl: CEDAR PROGRAM IMPORTS DESFace, NamesGV, Rope, RPC, RPCSecurity EXPORTS NamesRPC, RPC SHARES RPCSecurity = { Conversation: TYPE = REF ConversationObject; ConversationObject: PUBLIC TYPE = RPCInternal.ConversationObject; Authenticator: TYPE = RPCInternal.Authenticator; <> <<{KY}KB, spare, { {CK}KB, spare, time, A }KY .>> <> -- 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; RPCSecurity.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[RPCSecurity.EntryGenerate[level, iv, caller, callee, convKey, authenticator]]; }; }.