Mercurial > dropbear
comparison libtomcrypt/src/prngs/yarrow.c @ 1478:3a933956437e coverity
update coverity
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 09 Feb 2018 23:49:22 +0800 |
parents | 6dba84798cd5 |
children |
comparison
equal
deleted
inserted
replaced
1439:8d24733026c5 | 1478:3a933956437e |
---|---|
3 * LibTomCrypt is a library that provides various cryptographic | 3 * LibTomCrypt is a library that provides various cryptographic |
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 * | |
9 * Tom St Denis, [email protected], http://libtom.org | |
10 */ | 8 */ |
11 #include "tomcrypt.h" | 9 #include "tomcrypt.h" |
12 | 10 |
13 /** | 11 /** |
14 @file yarrow.c | 12 @file yarrow.c |
15 Yarrow PRNG, Tom St Denis | 13 Yarrow PRNG, Tom St Denis |
16 */ | 14 */ |
17 | 15 |
18 #ifdef LTC_YARROW | 16 #ifdef LTC_YARROW |
19 | 17 |
20 const struct ltc_prng_descriptor yarrow_desc = | 18 const struct ltc_prng_descriptor yarrow_desc = |
21 { | 19 { |
32 | 30 |
33 /** | 31 /** |
34 Start the PRNG | 32 Start the PRNG |
35 @param prng [out] The PRNG state to initialize | 33 @param prng [out] The PRNG state to initialize |
36 @return CRYPT_OK if successful | 34 @return CRYPT_OK if successful |
37 */ | 35 */ |
38 int yarrow_start(prng_state *prng) | 36 int yarrow_start(prng_state *prng) |
39 { | 37 { |
40 int err; | 38 int err; |
41 | 39 |
42 LTC_ARGCHK(prng != NULL); | 40 LTC_ARGCHK(prng != NULL); |
41 prng->ready = 0; | |
43 | 42 |
44 /* these are the default hash/cipher combo used */ | 43 /* these are the default hash/cipher combo used */ |
45 #ifdef LTC_RIJNDAEL | 44 #ifdef LTC_RIJNDAEL |
46 #if LTC_YARROW_AES==0 | 45 #if LTC_YARROW_AES==0 |
47 prng->yarrow.cipher = register_cipher(&rijndael_enc_desc); | 46 prng->yarrow.cipher = register_cipher(&rijndael_enc_desc); |
62 prng->yarrow.cipher = register_cipher(&rc5_desc); | 61 prng->yarrow.cipher = register_cipher(&rc5_desc); |
63 #elif defined(LTC_SAFERP) | 62 #elif defined(LTC_SAFERP) |
64 prng->yarrow.cipher = register_cipher(&saferp_desc); | 63 prng->yarrow.cipher = register_cipher(&saferp_desc); |
65 #elif defined(LTC_RC2) | 64 #elif defined(LTC_RC2) |
66 prng->yarrow.cipher = register_cipher(&rc2_desc); | 65 prng->yarrow.cipher = register_cipher(&rc2_desc); |
67 #elif defined(LTC_NOEKEON) | 66 #elif defined(LTC_NOEKEON) |
68 prng->yarrow.cipher = register_cipher(&noekeon_desc); | 67 prng->yarrow.cipher = register_cipher(&noekeon_desc); |
69 #elif defined(LTC_ANUBIS) | 68 #elif defined(LTC_ANUBIS) |
70 prng->yarrow.cipher = register_cipher(&anubis_desc); | 69 prng->yarrow.cipher = register_cipher(&anubis_desc); |
71 #elif defined(LTC_KSEED) | 70 #elif defined(LTC_KSEED) |
72 prng->yarrow.cipher = register_cipher(&kseed_desc); | 71 prng->yarrow.cipher = register_cipher(&kseed_desc); |
73 #elif defined(LTC_KHAZAD) | 72 #elif defined(LTC_KHAZAD) |
74 prng->yarrow.cipher = register_cipher(&khazad_desc); | 73 prng->yarrow.cipher = register_cipher(&khazad_desc); |
75 #elif defined(LTC_CAST5) | 74 #elif defined(LTC_CAST5) |
76 prng->yarrow.cipher = register_cipher(&cast5_desc); | 75 prng->yarrow.cipher = register_cipher(&cast5_desc); |
77 #elif defined(LTC_XTEA) | 76 #elif defined(LTC_XTEA) |
78 prng->yarrow.cipher = register_cipher(&xtea_desc); | 77 prng->yarrow.cipher = register_cipher(&xtea_desc); |
118 return err; | 117 return err; |
119 } | 118 } |
120 | 119 |
121 /* zero the memory used */ | 120 /* zero the memory used */ |
122 zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool)); | 121 zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool)); |
123 LTC_MUTEX_INIT(&prng->yarrow.prng_lock) | 122 LTC_MUTEX_INIT(&prng->lock) |
124 | 123 |
125 return CRYPT_OK; | 124 return CRYPT_OK; |
126 } | 125 } |
127 | 126 |
128 /** | 127 /** |
129 Add entropy to the PRNG state | 128 Add entropy to the PRNG state |
130 @param in The data to add | 129 @param in The data to add |
131 @param inlen Length of the data to add | 130 @param inlen Length of the data to add |
132 @param prng PRNG state to update | 131 @param prng PRNG state to update |
133 @return CRYPT_OK if successful | 132 @return CRYPT_OK if successful |
134 */ | 133 */ |
135 int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) | 134 int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) |
136 { | 135 { |
137 hash_state md; | 136 hash_state md; |
138 int err; | 137 int err; |
139 | 138 |
140 LTC_ARGCHK(in != NULL); | 139 LTC_ARGCHK(prng != NULL); |
141 LTC_ARGCHK(prng != NULL); | 140 LTC_ARGCHK(in != NULL); |
142 | 141 LTC_ARGCHK(inlen > 0); |
143 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); | 142 |
144 | 143 LTC_MUTEX_LOCK(&prng->lock); |
144 | |
145 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); | 146 goto LBL_UNLOCK; |
147 return err; | |
148 } | 147 } |
149 | 148 |
150 /* start the hash */ | 149 /* start the hash */ |
151 if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) { | 150 if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) { |
152 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 151 goto LBL_UNLOCK; |
153 return err; | |
154 } | 152 } |
155 | 153 |
156 /* hash the current pool */ | 154 /* hash the current pool */ |
157 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, | 155 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, |
158 hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) { | 156 hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) { |
159 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 157 goto LBL_UNLOCK; |
160 return err; | |
161 } | 158 } |
162 | 159 |
163 /* add the new entropy */ | 160 /* add the new entropy */ |
164 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) { | 161 if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) { |
165 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 162 goto LBL_UNLOCK; |
166 return err; | |
167 } | 163 } |
168 | 164 |
169 /* store result */ | 165 /* store result */ |
170 if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) { | 166 err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool); |
171 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 167 |
172 return err; | 168 LBL_UNLOCK: |
173 } | 169 LTC_MUTEX_UNLOCK(&prng->lock); |
174 | 170 return err; |
175 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | |
176 return CRYPT_OK; | |
177 } | 171 } |
178 | 172 |
179 /** | 173 /** |
180 Make the PRNG ready to read from | 174 Make the PRNG ready to read from |
181 @param prng The PRNG to make active | 175 @param prng The PRNG to make active |
182 @return CRYPT_OK if successful | 176 @return CRYPT_OK if successful |
183 */ | 177 */ |
184 int yarrow_ready(prng_state *prng) | 178 int yarrow_ready(prng_state *prng) |
185 { | 179 { |
186 int ks, err; | 180 int ks, err; |
187 | 181 |
188 LTC_ARGCHK(prng != NULL); | 182 LTC_ARGCHK(prng != NULL); |
189 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); | 183 |
184 LTC_MUTEX_LOCK(&prng->lock); | |
190 | 185 |
191 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { | 186 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { |
192 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 187 goto LBL_UNLOCK; |
193 return err; | 188 } |
194 } | 189 |
195 | |
196 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { | 190 if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { |
197 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 191 goto LBL_UNLOCK; |
198 return err; | |
199 } | 192 } |
200 | 193 |
201 /* setup CTR mode using the "pool" as the key */ | 194 /* setup CTR mode using the "pool" as the key */ |
202 ks = (int)hash_descriptor[prng->yarrow.hash].hashsize; | 195 ks = (int)hash_descriptor[prng->yarrow.hash].hashsize; |
203 if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) { | 196 if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) { |
204 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 197 goto LBL_UNLOCK; |
205 return err; | |
206 } | 198 } |
207 | 199 |
208 if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ | 200 if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ |
209 prng->yarrow.pool, /* IV */ | 201 prng->yarrow.pool, /* IV */ |
210 prng->yarrow.pool, ks, /* KEY and key size */ | 202 prng->yarrow.pool, ks, /* KEY and key size */ |
211 0, /* number of rounds */ | 203 0, /* number of rounds */ |
212 CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */ | 204 CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */ |
213 &prng->yarrow.ctr)) != CRYPT_OK) { | 205 &prng->yarrow.ctr)) != CRYPT_OK) { |
214 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 206 goto LBL_UNLOCK; |
215 return err; | 207 } |
216 } | 208 prng->ready = 1; |
217 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 209 |
218 return CRYPT_OK; | 210 LBL_UNLOCK: |
211 LTC_MUTEX_UNLOCK(&prng->lock); | |
212 return err; | |
219 } | 213 } |
220 | 214 |
221 /** | 215 /** |
222 Read from the PRNG | 216 Read from the PRNG |
223 @param out Destination | 217 @param out Destination |
224 @param outlen Length of output | 218 @param outlen Length of output |
225 @param prng The active PRNG to read from | 219 @param prng The active PRNG to read from |
226 @return Number of octets read | 220 @return Number of octets read |
227 */ | 221 */ |
228 unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng) | 222 unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng) |
229 { | 223 { |
230 LTC_ARGCHK(out != NULL); | 224 if (outlen == 0 || prng == NULL || out == NULL) return 0; |
231 LTC_ARGCHK(prng != NULL); | 225 |
232 | 226 LTC_MUTEX_LOCK(&prng->lock); |
233 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); | 227 |
228 if (!prng->ready) { | |
229 outlen = 0; | |
230 goto LBL_UNLOCK; | |
231 } | |
234 | 232 |
235 /* put out in predictable state first */ | 233 /* put out in predictable state first */ |
236 zeromem(out, outlen); | 234 zeromem(out, outlen); |
237 | 235 |
238 /* now randomize it */ | 236 /* now randomize it */ |
239 if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) { | 237 if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) { |
240 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 238 outlen = 0; |
241 return 0; | 239 } |
242 } | 240 |
243 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 241 LBL_UNLOCK: |
242 LTC_MUTEX_UNLOCK(&prng->lock); | |
244 return outlen; | 243 return outlen; |
245 } | 244 } |
246 | 245 |
247 /** | 246 /** |
248 Terminate the PRNG | 247 Terminate the PRNG |
249 @param prng The PRNG to terminate | 248 @param prng The PRNG to terminate |
250 @return CRYPT_OK if successful | 249 @return CRYPT_OK if successful |
251 */ | 250 */ |
252 int yarrow_done(prng_state *prng) | 251 int yarrow_done(prng_state *prng) |
253 { | 252 { |
254 int err; | 253 int err; |
255 LTC_ARGCHK(prng != NULL); | 254 LTC_ARGCHK(prng != NULL); |
256 | 255 |
257 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); | 256 LTC_MUTEX_LOCK(&prng->lock); |
257 prng->ready = 0; | |
258 | 258 |
259 /* call cipher done when we invent one ;-) */ | 259 /* call cipher done when we invent one ;-) */ |
260 | 260 |
261 /* we invented one */ | 261 /* we invented one */ |
262 err = ctr_done(&prng->yarrow.ctr); | 262 err = ctr_done(&prng->yarrow.ctr); |
263 | 263 |
264 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 264 LTC_MUTEX_UNLOCK(&prng->lock); |
265 LTC_MUTEX_DESTROY(&prng->lock); | |
265 return err; | 266 return err; |
266 } | 267 } |
267 | 268 |
268 /** | 269 /** |
269 Export the PRNG state | 270 Export the PRNG state |
270 @param out [out] Destination | 271 @param out [out] Destination |
271 @param outlen [in/out] Max size and resulting size of the state | 272 @param outlen [in/out] Max size and resulting size of the state |
272 @param prng The PRNG to export | 273 @param prng The PRNG to export |
273 @return CRYPT_OK if successful | 274 @return CRYPT_OK if successful |
274 */ | 275 */ |
275 int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng) | 276 int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng) |
276 { | 277 { |
278 unsigned long len = yarrow_desc.export_size; | |
279 | |
277 LTC_ARGCHK(out != NULL); | 280 LTC_ARGCHK(out != NULL); |
278 LTC_ARGCHK(outlen != NULL); | 281 LTC_ARGCHK(outlen != NULL); |
279 LTC_ARGCHK(prng != NULL); | 282 LTC_ARGCHK(prng != NULL); |
280 | 283 |
281 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); | 284 if (*outlen < len) { |
282 | 285 *outlen = len; |
283 /* we'll write 64 bytes for s&g's */ | |
284 if (*outlen < 64) { | |
285 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | |
286 *outlen = 64; | |
287 return CRYPT_BUFFER_OVERFLOW; | 286 return CRYPT_BUFFER_OVERFLOW; |
288 } | 287 } |
289 | 288 |
290 if (yarrow_read(out, 64, prng) != 64) { | 289 if (yarrow_read(out, len, prng) != len) { |
291 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | |
292 return CRYPT_ERROR_READPRNG; | 290 return CRYPT_ERROR_READPRNG; |
293 } | 291 } |
294 *outlen = 64; | 292 |
295 | 293 *outlen = len; |
296 return CRYPT_OK; | 294 return CRYPT_OK; |
297 } | 295 } |
298 | 296 |
299 /** | 297 /** |
300 Import a PRNG state | 298 Import a PRNG state |
301 @param in The PRNG state | 299 @param in The PRNG state |
302 @param inlen Size of the state | 300 @param inlen Size of the state |
303 @param prng The PRNG to import | 301 @param prng The PRNG to import |
304 @return CRYPT_OK if successful | 302 @return CRYPT_OK if successful |
305 */ | 303 */ |
306 int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng) | 304 int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng) |
307 { | 305 { |
308 int err; | 306 int err; |
309 | 307 |
310 LTC_ARGCHK(in != NULL); | 308 LTC_ARGCHK(in != NULL); |
311 LTC_ARGCHK(prng != NULL); | 309 LTC_ARGCHK(prng != NULL); |
312 | 310 if (inlen < (unsigned long)yarrow_desc.export_size) return CRYPT_INVALID_ARG; |
313 LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); | 311 |
314 | 312 if ((err = yarrow_start(prng)) != CRYPT_OK) return err; |
315 if (inlen != 64) { | 313 if ((err = yarrow_add_entropy(in, inlen, prng)) != CRYPT_OK) return err; |
316 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | 314 return CRYPT_OK; |
317 return CRYPT_INVALID_ARG; | |
318 } | |
319 | |
320 if ((err = yarrow_start(prng)) != CRYPT_OK) { | |
321 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | |
322 return err; | |
323 } | |
324 err = yarrow_add_entropy(in, 64, prng); | |
325 LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); | |
326 return err; | |
327 } | 315 } |
328 | 316 |
329 /** | 317 /** |
330 PRNG self-test | 318 PRNG self-test |
331 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled | 319 @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled |
332 */ | 320 */ |
333 int yarrow_test(void) | 321 int yarrow_test(void) |
334 { | 322 { |
335 #ifndef LTC_TEST | 323 #ifndef LTC_TEST |
336 return CRYPT_NOP; | 324 return CRYPT_NOP; |
337 #else | 325 #else |
339 prng_state prng; | 327 prng_state prng; |
340 | 328 |
341 if ((err = yarrow_start(&prng)) != CRYPT_OK) { | 329 if ((err = yarrow_start(&prng)) != CRYPT_OK) { |
342 return err; | 330 return err; |
343 } | 331 } |
344 | 332 |
345 /* now let's test the hash/cipher that was chosen */ | 333 /* now let's test the hash/cipher that was chosen */ |
346 if ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK) { | 334 if (cipher_descriptor[prng.yarrow.cipher].test && |
347 return err; | 335 ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK)) { |
348 } | 336 return err; |
349 if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) { | 337 } |
350 return err; | 338 if (hash_descriptor[prng.yarrow.hash].test && |
339 ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK)) { | |
340 return err; | |
351 } | 341 } |
352 | 342 |
353 return CRYPT_OK; | 343 return CRYPT_OK; |
354 #endif | 344 #endif |
355 } | 345 } |
356 | 346 |
357 #endif | 347 #endif |
358 | 348 |
359 | 349 |
360 /* $Source$ */ | 350 /* ref: $Format:%D$ */ |
361 /* $Revision$ */ | 351 /* git commit: $Format:%H$ */ |
362 /* $Date$ */ | 352 /* commit time: $Format:%ai$ */ |