]> git.cryptolib.org Git - avr-crypto-lib.git/blob - prng.c
+RC5 +size-statistics tool +small modification to nessie_bc_test (optional free(...
[avr-crypto-lib.git] / prng.c
1 /**
2  * \file                prng.c
3  * \author              Daniel Otte
4  * \date                17.05.2006
5  * \par License:
6  *      GPL
7  * \brief       This file contains an implementaition of a pseudo-random-number generator.
8  * 
9  * Extension 1:
10  *      rndCore is expanded to 512 bits for more security.
11  *
12  * \verbatim
13  *                      ################################################################################################
14  *                      #                                                                                              #
15  *                      #         +---------------------------+                                                        #
16  *                      #         |                           |                             +---+                      #
17  *                      #         V                           |                             |   |                      #
18  *                      #      (concat)                       |                             |   V                      #
19  *  +---------------+   #    o---------o             (xor)+---------+      o---------o      | o----o     o---------o   #    +--------------+
20  *  | entropy Block | -----> | sha-256 | --(offset)-<     | rndCore | ---> | sha-256 | --+--+-| +1 |---> | sha-256 | -----> | random Block |
21  *  +---------------+   #    o---------o             (xor)+---------+      o---------o   |    o----o     o---------o   #    +--------------+
22  *                      #                                 (xor) (xor)                    |                             #
23  *                      #                                   ^     ^                      |                             #
24  *                      #                                    \   /                       |                             #
25  *                      #                                   (offset)---------------------+                             #
26  *                      #                                                                                              #
27  *                      ################################################################################################
28  * \endverbatim
29  */
30
31  /* \verbatim
32  *                      ################################################################################################
33  *                      #                                                                                              #
34  *                      #         +---------------------------+                                                        #
35  *                      #         |                           |                             +---+                      #
36  *                      #         V                           |                             |   |                      #
37  *                      #      (concat)                       |                             |   V                      #
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   #    +--------------+
41  *                      #                                 (xor) (xor)                    |                             #
42  *                      #                                   ^     ^                      |                             #
43  *                      #                                    \   /                       |                             #
44  *                      #                                   (offset)---------------------+                             #
45  *                      #                                                                                              #
46  *                      ################################################################################################
47  * \endverbatim
48  */
49
50 #include <stdint.h>
51 #include <string.h>
52 #include "sha256.h"
53 #include "prng.h"
54
55 /**
56  * \brief secret entropy pool. 
57  * This is the core of the random which is generated
58  */
59 uint32_t rndCore[16]; 
60
61 /*************************************************************************/
62
63 /**
64  * \brief This function adds entropy to the central entropy pool
65  * 
66  * @param length This ist the length of the random data in BITS. 
67  * @param data This is the random data which should be added to the entropy pool
68 */
69 /* idea is: hash the message and add it via xor to rndCore
70  *
71  * length in bits 
72  * 
73  * we simply first "hash" rndCore, then entropy.
74  */
75 void addEntropy(unsigned length, void* data){
76         sha256_ctx_t s;
77         static uint8_t offset=0; /* selects if higher or lower half gets updated */
78         sha256_init(&s);
79         sha256_nextBlock(&s, rndCore);
80         while (length>=512){
81                 sha256_nextBlock(&s, data);
82                 data = (uint8_t*)data+ 512/8;
83                 length -= 512;  
84         }
85         sha256_lastBlock(&s, data, length);
86         uint8_t i;
87         for (i=0; i<8; ++i){
88                 rndCore[i+offset] ^= s.h[i];
89         }
90         offset ^= 8; /* hehe */
91 }
92
93 /*************************************************************************/
94 /**
95  * \brief This function fills a given buffer with 32 random bytes
96  * @param b Pointer to buffer wich is to fill
97  */
98 void getRandomBlock(uint32_t *b){
99         sha256_ctx_t s;
100         uint8_t offset=8;
101         
102         sha256_init(&s);
103         sha256_lastBlock(&s, rndCore, 512); /* remeber the byte order! */
104         uint8_t i;
105         for (i=0; i<8; ++i){
106                 rndCore[i+offset] ^= s.h[i];
107         }
108         offset ^= 8; /* hehe */
109         memcpy(b, s.h, 32); /* back up first hash in b */
110         ((uint8_t*)b)[*b&31]++;         /* the important increment step */
111         sha256_init(&s);
112         sha256_lastBlock(&s, b, 256);
113         memcpy(b, s.h, 32);
114 }
115
116 /*************************************************************************/
117  
118 /**
119  * \brief This function simply returns a random byte
120  * @return a random byte
121  */
122 uint8_t getRandomByte(void){
123         static uint8_t block[32];
124         static uint8_t i=32;
125         
126         if (i==32){
127                 getRandomBlock((void*)block);
128                 i=0;
129         }       
130         return block[i++];
131 }
132
133 /*************************************************************************/
134  
135 /**
136  * \brief This function fills the given bock with length random bytes
137  * @return a random byte
138  */
139  
140 void fillBlockRandom(void* block, unsigned length){
141         while(length>RANDOMBLOCK_SIZE){
142                 getRandomBlock(block);
143                 block = (uint8_t*)block + RANDOMBLOCK_SIZE;
144                 length -= RANDOMBLOCK_SIZE;
145         }
146         while(length){
147                 *((uint8_t*)block) = getRandomByte();
148                 block= (uint8_t*)block +1; --length;
149         }
150 }
151  
152