summaryrefslogtreecommitdiffstats
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 91a78b57..bf4e145b 100644
--- a/helper.c
+++ b/helper.c
@@ -45,7 +45,6 @@
#include <sys/un.h>
#include <fcntl.h>
-#include "rc4.h"
#include "xmalloc.h"
#include "ssh.h"
#include "config.h"
@@ -57,10 +56,58 @@
#ifndef HAVE_ARC4RANDOM
+typedef struct
+{
+ unsigned int s[256];
+ int i;
+ int j;
+} rc4_t;
+
void get_random_bytes(unsigned char *buf, int len);
+void rc4_key(rc4_t *r, unsigned char *key, int len);
+void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len);
static rc4_t *rc4 = NULL;
+void rc4_key(rc4_t *r, unsigned char *key, int len)
+{
+ int t;
+
+ for(r->i = 0; r->i < 256; r->i++)
+ r->s[r->i] = r->i;
+
+ r->j = 0;
+ for(r->i = 0; r->i < 256; r->i++)
+ {
+ r->j = (r->j + r->s[r->i] + key[r->i % len]) % 256;
+ t = r->s[r->i];
+ r->s[r->i] = r->s[r->j];
+ r->s[r->j] = t;
+ }
+ r->i = r->j = 0;
+}
+
+void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len)
+{
+ int t;
+ int c;
+
+ c = 0;
+ while(c < len)
+ {
+ r->i = (r->i + 1) % 256;
+ r->j = (r->j + r->s[r->i]) % 256;
+ t = r->s[r->i];
+ r->s[r->i] = r->s[r->j];
+ r->s[r->j] = t;
+
+ t = (r->s[r->i] + r->s[r->j]) % 256;
+
+ buffer[c] = r->s[t];
+ c++;
+ }
+}
+
unsigned int arc4random(void)
{
unsigned int r;
@@ -117,7 +164,8 @@ void get_random_bytes(unsigned char *buf, int len)
/* Send blocking read request to EGD */
egd_message[1] = len;
- c = write(random_pool, egd_message, sizeof(egd_message));
+
+ c = atomicio(write, random_pool, egd_message, sizeof(egd_message));
if (c == -1)
fatal("Couldn't write to EGD socket \"%s\": %s", RANDOM_POOL, strerror(errno));
@@ -129,15 +177,9 @@ void get_random_bytes(unsigned char *buf, int len)
#endif /* HAVE_EGD */
- do {
- c = read(random_pool, buf, len);
-
- if ((c == -1) && (errno != EINTR))
- fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
- } while (c == -1);
-
- if (c != len)
- fatal("Short read from random pool \"%s\"", RANDOM_POOL);
+ c = atomicio(read, random_pool, buf, len);
+ if (c <= 0)
+ fatal("Couldn't read from random pool \"%s\": %s", RANDOM_POOL, strerror(errno));
close(random_pool);
}