Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

125 lines
3.4 KiB

/* Microsoft Corporation (C) 2000 */
#include "crptkPCH.h"
#include "bv4.h"
void bv4_key_C(BV4_KEYSTRUCT *pState, DWORD dwLen, unsigned char *buf)
{
if (pState == NULL)
{
return; // Too bad we return void.
}
int keyLength = dwLen;
BYTE *key = buf;
DWORD i;
for (i = 0; i < 256; i++)
{
pState->p_T[i] = (unsigned char)i;
}
// fill k with the key, repeated as many times as necessary
// to fill the entire array;
DWORD k[256]; // contains only 8-bit values zero-extended to 32 bits.
int keyPos = 0;
for (i = 0; i < 256; i++)
{
if (keyPos >= keyLength)
{
keyPos = 0;
}
k[i] = key[keyPos++];
}
DWORD j = 0;
for (i = 0; i < 256; i++)
{
j = (j + pState->p_T[i] + k[i]) & 0xff;
DWORD tmp = pState->p_T[i];
pState->p_T[i] = pState->p_T[j];
pState->p_T[j] = (unsigned char)tmp;
}
// treat alpha and beta as one contiguous array of 33 4-byte blocks.
// see "Applied Cryptography", 1996, by Bruce Schneier, p. 397.
i = 0;
j = 0;
for (int m = 0; m < 33; m++)
{
DWORD nextDword = 0;
// gather up the next 4 bytes of keys into one DWORD
for (int n = 0; n < 4; n++)
{
i = (i+1) & 0xff;
DWORD ti = pState->p_T[i];
j = (j+ti) & 0xff;
// swap T[i] and T[j];
DWORD tj = pState->p_T[j];
pState->p_T[i] = (unsigned char)tj;
pState->p_T[j] = (unsigned char)ti;
DWORD t = (ti+tj) & 0xff;
DWORD kk = pState->p_T[t];
nextDword |= kk << (n*8);
}
if (m == 0)
{
pState->p_alpha = nextDword;
}
else
{
pState->p_beta[m-1] = nextDword;
}
}
// keep the final state as the state we need for the new algorithm.
// T has already been updated.
pState->p_R = (unsigned char)i;
pState->p_S = (unsigned char)j;
}
// cipher: generate a stream of 32-bit keys and xor them with the
// contents of buffer. This can be used to encrypt/decrypt
// a stream of data.
void bv4_C(BV4_KEYSTRUCT *pState, DWORD dwLen, unsigned char *buf)
{
if (pState == NULL)
{
return; // Too bad we return void.
}
DWORD *buffer = (DWORD *)buf;
DWORD bufferLength = dwLen / sizeof(DWORD);
DWORD *last = buffer + bufferLength;
// load field values into local variables
// the following change on every iteration of the loop
DWORD r = pState->p_R;
DWORD s = pState->p_S;
DWORD alpha = pState->p_alpha;
// the following are loop invariant
unsigned char *t = pState->p_T;
DWORD *beta = pState->p_beta;
for (last = buffer + bufferLength; buffer < last; buffer++)
{
r = (r+1) & 0xff;
DWORD tr = t[r];
s = (s+tr) & 0xff;
DWORD ts = t[s];
t[r] = (unsigned char)ts;
t[s] = (unsigned char)tr;
DWORD tmp = (ts+tr) & 0xff;
DWORD randPad = alpha * t[tmp];
*buffer = randPad^(*buffer);
alpha = alpha + beta[s & 0x1f];
}
// update the field values from the local variables
pState->p_R = (unsigned char)r;
pState->p_S = (unsigned char)s;
pState->p_alpha = alpha;
}