// //rand-key.c // // // // //-UserX 2001/11/19 #include #include "crypt/rand-key.h" #include "base/mem.h" #include "base/dblock.h" #include "base/buffer.h" RandomKey *randomkeyMake(void) { RandomKey *rk = memAlloc(sizeof(RandomKey), "RandomKey", NULL);//ximalloc(sizeof(RandomKey)); SHA1Init(&rk->Sha1); rk->output = dblockMake(RANDOM_KEY_BLOCK_LENGTH, RANDOM_KEY_BLOCK_LENGTH, "randomkeyoutput"); rk->outputoffset = 0; rk->outputcounter = 0; rk->key = dblockMake(RANDOM_KEY_LENGTH, RANDOM_KEY_LENGTH, "randomkeykey"); rk->blowfish = memAlloc(sizeof(BlowfishContext), "RandomKeyBlowfishContext", NULL);//ximalloc(sizeof(BlowfishContext)); rk->counter = dblockMake(RANDOM_KEY_BLOCK_LENGTH, RANDOM_KEY_BLOCK_LENGTH, "randomkeycounter"); return rk; } void randomkeyMakeKey(RandomKey *rk, DataBlock *seed) { int ic; DataBlock *db; if(rk == NULL) { return; } db = dblockEmpty("randomkeyseedscratch"); //clear any existing key. rk->key = dblockResize(rk->key, 0); rk->key->size = 0; //crear the count of required zeros ic = 0; while(rk->key->size < RANDOM_KEY_LENGTH) { //make a buffer with seed prepended by a number 0 bytes equal //to the number complete iteration done by this loop. db = dblockResize(db, ic); db->size = ic; memset(db->data, 0, ic); db = dblockAppendBlock(db, seed); //put this through a SHA1 hash. SHA1Init(&rk->Sha1); SHA1Update(&rk->Sha1, db->data, db->size); db = dblockResize(db, 20); db->size = 20; SHA1Final(db->data, &rk->Sha1); //Append this to already created key data. rk->key = dblockAppendBlock(rk->key, db); //increment count of required zeros ic++; } dblockFree(db); //crop to the actual keylength. rk->key->size = RANDOM_KEY_LENGTH; randomkeyRekey(rk); } //This should be called after a change of the random key's key void randomkeyRekey(RandomKey *rk) { Blowfish_Init(rk->blowfish, rk->key->data, RANDOM_KEY_LENGTH); memset(rk->counter->data, 0, RANDOM_KEY_BLOCK_LENGTH); //todo: replace this with triple DES //xteabEncode((uint32 *) rk->counter->data, RANDOM_KEY_BLOCK_LENGTH / 4, (uint32 *) rk->key->data); Blowfish_Encrypt(rk->blowfish, (unsigned long *)(rk->counter->data), (unsigned long *)(rk->counter->data + 4)); randomkeyGenerateOutput(rk); } void randomkeyCounterIncrement(RandomKey *rk) { bufferInc(rk->counter->data, rk->counter->size); //int i; //for(i = rk->counter->size - 1; i >= 0; i--) { // if(rk->counter->data[i]-- != 0) { //carry if data[i] is zero. // break; //break if no carry // } //} } //Create a new key from the output of the random generator void randomkeyGateKey(RandomKey *rk) { DataBlock *db = dblockMake(RANDOM_KEY_LENGTH, RANDOM_KEY_LENGTH, "randomkeygate"); rk->outputcounter = 0; //todo: consider: appending this to the original seed and do a makekey with that. randomkeyGetBuffer(rk, db->data, db->size); dblockFree(rk->key); rk->key = db; Blowfish_Init(rk->blowfish, rk->key->data, RANDOM_KEY_LENGTH); randomkeyGenerateOutput(rk); } //Increment then encrypt the counter to generate another //buffer of output. void randomkeyGenerateOutput(RandomKey *rk) { //increment counter randomkeyCounterIncrement(rk); rk->outputcounter++; if(rk->outputcounter > RANDOM_KEY_PG) { randomkeyGateKey(rk); } //copy the counter. memcpy(rk->output->data, rk->counter->data, RANDOM_KEY_BLOCK_LENGTH); //encrypt the copy of the counter //todo: change this to triple DES //xteabEncode((uint32 *) rk->output->data, RANDOM_KEY_BLOCK_LENGTH / 4, (uint32 *) rk->key->data); Blowfish_Encrypt(rk->blowfish, (unsigned long *)(rk->output->data), (unsigned long *)(rk->output->data + 4)); //clear output offset. rk->outputoffset = 0; } //get a buffer of x bytes length void randomkeyGetBuffer(RandomKey *rk, uint8 *buffer, int length) { if(rk == NULL || buffer == NULL) { return; } for(;length > 0; buffer++, length--, rk->outputoffset++) { //check there are still bytes on the output buffer if(rk->outputoffset >= rk->output->size) { //generate if there are not randomkeyGenerateOutput(rk); } *buffer = rk->output->data[rk->outputoffset]; } }