;Alto->8086 small-c compiler rev 2.0 C_CODE SEGMENT $INCLUDE(8086LIB.D) $INCLUDE(RPCSecurity.DEC) ASSUME CS:C_CODE, DS:C_DATA ; #include ; extern int PktExchange(); ; extern SetupResponse(); ; extern struct ExportInstance *exportTable; ; extern union Machine myHost; ; extern int *mySoc; ; extern SendPup(); ; extern struct PBI *GetPBI(); ; extern int MultEq(); ; extern int DoubleEq(); ; extern ReleasePBI(); ; extern CryptData(); ; extern DecryptBlock(); ; extern CBCCheckDecrypt(); ; extern int DoubleComp(); ; extern int DoubleInc(); ; extern Move2(); ; extern int StringSize(); ; extern int StringSizeN(); ; extern struct ShortSTRING *ShallString(); ; extern int AuthenticateFailed; ; extern ReadCalendar(); ; extern Timer(); ; extern int *GetFixed(); ; extern MoveBlock(); ; struct ConversationID *lastConversation; ; struct PktConversationID *firstConversation; ; static struct Conversation *conversations[0]; ; int UnknownConversation; /* SIGNAL */ ; static struct EncryptionKey *ka; ; static struct EncryptionKey *kb; ; static struct EncryptionKey privateKey; /* null, for now */ ; struct Block { ; byte blockElt[8]; ; }; ; struct RFARequest { ; struct PktConversationID callerConv; ; struct PktID callerPktID; /* still encrypted , */ ; word nonceID[2]; /* nominated by requester*/ ; }; ; struct RFAResponse { ; struct IV iv; ; struct ConnectionID connection; ; struct CallCount callCt; ; word nonceID[2]; ; word level; ; struct Authenticator authenticator; ; }; ; struct EncryptionKey nullKeyB; /* = table { 0; 0; 0; 0; } */ ; struct EncryptionKey nullSeedB; /* = table { 0; 0; 0; 0; } */ ; struct Conversation ; *GenerateConversation() { _GenerateConversation: PUSH BP MOV BP,SP ; return (EntryGenerate(slNone, nullKey, 0, 0, nullKey, 0)); XOR BX,BX PUSH BX LEA BX,_nullKeyB PUSH BX XOR BX,BX PUSH BX XOR BX,BX PUSH BX XOR BX,BX LEA CX,_nullKeyB CALL _EntryGenerate ADD SP,8 MOV SP,BP POP BP RET; ; }; ; static struct Conversation ; *EntryGenerate(level, iv, originator, responder, convKey, auth) _EntryGenerate: ; int /* SecurityLevel */ level; ; struct IV *iv; ; struct ShortSTRING *originator; ; struct ShortSTRING *responder; ; struct EncryptionKey *convKey; ; struct Authenticator *auth; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; DoubleInc(&lastConversation->count, 1); MOV BX,_lastConversation INC BX INC BX PUSH BX MOV BX,1 POP CX CALL _DoubleInc ; lastConversation->count.fields &= notCalleeMask; MOV BX,_lastConversation AND WORD PTR [BX+4],0FF7FX ; return (AddConversation(lastConversation, level, iv, originator, responder, convKey, auth)); MOV BX,_lastConversation PUSH BX ; BX _ _level MOV BX,[BP+10] PUSH BX ; BX _ _iv MOV BX,[BP+8] PUSH BX ; BX _ _originator MOV BX,[BP+6] PUSH BX ; BX _ _responder MOV BX,[BP+4] PUSH BX ; BX _ _auth MOV BX,[BP-4] ; CX _ _convKey MOV CX,[BP-2] CALL _AddConversation ADD SP,0AX MOV SP,BP POP BP RET; ; }; ; struct Conversation ; *StartConversation(caller, key, callee, level) _StartConversation: ; struct ShortSTRING *caller; ; struct EncryptionKey *key; ; struct ShortSTRING *callee; ; int /* SecurityLevel */ level; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { /* RETURNS {conversation: Conversation;}; */ ; struct Authenticator *authenticator; ; struct IV iv; ; struct EncryptionKey convKey; ; if (level == slNone) SIGNAL(ERROR); /* may relax this constraint later, to allow multi clear convs. */ ADD SP,0FFEEX ; BX _ _level MOV BX,[BP-4] OR BX,BX JNZ X1 MOV BX,2 CALL _SIGNAL X1: ; authenticator = Authenticate(caller, key, callee, &convKey, &iv); ; BX _ _caller MOV BX,[BP+6] PUSH BX ; BX _ _key MOV BX,[BP+4] PUSH BX ; BX _ _callee MOV BX,[BP-2] PUSH BX ;&_iv LEA BX,[BP-14] ;&_convKey LEA CX,[BP-22] CALL _Authenticate ADD SP,6 ; _authenticator _ BX MOV [BP-6],BX ; return (EntryGenerate(level, &iv, caller, callee, &convKey, authenticator)); ; BX _ _level MOV BX,[BP-4] PUSH BX ;&_iv LEA BX,[BP-14] PUSH BX ; BX _ _caller MOV BX,[BP+6] PUSH BX ; BX _ _callee MOV BX,[BP-2] PUSH BX ; BX _ _authenticator MOV BX,[BP-6] ;&_convKey LEA CX,[BP-22] CALL _EntryGenerate ADD SP,8 MOV SP,BP POP BP RET; ; }; ; struct Authenticator ; *Authenticate(caller, key, callee, /* more results */ convKey, iv) _Authenticate: ; struct ShortSTRING *caller; ; struct EncryptionKey *key; ; struct ShortSTRING *callee; ; struct EncryptionKey *convKey; ; struct IV *iv; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; int nBlks, authLength; ; int nonceId[2]; ; int args[5]; ; struct Authenticator *authenticator; ; struct Authentication *authentication; ; struct EncryptionKey kx; ; struct ShortSTRING *b; ; int nonceOK; ADD SP,0FFDEX ; ReadCalendar(nonceId); ;&_nonceId LEA BX,[BP-12] CALL _ReadCalendar ; authentication = AgentAuthenticate(nonceId, caller, callee, &authenticator); ;&_nonceId LEA BX,[BP-12] PUSH BX ; BX _ _caller MOV BX,[BP+8] PUSH BX ;&_authenticator LEA BX,[BP-24] ; CX _ _callee MOV CX,[BP+4] CALL _AgentAuthenticate ADD SP,4 ; _authentication _ BX MOV [BP-26],BX ; if (authentication==0) SIGNAL(AuthenticateFailed, badCommunications); /* MORE analysis! */ ; BX _ _authentication MOV BX,[BP-26] OR BX,BX JNZ X2 MOV BX,1 MOV CX,_AuthenticateFailed CALL _SIGNAL X2: ; nBlks = DESBlocks(authentication->length); ; DI _ _authentication MOV DI,[BP-26] MOV BX,[DI] CALL _DESBlocks ; _nBlks _ BX MOV [BP-6],BX ; DecryptBlock(ka, &authentication->kx, &kx); MOV BX,_ka PUSH BX ; BX _ _authentication MOV BX,[BP-26] INC BX INC BX PUSH BX ;&_kx LEA BX,[BP-34] POP CX CALL _DecryptBlock POP DX ; CBCCheckDecrypt(&kx, nBlks-2, &authentication->ck, &authentication->ck, nullSeed); ;&_kx LEA BX,[BP-34] PUSH BX ; BX _ _nBlks MOV BX,[BP-6] DEC BX DEC BX PUSH BX ; BX _ _authentication MOV BX,[BP-26] ADD BX,012X PUSH BX ; BX _ _authentication MOV BX,[BP-26] ADD BX,012X PUSH BX LEA BX,_nullSeedB POP CX CALL _CBCCheckDecrypt ADD SP,6 ; nonceOK = (nonceId[0] == swab(authentication->nonceId[0]) && ; nonceId[1] == swab(authentication->nonceId[1])); ; BX _ _authentication MOV BX,[BP-26] ADD BX,022X MOV CX,[BX] MOV BX,CX CALL _swab ; CX _ _nonceId MOV CX,[BP-12] CMP CX,BX JNZ X3 ; BX _ _authentication MOV BX,[BP-26] ADD BX,022X MOV CX,[BX+2] MOV BX,CX CALL _swab ; CX _ _nonceId+2 MOV CX,[BP-10] CMP CX,BX X3: JNZ X4 MOV BX,1 JR X5 X4: XOR BX,BX X5: ; _nonceOK _ BX POP DX PUSH BX ; b = ShallString(0, &authentication->b.length, 2); XOR BX,BX PUSH BX ; BX _ _authentication MOV BX,[BP-26] ADD BX,026X PUSH BX MOV BX,2 POP CX CALL _ShallString POP DX ; _b _ BX MOV [BP-36],BX ; if ((!nonceOK) || !EquivalentStrings(callee, b)) SIGNAL(AuthenticateFailed, badKey); ; BX _ _nonceOK POP BX PUSH BX OR BX,BX JZ X8 ; BX _ _b MOV BX,[BP-36] ; CX _ _callee MOV CX,[BP+4] CALL _EquivalentStrings OR BX,BX X8: X7: JNZ X6 MOV BX,3 MOV CX,_AuthenticateFailed CALL _SIGNAL X6: ; DecryptBlock(ka, &authentication->ck, convKey); MOV BX,_ka PUSH BX ; BX _ _authentication MOV BX,[BP-26] ADD BX,012X PUSH BX ; BX _ _convKey MOV BX,[BP-2] POP CX CALL _DecryptBlock POP DX ; nBlks = DESBlocks(authenticator->length); ; DI _ _authenticator MOV DI,[BP-24] MOV BX,[DI] CALL _DESBlocks ; _nBlks _ BX MOV [BP-6],BX ; CBCCheckDecrypt(&kx, nBlks, &authenticator->ky, &authenticator->ky, nullSeed); ;&_kx LEA BX,[BP-34] PUSH BX ; BX _ _nBlks MOV BX,[BP-6] PUSH BX ; BX _ _authenticator MOV BX,[BP-24] INC BX INC BX PUSH BX ; BX _ _authenticator MOV BX,[BP-24] INC BX INC BX PUSH BX LEA BX,_nullSeedB POP CX CALL _CBCCheckDecrypt ADD SP,6 ; GetRandomIV(iv); ; BX _ _iv MOV BX,[BP-4] CALL _GetRandomIV ; return (authenticator); ; BX _ _authenticator MOV BX,[BP-24] MOV SP,BP POP BP RET; ; }; ; static struct Conversation ; *AddConversation(id, level, iv, originator, responder, convKey, auth) _AddConversation: ; struct ConversationID *id; ; int /* SecurityLevel */ level; ; struct IV *iv; ; struct ShortSTRING *originator; ; struct ShortSTRING *responder; ; struct EncryptionKey *convKey; ; struct Authenticator *auth; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; struct Conversation *conversation, *dataPtr; ADD SP,0FFFCX ; dataPtr = (struct Conversation *) &conversations[swab(id->count.LS) & 127]; ; BX _ _id MOV BX,[BP+12] MOV CX,[BX+2] MOV BX,CX CALL _swab AND BX,07FX MOV CX,_conversations SAL BX ADD BX,CX ; _dataPtr _ BX POP DX PUSH BX ; while (conversation=dataPtr->next) { X9: ; DI _ _dataPtr POP DI PUSH DI MOV BX,[DI] ; _conversation _ BX MOV [BP-6],BX OR BX,BX JZ X10 ; if (MultEq(&conversation->id, id, lenConversationID)) return conversation; ; BX _ _conversation MOV BX,[BP-6] INC BX INC BX PUSH BX MOV BX,3 ; CX _ _id MOV CX,[BP+12] CALL _MultEq POP DX OR BX,BX JZ X11 ; BX _ _conversation MOV BX,[BP-6] MOV SP,BP POP BP RET; X11: ; dataPtr = conversation; ; BX _ _conversation MOV BX,[BP-6] ; _dataPtr _ BX POP DX PUSH BX ; }; JR X9 X10: ; conversation = (struct Conversation *) GetFixed(lenConversationObject); MOV BX,010X CALL _GetFixed ; _conversation _ BX MOV [BP-6],BX ; MoveBlock(&conversation->id, id, lenConversationID); ; BX _ _conversation MOV BX,[BP-6] INC BX INC BX PUSH BX MOV BX,3 ; CX _ _id MOV CX,[BP+12] CALL _MoveBlock POP DX ; conversation->level = level; ; BX _ _conversation MOV BX,[BP-6] ; CX _ _level MOV CX,[BP+10] MOV [BX+8],CX ; MoveBlock(&conversation->key, convKey, lenEncryptionKey); ; BX _ _conversation MOV BX,[BP-6] ADD BX,0AX PUSH BX MOV BX,4 ; CX _ _convKey MOV CX,[BP-2] CALL _MoveBlock POP DX ; MoveBlock(&conversation->iv, iv, lenIV); ; BX _ _conversation MOV BX,[BP-6] ADD BX,012X PUSH BX MOV BX,4 ; CX _ _iv MOV CX,[BP+8] CALL _MoveBlock POP DX ; conversation->originator = ShallString(0, originator, 0); ; BX _ _conversation MOV BX,[BP-6] PUSH BX XOR BX,BX PUSH BX XOR BX,BX ; CX _ _originator MOV CX,[BP+6] CALL _ShallString POP DX MOV CX,BX POP BX MOV [BX+26],CX ; conversation->responder = ShallString(0, responder, 0); ; BX _ _conversation MOV BX,[BP-6] PUSH BX XOR BX,BX PUSH BX XOR BX,BX ; CX _ _responder MOV CX,[BP+4] CALL _ShallString POP DX MOV CX,BX POP BX MOV [BX+28],CX ; conversation->authenticator = auth; /* Assume I can keep it. */ ; BX _ _conversation MOV BX,[BP-6] ; CX _ _auth MOV CX,[BP-4] MOV [BX+30],CX ; dataPtr->next = conversation; ; BX _ _dataPtr POP BX PUSH BX ; CX _ _conversation MOV CX,[BP-6] MOV [BX],CX ; Block(); CALL _Block ; return (conversation); ; BX _ _conversation MOV BX,[BP-6] MOV SP,BP POP BP RET; ; }; ; EndConversation(conversation) _EndConversation: ; struct Conversation *conversation; PUSH BP MOV BP,SP PUSH BX ; { ; struct Conversation *dataPtr; ; struct Conversation *this; ADD SP,0FFFCX ; dataPtr = (struct Conversation *) &conversations[swab(conversation->id.count.LS) & 127]; ; BX _ _conversation MOV BX,[BP-2] MOV CX,[BX+4] MOV BX,CX CALL _swab AND BX,07FX MOV CX,_conversations SAL BX ADD BX,CX ; _dataPtr _ BX MOV [BP-4],BX ; this = dataPtr->next; ; DI _ _dataPtr MOV DI,[BP-4] MOV BX,[DI] ; _this _ BX POP DX PUSH BX ; if (conversation->id.originator.w == myHost.w) ; BX _ _conversation MOV BX,[BP-2] MOV CX,[BX+2] MOV BX,WORD PTR _myHost CMP CX,BX JNZ X12 ; while (this) { X13: ; BX _ _this POP BX PUSH BX OR BX,BX JZ X14 ; if (this == conversation) { ; BX _ _conversation MOV BX,[BP-2] ; CX _ _this POP CX PUSH CX CMP CX,BX JNZ X15 ; dataPtr->next = this->next; ; DI _ _this POP DI PUSH DI MOV BX,[DI] MOV CX,BX ; BX _ _dataPtr MOV BX,[BP-4] MOV [BX],CX ; Block(); CALL _Block ; return; MOV SP,BP POP BP RET; ; }; X15: ; dataPtr = this; this=this->next; ; BX _ _this POP BX PUSH BX ; _dataPtr _ BX MOV [BP-4],BX ; DI _ _this POP DI PUSH DI MOV BX,[DI] ; _this _ BX POP DX PUSH BX ; }; JR X13 X14: X12: ; SIGNAL(UnknownConversation); MOV BX,_UnknownConversation CALL _SIGNAL ; }; MOV SP,BP POP BP RET; ; InvalidateConversations() _InvalidateConversations: PUSH BP MOV BP,SP ; { ; int i; ; struct Conversation *conv; ; for (i=0; i<128; ++i) { ADD SP,0FFFCX MOV WORD PTR [BP-2],0 X18: ; BX _ _i MOV BX,[BP-2] CMP BX,080X JGE X17 JR X16 X19: INC WORD PTR [BP-2] JR X18 X16: ; conv = conversations[i]; ; BX _ _i MOV BX,[BP-2] MOV CX,_conversations SAL BX ADD BX,CX MOV CX,[BX] ; _conv _ CX POP DX PUSH CX ; while (conv) { X20: ; BX _ _conv POP BX PUSH BX OR BX,BX JZ X21 ; if (conv->id.originator.w == myHost.w) conv->id.originator.w = 0; ; BX _ _conv POP BX PUSH BX MOV CX,[BX+2] MOV BX,WORD PTR _myHost CMP CX,BX JNZ X22 ; BX _ _conv POP BX PUSH BX MOV WORD PTR [BX+2],0 X22: ; conv = conv->next; ; DI _ _conv POP DI PUSH DI MOV BX,[DI] ; _conv _ BX POP DX PUSH BX ; }; JR X20 X21: ; }; JR X19 X17: ; }; MOV SP,BP POP BP RET; ; AttachConversation(handle, conversation) _AttachConversation: ; struct ImportInstance *handle; ; struct Conversation *conversation; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; handle->currentConversation = conversation; ; BX _ _handle MOV BX,[BP-2] ; CX _ _conversation POP CX PUSH CX MOV [BX+2],CX ; }; MOV SP,BP POP BP RET; ; struct ConversationID ; *GetConversationID(conversation) _GetConversationID: ; struct Conversation *conversation; PUSH BP MOV BP,SP PUSH BX ; { ; return((conversation)? &conversation->id: 0); ; BX _ _conversation POP BX PUSH BX OR BX,BX JZ X23 ; BX _ _conversation POP BX PUSH BX INC BX INC BX JR X24 X23: XOR BX,BX X24: MOV SP,BP POP BP RET; ; }; ; struct ShortSTRING ; *GetCaller(conversation) _GetCaller: ; struct Conversation *conversation; PUSH BP MOV BP,SP PUSH BX ; { ; return((conversation)? conversation->originator: 0); ; BX _ _conversation POP BX PUSH BX OR BX,BX JZ X25 ; BX _ _conversation POP BX PUSH BX MOV CX,[BX+26] JR X26 X25: XOR CX,CX X26: MOV BX,CX MOV SP,BP POP BP RET; ; }; ; int /* SecurityLevel */ ; *GetLevel(conversation) _GetLevel: ; struct Conversation *conversation; PUSH BP MOV BP,SP PUSH BX ; { ; return((conversation)? conversation->level: slNone); ; BX _ _conversation POP BX PUSH BX OR BX,BX JZ X27 ; BX _ _conversation POP BX PUSH BX MOV CX,[BX+8] JR X28 X27: XOR CX,CX X28: MOV BX,CX MOV SP,BP POP BP RET; ; }; ; int /* DataLength */ ; EncryptPkt(pkt, ln) _EncryptPkt: ; struct PBI *pkt; ; int ln; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; struct Header *header; ; struct Conversation *conv; ; int words, nBlks, *checkPtr; ; struct Block blocks[]; ADD SP,0FFF4X ; header = pkt->pup; ; BX _ _pkt MOV BX,[BP-2] MOV CX,[BX+6] ; _header _ CX MOV [BP-6],CX ; conv = pkt->convHandle; ; BX _ _pkt MOV BX,[BP-2] MOV CX,[BX+4] ; _conv _ CX MOV [BP-8],CX ; if ((conv != 0) && (conv->level != slNone) && (conv->level != slAuthOnly)) { ; BX _ _conv MOV BX,[BP-8] OR BX,BX JZ X30 ; BX _ _conv MOV BX,[BP-8] MOV CX,[BX+8] OR CX,CX JZ X31 ; BX _ _conv MOV BX,[BP-8] MOV CX,[BX+8] MOV BX,CX CMP BX,0100X X31: X30: JZ X29 ; words = ln /* stub data words */ + encryptedHeaderLength + 2 /* SIZE[Check] */; ; BX _ _ln MOV BX,[BP-4] ADD BX,0AX ; _words _ BX MOV [BP-10],BX ; nBlks = (words + encryptionBlockSize - 1)/encryptionBlockSize; ; BX _ _words MOV BX,[BP-10] ADD BX,3 SAR BX SAR BX ; _nBlks _ BX MOV [BP-12],BX ; blocks = (struct Block *) &header->pktID; ; BX _ _header MOV BX,[BP-6] ADD BX,018X ; _blocks _ BX POP DX PUSH BX ; checkPtr = ((int *) (&blocks[nBlks])) - lenCheck; ; BX _ _nBlks MOV BX,[BP-12] ; CX _ _blocks POP CX PUSH CX SAL BX SAL BX SAL BX ADD BX,CX ADD BX,0FFFCX ; _checkPtr _ BX MOV [BP-14],BX ; checkPtr[0] = swab(nBlks*encryptionBlockSize-words); /* Roundoff adj? */ ; BX _ _nBlks MOV BX,[BP-12] SAL BX SAL BX ; CX _ _words MOV CX,[BP-10] SUB BX,CX CALL _swab MOV CX,BX ; BX _ _checkPtr MOV BX,[BP-14] MOV [BX],CX ; checkPtr[1] = 0; ; BX _ _checkPtr MOV BX,[BP-14] MOV WORD PTR [BX+2],0 ; CryptData(&conv->key, nBlks, blocks, 0, dirEncrypt, conv->level, &conv->iv); ; BX _ _conv MOV BX,[BP-8] ADD BX,0AX PUSH BX ; BX _ _nBlks MOV BX,[BP-12] PUSH BX ; BX _ _blocks MOV BX,[BP-16] PUSH BX XOR BX,BX PUSH BX MOV BX,1 PUSH BX ; BX _ _conv MOV BX,[BP-8] MOV CX,[BX+8] ; BX _ _conv MOV BX,[BP-8] ADD BX,012X CALL _CryptData JR $+5 X29: JMP X32 ADD SP,0AX ; return (((nBlks*encryptionBlockSize) - encryptedHeaderLength) + pktLengthOverhead); ; BX _ _nBlks MOV BX,[BP-12] SAL BX SAL BX ADD BX,0FFF8X ADD BX,015X MOV SP,BP POP BP RET; ; }; X32: ; return (ln+pktLengthOverhead); ; BX _ _ln MOV BX,[BP-4] ADD BX,015X MOV SP,BP POP BP RET; ; }; ; int /* BOOL */ ; DecryptPkt(header, convHandle, /* results */ lvL) _DecryptPkt: ; struct Header *header; ; struct Conversation *convHandle; ; int *lvL; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; int /*BOOL*/ ok, pktLen; ; int nBlks, *checkPtr, cp; ; struct Block blocks[]; ADD SP,0FFF4X ; ok=true; MOV WORD PTR [BP-6],0FFFFX ; pktLen = (swab(header->length)>>1) - pktLengthOverhead; ; DI _ _header MOV DI,[BP+4] MOV BX,[DI] CALL _swab SHR BX ADD BX,0FFEBX ; _pktLen _ BX MOV [BP-8],BX ; if (convHandle != 0 && convHandle->level != slNone && convHandle->level != slAuthOnly) { ; BX _ _convHandle MOV BX,[BP-2] OR BX,BX JZ X34 ; BX _ _convHandle MOV BX,[BP-2] MOV CX,[BX+8] OR CX,CX JZ X35 ; BX _ _convHandle MOV BX,[BP-2] MOV CX,[BX+8] MOV BX,CX CMP BX,0100X X35: X34: JZ X33 ; nBlks = (pktLen + encryptedHeaderLength)/encryptionBlockSize; ; BX _ _pktLen MOV BX,[BP-8] ADD BX,8 SAR BX SAR BX ; _nBlks _ BX MOV [BP-10],BX ; blocks = (struct Block *) &header->pktID; ; BX _ _header MOV BX,[BP+4] ADD BX,018X ; _blocks _ BX POP DX PUSH BX ; checkPtr = ((int *) (&blocks[nBlks])) - lenCheck; ; BX _ _nBlks MOV BX,[BP-10] ; CX _ _blocks POP CX PUSH CX SAL BX SAL BX SAL BX ADD BX,CX ADD BX,0FFFCX ; _checkPtr _ BX MOV [BP-12],BX ; CryptData(&convHandle->key, nBlks, blocks, 0, dirDecrypt, ; convHandle->level, &convHandle->iv); ; BX _ _convHandle MOV BX,[BP-2] ADD BX,0AX PUSH BX ; BX _ _nBlks MOV BX,[BP-10] PUSH BX ; BX _ _blocks MOV BX,[BP-16] PUSH BX XOR BX,BX PUSH BX XOR BX,BX PUSH BX ; BX _ _convHandle MOV BX,[BP-2] MOV CX,[BX+8] ; BX _ _convHandle MOV BX,[BP-2] ADD BX,012X CALL _CryptData ADD SP,0AX ; cp = swab(checkPtr[0]); ; DI _ _checkPtr MOV DI,[BP-12] MOV BX,[DI] CALL _swab ; _cp _ BX MOV [BP-14],BX ; if (0 > cp || cp >= encryptionBlockSize) ok = false; ; BX _ _cp MOV BX,[BP-14] XOR CX,CX CMP CX,BX JG X38 ; BX _ _cp MOV BX,[BP-14] CMP BX,4 JL X37 X38: MOV AL,1 JR X39 X37: XOR AL,AL X39: OR AL,AL JR $+5 X33: JMP X40 JZ X36 MOV WORD PTR [BP-6],0 ; else *lvL = (((nBlks*encryptionBlockSize) - cp) - lenCheck) - encryptedHeaderLength; JR X41 X36: ; BX _ _nBlks MOV BX,[BP-10] SAL BX SAL BX ; CX _ _cp MOV CX,[BP-14] SUB BX,CX DEC BX DEC BX ADD BX,0FFF8X MOV CX,BX ; BX _ _lvL MOV BX,[BP-4] MOV [BX],CX X41: ; }; ; else *lvL = pktLen; JR X42 X40: ; BX _ _lvL MOV BX,[BP-4] ; CX _ _pktLen MOV CX,[BP-8] MOV [BX],CX X42: ; return (ok); ; BX _ _ok MOV BX,[BP-6] MOV SP,BP POP BP RET; ; }; ; static int Rlse(sig,code,sel) _Rlse: ; int sig, code; ; struct Seal1 *sel; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; ReleasePBI(sel->data[0]); ; BX _ _sel POP BX PUSH BX ADD BX,4 MOV CX,[BX] MOV BX,CX CALL _ReleasePBI ; return (sig); ; BX _ _sig MOV BX,[BP+4] MOV SP,BP POP BP RET; ; }; ; int /* ok: BOOLEAN */ ; GetConnectionState(decrypted, callPkt, /* more results */ id, callCt, lvConv, lvNewLength) _GetConnectionState: ; int /*BOOL*/ decrypted; ; struct PBI *callPkt; ; struct ConversationID *id; ; struct CallCount *callCt; ; struct Conversation *lvConv[]; ; int *lvNewLength; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; struct PBI *rfaPkt; ; struct Seal1 sel; ; word myNonceID[2]; ; struct Header *callHeader; ; struct Header *rfaHeader; ; struct RFARequest *request; ; struct RFAResponse *response; ; int responseLength; ; struct ConversationID convID; ; int ok; ; struct EncryptionKey *ky, *ck; ADD SP,0FFDEX ; callHeader = callPkt->pup; ; BX _ _callPkt MOV BX,[BP+8] MOV CX,[BX+6] ; _callHeader _ CX MOV [BP-18],CX ; rfaPkt = GetPBI(mySoc); MOV BX,_mySoc CALL _GetPBI ; _rfaPkt _ BX MOV [BP-6],BX ; sel.data[0] = (int) rfaPkt; ; BX _ _rfaPkt MOV BX,[BP-6] ; _sel+4 _ BX MOV [BP-8],BX ; ENABLE(UNWIND, &Rlse, &sel); MOV BX,1 PUSH BX ;&_sel LEA BX,[BP-12] MOV CX,OFFSET _Rlse CALL _ENABLE POP DX ; Timer(myNonceID); ;&_myNonceID LEA BX,[BP-16] CALL _Timer ; rfaHeader = rfaPkt->pup; ; BX _ _rfaPkt MOV BX,[BP-6] MOV CX,[BX+6] ; _rfaHeader _ CX MOV [BP-20],CX ; request = (struct RFARequest *) &rfaHeader->callData; ; BX _ _rfaHeader MOV BX,[BP-20] ADD BX,028X ; _request _ BX MOV [BP-22],BX ; response = (struct RFAResponse *) request; ; BX _ _request MOV BX,[BP-22] ; _response _ BX MOV [BP-24],BX ; MoveBlock(&request->callerConv, ; &callHeader->conv, lenPktConversationID+lenPktID); /* PktID still encrypted */ ; BX _ _request MOV BX,[BP-22] PUSH BX ; BX _ _callHeader MOV BX,[BP-18] ADD BX,014X PUSH BX MOV BX,6 POP CX CALL _MoveBlock POP DX ; Move2(&request->nonceID[0], myNonceID); ; BX _ _request MOV BX,[BP-22] ADD BX,0CX PUSH BX ;&_myNonceID LEA BX,[BP-16] POP CX CALL _Move2 ; rfaPkt->convHandle = unencrypted; ; BX _ _rfaPkt MOV BX,[BP-6] MOV WORD PTR [BX+4],0 ; MoveBlock(rfaHeader, callHeader, lenHeader); ; BX _ _rfaHeader MOV BX,[BP-20] PUSH BX MOV BX,014X ; CX _ _callHeader MOV CX,[BP-18] CALL _MoveBlock POP DX ; SetupResponse(rfaHeader); ; BX _ _rfaHeader MOV BX,[BP-20] CALL _SetupResponse ; Move2(&rfaHeader->conv, firstConversation); ; BX _ _rfaHeader MOV BX,[BP-20] ADD BX,014X PUSH BX MOV BX,_firstConversation POP CX CALL _Move2 ; rfaHeader->pktID.activity = 0; ; BX _ _rfaHeader MOV BX,[BP-20] MOV WORD PTR [BX+24],0 ; rfaHeader->pktID.pktSeq = 0; ; BX _ _rfaHeader MOV BX,[BP-20] MOV WORD PTR [BX+30],0 ; responseLength = PktExchange(rfaPkt, lenRFARequest, rfaDataLength, authReq); ; BX _ _rfaPkt MOV BX,[BP-6] PUSH BX MOV BX,8 PUSH BX MOV BX,4 MOV CX,060X CALL _PktExchange ADD SP,4 ; _responseLength _ BX MOV [BP-26],BX ; if (responseLength < lenRFAResponse-lenAuthenticator) return (false); ; BX _ _responseLength MOV BX,[BP-26] CMP BX,0DX JGE X43 XOR BX,BX MOV SP,BP POP BP RET; X43: ; ok = true; MOV WORD PTR [BP-34],0FFFFX ; if (response->level == slNone) { ; BX _ _response MOV BX,[BP-24] MOV CX,[BX+24] OR CX,CX JNZ X44 ; *lvNewLength = (swab(callHeader->length)>>1) - pktLengthOverhead; *lvConv = 0; }; ; DI _ _callHeader MOV DI,[BP-18] MOV BX,[DI] CALL _swab SHR BX ADD BX,0FFEBX MOV CX,BX ; BX _ _lvNewLength MOV BX,[BP-4] MOV [BX],CX ; BX _ _lvConv MOV BX,[BP-2] MOV WORD PTR [BX],0 ; else { /* response = {IV, conn, call, nonce}CK,,{KY}KB,{{CK}KB, time, A}KY */ JR X45 X44: ; ky = &response->authenticator.ky; ; BX _ _response MOV BX,[BP-24] ADD BX,01CX ; _ky _ BX MOV [BP-36],BX ; ck = &response->authenticator.ck; ; BX _ _response MOV BX,[BP-24] ADD BX,02CX ; _ck _ BX POP DX PUSH BX ; DecryptBlock(kb, ky, 0); MOV BX,_kb PUSH BX XOR BX,BX ; CX _ _ky MOV CX,[BP-36] CALL _DecryptBlock POP DX ; CBCCheckDecrypt(ky, ; (swab(response->authenticator.length)/encryptionBlockSize)-2, ck, 0, nullSeed); ; BX _ _ky MOV BX,[BP-36] PUSH BX ; BX _ _response MOV BX,[BP-24] MOV CX,[BX+26] MOV BX,CX CALL _swab SAR BX SAR BX DEC BX DEC BX PUSH BX ; BX _ _ck MOV BX,[BP-38] PUSH BX LEA BX,_nullSeedB XOR CX,CX CALL _CBCCheckDecrypt ADD SP,6 ; DecryptBlock(kb, ck, 0); MOV BX,_kb PUSH BX XOR BX,BX ; CX _ _ck MOV CX,[BP-38] CALL _DecryptBlock POP DX ; CBCCheckDecrypt(ck, responseCKBlocks, response, 0, nullSeed); ; BX _ _ck POP BX PUSH BX PUSH BX MOV BX,3 PUSH BX ; BX _ _response MOV BX,[BP-24] PUSH BX LEA BX,_nullSeedB XOR CX,CX CALL _CBCCheckDecrypt ADD SP,6 ; Move2(&convID.count, &response->connection.conv); ; BX _ _response MOV BX,[BP-24] ADD BX,8 ;&_convID LEA CX,[BP-30] CALL _Move2 ; convID.count.fields &= notCalleeMask; JR $+5 X45: JMP X46 AND WORD PTR [BP-28],0FF7FX ; convID.originator = ; ((response->connection.conv.fields&originatorField) != callerField)? myHost.w ; :response->connection.caller.w; ; BX _ _response MOV BX,[BP-24] MOV CX,[BX+10] MOV BX,CX AND BX,080X PUSH BX POP BX OR BX,BX JZ X47 MOV BX,WORD PTR _myHost JR X48 X47: ; BX _ _response MOV BX,[BP-24] MOV CX,[BX+12] MOV BX,CX X48: ; _convID _ BX MOV [BP-32],BX ; response->authenticator.a.length = swab(response->authenticator.a.length); ; BX _ _response MOV BX,[BP-24] PUSH BX ; BX _ _response MOV BX,[BP-24] MOV CX,[BX+64] MOV BX,CX CALL _swab MOV CX,BX POP BX MOV [BX+64],CX ; *lvConv = AddConversation( /* Construct a ConversationID from a PktConversationID */ ; &convID, response->level, &response->iv, &response->authenticator.a, 0, ; &response->authenticator.ck, 0); ;&_convID LEA BX,[BP-32] PUSH BX ; BX _ _response MOV BX,[BP-24] MOV CX,[BX+24] PUSH CX ; BX _ _response MOV BX,[BP-24] PUSH BX ; BX _ _response MOV BX,[BP-24] ADD BX,040X PUSH BX XOR BX,BX PUSH BX ; BX _ _response MOV BX,[BP-24] ADD BX,02CX PUSH BX XOR BX,BX POP CX CALL _AddConversation ADD SP,0AX MOV CX,BX ; BX _ _lvConv MOV BX,[BP-2] MOV [BX],CX ; callPkt->convHandle = *lvConv; ; BX _ _callPkt MOV BX,[BP+8] ; DI _ _lvConv MOV DI,[BP-2] MOV CX,[DI] MOV [BX+4],CX ; if (decrypted==false && DecryptPkt(callHeader, *lvConv, lvNewLength)==false) ok=false; ; BX _ _decrypted MOV BX,[BP+10] OR BX,BX JNZ X50 ; BX _ _callHeader MOV BX,[BP-18] PUSH BX ; DI _ _lvConv MOV DI,[BP-2] MOV BX,[DI] PUSH BX ; BX _ _lvNewLength MOV BX,[BP-4] POP CX CALL _DecryptPkt POP DX OR BX,BX X50: JNZ X49 MOV WORD PTR [BP-34],0 X49: ; } X46: ; if (ok) if (DoubleComp(&response->nonceID[0], myNonceID) != 1) ok=false; ; BX _ _ok MOV BX,[BP-34] OR BX,BX JZ X51 ; BX _ _response MOV BX,[BP-24] ADD BX,014X PUSH BX ;&_myNonceID LEA BX,[BP-16] POP CX CALL _DoubleComp CMP BX,1 JZ X52 MOV WORD PTR [BP-34],0 ; else if (DoubleEq(&response->connection.conv, &callHeader->conv)==false) ok=false; JR X53 X52: ; BX _ _response MOV BX,[BP-24] ADD BX,8 ; CX _ _callHeader MOV CX,[BP-18] ADD CX,014X XCHG BX,CX CALL _DoubleEq OR BX,BX JNZ X54 MOV WORD PTR [BP-34],0 ; else if (response->connection.caller != callHeader->srceHost) ok=false; JR X55 X54: ; BX _ _response MOV BX,[BP-24] MOV CX,[BX+12] ; BX _ _callHeader MOV BX,[BP-18] MOV AX,[BX+14] CMP CX,AX JZ X56 MOV WORD PTR [BP-34],0 ; else if (response->connection.activity != callHeader->pktID.activity) ok=false; JR X57 X56: ; BX _ _response MOV BX,[BP-24] MOV CX,[BX+14] ; BX _ _callHeader MOV BX,[BP-18] MOV AX,[BX+24] CMP CX,AX JZ X58 MOV WORD PTR [BP-34],0 ; else if (DoubleEq(&response->callCt, &callHeader->pktID.callCt) == false) ok=false; JR X59 X58: ; BX _ _response MOV BX,[BP-24] ADD BX,010X ; CX _ _callHeader MOV CX,[BP-18] ADD CX,01AX XCHG BX,CX CALL _DoubleEq JR $+5 X51: JMP X61 OR BX,BX JNZ X60 MOV WORD PTR [BP-34],0 X60: X59: X57: X55: X53: X61: ; if (ok) { MoveBlock(id, &response->connection, lenConnectionID); ; BX _ _ok MOV BX,[BP-34] OR BX,BX JZ X62 ; BX _ _id MOV BX,[BP+6] PUSH BX ; BX _ _response MOV BX,[BP-24] ADD BX,8 PUSH BX MOV BX,4 POP CX CALL _MoveBlock POP DX ; Move2(callCt, &response->callCt); }; ; BX _ _response MOV BX,[BP-24] ADD BX,010X ; CX _ _callCt MOV CX,[BP+4] CALL _Move2 X62: ; Block(); CALL _Block ; return (Rlse(ok, 0, &sel)); ; BX _ _ok MOV BX,[BP-34] PUSH BX ;&_sel LEA BX,[BP-12] XOR CX,CX CALL _Rlse POP DX MOV SP,BP POP BP RET; ; }; ; int /*BOOLEAN*/ ; ReplyToRFA(recvdPkt, callHeader/*encrypted*/, callPktID /* clear */, convHandle) _ReplyToRFA: ; struct PBI *recvdPkt; ; struct Header *callHeader; ; struct PktID *callPktID; ; struct Conversation *convHandle; PUSH BP MOV BP,SP PUSH CX PUSH BX ; { ; struct Header *recvdHeader; ; struct RFARequest request; ; struct RFAResponse *response; ; int used; ; int authLen; ; struct Authenticator *auth; ; int *resp; ADD SP,0FFE4X ; recvdHeader = recvdPkt->pup; ; BX _ _recvdPkt MOV BX,[BP+6] MOV CX,[BX+6] ; _recvdHeader _ CX MOV [BP-6],CX ; response = (struct RFAResponse *) &recvdHeader->callData; ; BX _ _recvdHeader MOV BX,[BP-6] ADD BX,028X ; _response _ BX MOV [BP-24],BX ; MoveBlock(&request, response, lenRFARequest); ;&_request LEA BX,[BP-22] PUSH BX MOV BX,8 ; CX _ _response MOV CX,[BP-24] CALL _MoveBlock POP DX ; used = lenRFAResponse-lenAuthenticator; MOV WORD PTR [BP-26],0DX ; if (MultEq(&request.callerConv, ; &callHeader->conv, lenPktConversationID+lenPktID) == 0) { ;&_request LEA BX,[BP-22] PUSH BX ; BX _ _callHeader MOV BX,[BP+4] ADD BX,014X PUSH BX MOV BX,6 POP CX CALL _MultEq POP DX OR BX,BX JNZ X63 ; ReleasePBI(recvdPkt); ; BX _ _recvdPkt MOV BX,[BP+6] CALL _ReleasePBI ; return (false); XOR BX,BX MOV SP,BP POP BP RET; ; }; X63: ; Move2(&response->connection.conv, &callHeader->conv); ; BX _ _response MOV BX,[BP-24] ADD BX,8 ; CX _ _callHeader MOV CX,[BP+4] ADD CX,014X XCHG BX,CX CALL _Move2 ; response->connection.caller = callHeader->srceHost; ; BX _ _response MOV BX,[BP-24] ; CX _ _callHeader MOV CX,[BP+4] MOV DI,CX MOV CX,[DI+14] MOV [BX+12],CX ; response->connection.activity = callPktID->activity; ; BX _ _response MOV BX,[BP-24] ; DI _ _callPktID MOV DI,[BP-2] MOV CX,[DI] MOV [BX+14],CX ; Move2(&response->callCt, &callPktID->callCt); ; BX _ _response MOV BX,[BP-24] ADD BX,010X ; CX _ _callPktID MOV CX,[BP-2] INC CX INC CX XCHG BX,CX CALL _Move2 ; Move2(&response->nonceID[0], &request.nonceID[0]); ; BX _ _response MOV BX,[BP-24] ADD BX,014X PUSH BX ;&_request LEA BX,[BP-10] POP CX CALL _Move2 ; DoubleInc(&response->nonceID[0], 1); ; BX _ _response MOV BX,[BP-24] ADD BX,014X PUSH BX MOV BX,1 POP CX CALL _DoubleInc ; if (DoubleEq(&callHeader->conv, firstConversation)) { ; BX _ _callHeader MOV BX,[BP+4] ADD BX,014X PUSH BX MOV BX,_firstConversation POP CX CALL _DoubleEq OR BX,BX JZ X64 ; response->level = slNone; ; BX _ _response MOV BX,[BP-24] MOV WORD PTR [BX+24],0 ; ++used; INC WORD PTR [BP-26] ; }; ; else { JR X65 X64: ; if ((callHeader->conv.fields&originatorField) == calleeField) SIGNAL(ERROR); /* TEMP */ ; BX _ _callHeader MOV BX,[BP+4] MOV CX,[BX+22] MOV BX,CX AND BX,080X CMP BX,080X JNZ X66 MOV BX,2 CALL _SIGNAL X66: ; response->level = convHandle->level; ; BX _ _response MOV BX,[BP-24] ; CX _ _convHandle MOV CX,[BP-4] MOV DI,CX MOV CX,[DI+8] MOV [BX+24],CX ; MoveBlock(&response->iv, &convHandle->iv, lenIV); ; BX _ _response MOV BX,[BP-24] PUSH BX ; BX _ _convHandle MOV BX,[BP-4] ADD BX,012X PUSH BX MOV BX,4 POP CX CALL _MoveBlock POP DX ; CryptData(&convHandle->key, responseCKBlocks, ; response, 0, dirEncrypt, slCBCCheck, nullSeed); ; BX _ _convHandle MOV BX,[BP-4] ADD BX,0AX PUSH BX MOV BX,3 PUSH BX ; BX _ _response MOV BX,[BP-24] PUSH BX XOR BX,BX PUSH BX MOV BX,1 PUSH BX LEA BX,_nullSeedB MOV CX,0400X CALL _CryptData ADD SP,0AX ; auth = convHandle->authenticator; ; BX _ _convHandle MOV BX,[BP-4] MOV CX,[BX+30] ; _auth _ CX MOV [BP-30],CX ; authLen = auth->length+1; ; DI _ _auth MOV DI,[BP-30] MOV BX,[DI] INC BX ; _authLen _ BX MOV [BP-28],BX ; MoveBlock(&response->authenticator, auth, authLen); ; BX _ _response MOV BX,[BP-24] ADD BX,01AX PUSH BX ; BX _ _authLen JR $+5 X65: JMP X67 MOV BX,[BP-28] ; CX _ _auth MOV CX,[BP-30] CALL _MoveBlock POP DX ; response->authenticator.length = swab(auth->length); ; BX _ _response MOV BX,[BP-24] PUSH BX ; DI _ _auth MOV DI,[BP-30] MOV BX,[DI] CALL _swab MOV CX,BX POP BX MOV [BX+26],CX ; used += authLen; ; BX _ _authLen MOV BX,[BP-28] ADD [BP-26],BX ; resp = (int *) response; ; BX _ _response MOV BX,[BP-24] ; _resp _ BX POP DX PUSH BX ; ShallString(&resp[used], convHandle->originator, 1); ; BX _ _used MOV BX,[BP-26] ; CX _ _resp POP CX PUSH CX SAL BX ADD BX,CX PUSH BX ; BX _ _convHandle MOV BX,[BP-4] MOV CX,[BX+26] MOV BX,1 CALL _ShallString POP DX ; used += StringSize(convHandle->originator); ; BX _ _convHandle MOV BX,[BP-4] MOV CX,[BX+26] MOV BX,CX CALL _StringSize ADD [BP-26],BX ; }; X67: ; SetupResponse(recvdHeader); ; BX _ _recvdHeader MOV BX,[BP-6] CALL _SetupResponse ; recvdHeader->length = swab((pktLengthOverhead + used) << 1); ; BX _ _used MOV BX,[BP-26] ADD BX,015X SAL BX CALL _swab MOV CX,BX ; BX _ _recvdHeader MOV BX,[BP-6] MOV [BX],CX ; recvdHeader->type.fields = typeData; ; BX _ _recvdHeader MOV BX,[BP-6] MOV BYTE PTR [BX+3],061X ; recvdHeader->pktID.pktSeq += swapped1; ; BX _ _recvdHeader MOV BX,[BP-6] ADD WORD PTR [BX+30],0100X ; recvdHeader->srceHost.w = myHost.w; ; BX _ _recvdHeader MOV BX,[BP-6] MOV CX,WORD PTR _myHost MOV [BX+14],CX ; recvdHeader->srceSoc.LS = rpcSocket; ; BX _ _recvdHeader MOV BX,[BP-6] MOV BYTE PTR [BX+19],01EX ; recvdHeader->srcePSB = nullPSB; ; BX _ _recvdHeader MOV BX,[BP-6] MOV WORD PTR [BX+6],0 ; SendPup(recvdPkt); ; BX _ _recvdPkt MOV BX,[BP+6] CALL _SendPup ; Block(); CALL _Block ; return (true); MOV BX,0FFFFX MOV SP,BP POP BP RET; ; }; ; SecurityInitialize() { _SecurityInitialize: PUSH BP MOV BP,SP ; firstConversation = ; (struct PktConversationID *) GetFixed(lenPktConversationID); MOV BX,2 CALL _GetFixed MOV _firstConversation,BX ; ReadCalendar(firstConversation); MOV BX,_firstConversation CALL _ReadCalendar ; firstConversation->fields &= notCalleeMask; /* time unpredictable in 32 bits */ MOV BX,_firstConversation AND WORD PTR [BX+2],0FF7FX ; lastConversation = ; (struct ConversationID *) GetFixed(lenConversationID); MOV BX,3 CALL _GetFixed MOV _lastConversation,BX ; lastConversation->originator.w = myHost.w; MOV BX,_lastConversation MOV CX,WORD PTR _myHost MOV [BX],CX ; Move2(&lastConversation->count, firstConversation); MOV BX,_lastConversation INC BX INC BX PUSH BX MOV BX,_firstConversation POP CX CALL _Move2 ; conversations = (struct Conversation **) GetFixed(128); MOV BX,080X CALL _GetFixed MOV _conversations,BX ; UnknownConversation = CODE(); CALL _CODE MOV _UnknownConversation,BX ; AddConversation(lastConversation, slNone, nullSeed, 0, 0, nullKey, 0); MOV BX,_lastConversation PUSH BX XOR BX,BX PUSH BX LEA BX,_nullSeedB PUSH BX XOR BX,BX PUSH BX XOR BX,BX PUSH BX XOR BX,BX LEA CX,_nullKeyB CALL _AddConversation ADD SP,0AX ; kb = ka = &privateKey; LEA BX,_privateKey MOV _ka,BX MOV _kb,BX ; CorrectParity(ka); MOV BX,_ka CALL _CorrectParity ; }; MOV SP,BP POP BP RET; ; SecurityRestart() _SecurityRestart: PUSH BP MOV BP,SP ; { ; InvalidateConversations(); CALL _InvalidateConversations ; }; MOV SP,BP POP BP RET; ; Externals Declared Here PUBLIC _lastConversation PUBLIC _firstConversation PUBLIC _UnknownConversation PUBLIC _nullKeyB PUBLIC _nullSeedB PUBLIC _GenerateConversation PUBLIC _StartConversation PUBLIC _Authenticate PUBLIC _EndConversation PUBLIC _InvalidateConversations PUBLIC _AttachConversation PUBLIC _GetConversationID PUBLIC _GetCaller PUBLIC _GetLevel PUBLIC _EncryptPkt PUBLIC _DecryptPkt PUBLIC _GetConnectionState PUBLIC _ReplyToRFA PUBLIC _SecurityInitialize PUBLIC _SecurityRestart C_CODE ENDS ; Number of Bytes of Code = 0ACDX, (2765)