yarrow.c 5.9 KB

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