From de1736c211dc8d27961ef0495c82d25fbf813e05 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 26 Mar 2017 00:20:29 +0100 Subject: Refactored EC_Params, renamed EC_Data, added first test vectors. --- src/cz/crcs/ectester/data/EC_Store.java | 246 ++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 src/cz/crcs/ectester/data/EC_Store.java (limited to 'src/cz/crcs/ectester/data/EC_Store.java') diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java new file mode 100644 index 0000000..60a1065 --- /dev/null +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -0,0 +1,246 @@ +package cz.crcs.ectester.data; + +import cz.crcs.ectester.reader.ec.EC_Curve; +import cz.crcs.ectester.reader.ec.EC_Key; +import cz.crcs.ectester.reader.ec.EC_Keypair; +import cz.crcs.ectester.reader.ec.EC_Params; +import javacard.security.KeyPair; +import org.omg.PortableInterceptor.SYSTEM_EXCEPTION; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class EC_Store { + + private DocumentBuilder db; + + private Map categories; + + public EC_Store() { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + + try { + SchemaFactory scf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema sch = scf.newSchema(this.getClass().getResource("/cz/crcs/ectester/data/schema.xsd")); + dbf.setSchema(sch); + dbf.setNamespaceAware(true); + dbf.setIgnoringComments(true); + dbf.setIgnoringElementContentWhitespace(true); + db = dbf.newDocumentBuilder(); + db.setErrorHandler(new ErrorHandler() { + @Override + public void warning(SAXParseException exception) throws SAXException { + System.err.println("EC_Store | Warning : " + exception); + } + + @Override + public void error(SAXParseException exception) throws SAXException { + System.err.println("EC_Store | Error : " + exception); + } + + @Override + public void fatalError(SAXParseException exception) throws SAXException { + System.err.println("EC_Store | Fatal : " + exception); + } + }); + + parse(); + } catch (ParserConfigurationException | IOException | SAXException e) { + e.printStackTrace(); + } + } + + private void parse() throws SAXException, ParserConfigurationException, IOException { + + Document categoriesDoc = db.parse(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/categories.xml")); + categoriesDoc.normalize(); + + NodeList catList = categoriesDoc.getElementsByTagName("category"); + + this.categories = new HashMap<>(catList.getLength()); + for (int i = 0; i < catList.getLength(); ++i) { + Node catNode = catList.item(i); + if (catNode instanceof Element) { + Element catElem = (Element) catNode; + Node name = catElem.getElementsByTagName("name").item(0); + Node dir = catElem.getElementsByTagName("directory").item(0); + Node desc = catElem.getElementsByTagName("desc").item(0); + + EC_Category category = parseCategory(name.getTextContent(), dir.getTextContent(), desc.getTextContent()); + this.categories.put(name.getTextContent(), category); + } else { + throw new SAXException("?"); + } + } + } + + private EC_Category parseCategory(String name, String dir, String desc) throws ParserConfigurationException, IOException, SAXException { + + Map objMap = new HashMap<>(); + + InputStream curvesStream = this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/curves.xml"); + if (curvesStream != null) { + Document curvesDoc = db.parse(curvesStream); + curvesDoc.normalize(); + + NodeList curveList = curvesDoc.getElementsByTagName("curve"); + + for (int i = 0; i < curveList.getLength(); ++i) { + Node curveNode = curveList.item(i); + if (curveNode instanceof Element) { + Element curveElem = (Element) curveNode; + Node id = curveElem.getElementsByTagName("id").item(0); + Node bits = curveElem.getElementsByTagName("bits").item(0); + Node field = curveElem.getElementsByTagName("field").item(0); + Node file = curveElem.getElementsByTagName("file").item(0); + + NodeList descc = curveElem.getElementsByTagName("desc"); + String descs = null; + if (descc.getLength() != 0) { + descs = descc.item(0).getTextContent(); + } + + byte alg; + if (field.getTextContent().equalsIgnoreCase("prime")) { + alg = KeyPair.ALG_EC_FP; + } else { + alg = KeyPair.ALG_EC_F2M; + } + short bitsize = Short.parseShort(bits.getTextContent()); + + EC_Curve curve = new EC_Curve(bitsize, alg, descs); + if (!curve.readCSV(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/" + file.getTextContent()))) { + throw new IOException("Invalid csv data."); + } + + objMap.put(id.getTextContent(), curve); + } else { + throw new SAXException("?"); + } + } + } + + InputStream keysStream = this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/keys.xml"); + if (keysStream != null) { + Document keysDoc = db.parse(keysStream); + keysDoc.normalize(); + + NodeList directs = keysDoc.getDocumentElement().getChildNodes(); + for (int i = 0; i < directs.getLength(); ++i) { + Node direct = directs.item(i); + if (direct instanceof Element) { + Element elem = (Element) direct; + + NodeList childs = elem.getChildNodes(); + String id = null; + for (int j = 0; j < childs.getLength(); ++j) { + Node child = childs.item(j); + if (child instanceof Element) { + Element childElem = (Element) child; + if (childElem.getTagName().equals("id")) { + id = childElem.getTextContent(); + break; + } + } + } + if (id == null) { + throw new SAXException("key no id?"); + } + + EC_Params result = parseKeylike(dir, elem); + + objMap.put(id, result); + } else { + throw new SAXException("?"); + } + } + } + + return new EC_Category(name, dir, desc, objMap); + } + + private EC_Params parseKeylike(String dir, Element elem) throws SAXException { + Node file = elem.getElementsByTagName("file").item(0); + Node curve = elem.getElementsByTagName("curve").item(0); + + NodeList desc = elem.getElementsByTagName("desc"); + String descs = null; + if (desc.getLength() != 0) { + descs = desc.item(0).getTextContent(); + } + + EC_Params result; + if (elem.getTagName().equals("pubkey")) { + result = new EC_Key.Public(curve.getTextContent(), descs); + } else if (elem.getTagName().equals("privkey")) { + result = new EC_Key.Private(curve.getTextContent(), descs); + } else if (elem.getTagName().equals("keypair")) { + result = new EC_Keypair(curve.getTextContent(), descs); + } else { + throw new SAXException("?"); + } + result.readCSV(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/" + file.getTextContent())); + return result; + } + + public Map getCategories() { + return Collections.unmodifiableMap(categories); + } + + public EC_Category getCategory(String category) { + return categories.get(category); + } + + public Map getObjects(String category) { + EC_Category cat = categories.get(category); + if (cat != null) { + return cat.getObjects(); + } + return null; + } + + public Map getObjects(Class objClass, String category) { + EC_Category cat = categories.get(category); + if (cat != null) { + return cat.getObjects(objClass); + } + return null; + } + + public T getObject(Class objClass, String category, String id) { + EC_Category cat = categories.get(category); + if (cat != null) { + return cat.getObject(objClass, id); + } + return null; + } + + public T getObject(Class objClass, String query) { + String[] parts = query.split("/"); + if (parts.length != 2) { + return null; + } + return getObject(objClass, parts[0], parts[1]); + } + + +} -- cgit v1.3.1 From 0ab7f6dd030c866565cb6592b2a40a39af82be09 Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 27 Mar 2017 01:03:56 +0200 Subject: Added new curves, started adding default & dangerous tests. --- !uploader/ectester.cap | Bin 13783 -> 13811 bytes dist/ECTester.jar | Bin 238953 -> 253043 bytes src/cz/crcs/ectester/applet/EC_Consts.java | 12 ++ src/cz/crcs/ectester/data/EC_Category.java | 4 +- src/cz/crcs/ectester/data/EC_Store.java | 3 +- src/cz/crcs/ectester/data/nist/b163.csv | 1 + src/cz/crcs/ectester/data/nist/b233.csv | 1 + src/cz/crcs/ectester/data/nist/b283.csv | 1 + src/cz/crcs/ectester/data/nist/b409.csv | 9 ++ src/cz/crcs/ectester/data/nist/b571.csv | 1 + src/cz/crcs/ectester/data/nist/curves.xml | 61 +++++++++ src/cz/crcs/ectester/data/nist/k163.csv | 1 + src/cz/crcs/ectester/data/nist/k233.csv | 1 + src/cz/crcs/ectester/data/nist/k283.csv | 1 + src/cz/crcs/ectester/data/nist/k409.csv | 1 + src/cz/crcs/ectester/data/nist/k571.csv | 1 + src/cz/crcs/ectester/data/secg/curves.xml | 42 ++++++ src/cz/crcs/ectester/data/secg/secp112r1.csv | 1 + src/cz/crcs/ectester/data/secg/secp112r2.csv | 1 + src/cz/crcs/ectester/data/secg/secp128r1.csv | 1 + src/cz/crcs/ectester/data/secg/secp128r2.csv | 1 + src/cz/crcs/ectester/data/secg/secp160k1.csv | 1 + src/cz/crcs/ectester/data/secg/secp160r1.csv | 1 + src/cz/crcs/ectester/data/secg/secp160r2.csv | 1 + .../ectester/data/test/secg/sect163k1-dh-kdf.csv | 1 + .../ectester/data/test/secg/sect163k1-dh-raw.csv | 1 + .../ectester/data/test/secg/sect163k1-dh-sha1.csv | 1 + .../ectester/data/test/secg/sect163k1-dhc-kdf.csv | 1 + .../ectester/data/test/secg/sect163k1-dhc-raw.csv | 1 + .../ectester/data/test/secg/sect163k1-dhc-sha1.csv | 1 + .../ectester/data/test/secg/sect163k1-keyU.csv | 1 + .../ectester/data/test/secg/sect163k1-keyV.csv | 1 + src/cz/crcs/ectester/reader/ECTester.java | 144 ++++++++++++++------- 33 files changed, 251 insertions(+), 48 deletions(-) create mode 100644 src/cz/crcs/ectester/data/nist/b163.csv create mode 100644 src/cz/crcs/ectester/data/nist/b233.csv create mode 100644 src/cz/crcs/ectester/data/nist/b283.csv create mode 100644 src/cz/crcs/ectester/data/nist/b409.csv create mode 100644 src/cz/crcs/ectester/data/nist/b571.csv create mode 100644 src/cz/crcs/ectester/data/nist/k163.csv create mode 100644 src/cz/crcs/ectester/data/nist/k233.csv create mode 100644 src/cz/crcs/ectester/data/nist/k283.csv create mode 100644 src/cz/crcs/ectester/data/nist/k409.csv create mode 100644 src/cz/crcs/ectester/data/nist/k571.csv create mode 100644 src/cz/crcs/ectester/data/secg/secp112r1.csv create mode 100644 src/cz/crcs/ectester/data/secg/secp112r2.csv create mode 100644 src/cz/crcs/ectester/data/secg/secp128r1.csv create mode 100644 src/cz/crcs/ectester/data/secg/secp128r2.csv create mode 100644 src/cz/crcs/ectester/data/secg/secp160k1.csv create mode 100644 src/cz/crcs/ectester/data/secg/secp160r1.csv create mode 100644 src/cz/crcs/ectester/data/secg/secp160r2.csv create mode 100644 src/cz/crcs/ectester/data/test/secg/sect163k1-dh-kdf.csv create mode 100644 src/cz/crcs/ectester/data/test/secg/sect163k1-dh-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/secg/sect163k1-dh-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-kdf.csv create mode 100644 src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/secg/sect163k1-keyU.csv create mode 100644 src/cz/crcs/ectester/data/test/secg/sect163k1-keyV.csv (limited to 'src/cz/crcs/ectester/data/EC_Store.java') diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap index 3a5506d..bed5dc6 100644 Binary files a/!uploader/ectester.cap and b/!uploader/ectester.cap differ diff --git a/dist/ECTester.jar b/dist/ECTester.jar index 348be01..a5dd71c 100644 Binary files a/dist/ECTester.jar and b/dist/ECTester.jar differ diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index cac5d79..534d552 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -958,6 +958,9 @@ public class EC_Consts { public static final byte CORRUPTION_MAX = (byte) 0x06; public static final byte CORRUPTION_INCREMENT = (byte) 0x07; public static final byte CORRUPTION_INFINITY = (byte) 0x08; + public static final byte CORRUPTION_PREFIX_COMPRESSED = (byte) 0x09; + public static final byte CORRUPTION_PREFIX_HYBRID = (byte) 0x0a; + public static final byte CORRUPTION_PREFIX_UNCOMPRESSED = (byte) 0x0b; // toX962 FORM types public static final byte X962_UNCOMPRESSED = (byte) 0x00; @@ -1290,6 +1293,15 @@ public class EC_Consts { case CORRUPTION_INFINITY: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 0); return 1; + case CORRUPTION_PREFIX_COMPRESSED: + buffer[offset] = 2; + break; + case CORRUPTION_PREFIX_HYBRID: + buffer[offset] = 6; + break; + case CORRUPTION_PREFIX_UNCOMPRESSED: + buffer[offset] = 4; + break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } diff --git a/src/cz/crcs/ectester/data/EC_Category.java b/src/cz/crcs/ectester/data/EC_Category.java index aed7e7d..81b8784 100644 --- a/src/cz/crcs/ectester/data/EC_Category.java +++ b/src/cz/crcs/ectester/data/EC_Category.java @@ -3,7 +3,7 @@ package cz.crcs.ectester.data; import cz.crcs.ectester.reader.ec.EC_Params; import java.util.Collections; -import java.util.HashMap; +import java.util.TreeMap; import java.util.Map; /** @@ -50,7 +50,7 @@ public class EC_Category { } public Map getObjects(Class cls) { - Map objs = new HashMap<>(); + Map objs = new TreeMap<>(); for (Map.Entry entry : objects.entrySet()) { if (cls.isInstance(entry.getValue())) { objs.put(entry.getKey(), cls.cast(entry.getValue())); diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index 60a1065..c32f1ce 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -25,6 +25,7 @@ import java.io.InputStream; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.TreeMap; /** * @author Jan Jancar johny@neuromancer.sk @@ -95,7 +96,7 @@ public class EC_Store { private EC_Category parseCategory(String name, String dir, String desc) throws ParserConfigurationException, IOException, SAXException { - Map objMap = new HashMap<>(); + Map objMap = new TreeMap<>(); InputStream curvesStream = this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/curves.xml"); if (curvesStream != null) { diff --git a/src/cz/crcs/ectester/data/nist/b163.csv b/src/cz/crcs/ectester/data/nist/b163.csv new file mode 100644 index 0000000..b211f63 --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/b163.csv @@ -0,0 +1 @@ +00a3,0007,0006,0003,000000000000000000000000000000000000000001,020a601907b8c953ca1481eb10512f78744a3205fd,03f0eba16286a2d57ea0991168d4994637e8343e36,00d51fbc6c71a0094fa2cdd545b11c5c0c797324f1,040000000000000000000292FE77E70C12A4234C33,2 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nist/b233.csv b/src/cz/crcs/ectester/data/nist/b233.csv new file mode 100644 index 0000000..79f0e85 --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/b233.csv @@ -0,0 +1 @@ +00e9,004a,0000,0000,000000000000000000000000000000000000000000000000000000000001,0066647ede6c332c7f8c0923bb58213b333b20e9ce4281fe115f7d8f90ad,00fac9dfcbac8313bb2139f1bb755fef65bc391f8b36f8f8eb7371fd558b,01006a08a41903350678e58528bebf8a0beff867a7ca36716f7e01f81052,1000000000000000000000000000013e974e72f8a6922031d2603cfe0d7,2 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nist/b283.csv b/src/cz/crcs/ectester/data/nist/b283.csv new file mode 100644 index 0000000..88506b3 --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/b283.csv @@ -0,0 +1 @@ +011b,000c,0007,0005,00000000000000000000000000000000000000000000000000000000000000000000001,27b680ac8b8596da5a4af8a19a0303fca97fd7645309fa2a581485af6263e313b79a2f5,5f939258db7dd90e1934f8c70b0dfec2eed25b8557eac9c80e2e198f8cdbecd86b12053,3676854fe24141cb98fe6d4b20d02b4516ff702350eddb0826779c813f0df45be8112f4,3ffffffffffffffffffffffffffffffffffef90399660fc938a90165b042a7cefadb307,2 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nist/b409.csv b/src/cz/crcs/ectester/data/nist/b409.csv new file mode 100644 index 0000000..ed5ef5b --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/b409.csv @@ -0,0 +1,9 @@ +0199,0057,0000,0000,0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,021a5c2c8ee9feb5c4b9a753b7b476b7fd6422ef1f3dd674761fa99d6ac27c8a9a197b272822f6cd57a55aa4f50ae317b13545f,15d4860d088ddb3496b0c6064756260441cde4af1771d4db01ffe5b34e59703dc255a868a1180515603aeab60794e54bb7996a7,061b1cfab6be5f32bbfa78324ed106a7636b9c5a7bd198d0158aa4f5488d08f38514f1fdf4b4f40d2181b3681c364ba0273c706,10000000000000000000000000000000000000000000000000001e2aad6a612f33307be5fa47c3c9e052f838164cd37d9a21173,2 + + + + + + + + diff --git a/src/cz/crcs/ectester/data/nist/b571.csv b/src/cz/crcs/ectester/data/nist/b571.csv new file mode 100644 index 0000000..c0bef32 --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/b571.csv @@ -0,0 +1 @@ +023b,000a,0005,0002,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,2f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a,303001d34b856296c16c0d40d3cd7750a93d1d2955fa80aa5f40fc8db7b2abdbde53950f4c0d293cdd711a35b67fb1499ae60038614f1394abfa3b4c850d927e1e7769c8eec2d19,37bf27342da639b6dccfffeb73d69d78c6c27a6009cbbca1980f8533921e8a684423e43bab08a576291af8f461bb2a8b3531d2f0485c19b16e2f1516e23dd3c1a4827af1b8ac15b,3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47,2 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nist/curves.xml b/src/cz/crcs/ectester/data/nist/curves.xml index 00b109c..2abf72f 100644 --- a/src/cz/crcs/ectester/data/nist/curves.xml +++ b/src/cz/crcs/ectester/data/nist/curves.xml @@ -31,4 +31,65 @@ prime p521.csv + + + K-163 + 163 + binary + k163.csv + + + B-163 + 163 + binary + b163.csv + + + K-233 + 233 + binary + k233.csv + + + B-233 + 233 + binary + b233.csv + + + K-283 + 283 + binary + k283.csv + + + B-283 + 283 + binary + b283.csv + + + K-409 + 409 + binary + k409.csv + + + B-409 + 409 + binary + b409.csv + + + K-571 + 571 + binary + k571.csv + + + B-571 + 571 + binary + b571.csv + \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nist/k163.csv b/src/cz/crcs/ectester/data/nist/k163.csv new file mode 100644 index 0000000..d4f21be --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/k163.csv @@ -0,0 +1 @@ +00a3,0007,0006,0003,000000000000000000000000000000000000000001,000000000000000000000000000000000000000001,02fe13c0537bbc11acaa07d793de4e6d5e5c94eee8,0289070fb05d38ff58321f2e800536d538ccdaa3d9,04000000000000000000020108A2E0CC0D99F8A5EF,2 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nist/k233.csv b/src/cz/crcs/ectester/data/nist/k233.csv new file mode 100644 index 0000000..45e3c49 --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/k233.csv @@ -0,0 +1 @@ +00e9,004a,0000,0000,000000000000000000000000000000000000000000000000000000000000,000000000000000000000000000000000000000000000000000000000001,017232ba853a7e731af129f22ff4149563a419c26bf50a4c9d6eefad6126,01db537dece819b7f70f555a67c427a8cd9bf18aeb9b56e0c11056fae6a3,8000000000000000000000000000069d5bb915bcd46efb1ad5f173abdf,4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nist/k283.csv b/src/cz/crcs/ectester/data/nist/k283.csv new file mode 100644 index 0000000..b0e2800 --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/k283.csv @@ -0,0 +1 @@ +011b,000c,0007,0005,00000000000000000000000000000000000000000000000000000000000000000000000,00000000000000000000000000000000000000000000000000000000000000000000001,503213f78ca44883f1a3b8162f188e553cd265f23c1567a16876913b0c2ac2458492836,1ccda380f1c9e318d90f95d07e5426fe87e45c0e8184698e45962364e34116177dd2259,1ffffffffffffffffffffffffffffffffffe9ae2ed07577265dff7f94451e061e163c61,4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nist/k409.csv b/src/cz/crcs/ectester/data/nist/k409.csv new file mode 100644 index 0000000..fc44b82 --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/k409.csv @@ -0,0 +1 @@ +0199,0057,0000,0000,0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,060f05f658f49c1ad3ab1890f7184210efd0987e307c84c27accfb8f9f67cc2c460189eb5aaaa62ee222eb1b35540cfe9023746,1e369050b7c4e42acba1dacbf04299c3460782f918ea427e6325165e9ea10e3da5f6c42e9c55215aa9ca27a5863ec48d8e0286b,7ffffffffffffffffffffffffffffffffffffffffffffffffffe5f83b2d4ea20400ec4557d5ed3e3e7ca5b4b5c83b8e01e5fcf,4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nist/k571.csv b/src/cz/crcs/ectester/data/nist/k571.csv new file mode 100644 index 0000000..5660f6a --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/k571.csv @@ -0,0 +1 @@ +023b,000a,0005,0002,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001,26eb7a859923fbc82189631f8103fe4ac9ca2970012d5d46024804801841ca44370958493b205e647da304db4ceb08cbbd1ba39494776fb988b47174dca88c7e2945283a01c8972,349dc807f4fbf374f4aeade3bca95314dd58cec9f307a54ffc61efc006d8a2c9d4979c0ac44aea74fbebbb9f772aedcb620b01a7ba7af1b320430c8591984f601cd4c143ef1c7a3,20000000000000000000000000000000000000000000000000000000000000000000000131850e1f19a63e4b391a8db917f4138b630d84be5d639381e91deb45cfe778f637c1001,4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/secg/curves.xml b/src/cz/crcs/ectester/data/secg/curves.xml index 1807ec3..c04fe38 100644 --- a/src/cz/crcs/ectester/data/secg/curves.xml +++ b/src/cz/crcs/ectester/data/secg/curves.xml @@ -1,6 +1,48 @@ + + secp112r1 + 112 + prime + secp112r1.csv + + + secp112r2 + 112 + prime + secp112r2.csv + + + secp128r1 + 128 + prime + secp128r1.csv + + + secp128r2 + 128 + prime + secp128r2.csv + + + secp160k1 + 160 + prime + secp160k1.csv + + + secp160r1 + 160 + prime + secp160r1.csv + + + secp160r2 + 160 + prime + secp160r2.csv + secp192k1 192 diff --git a/src/cz/crcs/ectester/data/secg/secp112r1.csv b/src/cz/crcs/ectester/data/secg/secp112r1.csv new file mode 100644 index 0000000..1f63812 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp112r1.csv @@ -0,0 +1 @@ +DB7C2ABF62E35E668076BEAD208B,DB7C2ABF62E35E668076BEAD2088,659EF8BA043916EEDE8911702B22,09487239995A5EE76B55F9C2F098,A89CE5AF8724C0A23E0E0FF77500,DB7C2ABF62E35E7628DFAC6561C5,1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/secg/secp112r2.csv b/src/cz/crcs/ectester/data/secg/secp112r2.csv new file mode 100644 index 0000000..4ed7ad9 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp112r2.csv @@ -0,0 +1 @@ +DB7C2ABF62E35E668076BEAD208B,6127C24C05F38A0AAAF65C0EF02C,51DEF1815DB5ED74FCC34C85D709,4BA30AB5E892B4E1649DD0928643,ADCD46F5882E3747DEF36E956E97,36DF0AAFD8B8D7597CA10520D04B,4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/secg/secp128r1.csv b/src/cz/crcs/ectester/data/secg/secp128r1.csv new file mode 100644 index 0000000..a7f2dc8 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp128r1.csv @@ -0,0 +1 @@ +FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF,FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC,E87579C11079F43DD824993C2CEE5ED3,161FF7528B899B2D0C28607CA52C5B86,CF5AC8395BAFEB13C02DA292DDED7A83,FFFFFFFE0000000075A30D1B9038A115,1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/secg/secp128r2.csv b/src/cz/crcs/ectester/data/secg/secp128r2.csv new file mode 100644 index 0000000..384de92 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp128r2.csv @@ -0,0 +1 @@ +FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF,D6031998D1B3BBFEBF59CC9BBFF9AEE1,5EEEFCA380D02919DC2C6558BB6D8A5D,7B6AA5D85E572983E6FB32A7CDEBC140,27B6916A894D3AEE7106FE805FC34B44,3FFFFFFF7FFFFFFFBE0024720613B5A3,4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/secg/secp160k1.csv b/src/cz/crcs/ectester/data/secg/secp160k1.csv new file mode 100644 index 0000000..6a95e94 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp160k1.csv @@ -0,0 +1 @@ +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73,0000000000000000000000000000000000000000,0000000000000000000000000000000000000007,3B4C382CE37AA192A4019E763036F4F5DD4D7EBB,938CF935318FDCED6BC28286531733C3F03C4FEE,0100000000000000000001B8FA16DFAB9ACA16B6B3,1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/secg/secp160r1.csv b/src/cz/crcs/ectester/data/secg/secp160r1.csv new file mode 100644 index 0000000..a2be6f9 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp160r1.csv @@ -0,0 +1 @@ +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC,1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45,4A96B5688EF573284664698968C38BB913CBFC82,23A628553168947D59DCC912042351377AC5FB32,0100000000000000000001F4C8F927AED3CA752257,1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/secg/secp160r2.csv b/src/cz/crcs/ectester/data/secg/secp160r2.csv new file mode 100644 index 0000000..354ba53 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp160r2.csv @@ -0,0 +1 @@ +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73,FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70,B4E134D3FB59EB8BAB57274904664D5AF50388BA,52DCB034293A117E1F4FF11B30F7199D3144CE6D,FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E,0100000000000000000000351EE786A818F3A1A16B,1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/secg/sect163k1-dh-kdf.csv b/src/cz/crcs/ectester/data/test/secg/sect163k1-dh-kdf.csv new file mode 100644 index 0000000..fe86cff --- /dev/null +++ b/src/cz/crcs/ectester/data/test/secg/sect163k1-dh-kdf.csv @@ -0,0 +1 @@ +6655A9C8F9E593149DB24C91CE621641035C9282 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/secg/sect163k1-dh-raw.csv b/src/cz/crcs/ectester/data/test/secg/sect163k1-dh-raw.csv new file mode 100644 index 0000000..4007c6d --- /dev/null +++ b/src/cz/crcs/ectester/data/test/secg/sect163k1-dh-raw.csv @@ -0,0 +1 @@ +0357C3DCD1DF3E27BD8885170EE4975B5081DA7FA7 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/secg/sect163k1-dh-sha1.csv b/src/cz/crcs/ectester/data/test/secg/sect163k1-dh-sha1.csv new file mode 100644 index 0000000..badc2b7 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/secg/sect163k1-dh-sha1.csv @@ -0,0 +1 @@ +13132F8088D60F9FE0D955AE04C9D20DA829A38B \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-kdf.csv b/src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-kdf.csv new file mode 100644 index 0000000..b9c6f47 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-kdf.csv @@ -0,0 +1 @@ +59798528083F50B07528353CDA99D0E460A7229D \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-raw.csv b/src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-raw.csv new file mode 100644 index 0000000..8ec537a --- /dev/null +++ b/src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-raw.csv @@ -0,0 +1 @@ +04CB89474B33A518E1C3CD11BEB6E2B0CF48BEE64D \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-sha1.csv new file mode 100644 index 0000000..b96d64e --- /dev/null +++ b/src/cz/crcs/ectester/data/test/secg/sect163k1-dhc-sha1.csv @@ -0,0 +1 @@ +08E7DBCB78FE4020578C5EAA0AACA2CFFB7B38ED \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/secg/sect163k1-keyU.csv b/src/cz/crcs/ectester/data/test/secg/sect163k1-keyU.csv new file mode 100644 index 0000000..23fc166 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/secg/sect163k1-keyU.csv @@ -0,0 +1 @@ +037D529FA37E42195F10111127FFB2BB38644806BC,0447026EEE8B34157F3EB51BE5185D2BE0249ED776,03A41434AA99C2EF40C8495B2ED9739CB2155A1E0D \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/secg/sect163k1-keyV.csv b/src/cz/crcs/ectester/data/test/secg/sect163k1-keyV.csv new file mode 100644 index 0000000..6197eba --- /dev/null +++ b/src/cz/crcs/ectester/data/test/secg/sect163k1-keyV.csv @@ -0,0 +1 @@ +072783FAAB9549002B4F13140B88132D1C75B3886C,05A976794EA79A4DE26E2E19418F097942C08641C7,57E8A78E842BF4ACD5C315AA0569DB1703541D96 \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 247a260..80c3fb0 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -82,6 +82,7 @@ public class ECTester { private boolean optSimulate = false; //Action-related options + private String optListNamed; private String optTestCase; private int optGenerateAmount; private int optECDHCount; @@ -107,6 +108,10 @@ public class ECTester { help(); return; } + //if not, read other options first, into attributes, then do action + if (!readOptions(cli)) { + return; + } dataStore = new EC_Store(); //if list, print and quit @@ -115,11 +120,6 @@ public class ECTester { return; } - //if not, read other options first, into attributes, then do action - if (!readOptions(cli)) { - return; - } - //init CardManager cardManager = new CardMngr(optVerbose, optSimulate); @@ -245,7 +245,7 @@ public class ECTester { OptionGroup actions = new OptionGroup(); actions.setRequired(true); actions.addOption(Option.builder("h").longOpt("help").desc("Print help.").build()); - actions.addOption(Option.builder("ln").longOpt("list-named").desc("Print the list of supported named curves and keys.").build()); + actions.addOption(Option.builder("ln").longOpt("list-named").desc("Print the list of supported named curves and keys.").hasArg().argName("what").optionalArg(true).build()); actions.addOption(Option.builder("e").longOpt("export").desc("Export the defaut curve parameters of the card(if any).").build()); actions.addOption(Option.builder("g").longOpt("generate").desc("Generate [amount] of EC keys.").hasArg().argName("amount").optionalArg(true).build()); actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support.").hasArg().argName("test_case").optionalArg(true).build()); @@ -334,6 +334,11 @@ public class ECTester { optFresh = cli.hasOption("fresh"); optSimulate = cli.hasOption("simulate"); + if (cli.hasOption("list-named")) { + optListNamed = cli.getOptionValue("list-named"); + return true; + } + if ((optKey != null || optNamedKey != null) && (optPublic != null || optPrivate != null || optNamedPublic != null || optNamedPrivate != null)) { System.err.print("Can only specify the whole key with --key/--named-key or pubkey and privkey with --public/--named-public and --private/--named-private."); return false; @@ -403,8 +408,8 @@ public class ECTester { optPrimeField = true; } - optTestCase = cli.getOptionValue("test", "default"); - String[] tests = new String[]{"default", "non-prime", "invalid", "wrong"}; + optTestCase = cli.getOptionValue("test", "default").toLowerCase(); + String[] tests = new String[]{"default", "non-prime", "invalid", "smallpub", "test-vectors", "wrong"}; List testsList = Arrays.asList(tests); if (!testsList.contains(optTestCase)) { System.err.println("Unknown test case. Should be one of: " + Arrays.toString(tests)); @@ -463,35 +468,54 @@ public class ECTester { */ private void list() { Map categories = dataStore.getCategories(); - for (EC_Category cat : categories.values()) { - System.out.println("\t- " + cat.getName() + ": " + (cat.getDesc() == null ? "" : cat.getDesc())); - - Map curves = cat.getObjects(EC_Curve.class); - int size = curves.size(); - if (size > 0) { - System.out.print("\t\tCurves: "); - for (Map.Entry curve : curves.entrySet()) { - System.out.print(curve.getKey()); - size--; - if (size > 0) - System.out.print(", "); + if (optListNamed == null) { + // print all categories, briefly + for (EC_Category cat : categories.values()) { + System.out.println("\t- " + cat.getName() + ": " + (cat.getDesc() == null ? "" : cat.getDesc())); + + Map curves = cat.getObjects(EC_Curve.class); + int size = curves.size(); + if (size > 0) { + System.out.print("\t\tCurves: "); + for (Map.Entry curve : curves.entrySet()) { + System.out.print(curve.getKey()); + size--; + if (size > 0) + System.out.print(", "); + } + System.out.println(); } - System.out.println(); - } - Map keys = cat.getObjects(EC_Key.class); - size = keys.size(); - if (size > 0) { - System.out.print("\t\tKeys: "); - for (Map.Entry key : keys.entrySet()) { - System.out.print(key.getKey()); - size--; - if (size > 0) - System.out.print(", "); + Map keys = cat.getObjects(EC_Key.class); + size = keys.size(); + if (size > 0) { + System.out.print("\t\tKeys: "); + for (Map.Entry key : keys.entrySet()) { + System.out.print(key.getKey()); + size--; + if (size > 0) + System.out.print(", "); + } + System.out.println(); + } + + Map keypairs = cat.getObjects(EC_Keypair.class); + size = keypairs.size(); + if (size > 0) { + System.out.print("\t\tKeypairs: "); + for (Map.Entry key : keypairs.entrySet()) { + System.out.print(key.getKey()); + size--; + if (size > 0) + System.out.print(", "); + } + System.out.println(); } System.out.println(); } - System.out.println(); + } else if (categories.containsKey(optListNamed)) { + // print given category + //TODO } } @@ -596,8 +620,7 @@ public class ECTester { private void test() throws IOException, CardException { List commands = new LinkedList<>(); - if (optTestCase.equalsIgnoreCase("default")) { - + if (optTestCase.equals("default")) { if (optNamedCurve != null) { if (optPrimeField) { commands.addAll(testCurves(optNamedCurve, KeyPair.ALG_EC_FP)); @@ -641,21 +664,52 @@ public class ECTester { } } } - } else if (optTestCase.equalsIgnoreCase("wrong")) { - if (optPrimeField) { - commands.addAll(testCurves("wrong", KeyPair.ALG_EC_FP)); - } - if (optBinaryField) { - commands.addAll(testCurves("wrong", KeyPair.ALG_EC_F2M)); - } - } else if (optTestCase.equalsIgnoreCase("non-prime")) { - - } else if (optTestCase.equalsIgnoreCase("smallpub")) { + } else if (optTestCase.equals("test-vectors")) { + /* Set original curves (secg/nist/brainpool). Set keypairs from test vectors. + * Do ECDH both ways, export and verify that the result is correct. + * + */ + String category = optNamedCurve == null ? "secg" : optNamedCurve; + Map curves = dataStore.getObjects(EC_Curve.class, category); + //TODO - } else if (optTestCase.equalsIgnoreCase("invalid")) { + } else { + // These tests are dangerous, prompt before them. + System.out.println("The test you selected (" + optTestCase + ") is potentially dangerous."); + System.out.println("Some of these tests have caused temporary DoS of some cards."); + System.out.print("Do you want to proceed? (y/n):"); + String confirmation = System.console().readLine(); + if (!Arrays.asList("yes", "y", "Y").contains(confirmation)) { + return; + } + if (optTestCase.equals("wrong") || optTestCase.equals("non-prime")) { + /* Just do the default tests on the wrong and non-prime curves. + * These should generally fail, the curves aren't safe. + */ + if (optPrimeField) { + commands.addAll(testCurves(optTestCase, KeyPair.ALG_EC_FP)); + } + if (optBinaryField) { + commands.addAll(testCurves(optTestCase, KeyPair.ALG_EC_F2M)); + } + } else if (optTestCase.equals("smallpub")) { + /* Do the default tests with the public keys set to provided smallpub keys. + * These should fail, the curves aren't safe so that if the computation with + * a small order public key succeeds the private key modulo the public key order + * is revealed. + */ + //TODO + } else if (optTestCase.equals("invalid")) { + /* Set original curves (secg/nist/brainpool). Generate local. + * Try ECDH with invalid public keys of increasing (or decreasing) order. + * + */ + //TODO + } } + List test = Command.sendAll(commands); systemOutLogger.println(Response.toString(test)); -- cgit v1.3.1 From 6218dd2809dcc2f00adb70ac61784c681d4491ca Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 28 Mar 2017 01:50:53 +0200 Subject: Added nist and brainpool test vectors, also smallpub test --- !uploader/ectester.cap | Bin 13811 -> 13811 bytes !uploader/simpleECC.cap | Bin 18330 -> 0 bytes !uploader/simpleECC221.cap | Bin 4562 -> 0 bytes README.md | 45 ++--- dist/ECTester.jar | Bin 253043 -> 283382 bytes src/cz/crcs/ectester/data/EC_Category.java | 1 + src/cz/crcs/ectester/data/EC_Store.java | 7 +- src/cz/crcs/ectester/data/smallpub/keys.xml | 14 +- .../data/test/brainpool/brainpoolP224r1-dh-raw.csv | 1 + .../test/brainpool/brainpoolP224r1-dh-sha1.csv | 1 + .../data/test/brainpool/brainpoolP224r1-keyA.csv | 1 + .../data/test/brainpool/brainpoolP224r1-keyB.csv | 1 + .../data/test/brainpool/brainpoolP256r1-dh-raw.csv | 1 + .../test/brainpool/brainpoolP256r1-dh-sha1.csv | 1 + .../data/test/brainpool/brainpoolP256r1-keyA.csv | 1 + .../data/test/brainpool/brainpoolP256r1-keyB.csv | 1 + .../data/test/brainpool/brainpoolP384r1-dh-raw.csv | 1 + .../test/brainpool/brainpoolP384r1-dh-sha1.csv | 1 + .../data/test/brainpool/brainpoolP384r1-keyA.csv | 1 + .../data/test/brainpool/brainpoolP384r1-keyB.csv | 1 + .../data/test/brainpool/brainpoolP512r1-dh-raw.csv | 1 + .../test/brainpool/brainpoolP512r1-dh-sha1.csv | 1 + .../data/test/brainpool/brainpoolP512r1-keyA.csv | 1 + .../data/test/brainpool/brainpoolP512r1-keyB.csv | 1 + src/cz/crcs/ectester/data/test/keys.xml | 202 +++++++++++++++++++++ .../crcs/ectester/data/test/nist/b163-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/b163-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/b163-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/b163-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/b233-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/b233-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/b233-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/b233-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/b283-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/b283-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/b283-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/b283-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/b409-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/b409-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/b409-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/b409-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/b571-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/b571-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/b571-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/b571-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/k163-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/k163-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/k163-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/k163-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/k233-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/k233-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/k233-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/k233-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/k283-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/k283-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/k283-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/k283-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/k409-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/k409-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/k409-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/k409-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/k571-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/k571-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/k571-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/k571-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/p192-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/p192-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/p192-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/p192-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/p224-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/p224-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/p224-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/p224-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/p256-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/p256-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/p256-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/p256-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/p384-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/p384-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/p384-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/p384-keyIUT.csv | 1 + .../crcs/ectester/data/test/nist/p521-dhc-raw.csv | 1 + .../crcs/ectester/data/test/nist/p521-dhc-sha1.csv | 1 + .../crcs/ectester/data/test/nist/p521-keyCAVS.csv | 1 + .../crcs/ectester/data/test/nist/p521-keyIUT.csv | 1 + src/cz/crcs/ectester/reader/ECTester.java | 18 +- 86 files changed, 322 insertions(+), 41 deletions(-) delete mode 100644 !uploader/simpleECC.cap delete mode 100644 !uploader/simpleECC221.cap create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-dh-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-dh-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-keyA.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-keyB.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-dh-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-dh-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-keyA.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-keyB.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-dh-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-dh-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-keyA.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-keyB.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-dh-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-dh-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-keyA.csv create mode 100644 src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-keyB.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b163-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b163-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b163-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b163-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b233-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b233-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b233-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b233-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b283-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b283-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b283-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b283-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b409-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b409-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b409-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b409-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b571-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b571-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b571-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/b571-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k163-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k163-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k163-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k163-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k233-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k233-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k233-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k233-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k283-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k283-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k283-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k283-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k409-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k409-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k409-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k409-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k571-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k571-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k571-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/k571-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p192-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p192-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p192-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p192-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p224-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p224-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p224-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p224-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p256-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p256-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p256-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p256-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p384-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p384-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p384-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p384-keyIUT.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p521-dhc-raw.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p521-dhc-sha1.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p521-keyCAVS.csv create mode 100644 src/cz/crcs/ectester/data/test/nist/p521-keyIUT.csv (limited to 'src/cz/crcs/ectester/data/EC_Store.java') diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap index bed5dc6..de865a9 100644 Binary files a/!uploader/ectester.cap and b/!uploader/ectester.cap differ diff --git a/!uploader/simpleECC.cap b/!uploader/simpleECC.cap deleted file mode 100644 index 886ce88..0000000 Binary files a/!uploader/simpleECC.cap and /dev/null differ diff --git a/!uploader/simpleECC221.cap b/!uploader/simpleECC221.cap deleted file mode 100644 index ba7bbb5..0000000 Binary files a/!uploader/simpleECC221.cap and /dev/null differ diff --git a/README.md b/README.md index 0ec96dc..0bbc5c9 100644 --- a/README.md +++ b/README.md @@ -21,51 +21,44 @@ See `java -jar ectester.jar -h` for more. ### Options ``` - -ln,--list-named Print the list of supported named - curves, keys and keypairs. + -ln,--list-named Print the list of supported named + curves and keys. -dsa,--ecdsa Sign data with ECDSA, [count] times. - -t,--test Test ECC support. + -t,--test Test ECC support. -dh,--ecdh Do ECDH, [count] times. -e,--export Export the defaut curve parameters of the card(if any). -g,--generate Generate [amount] of EC keys. -h,--help Print help. - + -dhc,--ecdhc Do ECDHC, [count] times. -a,--all Test all curve sizes. -b,--bit-size Set curve size. - - -c,--curve Use curve from file [curve_file] + -fp,--prime-field Use a prime field. + -f2m,--binary-field Use a binary field. + -c,--curve Use curve from file (field,a,b,gx,gy,r,k). - -nc,--named-curve Use a named curve. - -u,--custom Use a custom curve(applet-side + -nc,--named-curve Use a named curve, from CurveDB: + + -u,--custom Use a custom curve (applet-side embedded, SECG curves). - - -fp,--prime-field Use prime field curve. - -f2m,--binary-field Use binary field curve. - - -npub,--named-public Use public key from KeyDB: [cat/id] - -pub,--public Use public key from file [pubkey_file] + -npub,--named-public Use public key from KeyDB: + -pub,--public Use public key from file (wx,wy). - -priv,--private Use private key from file - [privkey_file] (s). - -npriv,--named-private Use private key from KeyDB: [cat/id] - - -k,--key Use keyPair from file [key_file] + (s). + -npriv,--named-private Use private key from KeyDB: + -k,--key Use keyPair from file  (wx,wy,s). - -nk,--named-key Use keyPair from KeyDB: [cat/id] - - -i,--input Input from file [input_file], for ecdsa + -nk,--named-key Use keyPair from KeyDB: + -i,--input Input from file , for ECDSA signing. - -o,--output Output into file [output_file]. + -o,--output Output into file . -l,--log Log output into file [log_file]. -v,--verbose Turn on verbose logging. - - -f,--fresh Generate fresh keys(set domain + -f,--fresh Generate fresh keys (set domain parameters before every generation). -s,--simulate Simulate a card with jcardsim instead of using a terminal. - ``` ### Example diff --git a/dist/ECTester.jar b/dist/ECTester.jar index a5dd71c..2140b4d 100644 Binary files a/dist/ECTester.jar and b/dist/ECTester.jar differ diff --git a/src/cz/crcs/ectester/data/EC_Category.java b/src/cz/crcs/ectester/data/EC_Category.java index 81b8784..859b942 100644 --- a/src/cz/crcs/ectester/data/EC_Category.java +++ b/src/cz/crcs/ectester/data/EC_Category.java @@ -67,4 +67,5 @@ public class EC_Category { return null; } } + } diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index c32f1ce..aec635e 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -179,7 +179,7 @@ public class EC_Store { return new EC_Category(name, dir, desc, objMap); } - private EC_Params parseKeylike(String dir, Element elem) throws SAXException { + private EC_Params parseKeylike(String dir, Element elem) throws SAXException, IOException { Node file = elem.getElementsByTagName("file").item(0); Node curve = elem.getElementsByTagName("curve").item(0); @@ -199,7 +199,9 @@ public class EC_Store { } else { throw new SAXException("?"); } - result.readCSV(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/" + file.getTextContent())); + if(!result.readCSV(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/" + file.getTextContent()))) { + throw new IOException("Invalid CSV data."); + } return result; } @@ -243,5 +245,4 @@ public class EC_Store { return getObject(objClass, parts[0], parts[1]); } - } diff --git a/src/cz/crcs/ectester/data/smallpub/keys.xml b/src/cz/crcs/ectester/data/smallpub/keys.xml index 83e98b0..fbdf5e8 100644 --- a/src/cz/crcs/ectester/data/smallpub/keys.xml +++ b/src/cz/crcs/ectester/data/smallpub/keys.xml @@ -6,43 +6,43 @@ ecsp128-pub ecsp128_pub.csv - ecsp128 + smallpub/ecsp128 order = 5 ecsp160-pub ecsp160_pub.csv - ecsp160 + smallpub/ecsp160 order = 3 ecsp192-pub ecsp192_pub.csv - ecsp192 + smallpub/ecsp192 order = 3 ecsp224-pub ecsp224_pub.csv - ecsp224 + smallpub/ecsp224 order = 5 ecsp256-pub ecsp256_pub.csv - ecsp256 + smallpub/ecsp256 order = 3 ecsp384-pub ecsp384_pub.csv - ecsp384 + smallpub/ecsp384 order = 3 ecsp521-pub ecsp521_pub.csv - ecsp521 + smallpub/ecsp521 order = 5 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-dh-raw.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-dh-raw.csv new file mode 100644 index 0000000..9913e7d --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-dh-raw.csv @@ -0,0 +1 @@ +312DFD98783F9FB77B9704945A73BEB6DCCBE3B65D0F967DCAB574EB \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-dh-sha1.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-dh-sha1.csv new file mode 100644 index 0000000..01c5dbe --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-dh-sha1.csv @@ -0,0 +1 @@ +4ADCA2E2CFE8DBD4F0B9CE27E4422C57EE0A6B98 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-keyA.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-keyA.csv new file mode 100644 index 0000000..db4d4b5 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-keyA.csv @@ -0,0 +1 @@ +B104A67A6F6E85E14EC1825E1539E8ECDBBF584922367DD88C6BDCF2,46D782E7FDB5F60CD8404301AC5949C58EDB26BC68BA07695B750A94,7C4B7A2C8A4BAD1FBB7D79CC0955DB7C6A4660CA64CC4778159B495E \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-keyB.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-keyB.csv new file mode 100644 index 0000000..6544d00 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP224r1-keyB.csv @@ -0,0 +1 @@ +2A97089A9296147B71B21A4B574E1278245B536F14D8C2B9D07A874E,9B900D7C77A709A797276B8CA1BA61BB95B546FC29F862E44D59D25B,63976D4AAE6CD0F6DD18DEFEF55D96569D0507C03E74D6486FFA28FB \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-dh-raw.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-dh-raw.csv new file mode 100644 index 0000000..29aac4a --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-dh-raw.csv @@ -0,0 +1 @@ +89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-dh-sha1.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-dh-sha1.csv new file mode 100644 index 0000000..7790e0b --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-dh-sha1.csv @@ -0,0 +1 @@ +4F1CCFFBB2A14DA1F17DE291DABCDD109EB13BB7 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-keyA.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-keyA.csv new file mode 100644 index 0000000..a2f79da --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-keyA.csv @@ -0,0 +1 @@ +44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E3100BE5,8AB4846F11CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10EB089BDC,81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B063039804F1D \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-keyB.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-keyB.csv new file mode 100644 index 0000000..e2d8039 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP256r1-keyB.csv @@ -0,0 +1 @@ +8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B,990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A,55E40BC41E37E3E2AD25C3C6654511FFA8474A91A0032087593852D3E7D76BD3 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-dh-raw.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-dh-raw.csv new file mode 100644 index 0000000..93ec84b --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-dh-raw.csv @@ -0,0 +1 @@ +0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-dh-sha1.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-dh-sha1.csv new file mode 100644 index 0000000..c4b18a3 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-dh-sha1.csv @@ -0,0 +1 @@ +7562598C913DF9BCAD30D6985358F7779045B3A4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-keyA.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-keyA.csv new file mode 100644 index 0000000..7d923a3 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-keyA.csv @@ -0,0 +1 @@ +68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D4A6E77A252D6380FCAF068,55BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA20607493E0D038FF2FD30C2AB67D15C85F7FAA59,1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0BD65D6F15EB5D1EE1610DF870795143627D042 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-keyB.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-keyB.csv new file mode 100644 index 0000000..edb41f5 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP384r1-keyB.csv @@ -0,0 +1 @@ +4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E404B15738B2086DF37E71D1EB4,62D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E9185329B5B275903D192F8D4E1F32FE9CC78C48,032640BC6003C59260F7250C3DB58CE647F98E1260ACCE4ACDA3DD869F74E01F8BA5E0324309DB6A9831497ABAC96670 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-dh-raw.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-dh-raw.csv new file mode 100644 index 0000000..1b7e57a --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-dh-raw.csv @@ -0,0 +1 @@ +A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-dh-sha1.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-dh-sha1.csv new file mode 100644 index 0000000..554770a --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-dh-sha1.csv @@ -0,0 +1 @@ +8E4814D30F0B5C7FFA35E15809F529D6FD94D759 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-keyA.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-keyA.csv new file mode 100644 index 0000000..3122397 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-keyA.csv @@ -0,0 +1 @@ +0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD,72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7,16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-keyB.csv b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-keyB.csv new file mode 100644 index 0000000..6ce51b7 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/brainpool/brainpoolP512r1-keyB.csv @@ -0,0 +1 @@ +9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F,2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA,230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB80503666B25429 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/keys.xml b/src/cz/crcs/ectester/data/test/keys.xml index 56fc4e2..5f86b5b 100644 --- a/src/cz/crcs/ectester/data/test/keys.xml +++ b/src/cz/crcs/ectester/data/test/keys.xml @@ -13,4 +13,206 @@ secg/secp160r1-keyV.csv secg/secp160r1 + + sect163k1-U + secg/sect163k1-keyU.csv + secg/sect163k1 + + + sect163k1-V + secg/sect163k1-keyV.csv + secg/sect163k1 + + + + brainpoolP224r1-A + brainpool/brainpoolP224r1-keyA.csv + brainpool/brainpoolP224r1 + + + brainpoolP224r1-B + brainpool/brainpoolP224r1-keyB.csv + brainpool/brainpoolP224r1 + + + brainpoolP256r1-A + brainpool/brainpoolP256r1-keyA.csv + brainpool/brainpoolP256r1 + + + brainpoolP256r1-B + brainpool/brainpoolP256r1-keyB.csv + brainpool/brainpoolP256r1 + + + brainpoolP384r1-A + brainpool/brainpoolP384r1-keyA.csv + brainpool/brainpoolP384r1 + + + brainpoolP384r1-B + brainpool/brainpoolP384r1-keyB.csv + brainpool/brainpoolP384r1 + + + brainpoolP512r1-A + brainpool/brainpoolP512r1-keyA.csv + brainpool/brainpoolP512r1 + + + brainpoolP512r1-B + brainpool/brainpoolP512r1-keyB.csv + brainpool/brainpoolP512r1 + + + + p192-A + nist/p192-keyIUT.csv + nist/P-192 + + + p192-B + nist/p192-keyCAVS.csv + nist/P-192 + + + p224-A + nist/p224-keyIUT.csv + nist/P-224 + + + p224-B + nist/p224-keyCAVS.csv + nist/P-224 + + + p256-A + nist/p256-keyIUT.csv + nist/P-256 + + + p256-B + nist/p256-keyCAVS.csv + nist/P-256 + + + p384-A + nist/p384-keyIUT.csv + nist/P-384 + + + p384-B + nist/p384-keyCAVS.csv + nist/P-384 + + + p521-A + nist/p521-keyIUT.csv + nist/P-521 + + + p521-B + nist/p521-keyCAVS.csv + nist/P-521 + + + b163-A + nist/b163-keyIUT.csv + nist/B-163 + + + b163-B + nist/b163-keyCAVS.csv + nist/B-163 + + + b233-A + nist/b233-keyIUT.csv + nist/B-233 + + + b233-B + nist/b233-keyCAVS.csv + nist/B-233 + + + b283-A + nist/b283-keyIUT.csv + nist/B-283 + + + b283-B + nist/b283-keyCAVS.csv + nist/B-283 + + + b409-A + nist/b409-keyIUT.csv + nist/B-409 + + + b409-B + nist/b409-keyCAVS.csv + nist/B-409 + + + b571-A + nist/b571-keyIUT.csv + nist/B-571 + + + b571-B + nist/b571-keyCAVS.csv + nist/B-571 + + + k163-A + nist/k163-keyIUT.csv + nist/K-163 + + + k163-B + nist/k163-keyCAVS.csv + nist/K-163 + + + k233-A + nist/k233-keyIUT.csv + nist/K-233 + + + k233-B + nist/k233-keyCAVS.csv + nist/K-233 + + + k283-A + nist/k283-keyIUT.csv + nist/K-283 + + + k283-B + nist/k283-keyCAVS.csv + nist/K-283 + + + k409-A + nist/k409-keyIUT.csv + nist/K-409 + + + k409-B + nist/k409-keyCAVS.csv + nist/K-409 + + + k571-A + nist/k571-keyIUT.csv + nist/K-571 + + + k571-B + nist/k571-keyCAVS.csv + nist/K-571 + \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b163-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/b163-dhc-raw.csv new file mode 100644 index 0000000..fab00cb --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b163-dhc-raw.csv @@ -0,0 +1 @@ +0100fb42d177ffe6c31378e2e04e0da7376ffe8765 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b163-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/b163-dhc-sha1.csv new file mode 100644 index 0000000..8d98703 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b163-dhc-sha1.csv @@ -0,0 +1 @@ +10F4DDCF79C23FD7DC11563BF18B2BE75A139E4F \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b163-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/b163-keyCAVS.csv new file mode 100644 index 0000000..e0f7f15 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b163-keyCAVS.csv @@ -0,0 +1 @@ +00000003a647ba32dac71ec6780b0638a70cd24fc3bd4c8e,00000002e69e961541844a4aa33769a7bce710f6640a560c \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b163-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/b163-keyIUT.csv new file mode 100644 index 0000000..910ea7c --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b163-keyIUT.csv @@ -0,0 +1 @@ +000000035466701d0b0030d098b6ed2343d355c24c907271,00000000d8bc02f341d261860dfb65f0cb7f0b488d8296cc,00000003edae173de8fa0cf0412d6a7bdc81fdbd0617adf8 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b233-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/b233-dhc-raw.csv new file mode 100644 index 0000000..56ef836 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b233-dhc-raw.csv @@ -0,0 +1 @@ +00e9f3d8c4f1bec0f920e763ea1bb7415899f01734609e7547dc425ec946 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b233-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/b233-dhc-sha1.csv new file mode 100644 index 0000000..9795228 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b233-dhc-sha1.csv @@ -0,0 +1 @@ +958FD3D4A2F61130ACF6472A6DE421F11D9A4D13 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b233-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/b233-keyCAVS.csv new file mode 100644 index 0000000..bac3371 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b233-keyCAVS.csv @@ -0,0 +1 @@ +0000004756baddefc3dc337ab27b5452eb10affd9e31f5b55c330e90f0f686a2,0000012a79f65232308a21c98c01555ccafc7dce15c8fed3025a760cbd6c2327 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b233-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/b233-keyIUT.csv new file mode 100644 index 0000000..56d5f3a --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b233-keyIUT.csv @@ -0,0 +1 @@ +00000061e8a9b517fd05a026ec376616229fd8639a1fa76defe5398022f9d9c8,000000706b5cb08738a94552fee584b1372fead4af79040909fcf6f50084bbfa,0000003c3ee474ac0d0bc1df567e3c35f5f766c5332b2d6730ff0e4d8e75aedb \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b283-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/b283-dhc-raw.csv new file mode 100644 index 0000000..c1d1432 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b283-dhc-raw.csv @@ -0,0 +1 @@ +065194e26090e74047ee75f13f9769d20e1b52189650011e283daa090732cc53755dc366 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b283-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/b283-dhc-sha1.csv new file mode 100644 index 0000000..0d7bbf8 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b283-dhc-sha1.csv @@ -0,0 +1 @@ +75C8297B1DD59937F86C3063E8EC0B2B9AD118BF \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b283-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/b283-keyCAVS.csv new file mode 100644 index 0000000..9f973e7 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b283-keyCAVS.csv @@ -0,0 +1 @@ +02504e1a17819d39f010a4a69a0568299402b58f944a384c7d1a62c9c93ea4d1ff300e13,0265132f7b4c64b74b9179ed0f2e211f4328d625405022f554170da932b80fdf7c1aab12 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b283-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/b283-keyIUT.csv new file mode 100644 index 0000000..c7e4b04 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b283-keyIUT.csv @@ -0,0 +1 @@ +0561e495563018169804d4c8e2435b4afd85da376d914b69d39246f8e06113aa32e642d2,0781a7f59de7f42f5f9d6c3481f33fc5deb357c6ecf4c758e370d2435de3d8ee737703f4,02f43455842246a2cc8ec068e9d6c6e4160f6ba4e3b5d831d93c1daa8fd3d5a9660c7bb1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b409-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/b409-dhc-raw.csv new file mode 100644 index 0000000..36c3236 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b409-dhc-raw.csv @@ -0,0 +1 @@ +01d48a586be9285fa38dd3e70b0330b0ffebd327ceefef88fdc1521ef2fd61cbc9124e03b0c926e70fa56acb3edb54c3c48fab2b \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b409-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/b409-dhc-sha1.csv new file mode 100644 index 0000000..7264423 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b409-dhc-sha1.csv @@ -0,0 +1 @@ +B6562E95755880A16BC35FCC030AF5FEBC1113D4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b409-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/b409-keyCAVS.csv new file mode 100644 index 0000000..b737359 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b409-keyCAVS.csv @@ -0,0 +1 @@ +0146989a50297be373dd665c45455a2ae4c221da5cd424007bd97f9e8e846f96740f3fa58c3c94129671cdd4d7ea650a2aade9d7,01b42bffda843946a14ad6080f95b8fc6b7e173528d08ed36fe640aaf85aa00fb5edd5905a38b3c7961b7722b77b8dcb44bb25f5 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b409-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/b409-keyIUT.csv new file mode 100644 index 0000000..5eede05 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b409-keyIUT.csv @@ -0,0 +1 @@ +004ebc4d4acf9b404dabc3af3e8cbea8b88b32999d3ecb7f367b12eb3a6280b840038e22681637a7d16436e014f69616abf72e45,009e24109541c8024217e9ab2c963fa9e373640095a6c25a26eefac58e4342c0c85448b2709592a12402fe2b68a793c558ce8cd6,00ace92103ffe262ac17ad42a46d4366f4cb4c580eff3ab1dde6bddfdbb7374811d52b1fa99320b4af5d4e9208c14eb8efa8916c \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b571-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/b571-dhc-raw.csv new file mode 100644 index 0000000..be74f27 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b571-dhc-raw.csv @@ -0,0 +1 @@ +06775e1b99a236e02b020bc73666e5751c1210dcb6e9b02a69f4075376e49f7a1476d2209e861abb73f5e3ad189d268e035b1de93d47b3a64de5783c9a09bc223e1cc612f26dcdf1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b571-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/b571-dhc-sha1.csv new file mode 100644 index 0000000..80273a9 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b571-dhc-sha1.csv @@ -0,0 +1 @@ +624E4D4DC60F1064E378D34EF2E1FBB0ADE792E6 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b571-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/b571-keyCAVS.csv new file mode 100644 index 0000000..da4a6d6 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b571-keyCAVS.csv @@ -0,0 +1 @@ +03b63f5fa112ae6b5f113c765144fe4cbd6020e26d400c11609a3a634b9a325f416b0e3d3215734c68a1c2c8fad1d0bb9eb3939a41af22421f68781e7eb0664b9df5cea448deaa3b,008e6cc77bcddc816e84cfc1f626824fa24d3d5fd33d8093cbfe1fc4d881b63b494123bc759670edcb1887bb3b9d5a8b516bc503828163709d4dacb594d277a15a92c064e5770d1b \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/b571-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/b571-keyIUT.csv new file mode 100644 index 0000000..53d9e62 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/b571-keyIUT.csv @@ -0,0 +1 @@ +06af71fcec1a2904116fe14878663764c1ec74870e5d2d53919f0b635912db80dd5460d9e699458ff8494c5bfc74fba8d3b12f65f015e8def10de33f1800191f4cb502d21938b951,019584177b189c6641ffb678b6d7833d8d4bb25dee5018dda4e4c0d219048c01cd0da9eaffe346d53cf1a07b33b3dbdd4bc3acabe4832f9981eff2660991aac852147985eea3a51e,0344f22be87999b95b2287f67430ea8fe646c62fe38b7ce61f1f956597c27bddd9902e20d4436abf3bebd8243ec29a00481a8a2c19f550e99641b5f14aafbb5bda953a7559f8653a \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k163-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/k163-dhc-raw.csv new file mode 100644 index 0000000..cc8743f --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k163-dhc-raw.csv @@ -0,0 +1 @@ +04325bff38f1b0c83c27f554a6c972a80f14bc23bc \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k163-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/k163-dhc-sha1.csv new file mode 100644 index 0000000..7e8dc7a --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k163-dhc-sha1.csv @@ -0,0 +1 @@ +5E1384ED2D3D5EFC77E89581BBB467934ECB7B03 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k163-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/k163-keyCAVS.csv new file mode 100644 index 0000000..633b3d8 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k163-keyCAVS.csv @@ -0,0 +1 @@ +0000000574236f1428c432130946783a5b3aabb6c27ea5d6,00000007908c251b8da021cbac281f123f7af4fac5b3dbb8 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k163-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/k163-keyIUT.csv new file mode 100644 index 0000000..affd5c5 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k163-keyIUT.csv @@ -0,0 +1 @@ +000000071f8b2877d6027d9c1ade4244f2dea12692ef23d5,00000005c15ee776221c72b84b347ce383f38067b89c3e9a,6653b6077398fadc7bf5e60158170148c3dc4527 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k233-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/k233-dhc-raw.csv new file mode 100644 index 0000000..a18a3fb --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k233-dhc-raw.csv @@ -0,0 +1 @@ +00a822b141ca1f5ad32899e68c54d1fec3df8100df485ebf1c5868a9ac89 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k233-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/k233-dhc-sha1.csv new file mode 100644 index 0000000..3b4b97e --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k233-dhc-sha1.csv @@ -0,0 +1 @@ +70B67E77FB15C14CAAB64C04738E97EA3288C415 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k233-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/k233-keyCAVS.csv new file mode 100644 index 0000000..90ba87f --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k233-keyCAVS.csv @@ -0,0 +1 @@ +000001f40e34b3ed4a1b2d40c056fb75f2ad543c897cfd82f542cf746a0f202f,000000c130a1abe92bc4c977c800777996ccc50b90df991a2e81dd515c188599 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k233-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/k233-keyIUT.csv new file mode 100644 index 0000000..5d900a5 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k233-keyIUT.csv @@ -0,0 +1 @@ +000001a53e5c138b3d83905d563aa1db01274633c986b52f78225a92e33e7952,000000ecabd3e2e26729a965604e560ed4498a22b31c39642e1cf99b1dde3ec7,000000135a5b8c3ce047fbc5df26277d3bf83ac33ddadb5cf4a050ca82be48f0 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k283-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/k283-dhc-raw.csv new file mode 100644 index 0000000..f10922f --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k283-dhc-raw.csv @@ -0,0 +1 @@ +0745552817b5d729310b7dbebae687648714a9ae695dad20ca1ab6111c3d054670f21132 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k283-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/k283-dhc-sha1.csv new file mode 100644 index 0000000..6770696 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k283-dhc-sha1.csv @@ -0,0 +1 @@ +B2A69891DF7B9736507CE0126AB37213DB2CE68F \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k283-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/k283-keyCAVS.csv new file mode 100644 index 0000000..019ac52 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k283-keyCAVS.csv @@ -0,0 +1 @@ +03f075c24c35a9dc9952be6fd32b761dce63f4720a22408e3a14bbd097e012b5694c22a0,0675825b40202e95be7dab5a826147e04b8c51a09b0034577c1f31f8c16a70c8e1c85b89 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k283-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/k283-keyIUT.csv new file mode 100644 index 0000000..cca0cd3 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k283-keyIUT.csv @@ -0,0 +1 @@ +0611edc045dbe43ecc4ef6b324cd51f70fe3d7ddf877ec68b798909c3c4561756aa30e5f,00833b25511704af09b62d9f7cbac59814e75bbb9c735f55538491dbfa60c1e0115efe42,015fde49b802542a52c70b23a0b1784e5f8780b56853f9a5f8c3a5266e8727dce97d4a17 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k409-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/k409-dhc-raw.csv new file mode 100644 index 0000000..4034d18 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k409-dhc-raw.csv @@ -0,0 +1 @@ +0176bc5c4036ce5125493a58dd265f04d190f028366f7799f70aedf29ac67b5b37c37238593377a47944f5b639f43856dbd560ec \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k409-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/k409-dhc-sha1.csv new file mode 100644 index 0000000..3f988c9 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k409-dhc-sha1.csv @@ -0,0 +1 @@ +C25335980D8BF0BE8B039A1B525F6D002EEC48E9 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k409-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/k409-keyCAVS.csv new file mode 100644 index 0000000..c0bfde5 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k409-keyCAVS.csv @@ -0,0 +1 @@ +0177f736f6116320cafbb5b4dec202d40508182fe011189b81e1f3998f5408607a46bb150ac47bcaaafde47b8a7b72f478bc22d2,01df4ef4b37e0124e55b67f3586de24a88a6c5d98854007d4b0c4b4ccd68d51fafa7638bbe555d60b74def217c6a63c5b4068fb7 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k409-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/k409-keyIUT.csv new file mode 100644 index 0000000..050a771 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k409-keyIUT.csv @@ -0,0 +1 @@ +0068a3f8b12e02d10e2f52095526bc4048b8f6ac3a84531772870789938f1aeff813e05e509ea9587d2b7e4aa14344bac3ec46f0,00d1ceb40c7d5f3297e2955f0f3eb1422b3e6bbbfbf7eb518b9c17ae8d40feb84aaf36f5e5bd96075b2b4dbe538ac011962ac705,00084b711e3c60822e70fa6828b5abfb0e448888b35b0c8bb09f806616dc1ecf22dd86237d937c1bfde62b75ae655953fc6b2f7e \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k571-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/k571-dhc-raw.csv new file mode 100644 index 0000000..3b71041 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k571-dhc-raw.csv @@ -0,0 +1 @@ +003198a6b5d6cce847e24348a6a6ceff7a89ed3794d7acedc4e858c80ad04a74dbc02c7038e05ab26b2a299ec92ee0d2c7e66a81872a5157fbc5d4d37ad598d6ddee995ed28a2d74 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k571-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/k571-dhc-sha1.csv new file mode 100644 index 0000000..25265b3 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k571-dhc-sha1.csv @@ -0,0 +1 @@ +2D3100B4978FCCE89C26C4CEA4B72216EA942D2D \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k571-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/k571-keyCAVS.csv new file mode 100644 index 0000000..ba55ab2 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k571-keyCAVS.csv @@ -0,0 +1 @@ +03106a5c1d923a0990ea8c6008c36c366b53e5622b98464044741fbc7840284db8bbf602866c30ccbf5f9b7e59cc1d9bfcc5b970fa624da9b15f6cb336f5dda7e6b9924d5dce4543,005c5c7bbd5a789ac4c6283deb0d0d37c4852baa57d6bc2b0ac6337feb09704c44d1b385b70cc394fa235d83e6e7111787e57d0902c0cb132a190a6e62f398511c0c2c4cd50d4570 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/k571-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/k571-keyIUT.csv new file mode 100644 index 0000000..5607b40 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/k571-keyIUT.csv @@ -0,0 +1 @@ +03fbfbbcfba609157f68a23126d805f7c75efb19befb595e3a975e08ff46bd34c8b87b9645c0e86ea0ad915465d5c856c69bb9b722b0d17bf97ad95c4602dea17c6b512054cb22d8,071c16df71e1b71b4bd3d9938827d3959093b9db1ff86bed73944a42dcb67cc33102e28c1d0e9804a6450656f4bf33ad72ecf7bb83bd282cde4bc15d4e48064aa8ad2f02979f5f3f,0173cd1631e18ece01b73b3572ffaa7495c4bc81f4078ae50d69cb1e338acf13469117112921166ddf2d29f3a9f8e10c67e88c9a99203a834565be76ac59126436739a6afa029cc5 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p192-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/p192-dhc-raw.csv new file mode 100644 index 0000000..45533ec --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p192-dhc-raw.csv @@ -0,0 +1 @@ +803d8ab2e5b6e6fca715737c3a82f7ce3c783124f6d51cd0 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p192-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/p192-dhc-sha1.csv new file mode 100644 index 0000000..83bac75 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p192-dhc-sha1.csv @@ -0,0 +1 @@ +CB0FFAA3D3F9D5876765CF082EE0B893C8179D19 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p192-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/p192-keyCAVS.csv new file mode 100644 index 0000000..8a9bd57 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p192-keyCAVS.csv @@ -0,0 +1 @@ +42ea6dd9969dd2a61fea1aac7f8e98edcc896c6e55857cc0,dfbe5d7c61fac88b11811bde328e8a0d12bf01a9d204b523 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p192-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/p192-keyIUT.csv new file mode 100644 index 0000000..af9a670 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p192-keyIUT.csv @@ -0,0 +1 @@ +b15053401f57285637ec324c1cd2139e3a67de3739234b37,f269c158637482aad644cd692dd1d3ef2c8a7c49e389f7f6,f17d3fea367b74d340851ca4270dcb24c271f445bed9d527 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p224-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/p224-dhc-raw.csv new file mode 100644 index 0000000..f778111 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p224-dhc-raw.csv @@ -0,0 +1 @@ +7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p224-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/p224-dhc-sha1.csv new file mode 100644 index 0000000..446e658 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p224-dhc-sha1.csv @@ -0,0 +1 @@ +D022BCF6EAEF7789EF8D2AEAA9AB9D508944CE03 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p224-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/p224-keyCAVS.csv new file mode 100644 index 0000000..734aad1 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p224-keyCAVS.csv @@ -0,0 +1 @@ +af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280,882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p224-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/p224-keyIUT.csv new file mode 100644 index 0000000..2b84ffa --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p224-keyIUT.csv @@ -0,0 +1 @@ +8de2e26adf72c582d6568ef638c4fd59b18da171bdf501f1d929e048,4a68a1c2b0fb22930d120555c1ece50ea98dea8407f71be36efac0de,8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p256-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/p256-dhc-raw.csv new file mode 100644 index 0000000..230fe83 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p256-dhc-raw.csv @@ -0,0 +1 @@ +46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p256-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/p256-dhc-sha1.csv new file mode 100644 index 0000000..1fa92be --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p256-dhc-sha1.csv @@ -0,0 +1 @@ +381AE083BF9FF3BB49730A96D4E55AABAE1C42DA \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p256-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/p256-keyCAVS.csv new file mode 100644 index 0000000..6920fab --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p256-keyCAVS.csv @@ -0,0 +1 @@ +700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287,db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p256-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/p256-keyIUT.csv new file mode 100644 index 0000000..211f0d0 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p256-keyIUT.csv @@ -0,0 +1 @@ +ead218590119e8876b29146ff89ca61770c4edbbf97d38ce385ed281d8a6b230,28af61281fd35e2fa7002523acc85a429cb06ee6648325389f59edfce1405141,7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p384-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/p384-dhc-raw.csv new file mode 100644 index 0000000..0cd1bdc --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p384-dhc-raw.csv @@ -0,0 +1 @@ +5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p384-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/p384-dhc-sha1.csv new file mode 100644 index 0000000..5e878f9 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p384-dhc-sha1.csv @@ -0,0 +1 @@ +F84B679C77F7E42457AA306667AC2E6C2AC1D8D6 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p384-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/p384-keyCAVS.csv new file mode 100644 index 0000000..97ce5bc --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p384-keyCAVS.csv @@ -0,0 +1 @@ +a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066,ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p384-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/p384-keyIUT.csv new file mode 100644 index 0000000..3c2074a --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p384-keyIUT.csv @@ -0,0 +1 @@ +9803807f2f6d2fd966cdd0290bd410c0190352fbec7ff6247de1302df86f25d34fe4a97bef60cff548355c015dbb3e5f,ba26ca69ec2f5b5d9dad20cc9da711383a9dbe34ea3fa5a2af75b46502629ad54dd8b7d73a8abb06a3a3be47d650cc99,3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p521-dhc-raw.csv b/src/cz/crcs/ectester/data/test/nist/p521-dhc-raw.csv new file mode 100644 index 0000000..9c753ea --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p521-dhc-raw.csv @@ -0,0 +1 @@ +005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p521-dhc-sha1.csv b/src/cz/crcs/ectester/data/test/nist/p521-dhc-sha1.csv new file mode 100644 index 0000000..b565784 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p521-dhc-sha1.csv @@ -0,0 +1 @@ +1020FB37E0DADA201655AD3CC7410AED9CC034F3 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p521-keyCAVS.csv b/src/cz/crcs/ectester/data/test/nist/p521-keyCAVS.csv new file mode 100644 index 0000000..3fa895f --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p521-keyCAVS.csv @@ -0,0 +1 @@ +000000685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70d0f785601d37c09870ebf176666877a2046d,000001ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/test/nist/p521-keyIUT.csv b/src/cz/crcs/ectester/data/test/nist/p521-keyIUT.csv new file mode 100644 index 0000000..b575d06 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/nist/p521-keyIUT.csv @@ -0,0 +1 @@ +000000602f9d0cf9e526b29e22381c203c48a886c2b0673033366314f1ffbcba240ba42f4ef38a76174635f91e6b4ed34275eb01c8467d05ca80315bf1a7bbd945f550a5,000001b7c85f26f5d4b2d7355cf6b02117659943762b6d1db5ab4f1dbc44ce7b2946eb6c7de342962893fd387d1b73d7a8672d1f236961170b7eb3579953ee5cdc88cd2d,0000017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47 \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 80c3fb0..b8b0c04 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -409,7 +409,7 @@ public class ECTester { } optTestCase = cli.getOptionValue("test", "default").toLowerCase(); - String[] tests = new String[]{"default", "non-prime", "invalid", "smallpub", "test-vectors", "wrong"}; + String[] tests = new String[]{"default", "nonprime", "invalid", "smallpub", "test-vectors", "wrong"}; List testsList = Arrays.asList(tests); if (!testsList.contains(optTestCase)) { System.err.println("Unknown test case. Should be one of: " + Arrays.toString(tests)); @@ -669,8 +669,6 @@ public class ECTester { * Do ECDH both ways, export and verify that the result is correct. * */ - String category = optNamedCurve == null ? "secg" : optNamedCurve; - Map curves = dataStore.getObjects(EC_Curve.class, category); //TODO } else { @@ -683,7 +681,7 @@ public class ECTester { return; } - if (optTestCase.equals("wrong") || optTestCase.equals("non-prime")) { + if (optTestCase.equals("wrong") || optTestCase.equals("nonprime")) { /* Just do the default tests on the wrong and non-prime curves. * These should generally fail, the curves aren't safe. */ @@ -699,7 +697,17 @@ public class ECTester { * a small order public key succeeds the private key modulo the public key order * is revealed. */ - //TODO + Map keys = dataStore.getObjects(EC_Key.class, "smallpub"); + for (EC_Key key : keys.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if ((curve.getBits() == optBits || optAll)) { + commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField())); + commands.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL)); + commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, curve.getParams(), curve.flatten())); + commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH)); + commands.add(new Command.Cleanup(cardManager)); + } + } } else if (optTestCase.equals("invalid")) { /* Set original curves (secg/nist/brainpool). Generate local. * Try ECDH with invalid public keys of increasing (or decreasing) order. -- cgit v1.3.1 From 83c963ae78407e7a14ac71096f81254364d1e605 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 28 Mar 2017 16:04:13 +0200 Subject: Added test-vectors, and test-vector testing --- !uploader/ectester.cap | Bin 13811 -> 13811 bytes dist/ECTester.jar | Bin 283414 -> 276755 bytes src/cz/crcs/ectester/data/EC_Category.java | 15 +- src/cz/crcs/ectester/data/EC_Store.java | 95 +++++++++---- src/cz/crcs/ectester/data/schema.xsd | 43 +++++- src/cz/crcs/ectester/data/test/results.xml | 174 ++++++++++++++++++++++++ src/cz/crcs/ectester/reader/ECTester.java | 55 +++++++- src/cz/crcs/ectester/reader/ec/EC_Data.java | 8 ++ src/cz/crcs/ectester/reader/ec/EC_KAResult.java | 48 +++++++ 9 files changed, 394 insertions(+), 44 deletions(-) create mode 100644 src/cz/crcs/ectester/data/test/results.xml create mode 100644 src/cz/crcs/ectester/reader/ec/EC_KAResult.java (limited to 'src/cz/crcs/ectester/data/EC_Store.java') diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap index de865a9..6a16aa8 100644 Binary files a/!uploader/ectester.cap and b/!uploader/ectester.cap differ diff --git a/dist/ECTester.jar b/dist/ECTester.jar index 977185a..ffe19d1 100644 Binary files a/dist/ECTester.jar and b/dist/ECTester.jar differ diff --git a/src/cz/crcs/ectester/data/EC_Category.java b/src/cz/crcs/ectester/data/EC_Category.java index 859b942..57d9ca3 100644 --- a/src/cz/crcs/ectester/data/EC_Category.java +++ b/src/cz/crcs/ectester/data/EC_Category.java @@ -1,5 +1,6 @@ package cz.crcs.ectester.data; +import cz.crcs.ectester.reader.ec.EC_Data; import cz.crcs.ectester.reader.ec.EC_Params; import java.util.Collections; @@ -15,7 +16,7 @@ public class EC_Category { private String directory; private String desc; - private Map objects; + private Map objects; public EC_Category(String name, String directory) { @@ -28,7 +29,7 @@ public class EC_Category { this.desc = desc; } - public EC_Category(String name, String directory, String desc, Map objects) { + public EC_Category(String name, String directory, String desc, Map objects) { this(name, directory, desc); this.objects = objects; } @@ -45,13 +46,13 @@ public class EC_Category { return desc; } - public Map getObjects() { + public Map getObjects() { return Collections.unmodifiableMap(objects); } - public Map getObjects(Class cls) { + public Map getObjects(Class cls) { Map objs = new TreeMap<>(); - for (Map.Entry entry : objects.entrySet()) { + for (Map.Entry entry : objects.entrySet()) { if (cls.isInstance(entry.getValue())) { objs.put(entry.getKey(), cls.cast(entry.getValue())); } @@ -59,8 +60,8 @@ public class EC_Category { return Collections.unmodifiableMap(objs); } - public T getObject(Class cls, String id) { - EC_Params obj = objects.get(id); + public T getObject(Class cls, String id) { + EC_Data obj = objects.get(id); if (cls.isInstance(obj)) { return cls.cast(obj); } else { diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index aec635e..abf0a9b 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -1,11 +1,8 @@ package cz.crcs.ectester.data; -import cz.crcs.ectester.reader.ec.EC_Curve; -import cz.crcs.ectester.reader.ec.EC_Key; -import cz.crcs.ectester.reader.ec.EC_Keypair; -import cz.crcs.ectester.reader.ec.EC_Params; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.reader.ec.*; import javacard.security.KeyPair; -import org.omg.PortableInterceptor.SYSTEM_EXCEPTION; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; @@ -36,7 +33,7 @@ public class EC_Store { private Map categories; - public EC_Store() { + public EC_Store() throws IOException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { @@ -61,18 +58,24 @@ public class EC_Store { @Override public void fatalError(SAXParseException exception) throws SAXException { System.err.println("EC_Store | Fatal : " + exception); + throw new SAXException(exception); } }); parse(); - } catch (ParserConfigurationException | IOException | SAXException e) { + } catch (ParserConfigurationException | SAXException e) { e.printStackTrace(); } } private void parse() throws SAXException, ParserConfigurationException, IOException { - Document categoriesDoc = db.parse(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/categories.xml")); + InputStream categories = this.getClass().getResourceAsStream("/cz/crcs/ectester/data/categories.xml"); + if (categories == null) { + throw new IOException(); + } + Document categoriesDoc = db.parse(categories); + categories.close(); categoriesDoc.normalize(); NodeList catList = categoriesDoc.getElementsByTagName("category"); @@ -96,11 +99,11 @@ public class EC_Store { private EC_Category parseCategory(String name, String dir, String desc) throws ParserConfigurationException, IOException, SAXException { - Map objMap = new TreeMap<>(); + Map objMap = new TreeMap<>(); - InputStream curvesStream = this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/curves.xml"); - if (curvesStream != null) { - Document curvesDoc = db.parse(curvesStream); + InputStream curves = this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/curves.xml"); + if (curves != null) { + Document curvesDoc = db.parse(curves); curvesDoc.normalize(); NodeList curveList = curvesDoc.getElementsByTagName("curve"); @@ -138,11 +141,12 @@ public class EC_Store { throw new SAXException("?"); } } + curves.close(); } - InputStream keysStream = this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/keys.xml"); - if (keysStream != null) { - Document keysDoc = db.parse(keysStream); + InputStream keys = this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/keys.xml"); + if (keys != null) { + Document keysDoc = db.parse(keys); keysDoc.normalize(); NodeList directs = keysDoc.getDocumentElement().getChildNodes(); @@ -174,6 +178,51 @@ public class EC_Store { throw new SAXException("?"); } } + keys.close(); + } + + InputStream results = this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/results.xml"); + if (results != null) { + Document resultsDoc = db.parse(results); + resultsDoc.normalize(); + + NodeList directs = resultsDoc.getDocumentElement().getChildNodes(); + for (int i = 0; i < directs.getLength(); ++i) { + Node direct = directs.item(i); + if (direct instanceof Element) { + Element elem = (Element) direct; + + Node id = elem.getElementsByTagName("id").item(0); + Node ka = elem.getElementsByTagName("ka").item(0); + Node file = elem.getElementsByTagName("file").item(0); + Node curve = elem.getElementsByTagName("curve").item(0); + Node onekey = elem.getElementsByTagName("onekey").item(0); + Node otherkey = elem.getElementsByTagName("otherkey").item(0); + + NodeList descc = elem.getElementsByTagName("desc"); + String descs = null; + if (descc.getLength() != 0) { + descs = descc.item(0).getTextContent(); + } + + byte kab; + if (ka.getTextContent().equals("DH")) { + kab = EC_Consts.KA_ECDH; + } else { + kab = EC_Consts.KA_ECDHC; + } + + EC_KAResult kaResult = new EC_KAResult(kab, curve.getTextContent(), onekey.getTextContent(), otherkey.getTextContent(), descs); + if (!kaResult.readCSV(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/" + file.getTextContent()))) { + throw new IOException("Invalid csv data."); + } + + objMap.put(id.getTextContent(), kaResult); + } else { + throw new SAXException("?"); + } + } + results.close(); } return new EC_Category(name, dir, desc, objMap); @@ -199,7 +248,7 @@ public class EC_Store { } else { throw new SAXException("?"); } - if(!result.readCSV(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/" + file.getTextContent()))) { + if (!result.readCSV(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/" + file.getTextContent()))) { throw new IOException("Invalid CSV data."); } return result; @@ -213,7 +262,7 @@ public class EC_Store { return categories.get(category); } - public Map getObjects(String category) { + public Map getObjects(String category) { EC_Category cat = categories.get(category); if (cat != null) { return cat.getObjects(); @@ -221,7 +270,7 @@ public class EC_Store { return null; } - public Map getObjects(Class objClass, String category) { + public Map getObjects(Class objClass, String category) { EC_Category cat = categories.get(category); if (cat != null) { return cat.getObjects(objClass); @@ -229,7 +278,7 @@ public class EC_Store { return null; } - public T getObject(Class objClass, String category, String id) { + public T getObject(Class objClass, String category, String id) { EC_Category cat = categories.get(category); if (cat != null) { return cat.getObject(objClass, id); @@ -237,12 +286,12 @@ public class EC_Store { return null; } - public T getObject(Class objClass, String query) { - String[] parts = query.split("/"); - if (parts.length != 2) { + public T getObject(Class objClass, String query) { + int split = query.indexOf("/"); + if (split < 0) { return null; } - return getObject(objClass, parts[0], parts[1]); + return getObject(objClass, query.substring(0, split), query.substring(split + 1)); } } diff --git a/src/cz/crcs/ectester/data/schema.xsd b/src/cz/crcs/ectester/data/schema.xsd index a4dbe15..8f9427d 100644 --- a/src/cz/crcs/ectester/data/schema.xsd +++ b/src/cz/crcs/ectester/data/schema.xsd @@ -1,5 +1,5 @@ - @@ -12,13 +12,13 @@ - + - + @@ -32,12 +32,12 @@ - + - + @@ -52,14 +52,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + diff --git a/src/cz/crcs/ectester/data/test/results.xml b/src/cz/crcs/ectester/data/test/results.xml new file mode 100644 index 0000000..e382cd4 --- /dev/null +++ b/src/cz/crcs/ectester/data/test/results.xml @@ -0,0 +1,174 @@ + + + + secp160r1-dh + DH + secg/secp160r1-dh-sha1.csv + secg/secp160r1 + test/secp160r1-U + test/secp160r1-V + + + sect163k1-dh + DH + secg/sect163k1-dh-sha1.csv + secg/sect163k1 + test/sect163k1-U + test/sect163k1-V + + + + brainpoolP224r1-dh + DH + brainpool/brainpoolP224r1-dh-sha1.csv + brainpool/brainpoolP224r1 + test/brainpoolP224r1-A + test/brainpoolP224r1-B + + + brainpoolP256r1-dh + DH + brainpool/brainpoolP256r1-dh-sha1.csv + brainpool/brainpoolP256r1 + test/brainpoolP256r1-A + test/brainpoolP256r1-B + + + brainpoolP384r1-dh + DH + brainpool/brainpoolP384r1-dh-sha1.csv + brainpool/brainpoolP384r1 + test/brainpoolP384r1-A + test/brainpoolP384r1-B + + + brainpoolP512r1-dh + DH + brainpool/brainpoolP512r1-dh-sha1.csv + brainpool/brainpoolP512r1 + test/brainpoolP512r1-A + test/brainpoolP512r1-B + + + + b163-dhc + DHC + nist/b163-dhc-sha1.csv + nist/B-163 + test/b163-A + test/b163-B + + + b233-dhc + DHC + nist/b233-dhc-sha1.csv + nist/B-233 + test/b233-A + test/b233-B + + + b283-dhc + DHC + nist/b283-dhc-sha1.csv + nist/B-283 + test/b283-A + test/b283-B + + + b409-dhc + DHC + nist/b409-dhc-sha1.csv + nist/B-409 + test/b409-A + test/b409-B + + + b571-dhc + DHC + nist/b571-dhc-sha1.csv + nist/B-571 + test/b571-A + test/b571-B + + + k163-dhc + DHC + nist/k163-dhc-sha1.csv + nist/B-163 + test/k163-A + test/k163-B + + + k233-dhc + DHC + nist/k233-dhc-sha1.csv + nist/B-233 + test/k233-A + test/k233-B + + + k283-dhc + DHC + nist/k283-dhc-sha1.csv + nist/B-283 + test/k283-A + test/k283-B + + + k409-dhc + DHC + nist/k409-dhc-sha1.csv + nist/B-409 + test/k409-A + test/k409-B + + + k571-dhc + DHC + nist/k571-dhc-sha1.csv + nist/B-571 + test/k571-A + test/k571-B + + + p192-dhc + DHC + nist/p192-dhc-sha1.csv + nist/P-192 + test/p192-A + test/p192-B + + + p224-dhc + DHC + nist/p224-dhc-sha1.csv + nist/P-224 + test/p224-A + test/p224-B + + + p256-dhc + DHC + nist/p256-dhc-sha1.csv + nist/P-256 + test/p256-A + test/p256-B + + + p384-dhc + DHC + nist/p384-dhc-sha1.csv + nist/P-384 + test/p384-A + test/p384-B + + + p521-dhc + DHC + nist/p521-dhc-sha1.csv + nist/P-521 + test/p521-A + test/p521-B + + \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index b8b0c04..9926d3e 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -25,10 +25,7 @@ import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.data.EC_Category; import cz.crcs.ectester.data.EC_Store; -import cz.crcs.ectester.reader.ec.EC_Curve; -import cz.crcs.ectester.reader.ec.EC_Key; -import cz.crcs.ectester.reader.ec.EC_Keypair; -import cz.crcs.ectester.reader.ec.EC_Params; +import cz.crcs.ectester.reader.ec.*; import javacard.security.KeyPair; import org.apache.commons.cli.*; @@ -248,7 +245,7 @@ public class ECTester { actions.addOption(Option.builder("ln").longOpt("list-named").desc("Print the list of supported named curves and keys.").hasArg().argName("what").optionalArg(true).build()); actions.addOption(Option.builder("e").longOpt("export").desc("Export the defaut curve parameters of the card(if any).").build()); actions.addOption(Option.builder("g").longOpt("generate").desc("Generate [amount] of EC keys.").hasArg().argName("amount").optionalArg(true).build()); - actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support.").hasArg().argName("test_case").optionalArg(true).build()); + actions.addOption(Option.builder("t").longOpt("test").desc("Test ECC support. :\n- default:\n- invalid:\n- wrong:\n- nonprime:\n- smallpub:\n- test-vectors:").hasArg().argName("test_case").optionalArg(true).build()); actions.addOption(Option.builder("dh").longOpt("ecdh").desc("Do ECDH, [count] times.").hasArg().argName("count").optionalArg(true).build()); actions.addOption(Option.builder("dhc").longOpt("ecdhc").desc("Do ECDHC, [count] times.").hasArg().argName("count").optionalArg(true).build()); actions.addOption(Option.builder("dsa").longOpt("ecdsa").desc("Sign data with ECDSA, [count] times.").hasArg().argName("count").optionalArg(true).build()); @@ -511,6 +508,20 @@ public class ECTester { } System.out.println(); } + + Map results = cat.getObjects(EC_KAResult.class); + size = results.size(); + if (size > 0) { + System.out.print("\t\tResults: "); + for (Map.Entry result : results.entrySet()) { + System.out.print(result.getKey()); + size--; + if (size > 0) + System.out.print(", "); + } + System.out.println(); + } + System.out.println(); } } else if (categories.containsKey(optListNamed)) { @@ -669,7 +680,30 @@ public class ECTester { * Do ECDH both ways, export and verify that the result is correct. * */ - //TODO + Map results = dataStore.getObjects(EC_KAResult.class, "test"); + for (EC_KAResult result : results.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, result.getCurve()); + EC_Params onekey = dataStore.getObject(EC_Keypair.class, result.getOneKey()); + if (onekey == null) { + onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); + } + EC_Params otherkey = dataStore.getObject(EC_Keypair.class, result.getOtherKey()); + if (otherkey == null) { + otherkey = dataStore.getObject(EC_Key.Public.class, result.getOtherKey()); + } + if (onekey == null || otherkey == null) { + throw new IOException("Test vector keys not located"); + } + + commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField())); + commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten())); + commands.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH)); + commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S))); + commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W))); + commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA())); + //TODO add compare with result.getParam(0); + commands.add(new Command.Cleanup(cardManager)); + } } else { // These tests are dangerous, prompt before them. @@ -721,7 +755,14 @@ public class ECTester { List test = Command.sendAll(commands); systemOutLogger.println(Response.toString(test)); - // + for (Response response : test) { + if (response instanceof Response.ECDH) { + Response.ECDH ecdh = (Response.ECDH) response; + if (ecdh.hasSecret()) { + System.out.println(Util.bytesToHex(ecdh.getSecret(), false)); + } + } + } } /** diff --git a/src/cz/crcs/ectester/reader/ec/EC_Data.java b/src/cz/crcs/ectester/reader/ec/EC_Data.java index c1fb54c..2e1eb29 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Data.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Data.java @@ -31,6 +31,10 @@ public class EC_Data { this.data = data; } + public int getCount() { + return count; + } + public byte[][] getData() { return data; } @@ -39,6 +43,10 @@ public class EC_Data { return data != null; } + public byte[] getParam(int index) { + return data[index]; + } + public byte[] flatten() { ByteArrayOutputStream out = new ByteArrayOutputStream(); for (byte[] param : data) { diff --git a/src/cz/crcs/ectester/reader/ec/EC_KAResult.java b/src/cz/crcs/ectester/reader/ec/EC_KAResult.java new file mode 100644 index 0000000..e556f90 --- /dev/null +++ b/src/cz/crcs/ectester/reader/ec/EC_KAResult.java @@ -0,0 +1,48 @@ +package cz.crcs.ectester.reader.ec; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class EC_KAResult extends EC_Data { + + private byte ka; + private String curve; + private String oneKey; + private String otherKey; + + private String desc; + + public EC_KAResult(byte ka, String curve, String oneKey, String otherKey) { + super(1); + this.ka = ka; + this.curve = curve; + this.oneKey = oneKey; + this.otherKey = otherKey; + } + + public EC_KAResult(byte ka, String curve, String oneKey, String otherKey, String desc) { + this(ka, curve, oneKey, otherKey); + this.desc = desc; + } + + public byte getKA() { + return ka; + } + + public String getCurve() { + return curve; + } + + public String getOneKey() { + return oneKey; + } + + public String getOtherKey() { + return otherKey; + } + + public String getDesc() { + return desc; + } + +} -- cgit v1.3.1 From 914931cfea79c7947b180069b0e67cc208971869 Mon Sep 17 00:00:00 2001 From: J08nY Date: Sat, 15 Apr 2017 01:27:24 +0200 Subject: Add invalid curves test(partly) and some parameters (brainpool) for it - curves.xml, keys.xml and results.xml's entries can now instead of file path to point to csv file, contain the csv data inline. - Moved EC_Category to reader package from data - Fixed printing of named objects - Added ECDH/C test for KA_BOTH which does ECDH and ECDHC on the applet side, compares the results and reports success/failure etc. --- dist/ECTester.jar | Bin 155730 -> 295880 bytes src/cz/crcs/ectester/applet/ECKeyTester.java | 29 +++++ src/cz/crcs/ectester/applet/ECTesterApplet.java | 23 +++- src/cz/crcs/ectester/data/EC_Category.java | 72 ------------ src/cz/crcs/ectester/data/EC_Store.java | 54 +++++++-- src/cz/crcs/ectester/data/categories.xml | 5 + .../crcs/ectester/data/invalid/brainpool/keys.xml | 108 +++++++++++++++++ src/cz/crcs/ectester/data/invalid/curves.xml | 4 - src/cz/crcs/ectester/data/invalid/keys.xml | 14 +++ src/cz/crcs/ectester/data/invalid/nist/keys.xml | 6 + src/cz/crcs/ectester/data/invalid/secg/keys.xml | 6 + src/cz/crcs/ectester/data/schema.xsd | 12 +- src/cz/crcs/ectester/reader/ECTester.java | 115 ++++++------------ src/cz/crcs/ectester/reader/Response.java | 2 +- src/cz/crcs/ectester/reader/ec/EC_Category.java | 128 +++++++++++++++++++++ src/cz/crcs/ectester/reader/ec/EC_Curve.java | 2 +- src/cz/crcs/ectester/reader/ec/EC_KAResult.java | 2 +- src/cz/crcs/ectester/reader/ec/EC_Key.java | 4 +- src/cz/crcs/ectester/reader/ec/EC_Keypair.java | 2 +- 19 files changed, 409 insertions(+), 179 deletions(-) delete mode 100644 src/cz/crcs/ectester/data/EC_Category.java create mode 100644 src/cz/crcs/ectester/data/invalid/brainpool/keys.xml delete mode 100644 src/cz/crcs/ectester/data/invalid/curves.xml create mode 100644 src/cz/crcs/ectester/data/invalid/keys.xml create mode 100644 src/cz/crcs/ectester/data/invalid/nist/keys.xml create mode 100644 src/cz/crcs/ectester/data/invalid/secg/keys.xml create mode 100644 src/cz/crcs/ectester/reader/ec/EC_Category.java (limited to 'src/cz/crcs/ectester/data/EC_Store.java') diff --git a/dist/ECTester.jar b/dist/ECTester.jar index 5a8f64b..0126533 100644 Binary files a/dist/ECTester.jar and b/dist/ECTester.jar differ diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index e22094b..64f3024 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -3,6 +3,7 @@ package cz.crcs.ectester.applet; import javacard.framework.CardRuntimeException; import javacard.framework.ISO7816; +import javacard.framework.Util; import javacard.security.ECPrivateKey; import javacard.security.ECPublicKey; import javacard.security.KeyAgreement; @@ -104,6 +105,34 @@ public class ECKeyTester { return testKA(ecdhcKeyAgreement, privateKey, pubkeyBuffer, pubkeyOffset, length, outputBuffer, outputOffset); } + /** + * + * @param privateKey + * @param publicKey + * @param pubkeyBuffer + * @param pubkeyOffset + * @param outputBuffer + * @param outputOffset + * @param corruption + * @return + */ + public short testKA(ECPrivateKey privateKey, ECPublicKey publicKey, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { + short ecdhLength = testECDH(privateKey, publicKey, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); + if (sw != ISO7816.SW_NO_ERROR) { + return ecdhLength; + } + short ecdhcLength = testECDHC(privateKey, publicKey, pubkeyBuffer, pubkeyOffset, outputBuffer, (short) (outputOffset + ecdhLength), corruption); + short length = (short) (ecdhLength + ecdhcLength); + if (sw != ISO7816.SW_NO_ERROR) { + return length; + } + if (Util.arrayCompare(outputBuffer, outputOffset, outputBuffer, (short)(outputOffset + ecdhLength), ecdhLength) != 0) { + sw = ECTesterApplet.SW_DH_DHC_MISMATCH; + } + return length; + + } + /** * Uses {@code signKey} to sign data from {@code inputBuffer} at {@code inputOffset} with {@code inputOffset}. * Then checks for correct signature length. diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index f9fb5da..98f59c4 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -63,6 +63,7 @@ public class ECTesterApplet extends Applet { // STATUS WORDS public static final short SW_SIG_VERIFY_FAIL = (short) 0x0ee1; + public static final short SW_DH_DHC_MISMATCH = (short) 0x0ee2; private static final short ARRAY_LENGTH = (short) 0xff; @@ -556,7 +557,7 @@ public class ECTesterApplet extends Applet { secretLength = keyTester.testECDHC((ECPrivateKey) priv.getPrivate(), (ECPublicKey) pub.getPublic(), ramArray, (short) 0, ramArray2, (short) 0, corruption); break; case EC_Consts.KA_BOTH: - // TODO + secretLength = keyTester.testKA((ECPrivateKey) priv.getPrivate(), (ECPublicKey) pub.getPublic(), ramArray, (short) 0, ramArray2, (short) 0, corruption); break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); @@ -589,7 +590,7 @@ public class ECTesterApplet extends Applet { short dataLength = Util.getShort(buffer, inOffset); if (dataLength == 0) { //no data to sign //generate random - dataLength = 32; + dataLength = 64; randomData.generateData(ramArray, (short) 0, dataLength); } else { Util.arrayCopyNonAtomic(buffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength); @@ -636,9 +637,21 @@ public class ECTesterApplet extends Applet { */ private short support(byte[] buffer, short offset) { - Util.setShort(buffer, offset, ecdhSW); - Util.setShort(buffer, (short) (offset+2), ecdhcSW); - Util.setShort(buffer, (short) (offset+4), ecdsaSW); + if (keyTester.hasECDH()) { + Util.setShort(buffer, offset, ecdhSW); + } else { + Util.setShort(buffer, offset, ISO7816.SW_INS_NOT_SUPPORTED); + } + if (keyTester.hasECDHC()) { + Util.setShort(buffer, (short) (offset+2), ecdhcSW); + } else { + Util.setShort(buffer, (short) (offset+2), ISO7816.SW_INS_NOT_SUPPORTED); + } + if (keyTester.hasECDSA()) { + Util.setShort(buffer, (short) (offset+4), ecdsaSW); + } else { + Util.setShort(buffer, (short) (offset+4), ISO7816.SW_INS_NOT_SUPPORTED); + } return 6; } diff --git a/src/cz/crcs/ectester/data/EC_Category.java b/src/cz/crcs/ectester/data/EC_Category.java deleted file mode 100644 index 57d9ca3..0000000 --- a/src/cz/crcs/ectester/data/EC_Category.java +++ /dev/null @@ -1,72 +0,0 @@ -package cz.crcs.ectester.data; - -import cz.crcs.ectester.reader.ec.EC_Data; -import cz.crcs.ectester.reader.ec.EC_Params; - -import java.util.Collections; -import java.util.TreeMap; -import java.util.Map; - -/** - * @author Jan Jancar johny@neuromancer.sk - */ -public class EC_Category { - - private String name; - private String directory; - private String desc; - - private Map objects; - - - public EC_Category(String name, String directory) { - this.name = name; - this.directory = directory; - } - - public EC_Category(String name, String directory, String desc) { - this(name, directory); - this.desc = desc; - } - - public EC_Category(String name, String directory, String desc, Map objects) { - this(name, directory, desc); - this.objects = objects; - } - - public String getName() { - return name; - } - - public String getDirectory() { - return directory; - } - - public String getDesc() { - return desc; - } - - public Map getObjects() { - return Collections.unmodifiableMap(objects); - } - - public Map getObjects(Class cls) { - Map objs = new TreeMap<>(); - for (Map.Entry entry : objects.entrySet()) { - if (cls.isInstance(entry.getValue())) { - objs.put(entry.getKey(), cls.cast(entry.getValue())); - } - } - return Collections.unmodifiableMap(objs); - } - - public T getObject(Class cls, String id) { - EC_Data obj = objects.get(id); - if (cls.isInstance(obj)) { - return cls.cast(obj); - } else { - return null; - } - } - -} diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index abf0a9b..0571cd8 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -8,8 +8,10 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; +import org.xml.sax.ext.EntityResolver2; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; @@ -17,10 +19,10 @@ import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.TreeMap; @@ -61,6 +63,25 @@ public class EC_Store { throw new SAXException(exception); } }); + db.setEntityResolver(new EntityResolver2() { + @Override + public InputSource getExternalSubset(String name, String baseURI) throws SAXException, IOException { + return null; + } + + @Override + public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) throws SAXException, IOException { + InputSource is = new InputSource(); + is.setSystemId(systemId); + is.setByteStream(getClass().getClass().getResourceAsStream("/cz/crcs/ectester/data/" + systemId)); + return is; + } + + @Override + public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException { + return null; + } + }); parse(); } catch (ParserConfigurationException | SAXException e) { @@ -80,7 +101,7 @@ public class EC_Store { NodeList catList = categoriesDoc.getElementsByTagName("category"); - this.categories = new HashMap<>(catList.getLength()); + this.categories = new TreeMap<>(); for (int i = 0; i < catList.getLength(); ++i) { Node catNode = catList.item(i); if (catNode instanceof Element) { @@ -115,7 +136,6 @@ public class EC_Store { Node id = curveElem.getElementsByTagName("id").item(0); Node bits = curveElem.getElementsByTagName("bits").item(0); Node field = curveElem.getElementsByTagName("field").item(0); - Node file = curveElem.getElementsByTagName("file").item(0); NodeList descc = curveElem.getElementsByTagName("desc"); String descs = null; @@ -132,7 +152,9 @@ public class EC_Store { short bitsize = Short.parseShort(bits.getTextContent()); EC_Curve curve = new EC_Curve(bitsize, alg, descs); - if (!curve.readCSV(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/" + file.getTextContent()))) { + + InputStream csv = parseDataElement(dir, curveElem); + if (!curve.readCSV(csv)) { throw new IOException("Invalid csv data."); } @@ -194,7 +216,6 @@ public class EC_Store { Node id = elem.getElementsByTagName("id").item(0); Node ka = elem.getElementsByTagName("ka").item(0); - Node file = elem.getElementsByTagName("file").item(0); Node curve = elem.getElementsByTagName("curve").item(0); Node onekey = elem.getElementsByTagName("onekey").item(0); Node otherkey = elem.getElementsByTagName("otherkey").item(0); @@ -213,7 +234,9 @@ public class EC_Store { } EC_KAResult kaResult = new EC_KAResult(kab, curve.getTextContent(), onekey.getTextContent(), otherkey.getTextContent(), descs); - if (!kaResult.readCSV(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/" + file.getTextContent()))) { + + InputStream csv = parseDataElement(dir, elem); + if (!kaResult.readCSV(csv)) { throw new IOException("Invalid csv data."); } @@ -248,12 +271,29 @@ public class EC_Store { } else { throw new SAXException("?"); } - if (!result.readCSV(this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/" + file.getTextContent()))) { + + InputStream csv = parseDataElement(dir, elem); + if (!result.readCSV(csv)) { throw new IOException("Invalid CSV data."); } return result; } + private InputStream parseDataElement(String dir, Element elem) throws SAXException { + NodeList file = elem.getElementsByTagName("file"); + NodeList inline = elem.getElementsByTagName("inline"); + + InputStream csv; + if (file.getLength() == 1) { + csv = this.getClass().getResourceAsStream("/cz/crcs/ectester/data/" + dir + "/" + file.item(0).getTextContent()); + } else if (inline.getLength() == 1) { + csv = new ByteArrayInputStream(inline.item(0).getTextContent().getBytes()); + } else { + throw new SAXException("?"); + } + return csv; + } + public Map getCategories() { return Collections.unmodifiableMap(categories); } diff --git a/src/cz/crcs/ectester/data/categories.xml b/src/cz/crcs/ectester/data/categories.xml index 100d962..29dcba0 100644 --- a/src/cz/crcs/ectester/data/categories.xml +++ b/src/cz/crcs/ectester/data/categories.xml @@ -31,6 +31,11 @@ wrong Wrong field curves. These should definitely give an error when used. Since the "prime" used for the field are not prime, and the field polynomials are also not irreducible. Simply put these parameters don't specify a valid elliptic curve. + + invalid + invalid + + test test diff --git a/src/cz/crcs/ectester/data/invalid/brainpool/keys.xml b/src/cz/crcs/ectester/data/invalid/brainpool/keys.xml new file mode 100644 index 0000000..985fab6 --- /dev/null +++ b/src/cz/crcs/ectester/data/invalid/brainpool/keys.xml @@ -0,0 +1,108 @@ + + + 160r1-1 + 0xc4d7ddb433381eeb0c62b502b4059e616caf6fcf,0x0 + brainpool/brainpoolP160r1 + invalid order = 2 + + + +160r1-2 +0x55303e73394b0da59a85f48ad0ba78deee2df5d8,0x2874a5d9c08777c1151c87cd6d0577842ea68e13 +brainpool/brainpoolP160r1 +invalid order = 3 + + + +160r1-3 +0x4381828db3ae0c10a51074929b60700f87b0337b,0x2a2a76a4af0a96106ba6fe9d2496f1908edd2a23 +brainpool/brainpoolP160r1 +invalid order = 5 + + + +160r1-4 +0x68f115185e91815d9259714e7a7154300b8db314,0x3784f206684eb6c8c252ea4fe5453ff37b93eaf9 +brainpool/brainpoolP160r1 +invalid order = 7 + + + +160r1-5 +0xcc521e5a0366ee48cc37e757b994afee2452015e,0x93e0e6c648b0f0b2e354425025041345beb35b3c +brainpool/brainpoolP160r1 +invalid order = 11 + + + +160r1-6 +0x2b4d92bf08d99b87767e40f46ba4ad3dc21e2302,0x72f3e483e7b2c562fba12bad2402a411af02a15c +brainpool/brainpoolP160r1 +invalid order = 13 + + + +160r1-7 +0x1397bfed0edd4c38019af46c6864d106bc1c7241,0xa78a13e065701c31796231ceeb2200b4459c92ad +brainpool/brainpoolP160r1 +invalid order = 17 + + + +160r1-8 +0x448604062905058037d0776f0111e25d44b1abe3,0x1337a58bb32dd2c34355b47dedce2014b53cb832 +brainpool/brainpoolP160r1 +invalid order = 19 + + + +160r1-9 +0x64d734b3bf25c6546b963b43ece33fdc9347e66b,0xc311a5ed6b51380cada8c5c6658b633c4e40169e +brainpool/brainpoolP160r1 +invalid order = 23 + + + +160r1-10 +0x77c06cb540d349ebe61218241deb813c591f0509,0xd7eb002458fa0c38ae3528c9b3ec5e1117a84ff8 +brainpool/brainpoolP160r1 +invalid order = 29 + + + +160r1-11 +0xbefde0dd07cb3ef5d189b15fd129ec564d194cf3,0x55106a2379e3eef9010f4d11239ea0d83039cb66 +brainpool/brainpoolP160r1 +invalid order = 31 + + + +160r1-12 +0xe54d642cd1c68d018db437fb624b3595a5a9588c,0xae6165d75eec8e22072a0d7b800eae804e9b4136 +brainpool/brainpoolP160r1 +invalid order = 37 + + + +160r1-13 +0x60d871f4fde332d00e183381d0e3cbbc586dcb80,0x10a9f5e2a238ab38a743f52645dbbff2b250a34a +brainpool/brainpoolP160r1 +invalid order = 41 + + + +160r1-14 +0x7e2901c9f5610e4230aa7a53e8553426073458e4,0x3ac1810d4beb3244d62343ea40a23324b67b442 +brainpool/brainpoolP160r1 +invalid order = 43 + + + +160r1-15 +0x6b4d7bd164a2fb9fbb835a5ad5ee70adecf0cb37,0x22096241d3ec1f1ec072e10a04a731380fdedab5 +brainpool/brainpoolP160r1 +invalid order = 47 + + + + diff --git a/src/cz/crcs/ectester/data/invalid/curves.xml b/src/cz/crcs/ectester/data/invalid/curves.xml deleted file mode 100644 index e87269f..0000000 --- a/src/cz/crcs/ectester/data/invalid/curves.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/invalid/keys.xml b/src/cz/crcs/ectester/data/invalid/keys.xml new file mode 100644 index 0000000..9048518 --- /dev/null +++ b/src/cz/crcs/ectester/data/invalid/keys.xml @@ -0,0 +1,14 @@ + + + + + ]> + + &brainpool; + &nist; + &secg; + \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/invalid/nist/keys.xml b/src/cz/crcs/ectester/data/invalid/nist/keys.xml new file mode 100644 index 0000000..5427845 --- /dev/null +++ b/src/cz/crcs/ectester/data/invalid/nist/keys.xml @@ -0,0 +1,6 @@ + + 160r1-1 + 0xc4d7ddb433381eeb0c62b502b4059e616caf6fcf,0x0 + brainpool/brainpoolP160r1 + order = 2 + diff --git a/src/cz/crcs/ectester/data/invalid/secg/keys.xml b/src/cz/crcs/ectester/data/invalid/secg/keys.xml new file mode 100644 index 0000000..5427845 --- /dev/null +++ b/src/cz/crcs/ectester/data/invalid/secg/keys.xml @@ -0,0 +1,6 @@ + + 160r1-1 + 0xc4d7ddb433381eeb0c62b502b4059e616caf6fcf,0x0 + brainpool/brainpoolP160r1 + order = 2 + diff --git a/src/cz/crcs/ectester/data/schema.xsd b/src/cz/crcs/ectester/data/schema.xsd index 8f9427d..33b9acd 100644 --- a/src/cz/crcs/ectester/data/schema.xsd +++ b/src/cz/crcs/ectester/data/schema.xsd @@ -1,5 +1,5 @@ - @@ -11,12 +11,16 @@ + + + + - + @@ -34,7 +38,7 @@ - + @@ -65,7 +69,7 @@ - + diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index cb3d298..6965d14 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -23,7 +23,6 @@ package cz.crcs.ectester.reader; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; -import cz.crcs.ectester.data.EC_Category; import cz.crcs.ectester.data.EC_Store; import cz.crcs.ectester.reader.ec.*; import javacard.security.KeyPair; @@ -468,70 +467,18 @@ public class ECTester { if (optListNamed == null) { // print all categories, briefly for (EC_Category cat : categories.values()) { - System.out.println("\t- " + cat.getName() + ": " + (cat.getDesc() == null ? "" : cat.getDesc())); - - Map curves = cat.getObjects(EC_Curve.class); - int size = curves.size(); - if (size > 0) { - System.out.print("\t\tCurves: "); - for (Map.Entry curve : curves.entrySet()) { - System.out.print(curve.getKey()); - size--; - if (size > 0) - System.out.print(", "); - } - System.out.println(); - } - - Map keys = cat.getObjects(EC_Key.class); - size = keys.size(); - if (size > 0) { - System.out.print("\t\tKeys: "); - for (Map.Entry key : keys.entrySet()) { - System.out.print(key.getKey()); - size--; - if (size > 0) - System.out.print(", "); - } - System.out.println(); - } - - Map keypairs = cat.getObjects(EC_Keypair.class); - size = keypairs.size(); - if (size > 0) { - System.out.print("\t\tKeypairs: "); - for (Map.Entry key : keypairs.entrySet()) { - System.out.print(key.getKey()); - size--; - if (size > 0) - System.out.print(", "); - } - System.out.println(); - } - - Map results = cat.getObjects(EC_KAResult.class); - size = results.size(); - if (size > 0) { - System.out.print("\t\tResults: "); - for (Map.Entry result : results.entrySet()) { - System.out.print(result.getKey()); - size--; - if (size > 0) - System.out.print(", "); - } - System.out.println(); - } - - System.out.println(); + System.out.println(cat); } } else if (categories.containsKey(optListNamed)) { // print given category - //TODO + System.out.println(categories.get(optListNamed)); } else { // print given object EC_Data object = dataStore.getObject(EC_Data.class, optListNamed); if (object != null) { System.out.println(object); + } else { + System.err.println("Named object " + optListNamed + " not found!"); } } } @@ -562,9 +509,9 @@ public class ECTester { // Cofactor generally isn't set on the default curve parameters on cards, // since its not necessary for ECDH, only ECDHC which not many cards implement // TODO: check if its assumend to be == 1? - short domain_all = optPrimeField ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; - short domain = (short) (domain_all ^ EC_Consts.PARAMETER_K); - Response.Export export = new Command.Export(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, domain_all).send(); + short domainAll = optPrimeField ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; + short domain = (short) (domainAll ^ EC_Consts.PARAMETER_K); + Response.Export export = new Command.Export(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, domainAll).send(); if (!export.successful()) { export = new Command.Export(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, domain).send(); } @@ -722,12 +669,13 @@ public class ECTester { // These tests are dangerous, prompt before them. System.out.println("The test you selected (" + optTestSuite + ") is potentially dangerous."); System.out.println("Some of these tests have caused temporary DoS of some cards."); - System.out.print("Do you want to proceed? (y/n):"); + System.out.print("Do you want to proceed? (y/n): "); Scanner in = new Scanner(System.in); String confirmation = in.nextLine(); if (!Arrays.asList("yes", "y", "Y").contains(confirmation)) { return; } + in.close(); if (optTestSuite.equals("wrong")) { /* Just do the default tests on the wrong curves. @@ -750,20 +698,35 @@ public class ECTester { EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); if ((curve.getBits() == optBits || optAll)) { commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField())); - commands.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL)); commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten())); - commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten())); + commands.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL)); + commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten())); commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH)); commands.add(new Command.Cleanup(cardManager)); } } } else if (optTestSuite.equals("invalid")) { - /* Set original curves (secg/nist/brainpool). Generate local. - * Try ECDH with invalid public keys of increasing (or decreasing) order. - * - */ - //TODO - System.err.println("Currently not yet implemented."); + /* Set original curves (secg/nist/brainpool). Generate local. + * Try ECDH with invalid public keys of increasing (or decreasing) order. + */ + Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); + for (EC_Key.Public key : pubkeys.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if (optNamedCurve != null && !(key.getCurve().startsWith(optNamedCurve) || key.getCurve().equals(optNamedCurve))) { + continue; + } + if (curve.getBits() != optBits && !optAll) { + continue; + } + commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField())); + commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten())); + commands.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL)); + commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten())); + commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_BOTH)); + //commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDHC)); + commands.add(new Command.Cleanup(cardManager)); + + } } } @@ -771,14 +734,6 @@ public class ECTester { List test = Command.sendAll(commands); systemOutLogger.println(Response.toString(test, optTestSuite)); - for (Response response : test) { - if (response instanceof Response.ECDH) { - Response.ECDH ecdh = (Response.ECDH) response; - if (ecdh.hasSecret()) { - System.out.println(Util.bytesToHex(ecdh.getSecret(), false)); - } - } - } } /** @@ -1039,9 +994,8 @@ public class ECTester { } /** - * * @return - * @throws IOException if an IO error occurs when writing to key file. + * @throws IOException if an IO error occurs when writing to key file. */ private List testCurve() throws IOException { List commands = new LinkedList<>(); @@ -1056,11 +1010,10 @@ public class ECTester { } /** - * * @param category * @param field * @return - * @throws IOException if an IO error occurs when writing to key file. + * @throws IOException if an IO error occurs when writing to key file. */ private List testCurves(String category, byte field) throws IOException { List commands = new LinkedList<>(); diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java index c3f2fe4..ee27260 100644 --- a/src/cz/crcs/ectester/reader/Response.java +++ b/src/cz/crcs/ectester/reader/Response.java @@ -137,7 +137,7 @@ public abstract class Response { if (prefix != null) out.append(prefix); - out.append(String.format("%-58s:%4d ms : %s", message, r.time / 1000000, suffix)); + out.append(String.format("%-62s:%4d ms : %s", message, r.time / 1000000, suffix)); if (i < responses.size() - 1) { out.append("\n"); } diff --git a/src/cz/crcs/ectester/reader/ec/EC_Category.java b/src/cz/crcs/ectester/reader/ec/EC_Category.java new file mode 100644 index 0000000..a0c8755 --- /dev/null +++ b/src/cz/crcs/ectester/reader/ec/EC_Category.java @@ -0,0 +1,128 @@ +package cz.crcs.ectester.reader.ec; + +import java.util.Collections; +import java.util.Map; +import java.util.TreeMap; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class EC_Category { + + private String name; + private String directory; + private String desc; + + private Map objects; + + + public EC_Category(String name, String directory) { + this.name = name; + this.directory = directory; + } + + public EC_Category(String name, String directory, String desc) { + this(name, directory); + this.desc = desc; + } + + public EC_Category(String name, String directory, String desc, Map objects) { + this(name, directory, desc); + this.objects = objects; + } + + public String getName() { + return name; + } + + public String getDirectory() { + return directory; + } + + public String getDesc() { + return desc; + } + + public Map getObjects() { + return Collections.unmodifiableMap(objects); + } + + public Map getObjects(Class cls) { + Map objs = new TreeMap<>(); + for (Map.Entry entry : objects.entrySet()) { + if (cls.isInstance(entry.getValue())) { + objs.put(entry.getKey(), cls.cast(entry.getValue())); + } + } + return Collections.unmodifiableMap(objs); + } + + public T getObject(Class cls, String id) { + EC_Data obj = objects.get(id); + if (cls.isInstance(obj)) { + return cls.cast(obj); + } else { + return null; + } + } + + @Override + public String toString() { + StringBuilder out = new StringBuilder(); + out.append("\t- ").append(name).append((desc == null || desc.equals("")) ? "" : ": " + desc); + out.append(System.lineSeparator()); + + Map curves = getObjects(EC_Curve.class); + int size = curves.size(); + if (size > 0) { + out.append("\t\tCurves: "); + for (Map.Entry curve : curves.entrySet()) { + out.append(curve.getKey()); + size--; + if (size > 0) + out.append(", "); + } + out.append(System.lineSeparator()); + } + + Map keys = getObjects(EC_Key.class); + size = keys.size(); + if (size > 0) { + out.append("\t\tKeys: "); + for (Map.Entry key : keys.entrySet()) { + out.append(key.getKey()); + size--; + if (size > 0) + out.append(", "); + } + out.append(System.lineSeparator()); + } + + Map keypairs = getObjects(EC_Keypair.class); + size = keypairs.size(); + if (size > 0) { + out.append("\t\tKeypairs: "); + for (Map.Entry key : keypairs.entrySet()) { + out.append(key.getKey()); + size--; + if (size > 0) + out.append(", "); + } + out.append(System.lineSeparator()); + } + + Map results = getObjects(EC_KAResult.class); + size = results.size(); + if (size > 0) { + out.append("\t\tResults: "); + for (Map.Entry result : results.entrySet()) { + out.append(result.getKey()); + size--; + if (size > 0) + out.append(", "); + } + out.append(System.lineSeparator()); + } + return out.toString(); + } +} diff --git a/src/cz/crcs/ectester/reader/ec/EC_Curve.java b/src/cz/crcs/ectester/reader/ec/EC_Curve.java index 953884f..9b783ec 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Curve.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Curve.java @@ -43,6 +43,6 @@ public class EC_Curve extends EC_Params { @Override public String toString() { - return "Elliptic curve (" + String.valueOf(bits) + "b): " + desc; + return "Elliptic curve (" + String.valueOf(bits) + "b)" + (desc == null ? "" : ": " + desc); } } diff --git a/src/cz/crcs/ectester/reader/ec/EC_KAResult.java b/src/cz/crcs/ectester/reader/ec/EC_KAResult.java index f1be49a..1385f12 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_KAResult.java +++ b/src/cz/crcs/ectester/reader/ec/EC_KAResult.java @@ -50,7 +50,7 @@ public class EC_KAResult extends EC_Data { @Override public String toString() { String agreement = ka == EC_Consts.KA_ECDH ? "ECDH" : "ECDHC"; - return agreement + " over " + curve + ", " + oneKey + " + " + otherKey + ": " + desc; + return agreement + " result over " + curve + ", " + oneKey + " + " + otherKey + (desc == null ? "" : ": " + desc); } } diff --git a/src/cz/crcs/ectester/reader/ec/EC_Key.java b/src/cz/crcs/ectester/reader/ec/EC_Key.java index 983ffa8..ad846b8 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Key.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Key.java @@ -40,7 +40,7 @@ public class EC_Key extends EC_Params { @Override public String toString() { - return "EC Public key, over " + getCurve() + ": " + getDesc(); + return "EC Public key, over " + getCurve() + (getDesc() == null ? "" : ": " + getDesc()); } } @@ -56,7 +56,7 @@ public class EC_Key extends EC_Params { @Override public String toString() { - return "EC Private key, over " + getCurve() + ": " + getDesc(); + return "EC Private key, over " + getCurve() + (getDesc() == null ? "" : ": " + getDesc()); } } } diff --git a/src/cz/crcs/ectester/reader/ec/EC_Keypair.java b/src/cz/crcs/ectester/reader/ec/EC_Keypair.java index af4038a..bf87e9e 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Keypair.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Keypair.java @@ -30,6 +30,6 @@ public class EC_Keypair extends EC_Params { @Override public String toString() { - return "EC Keypair, over " + curve + ": " + desc; + return "EC Keypair, over " + curve + (desc == null ? "" : ": " + desc); } } -- cgit v1.3.1 From a7eef06134bef0861e43261640d61153ebb2a6e5 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 19 Apr 2017 01:10:17 +0200 Subject: Refactor testing, add Config class, make EC_Data read bytes - The ECTester.Config class now stores and reads all CLI options - Testing with the -t / --test option was partially refactored into: - Test: Encapsulates one Command and Response pair with expected result, a real result and a callback to dynamically assign result - TestSuite: Encapsulates a bunch of tests, represents a whole category of tests either that can be run on any curve or only on some. --- !uploader/ectester.cap | Bin 14053 -> 14353 bytes dist/ECTester.jar | Bin 295880 -> 322457 bytes src/cz/crcs/ectester/applet/ECKeyGenerator.java | 32 +- src/cz/crcs/ectester/applet/ECKeyTester.java | 49 +- src/cz/crcs/ectester/applet/ECTesterApplet.java | 7 +- src/cz/crcs/ectester/applet/ECUtil.java | 17 + src/cz/crcs/ectester/data/EC_Store.java | 8 +- src/cz/crcs/ectester/reader/ECTester.java | 666 +++++++++++------------- src/cz/crcs/ectester/reader/Response.java | 106 ++-- src/cz/crcs/ectester/reader/Test.java | 81 +++ src/cz/crcs/ectester/reader/TestSuite.java | 167 ++++++ src/cz/crcs/ectester/reader/Util.java | 82 ++- src/cz/crcs/ectester/reader/ec/EC_Curve.java | 10 +- src/cz/crcs/ectester/reader/ec/EC_Data.java | 40 +- src/cz/crcs/ectester/reader/ec/EC_KAResult.java | 13 +- src/cz/crcs/ectester/reader/ec/EC_Key.java | 10 + src/cz/crcs/ectester/reader/ec/EC_Keypair.java | 1 - src/cz/crcs/ectester/reader/ec/EC_Params.java | 28 +- 18 files changed, 854 insertions(+), 463 deletions(-) create mode 100644 src/cz/crcs/ectester/applet/ECUtil.java create mode 100644 src/cz/crcs/ectester/reader/Test.java create mode 100644 src/cz/crcs/ectester/reader/TestSuite.java (limited to 'src/cz/crcs/ectester/data/EC_Store.java') diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap index 96d0c82..1e7235d 100644 Binary files a/!uploader/ectester.cap and b/!uploader/ectester.cap differ diff --git a/dist/ECTester.jar b/dist/ECTester.jar index 0126533..58f44b9 100644 Binary files a/dist/ECTester.jar and b/dist/ECTester.jar differ diff --git a/src/cz/crcs/ectester/applet/ECKeyGenerator.java b/src/cz/crcs/ectester/applet/ECKeyGenerator.java index b412370..a36bd0c 100644 --- a/src/cz/crcs/ectester/applet/ECKeyGenerator.java +++ b/src/cz/crcs/ectester/applet/ECKeyGenerator.java @@ -39,8 +39,8 @@ public class ECKeyGenerator { } public short clearPair(KeyPair keypair, byte key) { - sw = ISO7816.SW_NO_ERROR; try { + sw = ECUtil.nullCheck(keypair); if ((key & EC_Consts.KEY_PUBLIC) != 0) keypair.getPublic().clearKey(); if ((key & EC_Consts.KEY_PRIVATE) != 0) keypair.getPrivate().clearKey(); } catch (CardRuntimeException ce) { @@ -54,8 +54,8 @@ public class ECKeyGenerator { * @return */ public short generatePair(KeyPair keypair) { - sw = ISO7816.SW_NO_ERROR; try { + sw = ECUtil.nullCheck(keypair); keypair.genKeyPair(); } catch (CardRuntimeException ce) { sw = ce.getReason(); @@ -155,11 +155,12 @@ public class ECKeyGenerator { * @return */ public short setParameter(KeyPair keypair, byte key, short param, byte[] data, short offset, short length) { - sw = ISO7816.SW_NO_ERROR; - ECPublicKey ecPublicKey = (ECPublicKey) keypair.getPublic(); - ECPrivateKey ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); - try { + sw = ECUtil.nullCheck(keypair); + + ECPublicKey ecPublicKey = (ECPublicKey) keypair.getPublic(); + ECPrivateKey ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); + switch (param) { case EC_Consts.PARAMETER_FP: if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldFP(data, offset, length); @@ -174,8 +175,11 @@ public class ECKeyGenerator { short i1 = Util.makeShort(data[(short) (offset + 2)], data[(short) (offset + 3)]); short i2 = Util.makeShort(data[(short) (offset + 4)], data[(short) (offset + 5)]); short i3 = Util.makeShort(data[(short) (offset + 6)], data[(short) (offset + 7)]); - if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i1, i2, i3); - if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i1, i2, i3); +// if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i1, i2, i3); +// if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i1, i2, i3); + // TODO fix this + if ((key & EC_Consts.KEY_PUBLIC) != 0) ecPublicKey.setFieldF2M(i3, i2, i1); + if ((key & EC_Consts.KEY_PRIVATE) != 0) ecPrivateKey.setFieldF2M(i3, i2, i1); } else { sw = ISO7816.SW_UNKNOWN; } @@ -275,12 +279,12 @@ public class ECKeyGenerator { * @return length of data written */ public short exportParameter(KeyPair keypair, byte key, short param, byte[] outputBuffer, short outputOffset) { - sw = ISO7816.SW_NO_ERROR; - ECPublicKey ecPublicKey = (ECPublicKey) keypair.getPublic(); - ECPrivateKey ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); - short length = 0; try { + sw = ECUtil.nullCheck(keypair); + ECPublicKey ecPublicKey = (ECPublicKey) keypair.getPublic(); + ECPrivateKey ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); + switch (param) { case EC_Consts.PARAMETER_FP: if ((key & EC_Consts.KEY_PUBLIC) != 0) length = ecPublicKey.getField(outputBuffer, outputOffset); @@ -385,8 +389,10 @@ public class ECKeyGenerator { * @return sw */ public short copyCurve(KeyPair from, KeyPair to, short params, byte[] buffer, short offset) { - sw = ISO7816.SW_NO_ERROR; try { + sw = ECUtil.nullCheck(from); + sw = ECUtil.nullCheck(to); + short param = EC_Consts.PARAMETER_FP; while (param <= EC_Consts.PARAMETER_K) { short masked = (short) (param & params); diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index 64f3024..c4b58e0 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -4,10 +4,7 @@ package cz.crcs.ectester.applet; import javacard.framework.CardRuntimeException; import javacard.framework.ISO7816; import javacard.framework.Util; -import javacard.security.ECPrivateKey; -import javacard.security.ECPublicKey; -import javacard.security.KeyAgreement; -import javacard.security.Signature; +import javacard.security.*; /** * Class capable of testing ECDH/C and ECDSA. @@ -53,11 +50,15 @@ public class ECKeyTester { return sw; } - private short testKA(KeyAgreement ka, ECPrivateKey privateKey, byte[] pubkeyBuffer, short pubkeyOffset, short pubkeyLength, byte[] outputBuffer, short outputOffset) { - sw = ISO7816.SW_NO_ERROR; + private short testKA(KeyAgreement ka, KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { short length = 0; try { - ka.init(privateKey); + sw = ECUtil.nullCheck(privatePair); + sw = ECUtil.nullCheck(publicPair); + + ka.init(privatePair.getPrivate()); + short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset); + pubkeyLength = EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, pubkeyLength); length = ka.generateSecret(pubkeyBuffer, pubkeyOffset, pubkeyLength, outputBuffer, outputOffset); } catch (CardRuntimeException ce) { sw = ce.getReason(); @@ -66,12 +67,12 @@ public class ECKeyTester { } /** - * Tests ECDH secret generation with given {@code privateKey} and {@code publicKey}. + * Tests ECDH secret generation with keys from given {@code privatePair} and {@code publicPair}. * Uses {@code pubkeyBuffer} at {@code pubkeyOffset} for computations. * Output should equal with ECDHC output. * - * @param privateKey - * @param publicKey + * @param privatePair + * @param publicPair * @param pubkeyBuffer * @param pubkeyOffset * @param outputBuffer @@ -79,19 +80,17 @@ public class ECKeyTester { * @param corruption * @return derived secret length **/ - public short testECDH(ECPrivateKey privateKey, ECPublicKey publicKey, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { - short length = publicKey.getW(pubkeyBuffer, pubkeyOffset); - length = EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, length); - return testKA(ecdhKeyAgreement, privateKey, pubkeyBuffer, pubkeyOffset, length, outputBuffer, outputOffset); + public short testECDH(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { + return testKA(ecdhKeyAgreement, privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); } /** - * Tests ECDHC secret generation with given {@code privateKey} and {@code publicKey}. + * Tests ECDHC secret generation with keys from given {@code privatePair} and {@code publicPair}. * Uses {@code pubkeyBuffer} at {@code pubkeyOffset} for computations. * Output should equal to ECDH output. * - * @param privateKey - * @param publicKey + * @param privatePair + * @param publicPair * @param pubkeyBuffer * @param pubkeyOffset * @param outputBuffer @@ -99,16 +98,14 @@ public class ECKeyTester { * @param corruption * @return derived secret length */ - public short testECDHC(ECPrivateKey privateKey, ECPublicKey publicKey, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { - short length = publicKey.getW(pubkeyBuffer, pubkeyOffset); - length = EC_Consts.corruptParameter(corruption, pubkeyBuffer, pubkeyOffset, length); - return testKA(ecdhcKeyAgreement, privateKey, pubkeyBuffer, pubkeyOffset, length, outputBuffer, outputOffset); + public short testECDHC(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { + return testKA(ecdhcKeyAgreement, privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); } /** * - * @param privateKey - * @param publicKey + * @param privatePair + * @param publicPair * @param pubkeyBuffer * @param pubkeyOffset * @param outputBuffer @@ -116,12 +113,12 @@ public class ECKeyTester { * @param corruption * @return */ - public short testKA(ECPrivateKey privateKey, ECPublicKey publicKey, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { - short ecdhLength = testECDH(privateKey, publicKey, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); + public short testECDH_ECDHC(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { + short ecdhLength = testECDH(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); if (sw != ISO7816.SW_NO_ERROR) { return ecdhLength; } - short ecdhcLength = testECDHC(privateKey, publicKey, pubkeyBuffer, pubkeyOffset, outputBuffer, (short) (outputOffset + ecdhLength), corruption); + short ecdhcLength = testECDHC(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, (short) (outputOffset + ecdhLength), corruption); short length = (short) (ecdhLength + ecdhcLength); if (sw != ISO7816.SW_NO_ERROR) { return length; diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index 98f59c4..f802233 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -64,6 +64,7 @@ public class ECTesterApplet extends Applet { // STATUS WORDS public static final short SW_SIG_VERIFY_FAIL = (short) 0x0ee1; public static final short SW_DH_DHC_MISMATCH = (short) 0x0ee2; + public static final short SW_KEYPAIR_NULL = (short) 0x0ee3; private static final short ARRAY_LENGTH = (short) 0xff; @@ -551,13 +552,13 @@ public class ECTesterApplet extends Applet { short secretLength = 0; switch (type) { case EC_Consts.KA_ECDH: - secretLength = keyTester.testECDH((ECPrivateKey) priv.getPrivate(), (ECPublicKey) pub.getPublic(), ramArray, (short) 0, ramArray2, (short) 0, corruption); + secretLength = keyTester.testECDH(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); break; case EC_Consts.KA_ECDHC: - secretLength = keyTester.testECDHC((ECPrivateKey) priv.getPrivate(), (ECPublicKey) pub.getPublic(), ramArray, (short) 0, ramArray2, (short) 0, corruption); + secretLength = keyTester.testECDHC(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); break; case EC_Consts.KA_BOTH: - secretLength = keyTester.testKA((ECPrivateKey) priv.getPrivate(), (ECPublicKey) pub.getPublic(), ramArray, (short) 0, ramArray2, (short) 0, corruption); + secretLength = keyTester.testECDH_ECDHC(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); diff --git a/src/cz/crcs/ectester/applet/ECUtil.java b/src/cz/crcs/ectester/applet/ECUtil.java new file mode 100644 index 0000000..e7e4a8a --- /dev/null +++ b/src/cz/crcs/ectester/applet/ECUtil.java @@ -0,0 +1,17 @@ +package cz.crcs.ectester.applet; + +import javacard.framework.ISO7816; +import javacard.framework.ISOException; +import javacard.security.KeyPair; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class ECUtil { + + static short nullCheck(KeyPair keyPair) { + if (keyPair == null) + ISOException.throwIt(ECTesterApplet.SW_KEYPAIR_NULL); + return ISO7816.SW_NO_ERROR; + } +} diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index 0571cd8..ccd3586 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -151,12 +151,13 @@ public class EC_Store { } short bitsize = Short.parseShort(bits.getTextContent()); - EC_Curve curve = new EC_Curve(bitsize, alg, descs); + EC_Curve curve = new EC_Curve(id.getTextContent(), bitsize, alg, descs); InputStream csv = parseDataElement(dir, curveElem); if (!curve.readCSV(csv)) { throw new IOException("Invalid csv data."); } + csv.close(); objMap.put(id.getTextContent(), curve); } else { @@ -233,12 +234,13 @@ public class EC_Store { kab = EC_Consts.KA_ECDHC; } - EC_KAResult kaResult = new EC_KAResult(kab, curve.getTextContent(), onekey.getTextContent(), otherkey.getTextContent(), descs); + EC_KAResult kaResult = new EC_KAResult(id.getTextContent(), kab, curve.getTextContent(), onekey.getTextContent(), otherkey.getTextContent(), descs); InputStream csv = parseDataElement(dir, elem); if (!kaResult.readCSV(csv)) { throw new IOException("Invalid csv data."); } + csv.close(); objMap.put(id.getTextContent(), kaResult); } else { @@ -276,6 +278,8 @@ public class EC_Store { if (!result.readCSV(csv)) { throw new IOException("Invalid CSV data."); } + csv.close(); + return result; } diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 6965d14..8afda17 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -44,47 +44,7 @@ public class ECTester { private CardMngr cardManager; private DirtyLogger systemOutLogger; private EC_Store dataStore; - - //Options - private int optBits; - private boolean optAll; - private boolean optPrimeField = false; - private boolean optBinaryField = false; - - private String optNamedCurve = null; - private String optCurveFile = null; - private boolean optCustomCurve = false; - - private boolean optAnyPublic = false; - private String optNamedPublic = null; - private String optPublic = null; - - private boolean optAnyPrivate = false; - private String optNamedPrivate = null; - private String optPrivate = null; - - private boolean optAnyKey = false; - private String optNamedKey = null; - private String optKey = null; - - private boolean optAnyKeypart = false; - - private String optLog = null; - - private boolean optVerbose = false; - private String optInput = null; - private String optOutput = null; - private boolean optFresh = false; - private boolean optSimulate = false; - - //Action-related options - private String optListNamed; - private String optTestSuite; - private int optGenerateAmount; - private int optECDHCount; - private byte optECDHKA; - private int optECDSACount; - + private Config cfg; private Options opts = new Options(); private static final String CLI_HEADER = "\nECTester, a javacard Elliptic Curve Cryptograhy support tester/utility.\n\n"; @@ -104,8 +64,10 @@ public class ECTester { help(); return; } + cfg = new Config(); + //if not, read other options first, into attributes, then do action - if (!readOptions(cli)) { + if (!cfg.readOptions(cli)) { return; } @@ -117,10 +79,10 @@ public class ECTester { } //init CardManager - cardManager = new CardMngr(optVerbose, optSimulate); + cardManager = new CardMngr(cfg.verbose, cfg.simulate); //connect or simulate connection - if (optSimulate) { + if (cfg.simulate) { if (!cardManager.prepareLocalSimulatorApplet(AID, INSTALL_DATA, ECTesterApplet.class)) { System.err.println("Failed to establish a simulator."); System.exit(1); @@ -133,7 +95,7 @@ public class ECTester { cardManager.send(SELECT_ECTESTERAPPLET); } - systemOutLogger = new DirtyLogger(optLog, true); + systemOutLogger = new DirtyLogger(cfg.log, true); //do action if (cli.hasOption("export")) { @@ -208,7 +170,7 @@ public class ECTester { * -dh / --ecdh [count] * -dhc / --ecdhc [count] * -dsa / --ecdsa [count] - * -ln / --list-named + * -ln / --list-named [obj] * * Options: * -b / --bit-size // -a / --all @@ -291,194 +253,26 @@ public class ECTester { return parser.parse(opts, args); } - /** - * Reads and validates options, also sets defaults. - * - * @param cli cli object, with parsed args - * @return whether the options are valid. - */ - private boolean readOptions(CommandLine cli) { - optBits = Integer.parseInt(cli.getOptionValue("bit-size", "0")); - optAll = cli.hasOption("all"); - optPrimeField = cli.hasOption("fp"); - optBinaryField = cli.hasOption("f2m"); - - optNamedCurve = cli.getOptionValue("named-curve"); - optCustomCurve = cli.hasOption("custom"); - optCurveFile = cli.getOptionValue("curve"); - - optNamedPublic = cli.getOptionValue("named-public"); - optPublic = cli.getOptionValue("public"); - optAnyPublic = (optPublic != null) || (optNamedPublic != null); - - optNamedPrivate = cli.getOptionValue("named-private"); - optPrivate = cli.getOptionValue("private"); - optAnyPrivate = (optPrivate != null) || (optNamedPrivate != null); - - optNamedKey = cli.getOptionValue("named-key"); - optKey = cli.getOptionValue("key"); - optAnyKey = (optKey != null) || (optNamedKey != null); - optAnyKeypart = optAnyKey || optAnyPublic || optAnyPrivate; - - if (cli.hasOption("log")) { - optLog = cli.getOptionValue("log", String.format("ECTESTER_log_%d.log", System.currentTimeMillis() / 1000)); - } - - optVerbose = cli.hasOption("verbose"); - optInput = cli.getOptionValue("input"); - optOutput = cli.getOptionValue("output"); - optFresh = cli.hasOption("fresh"); - optSimulate = cli.hasOption("simulate"); - - if (cli.hasOption("list-named")) { - optListNamed = cli.getOptionValue("list-named"); - return true; - } - - if ((optKey != null || optNamedKey != null) && (optPublic != null || optPrivate != null || optNamedPublic != null || optNamedPrivate != null)) { - System.err.print("Can only specify the whole key with --key/--named-key or pubkey and privkey with --public/--named-public and --private/--named-private."); - return false; - } - if (optBits < 0) { - System.err.println("Bit-size must not be negative."); - return false; - } - if (optBits == 0 && !optAll) { - System.err.println("You must specify either bit-size with -b or all bit-sizes with -a."); - return false; - } - - if (optKey != null && optNamedKey != null || optPublic != null && optNamedPublic != null || optPrivate != null && optNamedPrivate != null) { - System.err.println("You cannot specify both a named key and a key file."); - return false; - } - - if (cli.hasOption("export")) { - if (optPrimeField == optBinaryField) { - System.err.print("Need to specify field with -fp or -f2m. (not both)"); - return false; - } - if (optAnyKeypart) { - System.err.println("Keys should not be specified when exporting curve params."); - return false; - } - if (optNamedCurve != null || optCustomCurve || optCurveFile != null) { - System.err.println("Specifying a curve for curve export makes no sense."); - return false; - } - if (optOutput == null) { - System.err.println("You have to specify an output file for curve parameter export."); - return false; - } - if (optAll) { - System.err.println("You have to specify curve bit-size with -b"); - return false; - } - - } else if (cli.hasOption("generate")) { - if (optPrimeField == optBinaryField) { - System.err.print("Need to specify field with -fp or -f2m. (not both)"); - return false; - } - if (optAnyKeypart) { - System.err.println("Keys should not be specified when generating keys."); - return false; - } - if (optOutput == null) { - System.err.println("You have to specify an output file for the key generation process."); - return false; - } - if (optAll) { - System.err.println("You have to specify curve bit-size with -b"); - return false; - } - - optGenerateAmount = Integer.parseInt(cli.getOptionValue("generate", "0")); - if (optGenerateAmount < 0) { - System.err.println("Amount of keys generated cant be negative."); - return false; - } - } else if (cli.hasOption("test")) { - if (!optBinaryField && !optPrimeField) { - optBinaryField = true; - optPrimeField = true; - } - - optTestSuite = cli.getOptionValue("test", "default").toLowerCase(); - String[] tests = new String[]{"default", "nonprime", "invalid", "test-vectors", "wrong"}; - List testsList = Arrays.asList(tests); - if (!testsList.contains(optTestSuite)) { - System.err.println("Unknown test case. Should be one of: " + Arrays.toString(tests)); - return false; - } - - } else if (cli.hasOption("ecdh") || cli.hasOption("ecdhc")) { - if (optPrimeField == optBinaryField) { - System.err.print("Need to specify field with -fp or -f2m. (not both)"); - return false; - } - if (optAll) { - System.err.println("You have to specify curve bit-size with -b"); - return false; - } - - if (cli.hasOption("ecdh")) { - optECDHCount = Integer.parseInt(cli.getOptionValue("ecdh", "1")); - optECDHKA = EC_Consts.KA_ECDH; - } else if (cli.hasOption("ecdhc")) { - optECDHCount = Integer.parseInt(cli.getOptionValue("ecdhc", "1")); - optECDHKA = EC_Consts.KA_ECDHC; - } - if (optECDHCount <= 0) { - System.err.println("ECDH count cannot be <= 0."); - return false; - } - - } else if (cli.hasOption("ecdsa")) { - if (optPrimeField == optBinaryField) { - System.err.print("Need to specify field with -fp or -f2m. (but not both)"); - return false; - } - if (optAll) { - System.err.println("You have to specify curve bit-size with -b"); - return false; - } - - if ((optAnyPublic) != (optAnyPrivate) && !optAnyKey) { - System.err.println("You cannot only specify a part of a keypair."); - return false; - } - - optECDSACount = Integer.parseInt(cli.getOptionValue("ecdsa", "1")); - if (optECDSACount <= 0) { - System.err.println("ECDSA count cannot be <= 0."); - return false; - } - } - - return true; - } - /** * List categories and named curves. */ private void list() { Map categories = dataStore.getCategories(); - if (optListNamed == null) { + if (cfg.listNamed == null) { // print all categories, briefly for (EC_Category cat : categories.values()) { System.out.println(cat); } - } else if (categories.containsKey(optListNamed)) { + } else if (categories.containsKey(cfg.listNamed)) { // print given category - System.out.println(categories.get(optListNamed)); + System.out.println(categories.get(cfg.listNamed)); } else { // print given object - EC_Data object = dataStore.getObject(EC_Data.class, optListNamed); + EC_Data object = dataStore.getObject(EC_Data.class, cfg.listNamed); if (object != null) { System.out.println(object); } else { - System.err.println("Named object " + optListNamed + " not found!"); + System.err.println("Named object " + cfg.listNamed + " not found!"); } } } @@ -499,17 +293,17 @@ public class ECTester { * @throws IOException if an IO error occurs when writing to key file. */ private void export() throws CardException, IOException { - byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; + byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; List sent = new LinkedList<>(); - sent.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass).send()); + sent.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send()); sent.add(new Command.Clear(cardManager, ECTesterApplet.KEYPAIR_LOCAL).send()); sent.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL).send()); // Cofactor generally isn't set on the default curve parameters on cards, // since its not necessary for ECDH, only ECDHC which not many cards implement // TODO: check if its assumend to be == 1? - short domainAll = optPrimeField ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; + short domainAll = cfg.primeField ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; short domain = (short) (domainAll ^ EC_Consts.PARAMETER_K); Response.Export export = new Command.Export(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.KEY_PUBLIC, domainAll).send(); if (!export.successful()) { @@ -521,7 +315,7 @@ public class ECTester { EC_Params exported = new EC_Params(domain, export.getParams()); - FileOutputStream out = new FileOutputStream(optOutput); + FileOutputStream out = new FileOutputStream(cfg.output); exported.writeCSV(out); out.close(); } @@ -533,18 +327,18 @@ public class ECTester { * @throws IOException if an IO error occurs when writing to key file. */ private void generate() throws CardException, IOException { - byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; + byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; - new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass).send(); - List curve = prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass); + new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send(); + List curve = prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass); - FileWriter keysFile = new FileWriter(optOutput); + FileWriter keysFile = new FileWriter(cfg.output); keysFile.write("index;time;pubW;privS\n"); int generated = 0; int retry = 0; - while (generated < optGenerateAmount || optGenerateAmount == 0) { - if (optFresh || generated == 0) { + while (generated < cfg.generateAmount || cfg.generateAmount == 0) { + if (cfg.fresh || generated == 0) { Command.sendAll(curve); } @@ -583,19 +377,20 @@ public class ECTester { */ private void test() throws IOException, CardException { List commands = new LinkedList<>(); + TestSuite suite = null; - if (optTestSuite.equals("default")) { + if (cfg.testSuite.equals("default")) { commands.add(new Command.Support(cardManager)); - if (optNamedCurve != null) { - if (optPrimeField) { - commands.addAll(testCurves(optNamedCurve, KeyPair.ALG_EC_FP)); + if (cfg.namedCurve != null) { + if (cfg.primeField) { + commands.addAll(testCurves(cfg.namedCurve, KeyPair.ALG_EC_FP)); } - if (optBinaryField) { - commands.addAll(testCurves(optNamedCurve, KeyPair.ALG_EC_F2M)); + if (cfg.binaryField) { + commands.addAll(testCurves(cfg.namedCurve, KeyPair.ALG_EC_F2M)); } } else { - if (optAll) { - if (optPrimeField) { + if (cfg.all) { + if (cfg.primeField) { //iterate over prime curve sizes used: EC_Consts.FP_SIZES for (short keyLength : EC_Consts.FP_SIZES) { commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_FP)); @@ -604,7 +399,7 @@ public class ECTester { commands.add(new Command.Cleanup(cardManager)); } } - if (optBinaryField) { + if (cfg.binaryField) { //iterate over binary curve sizes used: EC_Consts.F2M_SIZES for (short keyLength : EC_Consts.F2M_SIZES) { commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_F2M)); @@ -614,60 +409,31 @@ public class ECTester { } } } else { - if (optPrimeField) { - commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) optBits, KeyPair.ALG_EC_FP)); - commands.addAll(prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) optBits, KeyPair.ALG_EC_FP)); + if (cfg.primeField) { + commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, KeyPair.ALG_EC_FP)); + commands.addAll(prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, KeyPair.ALG_EC_FP)); commands.addAll(testCurve()); commands.add(new Command.Cleanup(cardManager)); } - if (optBinaryField) { - commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) optBits, KeyPair.ALG_EC_F2M)); - commands.addAll(prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) optBits, KeyPair.ALG_EC_F2M)); + if (cfg.binaryField) { + commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, KeyPair.ALG_EC_F2M)); + commands.addAll(prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, KeyPair.ALG_EC_F2M)); commands.addAll(testCurve()); commands.add(new Command.Cleanup(cardManager)); } } } - } else if (optTestSuite.equals("test-vectors")) { + } else if (cfg.testSuite.equals("test-vectors")) { /* Set original curves (secg/nist/brainpool). Set keypairs from test vectors. * Do ECDH both ways, export and verify that the result is correct. * */ - Map results = dataStore.getObjects(EC_KAResult.class, "test"); - for (EC_KAResult result : results.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, result.getCurve()); - if (optNamedCurve != null && !(result.getCurve().startsWith(optNamedCurve) || result.getCurve().equals(optNamedCurve))) { - continue; - } - if (curve.getBits() != optBits && !optAll) { - continue; - } - EC_Params onekey = dataStore.getObject(EC_Keypair.class, result.getOneKey()); - if (onekey == null) { - onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); - } - EC_Params otherkey = dataStore.getObject(EC_Keypair.class, result.getOtherKey()); - if (otherkey == null) { - otherkey = dataStore.getObject(EC_Key.Public.class, result.getOtherKey()); - } - if (onekey == null || otherkey == null) { - throw new IOException("Test vector keys not located"); - } - - commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField())); - commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten())); - commands.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH)); - commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S))); - commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W))); - commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA())); - //TODO add compare with result.getParam(0); - commands.add(new Command.Cleanup(cardManager)); - } + suite = new TestSuite.TestVectors(dataStore, cfg); } else { // These tests are dangerous, prompt before them. - System.out.println("The test you selected (" + optTestSuite + ") is potentially dangerous."); + System.out.println("The test you selected (" + cfg.testSuite + ") is potentially dangerous."); System.out.println("Some of these tests have caused temporary DoS of some cards."); System.out.print("Do you want to proceed? (y/n): "); Scanner in = new Scanner(System.in); @@ -677,62 +443,40 @@ public class ECTester { } in.close(); - if (optTestSuite.equals("wrong")) { + if (cfg.testSuite.equals("wrong")) { /* Just do the default tests on the wrong curves. * These should generally fail, the curves aren't safe. */ - if (optPrimeField) { - commands.addAll(testCurves(optTestSuite, KeyPair.ALG_EC_FP)); + if (cfg.primeField) { + commands.addAll(testCurves(cfg.testSuite, KeyPair.ALG_EC_FP)); } - if (optBinaryField) { - commands.addAll(testCurves(optTestSuite, KeyPair.ALG_EC_F2M)); + if (cfg.binaryField) { + commands.addAll(testCurves(cfg.testSuite, KeyPair.ALG_EC_F2M)); } - } else if (optTestSuite.equals("nonprime")) { + } else if (cfg.testSuite.equals("nonprime")) { /* Do the default tests with the public keys set to provided nonprime keys. * These should fail, the curves aren't safe so that if the computation with * a small order public key succeeds the private key modulo the public key order * is revealed. */ - Map keys = dataStore.getObjects(EC_Key.class, "nonprime"); - for (EC_Key key : keys.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); - if ((curve.getBits() == optBits || optAll)) { - commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField())); - commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten())); - commands.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL)); - commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten())); - commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH)); - commands.add(new Command.Cleanup(cardManager)); - } - } - } else if (optTestSuite.equals("invalid")) { + suite = new TestSuite.NonPrime(dataStore, cfg); + } else if (cfg.testSuite.equals("invalid")) { /* Set original curves (secg/nist/brainpool). Generate local. * Try ECDH with invalid public keys of increasing (or decreasing) order. */ - Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); - for (EC_Key.Public key : pubkeys.values()) { - EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); - if (optNamedCurve != null && !(key.getCurve().startsWith(optNamedCurve) || key.getCurve().equals(optNamedCurve))) { - continue; - } - if (curve.getBits() != optBits && !optAll) { - continue; - } - commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField())); - commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten())); - commands.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL)); - commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten())); - commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_BOTH)); - //commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDHC)); - commands.add(new Command.Cleanup(cardManager)); - - } + suite = new TestSuite.Invalid(dataStore, cfg); } } List test = Command.sendAll(commands); - systemOutLogger.println(Response.toString(test, optTestSuite)); + if (suite != null) { + List tests = suite.run(cardManager); + for (Test t : tests) { + System.out.println(t); + } + } + systemOutLogger.println(Response.toString(test, cfg.testSuite)); } @@ -743,34 +487,34 @@ public class ECTester { * @throws IOException if an IO error occurs when writing to key file. */ private void ecdh() throws IOException, CardException { - byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; + byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; List prepare = new LinkedList<>(); - prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) optBits, keyClass).send()); - prepare.addAll(Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) optBits, keyClass))); + prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass).send()); + prepare.addAll(Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) cfg.bits, keyClass))); systemOutLogger.println(Response.toString(prepare)); - byte pubkey = (optAnyPublic || optAnyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; - byte privkey = (optAnyPrivate || optAnyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; + byte pubkey = (cfg.anyPublicKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; + byte privkey = (cfg.anyPrivateKey || cfg.anyKey) ? ECTesterApplet.KEYPAIR_REMOTE : ECTesterApplet.KEYPAIR_LOCAL; List generate = new LinkedList<>(); generate.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH)); - if (optAnyPublic || optAnyPrivate || optAnyKey) { + if (cfg.anyPublicKey || cfg.anyPrivateKey || cfg.anyKey) { generate.add(prepareKey(ECTesterApplet.KEYPAIR_REMOTE)); } FileWriter out = null; - if (optOutput != null) { - out = new FileWriter(optOutput); + if (cfg.output != null) { + out = new FileWriter(cfg.output); out.write("index;time;secret\n"); } int retry = 0; int done = 0; - while (done < optECDHCount) { + while (done < cfg.ECDHCount) { List ecdh = Command.sendAll(generate); - Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, optECDHKA).send(); + Response.ECDH perform = new Command.ECDH(cardManager, pubkey, privkey, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, cfg.ECDHKA).send(); ecdh.add(perform); systemOutLogger.println(Response.toString(ecdh)); @@ -804,38 +548,38 @@ public class ECTester { private void ecdsa() throws CardException, IOException { //read file, if asked to sign byte[] data = null; - if (optInput != null) { - File in = new File(optInput); + if (cfg.input != null) { + File in = new File(cfg.input); long len = in.length(); if (len == 0) { - throw new FileNotFoundException(optInput); + throw new FileNotFoundException(cfg.input); } data = Files.readAllBytes(in.toPath()); } Command generate; - if (optAnyKeypart) { + if (cfg.anyKeypart) { generate = prepareKey(ECTesterApplet.KEYPAIR_LOCAL); } else { generate = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL); } - byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; + byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; List prepare = new LinkedList<>(); - prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass).send()); - prepare.addAll(Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass))); + prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass).send()); + prepare.addAll(Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) cfg.bits, keyClass))); systemOutLogger.println(Response.toString(prepare)); FileWriter out = null; - if (optOutput != null) { - out = new FileWriter(optOutput); + if (cfg.output != null) { + out = new FileWriter(cfg.output); out.write("index;time;signature\n"); } int retry = 0; int done = 0; - while (done < optECDSACount) { + while (done < cfg.ECDSACount) { List ecdsa = new LinkedList<>(); ecdsa.add(generate.send()); @@ -873,14 +617,14 @@ public class ECTester { private List prepareCurve(byte keyPair, short keyLength, byte keyClass) throws IOException { List commands = new ArrayList<>(); - if (optCustomCurve) { + if (cfg.customCurve) { // Set custom curve (one of the SECG curves embedded applet-side) short domainParams = keyClass == KeyPair.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; commands.add(new Command.Set(cardManager, keyPair, EC_Consts.getCurve(keyLength, keyClass), domainParams, null)); - } else if (optNamedCurve != null) { + } else if (cfg.namedCurve != null) { // Set a named curve. - // parse optNamedCurve -> cat / id | cat | id - EC_Curve curve = dataStore.getObject(EC_Curve.class, optNamedCurve); + // parse cfg.namedCurve -> cat / id | cat | id + EC_Curve curve = dataStore.getObject(EC_Curve.class, cfg.namedCurve); if (curve == null) { throw new IOException("Curve could no be found."); } @@ -893,11 +637,11 @@ public class ECTester { throw new IOException("Couldn't read named curve data."); } commands.add(new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, curve.getParams(), external)); - } else if (optCurveFile != null) { + } else if (cfg.curveFile != null) { // Set curve loaded from a file - EC_Curve curve = new EC_Curve(keyLength, keyClass); + EC_Curve curve = new EC_Curve(null, keyLength, keyClass); - FileInputStream in = new FileInputStream(optCurveFile); + FileInputStream in = new FileInputStream(cfg.curveFile); curve.readCSV(in); in.close(); @@ -927,17 +671,17 @@ public class ECTester { short params = EC_Consts.PARAMETERS_NONE; byte[] data = null; - if (optKey != null || optNamedKey != null) { + if (cfg.key != null || cfg.namedKey != null) { params |= EC_Consts.PARAMETERS_KEYPAIR; EC_Params keypair; - if (optKey != null) { + if (cfg.key != null) { keypair = new EC_Params(EC_Consts.PARAMETERS_KEYPAIR); - FileInputStream in = new FileInputStream(optKey); + FileInputStream in = new FileInputStream(cfg.key); keypair.readCSV(in); in.close(); } else { - keypair = dataStore.getObject(EC_Keypair.class, optNamedKey); + keypair = dataStore.getObject(EC_Keypair.class, cfg.namedKey); } data = keypair.flatten(); @@ -946,19 +690,19 @@ public class ECTester { } } - if (optPublic != null || optNamedPublic != null) { + if (cfg.publicKey != null || cfg.namedPublicKey != null) { params |= EC_Consts.PARAMETER_W; EC_Params pub; - if (optPublic != null) { + if (cfg.publicKey != null) { pub = new EC_Params(EC_Consts.PARAMETER_W); - FileInputStream in = new FileInputStream(optPublic); + FileInputStream in = new FileInputStream(cfg.publicKey); pub.readCSV(in); in.close(); } else { - pub = dataStore.getObject(EC_Key.Public.class, optNamedPublic); + pub = dataStore.getObject(EC_Key.Public.class, cfg.namedPublicKey); if (pub == null) { - pub = dataStore.getObject(EC_Keypair.class, optNamedPublic); + pub = dataStore.getObject(EC_Keypair.class, cfg.namedPublicKey); } } @@ -968,19 +712,19 @@ public class ECTester { } data = pubkey; } - if (optPrivate != null || optNamedPrivate != null) { + if (cfg.privateKey != null || cfg.namedPrivateKey != null) { params |= EC_Consts.PARAMETER_S; EC_Params priv; - if (optPrivate != null) { + if (cfg.privateKey != null) { priv = new EC_Params(EC_Consts.PARAMETER_S); - FileInputStream in = new FileInputStream(optPrivate); + FileInputStream in = new FileInputStream(cfg.privateKey); priv.readCSV(in); in.close(); } else { - priv = dataStore.getObject(EC_Key.Public.class, optNamedPrivate); + priv = dataStore.getObject(EC_Key.Public.class, cfg.namedPrivateKey); if (priv == null) { - priv = dataStore.getObject(EC_Keypair.class, optNamedPrivate); + priv = dataStore.getObject(EC_Keypair.class, cfg.namedPrivateKey); } } @@ -1022,7 +766,7 @@ public class ECTester { return commands; for (Map.Entry entry : curves.entrySet()) { EC_Curve curve = entry.getValue(); - if (curve.getField() == field && (curve.getBits() == optBits || optAll)) { + if (curve.getField() == field && (curve.getBits() == cfg.bits || cfg.all)) { commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), field)); commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten())); commands.addAll(testCurve()); @@ -1037,4 +781,214 @@ public class ECTester { ECTester app = new ECTester(); app.run(args); } + + public static class Config { + + //Options + public int bits; + public boolean all; + public boolean primeField = false; + public boolean binaryField = false; + + public String namedCurve; + public String curveFile; + public boolean customCurve = false; + + public boolean anyPublicKey = false; + public String namedPublicKey; + public String publicKey; + + public boolean anyPrivateKey = false; + public String namedPrivateKey; + public String privateKey; + + public boolean anyKey = false; + public String namedKey; + public String key; + + public boolean anyKeypart = false; + + public String log; + + public boolean verbose = false; + public String input; + public String output; + public boolean fresh = false; + public boolean simulate = false; + + //Action-related ions + public String listNamed; + public String testSuite; + public int generateAmount; + public int ECDHCount; + public byte ECDHKA; + public int ECDSACount; + + /** + * Reads and validates options, also sets defaults. + * + * @param cli cli object, with parsed args + * @return whether the options are valid. + */ + public boolean readOptions(CommandLine cli) { + bits = Integer.parseInt(cli.getOptionValue("bit-size", "0")); + all = cli.hasOption("all"); + primeField = cli.hasOption("fp"); + binaryField = cli.hasOption("f2m"); + + namedCurve = cli.getOptionValue("named-curve"); + customCurve = cli.hasOption("custom"); + curveFile = cli.getOptionValue("curve"); + + namedPublicKey = cli.getOptionValue("named-public"); + publicKey = cli.getOptionValue("public"); + anyPublicKey = (publicKey != null) || (namedPublicKey != null); + + namedPrivateKey = cli.getOptionValue("named-private"); + privateKey = cli.getOptionValue("private"); + anyPrivateKey = (privateKey != null) || (namedPrivateKey != null); + + namedKey = cli.getOptionValue("named-key"); + key = cli.getOptionValue("key"); + anyKey = (key != null) || (namedKey != null); + anyKeypart = anyKey || anyPublicKey || anyPrivateKey; + + if (cli.hasOption("log")) { + log = cli.getOptionValue("log", String.format("ECTESTER_log_%d.log", System.currentTimeMillis() / 1000)); + } + + verbose = cli.hasOption("verbose"); + input = cli.getOptionValue("input"); + output = cli.getOptionValue("output"); + fresh = cli.hasOption("fresh"); + simulate = cli.hasOption("simulate"); + + if (cli.hasOption("list-named")) { + listNamed = cli.getOptionValue("list-named"); + return true; + } + + if ((key != null || namedKey != null) && (anyPublicKey || anyPrivateKey)) { + System.err.print("Can only specify the whole key with --key/--named-key or pubkey and privkey with --public/--named-public and --private/--named-private."); + return false; + } + if (bits < 0) { + System.err.println("Bit-size must not be negative."); + return false; + } + if (bits == 0 && !all) { + System.err.println("You must specify either bit-size with -b or all bit-sizes with -a."); + return false; + } + + if (key != null && namedKey != null || publicKey != null && namedPublicKey != null || privateKey != null && namedPrivateKey != null) { + System.err.println("You cannot specify both a named key and a key file."); + return false; + } + + if (cli.hasOption("export")) { + if (primeField == binaryField) { + System.err.print("Need to specify field with -fp or -f2m. (not both)"); + return false; + } + if (anyKeypart) { + System.err.println("Keys should not be specified when exporting curve params."); + return false; + } + if (namedCurve != null || customCurve || curveFile != null) { + System.err.println("Specifying a curve for curve export makes no sense."); + return false; + } + if (output == null) { + System.err.println("You have to specify an output file for curve parameter export."); + return false; + } + if (all) { + System.err.println("You have to specify curve bit-size with -b"); + return false; + } + + } else if (cli.hasOption("generate")) { + if (primeField == binaryField) { + System.err.print("Need to specify field with -fp or -f2m. (not both)"); + return false; + } + if (anyKeypart) { + System.err.println("Keys should not be specified when generating keys."); + return false; + } + if (output == null) { + System.err.println("You have to specify an output file for the key generation process."); + return false; + } + if (all) { + System.err.println("You have to specify curve bit-size with -b"); + return false; + } + + generateAmount = Integer.parseInt(cli.getOptionValue("generate", "0")); + if (generateAmount < 0) { + System.err.println("Amount of keys generated cant be negative."); + return false; + } + } else if (cli.hasOption("test")) { + if (!binaryField && primeField) { + binaryField = true; + primeField = true; + } + + testSuite = cli.getOptionValue("test", "default").toLowerCase(); + String[] tests = new String[]{"default", "nonprime", "invalid", "test-vectors", "wrong"}; + List testsList = Arrays.asList(tests); + if (!testsList.contains(testSuite)) { + System.err.println("Unknown test case. Should be one of: " + Arrays.toString(tests)); + return false; + } + + } else if (cli.hasOption("ecdh") || cli.hasOption("ecdhc")) { + if (primeField == binaryField) { + System.err.print("Need to specify field with -fp or -f2m. (not both)"); + return false; + } + if (all) { + System.err.println("You have to specify curve bit-size with -b"); + return false; + } + + if (cli.hasOption("ecdh")) { + ECDHCount = Integer.parseInt(cli.getOptionValue("ecdh", "1")); + ECDHKA = EC_Consts.KA_ECDH; + } else if (cli.hasOption("ecdhc")) { + ECDHCount = Integer.parseInt(cli.getOptionValue("ecdhc", "1")); + ECDHKA = EC_Consts.KA_ECDHC; + } + if (ECDHCount <= 0) { + System.err.println("ECDH count cannot be <= 0."); + return false; + } + + } else if (cli.hasOption("ecdsa")) { + if (primeField == binaryField) { + System.err.print("Need to specify field with -fp or -f2m. (but not both)"); + return false; + } + if (all) { + System.err.println("You have to specify curve bit-size with -b"); + return false; + } + + if ((anyPublicKey) != (anyPrivateKey) && !anyKey) { + System.err.println("You cannot only specify a part of a keypair."); + return false; + } + + ECDSACount = Integer.parseInt(cli.getOptionValue("ecdsa", "1")); + if (ECDSACount <= 0) { + System.err.println("ECDSA count cannot be <= 0."); + return false; + } + } + return true; + } + } } diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java index ee27260..e5b8c1c 100644 --- a/src/cz/crcs/ectester/reader/Response.java +++ b/src/cz/crcs/ectester/reader/Response.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.reader; import cz.crcs.ectester.applet.ECTesterApplet; import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.reader.ec.EC_Curve; import javacard.framework.ISO7816; import javacard.security.KeyPair; @@ -12,11 +13,13 @@ import java.util.List; * @author Jan Jancar johny@neuromancer.sk */ public abstract class Response { + private ResponseAPDU resp; private long time; private short[] sws; private int numSW = 0; private byte[][] params; + //TODO replace params with EC_Data? private boolean success = true; protected Response(ResponseAPDU response, long time) { @@ -40,9 +43,14 @@ public abstract class Response { if (sw != ISO7816.SW_NO_ERROR) { success = false; } + } else { + success = false; } } + if ((short) resp.getSW() != ISO7816.SW_NO_ERROR) + success = false; + //try to parse numParams.. params = new byte[numParams][]; for (int i = 0; i < numParams; i++) { @@ -70,16 +78,8 @@ public abstract class Response { return time; } - public int getNaturalSW() { - return resp.getSW(); - } - - public short getSW1() { - return sws[0]; - } - - public short getSW2() { - return sws[1]; + public short getNaturalSW() { + return (short) resp.getSW(); } public short getSW(int index) { @@ -90,15 +90,15 @@ public abstract class Response { return numSW; } - protected boolean hasParam(int index) { + public boolean hasParam(int index) { return params.length >= index + 1 && params[index] != null; } - protected int getParamLength(int index) { + public int getParamLength(int index) { return params[index].length; } - protected byte[] getParam(int index) { + public byte[] getParam(int index) { return params[index]; } @@ -117,27 +117,32 @@ public abstract class Response { @Override public abstract String toString(); + public String toString(String inner) { + StringBuilder suffix = new StringBuilder(); + for (int j = 0; j < getNumSW(); ++j) { + suffix.append(" ").append(Util.getSWString(getSW(j))); + } + return String.format("%-62s:%4d ms : %s", inner, time / 1000000, suffix); + } + public static String toString(List responses) { return toString(responses, null); } - public static String toString(List responses, String prefix) { + public static String toString(List responses, String prefix) { if (prefix != null) prefix += " | "; StringBuilder out = new StringBuilder(); for (int i = 0; i < responses.size(); ++i) { Response r = responses.get(i); - String message = r.toString(); - String suffix = ""; - for (int j = 0; j < r.getNumSW(); ++j) { - suffix += " " + Util.getSWString(r.getSW(j)); - } - if (prefix != null) out.append(prefix); - out.append(String.format("%-62s:%4d ms : %s", message, r.time / 1000000, suffix)); + String message = r.toString(); + String full = r.toString(message); + + out.append(full); if (i < responses.size() - 1) { out.append("\n"); } @@ -149,6 +154,7 @@ public abstract class Response { * */ public static class Allocate extends Response { + private byte keyPair; private short keyLength; private byte keyClass; @@ -174,11 +180,15 @@ public abstract class Response { } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return String.format("Allocated %s %db %s", key, keyLength, field); + return super.toString(String.format("Allocated %s %db %s", key, keyLength, field)); } } + /** + * + */ public static class Clear extends Response { + private byte keyPair; protected Clear(ResponseAPDU response, long time, byte keyPair) { @@ -199,7 +209,7 @@ public abstract class Response { } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return String.format("Cleared %s", key); + return super.toString(String.format("Cleared %s", key)); } } @@ -207,6 +217,7 @@ public abstract class Response { * */ public static class Set extends Response { + private byte keyPair; private byte curve; private short parameters; @@ -238,13 +249,24 @@ public abstract class Response { name = "custom"; break; } + String what = ""; + if (parameters == EC_Consts.PARAMETERS_DOMAIN_F2M || parameters == EC_Consts.PARAMETERS_DOMAIN_FP) { + what = "curve"; + } else if (parameters == EC_Consts.PARAMETER_W) { + what = "pubkey"; + } else if (parameters == EC_Consts.PARAMETER_S) { + what = "privkey"; + } else if (parameters == EC_Consts.PARAMETERS_KEYPAIR) { + what = "keypair"; + } + String pair; if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { pair = "both keypairs"; } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return String.format("Set %s curve parameters on %s", name, pair); + return super.toString(String.format("Set %s %s parameters on %s", name, what, pair)); } } @@ -253,6 +275,7 @@ public abstract class Response { * */ public static class Corrupt extends Response { + private byte keyPair; private byte key; private short params; @@ -282,7 +305,7 @@ public abstract class Response { } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return String.format("Corrupted params of %s, %s", pair, corrupt); + return super.toString(String.format("Corrupted params of %s, %s", pair, corrupt)); } } @@ -290,6 +313,7 @@ public abstract class Response { * */ public static class Generate extends Response { + private byte keyPair; protected Generate(ResponseAPDU response, long time, byte keyPair) { @@ -310,7 +334,7 @@ public abstract class Response { } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return String.format("Generated %s", key); + return super.toString(String.format("Generated %s", key)); } } @@ -319,6 +343,7 @@ public abstract class Response { * */ public static class Export extends Response { + private byte keyPair; private byte key; private short parameters; @@ -419,7 +444,7 @@ public abstract class Response { } else { pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return String.format("Exported params from %s of %s", source, pair); + return super.toString(String.format("Exported params from %s of %s", source, pair)); } } @@ -427,6 +452,7 @@ public abstract class Response { * */ public static class ECDH extends Response { + private byte pubkey; private byte privkey; private byte export; @@ -452,18 +478,13 @@ public abstract class Response { return getParam(0); } + public int secretLength() { + return getParamLength(0); + } + @Override public String toString() { - String algo = ""; - if ((type & EC_Consts.KA_ECDH) != 0) { - algo += "ECDH"; - } - if (type == EC_Consts.KA_BOTH) { - algo += "+"; - } - if ((type & EC_Consts.KA_ECDHC) != 0) { - algo += "ECDHC"; - } + String algo = Util.getKA(type); String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; @@ -474,7 +495,7 @@ public abstract class Response { } else { validity = Util.getCorruption(corruption); } - return String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity); + return super.toString(String.format("%s of %s pubkey and %s privkey(%s point)", algo, pub, priv, validity)); } } @@ -482,6 +503,7 @@ public abstract class Response { * */ public static class ECDSA extends Response { + private byte keyPair; private byte export; private byte[] raw; @@ -507,7 +529,7 @@ public abstract class Response { public String toString() { String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String data = raw == null ? "random" : "provided"; - return String.format("ECDSA with %s keypair(%s data)", key, data); + return super.toString(String.format("ECDSA with %s keypair(%s data)", key, data)); } } @@ -524,7 +546,7 @@ public abstract class Response { @Override public String toString() { - return "Requested JCSystem object deletion"; + return super.toString("Requested JCSystem object deletion"); } } @@ -537,12 +559,12 @@ public abstract class Response { protected Support(ResponseAPDU response, long time) { super(response, time); - parse(3,0); + parse(3, 0); } @Override public String toString() { - return "Support of ECDH, ECDHC, ECDSA"; + return super.toString("Support of ECDH, ECDHC, ECDSA"); } } } diff --git a/src/cz/crcs/ectester/reader/Test.java b/src/cz/crcs/ectester/reader/Test.java new file mode 100644 index 0000000..78efef5 --- /dev/null +++ b/src/cz/crcs/ectester/reader/Test.java @@ -0,0 +1,81 @@ +package cz.crcs.ectester.reader; + +import javax.smartcardio.CardException; +import java.util.function.BiFunction; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public class Test { + private boolean hasRun = false; + private BiFunction callback; + private Result result; + private Result expected; + private Command command; + private Response response; + + public Test(Command command, Result expected) { + this.command = command; + this.expected = expected; + } + + public Test(Command command, Result expected, BiFunction callback) { + this(command, expected); + this.callback = callback; + } + + public Command getCommand() { + return command; + } + + public Response getResponse() { + if (!hasRun) { + return null; + } + return response; + } + + public Result getResult() { + if (!hasRun) { + return null; + } + return result; + } + + public Result getExpected() { + return expected; + } + + public boolean ok() { + return result == expected || expected == Result.ANY; + } + + public void run() throws CardException { + response = command.send(); + if (callback != null) { + result = callback.apply(command, response); + } else { + if (response.successful()) { + result = Result.SUCCESS; + } else { + result = Result.FAILURE; + } + } + hasRun = true; + } + + @Override + public String toString() { + if (hasRun) { + return (ok() ? "OK " : "NOK") + " " + response.toString(); + } else { + return ""; + } + } + + public enum Result { + SUCCESS, + FAILURE, + ANY + } +} diff --git a/src/cz/crcs/ectester/reader/TestSuite.java b/src/cz/crcs/ectester/reader/TestSuite.java new file mode 100644 index 0000000..892e853 --- /dev/null +++ b/src/cz/crcs/ectester/reader/TestSuite.java @@ -0,0 +1,167 @@ +package cz.crcs.ectester.reader; + +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.data.EC_Store; +import cz.crcs.ectester.reader.ec.*; + +import javax.smartcardio.CardException; +import java.io.IOException; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class TestSuite { + + EC_Store dataStore; + ECTester.Config cfg; + String name; + boolean hasRun; + List tests = new LinkedList<>(); + + public TestSuite(EC_Store dataStore, ECTester.Config cfg, String name) { + this.dataStore = dataStore; + this.cfg = cfg; + this.name = name; + } + + public List run(CardMngr cardManager) throws IOException, CardException { + for (Test t : tests) { + t.run(); + System.out.println(t); + } + hasRun = true; + return tests; + } + + public List getTests() { + return Collections.unmodifiableList(tests); + } + + public boolean hasRun() { + return hasRun; + } + + public String getName() { + return name; + } + + public static class Default extends TestSuite { + + public Default(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "default"); + } + + @Override + public List run(CardMngr cardManager) { + return null; + } + } + + public static class TestVectors extends TestSuite { + public TestVectors(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "test"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + + Map results = dataStore.getObjects(EC_KAResult.class, "test"); + for (EC_KAResult result : results.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, result.getCurve()); + if (cfg.namedCurve != null && !(result.getCurve().startsWith(cfg.namedCurve) || result.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getBits() != cfg.bits && !cfg.all) { + continue; + } + EC_Params onekey = dataStore.getObject(EC_Keypair.class, result.getOneKey()); + if (onekey == null) { + onekey = dataStore.getObject(EC_Key.Private.class, result.getOneKey()); + } + EC_Params otherkey = dataStore.getObject(EC_Keypair.class, result.getOtherKey()); + if (otherkey == null) { + otherkey = dataStore.getObject(EC_Key.Public.class, result.getOtherKey()); + } + if (onekey == null || otherkey == null) { + throw new IOException("Test vector keys couldn't be located."); + } + + tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + //tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_LOCAL, EC_Consts.CURVE_external, EC_Consts.PARAMETER_S, onekey.flatten(EC_Consts.PARAMETER_S)), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, EC_Consts.PARAMETER_W, otherkey.flatten(EC_Consts.PARAMETER_W)), Test.Result.SUCCESS)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_TRUE, EC_Consts.CORRUPTION_NONE, result.getKA()), Test.Result.SUCCESS, (command, response) -> { + Response.ECDH dh = (Response.ECDH) response; + if (!dh.successful() || !dh.hasSecret()) + return Test.Result.FAILURE; + if (!Util.compareBytes(dh.getSecret(), 0, result.getParam(0), 0, dh.secretLength())) { + return Test.Result.FAILURE; + } + return Test.Result.SUCCESS; + })); + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + + } + return super.run(cardManager); + } + } + + public static class NonPrime extends TestSuite { + + + public NonPrime(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "nonprime"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + Map keys = dataStore.getObjects(EC_Key.class, "nonprime"); + for (EC_Key key : keys.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if ((curve.getBits() == cfg.bits || cfg.all)) { + tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.ANY)); + tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.ANY)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_ECDH), Test.Result.FAILURE)); + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + } + return super.run(cardManager); + } + } + + public static class Invalid extends TestSuite { + + public Invalid(EC_Store dataStore, ECTester.Config cfg) { + super(dataStore, cfg, "invalid"); + } + + @Override + public List run(CardMngr cardManager) throws IOException, CardException { + Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); + for (EC_Key.Public key : pubkeys.values()) { + EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); + if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { + continue; + } + if (curve.getBits() != cfg.bits && !cfg.all) { + continue; + } + tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_BOTH), Test.Result.FAILURE)); + tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); + } + return super.run(cardManager); + } + } +} diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java index 41a7821..3a6a8ae 100644 --- a/src/cz/crcs/ectester/reader/Util.java +++ b/src/cz/crcs/ectester/reader/Util.java @@ -22,6 +22,25 @@ public class Util { array[offset] = (byte) ((value >> 8) & 0xFF); } + public static boolean compareBytes(byte[] one, int oneOffset, byte[] other, int otherOffset, int length) { + for (int i = 0; i < length; ++i) { + byte a = one[i + oneOffset]; + byte b = other[i + otherOffset]; + if (a != b) { + return false; + } + } + return true; + } + + public static boolean allValue(byte[] array, byte value) { + for (byte a : array) { + if (a != value) + return false; + } + return true; + } + public static byte[] hexToBytes(String hex) { return hexToBytes(hex, true); } @@ -103,6 +122,47 @@ public class Util { return out; } + public static String getSWSource(short sw) { + switch (sw) { + case ISO7816.SW_NO_ERROR: + case ISO7816.SW_APPLET_SELECT_FAILED: + case ISO7816.SW_BYTES_REMAINING_00: + case ISO7816.SW_CLA_NOT_SUPPORTED: + case ISO7816.SW_COMMAND_NOT_ALLOWED: + case ISO7816.SW_CONDITIONS_NOT_SATISFIED: + case ISO7816.SW_CORRECT_LENGTH_00: + case ISO7816.SW_DATA_INVALID: + case ISO7816.SW_FILE_FULL: + case ISO7816.SW_FILE_INVALID: + case ISO7816.SW_FILE_NOT_FOUND: + case ISO7816.SW_FUNC_NOT_SUPPORTED: + case ISO7816.SW_INCORRECT_P1P2: + case ISO7816.SW_INS_NOT_SUPPORTED: + case ISO7816.SW_LOGICAL_CHANNEL_NOT_SUPPORTED: + case ISO7816.SW_RECORD_NOT_FOUND: + case ISO7816.SW_SECURE_MESSAGING_NOT_SUPPORTED: + case ISO7816.SW_SECURITY_STATUS_NOT_SATISFIED: + case ISO7816.SW_UNKNOWN: + case ISO7816.SW_WARNING_STATE_UNCHANGED: + case ISO7816.SW_WRONG_DATA: + case ISO7816.SW_WRONG_LENGTH: + case ISO7816.SW_WRONG_P1P2: + return "ISO"; + case CryptoException.ILLEGAL_VALUE: + case CryptoException.UNINITIALIZED_KEY: + case CryptoException.NO_SUCH_ALGORITHM: + case CryptoException.INVALID_INIT: + case CryptoException.ILLEGAL_USE: + return "CryptoException"; + case ECTesterApplet.SW_SIG_VERIFY_FAIL: + case ECTesterApplet.SW_DH_DHC_MISMATCH: + case ECTesterApplet.SW_KEYPAIR_NULL: + return "ECTesterApplet"; + default: + return "?"; + } + } + public static String getSWString(short sw) { if (sw == ISO7816.SW_NO_ERROR) { return "OK\t(0x9000)"; @@ -193,6 +253,12 @@ public class Util { case ECTesterApplet.SW_SIG_VERIFY_FAIL: str = "SIG_VERIFY_FAIL"; break; + case ECTesterApplet.SW_DH_DHC_MISMATCH: + str = "DH_DHC_MISMATCH"; + break; + case ECTesterApplet.SW_KEYPAIR_NULL: + str = "KEYPAIR_NULL"; + break; default: str = "unknown"; break; @@ -229,9 +295,23 @@ public class Util { corrupt = "INFINITY"; break; default: - corrupt = "UNKNOWN"; + corrupt = "unknown"; break; } return corrupt; } + + public static String getKA(byte ka) { + String algo = ""; + if ((ka & EC_Consts.KA_ECDH) != 0) { + algo += "ECDH"; + } + if (ka == EC_Consts.KA_BOTH) { + algo += "+"; + } + if ((ka & EC_Consts.KA_ECDHC) != 0) { + algo += "ECDHC"; + } + return algo; + } } diff --git a/src/cz/crcs/ectester/reader/ec/EC_Curve.java b/src/cz/crcs/ectester/reader/ec/EC_Curve.java index 9b783ec..7d056a5 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Curve.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Curve.java @@ -7,25 +7,27 @@ import javacard.security.KeyPair; * @author Jan Jancar johny@neuromancer.sk */ public class EC_Curve extends EC_Params { - private short bits; private byte field; private String desc; /** - * * @param bits * @param field KeyPair.ALG_EC_FP or KeyPair.ALG_EC_F2M */ public EC_Curve(short bits, byte field) { super(field == KeyPair.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M); this.bits = bits; - this.field = field; } - public EC_Curve(short bits, byte field, String desc) { + public EC_Curve(String id, short bits, byte field) { this(bits, field); + this.id = id; + } + + public EC_Curve(String id, short bits, byte field, String desc) { + this(id, bits, field); this.desc = desc; } diff --git a/src/cz/crcs/ectester/reader/ec/EC_Data.java b/src/cz/crcs/ectester/reader/ec/EC_Data.java index c55b99d..49b5316 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Data.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Data.java @@ -13,11 +13,12 @@ import java.util.regex.Pattern; * @author Jan Jancar johny@neuromancer.sk */ public class EC_Data { - private static final Pattern hex = Pattern.compile("(0x|0X)?[a-fA-F\\d]+"); - + String id; int count; byte[][] data; + private static final Pattern HEX = Pattern.compile("(0x|0X)?[a-fA-F\\d]+"); + EC_Data() { } @@ -31,6 +32,20 @@ public class EC_Data { this.data = data; } + EC_Data(String id, int count) { + this(count); + this.id = id; + } + + EC_Data(String id, byte[][] data) { + this(data); + this.id = id; + } + + public String getId() { + return id; + } + public int getCount() { return count; } @@ -117,16 +132,29 @@ public class EC_Data { return false; } for (String param : data) { - if (!hex.matcher(param).matches()) { + if (!HEX.matcher(param).matches()) { return false; } } return readHex(data.toArray(new String[data.size()])); } - public boolean readBytes(byte[] data) { - //TODO - return false; + public boolean readBytes(byte[] bytes) { + int offset = 0; + for (int i = 0; i < count; i++) { + if (bytes.length - offset < 2) { + return false; + } + short paramLength = Util.getShort(bytes, offset); + offset += 2; + if (bytes.length < offset + paramLength) { + return false; + } + data[i] = new byte[paramLength]; + System.arraycopy(bytes, offset, data[i], 0, paramLength); + offset += paramLength; + } + return true; } public void writeCSV(OutputStream out) throws IOException { diff --git a/src/cz/crcs/ectester/reader/ec/EC_KAResult.java b/src/cz/crcs/ectester/reader/ec/EC_KAResult.java index 1385f12..9e92fd9 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_KAResult.java +++ b/src/cz/crcs/ectester/reader/ec/EC_KAResult.java @@ -1,6 +1,6 @@ package cz.crcs.ectester.reader.ec; -import cz.crcs.ectester.applet.EC_Consts; +import cz.crcs.ectester.reader.Util; /** * @author Jan Jancar johny@neuromancer.sk @@ -22,8 +22,13 @@ public class EC_KAResult extends EC_Data { this.otherKey = otherKey; } - public EC_KAResult(byte ka, String curve, String oneKey, String otherKey, String desc) { + public EC_KAResult(String id, byte ka, String curve, String oneKey, String otherKey) { this(ka, curve, oneKey, otherKey); + this.id = id; + } + + public EC_KAResult(String id, byte ka, String curve, String oneKey, String otherKey, String desc) { + this(id, ka, curve, oneKey, otherKey); this.desc = desc; } @@ -49,8 +54,8 @@ public class EC_KAResult extends EC_Data { @Override public String toString() { - String agreement = ka == EC_Consts.KA_ECDH ? "ECDH" : "ECDHC"; - return agreement + " result over " + curve + ", " + oneKey + " + " + otherKey + (desc == null ? "" : ": " + desc); + String algo = Util.getKA(ka); + return algo + " result over " + curve + ", " + oneKey + " + " + otherKey + (desc == null ? "" : ": " + desc); } } diff --git a/src/cz/crcs/ectester/reader/ec/EC_Key.java b/src/cz/crcs/ectester/reader/ec/EC_Key.java index ad846b8..85fd652 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Key.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Key.java @@ -20,6 +20,16 @@ public class EC_Key extends EC_Params { this.desc = desc; } + private EC_Key(String id, short mask, String curve) { + this(mask, curve); + this.id = id; + } + + private EC_Key(String id, short mask, String curve, String desc) { + this(mask, curve, desc); + this.id = id; + } + public String getCurve() { return curve; } diff --git a/src/cz/crcs/ectester/reader/ec/EC_Keypair.java b/src/cz/crcs/ectester/reader/ec/EC_Keypair.java index bf87e9e..4da7218 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Keypair.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Keypair.java @@ -6,7 +6,6 @@ import cz.crcs.ectester.applet.EC_Consts; * @author Jan Jancar johny@neuromancer.sk */ public class EC_Keypair extends EC_Params { - private String curve; private String desc; diff --git a/src/cz/crcs/ectester/reader/ec/EC_Params.java b/src/cz/crcs/ectester/reader/ec/EC_Params.java index 00747b1..cee9c16 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Params.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Params.java @@ -4,6 +4,7 @@ import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.reader.Util; import java.io.ByteArrayOutputStream; +import java.io.InputStream; import java.util.ArrayList; import java.util.List; @@ -25,6 +26,16 @@ public class EC_Params extends EC_Data { this.data = data; } + public EC_Params(String id, short params) { + this(params); + this.id = id; + } + + public EC_Params(String id, short params, byte[][] data) { + this(params, data); + this.id = id; + } + public short getParams() { return params; } @@ -67,8 +78,14 @@ public class EC_Params extends EC_Data { byte[] param = data[i]; if (masked == EC_Consts.PARAMETER_F2M) { //add m, e_1, e_2, e_3 - param = Util.concatenate(param, data[i + 1], data[i + 2], data[i + 3]); - if (param.length != 8) + param = Util.concatenate(param, data[i + 1]); + if (!Util.allValue(data[i + 2], (byte) 0)) { + param = Util.concatenate(param, data[i + 2]); + } + if (!Util.allValue(data[i + 3], (byte) 0)) { + param = Util.concatenate(param, data[i + 3]); + } + if (!(param.length == 4 || param.length == 8)) throw new RuntimeException("PARAMETER_F2M length is not 8.(should be)"); } if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) { @@ -112,9 +129,6 @@ public class EC_Params extends EC_Data { if (masked == EC_Consts.PARAMETER_F2M) { //split into m, e1, e2, e3 - if (param.length != 8) { - throw new RuntimeException("PARAMETER_F2M length is not 8.(should be)"); - } for (int i = 0; i < 4; ++i) { out.add(String.format("%04x", Util.getShort(param, i * 2))); } @@ -136,4 +150,8 @@ public class EC_Params extends EC_Data { return out.toArray(new String[out.size()]); } + @Override + public String toString() { + return String.join(",", expand()); + } } -- cgit v1.3.1 From 3aaead661e2b23b5e5811a3a06daed61db638a72 Mon Sep 17 00:00:00 2001 From: J08nY Date: Wed, 19 Apr 2017 21:56:39 +0200 Subject: Fix some test-vector tests, also test printing --- !uploader/ectester.cap | Bin 14353 -> 14586 bytes dist/ECTester.jar | Bin 322457 -> 323844 bytes src/cz/crcs/ectester/applet/ECKeyGenerator.java | 12 +++++------ src/cz/crcs/ectester/applet/ECKeyTester.java | 27 ++++++++++++++++++++---- src/cz/crcs/ectester/applet/ECTesterApplet.java | 8 ++++++- src/cz/crcs/ectester/applet/ECUtil.java | 24 ++++++++++++++++++--- src/cz/crcs/ectester/applet/EC_Consts.java | 1 + src/cz/crcs/ectester/data/EC_Store.java | 23 ++++++++++++++------ src/cz/crcs/ectester/data/schema.xsd | 4 ++++ src/cz/crcs/ectester/data/test/results.xml | 10 ++++----- src/cz/crcs/ectester/reader/ECTester.java | 5 +---- src/cz/crcs/ectester/reader/Response.java | 4 +--- src/cz/crcs/ectester/reader/TestSuite.java | 1 + src/cz/crcs/ectester/reader/Util.java | 18 ++++++++++++++-- 14 files changed, 103 insertions(+), 34 deletions(-) (limited to 'src/cz/crcs/ectester/data/EC_Store.java') diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap index 1e7235d..ea66c8f 100644 Binary files a/!uploader/ectester.cap and b/!uploader/ectester.cap differ diff --git a/dist/ECTester.jar b/dist/ECTester.jar index 58f44b9..adfa6d4 100644 Binary files a/dist/ECTester.jar and b/dist/ECTester.jar differ diff --git a/src/cz/crcs/ectester/applet/ECKeyGenerator.java b/src/cz/crcs/ectester/applet/ECKeyGenerator.java index a36bd0c..a602ab1 100644 --- a/src/cz/crcs/ectester/applet/ECKeyGenerator.java +++ b/src/cz/crcs/ectester/applet/ECKeyGenerator.java @@ -40,7 +40,7 @@ public class ECKeyGenerator { public short clearPair(KeyPair keypair, byte key) { try { - sw = ECUtil.nullCheck(keypair); + sw = ECUtil.keypairCheck(keypair); if ((key & EC_Consts.KEY_PUBLIC) != 0) keypair.getPublic().clearKey(); if ((key & EC_Consts.KEY_PRIVATE) != 0) keypair.getPrivate().clearKey(); } catch (CardRuntimeException ce) { @@ -55,7 +55,7 @@ public class ECKeyGenerator { */ public short generatePair(KeyPair keypair) { try { - sw = ECUtil.nullCheck(keypair); + sw = ECUtil.keypairCheck(keypair); keypair.genKeyPair(); } catch (CardRuntimeException ce) { sw = ce.getReason(); @@ -156,7 +156,7 @@ public class ECKeyGenerator { */ public short setParameter(KeyPair keypair, byte key, short param, byte[] data, short offset, short length) { try { - sw = ECUtil.nullCheck(keypair); + sw = ECUtil.keypairCheck(keypair); ECPublicKey ecPublicKey = (ECPublicKey) keypair.getPublic(); ECPrivateKey ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); @@ -281,7 +281,7 @@ public class ECKeyGenerator { public short exportParameter(KeyPair keypair, byte key, short param, byte[] outputBuffer, short outputOffset) { short length = 0; try { - sw = ECUtil.nullCheck(keypair); + sw = ECUtil.keypairCheck(keypair); ECPublicKey ecPublicKey = (ECPublicKey) keypair.getPublic(); ECPrivateKey ecPrivateKey = (ECPrivateKey) keypair.getPrivate(); @@ -390,8 +390,8 @@ public class ECKeyGenerator { */ public short copyCurve(KeyPair from, KeyPair to, short params, byte[] buffer, short offset) { try { - sw = ECUtil.nullCheck(from); - sw = ECUtil.nullCheck(to); + sw = ECUtil.keypairCheck(from); + sw = ECUtil.keypairCheck(to); short param = EC_Consts.PARAMETER_FP; while (param <= EC_Consts.PARAMETER_K) { diff --git a/src/cz/crcs/ectester/applet/ECKeyTester.java b/src/cz/crcs/ectester/applet/ECKeyTester.java index c4b58e0..aac4656 100644 --- a/src/cz/crcs/ectester/applet/ECKeyTester.java +++ b/src/cz/crcs/ectester/applet/ECKeyTester.java @@ -53,8 +53,9 @@ public class ECKeyTester { private short testKA(KeyAgreement ka, KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { short length = 0; try { - sw = ECUtil.nullCheck(privatePair); - sw = ECUtil.nullCheck(publicPair); + sw = ECUtil.kaCheck(ka); + sw = ECUtil.keypairCheck(privatePair); + sw = ECUtil.keypairCheck(publicPair); ka.init(privatePair.getPrivate()); short pubkeyLength = ((ECPublicKey) publicPair.getPublic()).getW(pubkeyBuffer, pubkeyOffset); @@ -113,7 +114,7 @@ public class ECKeyTester { * @param corruption * @return */ - public short testECDH_ECDHC(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { + public short testBOTH(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[] outputBuffer, short outputOffset, byte corruption) { short ecdhLength = testECDH(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); if (sw != ISO7816.SW_NO_ERROR) { return ecdhLength; @@ -130,6 +131,23 @@ public class ECKeyTester { } + /** + * + * @param privatePair + * @param publicPair + * @param pubkeyBuffer + * @param pubkeyOffset + * @param outputBuffer + * @param outputOffset + * @param corruption + * @return + */ + public short testANY(KeyPair privatePair, KeyPair publicPair, byte[] pubkeyBuffer, short pubkeyOffset, byte[]outputBuffer, short outputOffset, byte corruption) { + short ecdhLength = testECDH(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); + if (sw == ISO7816.SW_NO_ERROR) + return ecdhLength; + return testECDHC(privatePair, publicPair, pubkeyBuffer, pubkeyOffset, outputBuffer, outputOffset, corruption); + } /** * Uses {@code signKey} to sign data from {@code inputBuffer} at {@code inputOffset} with {@code inputOffset}. * Then checks for correct signature length. @@ -145,9 +163,10 @@ public class ECKeyTester { * @return signature length */ public short testECDSA(ECPrivateKey signKey, ECPublicKey verifyKey, byte[] inputBuffer, short inputOffset, short inputLength, byte[] sigBuffer, short sigOffset) { - sw = ISO7816.SW_NO_ERROR; short length = 0; try { + sw = ECUtil.signCheck(ecdsaSignature); + ecdsaSignature.init(signKey, Signature.MODE_SIGN); length = ecdsaSignature.sign(inputBuffer, inputOffset, inputLength, sigBuffer, sigOffset); diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index f802233..88d1b8c 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -65,6 +65,9 @@ public class ECTesterApplet extends Applet { public static final short SW_SIG_VERIFY_FAIL = (short) 0x0ee1; public static final short SW_DH_DHC_MISMATCH = (short) 0x0ee2; public static final short SW_KEYPAIR_NULL = (short) 0x0ee3; + public static final short SW_KA_NULL = (short) 0x0ee4; + public static final short SW_SIGNATURE_NULL = (short) 0x0ee5; + public static final short SW_OBJECT_NULL = (short) 0x0ee6; private static final short ARRAY_LENGTH = (short) 0xff; @@ -558,7 +561,10 @@ public class ECTesterApplet extends Applet { secretLength = keyTester.testECDHC(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); break; case EC_Consts.KA_BOTH: - secretLength = keyTester.testECDH_ECDHC(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); + secretLength = keyTester.testBOTH(priv, pub, ramArray, (short) 0, ramArray2, (short) 0, corruption); + break; + case EC_Consts.KA_ANY: + secretLength = keyTester.testANY(priv, pub, ramArray, (short) 0, ramArray2, (short)0, corruption); break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); diff --git a/src/cz/crcs/ectester/applet/ECUtil.java b/src/cz/crcs/ectester/applet/ECUtil.java index e7e4a8a..5d5c4d2 100644 --- a/src/cz/crcs/ectester/applet/ECUtil.java +++ b/src/cz/crcs/ectester/applet/ECUtil.java @@ -2,16 +2,34 @@ package cz.crcs.ectester.applet; import javacard.framework.ISO7816; import javacard.framework.ISOException; +import javacard.security.KeyAgreement; import javacard.security.KeyPair; +import javacard.security.Signature; /** * @author Jan Jancar johny@neuromancer.sk */ public class ECUtil { - static short nullCheck(KeyPair keyPair) { - if (keyPair == null) - ISOException.throwIt(ECTesterApplet.SW_KEYPAIR_NULL); + private static short nullCheck(Object obj, short sw) { + if (obj == null) + ISOException.throwIt(sw); return ISO7816.SW_NO_ERROR; } + + static short objCheck(Object obj) { + return nullCheck(obj, ECTesterApplet.SW_OBJECT_NULL); + } + + static short keypairCheck(KeyPair keyPair) { + return nullCheck(keyPair, ECTesterApplet.SW_KEYPAIR_NULL); + } + + static short kaCheck(KeyAgreement keyAgreement) { + return nullCheck(keyAgreement, ECTesterApplet.SW_KA_NULL); + } + + static short signCheck(Signature signature) { + return nullCheck(signature, ECTesterApplet.SW_SIGNATURE_NULL); + } } diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index 534d552..1334541 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -64,6 +64,7 @@ public class EC_Consts { public static final byte KA_ECDH = 0x01; public static final byte KA_ECDHC = 0x02; public static final byte KA_BOTH = KA_ECDH | KA_ECDHC; + public static final byte KA_ANY = 0x04; public static RandomData randomData = null; diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index ccd3586..906eb8d 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -227,11 +227,22 @@ public class EC_Store { descs = descc.item(0).getTextContent(); } - byte kab; - if (ka.getTextContent().equals("DH")) { - kab = EC_Consts.KA_ECDH; - } else { - kab = EC_Consts.KA_ECDHC; + byte kab = EC_Consts.KA_ANY; + switch (ka.getTextContent()) { + case "DH": + case "ECDH": + kab = EC_Consts.KA_ECDH; + break; + case "DHC": + case "ECDHC": + kab = EC_Consts.KA_ECDHC; + break; + case "ANY": + kab = EC_Consts.KA_ANY; + break; + case "BOTH": + kab = EC_Consts.KA_BOTH; + break; } EC_KAResult kaResult = new EC_KAResult(id.getTextContent(), kab, curve.getTextContent(), onekey.getTextContent(), otherkey.getTextContent(), descs); @@ -254,7 +265,7 @@ public class EC_Store { } private EC_Params parseKeylike(String dir, Element elem) throws SAXException, IOException { - Node file = elem.getElementsByTagName("file").item(0); + Node id = elem.getElementsByTagName("id").item(0); Node curve = elem.getElementsByTagName("curve").item(0); NodeList desc = elem.getElementsByTagName("desc"); diff --git a/src/cz/crcs/ectester/data/schema.xsd b/src/cz/crcs/ectester/data/schema.xsd index 33b9acd..2fe7892 100644 --- a/src/cz/crcs/ectester/data/schema.xsd +++ b/src/cz/crcs/ectester/data/schema.xsd @@ -61,7 +61,11 @@ + + + + diff --git a/src/cz/crcs/ectester/data/test/results.xml b/src/cz/crcs/ectester/data/test/results.xml index e382cd4..1146500 100644 --- a/src/cz/crcs/ectester/data/test/results.xml +++ b/src/cz/crcs/ectester/data/test/results.xml @@ -133,7 +133,7 @@ p192-dhc - DHC + ANY nist/p192-dhc-sha1.csv nist/P-192 test/p192-A @@ -141,7 +141,7 @@ p224-dhc - DHC + ANY nist/p224-dhc-sha1.csv nist/P-224 test/p224-A @@ -149,7 +149,7 @@ p256-dhc - DHC + ANY nist/p256-dhc-sha1.csv nist/P-256 test/p256-A @@ -157,7 +157,7 @@ p384-dhc - DHC + ANY nist/p384-dhc-sha1.csv nist/P-384 test/p384-A @@ -165,7 +165,7 @@ p521-dhc - DHC + ANY nist/p521-dhc-sha1.csv nist/P-521 test/p521-A diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 8afda17..9191b70 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -471,10 +471,7 @@ public class ECTester { List test = Command.sendAll(commands); if (suite != null) { - List tests = suite.run(cardManager); - for (Test t : tests) { - System.out.println(t); - } + suite.run(cardManager); } systemOutLogger.println(Response.toString(test, cfg.testSuite)); diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java index e5b8c1c..89dce9c 100644 --- a/src/cz/crcs/ectester/reader/Response.java +++ b/src/cz/crcs/ectester/reader/Response.java @@ -140,9 +140,7 @@ public abstract class Response { out.append(prefix); String message = r.toString(); - String full = r.toString(message); - - out.append(full); + out.append(message); if (i < responses.size() - 1) { out.append("\n"); } diff --git a/src/cz/crcs/ectester/reader/TestSuite.java b/src/cz/crcs/ectester/reader/TestSuite.java index 892e853..56e0a4a 100644 --- a/src/cz/crcs/ectester/reader/TestSuite.java +++ b/src/cz/crcs/ectester/reader/TestSuite.java @@ -63,6 +63,7 @@ public abstract class TestSuite { } public static class TestVectors extends TestSuite { + public TestVectors(EC_Store dataStore, ECTester.Config cfg) { super(dataStore, cfg, "test"); } diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java index 3a6a8ae..6fe3b8e 100644 --- a/src/cz/crcs/ectester/reader/Util.java +++ b/src/cz/crcs/ectester/reader/Util.java @@ -157,6 +157,9 @@ public class Util { case ECTesterApplet.SW_SIG_VERIFY_FAIL: case ECTesterApplet.SW_DH_DHC_MISMATCH: case ECTesterApplet.SW_KEYPAIR_NULL: + case ECTesterApplet.SW_KA_NULL: + case ECTesterApplet.SW_SIGNATURE_NULL: + case ECTesterApplet.SW_OBJECT_NULL: return "ECTesterApplet"; default: return "?"; @@ -259,6 +262,15 @@ public class Util { case ECTesterApplet.SW_KEYPAIR_NULL: str = "KEYPAIR_NULL"; break; + case ECTesterApplet.SW_KA_NULL: + str = "KA_NULL"; + break; + case ECTesterApplet.SW_SIGNATURE_NULL: + str = "SIGNATURE_NULL"; + break; + case ECTesterApplet.SW_OBJECT_NULL: + str = "OBJECT_NULL"; + break; default: str = "unknown"; break; @@ -303,13 +315,15 @@ public class Util { public static String getKA(byte ka) { String algo = ""; - if ((ka & EC_Consts.KA_ECDH) != 0) { + if ((ka & EC_Consts.KA_ECDH) != 0 || ka == EC_Consts.KA_ANY) { algo += "ECDH"; } if (ka == EC_Consts.KA_BOTH) { algo += "+"; + } else if (ka == EC_Consts.KA_ANY) { + algo += "/"; } - if ((ka & EC_Consts.KA_ECDHC) != 0) { + if ((ka & EC_Consts.KA_ECDHC) != 0 || ka == EC_Consts.KA_ANY) { algo += "ECDHC"; } return algo; -- cgit v1.3.1 From cc4e981402369ce14150d3949e0b02905865c37f Mon Sep 17 00:00:00 2001 From: J08nY Date: Mon, 1 May 2017 22:30:34 +0200 Subject: Reworked invalid curve testing, added generated anomalous curves --- !uploader/ectester.cap | Bin 14586 -> 14675 bytes FORMAT.md | 7 ++- TESTS.md | 4 +- dist/ECTester.jar | Bin 323844 -> 343742 bytes src/cz/crcs/ectester/applet/EC_Consts.java | 8 +-- src/cz/crcs/ectester/data/EC_Store.java | 16 ++---- .../crcs/ectester/data/anomalous/anomalous112.csv | 1 + .../crcs/ectester/data/anomalous/anomalous128.csv | 1 + .../crcs/ectester/data/anomalous/anomalous160.csv | 1 + .../crcs/ectester/data/anomalous/anomalous192.csv | 1 + .../crcs/ectester/data/anomalous/anomalous224.csv | 1 + .../crcs/ectester/data/anomalous/anomalous256.csv | 1 + .../crcs/ectester/data/anomalous/anomalous320.csv | 1 + .../crcs/ectester/data/anomalous/anomalous384.csv | 1 + .../crcs/ectester/data/anomalous/anomalous512.csv | 1 + .../crcs/ectester/data/anomalous/anomalous521.csv | 1 + src/cz/crcs/ectester/data/anomalous/curves.xml | 60 +++++++++++++++++++++ .../crcs/ectester/data/invalid/brainpool/keys.xml | 2 +- src/cz/crcs/ectester/data/invalid/nist/keys.xml | 6 --- src/cz/crcs/ectester/data/invalid/secg/keys.xml | 7 +-- src/cz/crcs/ectester/reader/TestSuite.java | 21 +++++--- src/cz/crcs/ectester/reader/ec/EC_Category.java | 12 +++++ src/cz/crcs/ectester/reader/ec/EC_Data.java | 36 +++++++++++-- src/cz/crcs/ectester/reader/ec/EC_Params.java | 1 - 24 files changed, 141 insertions(+), 49 deletions(-) create mode 100644 src/cz/crcs/ectester/data/anomalous/anomalous112.csv create mode 100644 src/cz/crcs/ectester/data/anomalous/anomalous128.csv create mode 100644 src/cz/crcs/ectester/data/anomalous/anomalous160.csv create mode 100644 src/cz/crcs/ectester/data/anomalous/anomalous192.csv create mode 100644 src/cz/crcs/ectester/data/anomalous/anomalous224.csv create mode 100644 src/cz/crcs/ectester/data/anomalous/anomalous256.csv create mode 100644 src/cz/crcs/ectester/data/anomalous/anomalous320.csv create mode 100644 src/cz/crcs/ectester/data/anomalous/anomalous384.csv create mode 100644 src/cz/crcs/ectester/data/anomalous/anomalous512.csv create mode 100644 src/cz/crcs/ectester/data/anomalous/anomalous521.csv (limited to 'src/cz/crcs/ectester/data/EC_Store.java') diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap index ea66c8f..0d50b57 100644 Binary files a/!uploader/ectester.cap and b/!uploader/ectester.cap differ diff --git a/FORMAT.md b/FORMAT.md index a753c75..b68db39 100644 --- a/FORMAT.md +++ b/FORMAT.md @@ -5,7 +5,6 @@ CSV based, little-endian hexadecimal values. ### Prime field `p,a,b,gx,gy,n,h` - ### Binary field `m,e1,e2,e3,a,b,gx,gy,n,h` @@ -22,9 +21,9 @@ CSV based, little-endian hexadecimal values. # Notation - `p` - prime F_p - `m` - binary field exponent F_2^m - - e1 - largest exponent of the field polynomial - - e2 - middle exponenet of the field polynomial, or `0000` if field poly is a trinomial - - e3 - smallest exponent (except zero) of the field polynomial, or `0000` if field poly is a trinomial + - `e1` - largest exponent of the field polynomial + - `e2` - middle exponenet of the field polynomial, or `0000` if field poly is a trinomial + - `e3` - smallest exponent (except zero) of the field polynomial, or `0000` if field poly is a trinomial - `a` - a parameter in short Weierstrass curve equation - `b` - b parameter in short Weierstrass curve equation - `gx` - x coordinate of the curve base-point g diff --git a/TESTS.md b/TESTS.md index 710a04b..1e4f5ca 100644 --- a/TESTS.md +++ b/TESTS.md @@ -77,6 +77,4 @@ For example: ```bash java -jar ECTester.jar -t invalid -nc nist -a -fp ``` -tests using all(`-a`), prime-field(`-fp`) NIST curves and pregenerated *invalid* public keys for these curves. - -**TODO: CURRENTLY NOT IMPLEMENTED** \ No newline at end of file +tests using all(`-a`), prime-field(`-fp`) NIST curves and pregenerated *invalid* public keys for these curves. \ No newline at end of file diff --git a/dist/ECTester.jar b/dist/ECTester.jar index adfa6d4..d764a7b 100644 Binary files a/dist/ECTester.jar and b/dist/ECTester.jar differ diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index f749af5..d970542 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -1249,7 +1249,7 @@ public class EC_Consts { while (corruptionMask <= CORRUPTION_COMPRESS) { short corruptionPart = (short) (corruptionMask & corruption); switch (corruptionPart) { - case 0: + case (short) 0: break; case CORRUPTION_FIXED: if (length >= 1) { @@ -1301,14 +1301,14 @@ public class EC_Consts { length = 1; break; case CORRUPTION_COMPRESS: - if (length % 2 != 1) { + + if ((short) (length % 2) != 1) { // an uncompressed point should have odd length (since 1 byte type, + 2 * coords) ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); } - short half = (short) ((length - 1) / 2); + short half = (short) ((short)(length - 1) / 2); byte yLSB = buffer[(short) (offset + length)]; byte yBit = (byte) (yLSB & 0x01); - if (yBit == 1) { buffer[offset] = 3; } else { diff --git a/src/cz/crcs/ectester/data/EC_Store.java b/src/cz/crcs/ectester/data/EC_Store.java index 906eb8d..94eb011 100644 --- a/src/cz/crcs/ectester/data/EC_Store.java +++ b/src/cz/crcs/ectester/data/EC_Store.java @@ -178,21 +178,11 @@ public class EC_Store { if (direct instanceof Element) { Element elem = (Element) direct; - NodeList childs = elem.getChildNodes(); - String id = null; - for (int j = 0; j < childs.getLength(); ++j) { - Node child = childs.item(j); - if (child instanceof Element) { - Element childElem = (Element) child; - if (childElem.getTagName().equals("id")) { - id = childElem.getTextContent(); - break; - } - } - } - if (id == null) { + NodeList ids = elem.getElementsByTagName("id"); + if (ids.getLength() != 1) { throw new SAXException("key no id?"); } + String id = ids.item(0).getTextContent(); EC_Params result = parseKeylike(dir, elem); diff --git a/src/cz/crcs/ectester/data/anomalous/anomalous112.csv b/src/cz/crcs/ectester/data/anomalous/anomalous112.csv new file mode 100644 index 0000000..6711b71 --- /dev/null +++ b/src/cz/crcs/ectester/data/anomalous/anomalous112.csv @@ -0,0 +1 @@ +0xa2d803b165bdb58f5282cd95ae0f,0x5de65e36c0ec85d5908cdce4c978,0x71801c406b1541de2f9e96b0dc55,0x8073044c904d588dde72e51009c8,0x9dda8938ea7144df116677ae5d93,0xa2d803b165bdb58f5282cd95ae0f,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/anomalous/anomalous128.csv b/src/cz/crcs/ectester/data/anomalous/anomalous128.csv new file mode 100644 index 0000000..2dcf172 --- /dev/null +++ b/src/cz/crcs/ectester/data/anomalous/anomalous128.csv @@ -0,0 +1 @@ +0xe617383c9d207ab3a6ea5e83ab21b241,0x6ff1fa365aafec734e23d52b50edd6ba,0x1813525c76d5183ce9053236ab4d5699,0x27b56a1b55ed41fd2d25b8e7680c65fb,0xcd4b59a0a7814bf14ea6deb5d40d5c9,0xe617383c9d207ab3a6ea5e83ab21b241,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/anomalous/anomalous160.csv b/src/cz/crcs/ectester/data/anomalous/anomalous160.csv new file mode 100644 index 0000000..bc50f6d --- /dev/null +++ b/src/cz/crcs/ectester/data/anomalous/anomalous160.csv @@ -0,0 +1 @@ +0xc1980258d215dfa641705a68dec6398f69cfb7dd,0x539387a1d2901a0d0aa82e18d31e6b6e45c725c2,0x908c9541398e59bcb0679dcfc1d5e3165a4228e6,0x781ad9264fab66e82a9661efe5cfb7ae963ee2bb,0x8dc2f7237e152c3287658738986d1cce2397e8a6,0xc1980258d215dfa641705a68dec6398f69cfb7dd,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/anomalous/anomalous192.csv b/src/cz/crcs/ectester/data/anomalous/anomalous192.csv new file mode 100644 index 0000000..35a5c07 --- /dev/null +++ b/src/cz/crcs/ectester/data/anomalous/anomalous192.csv @@ -0,0 +1 @@ +0x856728e701179222ea33faa5c3634dc2220f7f8a9a6f1215,0x35db21b91c3044ca550379891307606e9d6b81928a9f09eb,0x80839b7e6774fa9964008017048de3cbaa966a501cb1a5f1,0x78a3df2e57554cd64ac3723d0329c9582a80aac3316ea732,0x7150cc7660022e4b9f4460bc5afbbfa9a11eeb7a40ae5ae6,0x856728e701179222ea33faa5c3634dc2220f7f8a9a6f1215,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/anomalous/anomalous224.csv b/src/cz/crcs/ectester/data/anomalous/anomalous224.csv new file mode 100644 index 0000000..bf24496 --- /dev/null +++ b/src/cz/crcs/ectester/data/anomalous/anomalous224.csv @@ -0,0 +1 @@ +0xed0377332aa665c2d0eaf466a536ddd7d478e66f573eeb8b0973b7a3,0x7fe9c52bb4892ac826d50355f24b6bfb0f4165d2f1dd550e231fa5fb,0xa0b20244694978a19e1910718b57b990542b5fb95c33be692f80e276,0x8225e0f325d74d4b4a729749ef24a0a3edd9c53c7e0bc3cb2cc87466,0x6dfacd713b83267a78a9c2bb0596cc12ddbe0bdfe4008daa277a95b3,0xed0377332aa665c2d0eaf466a536ddd7d478e66f573eeb8b0973b7a3,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/anomalous/anomalous256.csv b/src/cz/crcs/ectester/data/anomalous/anomalous256.csv new file mode 100644 index 0000000..24d7454 --- /dev/null +++ b/src/cz/crcs/ectester/data/anomalous/anomalous256.csv @@ -0,0 +1 @@ +0x8a17b15dd963f53ed8253cb6dd2644819db58d1b1a70a8cf14a6f7ad5c61b7a9,0x7a6c106d27dea9b6c826b5aa585f3ed2dd17b23c8287f0a8de0364baba01b7d7,0x2d42716d40e73c4fe01de111ad155a84350613d8580379b764d207a87242a884,0x3489a3d1ba3181626a6f52badafe4ed68c07efa6ebcff001d78e5c770c3189ba,0x883a994b4dfea1a1fc2b7bffa46a3336e64d5e19bc81e5991bc2a821a2aaf9b1,0x8a17b15dd963f53ed8253cb6dd2644819db58d1b1a70a8cf14a6f7ad5c61b7a9,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/anomalous/anomalous320.csv b/src/cz/crcs/ectester/data/anomalous/anomalous320.csv new file mode 100644 index 0000000..96e98e5 --- /dev/null +++ b/src/cz/crcs/ectester/data/anomalous/anomalous320.csv @@ -0,0 +1 @@ +0xac418bcddf4be30b913032dab704fe4b24cf2fec47b36a0463ab5f7e1ab9985e38f4551408f82439,0x9e7dba38d327f78e918193af78700ebab0deecfbd884995dbbbed047ecab7c55c7d3d5fbb6fafd38,0x5eb3a1f211d52c0eb92e47bd151e05d471da8eb18a1ebe0cd4d6e99c50237c56230f69d517188e0b,0x88fb80cc5aa7dc8dfdd8f275d1c5ef9fe0680e3d5cabd08ac22407e3935ac0a15ecfe6690ee37783,0x44810f747b41aedc20a2d022d35a29391522c3843cb36bf73840b56ccca93626a336ab81f613010,0xac418bcddf4be30b913032dab704fe4b24cf2fec47b36a0463ab5f7e1ab9985e38f4551408f82439,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/anomalous/anomalous384.csv b/src/cz/crcs/ectester/data/anomalous/anomalous384.csv new file mode 100644 index 0000000..6034b4a --- /dev/null +++ b/src/cz/crcs/ectester/data/anomalous/anomalous384.csv @@ -0,0 +1 @@ +0xfddbf8939f25d39bb926c45a1d3eb5b45ef9af276821fbefbee51174464cdd8b90181d7a111275cf394dd6015589d827,0x7c80b4961ae672c74b5db842293ad567bed30efd6f693143f9bb3d3e1e7587e5b379c36188d3e19c8336a3025f66deb7,0x7aa96bf076ddf659bdcf4c0f2eea1ed80017ead209cc21931e6156171dd8b423edeeab77cc01b30c979993756d398ebd,0xfcf723a7b33621ab6af8e42cf3e5dc7b3143f1df037e82708acfad0fc953f797f31d38e2c651781f5f70aeb0b8abd165,0x259d66287d38573dcc4fa3260e1c0fe6d93c1ed739f91deae1a89d14109f027dd972cba62406f7fca1d0082634f08b2c,0xfddbf8939f25d39bb926c45a1d3eb5b45ef9af276821fbefbee51174464cdd8b90181d7a111275cf394dd6015589d827,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/anomalous/anomalous512.csv b/src/cz/crcs/ectester/data/anomalous/anomalous512.csv new file mode 100644 index 0000000..ed7ee5b --- /dev/null +++ b/src/cz/crcs/ectester/data/anomalous/anomalous512.csv @@ -0,0 +1 @@ +0x83503ecb98832514b71d0e9fcfea296a3a8ad4f58661c1d997823213343b1ffb7533cb0d589485fd45527d7af1f3896ee0efc67d008b24d5e6fae51edca998f1,0x3ee9f2b4493b7572e5becbe781655ef6a462d20051cc526d5ae89b45a145eb2b31006ac9cc62fd549d370eccd1cbb4945afada0a258cf6c0505814cbbdf4c1dd,0x7fb55135325e108e20914f6558af59dbe328a04629c576efc86184fdb48402a2968f2eb2d9fa6bc6e19f0ca41fb99984f1278197b3c901c20d9f3fa0a5242952,0x52cd825e32cbc4da7f927b5f7a36f15c4d7b42cb03d426654f8f3526711336f1d18dbe4c8ca8843539d3f416de4039c9fe030d30cba1b292fec155dedf8e5c5b,0x39258758239cde1ff6cf41d2b219585ed533c4a042c7714c2d14247e853668839979e60f82255c0657356912a4113e148efbaec32ecb2b4f489f637d88b868da,0x83503ecb98832514b71d0e9fcfea296a3a8ad4f58661c1d997823213343b1ffb7533cb0d589485fd45527d7af1f3896ee0efc67d008b24d5e6fae51edca998f1,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/anomalous/anomalous521.csv b/src/cz/crcs/ectester/data/anomalous/anomalous521.csv new file mode 100644 index 0000000..e0d935e --- /dev/null +++ b/src/cz/crcs/ectester/data/anomalous/anomalous521.csv @@ -0,0 +1 @@ +0x1dcf4a3c1f9ac39550c7eb7bfb1dd6c345658a277d888d9b23273aac2914cde52ee7e8f424767d62fd266d46491d805564f32919b265d784941d61eefa43da0501f,0x14fb5e18b58eaa6e879edb5542e5c1e1140a0cb1df41c49b5d4be6b7abdaf2afd7a22b8bc95711dd9196968677a1edf9a99e60db654ad62755904ee34b592db2838,0x1c543ff6f595aaf4651f0315c95b1f433b9aa3b5be69f300d4a7f4441bb3331781fbc9527b62fe60d4eb7aaedb2cd50ea4a8ad70ab2935bf8e129cf6ffc30ec027c,0x11fd1c6612169a69250632396ec192b97490c6af601f2d0b2ffad81a2a8772c8f8c0ac6cf273335aed6852fda2a3fb0b32a366ad19662513751412d9d2e168c144d,0x11c894ae2c3647cae6ca89b7c090bf19a52781bddbebb2a21b4123cf16445f7bca20aa1fac5a0228c37e8b89c974c5a659810d29afa96f48cdca6ba77baa88fbac,0x1dcf4a3c1f9ac39550c7eb7bfb1dd6c345658a277d888d9b23273aac2914cde52ee7e8f424767d62fd266d46491d805564f32919b265d784941d61eefa43da0501f,0x1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/anomalous/curves.xml b/src/cz/crcs/ectester/data/anomalous/curves.xml index b0b9b02..5486f35 100644 --- a/src/cz/crcs/ectester/data/anomalous/curves.xml +++ b/src/cz/crcs/ectester/data/anomalous/curves.xml @@ -29,4 +29,64 @@ miyaji128b2.csv Second curve in the "Proposed scheme B" section of Atsuko Miyaji's paper. + + anomalous112 + 112 + prime + anomalous112.csv + + + anomalous128 + 128 + prime + anomalous128.csv + + + anomalous160 + 160 + prime + anomalous160.csv + + + anomalous192 + 192 + prime + anomalous192.csv + + + anomalous224 + 224 + prime + anomalous224.csv + + + anomalous256 + 256 + prime + anomalous256.csv + + + anomalous320 + 320 + prime + anomalous320.csv + + + anomalous384 + 384 + prime + anomalous384.csv + + + anomalous512 + 512 + prime + anomalous512.csv + + + anomalous521 + 521 + prime + anomalous521.csv + diff --git a/src/cz/crcs/ectester/data/invalid/brainpool/keys.xml b/src/cz/crcs/ectester/data/invalid/brainpool/keys.xml index 985fab6..3823658 100644 --- a/src/cz/crcs/ectester/data/invalid/brainpool/keys.xml +++ b/src/cz/crcs/ectester/data/invalid/brainpool/keys.xml @@ -1,7 +1,7 @@ 160r1-1 - 0xc4d7ddb433381eeb0c62b502b4059e616caf6fcf,0x0 + 0xc4d7ddb433381eeb0c62b502b4059e616caf6fcf,0x0000000000000000000000000000000000000000 brainpool/brainpoolP160r1 invalid order = 2 diff --git a/src/cz/crcs/ectester/data/invalid/nist/keys.xml b/src/cz/crcs/ectester/data/invalid/nist/keys.xml index 5427845..e69de29 100644 --- a/src/cz/crcs/ectester/data/invalid/nist/keys.xml +++ b/src/cz/crcs/ectester/data/invalid/nist/keys.xml @@ -1,6 +0,0 @@ - - 160r1-1 - 0xc4d7ddb433381eeb0c62b502b4059e616caf6fcf,0x0 - brainpool/brainpoolP160r1 - order = 2 - diff --git a/src/cz/crcs/ectester/data/invalid/secg/keys.xml b/src/cz/crcs/ectester/data/invalid/secg/keys.xml index 5427845..8b13789 100644 --- a/src/cz/crcs/ectester/data/invalid/secg/keys.xml +++ b/src/cz/crcs/ectester/data/invalid/secg/keys.xml @@ -1,6 +1 @@ - - 160r1-1 - 0xc4d7ddb433381eeb0c62b502b4059e616caf6fcf,0x0 - brainpool/brainpoolP160r1 - order = 2 - + diff --git a/src/cz/crcs/ectester/reader/TestSuite.java b/src/cz/crcs/ectester/reader/TestSuite.java index c2ccb54..e4d7dd6 100644 --- a/src/cz/crcs/ectester/reader/TestSuite.java +++ b/src/cz/crcs/ectester/reader/TestSuite.java @@ -8,10 +8,7 @@ import javacard.security.KeyPair; import javax.smartcardio.CardException; import java.io.IOException; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; +import java.util.*; /** * @author Jan Jancar johny@neuromancer.sk @@ -250,6 +247,7 @@ public abstract class TestSuite { * Try ECDH with invalid public keys of increasing (or decreasing) order. */ Map pubkeys = dataStore.getObjects(EC_Key.Public.class, "invalid"); + Map> curves = new HashMap<>(); for (EC_Key.Public key : pubkeys.values()) { EC_Curve curve = dataStore.getObject(EC_Curve.class, key.getCurve()); if (cfg.namedCurve != null && !(key.getCurve().startsWith(cfg.namedCurve) || key.getCurve().equals(cfg.namedCurve))) { @@ -258,13 +256,24 @@ public abstract class TestSuite { if (curve.getBits() != cfg.bits && !cfg.all) { continue; } + List keys = curves.getOrDefault(curve, new LinkedList<>()); + keys.add(key); + curves.putIfAbsent(curve, keys); + } + for (Map.Entry> e : curves.entrySet()) { + EC_Curve curve = e.getKey(); + List keys = e.getValue(); + tests.add(new Test(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), curve.getField()), Test.Result.SUCCESS)); tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), curve.flatten()), Test.Result.SUCCESS)); tests.add(new Test(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL), Test.Result.SUCCESS)); - tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, key.getParams(), key.flatten()), Test.Result.ANY)); - tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_BOTH), Test.Result.FAILURE)); + for (EC_Key.Public pub : keys) { + tests.add(new Test(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_REMOTE, EC_Consts.CURVE_external, pub.getParams(), pub.flatten()), Test.Result.ANY)); + tests.add(new Test(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_FALSE, EC_Consts.CORRUPTION_NONE, EC_Consts.KA_BOTH), Test.Result.FAILURE)); + } tests.add(new Test(new Command.Cleanup(cardManager), Test.Result.ANY)); } + return super.run(cardManager); } } diff --git a/src/cz/crcs/ectester/reader/ec/EC_Category.java b/src/cz/crcs/ectester/reader/ec/EC_Category.java index a0c8755..97dd1b4 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Category.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Category.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.reader.ec; import java.util.Collections; import java.util.Map; +import java.util.Objects; import java.util.TreeMap; /** @@ -125,4 +126,15 @@ public class EC_Category { } return out.toString(); } + + @Override + public boolean equals(Object obj) { + return obj instanceof EC_Category && Objects.equals(this.name, ((EC_Category) obj).name); + } + + @Override + public int hashCode() { + return this.name.hashCode() ^ this.directory.hashCode(); + } + } diff --git a/src/cz/crcs/ectester/reader/ec/EC_Data.java b/src/cz/crcs/ectester/reader/ec/EC_Data.java index 5197665..9dcbbe0 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Data.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Data.java @@ -3,16 +3,13 @@ package cz.crcs.ectester.reader.ec; import cz.crcs.ectester.reader.Util; import java.io.*; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Scanner; +import java.util.*; import java.util.regex.Pattern; /** * @author Jan Jancar johny@neuromancer.sk */ -public class EC_Data { +public abstract class EC_Data { String id; int count; byte[][] data; @@ -167,4 +164,33 @@ public class EC_Data { public String toString() { return String.join(",", expand()); } + + @Override + public boolean equals(Object obj) { + if (obj instanceof EC_Data) { + EC_Data other = (EC_Data) obj; + if (this.id != null || other.id != null) { + return Objects.equals(this.id, other.id); + } + + if (this.count != other.count) + return false; + for (int i = 0; i < this.count; ++i) { + if (!Arrays.equals(this.data[i], other.data[i])) { + return false; + } + } + return true; + } else { + return false; + } + } + + @Override + public int hashCode() { + if (this.id != null) { + return this.id.hashCode(); + } + return Arrays.deepHashCode(this.data); + } } diff --git a/src/cz/crcs/ectester/reader/ec/EC_Params.java b/src/cz/crcs/ectester/reader/ec/EC_Params.java index 7192b61..ea2e633 100644 --- a/src/cz/crcs/ectester/reader/ec/EC_Params.java +++ b/src/cz/crcs/ectester/reader/ec/EC_Params.java @@ -4,7 +4,6 @@ import cz.crcs.ectester.applet.EC_Consts; import cz.crcs.ectester.reader.Util; import java.io.ByteArrayOutputStream; -import java.io.InputStream; import java.util.ArrayList; import java.util.List; -- cgit v1.3.1