aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJ08nY2018-11-03 00:02:02 +0100
committerJ08nY2018-11-03 00:04:50 +0100
commit1243b4acace365b0231aca22470517ae42c4ed1d (patch)
tree61f8a0ccd9a67a44f6922d57a4ef7e6c65669f3b /src
parent7c3a97023703180ec6af60c27738d6d1294a0d17 (diff)
downloadECTester-1243b4acace365b0231aca22470517ae42c4ed1d.tar.gz
ECTester-1243b4acace365b0231aca22470517ae42c4ed1d.tar.zst
ECTester-1243b4acace365b0231aca22470517ae42c4ed1d.zip
Diffstat (limited to 'src')
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_SigResult.java2
-rw-r--r--src/cz/crcs/ectester/common/util/ECUtil.java8
-rw-r--r--src/cz/crcs/ectester/data/EC_Store.java18
-rw-r--r--src/cz/crcs/ectester/data/other/keys.xml38
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCompositeSuite.java18
-rw-r--r--src/cz/crcs/ectester/reader/test/CardCompressionSuite.java30
-rw-r--r--src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java8
-rw-r--r--src/cz/crcs/ectester/reader/test/CardSignatureSuite.java6
8 files changed, 98 insertions, 30 deletions
diff --git a/src/cz/crcs/ectester/common/ec/EC_SigResult.java b/src/cz/crcs/ectester/common/ec/EC_SigResult.java
index f1ab0f5..d97ced1 100644
--- a/src/cz/crcs/ectester/common/ec/EC_SigResult.java
+++ b/src/cz/crcs/ectester/common/ec/EC_SigResult.java
@@ -69,7 +69,7 @@ public class EC_SigResult extends EC_Data {
@Override
public String toString() {
- return "<" + getId() + "> " + sig + " result over " + curve + ", " + signKey + " + " + verifyKey + (data == null ? "" : " of data \"" + data + "\"") + (desc == null ? "" : ": " + desc) + System.lineSeparator() + super.toString();
+ return "<" + getId() + "> " + sig + " result over " + curve + ", " + signKey + " + " + verifyKey + (data == null ? "" : " of data \"" + data + "\"") + (desc == null ? "" : ": " + desc) + System.lineSeparator() + super.toString();
}
}
diff --git a/src/cz/crcs/ectester/common/util/ECUtil.java b/src/cz/crcs/ectester/common/util/ECUtil.java
index 6c3ad58..1706ca0 100644
--- a/src/cz/crcs/ectester/common/util/ECUtil.java
+++ b/src/cz/crcs/ectester/common/util/ECUtil.java
@@ -31,6 +31,14 @@ public class ECUtil {
return raw;
}
+ public static byte[] toX962Compressed(byte[][] point) {
+ if (point.length != 2) {
+ return null;
+ }
+ byte ybit = (byte) (point[1][point[1].length - 1] % 2);
+ return ByteUtil.concatenate(new byte[]{(byte) (0x02 | ybit)}, point[0]);
+ }
+
public static byte[] toX962Compressed(ECPoint point, int bits) {
if (point.equals(ECPoint.POINT_INFINITY)) {
return new byte[]{0};
diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java
index f1d4260..d104fa4 100644
--- a/src/cz/crcs/ectester/data/EC_Store.java
+++ b/src/cz/crcs/ectester/data/EC_Store.java
@@ -350,7 +350,7 @@ public class EC_Store {
return getObject(objClass, query.substring(0, split), query.substring(split + 1));
}
- private static <T extends EC_Data> List<Map.Entry<EC_Curve, List<T>>> mapKeyToCurve(Collection<T> data, Function<T, String> getter) {
+ private static <T extends EC_Data> Map<EC_Curve, List<T>> mapKeyToCurve(Collection<T> data, Function<T, String> getter) {
Map<EC_Curve, List<T>> curves = new TreeMap<>();
for (T item : data) {
EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, getter.apply(item));
@@ -361,21 +361,18 @@ public class EC_Store {
for (List<T> keyList : curves.values()) {
Collections.sort(keyList);
}
- List<Map.Entry<EC_Curve, List<T>>> curveList = new LinkedList<>();
- curveList.addAll(curves.entrySet());
- Comparator<Map.Entry<EC_Curve, List<T>>> c = Comparator.comparing(Map.Entry::getKey);
- return curveList;
+ return curves;
}
- public static <T extends EC_Key> List<Map.Entry<EC_Curve, List<T>>> mapKeyToCurve(Collection<T> keys) {
+ public static <T extends EC_Key> Map<EC_Curve, List<T>> mapKeyToCurve(Collection<T> keys) {
return mapKeyToCurve(keys, EC_Key::getCurve);
}
- public static List<Map.Entry<EC_Curve, List<EC_KAResult>>> mapResultToCurve(Collection<EC_KAResult> results) {
+ public static Map<EC_Curve, List<EC_KAResult>> mapResultToCurve(Collection<EC_KAResult> results) {
return mapKeyToCurve(results, EC_KAResult::getCurve);
}
- public static <T extends EC_Data> List<Map.Entry<String, List<T>>> mapToPrefix(Collection<T> data) {
+ public static <T extends EC_Data> Map<String, List<T>> mapToPrefix(Collection<T> data) {
Map<String, List<T>> groups = new TreeMap<>();
for (T item : data) {
String prefix = item.getId().split("/")[0];
@@ -386,10 +383,7 @@ public class EC_Store {
for (List<T> itemList : groups.values()) {
Collections.sort(itemList);
}
- List<Map.Entry<String, List<T>>> result = new LinkedList<>();
- result.addAll(groups.entrySet());
- result.sort(Comparator.comparing(Map.Entry::getKey));
- return result;
+ return groups;
}
public static EC_Store getInstance() {
diff --git a/src/cz/crcs/ectester/data/other/keys.xml b/src/cz/crcs/ectester/data/other/keys.xml
index d06de81..e17b45b 100644
--- a/src/cz/crcs/ectester/data/other/keys.xml
+++ b/src/cz/crcs/ectester/data/other/keys.xml
@@ -11,4 +11,40 @@
<inline>0x296D416994A4801B9A48E8C67C98E0C05DE1C0E85D4DC676F32FEACDC4998F0E,0xA91F9BE06C1D50EEB0295A35CA0F130F17EA647147626318E28AEC97F0653749</inline>
<curve>secg/secp256r1</curve>
</pubkey>
-</keys> \ No newline at end of file
+
+ <pubkey>
+ <id>compression/128/non-residue</id>
+ <inline>0xb6707fa8afeddf79b9579e8dda4eaf51,0x000000000000000000000000000000</inline>
+ <curve>secg/secp128r1</curve>
+ </pubkey>
+ <pubkey>
+ <id>compression/160/non-residue</id>
+ <inline>0xb1cb90992ff28689c6f160dcfb51b9525492e3d9,0x0000000000000000000000000000000000000000</inline>
+ <curve>secg/secp160r1</curve>
+ </pubkey>
+ <pubkey>
+ <id>compression/192/non-residue</id>
+ <inline>0x8910baef94195e069c142b129e97507bfc2e19b53b707441,0x000000000000000000000000000000000000000000000000</inline>
+ <curve>secg/secp192r1</curve>
+ </pubkey>
+ <pubkey>
+ <id>compression/224/non-residue</id>
+ <inline>0xafd44b41555e8bea506518b35405d4f5be78355d6342e7f5287bd748,0x00000000000000000000000000000000000000000000000000000000</inline>
+ <curve>secg/secp224r1</curve>
+ </pubkey>
+ <pubkey>
+ <id>compression/256/non-residue</id>
+ <inline>0xeb7a88c476ede6ecae7909aa19631d9918762e851c38a3ea00fe50b7b2e2e656,0x0000000000000000000000000000000000000000000000000000000000000000</inline>
+ <curve>secg/secp256r1</curve>
+ </pubkey>
+ <pubkey>
+ <id>compression/384/non-residue</id>
+ <inline>0x45d50b222c11c0f20946133382a988caf2d4f64e669340ba60a5ab3151a6bf3883e7e77a6d358fd07db411bc8ad0f375,0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</inline>
+ <curve>secg/secp384r1</curve>
+ </pubkey>
+ <pubkey>
+ <id>compression/521/non-residue</id>
+ <inline>0x1d7b127de8415bbf498c26f7a17c9e39dcd866b68359bc8e139f401f8ee8489419fb6166850c98cce7e1fdc620902961656d72f9b42703f06ccb9fe6e218e7e3fe3,0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</inline>
+ <curve>secg/secp521r1</curve>
+ </pubkey>
+</keys>
diff --git a/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java b/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
index 336b371..4bf9290 100644
--- a/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCompositeSuite.java
@@ -37,8 +37,8 @@ public class CardCompositeSuite extends CardTestSuite {
* is revealed.
*/
Map<String, EC_Key> keys = EC_Store.getInstance().getObjects(EC_Key.class, "composite");
- List<Map.Entry<EC_Curve, List<EC_Key>>> mappedKeys = EC_Store.mapKeyToCurve(keys.values());
- for (Map.Entry<EC_Curve, List<EC_Key>> curveKeys : mappedKeys) {
+ Map<EC_Curve, List<EC_Key>> mappedKeys = EC_Store.mapKeyToCurve(keys.values());
+ for (Map.Entry<EC_Curve, List<EC_Key>> curveKeys : mappedKeys.entrySet()) {
EC_Curve curve = curveKeys.getKey();
List<Test> tests = new LinkedList<>();
Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), ExpectedValue.SUCCESS));
@@ -59,35 +59,35 @@ public class CardCompositeSuite extends CardTestSuite {
Map<String, EC_Curve> results = EC_Store.getInstance().getObjects(EC_Curve.class, "composite");
- List<Map.Entry<String, List<EC_Curve>>> groupList = EC_Store.mapToPrefix(results.values());
+ Map<String, List<EC_Curve>> groups = EC_Store.mapToPrefix(results.values());
/* Test the whole curves with both keypairs generated on card(no small-order public points provided).
*/
- List<EC_Curve> wholeCurves = groupList.stream().filter((e) -> e.getKey().equals("whole")).findFirst().get().getValue();
+ List<EC_Curve> wholeCurves = groups.entrySet().stream().filter((e) -> e.getKey().equals("whole")).findFirst().get().getValue();
testGroup(wholeCurves, "Composite generator order", ExpectedValue.FAILURE, "Card rejected to do ECDH with composite order generator.", "Card did not reject to do ECDH with composite order generator.");
/* Also test having a G of small order, so small R.
*/
- List<EC_Curve> smallRCurves = groupList.stream().filter((e) -> e.getKey().equals("small")).findFirst().get().getValue();
+ List<EC_Curve> smallRCurves = groups.entrySet().stream().filter((e) -> e.getKey().equals("small")).findFirst().get().getValue();
testGroup(smallRCurves, "Small generator order", ExpectedValue.FAILURE, "Card correctly rejected to do ECDH over a small order generator.", "Card incorrectly does ECDH over a small order generator.");
/* Test increasingly larger prime R, to determine where/if card behavior changes.
*/
- List<EC_Curve> varyingCurves = groupList.stream().filter((e) -> e.getKey().equals("varying")).findFirst().get().getValue();
+ List<EC_Curve> varyingCurves = groups.entrySet().stream().filter((e) -> e.getKey().equals("varying")).findFirst().get().getValue();
testGroup(varyingCurves, null, ExpectedValue.ANY, "", "");
/* Also test having a G of large but composite order, R = p * q,
*/
- List<EC_Curve> pqCurves = groupList.stream().filter((e) -> e.getKey().equals("pq")).findFirst().get().getValue();
+ List<EC_Curve> pqCurves = groups.entrySet().stream().filter((e) -> e.getKey().equals("pq")).findFirst().get().getValue();
testGroup(pqCurves, null, ExpectedValue.ANY, "", "");
/* Also test having G or large order being a Carmichael pseudoprime, R = p * q * r,
*/
- List<EC_Curve> ppCurves = groupList.stream().filter((e) -> e.getKey().equals("pp")).findFirst().get().getValue();
+ List<EC_Curve> ppCurves = groups.entrySet().stream().filter((e) -> e.getKey().equals("pp")).findFirst().get().getValue();
testGroup(ppCurves, "Generator order = Carmichael pseudoprime", ExpectedValue.ANY, "", "");
/* Also test rg0 curves.
*/
- List<EC_Curve> rg0Curves = groupList.stream().filter((e) -> e.getKey().equals("rg0")).findFirst().get().getValue();
+ List<EC_Curve> rg0Curves = groups.entrySet().stream().filter((e) -> e.getKey().equals("rg0")).findFirst().get().getValue();
testGroup(rg0Curves, null, ExpectedValue.ANY, "", "");
}
diff --git a/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java b/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java
index ae25bf1..7338415 100644
--- a/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardCompressionSuite.java
@@ -2,6 +2,8 @@ package cz.crcs.ectester.reader.test;
import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.applet.EC_Consts;
+import cz.crcs.ectester.common.ec.EC_Curve;
+import cz.crcs.ectester.common.ec.EC_Key;
import cz.crcs.ectester.common.output.TestWriter;
import cz.crcs.ectester.common.test.CompoundTest;
import cz.crcs.ectester.common.test.Result;
@@ -9,6 +11,7 @@ import cz.crcs.ectester.common.test.Test;
import cz.crcs.ectester.common.util.ByteUtil;
import cz.crcs.ectester.common.util.CardUtil;
import cz.crcs.ectester.common.util.ECUtil;
+import cz.crcs.ectester.data.EC_Store;
import cz.crcs.ectester.reader.CardMngr;
import cz.crcs.ectester.reader.ECTesterReader;
import cz.crcs.ectester.reader.command.Command;
@@ -18,6 +21,7 @@ import javacard.security.KeyPair;
import java.security.spec.ECPoint;
import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
/**
* @author Jan Jancar johny@neuromancer.sk
@@ -51,6 +55,10 @@ public class CardCompressionSuite extends CardTestSuite {
if (cfg.binaryField) {
runCompression(KeyPair.ALG_EC_F2M);
}
+
+ // Now, do ECDH over SECG curves and give the implementation a compressed key that is not a quadratic residue in
+ // decompression.
+ runNonResidue();
}
private void runCompression(byte field) throws Exception {
@@ -119,4 +127,26 @@ public class CardCompressionSuite extends CardTestSuite {
doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Compression test of " + spec + ".", compressionTests.toArray(new Test[0])));
}
}
+
+ private void runNonResidue() {
+ Map<String, EC_Key.Public> otherKeys = EC_Store.getInstance().getObjects(EC_Key.Public.class, "other");
+ List<EC_Key.Public> compressionKeys = EC_Store.mapToPrefix(otherKeys.values()).get("compression");
+
+ for (EC_Key.Public key : compressionKeys) {
+ EC_Curve curve = EC_Store.getInstance().getObject(EC_Curve.class, key.getCurve());
+ List<Test> tests = new LinkedList<>();
+ Test allocate = runTest(CommandTest.expect(new Command.Allocate(this.card, ECTesterApplet.KEYPAIR_LOCAL, curve.getBits(), curve.getField()), Result.ExpectedValue.SUCCESS));
+ if (!allocate.ok()) {
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "No support for " + curve.getBits() + "b " + CardUtil.getKeyTypeString(curve.getField()) + ".", allocate));
+ continue;
+ }
+ tests.add(allocate);
+ tests.add(CommandTest.expect(new Command.Set(this.card, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Result.ExpectedValue.ANY));
+ tests.add(CommandTest.expect(new Command.Generate(this.card, ECTesterApplet.KEYPAIR_LOCAL), Result.ExpectedValue.ANY));
+ byte[] pointData = ECUtil.toX962Compressed(key.getParam(EC_Consts.PARAMETER_W));
+ byte[] pointDataEncoded = ByteUtil.prependLength(pointData);
+ tests.add(CommandTest.expect(new Command.ECDH_direct(this.card, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.TRANSFORMATION_NONE, EC_Consts.KeyAgreement_ALG_EC_SVDP_DH, pointDataEncoded), Result.ExpectedValue.FAILURE));
+ doTest(CompoundTest.all(Result.ExpectedValue.SUCCESS, "Non-residue test of " + curve.getId() + ".", tests.toArray(new Test[0])));
+ }
+ }
}
diff --git a/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java b/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
index b68b2ec..c0fde69 100644
--- a/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardEdgeCasesSuite.java
@@ -39,8 +39,8 @@ public class CardEdgeCasesSuite extends CardTestSuite {
@Override
protected void runTests() throws Exception {
Map<String, EC_KAResult> results = EC_Store.getInstance().getObjects(EC_KAResult.class, "wycheproof");
- List<Map.Entry<String, List<EC_KAResult>>> groupList = EC_Store.mapToPrefix(results.values());
- for (Map.Entry<String, List<EC_KAResult>> e : groupList) {
+ Map<String, List<EC_KAResult>> groups = EC_Store.mapToPrefix(results.values());
+ for (Map.Entry<String, List<EC_KAResult>> e : groups.entrySet()) {
String description = null;
switch (e.getKey()) {
case "addsub":
@@ -55,8 +55,8 @@ public class CardEdgeCasesSuite extends CardTestSuite {
}
List<Test> groupTests = new LinkedList<>();
- List<Map.Entry<EC_Curve, List<EC_KAResult>>> curveList = EC_Store.mapResultToCurve(e.getValue());
- for (Map.Entry<EC_Curve, List<EC_KAResult>> c : curveList) {
+ Map<EC_Curve, List<EC_KAResult>> curveList = EC_Store.mapResultToCurve(e.getValue());
+ for (Map.Entry<EC_Curve, List<EC_KAResult>> c : curveList.entrySet()) {
EC_Curve curve = c.getKey();
List<Test> curveTests = new LinkedList<>();
diff --git a/src/cz/crcs/ectester/reader/test/CardSignatureSuite.java b/src/cz/crcs/ectester/reader/test/CardSignatureSuite.java
index 59def74..20546c8 100644
--- a/src/cz/crcs/ectester/reader/test/CardSignatureSuite.java
+++ b/src/cz/crcs/ectester/reader/test/CardSignatureSuite.java
@@ -28,16 +28,16 @@ public class CardSignatureSuite extends CardTestSuite {
@Override
protected void runTests() throws Exception {
Map<String, EC_SigResult> results = EC_Store.getInstance().getObjects(EC_SigResult.class, "wrong");
- List<Map.Entry<String, List<EC_SigResult>>> groupList = EC_Store.mapToPrefix(results.values());
+ Map<String, List<EC_SigResult>> groups = EC_Store.mapToPrefix(results.values());
- List<EC_SigResult> nok = groupList.stream().filter((e) -> e.getKey().equals("nok")).findFirst().get().getValue();
+ List<EC_SigResult> nok = groups.entrySet().stream().filter((e) -> e.getKey().equals("nok")).findFirst().get().getValue();
byte[] data = "Some stuff that is not the actual data".getBytes();
for (EC_SigResult sig : nok) {
ecdsaTest(sig, Result.ExpectedValue.FAILURE, data);
}
- List<EC_SigResult> ok = groupList.stream().filter((e) -> e.getKey().equals("ok")).findFirst().get().getValue();
+ List<EC_SigResult> ok = groups.entrySet().stream().filter((e) -> e.getKey().equals("ok")).findFirst().get().getValue();
for (EC_SigResult sig : ok) {
ecdsaTest(sig, Result.ExpectedValue.SUCCESS, null);
}