~ubuntu-branches/debian/sid/postgresql-9.3/sid

« back to all changes in this revision

Viewing changes to contrib/pgcrypto/internal.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-05-08 05:39:52 UTC
  • Revision ID: package-import@ubuntu.com-20130508053952-1j7uilp7mjtrvq8q
Tags: upstream-9.3~beta1
ImportĀ upstreamĀ versionĀ 9.3~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * internal.c
 
3
 *              Wrapper for builtin functions
 
4
 *
 
5
 * Copyright (c) 2001 Marko Kreen
 
6
 * All rights reserved.
 
7
 *
 
8
 * Redistribution and use in source and binary forms, with or without
 
9
 * modification, are permitted provided that the following conditions
 
10
 * are met:
 
11
 * 1. Redistributions of source code must retain the above copyright
 
12
 *        notice, this list of conditions and the following disclaimer.
 
13
 * 2. Redistributions in binary form must reproduce the above copyright
 
14
 *        notice, this list of conditions and the following disclaimer in the
 
15
 *        documentation and/or other materials provided with the distribution.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 
18
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
20
 * ARE DISCLAIMED.      IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 
21
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
22
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
23
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
24
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
26
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
27
 * SUCH DAMAGE.
 
28
 *
 
29
 * contrib/pgcrypto/internal.c
 
30
 */
 
31
 
 
32
#include "postgres.h"
 
33
 
 
34
#include <time.h>
 
35
 
 
36
#include "px.h"
 
37
#include "md5.h"
 
38
#include "sha1.h"
 
39
#include "blf.h"
 
40
#include "rijndael.h"
 
41
#include "fortuna.h"
 
42
 
 
43
/*
 
44
 * System reseeds should be separated at least this much.
 
45
 */
 
46
#define SYSTEM_RESEED_MIN                       (20*60)         /* 20 min */
 
47
/*
 
48
 * How often to roll dice.
 
49
 */
 
50
#define SYSTEM_RESEED_CHECK_TIME        (10*60)         /* 10 min */
 
51
/*
 
52
 * The chance is x/256 that the reseed happens.
 
53
 */
 
54
#define SYSTEM_RESEED_CHANCE            (4) /* 256/4 * 10min ~ 10h */
 
55
 
 
56
/*
 
57
 * If this much time has passed, force reseed.
 
58
 */
 
59
#define SYSTEM_RESEED_MAX                       (12*60*60)      /* 12h */
 
60
 
 
61
 
 
62
#ifndef MD5_DIGEST_LENGTH
 
63
#define MD5_DIGEST_LENGTH 16
 
64
#endif
 
65
 
 
66
#ifndef SHA1_DIGEST_LENGTH
 
67
#ifdef SHA1_RESULTLEN
 
68
#define SHA1_DIGEST_LENGTH SHA1_RESULTLEN
 
69
#else
 
70
#define SHA1_DIGEST_LENGTH 20
 
71
#endif
 
72
#endif
 
73
 
 
74
#define SHA1_BLOCK_SIZE 64
 
75
#define MD5_BLOCK_SIZE 64
 
76
 
 
77
static void init_md5(PX_MD *h);
 
78
static void init_sha1(PX_MD *h);
 
79
 
 
80
void            init_sha224(PX_MD *h);
 
81
void            init_sha256(PX_MD *h);
 
82
void            init_sha384(PX_MD *h);
 
83
void            init_sha512(PX_MD *h);
 
84
 
 
85
struct int_digest
 
86
{
 
87
        char       *name;
 
88
        void            (*init) (PX_MD *h);
 
89
};
 
90
 
 
91
static const struct int_digest
 
92
                        int_digest_list[] = {
 
93
        {"md5", init_md5},
 
94
        {"sha1", init_sha1},
 
95
        {"sha224", init_sha224},
 
96
        {"sha256", init_sha256},
 
97
        {"sha384", init_sha384},
 
98
        {"sha512", init_sha512},
 
99
        {NULL, NULL}
 
100
};
 
