]> git.cryptolib.org Git - avr-crypto-lib.git/blob - entropium.c
integrated automatic testing scrips (1/2)
[avr-crypto-lib.git] / entropium.c
1 /* entropium.c */
2 /*
3     This file is part of the Crypto-avr-lib/microcrypt-lib.
4     Copyright (C) 2008  Daniel Otte (daniel.otte@rub.de)
5
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.
10
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.
15
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/>.
18 */
19 /**
20  * \file        entropium.c
21  * \author      Daniel Otte
22  * \email       daniel.otte@rub.de
23  * \date        2006-05-17
24  * \par License:
25  *      GPLv3 or later
26  * \brief       This file contains an implementaition of a pseudo-random-number generator.
27  * 
28  * Extension 1:
29  *      rndCore is expanded to 512 bits for more security.
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  /* \verbatim
51  *                      ################################################################################################
52  *                      #                                                                                              #
53  *                      #         +---------------------------+                                                        #
54  *                      #         |                           |                             +---+                      #
55  *                      #         V                           |                             |   |                      #
56  *                      #      (concat)                       |                             |   V                      #
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   #    +--------------+
60  *                      #                                 (xor) (xor)                    |                             #
61  *                      #                                   ^     ^                      |                             #
62  *                      #                                    \   /                       |                             #
63  *                      #                                   (offset)---------------------+                             #
64  *                      #                                                                                              #
65  *                      ################################################################################################
66  * \endverbatim
67  */
68
69 #include <stdint.h>
70 #include <string.h>
71 #include "sha256.h"
72 #include "entropium.h"
73
74 /**
75  * \brief secret entropy pool. 
76  * This is the core of the random which is generated
77  */
78 uint32_t rndCore[16]; 
79
80 /*************************************************************************/
81
82 /**
83  * \brief This function adds entropy to the central entropy pool
84  * 
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
87 */
88 /* idea is: hash the message and add it via xor to rndCore
89  *
90  * length in bits 
91  * 
92  * we simply first "hash" rndCore, then entropy.
93  */
94 void entropium_addEntropy(unsigned length_b, const void* data){
95         sha256_ctx_t s;
96         static uint8_t offset=0; /* selects if higher or lower half gets updated */
97         sha256_init(&s);
98         sha256_nextBlock(&s, rndCore);
99         while (length_b>=512){
100                 sha256_nextBlock(&s, data);
101                 data = (uint8_t*)data+ 512/8;
102                 length_b -= 512;        
103         }
104         sha256_lastBlock(&s, data, length_b);
105         uint8_t i;
106         for (i=0; i<8; ++i){
107                 rndCore[i+offset] ^= s.h[i];
108         }
109         offset ^= 8; /* hehe */
110 }
111
112 /*************************************************************************/
113 /**
114  * \brief This function fills a given buffer with 32 random bytes
115  * @param b Pointer to buffer wich is to fill
116  */
117 void entropium_getRandomBlock(void *b){
118         sha256_ctx_t s;
119         uint8_t offset=8;
120         
121         sha256_init(&s);
122         sha256_lastBlock(&s, rndCore, 512); /* remeber the byte order! */
123         uint8_t i;
124         for (i=0; i<8; ++i){
125                 rndCore[i+offset] ^= s.h[i];
126         }
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 */
130         sha256_init(&s);
131         sha256_lastBlock(&s, b, 256);
132         memcpy(b, s.h, 32);
133 }
134
135 /*************************************************************************/
136  
137 /**
138  * \brief This function simply returns a random byte
139  * @return a random byte
140  */
141 uint8_t entropium_getRandomByte(void){
142         static uint8_t block[32];
143         static uint8_t i=32;
144         
145         if (i==32){
146                 entropium_getRandomBlock((void*)block);
147                 i=0;
148         }       
149         return block[i++];
150 }
151
152 /*************************************************************************/
153  
154 /**
155  * \brief This function fills the given bock with length random bytes
156  * @return a random byte
157  */
158  
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;
164         }
165         while(length_B){
166                 *((uint8_t*)block) = entropium_getRandomByte();
167                 block= (uint8_t*)block +1; --length_B;
168         }
169 }
170  
171