Browse Source

Use cryptobox chacha for libottery.

tags/1.0.6
Vsevolod Stakhov 8 years ago
parent
commit
572f8723c8

+ 1
- 1
contrib/blake2/CMakeLists.txt View File

@@ -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 ()

+ 3
- 2
contrib/http-parser/CMakeLists.txt View File

@@ -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")
SET_TARGET_PROPERTIES(rspamd-http-parser PROPERTIES COMPILE_FLAGS "${HTTP_COMPILE_FLAGS}")

+ 6
- 3
contrib/libottery/CMakeLists.txt View File

@@ -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 ()
SET(OTTERY_CFLAGS "${OTTERY_CFLAGS} -O3")
endif ()
set_target_properties(ottery PROPERTIES COMPILE_FLAGS "${OTTERY_CFLAGS}")

+ 64
- 0
contrib/libottery/chacha_cryptobox.c View File

@@ -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);

+ 8
- 0
contrib/libottery/ottery-internal.h View File

@@ -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
/**@}*/

/**

+ 5
- 0
contrib/libottery/ottery-threading.h View File

@@ -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. */

+ 162
- 159
contrib/libottery/ottery.c View File

@@ -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);

+ 1
- 1
src/libutil/util.c View File

@@ -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");

Loading…
Cancel
Save