|
|
1.1 root 1: /* R_RANDOM.C - random objects for RSAREF
2: */
3:
4: /* Copyright (C) 1991-2 RSA Laboratories, a division of RSA Data
5: Security, Inc. 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:
15: int R_RandomInit (randomStruct)
16: R_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:
25: int R_RandomUpdate (randomStruct, block, blockLen)
26: R_RANDOM_STRUCT *randomStruct; /* random structure */
27: unsigned char *block; /* block of values to mix in */
28: unsigned 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:
59: int R_GetRandomBytesNeeded (bytesNeeded, randomStruct)
60: unsigned int *bytesNeeded; /* number of mix-in bytes needed */
61: R_RANDOM_STRUCT *randomStruct; /* random structure */
62: {
63: *bytesNeeded = randomStruct->bytesNeeded;
64:
65: return (0);
66: }
67:
68: int R_GenerateBytes (block, blockLen, randomStruct)
69: unsigned char *block; /* block */
70: unsigned int blockLen; /* length of block */
71: R_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:
107: void R_RandomFinal (randomStruct)
108: R_RANDOM_STRUCT *randomStruct; /* random structure */
109: {
110: R_memset ((POINTER)randomStruct, 0, sizeof (*randomStruct));
111: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.