X-Git-Url: https://git.cryptolib.org/?p=arm-crypto-lib.git;a=blobdiff_plain;f=entropium%2Fentropium.c;fp=entropium%2Fentropium.c;h=45ef61912a71b5f59714842a3982e1404f60bf1c;hp=0000000000000000000000000000000000000000;hb=2a4779378a7bf4322a0e6b2024284092135e8a3d;hpb=e69f1207a9fbd9c0f45bfdbb2d8ebe9852d95969 diff --git a/entropium/entropium.c b/entropium/entropium.c new file mode 100644 index 0000000..45ef619 --- /dev/null +++ b/entropium/entropium.c @@ -0,0 +1,135 @@ +/* entropium.c */ +/* + This file is part of the ARM-Crypto-Lib. + Copyright (C) 2006-2010 Daniel Otte (daniel.otte@rub.de) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/** + * \file entropium.c + * \author Daniel Otte + * \email daniel.otte@rub.de + * \date 2006-05-17 + * \license GPLv3 or later + * \brief This file contains an implementaition of a pseudo-random-number generator. + * + * Extension 1: + * rndCore is expanded to 512 bits for more security. + * + \verbatim + ################################################################################################ + # # + # +---------------------------+ # + # | | # + # V | # + # (concat) | # + +---------------+ # o---------o (xor)+---------+ o---------o o----o o---------o # +--------------+ + | entropy Block | -----> | sha-256 | --(offset)-< | rndCore | ---> | sha-256 | --+----| +1 |---> | sha-256 | -----> | random Block | + +---------------+ # o---------o (xor)+---------+ o---------o | o----o o---------o # +--------------+ + # (xor) (xor) | # + # ^ ^ | # + # \ / | # + # (offset)---------------------+ # + # # + ################################################################################################ + \endverbatim + */ + +#include +#include +#include "sha256.h" +#include "entropium.h" + +#include + +/** + * \brief secret entropy pool. + * This is the core of the random which is generated + */ +static +uint32_t rndCore[16]; + +/*************************************************************************/ + +/* idea is: hash the message and add it via xor to rndCore + * + * length in bits + * + * we simply first "hash" rndCore, then entropy. + */ +void entropium_addEntropy(unsigned length_b, const void* data){ + sha256_ctx_t s; + static uint8_t offset=0; /* selects if higher or lower half gets updated */ + sha256_init(&s); + sha256_nextBlock(&s, rndCore); + while (length_b>=512){ + sha256_nextBlock(&s, data); + data = (uint8_t*)data+ 512/8; + length_b -= 512; + } + sha256_lastBlock(&s, data, length_b); + uint8_t i; + for (i=0; i<8; ++i){ + rndCore[i+offset] ^= s.h[i]; + } + offset ^= 8; /* hehe */ +} + +/*************************************************************************/ + +void entropium_getRandomBlock(void *b){ + sha256_ctx_t s; + uint8_t offset=8; + + sha256_init(&s); + sha256_lastBlock(&s, rndCore, 512); /* remember the byte order! */ + uint8_t i; + for (i=0; i<8; ++i){ + rndCore[i+offset] ^= s.h[i]; + } + offset ^= 8; /* hehe */ + memcpy(b, s.h, 32); /* back up first hash in b */ + ((uint8_t*)b)[*((uint8_t*)b)&31]++; /* the important increment step */ + sha256_init(&s); + sha256_lastBlock(&s, b, 256); + memcpy(b, s.h, 32); +} + +/*************************************************************************/ + + +uint8_t entropium_getRandomByte(void){ + static uint8_t block[32]; + static uint8_t i = 0; + + if(i == 0){ + entropium_getRandomBlock((void*)block); + i = 32; + } + return block[--i]; +} + +void entropium_fillBlockRandom(void* block, unsigned length_B){ + while(length_B>ENTROPIUM_RANDOMBLOCK_SIZE){ + entropium_getRandomBlock(block); + block = (uint8_t*)block + ENTROPIUM_RANDOMBLOCK_SIZE; + length_B -= ENTROPIUM_RANDOMBLOCK_SIZE; + } + while(length_B){ + *((uint8_t*)block) = entropium_getRandomByte(); + block= (uint8_t*)block +1; --length_B; + } +} + +