101
 
 
102
/* MD5 */
 
103
 
 
104
static unsigned
 
105
int_md5_len(PX_MD *h)
 
106
{
 
107
        return MD5_DIGEST_LENGTH;
 
108
}
 
109
 
 
110
static unsigned
 
111
int_md5_block_len(PX_MD *h)
 
112
{
 
113
        return MD5_BLOCK_SIZE;
 
114
}
 
115
 
 
116
static void
 
117
int_md5_update(PX_MD *h, const uint8 *data, unsigned dlen)
 
118
{
 
119
        MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
 
120
 
 
121
        MD5Update(ctx, data, dlen);
 
122
}
 
123
 
 
124
static void
 
125
int_md5_reset(PX_MD *h)
 
126
{
 
127
        MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
 
128
 
 
129
        MD5Init(ctx);
 
130
}
 
131
 
 
132
static void
 
133
int_md5_finish(PX_MD *h, uint8 *dst)
 
134
{
 
135
        MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
 
136
 
 
137
        MD5Final(dst, ctx);
 
138
}
 
139
 
 
140
static void
 
141
int_md5_free(PX_MD *h)
 
142
{
 
143
        MD5_CTX    *ctx = (MD5_CTX *) h->p.ptr;
 
144
 
 
145
        memset(ctx, 0, sizeof(*ctx));
 
146
        px_free(ctx);
 
147
        px_free(h);
 
148
}
 
149
 
 
150
/* SHA1 */
 
151
 
 
152
static unsigned
 
153
int_sha1_len(PX_MD *h)
 
154
{
 
155
        return SHA1_DIGEST_LENGTH;
 
156
}
 
157
 
 
158
static unsigned
 
159
int_sha1_block_len(PX_MD *h)
 
160
{
 
161
        return SHA1_BLOCK_SIZE;
 
162
}
 
163
 
 
164
static void
 
165
int_sha1_update(PX_MD *h, const uint8 *data, unsigned dlen)
 
166
{
 
167
        SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
 
168
 
 
169
        SHA1Update(ctx, data, dlen);
 
170
}
 
171
 
 
172
static void
 
173
int_sha1_reset(PX_MD *h)
 
174
{
 
175
        SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
 
176
 
 
177
        SHA1Init(ctx);
 
178
}
 
179
 
 
180
static void
 
181
int_sha1_finish(PX_MD *h, uint8 *dst)
 
182
{
 
183
        SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
 
184
 
 
185
        SHA1Final(dst, ctx);
 
186
}
 
187
 
 
188
static void
 
189
int_sha1_free(PX_MD *h)
 
190
{
 
191
        SHA1_CTX   *ctx = (SHA1_CTX *) h->p.ptr;
 
192
 
 
193
        memset(ctx, 0, sizeof(*ctx));
 
194
        px_free(ctx);
 
195
        px_free(h);
 
196
}
 
197
 
 
198
/* init functions */
 
199
 
 
200
static void
 
201
init_md5(PX_MD *md)
 
202
{
 
203
        MD5_CTX    *ctx;
 
204
 
 
205
        ctx = px_alloc(sizeof(*ctx));
 
206
        memset(ctx, 0, sizeof(*ctx));
 
207
 
 
208
        md->p.ptr = ctx;
 
209
 
 
210
        md->result_size = int_md5_len;
 
211
        md->block_size = int_md5_block_len;
 
212
        md->reset = int_md5_reset;
 
213
        md->update = int_md5_update;
 
214
        md->finish = int_md5_finish;
 
215
        md->free = int_md5_free;
 
216
 
 
217
        md->reset(md);
 
218
}
 
219
 
 
220
static void
 
221
init_sha1(PX_MD *md)
 
