blob: f4179537325a2496b9f7aa804bc02072b701c54b [file] [log] [blame]
/*
* Non-physical true random number generator based on timing jitter.
*
* Copyright Stephan Mueller <smueller@chronox.de>, 2014
*
* License
* =======
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, and the entire permission notice in its entirety,
* including the disclaimer of warranties.
* 2. 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.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* ALTERNATIVELY, this product may be distributed under the terms of
* the GNU General Public License, in which case the provisions of the GPL are
* required INSTEAD OF the above restrictions. (This clause is
* necessary due to a potential bad interaction between the GPL and
* the restrictions contained in a BSD-style copyright.)
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
* WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* Modifications by the Fuchsia Authors, 2017
* =======
*
* - Remove references to jitterentropy-base-{kernel,user}.h.
* - Add __BEGIN/END_CDECLS.
* - Add #include lines for required system libraries.
* - Remove CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT flag.
* - Add jent_entropy_collector_init declaration.
* - Moved comment for jent_lfsr_var_stat from jitterentropy-base.c to here.
*/
#ifndef _JITTERENTROPY_H
#define _JITTERENTROPY_H
#include <zircon/compiler.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/types.h>
__BEGIN_CDECLS;
/* The entropy pool */
struct rand_data
{
/* all data values that are vital to maintain the security
* of the RNG are marked as SENSITIVE. A user must not
* access that information while the RNG executes its loops to
* calculate the next random value. */
uint64_t data; /* SENSITIVE Actual random number */
uint64_t old_data; /* SENSITIVE Previous random number */
uint64_t prev_time; /* SENSITIVE Previous time stamp */
#define DATA_SIZE_BITS ((sizeof(uint64_t)) * 8)
uint64_t last_delta; /* SENSITIVE stuck test */
int64_t last_delta2; /* SENSITIVE stuck test */
unsigned int osr; /* Oversample rate */
int fips_enabled; /* FIPS enabled? */
unsigned int stir:1; /* Post-processing stirring */
unsigned int disable_unbias:1; /* Deactivate Von-Neuman unbias */
#define JENT_MEMORY_BLOCKS 64
#define JENT_MEMORY_BLOCKSIZE 32
#define JENT_MEMORY_ACCESSLOOPS 128
#define JENT_MEMORY_SIZE (JENT_MEMORY_BLOCKS*JENT_MEMORY_BLOCKSIZE)
unsigned char *mem; /* Memory access location with size of
* memblocks * memblocksize */
unsigned int memlocation; /* Pointer to byte in *mem */
unsigned int memblocks; /* Number of memory blocks in *mem */
unsigned int memblocksize; /* Size of one memory block in bytes */
unsigned int memaccessloops; /* Number of memory accesses per random
* bit generation */
};
/* Flags that can be used to initialize the RNG */
#define JENT_DISABLE_STIR (1<<0) /* Disable stirring the entropy pool */
#define JENT_DISABLE_UNBIAS (1<<1) /* Disable the Von-Neuman Unbiaser */
#define JENT_DISABLE_MEMORY_ACCESS (1<<2) /* Disable memory access for more
entropy, saves MEMORY_SIZE RAM for
entropy collector */
/* -- BEGIN Main interface functions -- */
#ifndef JENT_STUCK_INIT_THRES
/*
* Per default, not more than 90% of all measurements during initialization
* are allowed to be stuck.
*
* It is allowed to change this value as required for the intended environment.
*/
#define JENT_STUCK_INIT_THRES(x) (x/10 * 9)
#endif
#ifdef JENT_PRIVATE_COMPILE
# define JENT_PRIVATE_STATIC static
#else /* JENT_PRIVATE_COMPILE */
# define JENT_PRIVATE_STATIC
#endif
/* Number of low bits of the time value that we want to consider */
/* get raw entropy */
JENT_PRIVATE_STATIC
ssize_t jent_read_entropy(struct rand_data *ec, char *data, size_t len);
/* initialize an instance of the entropy collector */
JENT_PRIVATE_STATIC
struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
unsigned int flags);
/* clearing of entropy collector */
JENT_PRIVATE_STATIC
void jent_entropy_collector_free(struct rand_data *entropy_collector);
/* initialization of entropy collector */
JENT_PRIVATE_STATIC
int jent_entropy_init(void);
/* return version number of core library */
JENT_PRIVATE_STATIC
unsigned int jent_version(void);
/* -- END of Main interface functions -- */
/* -- BEGIN error codes for init function -- */
#define ENOTIME 1 /* Timer service not available */
#define ECOARSETIME 2 /* Timer too coarse for RNG */
#define ENOMONOTONIC 3 /* Timer is not monotonic increasing */
#define EMINVARIATION 4 /* Timer variations too small for RNG */
#define EVARVAR 5 /* Timer does not produce variations of variations
(2nd derivation of time is zero) */
#define EMINVARVAR 6 /* Timer variations of variations is too small */
#define EPROGERR 7 /* Programming error */
#define ESTUCK 8 /* Too many stuck results during init. */
/* -- BEGIN statistical test functions only complied with CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT -- */
/*
* Statistical test: return the time duration for the folding operation. If
* lfsr_loops_override/mem_loops_override is non-zero, perform the given number
* of LFSR/memaccess ops. Otherwise, allow the loop count shuffling to define
* the number of LFSR/memaccess ops.
*/
JENT_PRIVATE_STATIC
uint64_t jent_lfsr_var_stat(struct rand_data *ec,
unsigned int lfsr_loops_override,
unsigned int mem_loops_override);
/* -- END of statistical test function -- */
/* -- BEGIN Zircon interface -- */
/* Initialize an entropy collector using already allocated memory. This function
* is to jent_entropy_collector_alloc as placement new is to regular new in C++.
*
* |ec| is the entropy collector to initialize. |mem| points to a block of
* |mem_size| bytes used for memory access loops (to generate CPU instruction
* time variation).
*
* The memory will be logically divided into |mem_block_count| blocks of size
* |mem_block_size|; it is an error if the product of these two values is larger
* than |mem_size|. Ideally, the mem_block_* parameters should be configured for
* each target, or at least each architecture. The entropy collector will
* perform at least |mem_loops| memory access loops to generate variations.
*
* The |stir| flag controls whether to stir a deterministic constant into the
* entropy pool, which does not destroy entropy but may whiten it.
*/
void jent_entropy_collector_init(
struct rand_data* ec, uint8_t* mem, size_t mem_size,
unsigned int mem_block_size, unsigned int mem_block_count,
unsigned int mem_loops, bool stir);
/* -- END of Zircon interface -- */
__END_CDECLS;
#endif /* _JITTERENTROPY_H */