diff options
Diffstat (limited to 'services/java/com/android/server/EntropyMixer.java')
-rw-r--r-- | services/java/com/android/server/EntropyMixer.java | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/services/java/com/android/server/EntropyMixer.java b/services/java/com/android/server/EntropyMixer.java index fbb66f9..cfdbf7d 100644 --- a/services/java/com/android/server/EntropyMixer.java +++ b/services/java/com/android/server/EntropyMixer.java @@ -36,7 +36,8 @@ import android.util.Slog; /** * A service designed to load and periodically save "randomness" - * for the Linux kernel. + * for the Linux kernel RNG and to mix in data from Hardware RNG (if present) + * into the Linux RNG. * * <p>When a Linux system starts up, the entropy pool associated with * {@code /dev/random} may be in a fairly predictable state. Applications which @@ -45,6 +46,13 @@ import android.util.Slog; * this effect, it's helpful to carry the entropy pool information across * shutdowns and startups. * + * <p>On systems with Hardware RNG (/dev/hw_random), a block of output from HW + * RNG is mixed into the Linux RNG on EntropyMixer's startup and whenever + * EntropyMixer periodically runs to save a block of output from Linux RNG on + * disk. This mixing is done in a way that does not increase the Linux RNG's + * entropy estimate is not increased. This is to avoid having to trust/verify + * the quality and authenticity of the "randomness" of the HW RNG. + * * <p>This class was modeled after the script in * <a href="http://www.kernel.org/doc/man-pages/online/pages/man4/random.4.html">man * 4 random</a>. @@ -57,6 +65,7 @@ public class EntropyMixer extends Binder { private static final long START_NANOTIME = System.nanoTime(); private final String randomDevice; + private final String hwRandomDevice; private final String entropyFile; /** @@ -69,6 +78,7 @@ public class EntropyMixer extends Binder { Slog.e(TAG, "Will not process invalid message"); return; } + addHwRandomEntropy(); writeEntropy(); scheduleEntropyWriter(); } @@ -82,18 +92,25 @@ public class EntropyMixer extends Binder { }; public EntropyMixer(Context context) { - this(context, getSystemDir() + "/entropy.dat", "/dev/urandom"); + this(context, getSystemDir() + "/entropy.dat", "/dev/urandom", "/dev/hw_random"); } /** Test only interface, not for public use */ - public EntropyMixer(Context context, String entropyFile, String randomDevice) { + public EntropyMixer( + Context context, + String entropyFile, + String randomDevice, + String hwRandomDevice) { if (randomDevice == null) { throw new NullPointerException("randomDevice"); } + if (hwRandomDevice == null) { throw new NullPointerException("hwRandomDevice"); } if (entropyFile == null) { throw new NullPointerException("entropyFile"); } this.randomDevice = randomDevice; + this.hwRandomDevice = hwRandomDevice; this.entropyFile = entropyFile; loadInitialEntropy(); addDeviceSpecificEntropy(); + addHwRandomEntropy(); writeEntropy(); scheduleEntropyWriter(); IntentFilter broadcastFilter = new IntentFilter(Intent.ACTION_SHUTDOWN); @@ -168,6 +185,20 @@ public class EntropyMixer extends Binder { } } + /** + * Mixes in the output from HW RNG (if present) into the Linux RNG. + */ + private void addHwRandomEntropy() { + try { + RandomBlock.fromFile(hwRandomDevice).toFile(randomDevice, false); + Slog.i(TAG, "Added HW RNG output to entropy pool"); + } catch (FileNotFoundException ignored) { + // HW RNG not present/exposed -- ignore + } catch (IOException e) { + Slog.w(TAG, "Failed to add HW RNG output to entropy pool", e); + } + } + private static String getSystemDir() { File dataDir = Environment.getDataDirectory(); File systemDir = new File(dataDir, "system"); |