Package list libcryptx-perl / e038ed0
anon union - workaround Karel Miko 3 years ago
6 changed file(s) with 104 addition(s) and 98 deletion(s). Raw diff Collapse all Expand all
1212 int cipher, hash;
1313 unsigned char pool[MAXBLOCKSIZE];
1414 symmetric_CTR ctr;
15 short ready; /* ready flag 0-1 */
16 LTC_MUTEX_TYPE(lock) /* lock */
1517 };
1618 #endif
1719
1820 #ifdef LTC_RC4
1921 struct rc4_prng {
2022 rc4_state s;
23 short ready; /* ready flag 0-1 */
24 LTC_MUTEX_TYPE(lock) /* lock */
2125 };
2226 #endif
2327
2630 chacha_state s; /* chacha state */
2731 unsigned char ent[40]; /* entropy buffer */
2832 unsigned long idx; /* entropy counter */
33 short ready; /* ready flag 0-1 */
34 LTC_MUTEX_TYPE(lock) /* lock */
2935 };
3036 #endif
3137
4349 wd;
4450
4551 ulong64 reset_cnt; /* number of times we have reseeded */
52 short ready; /* ready flag 0-1 */
53 LTC_MUTEX_TYPE(lock) /* lock */
4654 };
4755 #endif
4856
5159 sober128_state s; /* sober128 state */
5260 unsigned char ent[40]; /* entropy buffer */
5361 unsigned long idx; /* entropy counter */
54 };
55 #endif
56
57 typedef struct {
58 union {
59 char dummy[1];
62 short ready; /* ready flag 0-1 */
63 LTC_MUTEX_TYPE(lock) /* lock */
64 };
65 #endif
66
67 typedef union Prng_state {
68 char dummy[1];
6069 #ifdef LTC_YARROW
61 struct yarrow_prng yarrow;
70 struct yarrow_prng yarrow;
6271 #endif
6372 #ifdef LTC_RC4
64 struct rc4_prng rc4;
73 struct rc4_prng rc4;
6574 #endif
6675 #ifdef LTC_CHACHA20_PRNG
67 struct chacha20_prng chacha;
76 struct chacha20_prng chacha;
6877 #endif
6978 #ifdef LTC_FORTUNA
70 struct fortuna_prng fortuna;
79 struct fortuna_prng fortuna;
7180 #endif
7281 #ifdef LTC_SOBER128
73 struct sober128_prng sober128;
74 #endif
75 };
76 short ready; /* ready flag 0-1 */
77 LTC_MUTEX_TYPE(lock) /* lock */
82 struct sober128_prng sober128;
83 #endif
7884 } prng_state;
7985
8086 /** PRNG descriptor */
3636 int chacha20_prng_start(prng_state *prng)
3737 {
3838 LTC_ARGCHK(prng != NULL);
39 prng->ready = 0;
39 prng->chacha.ready = 0;
4040 XMEMSET(&prng->chacha.ent, 0, sizeof(prng->chacha.ent));
4141 prng->chacha.idx = 0;
42 LTC_MUTEX_INIT(&prng->lock)
42 LTC_MUTEX_INIT(&prng->chacha.lock)
4343 return CRYPT_OK;
4444 }
4545
6060 LTC_ARGCHK(in != NULL);
6161 LTC_ARGCHK(inlen > 0);
6262
63 LTC_MUTEX_LOCK(&prng->lock);
64 if (prng->ready) {
63 LTC_MUTEX_LOCK(&prng->chacha.lock);
64 if (prng->chacha.ready) {
6565 /* chacha20_prng_ready() was already called, do "rekey" operation */
6666 if ((err = chacha_keystream(&prng->chacha.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK;
6767 for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i];
7878 }
7979 err = CRYPT_OK;
8080 LBL_UNLOCK:
81 LTC_MUTEX_UNLOCK(&prng->lock);
81 LTC_MUTEX_UNLOCK(&prng->chacha.lock);
8282 return err;
8383 }
8484
9393
9494 LTC_ARGCHK(prng != NULL);
9595
96 LTC_MUTEX_LOCK(&prng->lock);
97 if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
96 LTC_MUTEX_LOCK(&prng->chacha.lock);
97 if (prng->chacha.ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
9898 /* key 32 bytes, 20 rounds */
9999 if ((err = chacha_setup(&prng->chacha.s, prng->chacha.ent, 32, 20)) != CRYPT_OK) goto LBL_UNLOCK;
100100 /* iv 8 bytes */
101101 if ((err = chacha_ivctr64(&prng->chacha.s, prng->chacha.ent + 32, 8, 0)) != CRYPT_OK) goto LBL_UNLOCK;
102102 XMEMSET(&prng->chacha.ent, 0, sizeof(prng->chacha.ent));
103103 prng->chacha.idx = 0;
104 prng->ready = 1;
104 prng->chacha.ready = 1;
105105 LBL_UNLOCK:
106 LTC_MUTEX_UNLOCK(&prng->lock);
106 LTC_MUTEX_UNLOCK(&prng->chacha.lock);
107107 return err;
108108 }
109109
117117 unsigned long chacha20_prng_read(unsigned char *out, unsigned long outlen, prng_state *prng)
118118 {
119119 if (outlen == 0 || prng == NULL || out == NULL) return 0;
120 LTC_MUTEX_LOCK(&prng->lock);
121 if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; }
120 LTC_MUTEX_LOCK(&prng->chacha.lock);
121 if (!prng->chacha.ready) { outlen = 0; goto LBL_UNLOCK; }
122122 if (chacha_keystream(&prng->chacha.s, out, outlen) != CRYPT_OK) outlen = 0;
123123 LBL_UNLOCK:
124 LTC_MUTEX_UNLOCK(&prng->lock);
124 LTC_MUTEX_UNLOCK(&prng->chacha.lock);
125125 return outlen;
126126 }
127127
134134 {
135135 int err;
136136 LTC_ARGCHK(prng != NULL);
137 LTC_MUTEX_LOCK(&prng->lock);
138 prng->ready = 0;
137 LTC_MUTEX_LOCK(&prng->chacha.lock);
138 prng->chacha.ready = 0;
139139 err = chacha_done(&prng->chacha.s);
140 LTC_MUTEX_UNLOCK(&prng->lock);
141 LTC_MUTEX_DESTROY(&prng->lock);
140 LTC_MUTEX_UNLOCK(&prng->chacha.lock);
141 LTC_MUTEX_DESTROY(&prng->chacha.lock);
142142 return err;
143143 }
144144
182182 unsigned char tmp[MAXBLOCKSIZE];
183183 hash_state md;
184184
185 LTC_MUTEX_LOCK(&prng->lock);
185 LTC_MUTEX_LOCK(&prng->fortuna.lock);
186186 /* new K = LTC_SHA256(K || in) */
187187 sha256_init(&md);
188188 if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) {
200200 _fortuna_update_iv(prng);
201201
202202 LBL_UNLOCK:
203 LTC_MUTEX_UNLOCK(&prng->lock);
203 LTC_MUTEX_UNLOCK(&prng->fortuna.lock);
204204 #ifdef LTC_CLEAN_STACK
205205 zeromem(&md, sizeof(md));
206206 #endif
219219 unsigned char tmp[MAXBLOCKSIZE];
220220
221221 LTC_ARGCHK(prng != NULL);
222 prng->ready = 0;
222 prng->fortuna.ready = 0;
223223
224224 /* initialize the pools */
225225 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
243243 }
244244 zeromem(prng->fortuna.IV, 16);
245245
246 LTC_MUTEX_INIT(&prng->lock)
246 LTC_MUTEX_INIT(&prng->fortuna.lock)
247247
248248 return CRYPT_OK;
249249 }
293293 LTC_ARGCHK(source <= 255);
294294 LTC_ARGCHK(pool < LTC_FORTUNA_POOLS);
295295
296 LTC_MUTEX_LOCK(&prng->lock);
296 LTC_MUTEX_LOCK(&prng->fortuna.lock);
297297
298298 err = _fortuna_add(source, pool, in, inlen, prng);
299299
300 LTC_MUTEX_UNLOCK(&prng->lock);
300 LTC_MUTEX_UNLOCK(&prng->fortuna.lock);
301301
302302 return err;
303303 }
317317 LTC_ARGCHK(in != NULL);
318318 LTC_ARGCHK(inlen > 0);
319319
320 LTC_MUTEX_LOCK(&prng->lock);
320 LTC_MUTEX_LOCK(&prng->fortuna.lock);
321321
322322 err = _fortuna_add(0, prng->fortuna.pool_idx, in, inlen, prng);
323323
326326 prng->fortuna.pool_idx %= LTC_FORTUNA_POOLS;
327327 }
328328
329 LTC_MUTEX_UNLOCK(&prng->lock);
329 LTC_MUTEX_UNLOCK(&prng->fortuna.lock);
330330
331331 return err;
332332 }
341341 int err;
342342 LTC_ARGCHK(prng != NULL);
343343
344 LTC_MUTEX_LOCK(&prng->lock);
344 LTC_MUTEX_LOCK(&prng->fortuna.lock);
345345 /* make sure the reseed doesn't fail because
346346 * of the chosen rate limit */
347347 #ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED
350350 prng->fortuna.wd = LTC_FORTUNA_WD;
351351 #endif
352352 err = _fortuna_reseed(prng);
353 prng->ready = (err == CRYPT_OK) ? 1 : 0;
354
355 LTC_MUTEX_UNLOCK(&prng->lock);
353 prng->fortuna.ready = (err == CRYPT_OK) ? 1 : 0;
354
355 LTC_MUTEX_UNLOCK(&prng->fortuna.lock);
356356 return err;
357357 }
358358
370370
371371 if (outlen == 0 || prng == NULL || out == NULL) return 0;
372372
373 LTC_MUTEX_LOCK(&prng->lock);
374
375 if (!prng->ready) {
373 LTC_MUTEX_LOCK(&prng->fortuna.lock);
374
375 if (!prng->fortuna.ready) {
376376 goto LBL_UNLOCK;
377377 }
378378
422422 #ifdef LTC_CLEAN_STACK
423423 zeromem(tmp, sizeof(tmp));
424424 #endif
425 LTC_MUTEX_UNLOCK(&prng->lock);
425 LTC_MUTEX_UNLOCK(&prng->fortuna.lock);
426426 return tlen;
427427 }
428428
438438
439439 LTC_ARGCHK(prng != NULL);
440440
441 LTC_MUTEX_LOCK(&prng->lock);
442 prng->ready = 0;
441 LTC_MUTEX_LOCK(&prng->fortuna.lock);
442 prng->fortuna.ready = 0;
443443
444444 /* terminate all the hashes */
445445 for (x = 0; x < LTC_FORTUNA_POOLS; x++) {
454454 #ifdef LTC_CLEAN_STACK
455455 zeromem(tmp, sizeof(tmp));
456456 #endif
457 LTC_MUTEX_UNLOCK(&prng->lock);
458 LTC_MUTEX_DESTROY(&prng->lock);
457 LTC_MUTEX_UNLOCK(&prng->fortuna.lock);
458 LTC_MUTEX_DESTROY(&prng->fortuna.lock);
459459 return err;
460460 }
461461
3636 int rc4_start(prng_state *prng)
3737 {
3838 LTC_ARGCHK(prng != NULL);
39 prng->ready = 0;
39 prng->rc4.ready = 0;
4040 /* set entropy (key) size to zero */
4141 prng->rc4.s.x = 0;
4242 /* clear entropy (key) buffer */
4343 XMEMSET(&prng->rc4.s.buf, 0, sizeof(prng->rc4.s.buf));
44 LTC_MUTEX_INIT(&prng->lock)
44 LTC_MUTEX_INIT(&prng->rc4.lock)
4545 return CRYPT_OK;
4646 }
4747
6262 LTC_ARGCHK(in != NULL);
6363 LTC_ARGCHK(inlen > 0);
6464
65 LTC_MUTEX_LOCK(&prng->lock);
66 if (prng->ready) {
65 LTC_MUTEX_LOCK(&prng->rc4.lock);
66 if (prng->rc4.ready) {
6767 /* rc4_ready() was already called, do "rekey" operation */
6868 if ((err = rc4_stream_keystream(&prng->rc4.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK;
6969 for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i];
7979 }
8080 err = CRYPT_OK;
8181 LBL_UNLOCK:
82 LTC_MUTEX_UNLOCK(&prng->lock);
82 LTC_MUTEX_UNLOCK(&prng->rc4.lock);
8383 return err;
8484 }
8585
9696
9797 LTC_ARGCHK(prng != NULL);
9898
99 LTC_MUTEX_LOCK(&prng->lock);
100 if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
99 LTC_MUTEX_LOCK(&prng->rc4.lock);
100 if (prng->rc4.ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
101101 XMEMCPY(buf, prng->rc4.s.buf, sizeof(buf));
102102 /* initialize RC4 */
103103 len = MIN(prng->rc4.s.x, 256); /* TODO: we can perhaps always use all 256 bytes */
104104 if ((err = rc4_stream_setup(&prng->rc4.s, buf, len)) != CRYPT_OK) goto LBL_UNLOCK;
105105 /* drop first 3072 bytes - https://en.wikipedia.org/wiki/RC4#Fluhrer.2C_Mantin_and_Shamir_attack */
106106 for (i = 0; i < 12; i++) rc4_stream_keystream(&prng->rc4.s, buf, sizeof(buf));
107 prng->ready = 1;
107 prng->rc4.ready = 1;
108108 LBL_UNLOCK:
109 LTC_MUTEX_UNLOCK(&prng->lock);
109 LTC_MUTEX_UNLOCK(&prng->rc4.lock);
110110 return err;
111111 }
112112
120120 unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng)
121121 {
122122 if (outlen == 0 || prng == NULL || out == NULL) return 0;
123 LTC_MUTEX_LOCK(&prng->lock);
124 if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; }
123 LTC_MUTEX_LOCK(&prng->rc4.lock);
124 if (!prng->rc4.ready) { outlen = 0; goto LBL_UNLOCK; }
125125 if (rc4_stream_keystream(&prng->rc4.s, out, outlen) != CRYPT_OK) outlen = 0;
126126 LBL_UNLOCK:
127 LTC_MUTEX_UNLOCK(&prng->lock);
127 LTC_MUTEX_UNLOCK(&prng->rc4.lock);
128128 return outlen;
129129 }
130130
137137 {
138138 int err;
139139 LTC_ARGCHK(prng != NULL);
140 LTC_MUTEX_LOCK(&prng->lock);
141 prng->ready = 0;
140 LTC_MUTEX_LOCK(&prng->rc4.lock);
141 prng->rc4.ready = 0;
142142 err = rc4_stream_done(&prng->rc4.s);
143 LTC_MUTEX_UNLOCK(&prng->lock);
144 LTC_MUTEX_DESTROY(&prng->lock);
143 LTC_MUTEX_UNLOCK(&prng->rc4.lock);
144 LTC_MUTEX_DESTROY(&prng->rc4.lock);
145145 return err;
146146 }
147147
3838 int sober128_start(prng_state *prng)
3939 {
4040 LTC_ARGCHK(prng != NULL);
41 prng->ready = 0;
41 prng->sober128.ready = 0;
4242 XMEMSET(&prng->sober128.ent, 0, sizeof(prng->sober128.ent));
4343 prng->sober128.idx = 0;
44 LTC_MUTEX_INIT(&prng->lock)
44 LTC_MUTEX_INIT(&prng->sober128.lock)
4545 return CRYPT_OK;
4646 }
4747
6262 LTC_ARGCHK(in != NULL);
6363 LTC_ARGCHK(inlen > 0);
6464
65 LTC_MUTEX_LOCK(&prng->lock);
66 if (prng->ready) {
65 LTC_MUTEX_LOCK(&prng->sober128.lock);
66 if (prng->sober128.ready) {
6767 /* sober128_ready() was already called, do "rekey" operation */
6868 if ((err = sober128_stream_keystream(&prng->sober128.s, buf, sizeof(buf))) != CRYPT_OK) goto LBL_UNLOCK;
6969 for(i = 0; i < inlen; i++) buf[i % sizeof(buf)] ^= in[i];
8080 }
8181 err = CRYPT_OK;
8282 LBL_UNLOCK:
83 LTC_MUTEX_UNLOCK(&prng->lock);
83 LTC_MUTEX_UNLOCK(&prng->sober128.lock);
8484 return err;
8585 }
8686
9595
9696 LTC_ARGCHK(prng != NULL);
9797
98 LTC_MUTEX_LOCK(&prng->lock);
99 if (prng->ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
98 LTC_MUTEX_LOCK(&prng->sober128.lock);
99 if (prng->sober128.ready) { err = CRYPT_OK; goto LBL_UNLOCK; }
100100 /* key 32 bytes, 20 rounds */
101101 if ((err = sober128_stream_setup(&prng->sober128.s, prng->sober128.ent, 32)) != CRYPT_OK) goto LBL_UNLOCK;
102102 /* iv 8 bytes */
103103 if ((err = sober128_stream_setiv(&prng->sober128.s, prng->sober128.ent + 32, 8)) != CRYPT_OK) goto LBL_UNLOCK;
104104 XMEMSET(&prng->sober128.ent, 0, sizeof(prng->sober128.ent));
105105 prng->sober128.idx = 0;
106 prng->ready = 1;
106 prng->sober128.ready = 1;
107107 LBL_UNLOCK:
108 LTC_MUTEX_UNLOCK(&prng->lock);
108 LTC_MUTEX_UNLOCK(&prng->sober128.lock);
109109 return err;
110110 }
111111
119119 unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng)
120120 {
121121 if (outlen == 0 || prng == NULL || out == NULL) return 0;
122 LTC_MUTEX_LOCK(&prng->lock);
123 if (!prng->ready) { outlen = 0; goto LBL_UNLOCK; }
122 LTC_MUTEX_LOCK(&prng->sober128.lock);
123 if (!prng->sober128.ready) { outlen = 0; goto LBL_UNLOCK; }
124124 if (sober128_stream_keystream(&prng->sober128.s, out, outlen) != CRYPT_OK) outlen = 0;
125125 LBL_UNLOCK:
126 LTC_MUTEX_UNLOCK(&prng->lock);
126 LTC_MUTEX_UNLOCK(&prng->sober128.lock);
127127 return outlen;
128128 }
129129
136136 {
137137 int err;
138138 LTC_ARGCHK(prng != NULL);
139 LTC_MUTEX_LOCK(&prng->lock);
140 prng->ready = 0;
139 LTC_MUTEX_LOCK(&prng->sober128.lock);
140 prng->sober128.ready = 0;
141141 err = sober128_stream_done(&prng->sober128.s);
142 LTC_MUTEX_UNLOCK(&prng->lock);
143 LTC_MUTEX_DESTROY(&prng->lock);
142 LTC_MUTEX_UNLOCK(&prng->sober128.lock);
143 LTC_MUTEX_DESTROY(&prng->sober128.lock);
144144 return err;
145145 }
146146
3737 int err;
3838
3939 LTC_ARGCHK(prng != NULL);
40 prng->ready = 0;
40 prng->yarrow.ready = 0;
4141
4242 /* these are the default hash/cipher combo used */
4343 #ifdef LTC_RIJNDAEL
118118
119119 /* zero the memory used */
120120 zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool));
121 LTC_MUTEX_INIT(&prng->lock)
121 LTC_MUTEX_INIT(&prng->yarrow.lock)
122122
123123 return CRYPT_OK;
124124 }
139139 LTC_ARGCHK(in != NULL);
140140 LTC_ARGCHK(inlen > 0);
141141
142 LTC_MUTEX_LOCK(&prng->lock);
142 LTC_MUTEX_LOCK(&prng->yarrow.lock);
143143
144144 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
145145 goto LBL_UNLOCK;
165165 err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool);
166166
167167 LBL_UNLOCK:
168 LTC_MUTEX_UNLOCK(&prng->lock);
168 LTC_MUTEX_UNLOCK(&prng->yarrow.lock);
169169 return err;
170170 }
171171
180180
181181 LTC_ARGCHK(prng != NULL);
182182
183 LTC_MUTEX_LOCK(&prng->lock);
183 LTC_MUTEX_LOCK(&prng->yarrow.lock);
184184
185185 if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
186186 goto LBL_UNLOCK;
204204 &prng->yarrow.ctr)) != CRYPT_OK) {
205205 goto LBL_UNLOCK;
206206 }
207 prng->ready = 1;
207 prng->yarrow.ready = 1;
208208
209209 LBL_UNLOCK:
210 LTC_MUTEX_UNLOCK(&prng->lock);
210 LTC_MUTEX_UNLOCK(&prng->yarrow.lock);
211211 return err;
212212 }
213213
222222 {
223223 if (outlen == 0 || prng == NULL || out == NULL) return 0;
224224
225 LTC_MUTEX_LOCK(&prng->lock);
226
227 if (!prng->ready) {
225 LTC_MUTEX_LOCK(&prng->yarrow.lock);
226
227 if (!prng->yarrow.ready) {
228228 outlen = 0;
229229 goto LBL_UNLOCK;
230230 }
238238 }
239239
240240 LBL_UNLOCK:
241 LTC_MUTEX_UNLOCK(&prng->lock);
241 LTC_MUTEX_UNLOCK(&prng->yarrow.lock);
242242 return outlen;
243243 }
244244
252252 int err;
253253 LTC_ARGCHK(prng != NULL);
254254
255 LTC_MUTEX_LOCK(&prng->lock);
256 prng->ready = 0;
255 LTC_MUTEX_LOCK(&prng->yarrow.lock);
256 prng->yarrow.ready = 0;
257257
258258 /* call cipher done when we invent one ;-) */
259259
260260 /* we invented one */
261261 err = ctr_done(&prng->yarrow.ctr);
262262
263 LTC_MUTEX_UNLOCK(&prng->lock);
264 LTC_MUTEX_DESTROY(&prng->lock);
263 LTC_MUTEX_UNLOCK(&prng->yarrow.lock);
264 LTC_MUTEX_DESTROY(&prng->yarrow.lock);
265265 return err;
266266 }
267267