www.pudn.com > RSA-MD2-MD5-source_code.rar > r_random.c, change:1994-03-26,size:3134b


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