mirror of
https://github.com/cryb-to/cryb-to.git
synced 2024-11-25 15:15:42 +00:00
111 lines
3 KiB
C
111 lines
3 KiB
C
/* R_RANDOM.C - random objects for RSAREF
|
|
*/
|
|
|
|
/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
|
|
Inc., created 1991. All rights reserved.
|
|
*/
|
|
|
|
#include "global.h"
|
|
#include "rsaref.h"
|
|
#include "r_random.h"
|
|
#include "md5.h"
|
|
|
|
#define RANDOM_BYTES_NEEDED 256
|
|
|
|
int R_RandomInit (randomStruct)
|
|
R_RANDOM_STRUCT *randomStruct; /* new random structure */
|
|
{
|
|
randomStruct->bytesNeeded = RANDOM_BYTES_NEEDED;
|
|
R_memset ((POINTER)randomStruct->state, 0, sizeof (randomStruct->state));
|
|
randomStruct->outputAvailable = 0;
|
|
|
|
return (0);
|
|
}
|
|
|
|
int R_RandomUpdate (randomStruct, block, blockLen)
|
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
|
unsigned char *block; /* block of values to mix in */
|
|
unsigned int blockLen; /* length of block */
|
|
{
|
|
MD5_CTX context;
|
|
unsigned char digest[16];
|
|
unsigned int i, x;
|
|
|
|
MD5Init (&context);
|
|
MD5Update (&context, block, blockLen);
|
|
MD5Final (digest, &context);
|
|
|
|
/* add digest to state */
|
|
x = 0;
|
|
for (i = 0; i < 16; i++) {
|
|
x += randomStruct->state[15-i] + digest[15-i];
|
|
randomStruct->state[15-i] = (unsigned char)x;
|
|
x >>= 8;
|
|
}
|
|
|
|
if (randomStruct->bytesNeeded < blockLen)
|
|
randomStruct->bytesNeeded = 0;
|
|
else
|
|
randomStruct->bytesNeeded -= blockLen;
|
|
|
|
/* Zeroize sensitive information.
|
|
*/
|
|
R_memset ((POINTER)digest, 0, sizeof (digest));
|
|
x = 0;
|
|
|
|
return (0);
|
|
}
|
|
|
|
int R_GetRandomBytesNeeded (bytesNeeded, randomStruct)
|
|
unsigned int *bytesNeeded; /* number of mix-in bytes needed */
|
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
|
{
|
|
*bytesNeeded = randomStruct->bytesNeeded;
|
|
|
|
return (0);
|
|
}
|
|
|
|
int R_GenerateBytes (block, blockLen, randomStruct)
|
|
unsigned char *block; /* block */
|
|
unsigned int blockLen; /* length of block */
|
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
|
{
|
|
MD5_CTX context;
|
|
unsigned int available, i;
|
|
|
|
if (randomStruct->bytesNeeded)
|
|
return (RE_NEED_RANDOM);
|
|
|
|
available = randomStruct->outputAvailable;
|
|
|
|
while (blockLen > available) {
|
|
R_memcpy
|
|
((POINTER)block, (POINTER)&randomStruct->output[16-available],
|
|
available);
|
|
block += available;
|
|
blockLen -= available;
|
|
|
|
/* generate new output */
|
|
MD5Init (&context);
|
|
MD5Update (&context, randomStruct->state, 16);
|
|
MD5Final (randomStruct->output, &context);
|
|
available = 16;
|
|
|
|
/* increment state */
|
|
for (i = 0; i < 16; i++)
|
|
if (randomStruct->state[15-i]++)
|
|
break;
|
|
}
|
|
|
|
R_memcpy
|
|
((POINTER)block, (POINTER)&randomStruct->output[16-available], blockLen);
|
|
randomStruct->outputAvailable = available - blockLen;
|
|
|
|
return (0);
|
|
}
|
|
|
|
void R_RandomFinal (randomStruct)
|
|
R_RANDOM_STRUCT *randomStruct; /* random structure */
|
|
{
|
|
R_memset ((POINTER)randomStruct, 0, sizeof (*randomStruct));
|
|
}
|