&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);
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;
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);
}
/**
*/
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;
* 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 */
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;
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);
}
{
#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
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. */
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;
}
ottery_fatal_error_(int error)
{
if (ottery_fatal_handler)
- ottery_fatal_handler(error);
+ ottery_fatal_handler(error);
else
- abort();
+ abort();
}
void
{
#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;
{
#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;
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;
}
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;
}
*/
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... */
/* 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. */
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);
}
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);
}
* @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)
/**
* @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
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;
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;
{
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);
{
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);