1 | ␊ |
2 | #include "libsaio.h"␊ |
3 | ␊ |
4 | /*␊ |
5 | * License for L15_Swap, L15_InitState, L_SCHEDULE, L15_KSA, L15_Discard, L15, L15_Byte␊ |
6 | *␊ |
7 | * Copyright (c) 2004, 2005, 2006 Robin J Carey. All rights reserved.␊ |
8 | *␊ |
9 | * Redistribution and use in source and binary forms, with or without␊ |
10 | * modification, are permitted provided that the following conditions␊ |
11 | * are met:␊ |
12 | * 1. Redistributions of source code must retain the above copyright␊ |
13 | * notice, this list of conditions, and the following disclaimer,␊ |
14 | * without modification, immediately at the beginning of the file.␊ |
15 | * 2. The name of the author may not be used to endorse or promote products␊ |
16 | * derived from this software without specific prior written permission.␊ |
17 | *␊ |
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND␊ |
19 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE␊ |
20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE␊ |
21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR␊ |
22 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL␊ |
23 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS␊ |
24 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)␊ |
25 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT␊ |
26 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY␊ |
27 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF␊ |
28 | * SUCH DAMAGE.␊ |
29 | *␊ |
30 | * $DragonFly: src/sys/kern/kern_nrandom.c,v 1.7 2008/08/01 04:42:30 dillon Exp $␊ |
31 | */␊ |
32 | ␊ |
33 | /*␊ |
34 | * IMPORTANT NOTE: LByteType must be exactly 8-bits in size or this software␊ |
35 | * will not function correctly.␊ |
36 | */␊ |
37 | typedef unsigned char LByteType;␊ |
38 | #define L15_STATE_SIZE 256␊ |
39 | static LByteType L15_x, L15_y;␊ |
40 | static LByteType L15_start_x;␊ |
41 | static LByteType L15_state[L15_STATE_SIZE];␊ |
42 | ␊ |
43 | /*␊ |
44 | * PRIVATE FUNCS:␊ |
45 | */␊ |
46 | static void L15(const LByteType * const key, const size_t keyLen);␊ |
47 | static void L15_Swap(const LByteType pos1, const LByteType pos2);␊ |
48 | static void L15_InitState(void);␊ |
49 | static void L15_KSA(const LByteType * const key,␊ |
50 | const size_t keyLen);␊ |
51 | static void L15_Discard(const LByteType numCalls);␊ |
52 | /*␊ |
53 | * PUBLIC INTERFACE:␊ |
54 | */␊ |
55 | static LByteType L15_Byte(void);␊ |
56 | ␊ |
57 | static __inline void␊ |
58 | L15_Swap(const LByteType pos1, const LByteType pos2)␊ |
59 | {␊ |
60 | ␉const LByteType save1 = L15_state[pos1];␊ |
61 | ␉␊ |
62 | ␉L15_state[pos1] = L15_state[pos2];␊ |
63 | ␉L15_state[pos2] = save1; ␊ |
64 | }␊ |
65 | ␊ |
66 | static void␊ |
67 | L15_InitState (void)␊ |
68 | {␊ |
69 | ␉size_t i;␊ |
70 | ␉for (i = 0; i < L15_STATE_SIZE; ++i)␊ |
71 | ␉␉L15_state[i] = i; ␊ |
72 | }␊ |
73 | ␊ |
74 | #define L_SCHEDULE(xx) \␊ |
75 | \␊ |
76 | for (i = 0; i < L15_STATE_SIZE; ++i) { \␊ |
77 | L15_Swap(i, (stateIndex += (L15_state[i] + (xx)))); \␊ |
78 | }␊ |
79 | ␊ |
80 | static void␊ |
81 | L15_KSA (const LByteType * const key, const size_t keyLen)␊ |
82 | {␊ |
83 | size_t i, keyIndex;␊ |
84 | LByteType stateIndex = 0;␊ |
85 | ␊ |
86 | L_SCHEDULE(keyLen);␊ |
87 | for (keyIndex = 0; keyIndex < keyLen; ++keyIndex) {␊ |
88 | L_SCHEDULE(key[keyIndex]);␊ |
89 | }␊ |
90 | }␊ |
91 | ␊ |
92 | static void␊ |
93 | L15_Discard(const LByteType numCalls)␊ |
94 | {␊ |
95 | LByteType i;␊ |
96 | for (i = 0; i < numCalls; ++i) {␊ |
97 | (void)L15_Byte();␊ |
98 | }␊ |
99 | }␊ |
100 | ␊ |
101 | /*␊ |
102 | * PUBLIC INTERFACE:␊ |
103 | */␊ |
104 | static void␊ |
105 | L15(const LByteType * const key, const size_t keyLen)␊ |
106 | {␊ |
107 | L15_x = L15_start_x = 0;␊ |
108 | L15_y = L15_STATE_SIZE - 1;␊ |
109 | L15_InitState();␊ |
110 | L15_KSA(key, keyLen);␊ |
111 | L15_Discard(L15_Byte());␊ |
112 | }␊ |
113 | ␊ |
114 | static LByteType␊ |
115 | L15_Byte(void)␊ |
116 | {␊ |
117 | ␉LByteType z;␊ |
118 | ␉␊ |
119 | ␉L15_Swap(L15_state[L15_x], L15_y);␊ |
120 | ␉z = (L15_state [L15_x++] + L15_state[L15_y--]);␊ |
121 | ␉if (L15_x == L15_start_x) {␊ |
122 | ␉␉--L15_y;␊ |
123 | ␉}␊ |
124 | ␉return (L15_state[z]); ␊ |
125 | }␊ |
126 | ␊ |
127 | ␊ |
128 | ␊ |
129 | /*-␊ |
130 | * THE BEER-WARE LICENSE␊ |
131 | *␊ |
132 | * <dan@FreeBSD.ORG> wrote this file. As long as you retain this notice you␊ |
133 | * can do whatever you want with this stuff. If we meet some day, and you␊ |
134 | * think this stuff is worth it, you can buy me a beer in return.␊ |
135 | *␊ |
136 | * Dan Moschuk␊ |
137 | *␊ |
138 | * $FreeBSD: src/sys/libkern/arc4random.c,v 1.3.2.2 2001/09/17 07:06:50 silby Exp $␊ |
139 | */␊ |
140 | ␊ |
141 | ␊ |
142 | #define␉ARC4_MAXRUNS 16384␊ |
143 | #define␉ARC4_RESEED_SECONDS 300 * 18␊ |
144 | #define␉ARC4_KEYBYTES 32 /* 256 bit key */␊ |
145 | ␊ |
146 | static u_int8_t arc4_i, arc4_j;␊ |
147 | static int arc4_initialized = 0;␊ |
148 | static int arc4_numruns = 0;␊ |
149 | static u_int8_t arc4_sbox[256];␊ |
150 | static u_int32_t arc4_tv_nextreseed;␊ |
151 | ␊ |
152 | static u_int8_t arc4_randbyte(void);␊ |
153 | ␊ |
154 | static __inline void␊ |
155 | arc4_swap(u_int8_t *a, u_int8_t *b)␊ |
156 | {␊ |
157 | ␉u_int8_t c;␊ |
158 | ␉␊ |
159 | ␉c = *a;␊ |
160 | ␉*a = *b;␊ |
161 | ␉*b = c;␊ |
162 | }␉␊ |
163 | ␊ |
164 | /*␊ |
165 | * Stir our S-box.␊ |
166 | */␊ |
167 | static void␊ |
168 | arc4_randomstir (void)␊ |
169 | {␊ |
170 | ␉u_int8_t key[256];␊ |
171 | ␉int r, n;␊ |
172 | ␉␊ |
173 | ␉/*␊ |
174 | ␉ * XXX read_random() returns unsafe numbers if the entropy␊ |
175 | ␉ * device is not loaded -- MarkM.␊ |
176 | ␉ */␊ |
177 | ␉ ␊ |
178 | ␉{␉␉␊ |
179 | ␉␉for (r = 0; r < ARC4_KEYBYTES; ++r)␊ |
180 | ␉␉␉((u_char *)key)[r] = L15_Byte();␊ |
181 | ␉}␊ |
182 | ␊ |
183 | ␉/* If r == 0 || -1, just use what was on the stack. */␊ |
184 | ␉if (r > 0)␊ |
185 | ␉{␊ |
186 | ␉␉for (n = r; n < sizeof(key); n++)␊ |
187 | ␉␉␉key[n] = key[n % r];␊ |
188 | ␉}␊ |
189 | ␉␊ |
190 | ␉for (n = 0; n < 256; n++)␊ |
191 | ␉{␊ |
192 | ␉␉arc4_j = (arc4_j + arc4_sbox[n] + key[n]) % 256;␊ |
193 | ␉␉arc4_swap(&arc4_sbox[n], &arc4_sbox[arc4_j]);␊ |
194 | ␉}␊ |
195 | ␉arc4_i = arc4_j = 0;␊ |
196 | ␉␊ |
197 | ␉/* Reset for next reseed cycle. */␊ |
198 | ␉arc4_tv_nextreseed = time18();␊ |
199 | ␉arc4_tv_nextreseed += ARC4_RESEED_SECONDS;␊ |
200 | ␉arc4_numruns = 0;␊ |
201 | }␊ |
202 | ␊ |
203 | /*␊ |
204 | * Initialize our S-box to its beginning defaults.␊ |
205 | */␊ |
206 | void␊ |
207 | arc4_init(void)␊ |
208 | {␊ |
209 | ␉int n;␊ |
210 | ␉␊ |
211 | ␉u_int32_t now = time18();␊ |
212 | ␉L15((const LByteType *)&now, sizeof(u_int32_t));␊ |
213 | ␉␊ |
214 | ␉arc4_i = arc4_j = 0;␊ |
215 | ␉for (n = 0; n < 256; n++)␊ |
216 | ␉␉arc4_sbox[n] = (u_int8_t) n;␊ |
217 | ␉␊ |
218 | ␉arc4_randomstir();␊ |
219 | ␉arc4_initialized = 1;␊ |
220 | ␉␊ |
221 | ␉/*␊ |
222 | ␉ * Throw away the first N words of output, as suggested in the␊ |
223 | ␉ * paper "Weaknesses in the Key Scheduling Algorithm of RC4"␊ |
224 | ␉ * by Fluher, Mantin, and Shamir. (N = 256 in our case.)␊ |
225 | ␉ */␊ |
226 | ␉for (n = 0; n < 256*4; n++)␊ |
227 | ␉␉arc4_randbyte();␊ |
228 | }␊ |
229 | ␊ |
230 | /*␊ |
231 | * Generate a random byte.␊ |
232 | */␊ |
233 | static u_int8_t␊ |
234 | arc4_randbyte(void)␊ |
235 | {␊ |
236 | ␉u_int8_t arc4_t;␊ |
237 | ␉␊ |
238 | ␉arc4_i = (arc4_i + 1) % 256;␊ |
239 | ␉arc4_j = (arc4_j + arc4_sbox[arc4_i]) % 256;␊ |
240 | ␉␊ |
241 | ␉arc4_swap(&arc4_sbox[arc4_i], &arc4_sbox[arc4_j]);␊ |
242 | ␉␊ |
243 | ␉arc4_t = (arc4_sbox[arc4_i] + arc4_sbox[arc4_j]) % 256;␊ |
244 | ␉return arc4_sbox[arc4_t];␊ |
245 | }␊ |
246 | ␊ |
247 | void␊ |
248 | arc4rand(void *ptr, u_int len, int reseed)␊ |
249 | {␊ |
250 | ␉u_char *p;␊ |
251 | ␉u_int32_t tv_now;␊ |
252 | ␉␊ |
253 | ␉/* Initialize array if needed. */␊ |
254 | ␉if (!arc4_initialized)␊ |
255 | ␉␉arc4_init();␊ |
256 | ␉␊ |
257 | ␉tv_now = time18();␊ |
258 | ␊ |
259 | ␉if (reseed || ␊ |
260 | ␉␉(arc4_numruns > ARC4_MAXRUNS) ||␊ |
261 | ␉␉(tv_now > arc4_tv_nextreseed))␊ |
262 | ␉␉arc4_randomstir();␊ |
263 | ␉␊ |
264 | ␉arc4_numruns += len;␊ |
265 | ␉p = ptr;␊ |
266 | ␉while (len--)␊ |
267 | ␉␉*p++ = arc4_randbyte();␊ |
268 | }␊ |
269 | ␊ |
270 | uint32_t␊ |
271 | arc4random(void)␊ |
272 | {␊ |
273 | ␉uint32_t ret;␊ |
274 | ␉␊ |
275 | ␉arc4rand(&ret, sizeof ret, 0);␊ |
276 | ␉return ret; ␊ |
277 | }␊ |
278 | |