entropium.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. /**
  17. * \file entropium.c
  18. * \author Daniel Otte
  19. * \email daniel.otte@rub.de
  20. * \date 2006-05-17
  21. * \license GPLv3 or later
  22. * \brief This file contains an implementaition of a pseudo-random-number generator.
  23. *
  24. * Extension 1:
  25. * rndCore is expanded to 512 bits for more security.
  26. *
  27. \verbatim
  28. ################################################################################################
  29. # #
  30. # +---------------------------+ #
  31. # | | #
  32. # V | #
  33. # (concat) | #
  34. +---------------+ # o---------o (xor)+---------+ o---------o o----o o---------o # +--------------+
  35. | entropy Block | -----> | sha-256 | --(offset)-< | rndCore | ---> | sha-256 | --+----| +1 |---> | sha-256 | -----> | random Block |
  36. +---------------+ # o---------o (xor)+---------+ o---------o | o----o o---------o # +--------------+
  37. # (xor) (xor) | #
  38. # ^ ^ | #
  39. # \ / | #
  40. # (offset)---------------------+ #
  41. # #
  42. ################################################################################################
  43. \endverbatim
  44. */
  45. #include <inttypes.h>
  46. #include <string.h>
  47. #include <crypto/sha256.h>
  48. #include <crypto/entropium.h>
  49. #include <stdio.h>
  50. /**
  51. * \brief secret entropy pool.
  52. * This is the core of the random which is generated
  53. */
  54. static
  55. uint32_t rndCore[16];
  56. /*************************************************************************/
  57. /* idea is: hash the message and add it via xor to rndCore
  58. *
  59. * length in bits
  60. *
  61. * we simply first "hash" rndCore, then entropy.
  62. */
  63. void entropium_addEntropy(unsigned length_b, const void* data){
  64. sha256_ctx_t s;
  65. static uint8_t offset=0; /* selects if higher or lower half gets updated */
  66. sha256_init(&s);
  67. sha256_nextBlock(&s, rndCore);
  68. while (length_b>=512){
  69. sha256_nextBlock(&s, data);
  70. data = (uint8_t*)data+ 512/8;
  71. length_b -= 512;
  72. }
  73. sha256_lastBlock(&s, data, length_b);
  74. uint8_t i;
  75. for (i=0; i<8; ++i){
  76. rndCore[i+offset] ^= s.h[i];
  77. }
  78. offset ^= 8; /* hehe */
  79. }
  80. /*************************************************************************/
  81. void entropium_getRandomBlock(void *b){
  82. sha256_ctx_t s;
  83. uint8_t offset=8;
  84. sha256_init(&s);
  85. sha256_lastBlock(&s, rndCore, 512); /* remember the byte order! */
  86. uint8_t i;
  87. for (i=0; i<8; ++i){
  88. rndCore[i+offset] ^= s.h[i];
  89. }
  90. offset ^= 8; /* hehe */
  91. memcpy(b, s.h, 32); /* back up first hash in b */
  92. ((uint8_t*)b)[*((uint8_t*)b)&31]++; /* the important increment step */
  93. sha256_init(&s);
  94. sha256_lastBlock(&s, b, 256);
  95. memcpy(b, s.h, 32);
  96. }
  97. /*************************************************************************/
  98. uint8_t entropium_getRandomByte(void){
  99. static uint8_t block[32];
  100. static uint8_t i = 0;
  101. if(i == 0){
  102. entropium_getRandomBlock((void*)block);
  103. i = 32;
  104. }
  105. return block[--i];
  106. }
  107. void entropium_fillBlockRandom(void* block, unsigned length_B){
  108. while(length_B>ENTROPIUM_RANDOMBLOCK_SIZE){
  109. entropium_getRandomBlock(block);
  110. block = (uint8_t*)block + ENTROPIUM_RANDOMBLOCK_SIZE;
  111. length_B -= ENTROPIUM_RANDOMBLOCK_SIZE;
  112. }
  113. while(length_B){
  114. *((uint8_t*)block) = entropium_getRandomByte();
  115. block= (uint8_t*)block +1; --length_B;
  116. }
  117. }