comparison libtomcrypt/src/prngs/yarrow.c @ 435:337c45621e81

merge of 'a9b0496634cdd25647b65e585cc3240f3fa699ee' and 'c22be8b8f570b48e9662dac32c7b3e7148a42206'
author Matt Johnston <matt@ucc.asn.au>
date Thu, 22 Feb 2007 14:53:49 +0000
parents 0cbe8f6dbf9e
children f849a5ca2efc
comparison
equal deleted inserted replaced
434:0aaaf68e97dc 435:337c45621e81
4 * algorithms in a highly modular and flexible manner. 4 * algorithms in a highly modular and flexible manner.
5 * 5 *
6 * The library is free for all purposes without any express 6 * The library is free for all purposes without any express
7 * guarantee it works. 7 * guarantee it works.
8 * 8 *
9 * Tom St Denis, [email protected], http://libtomcrypt.org 9 * Tom St Denis, [email protected], http://libtomcrypt.com
10 */ 10 */
11 #include "tomcrypt.h" 11 #include "tomcrypt.h"
12 12
13 /** 13 /**
14 @file yarrow.c 14 @file yarrow.c
64 prng->yarrow.cipher = register_cipher(&saferp_desc); 64 prng->yarrow.cipher = register_cipher(&saferp_desc);
65 #elif defined(RC2) 65 #elif defined(RC2)
66 prng->yarrow.cipher = register_cipher(&rc2_desc); 66 prng->yarrow.cipher = register_cipher(&rc2_desc);
67 #elif defined(NOEKEON) 67 #elif defined(NOEKEON)
68 prng->yarrow.cipher = register_cipher(&noekeon_desc); 68 prng->yarrow.cipher = register_cipher(&noekeon_desc);
69 #elif defined(ANUBIS)
70 prng->yarrow.cipher = register_cipher(&anubis_desc);
71 #elif defined(KSEED)
72 prng->yarrow.cipher = register_cipher(&kseed_desc);
73 #elif defined(KHAZAD)
74 prng->yarrow.cipher = register_cipher(&khazad_desc);
69 #elif defined(CAST5) 75 #elif defined(CAST5)
70 prng->yarrow.cipher = register_cipher(&cast5_desc); 76 prng->yarrow.cipher = register_cipher(&cast5_desc);
71 #elif defined(XTEA) 77 #elif defined(XTEA)
72 prng->yarrow.cipher = register_cipher(&xtea_desc); 78 prng->yarrow.cipher = register_cipher(&xtea_desc);
73 #elif defined(SAFER) 79 #elif defined(SAFER)
87 prng->yarrow.hash = register_hash(&sha512_desc); 93 prng->yarrow.hash = register_hash(&sha512_desc);
88 #elif defined(TIGER) 94 #elif defined(TIGER)
89 prng->yarrow.hash = register_hash(&tiger_desc); 95 prng->yarrow.hash = register_hash(&tiger_desc);
90 #elif defined(SHA1) 96 #elif defined(SHA1)
91 prng->yarrow.hash = register_hash(&sha1_desc); 97 prng->yarrow.hash = register_hash(&sha1_desc);
98 #elif defined(RIPEMD320)
99 prng->yarrow.hash = register_hash(&rmd320_desc);
100 #elif defined(RIPEMD256)
101 prng->yarrow.hash = register_hash(&rmd256_desc);
92 #elif defined(RIPEMD160) 102 #elif defined(RIPEMD160)
93 prng->yarrow.hash = register_hash(&rmd160_desc); 103 prng->yarrow.hash = register_hash(&rmd160_desc);
94 #elif defined(RIPEMD128) 104 #elif defined(RIPEMD128)
95 prng->yarrow.hash = register_hash(&rmd128_desc); 105 prng->yarrow.hash = register_hash(&rmd128_desc);
96 #elif defined(MD5) 106 #elif defined(MD5)
108 return err; 118 return err;
109 } 119 }
110 120
111 /* zero the memory used */ 121 /* zero the memory used */
112 zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool)); 122 zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool));
123 LTC_MUTEX_INIT(&prng->yarrow.prng_lock)
113 124
114 return CRYPT_OK; 125 return CRYPT_OK;
115 } 126 }
116 127
117 /** 128 /**
126 hash_state md; 137 hash_state md;
127 int err; 138 int err;
128 139
129 LTC_ARGCHK(in != NULL); 140 LTC_ARGCHK(in != NULL);
130 LTC_ARGCHK(prng != NULL); 141 LTC_ARGCHK(prng != NULL);
131 142
143 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
144
132 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { 145 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
146 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
133 return err; 147 return err;
134 } 148 }
135 149
136 /* start the hash */ 150 /* start the hash */
137 if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) { 151 if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) {
152 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
138 return err; 153 return err;
139 } 154 }
140 155
141 /* hash the current pool */ 156 /* hash the current pool */
142 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, 157 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool,
143 hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) { 158 hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) {
159 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
144 return err; 160 return err;
145 } 161 }
146 162
147 /* add the new entropy */ 163 /* add the new entropy */
148 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) { 164 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) {
165 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
149 return err; 166 return err;
150 } 167 }
151 168
152 /* store result */ 169 /* store result */
153 if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) { 170 if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) {
154 return err; 171 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
155 } 172 return err;
156 173 }
174
175 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
157 return CRYPT_OK; 176 return CRYPT_OK;
158 } 177 }
159 178
160 /** 179 /**
161 Make the PRNG ready to read from 180 Make the PRNG ready to read from
165 int yarrow_ready(prng_state *prng) 184 int yarrow_ready(prng_state *prng)
166 { 185 {
167 int ks, err; 186 int ks, err;
168 187
169 LTC_ARGCHK(prng != NULL); 188 LTC_ARGCHK(prng != NULL);
189 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
170 190
171 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { 191 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
192 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
172 return err; 193 return err;
173 } 194 }
174 195
175 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { 196 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
197 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
176 return err; 198 return err;
177 } 199 }
178 200
179 /* setup CTR mode using the "pool" as the key */ 201 /* setup CTR mode using the "pool" as the key */
180 ks = (int)hash_descriptor[prng->yarrow.hash].hashsize; 202 ks = (int)hash_descriptor[prng->yarrow.hash].hashsize;
181 if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) { 203 if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) {
204 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
182 return err; 205 return err;
183 } 206 }
184 207
185 if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ 208 if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */
186 prng->yarrow.pool, /* IV */ 209 prng->yarrow.pool, /* IV */
187 prng->yarrow.pool, ks, /* KEY and key size */ 210 prng->yarrow.pool, ks, /* KEY and key size */
188 0, /* number of rounds */ 211 0, /* number of rounds */
189 CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */ 212 CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */
190 &prng->yarrow.ctr)) != CRYPT_OK) { 213 &prng->yarrow.ctr)) != CRYPT_OK) {
191 return err; 214 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
192 } 215 return err;
216 }
217 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
193 return CRYPT_OK; 218 return CRYPT_OK;
194 } 219 }
195 220
196 /** 221 /**
197 Read from the PRNG 222 Read from the PRNG
203 unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng) 228 unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng)
204 { 229 {
205 LTC_ARGCHK(out != NULL); 230 LTC_ARGCHK(out != NULL);
206 LTC_ARGCHK(prng != NULL); 231 LTC_ARGCHK(prng != NULL);
207 232
233 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
234
208 /* put out in predictable state first */ 235 /* put out in predictable state first */
209 zeromem(out, outlen); 236 zeromem(out, outlen);
210 237
211 /* now randomize it */ 238 /* now randomize it */
212 if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) { 239 if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) {
240 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
213 return 0; 241 return 0;
214 } 242 }
243 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
215 return outlen; 244 return outlen;
216 } 245 }
217 246
218 /** 247 /**
219 Terminate the PRNG 248 Terminate the PRNG
220 @param prng The PRNG to terminate 249 @param prng The PRNG to terminate
221 @return CRYPT_OK if successful 250 @return CRYPT_OK if successful
222 */ 251 */
223 int yarrow_done(prng_state *prng) 252 int yarrow_done(prng_state *prng)
224 { 253 {
225 LTC_ARGCHK(prng != NULL); 254 int err;
255 LTC_ARGCHK(prng != NULL);
256
257 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
226 258
227 /* call cipher done when we invent one ;-) */ 259 /* call cipher done when we invent one ;-) */
228 260
229 /* we invented one */ 261 /* we invented one */
230 return ctr_done(&prng->yarrow.ctr); 262 err = ctr_done(&prng->yarrow.ctr);
263
264 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
265 return err;
231 } 266 }
232 267
233 /** 268 /**
234 Export the PRNG state 269 Export the PRNG state
235 @param out [out] Destination 270 @param out [out] Destination
241 { 276 {
242 LTC_ARGCHK(out != NULL); 277 LTC_ARGCHK(out != NULL);
243 LTC_ARGCHK(outlen != NULL); 278 LTC_ARGCHK(outlen != NULL);
244 LTC_ARGCHK(prng != NULL); 279 LTC_ARGCHK(prng != NULL);
245 280
281 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
282
246 /* we'll write 64 bytes for s&g's */ 283 /* we'll write 64 bytes for s&g's */
247 if (*outlen < 64) { 284 if (*outlen < 64) {
285 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
286 *outlen = 64;
248 return CRYPT_BUFFER_OVERFLOW; 287 return CRYPT_BUFFER_OVERFLOW;
249 } 288 }
250 289
251 if (yarrow_read(out, 64, prng) != 64) { 290 if (yarrow_read(out, 64, prng) != 64) {
291 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
252 return CRYPT_ERROR_READPRNG; 292 return CRYPT_ERROR_READPRNG;
253 } 293 }
254 *outlen = 64; 294 *outlen = 64;
255 295
256 return CRYPT_OK; 296 return CRYPT_OK;
267 { 307 {
268 int err; 308 int err;
269 309
270 LTC_ARGCHK(in != NULL); 310 LTC_ARGCHK(in != NULL);
271 LTC_ARGCHK(prng != NULL); 311 LTC_ARGCHK(prng != NULL);
312
313 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock);
272 314
273 if (inlen != 64) { 315 if (inlen != 64) {
316 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
274 return CRYPT_INVALID_ARG; 317 return CRYPT_INVALID_ARG;
275 } 318 }
276 319
277 if ((err = yarrow_start(prng)) != CRYPT_OK) { 320 if ((err = yarrow_start(prng)) != CRYPT_OK) {
278 return err; 321 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
279 } 322 return err;
280 return yarrow_add_entropy(in, 64, prng); 323 }
324 err = yarrow_add_entropy(in, 64, prng);
325 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock);
326 return err;
281 } 327 }
282 328
283 /** 329 /**
284 PRNG self-test 330 PRNG self-test
285 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled 331 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled
302 } 348 }
303 if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) { 349 if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) {
304 return err; 350 return err;
305 } 351 }
306 352
307 yarrow_done(&prng);
308 return CRYPT_OK; 353 return CRYPT_OK;
309 #endif 354 #endif
310 } 355 }
311 356
312 #endif 357 #endif
313 358
314 359
315 /* $Source: /cvs/libtom/libtomcrypt/src/prngs/yarrow.c,v $ */ 360 /* $Source: /cvs/libtom/libtomcrypt/src/prngs/yarrow.c,v $ */
316 /* $Revision: 1.5 $ */ 361 /* $Revision: 1.10 $ */
317 /* $Date: 2005/05/05 14:35:59 $ */ 362 /* $Date: 2006/11/14 04:21:17 $ */