;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 <Env.h>

; 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)