2
0

yarrow.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  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. #elif
  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. hash_descriptor[prng->yarrow.hash].init(&md);
  109. /* hash the current pool */
  110. if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool,
  111. hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) {
  112. return err;
  113. }
  114. /* add the new entropy */
  115. if ((err = hash_descriptor[prng->yarrow.hash].process(&md, buf, len)) != CRYPT_OK) {
  116. return err;
  117. }
  118. /* store result */
  119. if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) {
  120. return err;
  121. }
  122. return CRYPT_OK;
  123. }
  124. int yarrow_ready(prng_state *prng)
  125. {
  126. int ks, err;
  127. _ARGCHK(prng != NULL);
  128. if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
  129. return err;
  130. }
  131. if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
  132. return err;
  133. }
  134. /* setup CTR mode using the "pool" as the key */
  135. ks = (int)hash_descriptor[prng->yarrow.hash].hashsize;
  136. if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) {
  137. return err;
  138. }
  139. if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */
  140. prng->yarrow.pool, /* IV */
  141. prng->yarrow.pool, ks, /* KEY and key size */
  142. 0, /* number of rounds */
  143. &prng->yarrow.ctr)) != CRYPT_OK) {
  144. return err;
  145. }
  146. return CRYPT_OK;
  147. }
  148. unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng)
  149. {
  150. _ARGCHK(buf != NULL);
  151. _ARGCHK(prng != NULL);
  152. /* put buf in predictable state first */
  153. zeromem(buf, len);
  154. /* now randomize it */
  155. if (ctr_encrypt(buf, buf, len, &prng->yarrow.ctr) != CRYPT_OK) {
  156. return 0;
  157. }
  158. return len;
  159. }
  160. int yarrow_done(prng_state *prng)
  161. {
  162. _ARGCHK(prng != NULL);
  163. /* call cipher done when we invent one ;-) */
  164. return CRYPT_OK;
  165. }
  166. int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
  167. {
  168. _ARGCHK(out != NULL);
  169. _ARGCHK(outlen != NULL);
  170. _ARGCHK(prng != NULL);
  171. /* we'll write 64 bytes for s&g's */
  172. if (*outlen < 64) {
  173. return CRYPT_BUFFER_OVERFLOW;
  174. }
  175. if (yarrow_read(out, 64, prng) != 64) {
  176. return CRYPT_ERROR_READPRNG;
  177. }
  178. *outlen = 64;
  179. return CRYPT_OK;
  180. }
  181. int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
  182. {
  183. int err;
  184. _ARGCHK(in != NULL);
  185. _ARGCHK(prng != NULL);
  186. if (inlen != 64) {
  187. return CRYPT_INVALID_ARG;
  188. }
  189. if ((err = yarrow_start(prng)) != CRYPT_OK) {
  190. return err;
  191. }
  192. return yarrow_add_entropy(in, 64, prng);
  193. }
  194. int yarrow_test(void)
  195. {
  196. #ifndef LTC_TEST
  197. return CRYPT_NOP;
  198. #else
  199. int err;
  200. prng_state prng;
  201. if ((err = yarrow_start(&prng)) != CRYPT_OK) {
  202. return err;
  203. }
  204. /* now let's test the hash/cipher that was chosen */
  205. if ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK) {
  206. return err;
  207. }
  208. if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) {
  209. return err;
  210. }
  211. yarrow_done(&prng);
  212. return CRYPT_OK;
  213. #endif
  214. }
  215. #endif