diff options
author | Tobias Brunner <tobias@strongswan.org> | 2013-03-26 19:25:55 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2013-06-11 11:03:11 +0200 |
commit | bed4bc1327a43f8e4c494e7fdf71680ffcaa26f1 (patch) | |
tree | 2d36c42703a5dab1e61227f8c68fa354c5a4a01d | |
parent | d1953fe403a91d6f7a08fd4cdd0b01cf7106733d (diff) | |
download | strongswan-bed4bc1327a43f8e4c494e7fdf71680ffcaa26f1.tar.bz2 strongswan-bed4bc1327a43f8e4c494e7fdf71680ffcaa26f1.tar.xz |
Randomly allocate chunk_hash() key during first use
This avoids hash flooding attacks.
-rw-r--r-- | src/libstrongswan/utils/chunk.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/src/libstrongswan/utils/chunk.c b/src/libstrongswan/utils/chunk.c index 9033cbdaf..61c7bd5a5 100644 --- a/src/libstrongswan/utils/chunk.c +++ b/src/libstrongswan/utils/chunk.c @@ -16,9 +16,12 @@ */ #include <stdio.h> +#include <sys/types.h> #include <sys/stat.h> +#include <fcntl.h> #include <unistd.h> #include <errno.h> +#include <pthread.h> #include <ctype.h> #include "chunk.h" @@ -698,15 +701,56 @@ u_int64_t chunk_mac(chunk_t chunk, u_char *key) } /** - * Key used for chunk_hash. + * Secret key allocated randomly during first use. */ static u_char key[16]; /** + * Only allocate the key once + */ +static pthread_once_t key_allocated = PTHREAD_ONCE_INIT; + +/** + * Allocate a key on first use, we do this manually to avoid dependencies on + * plugins. + */ +static void allocate_key() +{ + ssize_t len; + size_t done = 0; + int fd; + + fd = open("/dev/urandom", O_RDONLY); + if (fd >= 0) + { + while (done < sizeof(key)) + { + len = read(fd, key + done, sizeof(key) - done); + if (len < 0) + { + break; + } + done += len; + } + close(fd); + } + /* on error we use random() to generate the key (better than nothing) */ + if (done < sizeof(key)) + { + srandom(time(NULL) + getpid()); + for (; done < sizeof(key); done++) + { + key[done] = (u_char)random(); + } + } +} + +/** * Described in header. */ u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash) { + pthread_once(&key_allocated, allocate_key); /* we could use a mac of the previous hash, but this is faster */ return chunk_mac_inc(chunk, key, ((u_int64_t)hash) << 32 | hash); } @@ -716,6 +760,7 @@ u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash) */ u_int32_t chunk_hash(chunk_t chunk) { + pthread_once(&key_allocated, allocate_key); return chunk_mac(chunk, key); } |