3 This file is part of the Crypto-avr-lib/microcrypt-lib.
4 Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * \email daniel.otte@rub.de
26 * \brief This file contains an implementaition of a pseudo-random-number generator.
29 * rndCore is expanded to 512 bits for more security.
32 * ################################################################################################
34 * # +---------------------------+ #
38 * +---------------+ # o---------o (xor)+---------+ o---------o | o----o o---------o # +--------------+
39 * | entropy Block | -----> | sha-256 | --(offset)-< | rndCore | ---> | sha-256 | --+--+-| +1 |---> | sha-256 | -----> | random Block |
40 * +---------------+ # o---------o (xor)+---------+ o---------o | o----o o---------o # +--------------+
44 * # (offset)---------------------+ #
46 * ################################################################################################
51 * ################################################################################################
53 * # +---------------------------+ #
57 * +---------------+ # o---------o (xor)+---------+ o---------o | o----o o---------o # +--------------+
58 * | entropy Block | -----> | sha-256 | --(offset)-< | rndCore | ---> | sha-256 | --+--+-| +1 |---> | sha-256 | -----> | random Block |
59 * +---------------+ # o---------o (xor)+---------+ o---------o | o----o o---------o # +--------------+
63 * # (offset)---------------------+ #
65 * ################################################################################################
72 #include "entropium.h"
75 * \brief secret entropy pool.
76 * This is the core of the random which is generated
80 /*************************************************************************/
83 * \brief This function adds entropy to the central entropy pool
85 * @param length This ist the length of the random data in BITS.
86 * @param data This is the random data which should be added to the entropy pool
88 /* idea is: hash the message and add it via xor to rndCore
92 * we simply first "hash" rndCore, then entropy.
94 void entropium_addEntropy(unsigned length_b, const void* data){
96 static uint8_t offset=0; /* selects if higher or lower half gets updated */
98 sha256_nextBlock(&s, rndCore);
99 while (length_b>=512){
100 sha256_nextBlock(&s, data);
101 data = (uint8_t*)data+ 512/8;
104 sha256_lastBlock(&s, data, length_b);
107 rndCore[i+offset] ^= s.h[i];
109 offset ^= 8; /* hehe */
112 /*************************************************************************/
114 * \brief This function fills a given buffer with 32 random bytes
115 * @param b Pointer to buffer wich is to fill
117 void entropium_getRandomBlock(void *b){
122 sha256_lastBlock(&s, rndCore, 512); /* remeber the byte order! */
125 rndCore[i+offset] ^= s.h[i];
127 offset ^= 8; /* hehe */
128 memcpy(b, s.h, 32); /* back up first hash in b */
129 ((uint8_t*)b)[*((uint8_t*)b)&31]++; /* the important increment step */
131 sha256_lastBlock(&s, b, 256);
135 /*************************************************************************/
138 * \brief This function simply returns a random byte
139 * @return a random byte
141 uint8_t entropium_getRandomByte(void){
142 static uint8_t block[32];
146 entropium_getRandomBlock((void*)block);
152 /*************************************************************************/
155 * \brief This function fills the given bock with length random bytes
156 * @return a random byte
159 void entropium_fillBlockRandom(void* block, unsigned length_B){
160 while(length_B>ENTROPIUM_RANDOMBLOCK_SIZE){
161 entropium_getRandomBlock(block);
162 block = (uint8_t*)block + ENTROPIUM_RANDOMBLOCK_SIZE;
163 length_B -= ENTROPIUM_RANDOMBLOCK_SIZE;
166 *((uint8_t*)block) = entropium_getRandomByte();
167 block= (uint8_t*)block +1; --length_B;