222
{
 
223
        SHA1_CTX   *ctx;
 
224
 
 
225
        ctx = px_alloc(sizeof(*ctx));
 
226
        memset(ctx, 0, sizeof(*ctx));
 
227
 
 
228
        md->p.ptr = ctx;
 
229
 
 
230
        md->result_size = int_sha1_len;
 
231
        md->block_size = int_sha1_block_len;
 
232
        md->reset = int_sha1_reset;
 
233
        md->update = int_sha1_update;
 
234
        md->finish = int_sha1_finish;
 
235
        md->free = int_sha1_free;
 
236
 
 
237
        md->reset(md);
 
238
}
 
239
 
 
240
/*
 
241
 * ciphers generally
 
242
 */
 
243
 
 
244
#define INT_MAX_KEY             (512/8)
 
245
#define INT_MAX_IV              (128/8)
 
246
 
 
247
struct int_ctx
 
248
{
 
249
        uint8           keybuf[INT_MAX_KEY];
 
250
        uint8           iv[INT_MAX_IV];
 
251
        union
 
252
        {
 
253
                BlowfishContext bf;
 
254
                rijndael_ctx rj;
 
255
        }                       ctx;
 
256
        unsigned        keylen;
 
257
        int                     is_init;
 
258
        int                     mode;
 
259
};
 
260
 
 
261
static void
 
262
intctx_free(PX_Cipher *c)
 
263
{
 
264
        struct int_ctx *cx = (struct int_ctx *) c->ptr;
 
265
 
 
266
        if (cx)
 
267
        {
 
268
                memset(cx, 0, sizeof *cx);
 
269
                px_free(cx);
 
270
        }
 
271
        px_free(c);
 
272
}
 
273
 
 
274
/*
 
275
 * AES/rijndael
 
276
 */
 
277
 
 
278
#define MODE_ECB 0
 
279
#define MODE_CBC 1
 
280
 
 
281
static unsigned
 
282
rj_block_size(PX_Cipher *c)
 
283
{
 
284
        return 128 / 8;
 
285
}
 
286
 
 
287
static unsigned
 
288
rj_key_size(PX_Cipher *c)
 
289
{
 
290
        return 256 / 8;
 
291
}
 
292
 
 
293
static unsigned
 
294
rj_iv_size(PX_Cipher *c)
 
295
{
 
296
        return 128 / 8;
 
297
}
 
298
 
 
299
static int
 
300
rj_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
 
301
{
 
302
        struct int_ctx *cx = (struct int_ctx *) c->ptr;
 
303
 
 
304
        if (klen <= 128 / 8)
 
305
                cx->keylen = 128 / 8;
 
306
        else if (klen <= 192 / 8)
 
307
                cx->keylen = 192 / 8;
 
308
        else if (klen <= 256 / 8)
 
309
                cx->keylen = 256 / 8;
 
310
        else
 
311
                return PXE_KEY_TOO_BIG;
 
312
 
 
313
        memcpy(&cx->keybuf, key, klen);
 
314
 
 
315
        if (iv)
 
316
                memcpy(cx->iv, iv, 128 / 8);
 
317
 
 
318
        return 0;
 
319
}
 
320
 
 
321
static int
 
322
rj_real_init(struct int_ctx * cx, int dir)
 
323
{
 
324
        aes_set_key(&cx->ctx.rj, cx->keybuf, cx->keylen * 8, dir);
 
325
        return 0;
 
326
}
 
327
 
 
328
static int
 
329
rj_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
 
330
{
 
331
        struct int_ctx *cx = (struct int_ctx *) c->ptr;
 
332
 
 
333
        if (!cx->is_init)
 
334
        {
 
335
                if (rj_real_init(cx, 1))
 
336
                        return PXE_CIPHER_INIT;
 
337
        }
 
338
 
 
339
        if (dlen == 0)
 
340
                return 0;
 
341
 
 
342
        if (dlen & 15)
 
343
                return PXE_NOTBLOCKSIZE;
 
344
 
 
345
        memcpy(res, data, dlen);
 
346
 
 
347
        if (cx->mode == MODE_CBC)
 
348
        {
 
349
                aes_cbc_encrypt(&cx->ctx.rj, cx->iv, res, dlen);
 
350
                memcpy(cx->iv, res + dlen - 16, 16);
 
351
        }
 
352
        else
 
353
                aes_ecb_encrypt(&cx->ctx.rj, res, dlen);
 
354
 
 
355
        return 0;
 
356
}
 
