X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/1647c2b5862cb00d0cbc9f48bdb3c076be6671bf..5c305c899bb2ae2ee614b054798047200a0943d4:/helper.c diff --git a/helper.c b/helper.c index 91a78b57..bf4e145b 100644 --- a/helper.c +++ b/helper.c @@ -45,7 +45,6 @@ #include #include -#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); }