110cb2424SMark Murray /*-
2d1b06863SMark Murray * Copyright (c) 2013-2015 Mark R V Murray
310cb2424SMark Murray * All rights reserved.
410cb2424SMark Murray *
510cb2424SMark Murray * Redistribution and use in source and binary forms, with or without
610cb2424SMark Murray * modification, are permitted provided that the following conditions
710cb2424SMark Murray * are met:
810cb2424SMark Murray * 1. Redistributions of source code must retain the above copyright
910cb2424SMark Murray * notice, this list of conditions and the following disclaimer
1010cb2424SMark Murray * in this position and unchanged.
1110cb2424SMark Murray * 2. Redistributions in binary form must reproduce the above copyright
1210cb2424SMark Murray * notice, this list of conditions and the following disclaimer in the
1310cb2424SMark Murray * documentation and/or other materials provided with the distribution.
1410cb2424SMark Murray *
1510cb2424SMark Murray * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1610cb2424SMark Murray * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1710cb2424SMark Murray * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
1810cb2424SMark Murray * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
1910cb2424SMark Murray * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2010cb2424SMark Murray * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2110cb2424SMark Murray * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2210cb2424SMark Murray * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2310cb2424SMark Murray * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2410cb2424SMark Murray * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2510cb2424SMark Murray */
2610cb2424SMark Murray
2710cb2424SMark Murray
2810cb2424SMark Murray #ifndef UNIT_TEST_H_INCLUDED
2910cb2424SMark Murray #define UNIT_TEST_H_INCLUDED
3010cb2424SMark Murray
31d1b06863SMark Murray #ifdef _KERNEL
32d1b06863SMark Murray #error "Random unit tests cannot be compiled into the kernel."
33d1b06863SMark Murray #endif
34d1b06863SMark Murray
353aa77530SMark Murray #include <sys/types.h>
363aa77530SMark Murray #include <inttypes.h>
373aa77530SMark Murray #include <stdint.h>
3810cb2424SMark Murray
39d1b06863SMark Murray #if defined(clang) && __has_builtin(__builtin_readcyclecounter)
40d1b06863SMark Murray #define rdtsc __builtin_readcyclecounter
41d1b06863SMark Murray #else /* !clang */
42d1b06863SMark Murray #if defined(__amd64__) || defined(__i386__)
43d1b06863SMark Murray static __inline uint64_t
rdtsc(void)44d1b06863SMark Murray rdtsc(void)
45d1b06863SMark Murray {
46d1b06863SMark Murray uint32_t low, high;
47d1b06863SMark Murray
48d1b06863SMark Murray __asm __volatile("rdtsc" : "=a" (low), "=d" (high));
49d1b06863SMark Murray return (low | ((uint64_t)high << 32));
50d1b06863SMark Murray }
51d1b06863SMark Murray #else /* __amd64__ || __i386__ */
52d1b06863SMark Murray #error "No rdtsc() implementation available."
53d1b06863SMark Murray #endif /* __amd64__ || __i386__ */
54d1b06863SMark Murray #endif /* !clang */
55d1b06863SMark Murray
5610cb2424SMark Murray static __inline uint64_t
get_cyclecount(void)5710cb2424SMark Murray get_cyclecount(void)
5810cb2424SMark Murray {
5910cb2424SMark Murray
60d1b06863SMark Murray return (rdtsc());
6110cb2424SMark Murray }
6210cb2424SMark Murray
63d1b06863SMark Murray #define HARVESTSIZE 2
643aa77530SMark Murray #define RANDOM_BLOCKSIZE 16
6510cb2424SMark Murray
6610cb2424SMark Murray enum random_entropy_source {
6710cb2424SMark Murray RANDOM_START = 0,
6810cb2424SMark Murray RANDOM_CACHED = 0,
6910cb2424SMark Murray ENTROPYSOURCE = 32
7010cb2424SMark Murray };
7110cb2424SMark Murray
7210cb2424SMark Murray struct harvest_event {
7310cb2424SMark Murray uintmax_t he_somecounter; /* fast counter for clock jitter */
74d1b06863SMark Murray uint32_t he_entropy[HARVESTSIZE];/* some harvested entropy */
75*19fa89e9SMark Murray uint8_t he_size; /* harvested entropy byte count */
76*19fa89e9SMark Murray uint8_t he_destination; /* destination pool of this entropy */
7710cb2424SMark Murray enum random_entropy_source he_source; /* origin of the entropy */
7810cb2424SMark Murray void * he_next; /* next item on the list */
7910cb2424SMark Murray };
8010cb2424SMark Murray
8110cb2424SMark Murray struct sysctl_ctx_list;
8210cb2424SMark Murray
8310cb2424SMark Murray #define CTASSERT(x) _Static_assert(x, "compile-time assertion failed")
8410cb2424SMark Murray #define KASSERT(exp,msg) do { \
8510cb2424SMark Murray if (!(exp)) { \
8610cb2424SMark Murray printf msg; \
8710cb2424SMark Murray exit(0); \
8810cb2424SMark Murray } \
8910cb2424SMark Murray } while (0)
9010cb2424SMark Murray
9110cb2424SMark Murray #endif /* UNIT_TEST_H_INCLUDED */
92