357
 
 
358
static int
 
359
rj_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
 
360
{
 
361
        struct int_ctx *cx = (struct int_ctx *) c->ptr;
 
362
 
 
363
        if (!cx->is_init)
 
364
                if (rj_real_init(cx, 0))
 
365
                        return PXE_CIPHER_INIT;
 
366
 
 
367
        if (dlen == 0)
 
368
                return 0;
 
369
 
 
370
        if (dlen & 15)
 
371
                return PXE_NOTBLOCKSIZE;
 
372
 
 
373
        memcpy(res, data, dlen);
 
374
 
 
375
        if (cx->mode == MODE_CBC)
 
376
        {
 
377
                aes_cbc_decrypt(&cx->ctx.rj, cx->iv, res, dlen);
 
378
                memcpy(cx->iv, data + dlen - 16, 16);
 
379
        }
 
380
        else
 
381
                aes_ecb_decrypt(&cx->ctx.rj, res, dlen);
 
382
 
 
383
        return 0;
 
384
}
 
385
 
 
386
/*
 
387
 * initializers
 
388
 */
 
389
 
 
390
static PX_Cipher *
 
391
rj_load(int mode)
 
392
{
 
393
        PX_Cipher  *c;
 
394
        struct int_ctx *cx;
 
395
 
 
396
        c = px_alloc(sizeof *c);
 
397
        memset(c, 0, sizeof *c);
 
398
 
 
399
        c->block_size = rj_block_size;
 
400
        c->key_size = rj_key_size;
 
401
        c->iv_size = rj_iv_size;
 
402
        c->init = rj_init;
 
403
        c->encrypt = rj_encrypt;
 
404
        c->decrypt = rj_decrypt;
 
405
        c->free = intctx_free;
 
406
 
 
407
        cx = px_alloc(sizeof *cx);
 
408
        memset(cx, 0, sizeof *cx);
 
409
        cx->mode = mode;
 
410
 
 
411
        c->ptr = cx;
 
412
        return c;
 
413
}
 
414
 
 
415
/*
 
416
 * blowfish
 
417
 */
 
418
 
 
419
static unsigned
 
420
bf_block_size(PX_Cipher *c)
 
421
{
 
422
        return 8;
 
423
}
 
424
 
 
425
static unsigned
 
426
bf_key_size(PX_Cipher *c)
 
427
{
 
428
        return 448 / 8;
 
429
}
 
430
 
 
431
static unsigned
 
432
bf_iv_size(PX_Cipher *c)
 
433
{
 
434
        return 8;
 
435
}
 
436
 
 
437
static int
 
438
bf_init(PX_Cipher *c, const uint8 *key, unsigned klen, const uint8 *iv)
 
439
{
 
440
        struct int_ctx *cx = (struct int_ctx *) c->ptr;
 
441
 
 
442
        blowfish_setkey(&cx->ctx.bf, key, klen);
 
443
        if (iv)
 
444
                blowfish_setiv(&cx->ctx.bf, iv);
 
445
 
 
446
        return 0;
 
447
}
 
448
 
 
449
static int
 
450
bf_encrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
 
451
{
 
452
        struct int_ctx *cx = (struct int_ctx *) c->ptr;
 
453
        BlowfishContext *bfctx = &cx->ctx.bf;
 
454
 
 
455
        if (dlen == 0)
 
456
                return 0;
 
457
 
 
458
        if (dlen & 7)
 
459
                return PXE_NOTBLOCKSIZE;
 
460
 
 
461
        memcpy(res, data, dlen);
 
462
        switch (cx->mode)
 
463
        {
 
464
                case MODE_ECB:
 
465
                        blowfish_encrypt_ecb(res, dlen, bfctx);
 
466
                        break;
 
467
                case MODE_CBC:
 
468
                        blowfish_encrypt_cbc(res, dlen, bfctx);
 
469
                        break;
 
470
        }
 
471
        return 0;
 
472
}
 
