Loading services/java/com/android/server/EntropyService.java 0 → 100644 +101 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server; import java.io.File; import java.io.IOException; import android.os.Binder; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.Log; /** * A service designed to load and periodically save "randomness" * for the Linux kernel. * * <p>When a Linux system starts up, the entropy pool associated with * {@code /dev/random} may be in a fairly predictable state. Applications which * depend strongly on randomness may find {@code /dev/random} or * {@code /dev/urandom} returning predictable data. In order to counteract * this effect, it's helpful to carry the entropy pool information across * shutdowns and startups. * * <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>. * * <p>TODO: Investigate attempting to write entropy data at shutdown time * instead of periodically. */ public class EntropyService extends Binder { private static final String ENTROPY_FILENAME = getSystemDir() + "/entropy.dat"; private static final String TAG = "EntropyService"; private static final int ENTROPY_WHAT = 1; private static final int ENTROPY_WRITE_PERIOD = 3 * 60 * 60 * 1000; // 3 hrs private static final String RANDOM_DEV = "/dev/urandom"; /** * Handler that periodically updates the entropy on disk. */ private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what != ENTROPY_WHAT) { Log.e(TAG, "Will not process invalid message"); return; } writeEntropy(); scheduleEntropyWriter(); } }; public EntropyService() { loadInitialEntropy(); writeEntropy(); scheduleEntropyWriter(); } private void scheduleEntropyWriter() { mHandler.removeMessages(ENTROPY_WHAT); mHandler.sendEmptyMessageDelayed(ENTROPY_WHAT, ENTROPY_WRITE_PERIOD); } private void loadInitialEntropy() { try { RandomBlock.fromFile(ENTROPY_FILENAME).toFile(RANDOM_DEV); } catch (IOException e) { Log.w(TAG, "unable to load initial entropy (first boot?)", e); } } private void writeEntropy() { try { RandomBlock.fromFile(RANDOM_DEV).toFile(ENTROPY_FILENAME); } catch (IOException e) { Log.e(TAG, "unable to write entropy", e); } } private static String getSystemDir() { File dataDir = Environment.getDataDirectory(); File systemDir = new File(dataDir, "system"); systemDir.mkdirs(); return systemDir.toString(); } } services/java/com/android/server/RandomBlock.java 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server; import android.util.Log; import java.io.Closeable; import java.io.EOFException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * A 4k block of random {@code byte}s. */ class RandomBlock { private static final String TAG = "RandomBlock"; private static final int BLOCK_SIZE = 4096; private byte[] block = new byte[BLOCK_SIZE]; private RandomBlock() { } static RandomBlock fromFile(String filename) throws IOException { Log.v(TAG, "reading from file " + filename); InputStream stream = null; try { stream = new FileInputStream(filename); return fromStream(stream); } finally { close(stream); } } private static RandomBlock fromStream(InputStream in) throws IOException { RandomBlock retval = new RandomBlock(); int total = 0; while(total < BLOCK_SIZE) { int result = in.read(retval.block, total, BLOCK_SIZE - total); if (result == -1) { throw new EOFException(); } total += result; } return retval; } void toFile(String filename) throws IOException { Log.v(TAG, "writing to file " + filename); OutputStream out = null; try { // TODO: Investigate using RandomAccessFile out = new FileOutputStream(filename); toStream(out); } finally { close(out); } } private void toStream(OutputStream out) throws IOException { out.write(block); } private static void close(Closeable c) { try { if (c == null) { return; } c.close(); } catch (IOException e) { Log.w(TAG, "IOException thrown while closing Closeable", e); } } } services/java/com/android/server/SystemServer.java +3 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,9 @@ class ServerThread extends Thread { // Critical services... try { Log.i(TAG, "Starting Entropy Service."); ServiceManager.addService("entropy", new EntropyService()); Log.i(TAG, "Starting Power Manager."); power = new PowerManagerService(); ServiceManager.addService(Context.POWER_SERVICE, power); Loading Loading
services/java/com/android/server/EntropyService.java 0 → 100644 +101 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server; import java.io.File; import java.io.IOException; import android.os.Binder; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.Log; /** * A service designed to load and periodically save "randomness" * for the Linux kernel. * * <p>When a Linux system starts up, the entropy pool associated with * {@code /dev/random} may be in a fairly predictable state. Applications which * depend strongly on randomness may find {@code /dev/random} or * {@code /dev/urandom} returning predictable data. In order to counteract * this effect, it's helpful to carry the entropy pool information across * shutdowns and startups. * * <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>. * * <p>TODO: Investigate attempting to write entropy data at shutdown time * instead of periodically. */ public class EntropyService extends Binder { private static final String ENTROPY_FILENAME = getSystemDir() + "/entropy.dat"; private static final String TAG = "EntropyService"; private static final int ENTROPY_WHAT = 1; private static final int ENTROPY_WRITE_PERIOD = 3 * 60 * 60 * 1000; // 3 hrs private static final String RANDOM_DEV = "/dev/urandom"; /** * Handler that periodically updates the entropy on disk. */ private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what != ENTROPY_WHAT) { Log.e(TAG, "Will not process invalid message"); return; } writeEntropy(); scheduleEntropyWriter(); } }; public EntropyService() { loadInitialEntropy(); writeEntropy(); scheduleEntropyWriter(); } private void scheduleEntropyWriter() { mHandler.removeMessages(ENTROPY_WHAT); mHandler.sendEmptyMessageDelayed(ENTROPY_WHAT, ENTROPY_WRITE_PERIOD); } private void loadInitialEntropy() { try { RandomBlock.fromFile(ENTROPY_FILENAME).toFile(RANDOM_DEV); } catch (IOException e) { Log.w(TAG, "unable to load initial entropy (first boot?)", e); } } private void writeEntropy() { try { RandomBlock.fromFile(RANDOM_DEV).toFile(ENTROPY_FILENAME); } catch (IOException e) { Log.e(TAG, "unable to write entropy", e); } } private static String getSystemDir() { File dataDir = Environment.getDataDirectory(); File systemDir = new File(dataDir, "system"); systemDir.mkdirs(); return systemDir.toString(); } }
services/java/com/android/server/RandomBlock.java 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server; import android.util.Log; import java.io.Closeable; import java.io.EOFException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * A 4k block of random {@code byte}s. */ class RandomBlock { private static final String TAG = "RandomBlock"; private static final int BLOCK_SIZE = 4096; private byte[] block = new byte[BLOCK_SIZE]; private RandomBlock() { } static RandomBlock fromFile(String filename) throws IOException { Log.v(TAG, "reading from file " + filename); InputStream stream = null; try { stream = new FileInputStream(filename); return fromStream(stream); } finally { close(stream); } } private static RandomBlock fromStream(InputStream in) throws IOException { RandomBlock retval = new RandomBlock(); int total = 0; while(total < BLOCK_SIZE) { int result = in.read(retval.block, total, BLOCK_SIZE - total); if (result == -1) { throw new EOFException(); } total += result; } return retval; } void toFile(String filename) throws IOException { Log.v(TAG, "writing to file " + filename); OutputStream out = null; try { // TODO: Investigate using RandomAccessFile out = new FileOutputStream(filename); toStream(out); } finally { close(out); } } private void toStream(OutputStream out) throws IOException { out.write(block); } private static void close(Closeable c) { try { if (c == null) { return; } c.close(); } catch (IOException e) { Log.w(TAG, "IOException thrown while closing Closeable", e); } } }
services/java/com/android/server/SystemServer.java +3 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,9 @@ class ServerThread extends Thread { // Critical services... try { Log.i(TAG, "Starting Entropy Service."); ServiceManager.addService("entropy", new EntropyService()); Log.i(TAG, "Starting Power Manager."); power = new PowerManagerService(); ServiceManager.addService(Context.POWER_SERVICE, power); Loading