;Alto->8086 small-c compiler rev 2.0 C←CODE SEGMENT $INCLUDE(8086LIB.D) $INCLUDE(DESSofter.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: 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: 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; { 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: 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: 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; { PUSH BP MOV BP,SP PUSH CX PUSH BX ; struct ECB ecb; ; struct Words4 newSeed; ; struct Words4 seed; ; struct Words4 *seedP; ; int okToContinue, blk; ADD SP,0FFDAX ; seedP = &seed; ;&←seed LEA BX,[BP-36] ; ←seedP ← BX MOV [BP-38],BX ; MoveBlock(seedP, firstSeed, 4); ; BX ← ←seedP MOV BX,[BP-38] PUSH BX MOV BX,4 ; CX ← ←firstSeed MOV CX,[BP-4] CALL ←MoveBlock POP DX ; 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.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 ; 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 ; 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-28] 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-28] 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: PUSH BP MOV BP,SP PUSH BX ; int *okToContinue; ; int i; ; char *from, *to, *key; ADD SP,0FFF6X ; okToContinue = (int *) ecb->item; ; BX ← ←ecb MOV BX,[BP-2] MOV CX,[BX+12] ; ←okToContinue ← CX MOV [BP-4],CX ; *okToContinue = false; ; BX ← ←okToContinue MOV BX,[BP-4] MOV WORD PTR [BX],0 ; { ; from = ecb->srcp; ; BX ← ←ecb MOV BX,[BP-2] MOV CX,[BX+4] ; ←from ← CX MOV [BP-8],CX ; to = ecb->dstp; ; BX ← ←ecb MOV BX,[BP-2] MOV CX,[BX+6] ; ←to ← CX MOV [BP-10],CX ; key = ecb->kp; ; BX ← ←ecb MOV BX,[BP-2] MOV CX,[BX+2] ; ←key ← CX POP DX PUSH CX ; for (i=0; i<ecb->count; ++i) { to[i] = from[i] ↑ key[i&7]; }; MOV WORD PTR [BP-6],0 X36: ; BX ← ←ecb MOV BX,[BP-2] MOV CX,[BX+8] ; BX ← ←i MOV BX,[BP-6] CMP BX,CX JGE X35 JR X34 X37: INC WORD PTR [BP-6] JR X36 X34: ; BX ← ←i MOV BX,[BP-6] ; CX ← ←to MOV CX,[BP-10] ADD BX,CX ; CX ← ←i MOV CX,[BP-6] ; AX ← ←from MOV AX,[BP-8] ADD CX,AX MOV DI,CX MOV AL,[DI] PUSH BX ; BX ← ←i MOV BX,[BP-6] AND BX,7 ; CX ← ←key MOV CX,[BP-12] ADD BX,CX MOV CL,[BX] XOR AL,CL POP BX MOV [BX],AL JR X37 X35: ; *okToContinue = true; Block(); }; ; BX ← ←okToContinue MOV BX,[BP-4] MOV WORD PTR [BX],0FFFFX CALL ←Block ; while (!(*okToContinue)) Block(); }; X38: ; DI ← ←okToContinue MOV DI,[BP-4] MOV BX,[DI] OR BX,BX JNZ X39 CALL ←Block JR X38 X39: MOV SP,BP POP BP RET; ; MakeKey(source, key) struct ShortSTRING *source; char key[]; { ←MakeKey: 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 X42: ; DI ← ←source MOV DI,[BP-2] MOV BX,[DI] ; CX ← ←i MOV CX,[BP-6] CMP CX,BX JGE X41 JR X40 X43: INC WORD PTR [BP-6] JR X42 X40: ; 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 X45 ; AL ← ←c POP AX PUSH AX CMP AL,05AX X45: JG X44 ADD BYTE PTR [BP-10],020X X44: ; 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 X43 X41: ; CorrectParity(key); }; ; BX ← ←key MOV BX,[BP-4] CALL ←CorrectParity MOV SP,BP POP BP RET; ; CorrectParity(keyP) char keyP[]; { ←CorrectParity: 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 X46 CALL ←InitParityTable X46: ; for (i=0; i<8; ++i) { MOV WORD PTR [BP-4],0 X49: ; BX ← ←i MOV BX,[BP-4] CMP BX,8 JGE X48 JR X47 X50: INC WORD PTR [BP-4] JR X49 X47: ; 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 X50 X48: MOV SP,BP POP BP RET; ; int DESBlocks(n) int n; { return (n+3)/4; }; ←DESBlocks: 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: 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: 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 = 055DX, (1373)