From 037a0dc0835bb5a442bdcbeecdd5baed723f0b45 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 7 Dec 1999 15:38:31 +1100 Subject: - Merged more OpenBSD changes: - [atomicio.c authfd.c scp.c serverloop.c ssh.h sshconnect.c sshd.c] move atomicio into it's own file. wrap all socket write()s which were doing write(sock, buf, len) != len, with atomicio() calls. - [auth-skey.c] fd leak - [authfile.c] properly name fd variable - [channels.c] display great hatred towards strcpy - [pty.c pty.h sshd.c] use openpty() if it exists (it does on BSD4_4) - [tildexpand.c] check for ~ expansion past MAXPATHLEN - Modified helper.c to use new atomicio function. - Reformat Makefile a little - Moved RC4 routines from rc4.[ch] into helper.c - Added autoconf code to detect /dev/ptmx (Solaris) and /dev/ptc (AIX) --- helper.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 11 deletions(-) (limited to 'helper.c') diff --git a/helper.c b/helper.c index 91a78b577..bf4e145b2 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); } -- cgit v1.2.3