comparison libtomcrypt/src/prngs/yarrow.c @ 285:1b9e69c058d2

propagate from branch 'au.asn.ucc.matt.ltc.dropbear' (head 20dccfc09627970a312d77fb41dc2970b62689c3) to branch 'au.asn.ucc.matt.dropbear' (head fdf4a7a3b97ae5046139915de7e40399cceb2c01)
author Matt Johnston <matt@ucc.asn.au>
date Wed, 08 Mar 2006 13:23:58 +0000
parents
children 0cbe8f6dbf9e
comparison
equal deleted inserted replaced
281:997e6f7dc01e 285:1b9e69c058d2
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 "tomcrypt.h"
12
13 /**
14 @file yarrow.c
15 Yarrow PRNG, Tom St Denis
16 */
17
18 #ifdef YARROW
19
20 const struct ltc_prng_descriptor yarrow_desc =
21 {
22 "yarrow", 64,
23 &yarrow_start,
24 &yarrow_add_entropy,
25 &yarrow_ready,
26 &yarrow_read,
27 &yarrow_done,
28 &yarrow_export,
29 &yarrow_import,
30 &yarrow_test
31 };
32
33 /**
34 Start the PRNG
35 @param prng [out] The PRNG state to initialize
36 @return CRYPT_OK if successful
37 */
38 int yarrow_start(prng_state *prng)
39 {
40 int err;
41
42 LTC_ARGCHK(prng != NULL);
43
44 /* these are the default hash/cipher combo used */
45 #ifdef RIJNDAEL
46 #if YARROW_AES==0
47 prng->yarrow.cipher = register_cipher(&rijndael_enc_desc);
48 #elif YARROW_AES==1
49 prng->yarrow.cipher = register_cipher(&aes_enc_desc);
50 #elif YARROW_AES==2
51 prng->yarrow.cipher = register_cipher(&rijndael_desc);
52 #elif YARROW_AES==3
53 prng->yarrow.cipher = register_cipher(&aes_desc);
54 #endif
55 #elif defined(BLOWFISH)
56 prng->yarrow.cipher = register_cipher(&blowfish_desc);
57 #elif defined(TWOFISH)
58 prng->yarrow.cipher = register_cipher(&twofish_desc);
59 #elif defined(RC6)
60 prng->yarrow.cipher = register_cipher(&rc6_desc);
61 #elif defined(RC5)
62 prng->yarrow.cipher = register_cipher(&rc5_desc);
63 #elif defined(SAFERP)
64 prng->yarrow.cipher = register_cipher(&saferp_desc);
65 #elif defined(RC2)
66 prng->yarrow.cipher = register_cipher(&rc2_desc);
67 #elif defined(NOEKEON)
68 prng->yarrow.cipher = register_cipher(&noekeon_desc);
69 #elif defined(CAST5)
70 prng->yarrow.cipher = register_cipher(&cast5_desc);
71 #elif defined(XTEA)
72 prng->yarrow.cipher = register_cipher(&xtea_desc);
73 #elif defined(SAFER)
74 prng->yarrow.cipher = register_cipher(&safer_sk128_desc);
75 #elif defined(DES)
76 prng->yarrow.cipher = register_cipher(&des3_desc);
77 #else
78 #error YARROW needs at least one CIPHER
79 #endif
80 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
81 return err;
82 }
83
84 #ifdef SHA256
85 prng->yarrow.hash = register_hash(&sha256_desc);
86 #elif defined(SHA512)
87 prng->yarrow.hash = register_hash(&sha512_desc);
88 #elif defined(TIGER)
89 prng->yarrow.hash = register_hash(&tiger_desc);
90 #elif defined(SHA1)
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);
96 #elif defined(MD5)
97 prng->yarrow.hash = register_hash(&md5_desc);
98 #elif defined(MD4)
99 prng->yarrow.hash = register_hash(&md4_desc);
100 #elif defined(MD2)
101 prng->yarrow.hash = register_hash(&md2_desc);
102 #elif defined(WHIRLPOOL)
103 prng->yarrow.hash = register_hash(&whirlpool_desc);
104 #else
105 #error YARROW needs at least one HASH
106 #endif
107 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
108 return err;
109 }
110
111 /* zero the memory used */
112 zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool));
113
114 return CRYPT_OK;
115 }
116
117 /**
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
123 */
124 int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng)
125 {
126 hash_state md;
127 int err;
128
129 LTC_ARGCHK(in != NULL);
130 LTC_ARGCHK(prng != NULL);
131
132 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
133 return err;
134 }
135
136 /* start the hash */
137 if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) {
138 return err;
139 }
140
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) {
144 return err;
145 }
146
147 /* add the new entropy */
148 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) {
149 return err;
150 }
151
152 /* store result */
153 if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) {
154 return err;
155 }
156
157 return CRYPT_OK;
158 }
159
160 /**
161 Make the PRNG ready to read from
162 @param prng The PRNG to make active
163 @return CRYPT_OK if successful
164 */
165 int yarrow_ready(prng_state *prng)
166 {
167 int ks, err;
168
169 LTC_ARGCHK(prng != NULL);
170
171 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
172 return err;
173 }
174
175 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
176 return err;
177 }
178
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) {
182 return err;
183 }
184
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) {
191 return err;
192 }
193 return CRYPT_OK;
194 }
195
196 /**
197 Read from the PRNG
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
202 */
203 unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng)
204 {
205 LTC_ARGCHK(out != NULL);
206 LTC_ARGCHK(prng != NULL);
207
208 /* put out in predictable state first */
209 zeromem(out, outlen);
210
211 /* now randomize it */
212 if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) {
213 return 0;
214 }
215 return outlen;
216 }
217
218 /**
219 Terminate the PRNG
220 @param prng The PRNG to terminate
221 @return CRYPT_OK if successful
222 */
223 int yarrow_done(prng_state *prng)
224 {
225 LTC_ARGCHK(prng != NULL);
226
227 /* call cipher done when we invent one ;-) */
228
229 /* we invented one */
230 return ctr_done(&prng->yarrow.ctr);
231 }
232
233 /**
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
239 */
240 int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng)
241 {
242 LTC_ARGCHK(out != NULL);
243 LTC_ARGCHK(outlen != NULL);
244 LTC_ARGCHK(prng != NULL);
245
246 /* we'll write 64 bytes for s&g's */
247 if (*outlen < 64) {
248 return CRYPT_BUFFER_OVERFLOW;
249 }
250
251 if (yarrow_read(out, 64, prng) != 64) {
252 return CRYPT_ERROR_READPRNG;
253 }
254 *outlen = 64;
255
256 return CRYPT_OK;
257 }
258
259 /**
260 Import a PRNG state
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
265 */
266 int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng)
267 {
268 int err;
269
270 LTC_ARGCHK(in != NULL);
271 LTC_ARGCHK(prng != NULL);
272
273 if (inlen != 64) {
274 return CRYPT_INVALID_ARG;
275 }
276
277 if ((err = yarrow_start(prng)) != CRYPT_OK) {
278 return err;
279 }
280 return yarrow_add_entropy(in, 64, prng);
281 }
282
283 /**
284 PRNG self-test
285 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
286 */
287 int yarrow_test(void)
288 {
289 #ifndef LTC_TEST
290 return CRYPT_NOP;
291 #else
292 int err;
293 prng_state prng;
294
295 if ((err = yarrow_start(&prng)) != CRYPT_OK) {
296 return err;
297 }
298
299 /* now let's test the hash/cipher that was chosen */
300 if ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK) {
301 return err;
302 }
303 if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) {
304 return err;
305 }
306
307 yarrow_done(&prng);
308 return CRYPT_OK;
309 #endif
310 }
311
312 #endif
313
314
315 /* $Source: /cvs/libtom/libtomcrypt/src/prngs/yarrow.c,v $ */
316 /* $Revision: 1.5 $ */
317 /* $Date: 2005/05/05 14:35:59 $ */