diff options
Diffstat (limited to 'helper.c')
-rw-r--r-- | helper.c | 64 |
1 files changed, 53 insertions, 11 deletions
@@ -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 | ||
59 | typedef struct | ||
60 | { | ||
61 | unsigned int s[256]; | ||
62 | int i; | ||
63 | int j; | ||
64 | } rc4_t; | ||
65 | |||
60 | void get_random_bytes(unsigned char *buf, int len); | 66 | void get_random_bytes(unsigned char *buf, int len); |
67 | void rc4_key(rc4_t *r, unsigned char *key, int len); | ||
68 | void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len); | ||
61 | 69 | ||
62 | static rc4_t *rc4 = NULL; | 70 | static rc4_t *rc4 = NULL; |
63 | 71 | ||
72 | void 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 | |||
90 | void 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 | |||
64 | unsigned int arc4random(void) | 111 | unsigned 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 | } |