/* 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 #include #include /* 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 0) { for (blk=0; blkitem; *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; icount; ++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; ilength; ++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; };