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$ */