/* Software interface to DES for RPC */ /* DESSofter.c */ /* Dan Swinehart, November 11, 1982 9:59 am */ /* Adapted from DESSoft.mesa, by Schroeder and Birrell, 1981-2 */ /* L. Stewart, December 27, 1982 2:56 PM flush nested declarations */ #include <Env.h> #include <Encrypt.h> #include <RPC.h> /* For slXXX encryption values */ 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; { CryptData(key, 1, from, to, dirEncrypt, slECB, 0); }; DecryptBlock(key, from, to) int *key; struct Words4 *from, *to; { CryptData(key, 1, from, to, dirDecrypt, slECB, 0); }; CBCCheckDecrypt(key, nBlks, from, to, seed) int *key, nBlks; struct Words4 *from, *to, *seed; { CryptData(key, nBlks, from, to, dirDecrypt, slCBCCheck, seed); }; XOR64(a,b,out) int a[], b[], out[]; { int i; for (i=0; i<4; ++i) out[i] = a[i] ↑ b[i]; }; OKToContinue(flag) int *flag; { *flag = true; }; CryptData(keyP, nBlks, from, to, direction, mode, firstSeed) int *keyP; int nBlks; struct Words4 from[], to[]; int direction, mode; struct Words4 *firstSeed; { struct ECB ecb; struct Words4 newSeed; struct Words4 seed; struct Words4 *seedP; int okToContinue, blk; seedP = &seed; MoveBlock(seedP, firstSeed, 4); if (to==0) to = from; ecb.kp = keyP; ecb.encrypt = direction; ecb.item = (int) &okToContinue; ecb.proc = (int) &OKToContinue; if (mode == slCBCCheck && direction == dirEncrypt && nBlks > 0) { for (blk=0; blk<nBlks-1; ++blk) XOR64(&from[nBlks-1], &from[blk], &from[nBlks-1]); Block(); }; if (mode == slECB) { ecb.count = nBlks*8; /* Why beat around the bush? */ ecb.srcp = from; ecb.dstp = to; Docrypt(&ecb); return; }; ecb.count = 8; for (blk=0; blk<nBlks; ++blk) { if (direction==dirEncrypt) XOR64(&from[blk], seedP, &from[blk]); else MoveBlock(&newSeed, &from[blk], 4); ecb.srcp = &from[blk]; ecb.dstp = &to[blk]; Docrypt(&ecb); if (direction == dirEncrypt) seedP = &to[blk]; else {XOR64(&to[blk], seedP, &to[blk]); MoveBlock(seedP, &newSeed, 4); }; }; Block(); if (mode == slCBCCheck && direction == dirDecrypt && nBlks > 0) { for (blk=0; blk<nBlks-1; ++blk) XOR64(&to[nBlks-1], &to[blk], &to[nBlks-1]); Block(); }; }; /* CryptData */ Docrypt(ecb) struct ECB *ecb; { int *okToContinue; int i; char *from, *to, *key; okToContinue = (int *) ecb->item; *okToContinue = false; /* Encrypt(ecb); */ /* Dummy encryption/decryption: XOR key with data, ho ho. */ { from = ecb->srcp; to = ecb->dstp; key = ecb->kp; for (i=0; i<ecb->count; ++i) { to[i] = from[i] ↑ key[i&7]; }; *okToContinue = true; Block(); }; /* End of Dummy encryption/decryption */ while (!(*okToContinue)) Block(); }; MakeKey(source, key) struct ShortSTRING *source; char key[]; { /* User interface routine to construct a 64 bit key from an ASCII string. "key" is an array that holds the 64 bit key. Note: every eighth bit of "key" is an odd parity bit for the preceeding seven bits. */ int i; int j; char c; Zero(key, 4); for (i=0; i<source->length; ++i) { j = i&7; c=source->text[i]; if ('A' <= c && c <= 'Z') c += ('a' - 'A'); key[j] ↑= c<<1; }; CorrectParity(key); }; CorrectParity(keyP) char keyP[]; { int i; char c; int pWord, pBitNo; if (parityTable[0] != 0x96) InitParityTable(); for (i=0; i<8; ++i) { c=keyP[i]; pWord = parityTable[c>>4]; c=c>>1; pBitNo = 7-(c&7); pWord = (pWord>>pBitNo)&1; keyP[i] = (c<<1) | pWord; }; }; int DESBlocks(n) int n; { return (n+3)/4; }; struct Words4 randomSeed; GetRandomIV(iv) struct Words4 *iv; { struct Words4 prevSeed, temp; MoveBlock(&prevSeed, &randomSeed, 4); Timer(&temp); ReadCalendar(&temp.words[2]); DoubleDifference(&randomSeed, &temp); Zero(&temp, 4); CorrectParity(&randomSeed); EncryptBlock(&randomSeed, &temp, &randomSeed); CorrectParity(&randomSeed); EncryptBlock(&randomSeed, &prevSeed, iv); }; InitParityTable() { parityTable[0] = 0x96; parityTable[1] = 0x69; parityTable[2] = 0x69; parityTable[3] = 0x96; parityTable[4] = 0x69; parityTable[5] = 0x96; parityTable[6] = 0x96; parityTable[7] = 0x69; parityTable[8] = 0x69; parityTable[9] = 0x96; parityTable[10] = 0x96; parityTable[11] = 0x69; parityTable[12] = 0x96; parityTable[13] = 0x69; parityTable[14] = 0x69; parityTable[15] = 0x96; };