473
 
 
474
static int
 
475
bf_decrypt(PX_Cipher *c, const uint8 *data, unsigned dlen, uint8 *res)
 
476
{
 
477
        struct int_ctx *cx = (struct int_ctx *) c->ptr;
 
478
        BlowfishContext *bfctx = &cx->ctx.bf;
 
479
 
 
480
        if (dlen == 0)
 
481
                return 0;
 
482
 
 
483
        if (dlen & 7)
 
484
                return PXE_NOTBLOCKSIZE;
 
485
 
 
486
        memcpy(res, data, dlen);
 
487
        switch (cx->mode)
 
488
        {
 
489
                case MODE_ECB:
 
490
                        blowfish_decrypt_ecb(res, dlen, bfctx);
 
491
                        break;
 
492
                case MODE_CBC:
 
493
                        blowfish_decrypt_cbc(res, dlen, bfctx);
 
494
                        break;
 
495
        }
 
496
        return 0;
 
497
}
 
498
 
 
499
static PX_Cipher *
 
500
bf_load(int mode)
 
501
{
 
502
        PX_Cipher  *c;
 
503
        struct int_ctx *cx;
 
504
 
 
505
        c = px_alloc(sizeof *c);
 
506
        memset(c, 0, sizeof *c);
 
507
 
 
508
        c->block_size = bf_block_size;
 
509
        c->key_size = bf_key_size;
 
510
        c->iv_size = bf_iv_size;
 
511
        c->init = bf_init;
 
512
        c->encrypt = bf_encrypt;
 
513
        c->decrypt = bf_decrypt;
 
514
        c->free = intctx_free;
 
515
 
 
516
        cx = px_alloc(sizeof *cx);
 
517
        memset(cx, 0, sizeof *cx);
 
518
        cx->mode = mode;
 
519
        c->ptr = cx;
 
520
        return c;
 
521
}
 
522
 
 
523
/* ciphers */
 
524
 
 
525
static PX_Cipher *
 
526
rj_128_ecb(void)
 
527
{
 
528
        return rj_load(MODE_ECB);
 
529
}
 
530
 
 
531
static PX_Cipher *
 
532
rj_128_cbc(void)
 
533
{
 
534
        return rj_load(MODE_CBC);
 
535
}
 
536
 
 
537
static PX_Cipher *
 
538
bf_ecb_load(void)
 
539
{
 
540
        return bf_load(MODE_ECB);
 
541
}
 
542
 
 
543
static PX_Cipher *
 
544
bf_cbc_load(void)
 
545
{
 
546
        return bf_load(MODE_CBC);
 
547
}
 
548
 
 
549
struct int_cipher
 
550
{
 
551
        char       *name;
 
552
        PX_Cipher  *(*load) (void);
 
553
};
 
554
 
 
555
static const struct int_cipher
 
556
                        int_ciphers[] = {
 
557
        {"bf-cbc", bf_cbc_load},
 
558
        {"bf-ecb", bf_ecb_load},
 
559
        {"aes-128-cbc", rj_128_cbc},
 
560
        {"aes-128-ecb", rj_128_ecb},
 
561
        {NULL, NULL}
 
562
};
 
563
 
 
564
static const PX_Alias int_aliases[] = {
 
565
        {"bf", "bf-cbc"},
 
566
        {"blowfish", "bf-cbc"},
 
567
        {"aes", "aes-128-cbc"},
 
568
        {"aes-ecb", "aes-128-ecb"},
 
569
        {"aes-cbc", "aes-128-cbc"},
 
570
        {"aes-128", "aes-128-cbc"},
 
571
        {"rijndael", "aes-128-cbc"},
 
572
        {"rijndael-128", "aes-128-cbc"},
 
573
        {NULL, NULL}
 
574
};
 
