diff options
author | provos <> | 1997-04-19 09:53:25 +0000 |
---|---|---|
committer | provos <> | 1997-04-19 09:53:25 +0000 |
commit | f0ac6744ca5b6c2e1b698f3b25ba2d1ff3a1cbc5 (patch) | |
tree | 9f88cace5834a32283937adf21800da34c1ffb9d | |
parent | d3dfa216a47a69cf59f1c091f262d6a32f84bc45 (diff) | |
download | openbsd-f0ac6744ca5b6c2e1b698f3b25ba2d1ff3a1cbc5.tar.gz openbsd-f0ac6744ca5b6c2e1b698f3b25ba2d1ff3a1cbc5.tar.bz2 openbsd-f0ac6744ca5b6c2e1b698f3b25ba2d1ff3a1cbc5.zip |
make things more complicated.
-rw-r--r-- | src/lib/libc/net/res_random.c | 59 |
1 files changed, 46 insertions, 13 deletions
diff --git a/src/lib/libc/net/res_random.c b/src/lib/libc/net/res_random.c index d6d3a9269c..f6956bdd36 100644 --- a/src/lib/libc/net/res_random.c +++ b/src/lib/libc/net/res_random.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: res_random.c,v 1.1 1997/04/13 21:30:47 provos Exp $ */ | 1 | /* $OpenBSD: res_random.c,v 1.2 1997/04/19 09:53:25 provos Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> | 4 | * Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de> |
@@ -43,7 +43,9 @@ | |||
43 | * | 43 | * |
44 | * X[0] = random seed. | 44 | * X[0] = random seed. |
45 | * X[n] = a*X[n-1]+b mod m is a Linear Congruential Generator | 45 | * X[n] = a*X[n-1]+b mod m is a Linear Congruential Generator |
46 | * with a = 625, b = 6571, m = 31104 and a maximal period of m-1. | 46 | * with a = 7^(even random) mod m, |
47 | * b = random with gcd(b,m) == 1 | ||
48 | * m = 31104 and a maximal period of m-1. | ||
47 | * | 49 | * |
48 | * The transaction id is determined by: | 50 | * The transaction id is determined by: |
49 | * id[n] = seed xor (g^X[n] mod n) | 51 | * id[n] = seed xor (g^X[n] mod n) |
@@ -51,6 +53,10 @@ | |||
51 | * Effectivly the id is restricted to the lower 15 bits, thus | 53 | * Effectivly the id is restricted to the lower 15 bits, thus |
52 | * yielding two different cycles by toggling the msb on and off. | 54 | * yielding two different cycles by toggling the msb on and off. |
53 | * This avoids reuse issues caused by reseeding. | 55 | * This avoids reuse issues caused by reseeding. |
56 | * | ||
57 | * The 16 bit space is very small and brute force attempts are | ||
58 | * entirly feasible, we skip a random number of transaction ids | ||
59 | * so that an attacker will not get sequential ids. | ||
54 | */ | 60 | */ |
55 | 61 | ||
56 | #include <sys/types.h> | 62 | #include <sys/types.h> |
@@ -61,13 +67,14 @@ | |||
61 | #include <unistd.h> | 67 | #include <unistd.h> |
62 | #include <stdlib.h> | 68 | #include <stdlib.h> |
63 | #include <string.h> | 69 | #include <string.h> |
70 | #include <time.h> | ||
64 | 71 | ||
65 | #define RU_MAX 20000 /* Uniq cycle, avoid blackjack prediction */ | 72 | #define RU_OUT 180 /* Time after wich will be reseeded */ |
73 | #define RU_MAX 30000 /* Uniq cycle, avoid blackjack prediction */ | ||
66 | #define RU_GEN 2 /* Starting generator */ | 74 | #define RU_GEN 2 /* Starting generator */ |
67 | #define RU_N 32749 /* RU_N-1 = 2*2*3*2729 */ | 75 | #define RU_N 32749 /* RU_N-1 = 2*2*3*2729 */ |
68 | #define RU_A 625 | 76 | #define RU_AGEN 7 /* determine ru_a as RU_AGEN^(2*rand) */ |
69 | #define RU_B 6571 | 77 | #define RU_M 31104 /* RU_M = 2^7*3^5 - don't change */ |
70 | #define RU_M 31104 | ||
71 | 78 | ||
72 | #define PFAC_N 3 | 79 | #define PFAC_N 3 |
73 | const static u_int16_t pfacts[PFAC_N] = { | 80 | const static u_int16_t pfacts[PFAC_N] = { |
@@ -78,9 +85,12 @@ const static u_int16_t pfacts[PFAC_N] = { | |||
78 | 85 | ||
79 | static u_int16_t ru_x; | 86 | static u_int16_t ru_x; |
80 | static u_int16_t ru_seed; | 87 | static u_int16_t ru_seed; |
88 | static u_int16_t ru_a, ru_b; | ||
81 | static u_int16_t ru_g; | 89 | static u_int16_t ru_g; |
82 | static u_int16_t ru_counter = 0; | 90 | static u_int16_t ru_counter = 0; |
83 | static u_int16_t ru_msb = 0; | 91 | static u_int16_t ru_msb = 0; |
92 | static time_t ru_reseed; | ||
93 | static u_int32_t tmp; /* Storage for unused random */ | ||
84 | 94 | ||
85 | static u_int32_t pmod __P((u_int32_t, u_int32_t, u_int32_t)); | 95 | static u_int32_t pmod __P((u_int32_t, u_int32_t, u_int32_t)); |
86 | static void res_initid __P((void)); | 96 | static void res_initid __P((void)); |
@@ -110,7 +120,7 @@ pmod(gen, exp, mod) | |||
110 | } | 120 | } |
111 | 121 | ||
112 | /* | 122 | /* |
113 | * Initalizes the seed and choosed a suitable generator. Also toggles | 123 | * Initalizes the seed and chooses a suitable generator. Also toggles |
114 | * the msb flag. The msb flag is used to generate two distinct | 124 | * the msb flag. The msb flag is used to generate two distinct |
115 | * cycles of random numbers and thus avoiding reuse of ids. | 125 | * cycles of random numbers and thus avoiding reuse of ids. |
116 | * | 126 | * |
@@ -121,7 +131,6 @@ static void | |||
121 | res_initid() | 131 | res_initid() |
122 | { | 132 | { |
123 | u_int16_t j, i; | 133 | u_int16_t j, i; |
124 | u_int32_t tmp; | ||
125 | int noprime = 1; | 134 | int noprime = 1; |
126 | 135 | ||
127 | tmp = arc4random(); | 136 | tmp = arc4random(); |
@@ -130,7 +139,17 @@ res_initid() | |||
130 | /* 15 bits of random seed */ | 139 | /* 15 bits of random seed */ |
131 | ru_seed = (tmp >> 16) & 0x7FFF; | 140 | ru_seed = (tmp >> 16) & 0x7FFF; |
132 | 141 | ||
133 | j = arc4random() % RU_N; | 142 | tmp = arc4random(); |
143 | |||
144 | /* Determine the LCG we use */ | ||
145 | ru_b = (tmp & 0xfffe) | 1; | ||
146 | ru_a = pmod(RU_AGEN, (tmp >> 16) & 0xfffe, RU_M); | ||
147 | while (ru_b % 3 == 0) | ||
148 | ru_b += 2; | ||
149 | |||
150 | tmp = arc4random(); | ||
151 | j = tmp % RU_N; | ||
152 | tmp = tmp >> 16; | ||
134 | 153 | ||
135 | /* | 154 | /* |
136 | * Do a fast gcd(j,RU_N-1), so we can find a j with | 155 | * Do a fast gcd(j,RU_N-1), so we can find a j with |
@@ -152,19 +171,31 @@ res_initid() | |||
152 | ru_g = pmod(RU_GEN,j,RU_N); | 171 | ru_g = pmod(RU_GEN,j,RU_N); |
153 | ru_counter = 0; | 172 | ru_counter = 0; |
154 | 173 | ||
174 | ru_reseed = time(NULL) + RU_OUT; | ||
155 | ru_msb = ru_msb == 0x8000 ? 0 : 0x8000; | 175 | ru_msb = ru_msb == 0x8000 ? 0 : 0x8000; |
156 | } | 176 | } |
157 | 177 | ||
158 | u_int | 178 | u_int |
159 | res_randomid() | 179 | res_randomid() |
160 | { | 180 | { |
161 | if (ru_counter % RU_MAX == 0) | 181 | int i, n; |
182 | |||
183 | if (ru_counter >= RU_MAX || time(NULL) > ru_reseed) | ||
162 | res_initid(); | 184 | res_initid(); |
163 | 185 | ||
164 | ru_counter++; | 186 | if (!tmp) |
187 | tmp = arc4random(); | ||
188 | |||
189 | /* Skip a random number of ids */ | ||
190 | n = tmp & 0x2f; tmp = tmp >> 6; | ||
191 | if (ru_counter + n >= RU_MAX) | ||
192 | res_initid(); | ||
193 | |||
194 | for (i=0; i<=n; i++) | ||
195 | /* Linear Congruential Generator */ | ||
196 | ru_x = (ru_a*ru_x + ru_b) % RU_M; | ||
165 | 197 | ||
166 | /* Linear Congruential Generator */ | 198 | ru_counter += i; |
167 | ru_x = (RU_A*ru_x + RU_B) % RU_M; | ||
168 | 199 | ||
169 | return (ru_seed ^ pmod(ru_g,ru_x,RU_N)) | ru_msb; | 200 | return (ru_seed ^ pmod(ru_g,ru_x,RU_N)) | ru_msb; |
170 | } | 201 | } |
@@ -181,6 +212,8 @@ main(int argc, char **argv) | |||
181 | printf("Generator: %d\n", ru_g); | 212 | printf("Generator: %d\n", ru_g); |
182 | printf("Seed: %d\n", ru_seed); | 213 | printf("Seed: %d\n", ru_seed); |
183 | printf("Ru_X: %d\n", ru_x); | 214 | printf("Ru_X: %d\n", ru_x); |
215 | printf("Ru_A: %d\n", ru_a); | ||
216 | printf("Ru_B: %d\n", ru_b); | ||
184 | 217 | ||
185 | n = atoi(argv[1]); | 218 | n = atoi(argv[1]); |
186 | for (i=0;i<n;i++) { | 219 | for (i=0;i<n;i++) { |