]> git.cryptolib.org Git - arm-crypto-lib.git/blob - entropium/entropium.c
45ef61912a71b5f59714842a3982e1404f60bf1c
[arm-crypto-lib.git] / entropium / entropium.c
1 /* entropium.c */
2 /*
3     This file is part of the ARM-Crypto-Lib.
4     Copyright (C) 2006-2010  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  * \license     GPLv3 or later
25  * \brief       This file contains an implementaition of a pseudo-random-number generator.
26  * 
27  * Extension 1:
28  *      rndCore is expanded to 512 bits for more security.
29  *
30   \verbatim
31                        ################################################################################################
32                        #                                                                                              #
33                        #         +---------------------------+                                                        #
34                        #         |                           |                                                        #
35                        #         V                           |                                                        #
36                        #      (concat)                       |                                                        #
37    +---------------+   #    o---------o             (xor)+---------+      o---------o        o----o     o---------o   #    +--------------+
38    | entropy Block | -----> | sha-256 | --(offset)-<     | rndCore | ---> | sha-256 | --+----| +1 |---> | sha-256 | -----> | random Block |
39    +---------------+   #    o---------o             (xor)+---------+      o---------o   |    o----o     o---------o   #    +--------------+
40                        #                                 (xor) (xor)                    |                             #
41                        #                                   ^     ^                      |                             #
42                        #                                    \   /                       |                             #
43                        #                                   (offset)---------------------+                             #
44                        #                                                                                              #
45                        ################################################################################################
46   \endverbatim
47  */
48
49 #include <inttypes.h>
50 #include <string.h>
51 #include "sha256.h"
52 #include "entropium.h"
53
54 #include <stdio.h>
55
56 /**
57  * \brief secret entropy pool. 
58  * This is the core of the random which is generated
59  */
60 static
61 uint32_t rndCore[16]; 
62
63 /*************************************************************************/
64
65 /* idea is: hash the message and add it via xor to rndCore
66  *
67  * length in bits 
68  * 
69  * we simply first "hash" rndCore, then entropy.
70  */
71 void entropium_addEntropy(unsigned length_b, const void* data){
72         sha256_ctx_t s;
73         static uint8_t offset=0; /* selects if higher or lower half gets updated */
74         sha256_init(&s);
75         sha256_nextBlock(&s, rndCore);
76         while (length_b>=512){
77                 sha256_nextBlock(&s, data);
78                 data = (uint8_t*)data+ 512/8;
79                 length_b -= 512;        
80         }
81         sha256_lastBlock(&s, data, length_b);
82         uint8_t i;
83         for (i=0; i<8; ++i){
84                 rndCore[i+offset] ^= s.h[i];
85         }
86         offset ^= 8; /* hehe */
87 }
88
89 /*************************************************************************/
90
91 void entropium_getRandomBlock(void *b){
92         sha256_ctx_t s;
93         uint8_t offset=8;
94         
95         sha256_init(&s);
96         sha256_lastBlock(&s, rndCore, 512); /* remember the byte order! */
97         uint8_t i;
98         for (i=0; i<8; ++i){
99                 rndCore[i+offset] ^= s.h[i];
100         }
101         offset ^= 8; /* hehe */
102         memcpy(b, s.h, 32); /* back up first hash in b */
103         ((uint8_t*)b)[*((uint8_t*)b)&31]++;     /* the important increment step */
104         sha256_init(&s);
105         sha256_lastBlock(&s, b, 256);
106         memcpy(b, s.h, 32);
107 }
108
109 /*************************************************************************/
110
111
112 uint8_t entropium_getRandomByte(void){
113     static uint8_t block[32];
114     static uint8_t i = 0;
115
116         if(i == 0){
117                 entropium_getRandomBlock((void*)block);
118                 i = 32;
119         }       
120         return block[--i];
121 }
122
123 void entropium_fillBlockRandom(void* block, unsigned length_B){
124         while(length_B>ENTROPIUM_RANDOMBLOCK_SIZE){
125                 entropium_getRandomBlock(block);
126                 block = (uint8_t*)block + ENTROPIUM_RANDOMBLOCK_SIZE;
127                 length_B -= ENTROPIUM_RANDOMBLOCK_SIZE;
128         }
129         while(length_B){
130                 *((uint8_t*)block) = entropium_getRandomByte();
131                 block= (uint8_t*)block +1; --length_B;
132         }
133 }
134  
135