/* 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; };