diff options
Diffstat (limited to 'helper.c')
-rw-r--r-- | helper.c | 64 |
1 files changed, 53 insertions, 11 deletions
@@ -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); } |