]> andersk Git - moira.git/blob - util/rsaref/r_random.c
RSAREF (for new reg_svr)
[moira.git] / util / rsaref / r_random.c
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
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 page took 0.125265 seconds and 5 git commands to generate.