aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-10-15 12:38:41 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-10-15 12:38:41 +0100
commit572f8723c85c2b5100fc76269f8b0f7ecb80c399 (patch)
tree36098d1ca96f351accb1793ccaf617780afaa5ed
parentb8bc9298b16c3b73aead0b15fa60cf061168a8a2 (diff)
downloadrspamd-572f8723c85c2b5100fc76269f8b0f7ecb80c399.tar.gz
rspamd-572f8723c85c2b5100fc76269f8b0f7ecb80c399.zip
Use cryptobox chacha for libottery.
-rw-r--r--contrib/blake2/CMakeLists.txt2
-rw-r--r--contrib/http-parser/CMakeLists.txt5
-rw-r--r--contrib/libottery/CMakeLists.txt9
-rw-r--r--contrib/libottery/chacha_cryptobox.c64
-rw-r--r--contrib/libottery/ottery-internal.h8
-rw-r--r--contrib/libottery/ottery-threading.h5
-rw-r--r--contrib/libottery/ottery.c321
-rw-r--r--src/libutil/util.c2
8 files changed, 250 insertions, 166 deletions
diff --git a/contrib/blake2/CMakeLists.txt b/contrib/blake2/CMakeLists.txt
index 76ea48591..02affd190 100644
--- a/contrib/blake2/CMakeLists.txt
+++ b/contrib/blake2/CMakeLists.txt
@@ -3,5 +3,5 @@ cmake_minimum_required(VERSION 2.6)
set(BLAKE_SRC blake2b-ref.c)
add_library(blake2 STATIC "${BLAKE_SRC}")
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
- set_target_properties(blake2 PROPERTIES COMPILER_FLAGS "-O3")
+ set_target_properties(blake2 PROPERTIES COMPILE_FLAGS "-O3")
endif ()
diff --git a/contrib/http-parser/CMakeLists.txt b/contrib/http-parser/CMakeLists.txt
index ac870d9c4..d54646e55 100644
--- a/contrib/http-parser/CMakeLists.txt
+++ b/contrib/http-parser/CMakeLists.txt
@@ -1,9 +1,10 @@
SET(HTTPSRC http_parser.c)
+SET(HTTP_COMPILE_FLAGS "-DRSPAMD_LIB")
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
+ set(HTTP_COMPILE_FLAGS "${HTTP_COMPILE_FLAGS} -O3")
endif ()
ADD_LIBRARY(rspamd-http-parser STATIC ${HTTPSRC})
SET_TARGET_PROPERTIES(rspamd-http-parser PROPERTIES VERSION ${RSPAMD_VERSION})
-SET_TARGET_PROPERTIES(rspamd-http-parser PROPERTIES COMPILE_FLAGS "-DRSPAMD_LIB") \ No newline at end of file
+SET_TARGET_PROPERTIES(rspamd-http-parser PROPERTIES COMPILE_FLAGS "${HTTP_COMPILE_FLAGS}") \ No newline at end of file
diff --git a/contrib/libottery/CMakeLists.txt b/contrib/libottery/CMakeLists.txt
index a2b3d8c0a..3ea5658f3 100644
--- a/contrib/libottery/CMakeLists.txt
+++ b/contrib/libottery/CMakeLists.txt
@@ -2,8 +2,11 @@ SET(OTTERYSRC chacha_merged.c
ottery.c
ottery_cpuinfo.c
ottery_entropy.c
- ottery_global.c)
+ ottery_global.c chacha_cryptobox.c)
ADD_LIBRARY(ottery STATIC ${OTTERYSRC})
+
+SET(OTTERY_CFLAGS "-DBUILD_RSPAMD")
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
- set_target_properties(ottery PROPERTIES COMPILER_FLAGS "-O3")
-endif () \ No newline at end of file
+ SET(OTTERY_CFLAGS "${OTTERY_CFLAGS} -O3")
+endif ()
+set_target_properties(ottery PROPERTIES COMPILE_FLAGS "${OTTERY_CFLAGS}") \ No newline at end of file
diff --git a/contrib/libottery/chacha_cryptobox.c b/contrib/libottery/chacha_cryptobox.c
new file mode 100644
index 000000000..ecbcccaf3
--- /dev/null
+++ b/contrib/libottery/chacha_cryptobox.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015, Vsevolod Stakhov
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ottery-internal.h"
+#include "libcryptobox/chacha20/chacha.h"
+
+#define STATE_LEN (sizeof(chacha_state))
+#define STATE_BYTES 40
+
+#define IDX_STEP 16
+#define OUTPUT_LEN (IDX_STEP * 64)
+
+static void
+chacha_cryptobox_state_setup (void *state_, const uint8_t *bytes)
+{
+ chacha_state *x = state_;
+ chacha_init (x, (chacha_key *)bytes, (chacha_iv *)(bytes + 32), 20);
+}
+
+static void
+chacha20_cryptobox_generate (void *state_, uint8_t *output, uint32_t idx)
+{
+ chacha_state *x = state_;
+
+ memset (output, 0, OUTPUT_LEN);
+ memcpy (output, &idx, sizeof (idx));
+ chacha_update (x, output, output, OUTPUT_LEN);
+}
+
+#define PRF_CHACHA(r) { \
+ "CHACHA" #r, \
+ "CHACHA" #r "-NOSIMD", \
+ "CHACHA" #r "-NOSIMD-DEFAULT", \
+ STATE_LEN, \
+ STATE_BYTES, \
+ OUTPUT_LEN, \
+ 0, \
+ chacha_cryptobox_state_setup, \
+ chacha ## r ## _cryptobox_generate \
+}
+
+const struct ottery_prf ottery_prf_chacha20_cryptobox_ = PRF_CHACHA(20);
diff --git a/contrib/libottery/ottery-internal.h b/contrib/libottery/ottery-internal.h
index 24279043e..145c5e4a9 100644
--- a/contrib/libottery/ottery-internal.h
+++ b/contrib/libottery/ottery-internal.h
@@ -15,7 +15,11 @@
#define OTTERY_INTERNAL_H_HEADER_INCLUDED_
#include <stdint.h>
#include <sys/types.h>
+
+#ifdef BUILD_RSPAMD
#include "config.h"
+#endif
+
#include "ottery-threading.h"
@@ -300,6 +304,10 @@ void ottery_disable_cpu_capabilities_(uint32_t disable);
extern const struct ottery_prf ottery_prf_chacha8_merged_;
extern const struct ottery_prf ottery_prf_chacha12_merged_;
extern const struct ottery_prf ottery_prf_chacha20_merged_;
+
+#ifdef BUILD_RSPAMD
+extern const struct ottery_prf ottery_prf_chacha20_cryptobox_;
+#endif
/**@}*/
/**
diff --git a/contrib/libottery/ottery-threading.h b/contrib/libottery/ottery-threading.h
index 383d9cd83..c5427adae 100644
--- a/contrib/libottery/ottery-threading.h
+++ b/contrib/libottery/ottery-threading.h
@@ -14,6 +14,11 @@
#ifndef OTTERY_LOCKING_H_HEADER_INCLUDED_
#define OTTERY_LOCKING_H_HEADER_INCLUDED_
+/* We don't need locks when building rspamd */
+#ifdef BUILD_RSPAMD
+#define OTTERY_NO_LOCKS
+#endif
+
/* Locks */
#ifdef OTTERY_NO_LOCKS
/* Nothing here. */
diff --git a/contrib/libottery/ottery.c b/contrib/libottery/ottery.c
index fd20b1132..0b466c641 100644
--- a/contrib/libottery/ottery.c
+++ b/contrib/libottery/ottery.c
@@ -183,59 +183,62 @@ ottery_get_impl(const char *impl)
&ottery_prf_chacha12_krovetz_1_,
&ottery_prf_chacha8_krovetz_1_,
#endif
- &ottery_prf_chacha20_merged_,
- &ottery_prf_chacha12_merged_,
- &ottery_prf_chacha8_merged_,
+#ifdef BUILD_RSPAMD
+ &ottery_prf_chacha20_cryptobox_,
+#endif
+ &ottery_prf_chacha20_merged_,
+ &ottery_prf_chacha12_merged_,
+ &ottery_prf_chacha8_merged_,
- NULL,
+ NULL,
};
const uint32_t cap = ottery_get_cpu_capabilities_();
for (i = 0; ALL_PRFS[i]; ++i) {
- const struct ottery_prf *prf = ALL_PRFS[i];
- if ((prf->required_cpucap & cap) != prf->required_cpucap)
- continue;
- if (impl == NULL)
- return prf;
- if (!strcmp(impl, prf->name))
- return prf;
- if (!strcmp(impl, prf->impl))
- return prf;
- if (!strcmp(impl, prf->flav))
- return prf;
+ const struct ottery_prf *prf = ALL_PRFS[i];
+ if ((prf->required_cpucap & cap) != prf->required_cpucap)
+ continue;
+ if (impl == NULL)
+ return prf;
+ if (!strcmp(impl, prf->name))
+ return prf;
+ if (!strcmp(impl, prf->impl))
+ return prf;
+ if (!strcmp(impl, prf->flav))
+ return prf;
}
return NULL;
}
int
ottery_config_force_implementation(struct ottery_config *cfg,
- const char *impl)
+ const char *impl)
{
const struct ottery_prf *prf = ottery_get_impl(impl);
if (prf) {
- cfg->impl = prf;
- return 0;
+ cfg->impl = prf;
+ return 0;
}
return OTTERY_ERR_INVALID_ARGUMENT;
}
void
ottery_config_set_manual_prf_(struct ottery_config *cfg,
- const struct ottery_prf *prf)
+ const struct ottery_prf *prf)
{
cfg->impl = prf;
}
void
ottery_config_set_urandom_device(struct ottery_config *cfg,
- const char *fname)
+ const char *fname)
{
cfg->entropy_config.urandom_fname = fname;
}
void
ottery_config_set_urandom_fd(struct ottery_config *cfg,
- int fd)
+ int fd)
{
cfg->entropy_config.urandom_fd = fd;
cfg->entropy_config.urandom_fd_is_set = (fd >= 0);
@@ -243,8 +246,8 @@ ottery_config_set_urandom_fd(struct ottery_config *cfg,
void
ottery_config_set_egd_socket(struct ottery_config *cfg,
- const struct sockaddr *addr,
- int len)
+ const struct sockaddr *addr,
+ int len)
{
cfg->entropy_config.egd_sockaddr = addr;
cfg->entropy_config.egd_socklen = len;
@@ -252,18 +255,18 @@ ottery_config_set_egd_socket(struct ottery_config *cfg,
void
ottery_config_disable_entropy_sources(struct ottery_config *cfg,
- uint32_t disabled_sources)
+ uint32_t disabled_sources)
{
cfg->entropy_config.disabled_sources =
- (disabled_sources & OTTERY_ENTROPY_ALL_SOURCES);
+ (disabled_sources & OTTERY_ENTROPY_ALL_SOURCES);
}
void
ottery_config_mark_entropy_sources_weak(struct ottery_config *cfg,
- uint32_t disabled_sources)
+ uint32_t disabled_sources)
{
cfg->entropy_config.weak_sources =
- (disabled_sources & OTTERY_ENTROPY_ALL_SOURCES);
+ (disabled_sources & OTTERY_ENTROPY_ALL_SOURCES);
}
/**
@@ -307,8 +310,8 @@ ottery_st_nextblock_nolock(struct ottery_state_nolock *st)
*/
static int
ottery_st_initialize(struct ottery_state *st,
- const struct ottery_config *config,
- int locked)
+ const struct ottery_config *config,
+ int locked)
{
const struct ottery_prf *prf = NULL;
struct ottery_config cfg_tmp;
@@ -317,46 +320,46 @@ ottery_st_initialize(struct ottery_state *st,
* error now, and not a crash when the SIMD instructions start to fail.
*/
if (((uintptr_t)st) & 0xf)
- return OTTERY_ERR_STATE_ALIGNMENT;
+ return OTTERY_ERR_STATE_ALIGNMENT;
if (!config) {
- ottery_config_init(&cfg_tmp);
- config = &cfg_tmp;
+ ottery_config_init(&cfg_tmp);
+ config = &cfg_tmp;
}
prf = config->impl;
if (!prf)
- prf = ottery_get_impl(NULL);
+ prf = ottery_get_impl(NULL);
memset(st, 0, sizeof(*st));
if (locked) {
- /* Now set up the spinlock or mutex or hybrid thing. */
- if (INIT_LOCK(&st->mutex))
- return OTTERY_ERR_LOCK_INIT;
+ /* Now set up the spinlock or mutex or hybrid thing. */
+ if (INIT_LOCK(&st->mutex))
+ return OTTERY_ERR_LOCK_INIT;
}
/* Check invariants for PRF, in case we wrote some bad code. */
if ((prf->state_len > MAX_STATE_LEN) ||
- (prf->state_bytes > MAX_STATE_BYTES) ||
- (prf->state_bytes > prf->output_len) ||
- (prf->output_len > MAX_OUTPUT_LEN))
- return OTTERY_ERR_INTERNAL;
+ (prf->state_bytes > MAX_STATE_BYTES) ||
+ (prf->state_bytes > prf->output_len) ||
+ (prf->output_len > MAX_OUTPUT_LEN))
+ return OTTERY_ERR_INTERNAL;
/* Check whether some of our structure size assumptions are right. */
if ((sizeof(struct ottery_state) > OTTERY_STATE_DUMMY_SIZE_) ||
- (sizeof(struct ottery_config) > OTTERY_CONFIG_DUMMY_SIZE_))
- return OTTERY_ERR_INTERNAL;
+ (sizeof(struct ottery_config) > OTTERY_CONFIG_DUMMY_SIZE_))
+ return OTTERY_ERR_INTERNAL;
memcpy(&st->entropy_config, &config->entropy_config,
- sizeof(struct ottery_entropy_config));
+ sizeof(struct ottery_entropy_config));
/* Copy the PRF into place. */
memcpy(&st->prf, prf, sizeof(*prf));
if ((err = ottery_st_reseed(st)))
- return err;
+ return err;
/* Set the magic number last, or else we might look like we succeeded
* when we didn't */
@@ -378,24 +381,24 @@ ottery_st_reseed(struct ottery_state *st)
size_t buflen = ottery_get_entropy_bufsize_(st->prf.state_bytes);
uint8_t *buf = alloca(buflen);
if (!buf)
- return OTTERY_ERR_INIT_STRONG_RNG;
+ return OTTERY_ERR_INIT_STRONG_RNG;
if ((err = ottery_get_entropy_(&st->entropy_config, &st->entropy_state, 0,
- buf, st->prf.state_bytes,
- &buflen,
- &flags)))
- return err;
+ buf, st->prf.state_bytes,
+ &buflen,
+ &flags)))
+ return err;
if (buflen < st->prf.state_bytes)
- return OTTERY_ERR_ACCESS_STRONG_RNG;
+ return OTTERY_ERR_ACCESS_STRONG_RNG;
/* The first state_bytes bytes become the initial key. */
st->prf.setup(st->state, buf);
/* If there are more bytes, we mix them into the key with add_seed */
if (buflen > st->prf.state_bytes)
- ottery_st_add_seed_impl(st,
- buf + st->prf.state_bytes,
- buflen - st->prf.state_bytes,
- 0,
- 0);
+ ottery_st_add_seed_impl(st,
+ buf + st->prf.state_bytes,
+ buflen - st->prf.state_bytes,
+ 0,
+ 0);
ottery_memclear_(buf, buflen);
st->last_entropy_flags = flags;
st->entropy_src_flags = flags;
@@ -415,7 +418,7 @@ ottery_st_init(struct ottery_state *st, const struct ottery_config *cfg)
int
ottery_st_init_nolock(struct ottery_state_nolock *st,
- const struct ottery_config *cfg)
+ const struct ottery_config *cfg)
{
return ottery_st_initialize(st, cfg, 0);
}
@@ -425,8 +428,8 @@ ottery_st_add_seed_impl(struct ottery_state *st, const uint8_t *seed, size_t n,
{
#ifndef OTTERY_NO_INIT_CHECK
if (check_magic && UNLIKELY(st->magic != MAGIC(st))) {
- ottery_fatal_error_(OTTERY_ERR_STATE_INIT);
- return OTTERY_ERR_STATE_INIT;
+ ottery_fatal_error_(OTTERY_ERR_STATE_INIT);
+ return OTTERY_ERR_STATE_INIT;
}
#endif
@@ -437,40 +440,40 @@ ottery_st_add_seed_impl(struct ottery_state *st, const uint8_t *seed, size_t n,
uint32_t flags = 0;
if (!seed || !n) {
- int err;
- tmp_seed_len = ottery_get_entropy_bufsize_(st->prf.state_bytes);
- tmp_seed = alloca(tmp_seed_len);
- if (!tmp_seed)
- return OTTERY_ERR_INIT_STRONG_RNG;
- n = tmp_seed_len;
- if ((err = ottery_get_entropy_(&st->entropy_config, &st->entropy_state, 0,
- tmp_seed, st->prf.state_bytes,
- &n,
- &flags)))
- return err;
- if (n < st->prf.state_bytes)
- return OTTERY_ERR_ACCESS_STRONG_RNG;
- seed = tmp_seed;
+ int err;
+ tmp_seed_len = ottery_get_entropy_bufsize_(st->prf.state_bytes);
+ tmp_seed = alloca(tmp_seed_len);
+ if (!tmp_seed)
+ return OTTERY_ERR_INIT_STRONG_RNG;
+ n = tmp_seed_len;
+ if ((err = ottery_get_entropy_(&st->entropy_config, &st->entropy_state, 0,
+ tmp_seed, st->prf.state_bytes,
+ &n,
+ &flags)))
+ return err;
+ if (n < st->prf.state_bytes)
+ return OTTERY_ERR_ACCESS_STRONG_RNG;
+ seed = tmp_seed;
}
if (locking)
- LOCK(st);
+ LOCK(st);
/* The algorithm here is really easy. We grab a block of output from the
* PRNG, that the first (state_bytes) bytes of that, XOR it with up to
* (state_bytes) bytes of our new seed data, and use that to set our new
* state. We do this over and over until we have no more seed data to add.
*/
while (n) {
- unsigned i;
- size_t m = n > st->prf.state_bytes/2 ? st->prf.state_bytes/2 : n;
- ottery_st_nextblock_nolock_norekey(st);
- for (i = 0; i < m; ++i) {
- st->buffer[i] ^= seed[i];
- }
- st->prf.setup(st->state, st->buffer);
- st->block_counter = 0;
- n -= m;
- seed += m;
+ unsigned i;
+ size_t m = n > st->prf.state_bytes/2 ? st->prf.state_bytes/2 : n;
+ ottery_st_nextblock_nolock_norekey(st);
+ for (i = 0; i < m; ++i) {
+ st->buffer[i] ^= seed[i];
+ }
+ st->prf.setup(st->state, st->buffer);
+ st->block_counter = 0;
+ n -= m;
+ seed += m;
}
/* Now make sure that st->buffer is set up with the new state. */
@@ -480,11 +483,11 @@ ottery_st_add_seed_impl(struct ottery_state *st, const uint8_t *seed, size_t n,
st->last_entropy_flags = flags;
if (locking)
- UNLOCK(st);
+ UNLOCK(st);
/* If we used stack-allocated seed material, wipe it. */
if (tmp_seed)
- ottery_memclear_(tmp_seed, tmp_seed_len);
+ ottery_memclear_(tmp_seed, tmp_seed_len);
return 0;
}
@@ -541,9 +544,9 @@ void
ottery_fatal_error_(int error)
{
if (ottery_fatal_handler)
- ottery_fatal_handler(error);
+ ottery_fatal_handler(error);
else
- abort();
+ abort();
}
void
@@ -561,8 +564,8 @@ ottery_st_rand_check_init(struct ottery_state *st)
{
#ifndef OTTERY_NO_INIT_CHECK
if (UNLIKELY(st->magic != MAGIC(st))) {
- ottery_fatal_error_(OTTERY_ERR_STATE_INIT);
- return -1;
+ ottery_fatal_error_(OTTERY_ERR_STATE_INIT);
+ return -1;
}
#else
(void)st;
@@ -576,12 +579,12 @@ ottery_st_rand_check_pid(struct ottery_state *st)
{
#ifndef OTTERY_NO_PID_CHECK
if (UNLIKELY(st->pid != getpid())) {
- int err;
- if ((err = ottery_st_reseed(st))) {
- ottery_fatal_error_(OTTERY_ERR_FLAG_POSTFORK_RESEED|err);
- return -1;
- }
- st->pid = getpid();
+ int err;
+ if ((err = ottery_st_reseed(st))) {
+ ottery_fatal_error_(OTTERY_ERR_FLAG_POSTFORK_RESEED|err);
+ return -1;
+ }
+ st->pid = getpid();
}
#else
(void) st;
@@ -593,11 +596,11 @@ static inline int
ottery_st_rand_lock_and_check(struct ottery_state *st)
{
if (ottery_st_rand_check_init(st))
- return -1;
+ return -1;
LOCK(st);
if (ottery_st_rand_check_pid(st)) {
- UNLOCK(st);
- return -1;
+ UNLOCK(st);
+ return -1;
}
return 0;
}
@@ -606,9 +609,9 @@ static inline int
ottery_st_rand_check_nolock(struct ottery_state_nolock *st)
{
if (ottery_st_rand_check_init(st))
- return -1;
+ return -1;
if (ottery_st_rand_check_pid(st))
- return -1;
+ return -1;
return 0;
}
@@ -624,36 +627,36 @@ ottery_st_rand_check_nolock(struct ottery_state_nolock *st)
*/
static inline void
ottery_st_rand_bytes_from_buf(struct ottery_state *st, uint8_t *out,
- size_t n)
+ size_t n)
{
if (n + st->pos < st->prf.output_len) {
- memcpy(out, st->buffer+st->pos, n);
- CLEARBUF(st->buffer+st->pos, n);
- st->pos += n;
+ memcpy(out, st->buffer+st->pos, n);
+ CLEARBUF(st->buffer+st->pos, n);
+ st->pos += n;
} else {
- unsigned cpy = st->prf.output_len - st->pos;
- memcpy(out, st->buffer+st->pos, cpy);
- n -= cpy;
- out += cpy;
- ottery_st_nextblock_nolock(st);
- memcpy(out, st->buffer+st->pos, n);
- CLEARBUF(st->buffer, n);
- st->pos += n;
- assert(st->pos < st->prf.output_len);
+ unsigned cpy = st->prf.output_len - st->pos;
+ memcpy(out, st->buffer+st->pos, cpy);
+ n -= cpy;
+ out += cpy;
+ ottery_st_nextblock_nolock(st);
+ memcpy(out, st->buffer+st->pos, n);
+ CLEARBUF(st->buffer, n);
+ st->pos += n;
+ assert(st->pos < st->prf.output_len);
}
}
static void
ottery_st_rand_bytes_impl(struct ottery_state *st, void *out_,
- size_t n)
+ size_t n)
{
uint8_t *out = out_;
size_t cpy;
if (n + st->pos < st->prf.output_len * 2 - st->prf.state_bytes - 1) {
- /* Fulfill it all from the buffer simply if possible. */
- ottery_st_rand_bytes_from_buf(st, out, n);
- return;
+ /* Fulfill it all from the buffer simply if possible. */
+ ottery_st_rand_bytes_from_buf(st, out, n);
+ return;
}
/* Okay. That's not going to happen. Well, take what we can... */
@@ -664,15 +667,15 @@ ottery_st_rand_bytes_impl(struct ottery_state *st, void *out_,
/* Then take whole blocks so long as we need them, without stirring... */
while (n >= st->prf.output_len) {
- /* (We could save a memcpy here if we generated the block directly at out
- * rather than doing the memcpy here. First we'd need to make sure that we
- * had gotten the block aligned to a 16-byte boundary, though, and we'd
- * have some other tricky bookkeeping to do. Let's call this good enough
- * for now.) */
- ottery_st_nextblock_nolock_norekey(st);
- memcpy(out, st->buffer, st->prf.output_len);
- out += st->prf.output_len;
- n -= st->prf.output_len;
+ /* (We could save a memcpy here if we generated the block directly at out
+ * rather than doing the memcpy here. First we'd need to make sure that we
+ * had gotten the block aligned to a 16-byte boundary, though, and we'd
+ * have some other tricky bookkeeping to do. Let's call this good enough
+ * for now.) */
+ ottery_st_nextblock_nolock_norekey(st);
+ memcpy(out, st->buffer, st->prf.output_len);
+ out += st->prf.output_len;
+ n -= st->prf.output_len;
}
/* Then stir for the last part. */
@@ -684,7 +687,7 @@ void
ottery_st_rand_bytes(struct ottery_state *st, void *out_, size_t n)
{
if (ottery_st_rand_lock_and_check(st))
- return;
+ return;
ottery_st_rand_bytes_impl(st, out_, n);
UNLOCK(st);
}
@@ -693,7 +696,7 @@ void
ottery_st_rand_bytes_nolock(struct ottery_state_nolock *st, void *out_, size_t n)
{
if (ottery_st_rand_check_nolock(st))
- return;
+ return;
ottery_st_rand_bytes_impl(st, out_, n);
}
@@ -705,7 +708,7 @@ ottery_st_rand_bytes_nolock(struct ottery_state_nolock *st, void *out_, size_t n
* @param p a pointer to the bytes to read from.
**/
#define INT_ASSIGN_PTR(type, r, p) do { \
- memcpy(&r, p, sizeof(type)); \
+ memcpy(&r, p, sizeof(type)); \
} while (0)
/**
@@ -715,38 +718,38 @@ ottery_st_rand_bytes_nolock(struct ottery_state_nolock *st, void *out_, size_t n
* @param inttype The type of integer to generate.
**/
#define OTTERY_RETURN_RAND_INTTYPE_IMPL(st, inttype, unlock) do { \
- inttype result; \
- if (sizeof(inttype) + (st)->pos <= (st)->prf.output_len) { \
- INT_ASSIGN_PTR(inttype, result, (st)->buffer + (st)->pos); \
- CLEARBUF((st)->buffer + (st)->pos, sizeof(inttype)); \
- (st)->pos += sizeof(inttype); \
- if (st->pos == (st)->prf.output_len) { \
- ottery_st_nextblock_nolock(st); \
- } \
- } else { \
- /* Our handling of this case here is significantly simpler */ \
- /* than that of ottery_st_rand_bytes_from_buf, at the expense */ \
- /* of wasting up to sizeof(inttype)-1 bytes. Since inttype */ \
- /* is at most 8 bytes long, that's not such a big deal. */ \
- ottery_st_nextblock_nolock(st); \
- INT_ASSIGN_PTR(inttype, result, (st)->buffer + (st)->pos); \
- CLEARBUF((st)->buffer, sizeof(inttype)); \
- (st)->pos += sizeof(inttype); \
- } \
- unlock; \
- return result; \
+ inttype result; \
+ if (sizeof(inttype) + (st)->pos <= (st)->prf.output_len) { \
+ INT_ASSIGN_PTR(inttype, result, (st)->buffer + (st)->pos); \
+ CLEARBUF((st)->buffer + (st)->pos, sizeof(inttype)); \
+ (st)->pos += sizeof(inttype); \
+ if (st->pos == (st)->prf.output_len) { \
+ ottery_st_nextblock_nolock(st); \
+ } \
+ } else { \
+ /* Our handling of this case here is significantly simpler */ \
+ /* than that of ottery_st_rand_bytes_from_buf, at the expense */ \
+ /* of wasting up to sizeof(inttype)-1 bytes. Since inttype */ \
+ /* is at most 8 bytes long, that's not such a big deal. */ \
+ ottery_st_nextblock_nolock(st); \
+ INT_ASSIGN_PTR(inttype, result, (st)->buffer + (st)->pos); \
+ CLEARBUF((st)->buffer, sizeof(inttype)); \
+ (st)->pos += sizeof(inttype); \
+ } \
+ unlock; \
+ return result; \
} while (0)
#define OTTERY_RETURN_RAND_INTTYPE(st, inttype) do { \
- if (ottery_st_rand_lock_and_check(st)) \
- return (inttype)0; \
- OTTERY_RETURN_RAND_INTTYPE_IMPL(st, inttype, UNLOCK(st)); \
+ if (ottery_st_rand_lock_and_check(st)) \
+ return (inttype)0; \
+ OTTERY_RETURN_RAND_INTTYPE_IMPL(st, inttype, UNLOCK(st)); \
} while (0)
#define OTTERY_RETURN_RAND_INTTYPE_NOLOCK(st, inttype) do { \
- if (ottery_st_rand_check_nolock(st)) \
- return (inttype)0; \
- OTTERY_RETURN_RAND_INTTYPE_IMPL(st, inttype, ); \
+ if (ottery_st_rand_check_nolock(st)) \
+ return (inttype)0; \
+ OTTERY_RETURN_RAND_INTTYPE_IMPL(st, inttype, ); \
} while (0)
unsigned
@@ -792,7 +795,7 @@ ottery_st_rand_range_nolock(struct ottery_state_nolock *st, unsigned upper)
unsigned divisor = lim ? (UINT_MAX / lim) : 1;
unsigned n;
do {
- n = (ottery_st_rand_unsigned_nolock(st) / divisor);
+ n = (ottery_st_rand_unsigned_nolock(st) / divisor);
} while (n > upper);
return n;
@@ -805,7 +808,7 @@ ottery_st_rand_range64_nolock(struct ottery_state_nolock *st, uint64_t upper)
uint64_t divisor = lim ? (UINT64_MAX / lim) : 1;
uint64_t n;
do {
- n = (ottery_st_rand_uint64_nolock(st) / divisor);
+ n = (ottery_st_rand_uint64_nolock(st) / divisor);
} while (n > upper);
return n;
@@ -816,7 +819,7 @@ ottery_st_rand_range(struct ottery_state *state, unsigned upper)
{
unsigned n;
if (ottery_st_rand_check_init(state))
- return 0;
+ return 0;
LOCK(state);
n = ottery_st_rand_range_nolock(state, upper);
UNLOCK(state);
@@ -828,7 +831,7 @@ ottery_st_rand_range64(struct ottery_state *state, uint64_t upper)
{
uint64_t n;
if (ottery_st_rand_check_init(state))
- return 0;
+ return 0;
LOCK(state);
n = ottery_st_rand_range64_nolock(state, upper);
UNLOCK(state);
diff --git a/src/libutil/util.c b/src/libutil/util.c
index 5e8951f65..66322fc6d 100644
--- a/src/libutil/util.c
+++ b/src/libutil/util.c
@@ -1914,9 +1914,9 @@ rspamd_init_libs (void)
{
struct rlimit rlim;
+ rspamd_cryptobox_init ();
ottery_init (NULL);
- rspamd_cryptobox_init ();
#ifdef HAVE_LOCALE_H
if (getenv ("LANG") == NULL) {
setlocale (LC_ALL, "C");