]>
git.ipfire.org Git - people/ms/strongswan.git/blob - src/libfreeswan/prng.c
2 * crypto-class pseudorandom number generator
3 * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
4 * Copyright (C) 2002 Henry Spencer.
6 * This library is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Library General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14 * License for more details.
16 * RCSID $Id: prng.c,v 1.1 2004/03/15 20:35:26 as Exp $
22 - prng_init - initialize PRNG from a key
25 prng_init(prng
, key
, keylen
)
27 const unsigned char *key
;
32 unsigned const char *p
;
33 unsigned const char *keyend
= key
+ keylen
;
36 for (i
= 0; i
<= 255; i
++)
39 for (i
= 0; i
<= 255; i
++) {
45 for (i
= 0; i
<= 255; i
++) {
46 j
= (j
+ prng
->sbox
[i
] + k
[i
]) & 0xff;
48 prng
->sbox
[i
] = prng
->sbox
[j
];
50 k
[i
] = 0; /* clear out key memory */
58 - prng_bytes - get some pseudorandom bytes from PRNG
61 prng_bytes(prng
, dst
, dstlen
)
67 unsigned char *p
= dst
;
68 size_t remain
= dstlen
;
69 # define MAX 4000000000ul
72 i
= (prng
->i
+ 1) & 0xff;
74 j
= (prng
->j
+ prng
->sbox
[i
]) & 0xff;
77 prng
->sbox
[i
] = prng
->sbox
[j
];
79 t
= (t
+ prng
->sbox
[i
]) & 0xff;
83 if (prng
->count
< MAX
- dstlen
)
84 prng
->count
+= dstlen
;
90 - prnt_count - how many bytes have been extracted from PRNG so far?
100 - prng_final - clear out PRNG to ensure nothing left in memory
108 for (i
= 0; i
<= 255; i
++)
112 prng
->count
= 0; /* just for good measure */
129 unsigned char buf
[100];
134 fprintf(stderr
, "Usage: %s {key|-r}\n", argv
[0]);
138 if (strcmp(argv
[1], "-r") == 0) {
140 fprintf(stderr
, "regress() returned?!?\n");
144 prng_init(&pr
, argv
[1], strlen(argv
[1]));
145 prng_bytes(&pr
, buf
, 32);
147 for (p
= buf
, n
= 32; n
> 0; p
++, n
--)
149 printf("\n%lu bytes\n", prng_count(&pr
));
158 unsigned char buf
[100];
161 /* somewhat non-random sample key */
162 unsigned char key
[] = "here we go gathering nuts in May";
163 /* first thirty bytes of output from that key */
164 unsigned char good
[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
165 "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
166 "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
170 prng_init(&pr
, key
, strlen(key
));
171 prng_bytes(&pr
, buf
, sizeof(buf
));
172 for (p
= buf
, n
= sizeof(buf
); n
> 0; p
++, n
--) {
178 if (nzero
> 3 || none
> 3) {
179 fprintf(stderr
, "suspiciously non-random output!\n");
182 if (memcmp(buf
, good
, strlen(good
)) != 0) {
183 fprintf(stderr
, "incorrect output!\n");
187 fprintf(stderr
, "0x");
188 for (p
= buf
, n
= sizeof(buf
); n
> 0; p
++, n
--)
189 fprintf(stderr
, "%02x", *p
);
190 fprintf(stderr
, "\n");
193 if (prng_count(&pr
) != sizeof(buf
)) {
194 fprintf(stderr
, "got %u bytes, but count is %lu\n",
195 sizeof(buf
), prng_count(&pr
));
202 #endif /* PRNG_MAIN */