yarrow.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. /* LibTomCrypt, modular cryptographic library -- Tom St Denis
  2. *
  3. * LibTomCrypt is a library that provides various cryptographic
  4. * algorithms in a highly modular and flexible manner.
  5. *
  6. * The library is free for all purposes without any express
  7. * guarantee it works.
  8. *
  9. * Tom St Denis, [email protected], http://libtomcrypt.org
  10. */
  11. #include "mycrypt.h"
  12. #ifdef YARROW
  13. const struct _prng_descriptor yarrow_desc =
  14. {
  15. "yarrow", 64,
  16. &yarrow_start,
  17. &yarrow_add_entropy,
  18. &yarrow_ready,
  19. &yarrow_read,
  20. &yarrow_done,
  21. &yarrow_export,
  22. &yarrow_import,
  23. &yarrow_test
  24. };
  25. int yarrow_start(prng_state *prng)
  26. {
  27. int err;
  28. _ARGCHK(prng != NULL);
  29. /* these are the default hash/cipher combo used */
  30. #ifdef RIJNDAEL
  31. #if YARROW_AES==0
  32. prng->yarrow.cipher = register_cipher(&rijndael_enc_desc);
  33. #elif YARROW_AES==1
  34. prng->yarrow.cipher = register_cipher(&aes_enc_desc);
  35. #elif YARROW_AES==2
  36. prng->yarrow.cipher = register_cipher(&rijndael_desc);
  37. #elif YARROW_AES==3
  38. prng->yarrow.cipher = register_cipher(&aes_desc);
  39. #endif
  40. #elif defined(BLOWFISH)
  41. prng->yarrow.cipher = register_cipher(&blowfish_desc);
  42. #elif defined(TWOFISH)
  43. prng->yarrow.cipher = register_cipher(&twofish_desc);
  44. #elif defined(RC6)
  45. prng->yarrow.cipher = register_cipher(&rc6_desc);
  46. #elif defined(RC5)
  47. prng->yarrow.cipher = register_cipher(&rc5_desc);
  48. #elif defined(SAFERP)
  49. prng->yarrow.cipher = register_cipher(&saferp_desc);
  50. #elif defined(RC2)
  51. prng->yarrow.cipher = register_cipher(&rc2_desc);
  52. #elif defined(NOEKEON)
  53. prng->yarrow.cipher = register_cipher(&noekeon_desc);
  54. #elif defined(CAST5)
  55. prng->yarrow.cipher = register_cipher(&cast5_desc);
  56. #elif defined(XTEA)
  57. prng->yarrow.cipher = register_cipher(&xtea_desc);
  58. #elif defined(SAFER)
  59. prng->yarrow.cipher = register_cipher(&safer_sk128_desc);
  60. #elif defined(DES)
  61. prng->yarrow.cipher = register_cipher(&des3_desc);
  62. #else
  63. #error YARROW needs at least one CIPHER
  64. #endif
  65. if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
  66. return err;
  67. }
  68. #ifdef SHA256
  69. prng->yarrow.hash = register_hash(&sha256_desc);
  70. #elif defined(SHA512)
  71. prng->yarrow.hash = register_hash(&sha512_desc);
  72. #elif defined(TIGER)
  73. prng->yarrow.hash = register_hash(&tiger_desc);
  74. #elif defined(SHA1)
  75. prng->yarrow.hash = register_hash(&sha1_desc);
  76. #elif defined(RIPEMD160)
  77. prng->yarrow.hash = register_hash(&rmd160_desc);
  78. #elif defined(RIPEMD128)
  79. prng->yarrow.hash = register_hash(&rmd128_desc);
  80. #elif defined(MD5)
  81. prng->yarrow.hash = register_hash(&md5_desc);
  82. #elif defined(MD4)
  83. prng->yarrow.hash = register_hash(&md4_desc);
  84. #elif defined(MD2)
  85. prng->yarrow.hash = register_hash(&md2_desc);
  86. #elif defined(WHIRLPOOL)
  87. prng->yarrow.hash = register_hash(&whirlpool_desc);
  88. #else
  89. #error YARROW needs at least one HASH
  90. #endif
  91. if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
  92. return err;
  93. }
  94. /* zero the memory used */
  95. zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool));
  96. return CRYPT_OK;
  97. }
  98. int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
  99. {
  100. hash_state md;
  101. int err;
  102. _ARGCHK(buf != NULL);
  103. _ARGCHK(prng != NULL);
  104. if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
  105. return err;
  106. }
  107. /* start the hash */
  108. if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) {
  109. return err;
  110. }
  111. /* hash the current pool */
  112. if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool,
  113. hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) {
  114. return err;
  115. }
  116. /* add the new entropy */
  117. if ((err = hash_descriptor[prng->yarrow.hash].process(&md, buf, len)) != CRYPT_OK) {
  118. return err;
  119. }
  120. /* store result */
  121. if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) {
  122. return err;
  123. }
  124. return CRYPT_OK;
  125. }
  126. int yarrow_ready(prng_state *prng)
  127. {
  128. int ks, err;
  129. _ARGCHK(prng != NULL);
  130. if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
  131. return err;
  132. }
  133. if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
  134. return err;
  135. }
  136. /* setup CTR mode using the "pool" as the key */
  137. ks = (int)hash_descriptor[prng->yarrow.hash].hashsize;
  138. if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) {
  139. return err;
  140. }
  141. if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */
  142. prng->yarrow.pool, /* IV */
  143. prng->yarrow.pool, ks, /* KEY and key size */
  144. 0, /* number of rounds */
  145. &prng->yarrow.ctr)) != CRYPT_OK) {
  146. return err;
  147. }
  148. return CRYPT_OK;
  149. }
  150. unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng)
  151. {
  152. _ARGCHK(buf != NULL);
  153. _ARGCHK(prng != NULL);
  154. /* put buf in predictable state first */
  155. zeromem(buf, len);
  156. /* now randomize it */
  157. if (ctr_encrypt(buf, buf, len, &prng->yarrow.ctr) != CRYPT_OK) {
  158. return 0;
  159. }
  160. return len;
  161. }
  162. int yarrow_done(prng_state *prng)
  163. {
  164. _ARGCHK(prng != NULL);
  165. /* call cipher done when we invent one ;-) */
  166. return CRYPT_OK;
  167. }
  168. int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
  169. {
  170. _ARGCHK(out != NULL);
  171. _ARGCHK(outlen != NULL);
  172. _ARGCHK(prng != NULL);
  173. /* we'll write 64 bytes for s&g's */
  174. if (*outlen < 64) {
  175. return CRYPT_BUFFER_OVERFLOW;
  176. }
  177. if (yarrow_read(out, 64, prng) != 64) {
  178. return CRYPT_ERROR_READPRNG;
  179. }
  180. *outlen = 64;
  181. return CRYPT_OK;
  182. }
  183. int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
  184. {
  185. int err;
  186. _ARGCHK(in != NULL);
  187. _ARGCHK(prng != NULL);
  188. if (inlen != 64) {
  189. return CRYPT_INVALID_ARG;
  190. }
  191. if ((err = yarrow_start(prng)) != CRYPT_OK) {
  192. return err;
  193. }
  194. return yarrow_add_entropy(in, 64, prng);
  195. }
  196. int yarrow_test(void)
  197. {
  198. #ifndef LTC_TEST
  199. return CRYPT_NOP;
  200. #else
  201. int err;
  202. prng_state prng;
  203. if ((err = yarrow_start(&prng)) != CRYPT_OK) {
  204. return err;
  205. }
  206. /* now let's test the hash/cipher that was chosen */
  207. if ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK) {
  208. return err;
  209. }
  210. if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) {
  211. return err;
  212. }
  213. yarrow_done(&prng);
  214. return CRYPT_OK;
  215. #endif
  216. }
  217. #endif