source: trunk/third/moira/util/rsaref/r_random.c @ 23095

Revision 23095, 3.0 KB checked in by ghudson, 16 years ago (diff)
Import the moira package from SIPB Debathena.
Line 
1/* R_RANDOM.C - random objects for RSAREF
2 */
3
4/* Copyright (C) RSA Laboratories, a division of RSA Data Security,
5     Inc., created 1991. All rights reserved.
6 */
7
8#include "global.h"
9#include "rsaref.h"
10#include "r_random.h"
11#include "md5.h"
12
13#define RANDOM_BYTES_NEEDED 256
14
15int R_RandomInit (randomStruct)
16R_RANDOM_STRUCT *randomStruct;                      /* new random structure */
17{
18  randomStruct->bytesNeeded = RANDOM_BYTES_NEEDED;
19  R_memset ((POINTER)randomStruct->state, 0, sizeof (randomStruct->state));
20  randomStruct->outputAvailable = 0;
21 
22  return (0);
23}
24
25int R_RandomUpdate (randomStruct, block, blockLen)
26R_RANDOM_STRUCT *randomStruct;                          /* random structure */
27unsigned char *block;                          /* block of values to mix in */
28unsigned int blockLen;                                   /* length of block */
29{
30  MD5_CTX context;
31  unsigned char digest[16];
32  unsigned int i, x;
33 
34  MD5Init (&context);
35  MD5Update (&context, block, blockLen);
36  MD5Final (digest, &context);
37
38  /* add digest to state */
39  x = 0;
40  for (i = 0; i < 16; i++) {
41    x += randomStruct->state[15-i] + digest[15-i];
42    randomStruct->state[15-i] = (unsigned char)x;
43    x >>= 8;
44  }
45 
46  if (randomStruct->bytesNeeded < blockLen)
47    randomStruct->bytesNeeded = 0;
48  else
49    randomStruct->bytesNeeded -= blockLen;
50 
51  /* Zeroize sensitive information.
52   */
53  R_memset ((POINTER)digest, 0, sizeof (digest));
54  x = 0;
55 
56  return (0);
57}
58
59int R_GetRandomBytesNeeded (bytesNeeded, randomStruct)
60unsigned int *bytesNeeded;                 /* number of mix-in bytes needed */
61R_RANDOM_STRUCT *randomStruct;                          /* random structure */
62{
63  *bytesNeeded = randomStruct->bytesNeeded;
64 
65  return (0);
66}
67
68int R_GenerateBytes (block, blockLen, randomStruct)
69unsigned char *block;                                              /* block */
70unsigned int blockLen;                                   /* length of block */
71R_RANDOM_STRUCT *randomStruct;                          /* random structure */
72{
73  MD5_CTX context;
74  unsigned int available, i;
75 
76  if (randomStruct->bytesNeeded)
77    return (RE_NEED_RANDOM);
78 
79  available = randomStruct->outputAvailable;
80 
81  while (blockLen > available) {
82    R_memcpy
83      ((POINTER)block, (POINTER)&randomStruct->output[16-available],
84       available);
85    block += available;
86    blockLen -= available;
87
88    /* generate new output */
89    MD5Init (&context);
90    MD5Update (&context, randomStruct->state, 16);
91    MD5Final (randomStruct->output, &context);
92    available = 16;
93
94    /* increment state */
95    for (i = 0; i < 16; i++)
96      if (randomStruct->state[15-i]++)
97        break;
98  }
99
100  R_memcpy
101    ((POINTER)block, (POINTER)&randomStruct->output[16-available], blockLen);
102  randomStruct->outputAvailable = available - blockLen;
103
104  return (0);
105}
106
107void R_RandomFinal (randomStruct)
108R_RANDOM_STRUCT *randomStruct;                          /* random structure */
109{
110  R_memset ((POINTER)randomStruct, 0, sizeof (*randomStruct));
111}
Note: See TracBrowser for help on using the repository browser.