575
 
 
576
/* PUBLIC FUNCTIONS */
 
577
 
 
578
int
 
579
px_find_digest(const char *name, PX_MD **res)
 
580
{
 
581
        const struct int_digest *p;
 
582
        PX_MD      *h;
 
583
 
 
584
        for (p = int_digest_list; p->name; p++)
 
585
                if (pg_strcasecmp(p->name, name) == 0)
 
586
                {
 
587
                        h = px_alloc(sizeof(*h));
 
588
                        p->init(h);
 
589
 
 
590
                        *res = h;
 
591
 
 
592
                        return 0;
 
593
                }
 
594
        return PXE_NO_HASH;
 
595
}
 
596
 
 
597
int
 
598
px_find_cipher(const char *name, PX_Cipher **res)
 
599
{
 
600
        int                     i;
 
601
        PX_Cipher  *c = NULL;
 
602
 
 
603
        name = px_resolve_alias(int_aliases, name);
 
604
 
 
605
        for (i = 0; int_ciphers[i].name; i++)
 
606
                if (strcmp(int_ciphers[i].name, name) == 0)
 
607
                {
 
608
                        c = int_ciphers[i].load();
 
609
                        break;
 
610
                }
 
611
 
 
612
        if (c == NULL)
 
613
                return PXE_NO_CIPHER;
 
614
 
 
615
        *res = c;
 
616
        return 0;
 
617
}
 
618
 
 
619
/*
 
620
 * Randomness provider
 
621
 */
 
622
 
 
623
/*
 
624
 * Use always strong randomness.
 
625
 */
 
626
int
 
627
px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
 
628
{
 
629
        return px_get_random_bytes(dst, count);
 
630
}
 
631
 
 
632
static time_t seed_time = 0;
 
633
static time_t check_time = 0;
 
634
 
 
635
static void
 
636
system_reseed(void)
 
637
{
 
638
        uint8           buf[1024];
 
639
        int                     n;
 
640
        time_t          t;
 
641
        int                     skip = 1;
 
642
 
 
643
        t = time(NULL);
 
644
 
 
645
        if (seed_time == 0)
 
646
                skip = 0;
 
647
        else if ((t - seed_time) < SYSTEM_RESEED_MIN)
 
648
                skip = 1;
 
649
        else if ((t - seed_time) > SYSTEM_RESEED_MAX)
 
650
                skip = 0;
 
651
        else if (check_time == 0 ||
 
652
                         (t - check_time) > SYSTEM_RESEED_CHECK_TIME)
 
653
        {
 
654
                check_time = t;
 
655
 
 
656
                /* roll dice */
 
657
                px_get_random_bytes(buf, 1);
 
658
                skip = buf[0] >= SYSTEM_RESEED_CHANCE;
 
659
        }
 
660
        /* clear 1 byte */
 
661
        memset(buf, 0, sizeof(buf));
 
662
 
 
663
        if (skip)
 
664
                return;
 
665
 
 
666
        n = px_acquire_system_randomness(buf);
 
667
        if (n > 0)
 
668
                fortuna_add_entropy(buf, n);
 
669
 
 
670
        seed_time = t;
 
671
        memset(buf, 0, sizeof(buf));
 
672
}
 
673
 
 
674
int
 
675
px_get_random_bytes(uint8 *dst, unsigned count)
 
676
{
 
677
        system_reseed();
 
678
        fortuna_get_bytes(count, dst);
 
679
        return 0;
 
680
}
 
681
 
 
682
int
 
683
px_add_entropy(const uint8 *data, unsigned count)
 
684
{
 
685
        system_reseed();
 
686
        fortuna_add_entropy(data, count);
 
687
        return 0;
 
688
}