aboutsummaryrefslogtreecommitdiffstats
path: root/src/org
diff options
context:
space:
mode:
authorKenny Root <kenny@the-b.org>2009-06-07 08:22:21 +0000
committerKenny Root <kenny@the-b.org>2009-06-07 08:22:21 +0000
commitd1e00c2f279169737fb15dd10287317d06d64ea5 (patch)
tree013450307066e8bde45083e0f286faa354a05f9f /src/org
parent564bde5c42170592fdeed845e19fd102ae2865aa (diff)
downloadconnectbot-d1e00c2f279169737fb15dd10287317d06d64ea5.tar.gz
connectbot-d1e00c2f279169737fb15dd10287317d06d64ea5.tar.bz2
connectbot-d1e00c2f279169737fb15dd10287317d06d64ea5.zip
Add von Neumann whitening to entropy gathering
git-svn-id: https://connectbot.googlecode.com/svn/trunk/connectbot@273 df292f66-193f-0410-a5fc-6d59da041ff2
Diffstat (limited to 'src/org')
-rw-r--r--src/org/connectbot/GeneratePubkeyActivity.java18
-rw-r--r--src/org/connectbot/util/EntropyView.java51
2 files changed, 56 insertions, 13 deletions
diff --git a/src/org/connectbot/GeneratePubkeyActivity.java b/src/org/connectbot/GeneratePubkeyActivity.java
index 17a0bea..cb565f4 100644
--- a/src/org/connectbot/GeneratePubkeyActivity.java
+++ b/src/org/connectbot/GeneratePubkeyActivity.java
@@ -213,6 +213,12 @@ public class GeneratePubkeyActivity extends Activity implements OnEntropyGathere
this.entropy = entropy.clone();
+ int numSetBits = 0;
+ for (int i = 0; i < 20; i++)
+ numSetBits += measureNumberOfSetBits(this.entropy[i]);
+
+ Log.d(TAG, "Entropy distribution=" + (int)(100.0 * numSetBits / 160.0) + "%");
+
Log.d(TAG, "entropy gathered; attemping to generate key...");
startKeyGen();
}
@@ -294,4 +300,16 @@ public class GeneratePubkeyActivity extends Activity implements OnEntropyGathere
checkEntries();
}
};
+
+ private int measureNumberOfSetBits(byte b) {
+ int numSetBits = 0;
+
+ for (int i = 0; i < 8; i++) {
+ if ((b & 1) == 1)
+ numSetBits++;
+ b >>= 1;
+ }
+
+ return numSetBits;
+ }
}
diff --git a/src/org/connectbot/util/EntropyView.java b/src/org/connectbot/util/EntropyView.java
index 55bebce..22a2745 100644
--- a/src/org/connectbot/util/EntropyView.java
+++ b/src/org/connectbot/util/EntropyView.java
@@ -32,6 +32,9 @@ import android.view.MotionEvent;
import android.view.View;
public class EntropyView extends View {
+ private static final int SHA1_MAX_BYTES = 20;
+ private static final int MILLIS_BETWEEN_INPUTS = 50;
+
private Paint mPaint;
private FontMetrics mFontMetrics;
private boolean mFlipFlop;
@@ -39,7 +42,8 @@ public class EntropyView extends View {
private Vector<OnEntropyGatheredListener> listeners;
private byte[] mEntropy;
- private int mEntropyIdx;
+ private int mEntropyByteIndex;
+ private int mEntropyBitIndex;
private int splitText = 0;
@@ -66,8 +70,9 @@ public class EntropyView extends View {
mPaint.setColor(Color.WHITE);
mFontMetrics = mPaint.getFontMetrics();
- mEntropy = new byte[20];
- mEntropyIdx = 0;
+ mEntropy = new byte[SHA1_MAX_BYTES];
+ mEntropyByteIndex = 0;
+ mEntropyBitIndex = 0;
listeners = new Vector<OnEntropyGatheredListener>();
}
@@ -83,7 +88,7 @@ public class EntropyView extends View {
@Override
public void onDraw(Canvas c) {
String prompt = String.format(getResources().getString(R.string.pubkey_touch_prompt),
- (int)(100.0 * (mEntropyIdx / 20.0)));
+ (int)(100.0 * (mEntropyByteIndex / 20.0)) + (int)(5.0 * (mEntropyBitIndex / 8.0)));
if (splitText > 0 ||
mPaint.measureText(prompt) > (getWidth() * 0.8)) {
if (splitText == 0)
@@ -107,31 +112,51 @@ public class EntropyView extends View {
@Override
public boolean onTouchEvent(MotionEvent event) {
- if (mEntropyIdx >= 20
+ if (mEntropyByteIndex >= SHA1_MAX_BYTES
|| lastX == event.getX()
|| lastY == event.getY())
return true;
// Only get entropy every 200 milliseconds to ensure the user has moved around.
long now = System.currentTimeMillis();
- if ((now - mLastTime) < 200)
+ if ((now - mLastTime) < MILLIS_BETWEEN_INPUTS)
return true;
else
mLastTime = now;
+ byte input;
+
+ lastX = event.getX();
+ lastY = event.getY();
+
// Get the lowest 4 bits of each X, Y input and concat to the entropy-gathering
// string.
if (mFlipFlop)
- mEntropy[mEntropyIdx++] += (byte)((((int)event.getX() & 0x0F) << 4) | ((int)event.getY() & 0x0F));
+ input = (byte)((((int)lastX & 0x0F) << 4) | ((int)lastY & 0x0F));
else
- mEntropy[mEntropyIdx++] += (byte)((((int)event.getY() & 0x0F) << 4) | ((int)event.getX() & 0x0F));
-
+ input = (byte)((((int)lastY & 0x0F) << 4) | ((int)lastX & 0x0F));
mFlipFlop = !mFlipFlop;
- lastX = event.getX();
- lastY = event.getY();
- // SHA1PRNG only keeps 20 bytes (160 bits) of entropy.
- if (mEntropyIdx >= 20) {
+ for (int i = 0; i < 4 && mEntropyByteIndex < SHA1_MAX_BYTES; i++) {
+ if ((input & 0x3) == 0x1) {
+ mEntropy[mEntropyByteIndex] <<= 1;
+ mEntropy[mEntropyByteIndex] |= 1;
+ mEntropyBitIndex++;
+ input >>= 2;
+ } else if ((input & 0x3) == 0x2) {
+ mEntropy[mEntropyByteIndex] <<= 1;
+ mEntropyBitIndex++;
+ input >>= 2;
+ }
+
+ if (mEntropyBitIndex >= 8) {
+ mEntropyBitIndex = 0;
+ mEntropyByteIndex++;
+ }
+ }
+
+ // SHA1PRNG only keeps 160 bits of entropy.
+ if (mEntropyByteIndex >= SHA1_MAX_BYTES) {
for (OnEntropyGatheredListener listener: listeners) {
listener.onEntropyGathered(mEntropy);
}