summaryrefslogtreecommitdiff
path: root/helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'helper.c')
-rw-r--r--helper.c64
1 files changed, 53 insertions, 11 deletions
diff --git a/helper.c b/helper.c
index 91a78b577..bf4e145b2 100644
--- a/helper.c
+++ b/helper.c
@@ -45,7 +45,6 @@
45#include <sys/un.h> 45#include <sys/un.h>
46#include <fcntl.h> 46#include <fcntl.h>
47 47
48#include "rc4.h"
49#include "xmalloc.h" 48#include "xmalloc.h"
50#include "ssh.h" 49#include "ssh.h"
51#include "config.h" 50#include "config.h"
@@ -57,10 +56,58 @@
57 56
58#ifndef HAVE_ARC4RANDOM 57#ifndef HAVE_ARC4RANDOM
59 58
59typedef struct
60{
61 unsigned int s[256];
62 int i;
63 int j;
64} rc4_t;
65
60void get_random_bytes(unsigned char *buf, int len); 66void get_random_bytes(unsigned char *buf, int len);
67void rc4_key(rc4_t *r, unsigned char *key, int len);
68void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len);
61 69
62static rc4_t *rc4 = NULL; 70static rc4_t *rc4 = NULL;
63 71
72void rc4_key(rc4_t *r, unsigned char *key, int len)
73{
74 int t;
75
76 for(r->i = 0; r->i < 256; r->i++)
77 r->s[r->i] = r->i;
78
79 r->j = 0;
80 for(r->i = 0; r->i < 256; r->i++)
81 {
82 r->j = (r->j + r->s[r->i] + key[r->i % len]) % 256;
83 t = r->s[r->i];
84 r->s[r->i] = r->s[r->j];
85 r->s[r->j] = t;
86 }
87 r->i = r->j = 0;
88}
89
90void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len)
91{
92 int t;
93 int c;
94
95 c = 0;
96 while(c < len)
97 {
98 r->i = (r->i + 1) % 256;
99 r->j = (r->j + r->s[r->i]) % 256;
100 t = r->s[r->i];
101 r->s[r->i] = r->s[r->j];
102 r->s[r->j] = t;
103
104 t = (r->s[r->i] + r->s[r->j]) % 256;
105
106 buffer[c] = r->s[t];
107 c++;
108 }
109}
110
64unsigned int arc4random(void) 111unsigned int arc4random(void)
65{ 112{
66 unsigned int r; 113 unsigned int r;
@@ -117,7 +164,8 @@ void get_random_bytes(unsigned char *buf, int len)
117 164
118 /* Send blocking read request to EGD */ 165 /* Send blocking read request to EGD */
119 egd_message[1] = len; 166 egd_message[1] = len;
120 c = write(random_pool, egd_message, sizeof(egd_message)); 167
168 c = atomicio(write, random_pool, egd_message, sizeof(egd_message));
121 if (c == -1) 169 if (c == -1)
122 fatal("Couldn't write to EGD socket \"%s\": %s", RANDOM_POOL, strerror(errno)); 170 fatal("Couldn't write to EGD socket \"%s\": %s", RANDOM_POOL, strerror(errno));
123 171
@@ -129,15 +177,9 @@ void get_random_bytes(unsigned char *buf, int len)
129 177
130#endif /* HAVE_EGD */ 178#endif /* HAVE_EGD */
131 179
132 do { 180 c = atomicio(read, random_pool, buf, len);
133 c = read(random_pool, buf, len); 181 if (c <= 0)
134 182 fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
135 if ((c == -1) && (errno != EINTR))
136 fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
137 } while (c == -1);
138
139 if (c != len)
140 fatal("Short read from random pool \"%s\"", RANDOM_POOL);
141 183
142 close(random_pool); 184 close(random_pool);
143} 185}