aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJ08nY2019-03-04 14:47:08 +0100
committerJ08nY2019-03-04 14:47:08 +0100
commit49a2dff91b3b506345e31770f77534b40ac4e381 (patch)
tree31eb595ba4d6887c5d5fb8e45cab8a0272c1bc69 /src
parent08cdda311e3360db27819045f2336803588ebf38 (diff)
downloadECTester-49a2dff91b3b506345e31770f77534b40ac4e381.tar.gz
ECTester-49a2dff91b3b506345e31770f77534b40ac4e381.tar.zst
ECTester-49a2dff91b3b506345e31770f77534b40ac4e381.zip
Diffstat (limited to 'src')
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_Curve.java23
-rw-r--r--src/cz/crcs/ectester/common/util/ECUtil.java144
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCofactorSuite.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCompositeSuite.java2
-rw-r--r--src/cz/crcs/ectester/reader/test/CardMiscSuite.java8
-rw-r--r--src/cz/crcs/ectester/reader/test/CardTestSuite.java30
-rw-r--r--src/cz/crcs/ectester/reader/test/CardWrongSuite.java2
7 files changed, 169 insertions, 42 deletions
diff --git a/src/cz/crcs/ectester/common/ec/EC_Curve.java b/src/cz/crcs/ectester/common/ec/EC_Curve.java
index 6c0d060..2672b8a 100644
--- a/src/cz/crcs/ectester/common/ec/EC_Curve.java
+++ b/src/cz/crcs/ectester/common/ec/EC_Curve.java
@@ -3,6 +3,7 @@ package cz.crcs.ectester.common.ec;
import cz.crcs.ectester.applet.EC_Consts;
import cz.crcs.ectester.common.util.ByteUtil;
import javacard.security.KeyPair;
+import org.bouncycastle.math.ec.ECCurve;
import java.math.BigInteger;
import java.security.spec.*;
@@ -74,6 +75,28 @@ public class EC_Curve extends EC_Params {
return new EllipticCurve(field, a, b);
}
+ public ECCurve toBCCurve() {
+ if (this.field == KeyPair.ALG_EC_FP) {
+ BigInteger p = new BigInteger(1, getParam(EC_Consts.PARAMETER_FP)[0]);
+ BigInteger a = new BigInteger(1, getParam(EC_Consts.PARAMETER_A)[0]);
+ BigInteger b = new BigInteger(1, getParam(EC_Consts.PARAMETER_B)[0]);
+ BigInteger r = new BigInteger(1, getParam(EC_Consts.PARAMETER_R)[0]);
+ BigInteger k = new BigInteger(1, getParam(EC_Consts.PARAMETER_K)[0]);
+ return new ECCurve.Fp(p, a, b, r, k);
+ } else {
+ byte[][] fieldData = getParam(EC_Consts.PARAMETER_F2M);
+ int m = ByteUtil.getShort(fieldData[0], 0);
+ int e1 = ByteUtil.getShort(fieldData[1], 0);
+ int e2 = ByteUtil.getShort(fieldData[2], 0);
+ int e3 = ByteUtil.getShort(fieldData[3], 0);
+ BigInteger a = new BigInteger(1, getParam(EC_Consts.PARAMETER_A)[0]);
+ BigInteger b = new BigInteger(1, getParam(EC_Consts.PARAMETER_B)[0]);
+ BigInteger r = new BigInteger(1, getParam(EC_Consts.PARAMETER_R)[0]);
+ BigInteger k = new BigInteger(1, getParam(EC_Consts.PARAMETER_K)[0]);
+ return new ECCurve.F2m(m, e1, e2, e3, a, b, r, k);
+ }
+ }
+
public ECParameterSpec toSpec() {
EllipticCurve curve = toCurve();
diff --git a/src/cz/crcs/ectester/common/util/ECUtil.java b/src/cz/crcs/ectester/common/util/ECUtil.java
index 4736f23..a7aff10 100644
--- a/src/cz/crcs/ectester/common/util/ECUtil.java
+++ b/src/cz/crcs/ectester/common/util/ECUtil.java
@@ -20,12 +20,15 @@ import java.security.interfaces.ECKey;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.*;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Random;
/**
* @author Jan Jancar johny@neuromancer.sk
*/
public class ECUtil {
+ private static Random rand = new Random();
public static byte[] toByteArray(BigInteger what, int bits) {
byte[] raw = what.toByteArray();
@@ -195,7 +198,7 @@ public class ECUtil {
}
}
- public static byte[] semiRandomKey(EC_Curve curve) {
+ private static byte[] hashCurve(EC_Curve curve) {
int bytes = (curve.getBits() + 7) / 8;
byte[] result = new byte[bytes];
SHA1Digest digest = new SHA1Digest();
@@ -210,10 +213,87 @@ public class ECUtil {
written += toWrite;
digest.update(dig, 0, dig.length);
}
+ return result;
+ }
+
+ public static EC_Params fullRandomKey(EC_Curve curve) {
+ int bytes = (curve.getBits() + 7) / 8;
+ byte[] result = new byte[bytes];
+ rand.nextBytes(result);
BigInteger priv = new BigInteger(1, result);
BigInteger order = new BigInteger(1, curve.getParam(EC_Consts.PARAMETER_R)[0]);
priv = priv.mod(order);
- return toByteArray(priv, curve.getBits());
+ return new EC_Params(EC_Consts.PARAMETER_S, new byte[][]{toByteArray(priv, curve.getBits())});
+ }
+
+ public static EC_Params fixedRandomKey(EC_Curve curve) {
+ byte[] hash = hashCurve(curve);
+ BigInteger priv = new BigInteger(1, hash);
+ BigInteger order = new BigInteger(1, curve.getParam(EC_Consts.PARAMETER_R)[0]);
+ priv = priv.mod(order);
+ return new EC_Params(EC_Consts.PARAMETER_S, new byte[][]{toByteArray(priv, curve.getBits())});
+ }
+
+ private static BigInteger computeRHS(BigInteger x, BigInteger a, BigInteger b, BigInteger p) {
+ BigInteger rhs = x.modPow(BigInteger.valueOf(3), p);
+ rhs = rhs.add(a.multiply(x)).mod(p);
+ rhs = rhs.add(b).mod(p);
+ return rhs;
+ }
+
+ public static EC_Params fullRandomPoint(EC_Curve curve) {
+ EllipticCurve ecCurve = curve.toCurve();
+
+ BigInteger p;
+ if (ecCurve.getField() instanceof ECFieldFp) {
+ ECFieldFp fp = (ECFieldFp) ecCurve.getField();
+ p = fp.getP();
+ } else {
+ //TODO
+ return null;
+ }
+ BigInteger x;
+ BigInteger rhs;
+ do {
+ x = new BigInteger(ecCurve.getField().getFieldSize(), rand).mod(p);
+ rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p);
+ } while (!isResidue(rhs, p));
+ BigInteger y = modSqrt(rhs, p);
+ if (rand.nextBoolean()) {
+ y = p.subtract(y);
+ }
+
+ byte[] xArr = toByteArray(x, ecCurve.getField().getFieldSize());
+ byte[] yArr = toByteArray(y, ecCurve.getField().getFieldSize());
+ return new EC_Params(EC_Consts.PARAMETER_W, new byte[][]{xArr, yArr});
+ }
+
+ public static EC_Params fixedRandomPoint(EC_Curve curve) {
+ EllipticCurve ecCurve = curve.toCurve();
+
+ BigInteger p;
+ if (ecCurve.getField() instanceof ECFieldFp) {
+ ECFieldFp fp = (ECFieldFp) ecCurve.getField();
+ p = fp.getP();
+ } else {
+ //TODO
+ return null;
+ }
+
+ BigInteger x = new BigInteger(1, hashCurve(curve)).mod(p);
+ BigInteger rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p);
+ while (!isResidue(rhs, p)) {
+ x = x.add(BigInteger.ONE).mod(p);
+ rhs = computeRHS(x, ecCurve.getA(), ecCurve.getB(), p);
+ }
+ BigInteger y = modSqrt(rhs, p);
+ if (y.bitCount() % 2 == 0) {
+ y = p.subtract(y);
+ }
+
+ byte[] xArr = toByteArray(x, ecCurve.getField().getFieldSize());
+ byte[] yArr = toByteArray(y, ecCurve.getField().getFieldSize());
+ return new EC_Params(EC_Consts.PARAMETER_W, new byte[][]{xArr, yArr});
}
public static ECPoint toPoint(EC_Params params) {
@@ -294,6 +374,38 @@ public class ECUtil {
}
}
+ public static EC_Params joinParams(EC_Params... params) {
+ List<EC_Params> paramList = new LinkedList<>();
+ short paramMask = 0;
+ int len = 0;
+ for (EC_Params param : params) {
+ if (param == null) {
+ continue;
+ }
+ int i = 0;
+ for (; i + 1 < paramList.size(); ++i) {
+ if (paramList.get(i + 1).getParams() == param.getParams()) {
+ throw new IllegalArgumentException();
+ }
+ if (paramList.get(i + 1).getParams() < param.getParams()) {
+ break;
+ }
+ }
+ paramList.add(i, param);
+ paramMask |= param.getParams();
+ len += param.numParams();
+ }
+
+ byte[][] res = new byte[len][];
+ int i = 0;
+ for (EC_Params param : params) {
+ for (byte[] data : param.getData()) {
+ res[i++] = data.clone();
+ }
+ }
+ return new EC_Params(paramMask, res);
+ }
+
public static EC_Params loadParams(short params, String named, String file) throws IOException {
EC_Params result = null;
if (file != null) {
@@ -331,31 +443,5 @@ public class ECUtil {
return null;
}
- public static EC_Params randomPoint(EllipticCurve curve) {
- BigInteger x;
- BigInteger p;
- if (curve.getField() instanceof ECFieldFp) {
- ECFieldFp fp = (ECFieldFp) curve.getField();
- p = fp.getP();
- } else {
- //TODO
- throw new UnsupportedOperationException();
- }
- BigInteger rhs;
- Random rand = new Random();
- do {
- x = new BigInteger(curve.getField().getFieldSize(), rand);
- x = x.mod(p);
- rhs = x.modPow(BigInteger.valueOf(3), p);
- rhs = rhs.add(curve.getA().multiply(x)).mod(p);
- rhs = rhs.add(curve.getB()).mod(p);
- } while (!isResidue(rhs, p));
- BigInteger y = modSqrt(rhs, p);
- if (rand.nextBoolean()) {
- y = p.subtract(y);
- }
- byte[] xArr = toByteArray(x, curve.getField().getFieldSize());
- byte[] yArr = toByteArray(y, curve.getField().getFieldSize());
- return new EC_Params(EC_Consts.PARAMETER_W, new byte[][]{xArr, yArr});
- }
+
}
diff --git a/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java b/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
index 7d44870..6b15ab0 100644
--- a/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCofactorSuite.java
@@ -39,7 +39,7 @@ public class CardCofactorSuite extends CardTestSuite {
Test allocate = CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS);
Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.SUCCESS);
- Test generate = genOrPreset(curve, ExpectedValue.SUCCESS);
+ Test generate = genOrPreset(curve, ExpectedValue.SUCCESS, ECTesterApplet.KEYPAIR_LOCAL);
Test prepare = CompoundTest.all(ExpectedValue.SUCCESS, "Prepare and generate keypair on " + curve.getId() + ".", allocate, set, generate);
diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
index 2712184..1a8d093 100644
--- a/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
@@ -56,7 +56,7 @@ public class CardCompositeSuite extends CardTestSuite {
} else {
name = "generated key";
}
- tests.add(genOrPreset(curve, ExpectedValue.ANY));
+ tests.add(genOrPreset(curve, ExpectedValue.ANY, ECTesterApplet.KEYPAIR_LOCAL));
for (EC_Key key : curveKeys.getValue()) {
Command ecdhCommand = new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, key.flatten());
Test ecdh = CommandTest.expect(ecdhCommand, ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a composite order curve.", "Card incorrectly does ECDH over a composite order curve, leaks bits of private key.");
diff --git a/src/cz/crcs/ectester/reader/test/CardMiscSuite.java b/src/cz/crcs/ectester/reader/test/CardMiscSuite.java
index f977466..acd8a04 100644
--- a/src/cz/crcs/ectester/reader/test/CardMiscSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardMiscSuite.java
@@ -58,18 +58,16 @@ public class CardMiscSuite extends CardTestSuite {
}
Test set = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.SUCCESS);
- Test generate = genOrPreset(curve, Result.ExpectedValue.ANY);
- EC_Params randomPub = ECUtil.randomPoint(curve.toCurve());
- Test setRemote = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, randomPub.getParams(), randomPub.flatten()), Result.ExpectedValue.SUCCESS);
+ Test generate = genOrPreset(curve, Result.ExpectedValue.ANY, ECTesterApplet.KEYPAIR_BOTH);
Test ka = CommandTest.expect(new Command.ECDH(this.card, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH), expected);
Test sig = CommandTest.expect(new Command.ECDSA_sign(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.Signature_ALG_ECDSA_SHA, ECTesterApplet.EXPORT_FALSE, null), expected);
Test perform = CompoundTest.all(Result.ExpectedValue.SUCCESS, "Perform ECDH and ECDSA.", ka, sig);
if (cfg.cleanup) {
Test cleanup = CommandTest.expect(new Command.Cleanup(this.card), Result.ExpectedValue.ANY);
- doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, setRemote, perform, cleanup));
+ doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform, cleanup));
} else {
- doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, setRemote, perform));
+ doTest(CompoundTest.greedyAll(Result.ExpectedValue.SUCCESS, "Tests over " + curve.getBits() + "b " + catName + " curve: " + curve.getId() + ".", allocateFirst, set, generate, perform));
}
}
diff --git a/src/cz/crcs/ectester/reader/test/CardTestSuite.java b/src/cz/crcs/ectester/reader/test/CardTestSuite.java
index ed3dc3b..87f6271 100644
--- a/src/cz/crcs/ectester/reader/test/CardTestSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardTestSuite.java
@@ -5,6 +5,7 @@ import cz.crcs.ectester.applet.EC_Consts;
import cz.crcs.ectester.common.ec.EC_Curve;
import cz.crcs.ectester.common.ec.EC_Params;
import cz.crcs.ectester.common.output.TestWriter;
+import cz.crcs.ectester.common.test.CompoundTest;
import cz.crcs.ectester.common.test.Result;
import cz.crcs.ectester.common.test.Test;
import cz.crcs.ectester.common.test.TestSuite;
@@ -46,13 +47,32 @@ public abstract class CardTestSuite extends TestSuite {
}
}
- public Test genOrPreset(EC_Curve curve, Result.ExpectedValue expected) {
+ public Test genOrPreset(EC_Curve curve, Result.ExpectedValue expected, byte keyPair) {
if (Arrays.asList(options).contains("preset") && cfg.testOptions.contains("preset")) {
- byte[] presetPriv = ECUtil.semiRandomKey(curve);
- EC_Params privParms = new EC_Params(EC_Consts.PARAMETER_S, new byte[][]{presetPriv});
- return CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, privParms.getParams(), privParms.flatten()), expected);
+ Test setLocal = null;
+ if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) {
+ EC_Params priv = ECUtil.fixedRandomKey(curve);
+ setLocal = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, priv.getParams(), priv.flatten()), expected);
+ }
+ Test setRemote = null;
+ if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) {
+ EC_Params pub = ECUtil.fixedRandomPoint(curve);
+ if (pub == null) {
+ setRemote = CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_REMOTE), expected);
+ } else {
+ setRemote = CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), expected);
+ }
+ }
+
+ if (keyPair == ECTesterApplet.KEYPAIR_LOCAL) {
+ return setLocal;
+ } else if (keyPair == ECTesterApplet.KEYPAIR_REMOTE) {
+ return setRemote;
+ } else {
+ return CompoundTest.all(expected, "Set semi-random parameters.", setLocal, setRemote);
+ }
} else {
- return CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), expected);
+ return CommandTest.expect(new Command.Generate(this.card, keyPair), expected);
}
}
}
diff --git a/src/cz/crcs/ectester/reader/test/CardWrongSuite.java b/src/cz/crcs/ectester/reader/test/CardWrongSuite.java
index 3ba0ee9..1db8126 100644
--- a/src/cz/crcs/ectester/reader/test/CardWrongSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardWrongSuite.java
@@ -50,7 +50,7 @@ public class CardWrongSuite extends CardTestSuite {
}
tests.add(key);
Test set = runTest(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), ExpectedValue.FAILURE));
- Test generate = runTest(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_BOTH), ExpectedValue.FAILURE));
+ Test generate = runTest(genOrPreset(curve, ExpectedValue.SUCCESS, ECTesterApplet.KEYPAIR_BOTH));
Test setup = runTest(CompoundTest.any(ExpectedValue.SUCCESS, "Set wrong curve and generate keypairs.", set, generate));
tests.add(setup);