1
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
3
* LibTomCrypt is a library that provides various cryptographic
4
* algorithms in a highly modular and flexible manner.
6
* The library is free for all purposes without any express
9
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
15
Yarrow PRNG, Tom St Denis
20
const struct ltc_prng_descriptor yarrow_desc =
35
@param prng [out] The PRNG state to initialize
36
@return CRYPT_OK if successful
38
int yarrow_start(prng_state *prng)
42
LTC_ARGCHK(prng != NULL);
44
/* these are the default hash/cipher combo used */
47
prng->yarrow.cipher = register_cipher(&rijndael_enc_desc);
49
prng->yarrow.cipher = register_cipher(&aes_enc_desc);
51
prng->yarrow.cipher = register_cipher(&rijndael_desc);
53
prng->yarrow.cipher = register_cipher(&aes_desc);
55
#elif defined(BLOWFISH)
56
prng->yarrow.cipher = register_cipher(&blowfish_desc);
57
#elif defined(TWOFISH)
58
prng->yarrow.cipher = register_cipher(&twofish_desc);
60
prng->yarrow.cipher = register_cipher(&rc6_desc);
62
prng->yarrow.cipher = register_cipher(&rc5_desc);
64
prng->yarrow.cipher = register_cipher(&saferp_desc);
66
prng->yarrow.cipher = register_cipher(&rc2_desc);
67
#elif defined(NOEKEON)
68
prng->yarrow.cipher = register_cipher(&noekeon_desc);
70
prng->yarrow.cipher = register_cipher(&cast5_desc);
72
prng->yarrow.cipher = register_cipher(&xtea_desc);
74
prng->yarrow.cipher = register_cipher(&safer_sk128_desc);
76
prng->yarrow.cipher = register_cipher(&des3_desc);
78
#error YARROW needs at least one CIPHER
80
if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
85
prng->yarrow.hash = register_hash(&sha256_desc);
87
prng->yarrow.hash = register_hash(&sha512_desc);
89
prng->yarrow.hash = register_hash(&tiger_desc);
91
prng->yarrow.hash = register_hash(&sha1_desc);
92
#elif defined(RIPEMD160)
93
prng->yarrow.hash = register_hash(&rmd160_desc);
94
#elif defined(RIPEMD128)
95
prng->yarrow.hash = register_hash(&rmd128_desc);
97
prng->yarrow.hash = register_hash(&md5_desc);
99
prng->yarrow.hash = register_hash(&md4_desc);
101
prng->yarrow.hash = register_hash(&md2_desc);
102
#elif defined(WHIRLPOOL)
103
prng->yarrow.hash = register_hash(&whirlpool_desc);
105
#error YARROW needs at least one HASH
107
if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
111
/* zero the memory used */
112
zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool));
118
Add entropy to the PRNG state
119
@param in The data to add
120
@param inlen Length of the data to add
121
@param prng PRNG state to update
122
@return CRYPT_OK if successful
124
int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
129
LTC_ARGCHK(in != NULL);
130
LTC_ARGCHK(prng != NULL);
132
if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
137
if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) {
141
/* hash the current pool */
142
if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool,
143
hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) {
147
/* add the new entropy */
148
if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) {
153
if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) {
161
Make the PRNG ready to read from
162
@param prng The PRNG to make active
163
@return CRYPT_OK if successful
165
int yarrow_ready(prng_state *prng)
169
LTC_ARGCHK(prng != NULL);
171
if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
175
if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
179
/* setup CTR mode using the "pool" as the key */
180
ks = (int)hash_descriptor[prng->yarrow.hash].hashsize;
181
if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) {
185
if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */
186
prng->yarrow.pool, /* IV */
187
prng->yarrow.pool, ks, /* KEY and key size */
188
0, /* number of rounds */
189
CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */
190
&prng->yarrow.ctr)) != CRYPT_OK) {
198
@param out Destination
199
@param outlen Length of output
200
@param prng The active PRNG to read from
201
@return Number of octets read
203
unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng)
205
LTC_ARGCHK(out != NULL);
206
LTC_ARGCHK(prng != NULL);
208
/* put out in predictable state first */
209
zeromem(out, outlen);
211
/* now randomize it */
212
if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) {
220
@param prng The PRNG to terminate
221
@return CRYPT_OK if successful
223
int yarrow_done(prng_state *prng)
225
LTC_ARGCHK(prng != NULL);
227
/* call cipher done when we invent one ;-) */
229
/* we invented one */
230
return ctr_done(&prng->yarrow.ctr);
234
Export the PRNG state
235
@param out [out] Destination
236
@param outlen [in/out] Max size and resulting size of the state
237
@param prng The PRNG to export
238
@return CRYPT_OK if successful
240
int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
242
LTC_ARGCHK(out != NULL);
243
LTC_ARGCHK(outlen != NULL);
244
LTC_ARGCHK(prng != NULL);
246
/* we'll write 64 bytes for s&g's */
248
return CRYPT_BUFFER_OVERFLOW;
251
if (yarrow_read(out, 64, prng) != 64) {
252
return CRYPT_ERROR_READPRNG;
261
@param in The PRNG state
262
@param inlen Size of the state
263
@param prng The PRNG to import
264
@return CRYPT_OK if successful
266
int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
270
LTC_ARGCHK(in != NULL);
271
LTC_ARGCHK(prng != NULL);
274
return CRYPT_INVALID_ARG;
277
if ((err = yarrow_start(prng)) != CRYPT_OK) {
280
return yarrow_add_entropy(in, 64, prng);
285
@return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
287
int yarrow_test(void)
295
if ((err = yarrow_start(&prng)) != CRYPT_OK) {
299
/* now let's test the hash/cipher that was chosen */
300
if ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK) {
303
if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) {
315
/* $Source: /cvs/libtom/libtomcrypt/src/prngs/yarrow.c,v $ */
316
/* $Revision: 1.5 $ */
317
/* $Date: 2005/05/05 14:35:59 $ */