//
//salt.c
//
//These functions are to be used to provide garbage filler to pad out sent structures.
//
//*Absolutely* no guarentees are made about the qualtity of the randomness
//of the bytes generated by this.
//
//
//-UserX 2001/11/16

#include <time.h>
#include "crypt/salt.h"
#include "base/dblock.h"
#include "crypt/arcfour.h"

#define SALTMAX 511

uint8 SaltBuffer[SALTMAX];
int SaltWrite = 0;
int SaltRead = 0;
ArcfourContext *SaltA4;

void saltInit(void) {
	*((clock_t *)(&SaltBuffer[0])) = clock();
	*((time_t *)(&SaltBuffer[sizeof(clock_t)])) = time(NULL);
	SaltA4 = arcfourMake();
	arcfourKey(SaltA4, SaltBuffer, sizeof(clock_t) + sizeof(time_t));

	arcfourBuffer(SaltA4, SaltBuffer, SALTMAX);
	arcfourCrypt(SaltA4, SaltBuffer, SALTMAX);
	arcfourCrypt(SaltA4, SaltBuffer, SALTMAX);
	arcfourCrypt(SaltA4, SaltBuffer, SALTMAX);
}

void saltCrypt(int offset, int length) {
	if(offset + length >= SALTMAX) {
		arcfourCrypt(SaltA4, SaltBuffer + offset, SALTMAX - offset);
		length -= SALTMAX - offset;
		offset = 0;
	}
	for(; length >= SALTMAX; length -= SALTMAX) {
		arcfourCrypt(SaltA4, SaltBuffer + 0, SALTMAX);
	}
	if(length > 0) {
		arcfourCrypt(SaltA4, SaltBuffer + offset, length);
	}
	
}

//Add the specified buffer to the saltbuffer.
void saltAddBuffer(uint8 *buffer, int length) {
	//int i;
	//length &= ~1;
	//for(i = 0; i < length; i += 2) {
	//	SaltBuffer[SaltWrite] ^= buffer[i] ^ (buffer[i + 1] << 4);
	//	SaltWrite = (SaltWrite + 1) % SALTMAX;
	//}
	arcfourAddKey(SaltA4, buffer, length);
	saltCrypt(SaltWrite, length);
	SaltWrite = (SaltWrite + length) % SALTMAX;
}

//Add all the data from a data block to the salt buffer.
void saltAdd(DataBlock *db) {
	saltAddBuffer(db->data, db->size);
}

//Insert salt into a specified buffer.
void saltBuffer(uint8 *buffer, int length) {
	int i;
	int t = SaltRead;
	for(i = 0; i < length; i++) {
		buffer[i] ^= SaltBuffer[SaltRead];
		SaltRead = (SaltRead + 1) % SALTMAX;
	}
	saltCrypt(t, length);
}

