;Alto->8086 small-c compiler rev 2.0
C←CODE SEGMENT
$INCLUDE(8086LIB.D)
$INCLUDE(DESSoft.DEC)
ASSUME CS:C←CODE, DS:C←DATA
; #include <Env.h>
; extern Block();
; extern Encrypt();
; extern MoveBlock();
; extern DoubleDifference();
; char parityTable[16];
; struct Words4 { int words[4]; };
; EncryptBlock(key, from, to) int *key; struct Words4 *from, *to; {
←EncryptBlock:
CALL StkChk
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX
; CryptData(key, 1, from, to, dirEncrypt, slECB, 0); };
; BX ← ←key
MOV BX,[BP+4]
PUSH BX
MOV BX,1
PUSH BX
; BX ← ←from
MOV BX,[BP-2]
PUSH BX
; BX ← ←to
MOV BX,[BP-4]
PUSH BX
MOV BX,1
PUSH BX
XOR BX,BX
MOV CX,0200X
CALL ←CryptData
ADD SP,0AX
MOV SP,BP
POP BP
RET;
; DecryptBlock(key, from, to) int *key; struct Words4 *from, *to; {
←DecryptBlock:
CALL StkChk
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX
; CryptData(key, 1, from, to, dirDecrypt, slECB, 0); };
; BX ← ←key
MOV BX,[BP+4]
PUSH BX
MOV BX,1
PUSH BX
; BX ← ←from
MOV BX,[BP-2]
PUSH BX
; BX ← ←to
MOV BX,[BP-4]
PUSH BX
XOR BX,BX
PUSH BX
XOR BX,BX
MOV CX,0200X
CALL ←CryptData
ADD SP,0AX
MOV SP,BP
POP BP
RET;
; CBCCheckDecrypt(key, nBlks, from, to, seed) int *key, nBlks;
←CBCCheckDecrypt:
; struct Words4 *from, *to, *seed; {
CALL StkChk
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX
; CryptData(key, nBlks, from, to, dirDecrypt, slCBCCheck, seed); };
; BX ← ←key
MOV BX,[BP+8]
PUSH BX
; BX ← ←nBlks
MOV BX,[BP+6]
PUSH BX
; BX ← ←from
MOV BX,[BP+4]
PUSH BX
; BX ← ←to
MOV BX,[BP-2]
PUSH BX
XOR BX,BX
PUSH BX
; BX ← ←seed
MOV BX,[BP-4]
MOV CX,0400X
CALL ←CryptData
ADD SP,0AX
MOV SP,BP
POP BP
RET;
; XOR64(a,b,out) int a[], b[], out[]; {
←XOR64:
CALL StkChk
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX
; int i;
; for (i=0; i<4; ++i) out[i] = a[i] ↑ b[i]; };
PUSH DX
MOV WORD PTR [BP-6],0
X3:
; BX ← ←i
POP BX
PUSH BX
CMP BX,4
JGE X2
JR X1
X4:
INC WORD PTR [BP-6]
JR X3
X1:
; BX ← ←i
POP BX
PUSH BX
; CX ← ←out
MOV CX,[BP-4]
SAL BX
ADD BX,CX
; CX ← ←i
POP CX
PUSH CX
; AX ← ←a
MOV AX,[BP+4]
SAL CX
ADD CX,AX
MOV DI,CX
MOV CX,[DI]
; AX ← ←i
POP AX
PUSH AX
PUSH CX
; CX ← ←b
MOV CX,[BP-2]
SAL AX
ADD AX,CX
MOV DI,AX
MOV CX,[DI]
POP AX
XOR AX,CX
MOV [BX],AX
JR X4
X2:
MOV SP,BP
POP BP
RET;
; OKToContinue(flag) int *flag; { *flag = true; };
←OKToContinue:
CALL StkChk
PUSH BP
MOV BP,SP
PUSH BX
; BX ← ←flag
POP BX
PUSH BX
MOV WORD PTR [BX],0FFFFX
MOV SP,BP
POP BP
RET;
; CryptData(keyP, nBlks, from, to, direction, mode, firstSeed)
←CryptData:
; int *keyP;
; int nBlks;
; struct Words4 from[], to[];
; int direction, mode;
; struct Words4 *firstSeed; {
CALL StkChk
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX
; struct ECB ecb;
; struct Words4 seed;
; struct Words4 newSeed;
; struct Words4 *seedP;
; int okToContinue, blk;
ADD SP,0FFDAX
; MoveBlock(&seed, firstSeed, 4);
;&←seed
LEA BX,[BP-28]
PUSH BX
MOV BX,4
; CX ← ←firstSeed
MOV CX,[BP-4]
CALL ←MoveBlock
POP DX
; seedP = &seed;
;&←seed
LEA BX,[BP-28]
; ←seedP ← BX
MOV [BP-38],BX
; if (to==0) to = from;
; BX ← ←to
MOV BX,[BP+6]
OR BX,BX
JNZ X5
; BX ← ←from
MOV BX,[BP+8]
; ←to ← BX
MOV [BP+6],BX
X5:
; ecb.kp = keyP;
; BX ← ←keyP
MOV BX,[BP+12]
; ←ecb+2 ← BX
MOV [BP-18],BX
; ecb.encrypt = direction;
; BX ← ←direction
MOV BX,[BP+4]
; ←ecb+0AX ← BX
MOV [BP-10],BX
; ecb.item = (int) &okToContinue;
;&←okToContinue
LEA BX,[BP-40]
; ←ecb+0CX ← BX
MOV [BP-8],BX
; ecb.proc = (int) &OKToContinue;
MOV BX,OFFSET ←OKToContinue
; ←ecb+0EX ← BX
MOV [BP-6],BX
; if (mode == slCBCCheck && direction == dirEncrypt && nBlks > 0) {
; BX ← ←mode
MOV BX,[BP-2]
CMP BX,0400X
JNZ X7
; BX ← ←direction
MOV BX,[BP+4]
CMP BX,1
JNZ X8
; BX ← ←nBlks
MOV BX,[BP+10]
CMP BX,0
JLE X8
MOV AL,1
JR X9
X8:
XOR AL,AL
X9:
OR AL,AL
JZ X7
MOV AL,1
JR X10
X7:
XOR AL,AL
X10:
OR AL,AL
JZ X6
; for (blk=0; blk<nBlks-1; ++blk)
MOV WORD PTR [BP-42],0
X13:
; BX ← ←nBlks
MOV BX,[BP+10]
DEC BX
; CX ← ←blk
POP CX
PUSH CX
CMP CX,BX
JGE X12
JR X11
X14:
INC WORD PTR [BP-42]
JR X13
X11:
; XOR64(&from[nBlks-1], &from[blk], &from[nBlks-1]);
; BX ← ←nBlks
MOV BX,[BP+10]
DEC BX
; CX ← ←from
MOV CX,[BP+8]
SAL BX
SAL BX
SAL BX
ADD BX,CX
PUSH BX
; BX ← ←blk
MOV BX,[BP-42]
; CX ← ←from
MOV CX,[BP+8]
SAL BX
SAL BX
SAL BX
ADD BX,CX
; CX ← ←nBlks
MOV CX,[BP+10]
DEC CX
; AX ← ←from
MOV AX,[BP+8]
SAL CX
SAL CX
SAL CX
ADD CX,AX
XCHG BX,CX
CALL ←XOR64
POP DX
JR X14
X12:
; Block(); };
CALL ←Block
X6:
; if (mode == slECB) {
; BX ← ←mode
MOV BX,[BP-2]
CMP BX,0200X
JNZ X15
; ecb.srcp = from;
; BX ← ←from
MOV BX,[BP+8]
; ←ecb+4 ← BX
MOV [BP-16],BX
; ecb.dstp = to;
; BX ← ←to
MOV BX,[BP+6]
; ←ecb+6 ← BX
MOV [BP-14],BX
; ecb.count = nBlks*8; /* Why beat around the bush? */
; BX ← ←nBlks
MOV BX,[BP+10]
SAL BX
SAL BX
SAL BX
; ←ecb+8 ← BX
MOV [BP-12],BX
; Docrypt(&ecb); return; };
;&←ecb
LEA BX,[BP-20]
CALL ←Docrypt
MOV SP,BP
POP BP
RET;
X15:
; ecb.count = 8;
MOV WORD PTR [BP-12],8
; for (blk=0; blk<nBlks; ++blk) {
MOV WORD PTR [BP-42],0
X18:
; BX ← ←nBlks
MOV BX,[BP+10]
; CX ← ←blk
POP CX
PUSH CX
CMP CX,BX
JGE X17
JR X16
X19:
INC WORD PTR [BP-42]
JR X18
X16:
; if (direction==dirEncrypt) XOR64(&from[blk], seedP, &from[blk]);
; BX ← ←direction
MOV BX,[BP+4]
CMP BX,1
JNZ X20
; BX ← ←blk
POP BX
PUSH BX
; CX ← ←from
MOV CX,[BP+8]
SAL BX
SAL BX
SAL BX
ADD BX,CX
PUSH BX
; BX ← ←blk
MOV BX,[BP-42]
; CX ← ←from
MOV CX,[BP+8]
SAL BX
SAL BX
SAL BX
ADD BX,CX
; CX ← ←seedP
MOV CX,[BP-38]
CALL ←XOR64
POP DX
; else MoveBlock(&newSeed, &from[blk], 4);
JR X21
X20:
;&←newSeed
LEA BX,[BP-36]
PUSH BX
; BX ← ←blk
MOV BX,[BP-42]
; CX ← ←from
MOV CX,[BP+8]
SAL BX
SAL BX
SAL BX
ADD BX,CX
PUSH BX
MOV BX,4
POP CX
CALL ←MoveBlock
POP DX
X21:
; ecb.srcp = &from[blk];
; BX ← ←blk
POP BX
PUSH BX
; CX ← ←from
MOV CX,[BP+8]
SAL BX
SAL BX
SAL BX
ADD BX,CX
; ←ecb+4 ← BX
MOV [BP-16],BX
; ecb.dstp = &to[blk];
; BX ← ←blk
POP BX
PUSH BX
; CX ← ←to
MOV CX,[BP+6]
SAL BX
SAL BX
SAL BX
ADD BX,CX
; ←ecb+6 ← BX
MOV [BP-14],BX
; Docrypt(&ecb);
;&←ecb
LEA BX,[BP-20]
CALL ←Docrypt
; if (direction == dirEncrypt) seedP = &to[blk];
; BX ← ←direction
JR $+5
X17:
JMP X23
MOV BX,[BP+4]
CMP BX,1
JNZ X22
; BX ← ←blk
POP BX
PUSH BX
; CX ← ←to
MOV CX,[BP+6]
SAL BX
SAL BX
SAL BX
ADD BX,CX
; ←seedP ← BX
MOV [BP-38],BX
; else {XOR64(&to[blk], seedP, &to[blk]); MoveBlock(seedP, &newSeed, 4); }; };
JR X24
X22:
; BX ← ←blk
POP BX
PUSH BX
; CX ← ←to
MOV CX,[BP+6]
SAL BX
SAL BX
SAL BX
ADD BX,CX
PUSH BX
; BX ← ←blk
MOV BX,[BP-42]
; CX ← ←to
MOV CX,[BP+6]
SAL BX
SAL BX
SAL BX
ADD BX,CX
; CX ← ←seedP
MOV CX,[BP-38]
CALL ←XOR64
POP DX
; BX ← ←seedP
MOV BX,[BP-38]
PUSH BX
MOV BX,4
;&←newSeed
LEA CX,[BP-36]
CALL ←MoveBlock
POP DX
X24:
JMP X19
X23:
; Block();
CALL ←Block
; if (mode == slCBCCheck && direction == dirDecrypt && nBlks > 0) {
; BX ← ←mode
MOV BX,[BP-2]
CMP BX,0400X
JNZ X26
; BX ← ←direction
MOV BX,[BP+4]
OR BX,BX
JNZ X27
; BX ← ←nBlks
MOV BX,[BP+10]
CMP BX,0
JLE X27
MOV AL,1
JR X28
X27:
XOR AL,AL
X28:
OR AL,AL
JZ X26
MOV AL,1
JR X29
X26:
XOR AL,AL
X29:
OR AL,AL
JZ X25
; for (blk=0; blk<nBlks-1; ++blk)
MOV WORD PTR [BP-42],0
X32:
; BX ← ←nBlks
MOV BX,[BP+10]
DEC BX
; CX ← ←blk
POP CX
PUSH CX
CMP CX,BX
JGE X31
JR X30
X33:
INC WORD PTR [BP-42]
JR X32
X30:
; XOR64(&to[nBlks-1], &to[blk], &to[nBlks-1]);
; BX ← ←nBlks
MOV BX,[BP+10]
DEC BX
; CX ← ←to
MOV CX,[BP+6]
SAL BX
SAL BX
SAL BX
ADD BX,CX
PUSH BX
; BX ← ←blk
MOV BX,[BP-42]
; CX ← ←to
MOV CX,[BP+6]
SAL BX
SAL BX
SAL BX
ADD BX,CX
; CX ← ←nBlks
MOV CX,[BP+10]
DEC CX
; AX ← ←to
MOV AX,[BP+6]
SAL CX
SAL CX
SAL CX
ADD CX,AX
XCHG BX,CX
CALL ←XOR64
POP DX
JR X33
X31:
; Block(); }; }; /* CryptData */
CALL ←Block
X25:
MOV SP,BP
POP BP
RET;
; Docrypt(ecb) struct ECB *ecb; {
←Docrypt:
CALL StkChk
PUSH BP
MOV BP,SP
PUSH BX
; int *okToContinue;
PUSH DX
; okToContinue = (int *) ecb->item;
; BX ← ←ecb
MOV BX,[BP-2]
MOV CX,[BX+12]
; ←okToContinue ← CX
POP DX
PUSH CX
; *okToContinue = false;
; BX ← ←okToContinue
POP BX
PUSH BX
MOV WORD PTR [BX],0
; Encrypt(ecb);
; BX ← ←ecb
MOV BX,[BP-2]
CALL ←Encrypt
; while (!(*okToContinue)) Block(); };
X34:
; DI ← ←okToContinue
POP DI
PUSH DI
MOV BX,[DI]
OR BX,BX
JNZ X35
CALL ←Block
JR X34
X35:
MOV SP,BP
POP BP
RET;
; MakeKey(source, key) struct ShortSTRING *source; char key[]; {
←MakeKey:
CALL StkChk
PUSH BP
MOV BP,SP
PUSH CX
PUSH BX
; int i;
; int j; char c;
ADD SP,0FFFAX
; Zero(key, 4);
MOV BX,4
; CX ← ←key
MOV CX,[BP-4]
CALL ←Zero
; for (i=0; i<source->length; ++i) {
MOV WORD PTR [BP-6],0
X38:
; DI ← ←source
MOV DI,[BP-2]
MOV BX,[DI]
; CX ← ←i
MOV CX,[BP-6]
CMP CX,BX
JGE X37
JR X36
X39:
INC WORD PTR [BP-6]
JR X38
X36:
; j = i&7;
; BX ← ←i
MOV BX,[BP-6]
AND BX,7
; ←j ← BX
MOV [BP-8],BX
; c=source->text[i];
; BX ← ←source
MOV BX,[BP-2]
ADD BX,4
; CX ← ←i
MOV CX,[BP-6]
ADD BX,CX
MOV AL,[BX]
; ←c ← AL
POP DX
PUSH AX
; if ('A' <= c && c <= 'Z') c += ('a' - 'A');
; AL ← ←c
POP AX
PUSH AX
MOV CL,041X
CMP CL,AL
JG X41
; AL ← ←c
POP AX
PUSH AX
CMP AL,05AX
X41:
JG X40
ADD BYTE PTR [BP-10],020X
X40:
; key[j] ↑= c<<1; };
; BX ← ←j
MOV BX,[BP-8]
; CX ← ←key
MOV CX,[BP-4]
ADD BX,CX
; AL ← ←c
POP AX
PUSH AX
SAL AL
XOR [BX],AL
JR X39
X37:
; CorrectParity(key); };
; BX ← ←key
MOV BX,[BP-4]
CALL ←CorrectParity
MOV SP,BP
POP BP
RET;
; CorrectParity(keyP) char keyP[]; {
←CorrectParity:
CALL StkChk
PUSH BP
MOV BP,SP
PUSH BX
; int i;
; char c;
; int pWord, pBitNo;
; if (parityTable[0] != 0x96) InitParityTable();
ADD SP,0FFF8X
MOV AX,WORD PTR ←parityTable
CMP AL,096X
JZ X42
CALL ←InitParityTable
X42:
; for (i=0; i<8; ++i) {
MOV WORD PTR [BP-4],0
X45:
; BX ← ←i
MOV BX,[BP-4]
CMP BX,8
JGE X44
JR X43
X46:
INC WORD PTR [BP-4]
JR X45
X43:
; c=keyP[i];
; BX ← ←i
MOV BX,[BP-4]
; CX ← ←keyP
MOV CX,[BP-2]
ADD BX,CX
MOV AL,[BX]
; ←c ← AL
MOV [BP-6],AL
; pWord = parityTable[c>>4];
MOV CL,4
; AL ← ←c
MOV AL,[BP-6]
SHR AL,CL
XOR AH,AH
LEA BX,←parityTable
ADD BX,AX
MOV AL,[BX]
XOR AH,AH
; ←pWord ← AX
MOV [BP-8],AX
; c=c>>1;
; AL ← ←c
MOV AL,[BP-6]
SHR AL
; ←c ← AL
MOV [BP-6],AL
; pBitNo = 7-(c&7);
; AL ← ←c
MOV AL,[BP-6]
AND AL,7
MOV CL,7
SUB CL,AL
XOR CH,CH
; ←pBitNo ← CX
POP DX
PUSH CX
; pWord = (pWord>>pBitNo)&1;
; CX ← ←pBitNo
POP CX
PUSH CX
; BX ← ←pWord
MOV BX,[BP-8]
SHR BX,CX
AND BX,1
; ←pWord ← BX
MOV [BP-8],BX
; keyP[i] = (c<<1) | pWord; }; };
; BX ← ←i
MOV BX,[BP-4]
; CX ← ←keyP
MOV CX,[BP-2]
ADD BX,CX
; AL ← ←c
MOV AL,[BP-6]
SAL AL
XOR AH,AH
; CX ← ←pWord
MOV CX,[BP-8]
OR AX,CX
MOV [BX],AL
JR X46
X44:
MOV SP,BP
POP BP
RET;
; int DESBlocks(n) int n; { return (n+3)/4; };
←DESBlocks:
CALL StkChk
PUSH BP
MOV BP,SP
PUSH BX
; BX ← ←n
POP BX
PUSH BX
ADD BX,3
SAR BX
SAR BX
MOV SP,BP
POP BP
RET;
; struct Words4 randomSeed;
; GetRandomIV(iv) struct Words4 *iv; {
←GetRandomIV:
CALL StkChk
PUSH BP
MOV BP,SP
PUSH BX
; struct Words4 prevSeed, temp;
ADD SP,0FFF0X
; MoveBlock(&prevSeed, &randomSeed, 4);
;&←prevSeed
LEA BX,[BP-10]
PUSH BX
MOV BX,4
LEA CX,←randomSeed
CALL ←MoveBlock
POP DX
; Timer(&temp);
;&←temp
LEA BX,[BP-18]
CALL ←Timer
; ReadCalendar(&temp.words[2]);
;&←temp
LEA BX,[BP-14]
CALL ←ReadCalendar
; DoubleDifference(&randomSeed, &temp);
;&←temp
LEA BX,[BP-18]
LEA CX,←randomSeed
CALL ←DoubleDifference
; Zero(&temp, 4);
MOV BX,4
;&←temp
LEA CX,[BP-18]
CALL ←Zero
; CorrectParity(&randomSeed);
LEA BX,←randomSeed
CALL ←CorrectParity
; EncryptBlock(&randomSeed, &temp, &randomSeed);
LEA BX,←randomSeed
PUSH BX
LEA BX,←randomSeed
;&←temp
LEA CX,[BP-18]
CALL ←EncryptBlock
POP DX
; CorrectParity(&randomSeed);
LEA BX,←randomSeed
CALL ←CorrectParity
; EncryptBlock(&randomSeed, &prevSeed, iv); };
LEA BX,←randomSeed
PUSH BX
; BX ← ←iv
MOV BX,[BP-2]
;&←prevSeed
LEA CX,[BP-10]
CALL ←EncryptBlock
POP DX
MOV SP,BP
POP BP
RET;
; InitParityTable() {
←InitParityTable:
CALL StkChk
PUSH BP
MOV BP,SP
; parityTable[0] = 0x96;
MOV ←parityTable,096X
; parityTable[1] = 0x69;
MOV ←parityTable+1,069X
; parityTable[2] = 0x69;
MOV ←parityTable+2,069X
; parityTable[3] = 0x96;
MOV ←parityTable+3,096X
; parityTable[4] = 0x69;
MOV ←parityTable+4,069X
; parityTable[5] = 0x96;
MOV ←parityTable+5,096X
; parityTable[6] = 0x96;
MOV ←parityTable+6,096X
; parityTable[7] = 0x69;
MOV ←parityTable+7,069X
; parityTable[8] = 0x69;
MOV ←parityTable+8,069X
; parityTable[9] = 0x96;
MOV ←parityTable+9,096X
; parityTable[10] = 0x96;
MOV ←parityTable+0AX,096X
; parityTable[11] = 0x69;
MOV ←parityTable+0BX,069X
; parityTable[12] = 0x96;
MOV ←parityTable+0CX,096X
; parityTable[13] = 0x69;
MOV ←parityTable+0DX,069X
; parityTable[14] = 0x69;
MOV ←parityTable+0EX,069X
; parityTable[15] = 0x96; };
MOV ←parityTable+0FX,096X
MOV SP,BP
POP BP
RET;
; Externals Declared Here
PUBLIC ←parityTable
PUBLIC ←EncryptBlock
PUBLIC ←CryptData
PUBLIC ←DecryptBlock
PUBLIC ←CBCCheckDecrypt
PUBLIC ←XOR64
PUBLIC ←OKToContinue
PUBLIC ←Docrypt
PUBLIC ←MakeKey
PUBLIC ←CorrectParity
PUBLIC ←InitParityTable
PUBLIC ←DESBlocks
PUBLIC ←randomSeed
PUBLIC ←GetRandomIV
C←CODE ENDS
; Number of Bytes of Code = 04F8X, (1272)