author | weijun |
Tue, 21 Jun 2016 11:09:13 +0800 | |
changeset 39127 | 2c67712d6935 |
parent 34716 | 7477a052aecc |
child 41120 | c730063ccd48 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
29923
e3ee0996bedb
8042332: Enhance thread contexts in security libraries
valeriep
parents:
28542
diff
changeset
|
2 |
* Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
5506 | 7 |
* published by the Free Software Foundation. Oracle designates this |
2 | 8 |
* particular file as subject to the "Classpath" exception as provided |
5506 | 9 |
* by Oracle in the LICENSE file that accompanied this code. |
2 | 10 |
* |
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
15 |
* accompanied this code). |
|
16 |
* |
|
17 |
* You should have received a copy of the GNU General Public License version |
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 |
* |
|
5506 | 21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
22 |
* or visit www.oracle.com if you need additional information or have any |
|
23 |
* questions. |
|
2 | 24 |
*/ |
25 |
||
26 |
package sun.security.provider; |
|
27 |
||
28 |
/** |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
29 |
* This class generates seeds for the SHA1PRNG cryptographically strong |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
30 |
* random number generator. |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
31 |
* <p> |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
32 |
* The seed is produced using one of two techniques, via a computation |
2 | 33 |
* of current system activity or from an entropy gathering device. |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
34 |
* <p> |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
35 |
* In the default technique the seed is produced by counting the |
2 | 36 |
* number of times the VM manages to loop in a given period. This number |
37 |
* roughly reflects the machine load at that point in time. |
|
38 |
* The samples are translated using a permutation (s-box) |
|
39 |
* and then XORed together. This process is non linear and |
|
40 |
* should prevent the samples from "averaging out". The s-box |
|
41 |
* was designed to have even statistical distribution; it's specific |
|
42 |
* values are not crucial for the security of the seed. |
|
43 |
* We also create a number of sleeper threads which add entropy |
|
44 |
* to the system by keeping the scheduler busy. |
|
45 |
* Twenty such samples should give us roughly 160 bits of randomness. |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
46 |
* <p> |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
47 |
* These values are gathered in the background by a daemon thread |
2 | 48 |
* thus allowing the system to continue performing it's different |
49 |
* activites, which in turn add entropy to the random seed. |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
50 |
* <p> |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
51 |
* The class also gathers miscellaneous system information, some |
2 | 52 |
* machine dependent, some not. This information is then hashed together |
53 |
* with the 20 seed bytes. |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
54 |
* <p> |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
55 |
* The alternative to the above approach is to acquire seed material |
2 | 56 |
* from an entropy gathering device, such as /dev/random. This can be |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
57 |
* accomplished by setting the value of the {@code securerandom.source} |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
58 |
* Security property to a URL specifying the location of the entropy |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
59 |
* gathering device, or by setting the {@code java.security.egd} System |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
60 |
* property. |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
61 |
* <p> |
2 | 62 |
* In the event the specified URL cannot be accessed the default |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
63 |
* threading mechanism is used. |
2 | 64 |
* |
65 |
* @author Joshua Bloch |
|
66 |
* @author Gadi Guy |
|
67 |
*/ |
|
68 |
||
69 |
import java.security.*; |
|
70 |
import java.io.*; |
|
71 |
import java.util.Properties; |
|
72 |
import java.util.Enumeration; |
|
73 |
import java.net.*; |
|
8158 | 74 |
import java.nio.file.DirectoryStream; |
75 |
import java.nio.file.Files; |
|
76 |
import java.nio.file.Path; |
|
2175
7d7e238cb41a
6705872: SecureRandom number init is taking too long on a java.io.tmpdir with a large number of files.
weijun
parents:
2
diff
changeset
|
77 |
import java.util.Random; |
2 | 78 |
import sun.security.util.Debug; |
79 |
||
80 |
abstract class SeedGenerator { |
|
81 |
||
82 |
// Static instance is created at link time |
|
83 |
private static SeedGenerator instance; |
|
84 |
||
85 |
private static final Debug debug = Debug.getInstance("provider"); |
|
86 |
||
87 |
// Static initializer to hook in selected or best performing generator |
|
88 |
static { |
|
89 |
String egdSource = SunEntries.getSeedSource(); |
|
90 |
||
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
91 |
/* |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
92 |
* Try the URL specifying the source (e.g. file:/dev/random) |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
93 |
* |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
94 |
* The URLs "file:/dev/random" or "file:/dev/urandom" are used to |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
95 |
* indicate the SeedGenerator should use OS support, if available. |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
96 |
* |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
97 |
* On Windows, this causes the MS CryptoAPI seeder to be used. |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
98 |
* |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
99 |
* On Solaris/Linux/MacOS, this is identical to using |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
100 |
* URLSeedGenerator to read from /dev/[u]random |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
101 |
*/ |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
102 |
if (egdSource.equals(SunEntries.URL_DEV_RANDOM) || |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
103 |
egdSource.equals(SunEntries.URL_DEV_URANDOM)) { |
2 | 104 |
try { |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
105 |
instance = new NativeSeedGenerator(egdSource); |
2 | 106 |
if (debug != null) { |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
107 |
debug.println( |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
108 |
"Using operating system seed generator" + egdSource); |
2 | 109 |
} |
110 |
} catch (IOException e) { |
|
111 |
if (debug != null) { |
|
112 |
debug.println("Failed to use operating system seed " |
|
113 |
+ "generator: " + e.toString()); |
|
114 |
} |
|
115 |
} |
|
116 |
} else if (egdSource.length() != 0) { |
|
117 |
try { |
|
118 |
instance = new URLSeedGenerator(egdSource); |
|
119 |
if (debug != null) { |
|
120 |
debug.println("Using URL seed generator reading from " |
|
121 |
+ egdSource); |
|
122 |
} |
|
123 |
} catch (IOException e) { |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
124 |
if (debug != null) { |
2 | 125 |
debug.println("Failed to create seed generator with " |
126 |
+ egdSource + ": " + e.toString()); |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
127 |
} |
2 | 128 |
} |
129 |
} |
|
130 |
||
131 |
// Fall back to ThreadedSeedGenerator |
|
132 |
if (instance == null) { |
|
133 |
if (debug != null) { |
|
134 |
debug.println("Using default threaded seed generator"); |
|
135 |
} |
|
136 |
instance = new ThreadedSeedGenerator(); |
|
137 |
} |
|
138 |
} |
|
139 |
||
140 |
/** |
|
141 |
* Fill result with bytes from the queue. Wait for it if it isn't ready. |
|
142 |
*/ |
|
32649
2ee9017c7597
8136583: Core libraries should use blessed modifier order
martin
parents:
30033
diff
changeset
|
143 |
public static void generateSeed(byte[] result) { |
2 | 144 |
instance.getSeedBytes(result); |
145 |
} |
|
146 |
||
7546
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
147 |
abstract void getSeedBytes(byte[] result); |
2 | 148 |
|
149 |
/** |
|
150 |
* Retrieve some system information, hashed. |
|
151 |
*/ |
|
152 |
static byte[] getSystemEntropy() { |
|
153 |
final MessageDigest md; |
|
154 |
||
155 |
try { |
|
156 |
md = MessageDigest.getInstance("SHA"); |
|
157 |
} catch (NoSuchAlgorithmException nsae) { |
|
24864 | 158 |
throw new InternalError("internal error: SHA-1 not available.", |
159 |
nsae); |
|
2 | 160 |
} |
161 |
||
162 |
// The current time in millis |
|
163 |
byte b =(byte)System.currentTimeMillis(); |
|
164 |
md.update(b); |
|
165 |
||
166 |
java.security.AccessController.doPrivileged |
|
30033
b9c86c17164a
8078468: Update security libraries to use diamond with anonymous classes
darcy
parents:
29923
diff
changeset
|
167 |
(new java.security.PrivilegedAction<>() { |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
168 |
@Override |
2 | 169 |
public Void run() { |
170 |
try { |
|
171 |
// System properties can change from machine to machine |
|
172 |
Properties p = System.getProperties(); |
|
24864 | 173 |
for (String s: p.stringPropertyNames()) { |
2 | 174 |
md.update(s.getBytes()); |
175 |
md.update(p.getProperty(s).getBytes()); |
|
176 |
} |
|
177 |
||
23923
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
178 |
// Include network adapter names (and a Mac address) |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
179 |
addNetworkAdapterInfo(md); |
2 | 180 |
|
181 |
// The temporary dir |
|
182 |
File f = new File(p.getProperty("java.io.tmpdir")); |
|
8158 | 183 |
int count = 0; |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
184 |
try ( |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
185 |
DirectoryStream<Path> stream = |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
186 |
Files.newDirectoryStream(f.toPath())) { |
2175
7d7e238cb41a
6705872: SecureRandom number init is taking too long on a java.io.tmpdir with a large number of files.
weijun
parents:
2
diff
changeset
|
187 |
// We use a Random object to choose what file names |
7d7e238cb41a
6705872: SecureRandom number init is taking too long on a java.io.tmpdir with a large number of files.
weijun
parents:
2
diff
changeset
|
188 |
// should be used. Otherwise on a machine with too |
7d7e238cb41a
6705872: SecureRandom number init is taking too long on a java.io.tmpdir with a large number of files.
weijun
parents:
2
diff
changeset
|
189 |
// many files, the same first 1024 files always get |
7d7e238cb41a
6705872: SecureRandom number init is taking too long on a java.io.tmpdir with a large number of files.
weijun
parents:
2
diff
changeset
|
190 |
// used. Any, We make sure the first 512 files are |
7d7e238cb41a
6705872: SecureRandom number init is taking too long on a java.io.tmpdir with a large number of files.
weijun
parents:
2
diff
changeset
|
191 |
// always used. |
7d7e238cb41a
6705872: SecureRandom number init is taking too long on a java.io.tmpdir with a large number of files.
weijun
parents:
2
diff
changeset
|
192 |
Random r = new Random(); |
8158 | 193 |
for (Path entry: stream) { |
194 |
if (count < 512 || r.nextBoolean()) { |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
195 |
md.update(entry.getFileName() |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
196 |
.toString().getBytes()); |
2175
7d7e238cb41a
6705872: SecureRandom number init is taking too long on a java.io.tmpdir with a large number of files.
weijun
parents:
2
diff
changeset
|
197 |
} |
8158 | 198 |
if (count++ > 1024) { |
199 |
break; |
|
200 |
} |
|
4176
bf303f38f727
6894534: SeedGenerator shouldn't require java.nio.file to be present
weijun
parents:
2175
diff
changeset
|
201 |
} |
2175
7d7e238cb41a
6705872: SecureRandom number init is taking too long on a java.io.tmpdir with a large number of files.
weijun
parents:
2
diff
changeset
|
202 |
} |
2 | 203 |
} catch (Exception ex) { |
204 |
md.update((byte)ex.hashCode()); |
|
205 |
} |
|
206 |
||
207 |
// get Runtime memory stats |
|
208 |
Runtime rt = Runtime.getRuntime(); |
|
209 |
byte[] memBytes = longToByteArray(rt.totalMemory()); |
|
210 |
md.update(memBytes, 0, memBytes.length); |
|
211 |
memBytes = longToByteArray(rt.freeMemory()); |
|
212 |
md.update(memBytes, 0, memBytes.length); |
|
213 |
||
214 |
return null; |
|
215 |
} |
|
216 |
}); |
|
217 |
return md.digest(); |
|
218 |
} |
|
219 |
||
23923
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
220 |
/* |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
221 |
* Include network adapter names and, if available, a Mac address |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
222 |
* |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
223 |
* See also java.util.concurrent.ThreadLocalRandom.initialSeed() |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
224 |
*/ |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
225 |
private static void addNetworkAdapterInfo(MessageDigest md) { |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
226 |
|
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
227 |
try { |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
228 |
Enumeration<NetworkInterface> ifcs = |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
229 |
NetworkInterface.getNetworkInterfaces(); |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
230 |
while (ifcs.hasMoreElements()) { |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
231 |
NetworkInterface ifc = ifcs.nextElement(); |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
232 |
md.update(ifc.toString().getBytes()); |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
233 |
if (!ifc.isVirtual()) { // skip fake addresses |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
234 |
byte[] bs = ifc.getHardwareAddress(); |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
235 |
if (bs != null) { |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
236 |
md.update(bs); |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
237 |
break; |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
238 |
} |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
239 |
} |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
240 |
} |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
241 |
} catch (Exception ignore) { |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
242 |
} |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
243 |
} |
baaff2487309
8035834: InetAddress.getLocalHost() can hang after JDK-8030731
vinnie
parents:
16915
diff
changeset
|
244 |
|
2 | 245 |
/** |
246 |
* Helper function to convert a long into a byte array (least significant |
|
247 |
* byte first). |
|
248 |
*/ |
|
249 |
private static byte[] longToByteArray(long l) { |
|
250 |
byte[] retVal = new byte[8]; |
|
251 |
||
252 |
for (int i=0; i<8; i++) { |
|
253 |
retVal[i] = (byte) l; |
|
254 |
l >>= 8; |
|
255 |
} |
|
256 |
||
257 |
return retVal; |
|
258 |
} |
|
259 |
||
260 |
/* |
|
261 |
// This method helps the test utility receive unprocessed seed bytes. |
|
262 |
public static int genTestSeed() { |
|
263 |
return myself.getByte(); |
|
264 |
} |
|
265 |
*/ |
|
266 |
||
267 |
||
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
268 |
private static class ThreadedSeedGenerator extends SeedGenerator |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
269 |
implements Runnable { |
2 | 270 |
// Queue is used to collect seed bytes |
271 |
private byte[] pool; |
|
272 |
private int start, end, count; |
|
273 |
||
274 |
// Thread group for our threads |
|
275 |
ThreadGroup seedGroup; |
|
276 |
||
277 |
/** |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
278 |
* The constructor is only called once to construct the one |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
279 |
* instance we actually use. It instantiates the message digest |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
280 |
* and starts the thread going. |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
281 |
*/ |
2 | 282 |
ThreadedSeedGenerator() { |
283 |
pool = new byte[20]; |
|
284 |
start = end = 0; |
|
285 |
||
286 |
MessageDigest digest; |
|
287 |
||
288 |
try { |
|
289 |
digest = MessageDigest.getInstance("SHA"); |
|
290 |
} catch (NoSuchAlgorithmException e) { |
|
10419
12c063b39232
7084245: Update usages of InternalError to use exception chaining
sherman
parents:
9035
diff
changeset
|
291 |
throw new InternalError("internal error: SHA-1 not available." |
12c063b39232
7084245: Update usages of InternalError to use exception chaining
sherman
parents:
9035
diff
changeset
|
292 |
, e); |
2 | 293 |
} |
294 |
||
295 |
final ThreadGroup[] finalsg = new ThreadGroup[1]; |
|
296 |
Thread t = java.security.AccessController.doPrivileged |
|
30033
b9c86c17164a
8078468: Update security libraries to use diamond with anonymous classes
darcy
parents:
29923
diff
changeset
|
297 |
(new java.security.PrivilegedAction<>() { |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
298 |
@Override |
2 | 299 |
public Thread run() { |
300 |
ThreadGroup parent, group = |
|
301 |
Thread.currentThread().getThreadGroup(); |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
302 |
while ((parent = group.getParent()) != null) { |
2 | 303 |
group = parent; |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
304 |
} |
2 | 305 |
finalsg[0] = new ThreadGroup |
306 |
(group, "SeedGenerator ThreadGroup"); |
|
34716
7477a052aecc
8056152: API to create Threads that do not inherit inheritable thread-local initial values
chegar
parents:
32649
diff
changeset
|
307 |
Thread newT = new Thread(finalsg[0], |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
308 |
ThreadedSeedGenerator.this, |
34716
7477a052aecc
8056152: API to create Threads that do not inherit inheritable thread-local initial values
chegar
parents:
32649
diff
changeset
|
309 |
"SeedGenerator Thread", |
7477a052aecc
8056152: API to create Threads that do not inherit inheritable thread-local initial values
chegar
parents:
32649
diff
changeset
|
310 |
0, |
7477a052aecc
8056152: API to create Threads that do not inherit inheritable thread-local initial values
chegar
parents:
32649
diff
changeset
|
311 |
false); |
2 | 312 |
newT.setPriority(Thread.MIN_PRIORITY); |
313 |
newT.setDaemon(true); |
|
314 |
return newT; |
|
315 |
} |
|
316 |
}); |
|
317 |
seedGroup = finalsg[0]; |
|
318 |
t.start(); |
|
319 |
} |
|
320 |
||
321 |
/** |
|
322 |
* This method does the actual work. It collects random bytes and |
|
323 |
* pushes them into the queue. |
|
324 |
*/ |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
325 |
@Override |
32649
2ee9017c7597
8136583: Core libraries should use blessed modifier order
martin
parents:
30033
diff
changeset
|
326 |
public final void run() { |
2 | 327 |
try { |
328 |
while (true) { |
|
329 |
// Queue full? Wait till there's room. |
|
330 |
synchronized(this) { |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
331 |
while (count >= pool.length) { |
2 | 332 |
wait(); |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
333 |
} |
2 | 334 |
} |
335 |
||
336 |
int counter, quanta; |
|
337 |
byte v = 0; |
|
338 |
||
339 |
// Spin count must not be under 64000 |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
340 |
for (counter = quanta = 0; |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
341 |
(counter < 64000) && (quanta < 6); quanta++) { |
2 | 342 |
|
343 |
// Start some noisy threads |
|
344 |
try { |
|
345 |
BogusThread bt = new BogusThread(); |
|
34716
7477a052aecc
8056152: API to create Threads that do not inherit inheritable thread-local initial values
chegar
parents:
32649
diff
changeset
|
346 |
Thread t = new Thread |
7477a052aecc
8056152: API to create Threads that do not inherit inheritable thread-local initial values
chegar
parents:
32649
diff
changeset
|
347 |
(seedGroup, bt, "SeedGenerator Thread", 0, false); |
2 | 348 |
t.start(); |
349 |
} catch (Exception e) { |
|
350 |
throw new InternalError("internal error: " + |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
351 |
"SeedGenerator thread creation error.", e); |
2 | 352 |
} |
353 |
||
354 |
// We wait 250milli quanta, so the minimum wait time |
|
355 |
// cannot be under 250milli. |
|
356 |
int latch = 0; |
|
39127
2c67712d6935
8157318: ThreadedSeedGenerator uses System.currentTimeMillis and stops generating when time is set back
weijun
parents:
34716
diff
changeset
|
357 |
long startTime = System.nanoTime(); |
2c67712d6935
8157318: ThreadedSeedGenerator uses System.currentTimeMillis and stops generating when time is set back
weijun
parents:
34716
diff
changeset
|
358 |
while (System.nanoTime() - startTime < 250000000) { |
2 | 359 |
synchronized(this){}; |
360 |
latch++; |
|
361 |
} |
|
362 |
||
363 |
// Translate the value using the permutation, and xor |
|
364 |
// it with previous values gathered. |
|
365 |
v ^= rndTab[latch % 255]; |
|
366 |
counter += latch; |
|
367 |
} |
|
368 |
||
369 |
// Push it into the queue and notify anybody who might |
|
370 |
// be waiting for it. |
|
371 |
synchronized(this) { |
|
372 |
pool[end] = v; |
|
373 |
end++; |
|
374 |
count++; |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
375 |
if (end >= pool.length) { |
2 | 376 |
end = 0; |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
377 |
} |
2 | 378 |
|
379 |
notifyAll(); |
|
380 |
} |
|
381 |
} |
|
382 |
} catch (Exception e) { |
|
383 |
throw new InternalError("internal error: " + |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
384 |
"SeedGenerator thread generated an exception.", e); |
2 | 385 |
} |
386 |
} |
|
387 |
||
7546
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
388 |
@Override |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
389 |
void getSeedBytes(byte[] result) { |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
390 |
for (int i = 0; i < result.length; i++) { |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
391 |
result[i] = getSeedByte(); |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
392 |
} |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
393 |
} |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
394 |
|
2 | 395 |
byte getSeedByte() { |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
396 |
byte b; |
2 | 397 |
|
398 |
try { |
|
399 |
// Wait for it... |
|
400 |
synchronized(this) { |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
401 |
while (count <= 0) { |
2 | 402 |
wait(); |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
403 |
} |
2 | 404 |
} |
405 |
} catch (Exception e) { |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
406 |
if (count <= 0) { |
2 | 407 |
throw new InternalError("internal error: " + |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
408 |
"SeedGenerator thread generated an exception.", e); |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
409 |
} |
2 | 410 |
} |
411 |
||
412 |
synchronized(this) { |
|
413 |
// Get it from the queue |
|
414 |
b = pool[start]; |
|
415 |
pool[start] = 0; |
|
416 |
start++; |
|
417 |
count--; |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
418 |
if (start == pool.length) { |
2 | 419 |
start = 0; |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
420 |
} |
2 | 421 |
|
422 |
// Notify the daemon thread, just in case it is |
|
423 |
// waiting for us to make room in the queue. |
|
424 |
notifyAll(); |
|
425 |
} |
|
426 |
||
427 |
return b; |
|
428 |
} |
|
429 |
||
430 |
// The permutation was calculated by generating 64k of random |
|
431 |
// data and using it to mix the trivial permutation. |
|
432 |
// It should be evenly distributed. The specific values |
|
433 |
// are not crucial to the security of this class. |
|
434 |
private static byte[] rndTab = { |
|
435 |
56, 30, -107, -6, -86, 25, -83, 75, -12, -64, |
|
436 |
5, -128, 78, 21, 16, 32, 70, -81, 37, -51, |
|
437 |
-43, -46, -108, 87, 29, 17, -55, 22, -11, -111, |
|
438 |
-115, 84, -100, 108, -45, -15, -98, 72, -33, -28, |
|
439 |
31, -52, -37, -117, -97, -27, 93, -123, 47, 126, |
|
440 |
-80, -62, -93, -79, 61, -96, -65, -5, -47, -119, |
|
441 |
14, 89, 81, -118, -88, 20, 67, -126, -113, 60, |
|
442 |
-102, 55, 110, 28, 85, 121, 122, -58, 2, 45, |
|
443 |
43, 24, -9, 103, -13, 102, -68, -54, -101, -104, |
|
444 |
19, 13, -39, -26, -103, 62, 77, 51, 44, 111, |
|
445 |
73, 18, -127, -82, 4, -30, 11, -99, -74, 40, |
|
446 |
-89, 42, -76, -77, -94, -35, -69, 35, 120, 76, |
|
447 |
33, -73, -7, 82, -25, -10, 88, 125, -112, 58, |
|
448 |
83, 95, 6, 10, 98, -34, 80, 15, -91, 86, |
|
449 |
-19, 52, -17, 117, 49, -63, 118, -90, 36, -116, |
|
450 |
-40, -71, 97, -53, -109, -85, 109, -16, -3, 104, |
|
451 |
-95, 68, 54, 34, 26, 114, -1, 106, -121, 3, |
|
452 |
66, 0, 100, -84, 57, 107, 119, -42, 112, -61, |
|
453 |
1, 48, 38, 12, -56, -57, 39, -106, -72, 41, |
|
454 |
7, 71, -29, -59, -8, -38, 79, -31, 124, -124, |
|
455 |
8, 91, 116, 99, -4, 9, -36, -78, 63, -49, |
|
456 |
-67, -87, 59, 101, -32, 92, 94, 53, -41, 115, |
|
457 |
-66, -70, -122, 50, -50, -22, -20, -18, -21, 23, |
|
458 |
-2, -48, 96, 65, -105, 123, -14, -110, 69, -24, |
|
459 |
-120, -75, 74, 127, -60, 113, 90, -114, 105, 46, |
|
460 |
27, -125, -23, -44, 64 |
|
461 |
}; |
|
462 |
||
463 |
/** |
|
464 |
* This inner thread causes the thread scheduler to become 'noisy', |
|
465 |
* thus adding entropy to the system load. |
|
466 |
* At least one instance of this class is generated for every seed byte. |
|
467 |
*/ |
|
468 |
private static class BogusThread implements Runnable { |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
469 |
@Override |
32649
2ee9017c7597
8136583: Core libraries should use blessed modifier order
martin
parents:
30033
diff
changeset
|
470 |
public final void run() { |
2 | 471 |
try { |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
472 |
for (int i = 0; i < 5; i++) { |
2 | 473 |
Thread.sleep(50); |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
474 |
} |
2 | 475 |
// System.gc(); |
476 |
} catch (Exception e) { |
|
477 |
} |
|
478 |
} |
|
479 |
} |
|
480 |
} |
|
481 |
||
482 |
static class URLSeedGenerator extends SeedGenerator { |
|
483 |
||
484 |
private String deviceName; |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
485 |
private InputStream seedStream; |
2 | 486 |
|
487 |
/** |
|
488 |
* The constructor is only called once to construct the one |
|
489 |
* instance we actually use. It opens the entropy gathering device |
|
490 |
* which will supply the randomness. |
|
491 |
*/ |
|
492 |
||
493 |
URLSeedGenerator(String egdurl) throws IOException { |
|
7546
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
494 |
if (egdurl == null) { |
2 | 495 |
throw new IOException("No random source specified"); |
496 |
} |
|
497 |
deviceName = egdurl; |
|
498 |
init(); |
|
499 |
} |
|
500 |
||
501 |
private void init() throws IOException { |
|
502 |
final URL device = new URL(deviceName); |
|
7546
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
503 |
try { |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
504 |
seedStream = java.security.AccessController.doPrivileged |
30033
b9c86c17164a
8078468: Update security libraries to use diamond with anonymous classes
darcy
parents:
29923
diff
changeset
|
505 |
(new java.security.PrivilegedExceptionAction<>() { |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
506 |
@Override |
7546
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
507 |
public InputStream run() throws IOException { |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
508 |
/* |
28542
d50a7783fe02
8047769: SecureRandom should be more frugal with file descriptors
plevart
parents:
25859
diff
changeset
|
509 |
* return a shared InputStream for file URLs and |
d50a7783fe02
8047769: SecureRandom should be more frugal with file descriptors
plevart
parents:
25859
diff
changeset
|
510 |
* avoid buffering. |
d50a7783fe02
8047769: SecureRandom should be more frugal with file descriptors
plevart
parents:
25859
diff
changeset
|
511 |
* The URL.openStream() call wraps InputStream in a |
d50a7783fe02
8047769: SecureRandom should be more frugal with file descriptors
plevart
parents:
25859
diff
changeset
|
512 |
* BufferedInputStream which |
7546
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
513 |
* can buffer up to 8K bytes. This read is a |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
514 |
* performance issue for entropy sources which |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
515 |
* can be slow to replenish. |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
516 |
*/ |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
517 |
if (device.getProtocol().equalsIgnoreCase("file")) { |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
518 |
File deviceFile = |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
519 |
SunEntries.getDeviceFile(device); |
28542
d50a7783fe02
8047769: SecureRandom should be more frugal with file descriptors
plevart
parents:
25859
diff
changeset
|
520 |
return FileInputStreamPool |
d50a7783fe02
8047769: SecureRandom should be more frugal with file descriptors
plevart
parents:
25859
diff
changeset
|
521 |
.getInputStream(deviceFile); |
7546
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
522 |
} else { |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
523 |
return device.openStream(); |
2 | 524 |
} |
525 |
} |
|
526 |
}); |
|
7546
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
527 |
} catch (Exception e) { |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
528 |
throw new IOException( |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
529 |
"Failed to open " + deviceName, e.getCause()); |
7546
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
530 |
} |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
531 |
} |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
532 |
|
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
533 |
@Override |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
534 |
void getSeedBytes(byte[] result) { |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
535 |
int len = result.length; |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
536 |
int read = 0; |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
537 |
try { |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
538 |
while (read < len) { |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
539 |
int count = seedStream.read(result, read, len - read); |
7546
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
540 |
// /dev/random blocks - should never have EOF |
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
541 |
if (count < 0) { |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
542 |
throw new InternalError( |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
543 |
"URLSeedGenerator " + deviceName + |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
544 |
" reached end of file"); |
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
545 |
} |
7546
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
546 |
read += count; |
c1915029b924
6998583: NativeSeedGenerator is making 8192 byte read requests from entropy pool on each init.
coffeys
parents:
5506
diff
changeset
|
547 |
} |
2 | 548 |
} catch (IOException ioe) { |
549 |
throw new InternalError("URLSeedGenerator " + deviceName + |
|
16915
675d1569af3e
6425477: Better support for generation of high entropy random numbers
wetmore
parents:
10419
diff
changeset
|
550 |
" generated exception: " + ioe.getMessage(), ioe); |
2 | 551 |
} |
552 |
} |
|
553 |
} |
|
554 |
} |