From 4debe5adb4bb486f488878e348ee7bcf386c43f2 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 17 Jan 2017 02:55:31 +0100 Subject: major changes, ECTester rewrite, moved to valid package reader: ECTester, mostly rewritten SimpleAPDU - communication with applet now done through simpler instructions: allocate, set, generate, ecdh, ecdsa - moved to a valid Java package dir cz.crcs.ectester - SimpleAPDU: renamed to ECTester - CardMngr: seamlessly supports simulation vs real card - DirtyLogger: takes a nullable String and creates file - ECTester: currently only supports key generation, curve testing under way - supports external curve setting, example files in data package - tests can be done through files, to achieve a more modular approach - Util: static utility class - ParamReader: reads curve domain parameters and keys from simple csv-like human-readable files with hex strings applet: ECTesterApplet, rewrite of SimpleECCApplet - more granularity in instructions - moved complexity over to the reader side - ECKeyGenerator: now a class that takes KeyPair as param - ECKeyTester: now a class that takes KeyPair as param - EC_Consts: removed ecsp curves(now done externally), removed unused methods - ECTesterApplet: currently only tested instructions are: allocate, set, generate data: contains several curve and pubkey files in format supported by ParamReader - Prime field curves: p,a,b,gx,gy,r,k - Binary field curves: e1,a,b,gx,gy,r,k or e1,e2,e3,a,b,gx,gy,r,k - Public key: wx,wy - Private key: s - Key: wx,wy,s - all values are hex strings --- src/cz/crcs/ectester/reader/CardMngr.java | 289 ++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 src/cz/crcs/ectester/reader/CardMngr.java (limited to 'src/cz/crcs/ectester/reader/CardMngr.java') diff --git a/src/cz/crcs/ectester/reader/CardMngr.java b/src/cz/crcs/ectester/reader/CardMngr.java new file mode 100644 index 0000000..d7a5c5f --- /dev/null +++ b/src/cz/crcs/ectester/reader/CardMngr.java @@ -0,0 +1,289 @@ +package cz.crcs.ectester.reader; + +import com.licel.jcardsim.io.CAD; +import com.licel.jcardsim.io.JavaxSmartCardInterface; +import java.util.List; +import java.util.Scanner; +import javacard.framework.AID; + +import javax.smartcardio.*; + +/** + * @author Petr Svenda petr@svenda.com + * @author Jan Jancar johny@neuromancer.sk + */ +public class CardMngr { + private CardTerminal m_terminal = null; + private CardChannel m_channel = null; + private Card m_card = null; + + // Simulator related attributes + private CAD m_cad = null; + private JavaxSmartCardInterface m_simulator = null; + + private boolean simulate = false; + + private final byte selectCM[] = { + (byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0xa0, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x18, (byte) 0x43, (byte) 0x4d}; + + public static final byte OFFSET_CLA = 0x00; + public static final byte OFFSET_INS = 0x01; + public static final byte OFFSET_P1 = 0x02; + public static final byte OFFSET_P2 = 0x03; + public static final byte OFFSET_LC = 0x04; + public static final byte OFFSET_DATA = 0x05; + public static final byte HEADER_LENGTH = 0x05; + + public static final short DATA_RECORD_LENGTH = (short) 0x80; // 128B per record + public static final short NUMBER_OF_RECORDS = (short) 0x0a; // 10 records + + public CardMngr() { + this(false); + } + + public CardMngr(boolean simulate) { + this.simulate = simulate; + } + + public boolean connectToCard() throws CardException { + if (simulate) + return true; + + // TRY ALL READERS, FIND FIRST SELECTABLE + List terminalList = getReaderList(); + + if (terminalList == null || terminalList.isEmpty()) { + System.out.println("No terminals found"); + return false; + } + + //List numbers of Card readers + boolean cardFound = false; + for (int i = 0; i < terminalList.size(); i++) { + System.out.println(i + " : " + terminalList.get(i)); + m_terminal = terminalList.get(i); + if (m_terminal.isCardPresent()) { + m_card = m_terminal.connect("*"); + System.out.println("card: " + m_card); + m_channel = m_card.getBasicChannel(); + + //reset the card + System.out.println(Util.bytesToHex(m_card.getATR().getBytes())); + + cardFound = true; + } + } + + return cardFound; + } + + public boolean connectToCardSelect() throws CardException { + if (simulate) + return true; + + // Test available card - if more present, let user to select one + List terminalList = CardMngr.getReaderList(); + if (terminalList == null || terminalList.isEmpty()) { + System.out.println("ERROR: No suitable reader with card detected. Please check your reader connection"); + return false; + } else { + if (terminalList.size() == 1) { + m_terminal = terminalList.get(0); // return first and only reader + } else { + int terminalIndex = 1; + // Let user select target terminal + for (CardTerminal terminal : terminalList) { + Card card; + try { + card = terminal.connect("*"); + ATR atr = card.getATR(); + System.out.println(terminalIndex + " : " + terminal.getName() + " - " + Util.bytesToHex(atr.getBytes())); + terminalIndex++; + } catch (CardException ex) { + ex.printStackTrace(System.out); + } + } + System.out.print("Select index of target reader you like to use 1.." + (terminalIndex - 1) + ": "); + Scanner sc = new Scanner(System.in); + int answ = sc.nextInt(); + System.out.println(String.format("%d", answ)); + answ--; // is starting with 0 + // BUGBUG; verify allowed index range + m_terminal = terminalList.get(answ); + } + } + + if (m_terminal != null) { + m_card = m_terminal.connect("*"); + System.out.println("card: " + m_card); + m_channel = m_card.getBasicChannel(); + } + + return true; + } + + public boolean reconnectToCard(byte[] selectAPDU) throws CardException { + if (simulate) + return true; + + if (connected()) { + disconnectFromCard(); + } + + boolean result = connectToCard(); + if (result) { + // Select our application on card + send(selectAPDU); + } + return result; + } + + public boolean connected() { + return simulate || m_card != null; + } + + public void disconnectFromCard() throws CardException { + if (simulate) + return; + + if (m_card != null) { + m_card.disconnect(false); + m_card = null; + } + } + + public byte[] getCPLCData() throws Exception { + byte[] data; + + // TODO: Modify to obtain CPLC data + byte apdu[] = new byte[HEADER_LENGTH]; + apdu[OFFSET_CLA] = (byte) 0x00; + apdu[OFFSET_INS] = (byte) 0x00; + apdu[OFFSET_P1] = (byte) 0x00; + apdu[OFFSET_P2] = (byte) 0x00; + apdu[OFFSET_LC] = (byte) 0x00; + + ResponseAPDU resp = send(apdu); + if (resp.getSW() != 0x9000) { // 0x9000 is "OK" + System.out.println("Fail to obtain card's response data"); + data = null; + } else { + byte temp[] = resp.getBytes(); + data = new byte[temp.length - 2]; + System.arraycopy(temp, 0, data, 0, temp.length - 2); + // Last two bytes are status word (also obtainable by resp.getSW()) + // Take a look at ISO7816_status_words.txt for common codes + } + + return data; + } + + public void probeCardCommands() throws Exception { + // TODO: modify to probe for instruction + for (int i = 0; i <= 0; i++) { + byte apdu[] = new byte[HEADER_LENGTH]; + apdu[OFFSET_CLA] = (byte) 0x00; + apdu[OFFSET_INS] = (byte) 0x00; + apdu[OFFSET_P1] = (byte) 0x00; + apdu[OFFSET_P2] = (byte) 0x00; + apdu[OFFSET_LC] = (byte) 0x00; + + ResponseAPDU resp = send(apdu); + + System.out.println("Response: " + Integer.toHexString(resp.getSW())); + + if (resp.getSW() != 0x6D00) { // Note: 0x6D00 is SW_INS_NOT_SUPPORTED + // something? + } + } + } + + public static List getReaderList() { + try { + TerminalFactory factory = TerminalFactory.getDefault(); + return factory.terminals().list(); + } catch (CardException ex) { + System.out.println("Exception : " + ex); + return null; + } + } + + public ResponseAPDU sendAPDU(CommandAPDU apdu) throws CardException { + System.out.println(">>>>"); + System.out.println(apdu); + + System.out.println(Util.bytesToHex(apdu.getBytes())); + + long elapsed = -System.nanoTime(); + + ResponseAPDU responseAPDU = m_channel.transmit(apdu); + + elapsed += System.nanoTime(); + + System.out.println(responseAPDU); + System.out.println(Util.bytesToHex(responseAPDU.getBytes())); + + if (responseAPDU.getSW1() == (byte) 0x61) { + CommandAPDU apduToSend = new CommandAPDU((byte) 0x00, + (byte) 0xC0, (byte) 0x00, (byte) 0x00, + responseAPDU.getSW1()); + + responseAPDU = m_channel.transmit(apduToSend); + System.out.println(Util.bytesToHex(responseAPDU.getBytes())); + } + + System.out.println("<<<<"); + System.out.println("Elapsed time (ms): " + elapsed / 1000000); + return responseAPDU; + } + + public ResponseAPDU sendAPDU(byte apdu[]) throws CardException { + CommandAPDU commandAPDU = new CommandAPDU(apdu); + return sendAPDU(commandAPDU); + } + + public boolean prepareLocalSimulatorApplet(byte[] appletAIDArray, byte[] installData, Class appletClass) { + System.setProperty("com.licel.jcardsim.terminal.type", "2"); + m_cad = new CAD(System.getProperties()); + m_simulator = (JavaxSmartCardInterface) m_cad.getCardInterface(); + AID appletAID = new AID(appletAIDArray, (short) 0, (byte) appletAIDArray.length); + + AID appletAIDRes = m_simulator.installApplet(appletAID, appletClass, installData, (short) 0, (byte) installData.length); + return m_simulator.selectApplet(appletAID); + } + + public ResponseAPDU sendAPDUSimulator(CommandAPDU apdu) { + System.out.println(">>>>"); + System.out.println(Util.bytesToHex(apdu.getBytes())); + + ResponseAPDU response = m_simulator.transmitCommand(apdu); + byte[] responseBytes = response.getBytes(); + + System.out.println(Util.bytesToHex(responseBytes)); + System.out.println("<<<<"); + + return response; + } + + public ResponseAPDU sendAPDUSimulator(byte[] apdu) { + CommandAPDU commandAPDU = new CommandAPDU(apdu); + return sendAPDUSimulator(commandAPDU); + } + + public ResponseAPDU send(CommandAPDU apdu) throws CardException { + ResponseAPDU response; + if (simulate) { + response = sendAPDUSimulator(apdu); + } else { + response = sendAPDU(apdu); + } + return response; + } + + public ResponseAPDU send(byte[] apdu) throws CardException { + CommandAPDU commandAPDU = new CommandAPDU(apdu); + return send(commandAPDU); + } + +} -- cgit v1.3.1 From e113197a41fc1961a9649cb3a96a18d7a9eab58f Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 17 Jan 2017 20:09:15 +0100 Subject: implemented ecdh testing reader side: ectester -dh -fp -b 192 --- !uploader/ectester.cap | Bin 13349 -> 13350 bytes dist/ECTester.jar | Bin 190873 -> 210499 bytes src/cz/crcs/ectester/applet/ECTesterApplet.java | 1 + src/cz/crcs/ectester/reader/CardMngr.java | 64 +++--- src/cz/crcs/ectester/reader/ECTester.java | 251 ++++++++++++++++-------- src/cz/crcs/ectester/reader/Util.java | 2 +- 6 files changed, 210 insertions(+), 108 deletions(-) (limited to 'src/cz/crcs/ectester/reader/CardMngr.java') diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap index f829de4..5eb763e 100644 Binary files a/!uploader/ectester.cap and b/!uploader/ectester.cap differ diff --git a/dist/ECTester.jar b/dist/ECTester.jar index 2c14e00..0bbc87c 100644 Binary files a/dist/ECTester.jar and b/dist/ECTester.jar differ diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index b461688..f304196 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -30,6 +30,7 @@ public class ECTesterApplet extends Applet { public static final byte KEYPAIR_LOCAL = (byte) 0x01; public static final byte KEYPAIR_REMOTE = (byte) 0x02; public static final byte KEYPAIR_BOTH = KEYPAIR_LOCAL | KEYPAIR_REMOTE; + public static final byte EXPORT_NONE = (byte) 0x00; public static final byte EXPORT_PUBLIC = (byte) 0x04; public static final byte EXPORT_PRIVATE = (byte) 0x08; public static final byte EXPORT_BOTH = EXPORT_PUBLIC | EXPORT_PRIVATE; diff --git a/src/cz/crcs/ectester/reader/CardMngr.java b/src/cz/crcs/ectester/reader/CardMngr.java index d7a5c5f..aab7da9 100644 --- a/src/cz/crcs/ectester/reader/CardMngr.java +++ b/src/cz/crcs/ectester/reader/CardMngr.java @@ -13,13 +13,13 @@ import javax.smartcardio.*; * @author Jan Jancar johny@neuromancer.sk */ public class CardMngr { - private CardTerminal m_terminal = null; - private CardChannel m_channel = null; - private Card m_card = null; + private CardTerminal terminal = null; + private CardChannel channel = null; + private Card card = null; // Simulator related attributes - private CAD m_cad = null; - private JavaxSmartCardInterface m_simulator = null; + private CAD cad = null; + private JavaxSmartCardInterface simulator = null; private boolean simulate = false; @@ -62,14 +62,14 @@ public class CardMngr { boolean cardFound = false; for (int i = 0; i < terminalList.size(); i++) { System.out.println(i + " : " + terminalList.get(i)); - m_terminal = terminalList.get(i); - if (m_terminal.isCardPresent()) { - m_card = m_terminal.connect("*"); - System.out.println("card: " + m_card); - m_channel = m_card.getBasicChannel(); + terminal = terminalList.get(i); + if (terminal.isCardPresent()) { + card = terminal.connect("*"); + System.out.println("card: " + card); + channel = card.getBasicChannel(); //reset the card - System.out.println(Util.bytesToHex(m_card.getATR().getBytes())); + System.out.println(Util.bytesToHex(card.getATR().getBytes())); cardFound = true; } @@ -89,7 +89,7 @@ public class CardMngr { return false; } else { if (terminalList.size() == 1) { - m_terminal = terminalList.get(0); // return first and only reader + terminal = terminalList.get(0); // return first and only reader } else { int terminalIndex = 1; // Let user select target terminal @@ -110,14 +110,14 @@ public class CardMngr { System.out.println(String.format("%d", answ)); answ--; // is starting with 0 // BUGBUG; verify allowed index range - m_terminal = terminalList.get(answ); + terminal = terminalList.get(answ); } } - if (m_terminal != null) { - m_card = m_terminal.connect("*"); - System.out.println("card: " + m_card); - m_channel = m_card.getBasicChannel(); + if (terminal != null) { + card = terminal.connect("*"); + System.out.println("card: " + card); + channel = card.getBasicChannel(); } return true; @@ -140,16 +140,16 @@ public class CardMngr { } public boolean connected() { - return simulate || m_card != null; + return simulate || card != null; } public void disconnectFromCard() throws CardException { if (simulate) return; - if (m_card != null) { - m_card.disconnect(false); - m_card = null; + if (card != null) { + card.disconnect(false); + card = null; } } @@ -217,7 +217,7 @@ public class CardMngr { long elapsed = -System.nanoTime(); - ResponseAPDU responseAPDU = m_channel.transmit(apdu); + ResponseAPDU responseAPDU = channel.transmit(apdu); elapsed += System.nanoTime(); @@ -229,7 +229,7 @@ public class CardMngr { (byte) 0xC0, (byte) 0x00, (byte) 0x00, responseAPDU.getSW1()); - responseAPDU = m_channel.transmit(apduToSend); + responseAPDU = channel.transmit(apduToSend); System.out.println(Util.bytesToHex(responseAPDU.getBytes())); } @@ -245,19 +245,19 @@ public class CardMngr { public boolean prepareLocalSimulatorApplet(byte[] appletAIDArray, byte[] installData, Class appletClass) { System.setProperty("com.licel.jcardsim.terminal.type", "2"); - m_cad = new CAD(System.getProperties()); - m_simulator = (JavaxSmartCardInterface) m_cad.getCardInterface(); + cad = new CAD(System.getProperties()); + simulator = (JavaxSmartCardInterface) cad.getCardInterface(); AID appletAID = new AID(appletAIDArray, (short) 0, (byte) appletAIDArray.length); - AID appletAIDRes = m_simulator.installApplet(appletAID, appletClass, installData, (short) 0, (byte) installData.length); - return m_simulator.selectApplet(appletAID); + AID appletAIDRes = simulator.installApplet(appletAID, appletClass, installData, (short) 0, (byte) installData.length); + return simulator.selectApplet(appletAID); } public ResponseAPDU sendAPDUSimulator(CommandAPDU apdu) { System.out.println(">>>>"); System.out.println(Util.bytesToHex(apdu.getBytes())); - ResponseAPDU response = m_simulator.transmitCommand(apdu); + ResponseAPDU response = simulator.transmitCommand(apdu); byte[] responseBytes = response.getBytes(); System.out.println(Util.bytesToHex(responseBytes)); @@ -286,4 +286,12 @@ public class CardMngr { return send(commandAPDU); } + public ResponseAPDU[] send(CommandAPDU... apdus) throws CardException { + ResponseAPDU[] result = new ResponseAPDU[apdus.length]; + for (int i = 0; i < apdus.length; i++) { + result[i] = send(apdus[i]); + } + return result; + } + } diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 8c00ea9..6d1be42 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -12,6 +12,8 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; /** * @author Petr Svenda petr@svenda.com @@ -185,11 +187,10 @@ public class ECTester { * -dsa / --ecdsa [data_file] * * Options: - * -b / --bit-size [b] / -a / --all + * -b / --bit-size [b] // -a / --all * -fp / --prime-field * -f2m / --binary-field - * -n / --named - * -c / --curve [curve_file] field,a,b,gx,gy,r,k + * -n / --named // -c / --curve [curve_file] field,a,b,gx,gy,r,k * --public [pubkey_file] wx,wy * --private [privkey_file] s * -k / --key [key_file] wx,wy,s @@ -206,14 +207,18 @@ public class ECTester { opts.addOptionGroup(actions); OptionGroup size = new OptionGroup(); + size.setRequired(true); size.addOption(Option.builder("b").longOpt("bit-size").desc("Set curve size.").hasArg().argName("b").build()); size.addOption(Option.builder("a").longOpt("all").desc("Test all curve sizes.").build()); opts.addOptionGroup(size); + OptionGroup curve = new OptionGroup(); + curve.addOption(Option.builder("n").longOpt("named").desc("Use a named curve.").build()); + curve.addOption(Option.builder("c").longOpt("curve").desc("Use curve from file [curve_file] (field,a,b,gx,gy,r,k).").hasArg().argName("curve_file").build()); + opts.addOptionGroup(curve); + opts.addOption(Option.builder("fp").longOpt("prime-field").desc("Use prime field curve.").build()); opts.addOption(Option.builder("f2m").longOpt("binary-field").desc("Use binary field curve.").build()); - opts.addOption(Option.builder("n").longOpt("named").desc("Use a named curve.").build()); - opts.addOption(Option.builder("c").longOpt("curve").desc("Use curve from file [curve_file] (field,a,b,gx,gy,r,k).").hasArg().argName("curve_file").build()); opts.addOption(Option.builder("pub").longOpt("public").desc("Use public key from file [pubkey_file] (wx,wy).").hasArg().argName("pubkey_file").build()); opts.addOption(Option.builder("priv").longOpt("private").desc("Use private key from file [privkey_file] (s).").hasArg().argName("privkey_file").build()); opts.addOption(Option.builder("k").longOpt("key").desc("Use keypair from file [key_file] (wx,wy,s).").hasArg().argName("key_file").build()); @@ -226,7 +231,7 @@ public class ECTester { } /** - * Reads and validates options. + * Reads and validates options, also sets defaults. * * @param cli cli object, with parsed args * @return whether the options are valid. @@ -255,14 +260,6 @@ public class ECTester { System.err.println("Bit-size must not be negative."); return false; } - if (optNamed && optCurve != null) { - System.err.println("Can only specify a named curve with --named or an external curve with --curve. (not both)"); - return false; - } - if (optBits == 0 || optAll) { - System.err.println("You have to specify curve bit-size."); - return false; - } if (cli.hasOption("generate")) { if (optPrimeField == optBinaryField) { @@ -273,11 +270,14 @@ public class ECTester { 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) { @@ -291,6 +291,15 @@ public class ECTester { } } else if (cli.hasOption("ecdh")) { + 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; + } + } else if (cli.hasOption("ecdsa")) { optECDSASign = cli.getOptionValue("ecdsa"); } @@ -307,23 +316,14 @@ public class ECTester { } /** - * Generates EC keypairs and outputs them to log. + * Generates EC keypairs and outputs them to output file. + * @throws CardException + * @throws IOException */ private void generate() throws CardException, IOException { - ///// - short keyLength = (short) optBits; byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; - short params = optPrimeField ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; - - cmdAllocate(ECTesterApplet.KEYPAIR_LOCAL, keyLength, keyClass); - - if (optNamed) { - cmdSet(ECTesterApplet.KEYPAIR_LOCAL, (byte) 0, EC_Consts.getCurve(keyLength, keyClass), params, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, null); - } else if (optCurve != null) { - byte[] external = ParamReader.flatten(params, ParamReader.readFile(optCurve)); - cmdSet(ECTesterApplet.KEYPAIR_LOCAL, (byte) 0, EC_Consts.CURVE_external, params, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, external); - } - ///// + CommandAPDU[] prepare = prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass); + cardManager.send(prepare); FileWriter keysFile = new FileWriter(optOutput); keysFile.write("index;time;pubW;privS\n"); @@ -331,8 +331,9 @@ public class ECTester { int generated = 0; int retry = 0; while (generated < optGenerateAmount || optGenerateAmount == 0) { + CommandAPDU generate = insGenerate(ECTesterApplet.KEYPAIR_LOCAL, (byte) (ECTesterApplet.EXPORT_BOTH | ECTesterApplet.KEYPAIR_LOCAL)); long elapsed = -System.nanoTime(); - ResponseAPDU response = cmdGenerate(ECTesterApplet.KEYPAIR_LOCAL, (byte) (ECTesterApplet.EXPORT_BOTH | ECTesterApplet.KEYPAIR_LOCAL)); + ResponseAPDU response = cardManager.send(generate); elapsed += System.nanoTime(); byte[] bytes = response.getData(); @@ -359,27 +360,72 @@ public class ECTester { } /** - * + * Tests */ private void test() { - //TODO - // allocate - // set custom - // generate - // ecdh local, local, valid - // ecdh local, local, invalid - // ecdsa local, local, 00? + if (optAll) { + if (optPrimeField) { + //iterate over prime curve sizes used: EC_Consts.FP_SIZES + for (short keyLength : EC_Consts.FP_SIZES) { + //prepareCurve(KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_FP); + //insGenerate(KEYPAIR_BOTH, EXPORT_NONE); + //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 00); + //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 01); + //insECDSA(KEYPAIR_LOCAL, EXPORT_NONE, null); + } + } + if (optBinaryField) { + //iterate over binary curve sizes used: EC_Consts.F2M_SIZES + for (short keyLength : EC_Consts.F2M_SIZES) { + //prepareCurve(KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_F2M); + //insGenerate(KEYPAIR_BOTH, EXPORT_NONE); + //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 00); + //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 01); + //insECDSA(KEYPAIR_LOCAL, EXPORT_NONE, null); + } + } + } else { + if (optPrimeField) { + //test with prepareCurve(KEYPAIR_BOTH, (short) optBits, KeyPair.ALG_EC_FP) + //insGenerate(KEYPAIR_BOTH, EXPORT_NONE); + //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 00); + //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 01); + //insECDSA(KEYPAIR_LOCAL, EXPORT_NONE, null); + } + if (optBinaryField) { + //test with prepareCurve(KEYPAIR_BOTH, (short) optBits, KeyPair.ALG_EC_F2M) + //insGenerate(KEYPAIR_BOTH, EXPORT_NONE); + //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 00); + //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 01); + //insECDSA(KEYPAIR_LOCAL, EXPORT_NONE, null); + } + } } /** * + * @throws IOException + * @throws CardException */ - private void ecdh() { - //TODO - //allocate local + remote - //set curve if specified - // + private void ecdh() throws IOException, CardException { + byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; + CommandAPDU[] curve = prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) optBits, keyClass); + cardManager.send(curve); + + if (optPublic != null || optPrivate != null || optKey != null) { + CommandAPDU local = insGenerate(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE); + cardManager.send(local); + CommandAPDU remote = prepareKey(ECTesterApplet.KEYPAIR_REMOTE); + cardManager.send(remote); + } else { + CommandAPDU both = insGenerate(ECTesterApplet.KEYPAIR_BOTH, ECTesterApplet.EXPORT_NONE); + cardManager.send(both); + } + + CommandAPDU ecdh = insECDH(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_ECDH, (byte) 0); + ResponseAPDU response = cardManager.send(ecdh); + //TODO output ecdh } /** @@ -389,36 +435,33 @@ public class ECTester { } /** - * Sends the INS_ALLOCATE instruction to the card/simulation. + * Creates the INS_ALLOCATE instruction. * - * @param keypair + * @param keyPair * @param keyLength * @param keyClass - * @return card response - * @throws CardException + * @return apdu to send */ - private ResponseAPDU cmdAllocate(byte keypair, short keyLength, byte keyClass) throws CardException { + private CommandAPDU insAllocate(byte keyPair, short keyLength, byte keyClass) throws CardException { byte[] data = new byte[]{0, 0, keyClass}; Util.setShort(data, 0, keyLength); - CommandAPDU allocate = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keypair, 0x00, data); - return cardManager.send(allocate); + return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, 0x00, data); } /** - * Sends the INS_SET instruction to the card/simulation. + * Creates the INS_SET instruction. * - * @param keypair + * @param keyPair * @param export * @param curve * @param params * @param corrupted * @param corruption * @param external - * @return card response - * @throws CardException + * @return apdu to send */ - private ResponseAPDU cmdSet(byte keypair, byte export, byte curve, short params, short corrupted, byte corruption, byte[] external) throws CardException { + private CommandAPDU insSet(byte keyPair, byte export, byte curve, short params, short corrupted, byte corruption, byte[] external) { int len = external != null ? 6 + 2 + external.length : 6; byte[] data = new byte[len]; data[0] = curve; @@ -429,48 +472,44 @@ public class ECTester { System.arraycopy(external, 0, data, 6, external.length); } - CommandAPDU set = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SET, keypair, export, data); - return cardManager.send(set); + return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SET, keyPair, export, data); } /** - * Sends the INS_GENERATE instruction to the card/simulation. + * Creates the INS_GENERATE instruction. * - * @param keypair + * @param keyPair * @param export - * @return card response + * @return apdu to send */ - private ResponseAPDU cmdGenerate(byte keypair, byte export) throws CardException { - CommandAPDU generate = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_GENERATE, keypair, export); - return cardManager.send(generate); + private CommandAPDU insGenerate(byte keyPair, byte export) { + return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_GENERATE, keyPair, export); } /** - * Sends the INS_ECDH instruction to the card/simulation. + * Creates the INS_ECDH instruction. * - * @param keypair + * @param pubkey + * @param privkey * @param export - * @param valid - * @return card response - * @throws CardException + * @param invalid + * @return apdu to send */ - private ResponseAPDU cmdECDH(byte keypair, byte export, byte valid) throws CardException { - byte[] data = new byte[1]; - data[0] = valid; + private CommandAPDU insECDH(byte pubkey, byte privkey, byte export, byte invalid) { + byte[] data = new byte[]{export, invalid}; - CommandAPDU ecdh = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, keypair, export, data); - return cardManager.send(ecdh); + return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, pubkey, privkey, data); } /** - * Sends the INS_ECDSA instruction to the card/simulation. + * Creates the INS_ECDSA instruction. * - * @param keypair + * @param keyPair * @param export * @param raw - * @return card response + * @return apdu to send */ - private ResponseAPDU cmdECDSA(byte keypair, byte export, byte[] raw) throws CardException { + private CommandAPDU insECDSA(byte keyPair, byte export, byte[] raw) { int len = raw != null ? raw.length : 0; byte[] data = new byte[2 + len]; Util.setShort(data, 0, (short) len); @@ -478,8 +517,62 @@ public class ECTester { System.arraycopy(raw, 0, data, 2, len); } - CommandAPDU ecdsa = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA, keypair, export, data); - return cardManager.send(ecdsa); + return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA, keyPair, export, data); + } + + /** + * @param keyPair + * @param keyLength + * @param keyClass + * @return + * @throws CardException + * @throws FileNotFoundException + */ + private CommandAPDU[] prepareCurve(byte keyPair, short keyLength, byte keyClass) throws CardException, IOException { + List commands = new ArrayList<>(); + commands.add(insAllocate(keyPair, keyLength, keyClass)); + + short domainParams = keyClass == KeyPair.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; + if (optNamed) { + commands.add(insSet(keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.getCurve(keyLength, keyClass), domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, null)); + } + if (optCurve != null) { + byte[] external = ParamReader.flatten(domainParams, ParamReader.readFile(optCurve)); + if (external == null) { + throw new IOException("Couldn't read the curve file correctly."); + } + commands.add(insSet(keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, external)); + } + + return commands.toArray(new CommandAPDU[commands.size()]); + } + + /** + * @param keypair + * @return + * @throws IOException + */ + private CommandAPDU prepareKey(byte keypair) throws IOException { + short params = EC_Consts.PARAMETERS_NONE; + byte[] data = null; + if (optKey != null) { + params |= EC_Consts.PARAMETERS_KEYPAIR; + data = ParamReader.flatten(EC_Consts.PARAMETERS_KEYPAIR, ParamReader.readFile(optKey)); + } + + if (optPublic != null) { + params |= EC_Consts.PARAMETER_W; + data = ParamReader.flatten(EC_Consts.PARAMETER_W, ParamReader.readFile(optPublic)); + } + if (optPrivate != null) { + params |= EC_Consts.PARAMETER_S; + data = Util.concatenate(data, ParamReader.flatten(EC_Consts.PARAMETER_S, ParamReader.readFile(optPrivate))); + } + + if (data == null && params != EC_Consts.PARAMETERS_NONE) { + throw new IOException("Couldn't read the key file correctly."); + } + return insSet(keypair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, params, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, data); } public static void main(String[] args) { diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java index 7af6e9c..aa0dfd5 100644 --- a/src/cz/crcs/ectester/reader/Util.java +++ b/src/cz/crcs/ectester/reader/Util.java @@ -72,7 +72,7 @@ public class Util { byte[] out = new byte[len]; int offset = 0; for (byte[] array : arrays) { - if (array == null) + if (array == null || array.length == 0) continue; System.arraycopy(array, 0, out, offset, array.length); offset += array.length; -- cgit v1.3.1 From b99a1484397cc1b64a4798fa4a73b0782d99f18e Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 17 Jan 2017 22:35:02 +0100 Subject: reader: implemented ecdh and ecdsa actions, also added some docs - ecdh and ecdsa instructions now work, although without output to file, yet. - added MIT license headers to main classes --- !uploader/ectester.cap | Bin 13350 -> 13350 bytes dist/ECTester.jar | Bin 210499 -> 211786 bytes src/cz/crcs/ectester/applet/ECTesterApplet.java | 107 ++++++++------ src/cz/crcs/ectester/reader/CardMngr.java | 32 ++--- src/cz/crcs/ectester/reader/ECTester.java | 178 +++++++++++++++++------- src/cz/crcs/ectester/reader/ParamReader.java | 5 +- src/cz/crcs/ectester/reader/Util.java | 35 +++++ 7 files changed, 248 insertions(+), 109 deletions(-) (limited to 'src/cz/crcs/ectester/reader/CardMngr.java') diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap index 5eb763e..63dd209 100644 Binary files a/!uploader/ectester.cap and b/!uploader/ectester.cap differ diff --git a/dist/ECTester.jar b/dist/ECTester.jar index 0bbc87c..bffc912 100644 Binary files a/dist/ECTester.jar and b/dist/ECTester.jar differ diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index f304196..dd13fc3 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2016-2017 Petr Svenda + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ /* * PACKAGEID: 4C6162616B417070 * APPLETID: 4C6162616B4170706C6574 @@ -11,6 +32,8 @@ import javacard.security.KeyPair; import javacard.security.RandomData; /** + * Reader part of ECTester, a tool for testing Elliptic curve support on javacards. + * * @author Petr Svenda petr@svenda.com * @author Jan Jancar johny@neuromancer.sk */ @@ -125,10 +148,10 @@ public class ECTesterApplet extends Applet { } /** - * Allocate local and remote keypairs. + * Allocates local and remote keyPairs. * returns allocate SWs * - * @param apdu P1 = byte keypair (KEYPAIR_* | ...) + * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) * P2 = * DATA = short keyLength * byte keyClass @@ -137,32 +160,32 @@ public class ECTesterApplet extends Applet { apdu.setIncomingAndReceive(); byte[] apdubuf = apdu.getBuffer(); - byte keypair = apdubuf[ISO7816.OFFSET_P1]; + byte keyPair = apdubuf[ISO7816.OFFSET_P1]; short keyLength = Util.getShort(apdubuf, ISO7816.OFFSET_CDATA); byte keyClass = apdubuf[ISO7816.OFFSET_CDATA + 2]; - short len = allocate(keypair, keyLength, keyClass, apdubuf, (short) 0); + short len = allocate(keyPair, keyLength, keyClass, apdubuf, (short) 0); apdu.setOutgoingAndSend((short) 0, len); } /** - * @param keypair which keypair to use, local/remote (KEYPAIR_* | ...) + * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) * @param keyLength key length to set * @param keyClass key class to allocate * @param buffer apdu buffer * @param offset offset into apdu buffer * @return length of data written to the buffer */ - private short allocate(byte keypair, short keyLength, byte keyClass, byte[] buffer, short offset) { + private short allocate(byte keyPair, short keyLength, byte keyClass, byte[] buffer, short offset) { short length = 0; - if ((keypair & KEYPAIR_LOCAL) != 0) { + if ((keyPair & KEYPAIR_LOCAL) != 0) { localKeypair = keyGenerator.allocatePair(keyClass, keyLength); Util.setShort(buffer, offset, keyGenerator.getSW()); length += 2; } - if ((keypair & KEYPAIR_REMOTE) != 0) { + if ((keyPair & KEYPAIR_REMOTE) != 0) { remoteKeypair = keyGenerator.allocatePair(keyClass, keyLength); Util.setShort(buffer, (short) (offset + length), keyGenerator.getSW()); length += 2; @@ -172,10 +195,10 @@ public class ECTesterApplet extends Applet { } /** - * Sets curve parameters on local and remote keypairs. + * Sets curve parameters on local and remote keyPairs. * returns setCurve SWs, set params if export * - * @param apdu P1 = byte keypair (KEYPAIR_* | ...) + * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) * P2 = byte export (EXPORT_* | KEYPAIR_*) * DATA = byte curve (EC_Consts.CURVE_*) * short params (EC_Consts.PARAMETER_* | ...) @@ -183,7 +206,7 @@ public class ECTesterApplet extends Applet { * byte corruptionType (EC_Consts.CORRUPTION_*) *

* if curveID = CURVE_EXTERNAL: - * [short param_length, byte[] param], + * [short paramLength, byte[] param], * for all params in params, * in order: field,a,b,g,r,k,w,s */ @@ -191,7 +214,7 @@ public class ECTesterApplet extends Applet { apdu.setIncomingAndReceive(); byte[] apdubuf = apdu.getBuffer(); - byte keypair = apdubuf[ISO7816.OFFSET_P1]; + byte keyPair = apdubuf[ISO7816.OFFSET_P1]; byte export = apdubuf[ISO7816.OFFSET_P2]; byte curve = apdubuf[ISO7816.OFFSET_CDATA]; short params = Util.getShort(apdubuf, (short) (ISO7816.OFFSET_CDATA + 1)); @@ -200,9 +223,9 @@ public class ECTesterApplet extends Applet { short len = 0; - if ((keypair & KEYPAIR_LOCAL) != 0) + if ((keyPair & KEYPAIR_LOCAL) != 0) len += set(localKeypair, curve, params, corruptedParams, corruptionType, apdubuf, (short) (ISO7816.OFFSET_CDATA + 6), (short) 0); - if ((keypair & KEYPAIR_REMOTE) != 0) + if ((keyPair & KEYPAIR_REMOTE) != 0) len += set(remoteKeypair, curve, params, corruptedParams, corruptionType, apdubuf, (short) (ISO7816.OFFSET_CDATA + 6), len); if ((export & KEYPAIR_LOCAL) != 0) len += export(localKeypair, export, params, apdubuf, len); @@ -213,7 +236,7 @@ public class ECTesterApplet extends Applet { } /** - * @param keypair KeyPair to set params on + * @param keyPair KeyPair to set params on * @param curve curve to set (EC_Consts.CURVE_*) * @param params parameters to set (EC_Consts.PARAMETER_* | ...) * @param corrupted parameters to corrupt (EC_Consts.PARAMETER_* | ...) @@ -223,7 +246,7 @@ public class ECTesterApplet extends Applet { * @param outOffset output offset in buffer * @return length of data written to the buffer */ - private short set(KeyPair keypair, byte curve, short params, short corrupted, byte corruption, byte[] buffer, short inOffset, short outOffset) { + private short set(KeyPair keyPair, byte curve, short params, short corrupted, byte corruption, byte[] buffer, short inOffset, short outOffset) { short sw = ISO7816.SW_NO_ERROR; switch (curve) { @@ -232,38 +255,38 @@ public class ECTesterApplet extends Applet { break; case EC_Consts.CURVE_external: //external - sw = keyGenerator.setExternalCurve(keypair, params, buffer, inOffset); + sw = keyGenerator.setExternalCurve(keyPair, params, buffer, inOffset); break; default: //custom - sw = keyGenerator.setCurve(keypair, curve, params, ramArray, (short) 0); + sw = keyGenerator.setCurve(keyPair, curve, params, ramArray, (short) 0); break; } if (sw == ISO7816.SW_NO_ERROR) - sw = keyGenerator.corruptCurve(keypair, corrupted, corruption, ramArray, (short) 0); + sw = keyGenerator.corruptCurve(keyPair, corrupted, corruption, ramArray, (short) 0); Util.setShort(buffer, outOffset, sw); return 2; } /** - * Generates the local and remote keypairs. + * Generates the local and remote keyPairs. * returns generate SWs, pubkey and privkey if export * - * @param apdu P1 = byte keypair (KEYPAIR_* | ...) + * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) * P2 = byte export (EXPORT_* | KEYPAIR_*) */ private void insGenerate(APDU apdu) { apdu.setIncomingAndReceive(); byte[] apdubuf = apdu.getBuffer(); - byte keypair = apdubuf[ISO7816.OFFSET_P1]; + byte keyPair = apdubuf[ISO7816.OFFSET_P1]; byte export = apdubuf[ISO7816.OFFSET_P2]; short len = 0; - if ((keypair & KEYPAIR_LOCAL) != 0) + if ((keyPair & KEYPAIR_LOCAL) != 0) len += generate(localKeypair, apdubuf, (short) 0); - if ((keypair & KEYPAIR_REMOTE) != 0) + if ((keyPair & KEYPAIR_REMOTE) != 0) len += generate(remoteKeypair, apdubuf, len); if ((export & KEYPAIR_LOCAL) != 0) len += export(localKeypair, export, (short) (EC_Consts.PARAMETER_W | EC_Consts.PARAMETER_S), apdubuf, len); @@ -274,44 +297,44 @@ public class ECTesterApplet extends Applet { } /** - * @param keypair KeyPair to generate + * @param keyPair KeyPair to generate * @param buffer buffer to write sw to * @param offset output offset in buffer * @return length of data written to the buffer */ - private short generate(KeyPair keypair, byte[] buffer, short offset) { - short sw = keyGenerator.generatePair(keypair); + private short generate(KeyPair keyPair, byte[] buffer, short offset) { + short sw = keyGenerator.generatePair(keyPair); Util.setShort(buffer, offset, sw); return 2; } /** - * @param keypair KeyPair to export from + * @param keyPair KeyPair to export from * @param export which key to export from (EXPORT_PUBLIC | EXPORT_PRIVATE) * @param params which params to export (EC_Consts.PARAMETER_* | ...) * @param buffer buffer to export params to * @param offset output offset in buffer * @return length of data written to the buffer */ - private short export(KeyPair keypair, byte export, short params, byte[] buffer, short offset) { + private short export(KeyPair keyPair, byte export, short params, byte[] buffer, short offset) { short length = 0; if ((export & EXPORT_PUBLIC) != 0) { //export params from public - length += keyGenerator.exportParameters(keypair, ECKeyGenerator.KEY_PUBLIC, params, buffer, offset); + length += keyGenerator.exportParameters(keyPair, ECKeyGenerator.KEY_PUBLIC, params, buffer, offset); } if ((export & EXPORT_PRIVATE) != 0) { //export params from private - length += keyGenerator.exportParameters(keypair, ECKeyGenerator.KEY_PRIVATE, params, buffer, (short) (offset + length)); + length += keyGenerator.exportParameters(keyPair, ECKeyGenerator.KEY_PRIVATE, params, buffer, (short) (offset + length)); } return length; } /** - * Does ECDH, between the pubkey specified in P1(local/remote) and the privkey specified in P2(local/remote). + * Performs ECDH, between the pubkey specified in P1(local/remote) and the privkey specified in P2(local/remote). * returns deriveSecret SW, if export != 0 => short secretlen, byte[] secret * * @param apdu P1 = byte pubkey (KEYPAIR_*) @@ -334,8 +357,8 @@ public class ECTesterApplet extends Applet { } /** - * @param pubkey keypair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) - * @param privkey keypair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDH secret * @param invalid whether to invalidate the pubkey before ECDH * @param buffer buffer to write sw to, and export ECDH secret if (export & EXPORT_ECDH) != 0 @@ -369,35 +392,35 @@ public class ECTesterApplet extends Applet { } /** - * Does and ECDSA signature and verification on data provided, using the keypair in P1(local/remote). + * Performs ECDSA signature and verification on data provided or random, using the keyPair in P1(local/remote). * returns ecdsa SW, if export != 0 => short signature_length, byte[] signature * - * @param apdu P1 = byte keypair (KEYPAIR_*) + * @param apdu P1 = byte keyPair (KEYPAIR_*) * P2 = byte export (EXPORT_SIG || 0) - * DATA = short data_length (00 = random data generated, !00 = data length) + * DATA = short dataLength (00 = random data generated, !00 = data length) * byte[] data */ private void insECDSA(APDU apdu) { apdu.setIncomingAndReceive(); byte[] apdubuf = apdu.getBuffer(); - byte keypair = apdubuf[ISO7816.OFFSET_P1]; + byte keyPair = apdubuf[ISO7816.OFFSET_P1]; byte export = apdubuf[ISO7816.OFFSET_P2]; - short len = ecdsa(keypair, export, apdubuf, ISO7816.OFFSET_CDATA, (short) 0); + short len = ecdsa(keyPair, export, apdubuf, ISO7816.OFFSET_CDATA, (short) 0); apdu.setOutgoingAndSend((short) 0, len); } /** - * @param keypair keypair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDSA signature * @param buffer buffer to write sw to, and export ECDSA signature if (export & EXPORT_SIG) != 0 * @param inOffset input offset in buffer * @param outOffset output offset in buffer * @return length of data written to the buffer */ - private short ecdsa(byte keypair, byte export, byte[] buffer, short inOffset, short outOffset) { + private short ecdsa(byte keyPair, byte export, byte[] buffer, short inOffset, short outOffset) { short length = 0; short dataLength = Util.getShort(buffer, inOffset); @@ -409,7 +432,7 @@ public class ECTesterApplet extends Applet { Util.arrayCopyNonAtomic(buffer, (short) (inOffset + 2), ramArray, (short) 0, dataLength); } - KeyPair sign = ((keypair & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair; + KeyPair sign = ((keyPair & KEYPAIR_LOCAL) != 0) ? localKeypair : remoteKeypair; short signatureLength = keyTester.testECDSA((ECPrivateKey) sign.getPrivate(), (ECPublicKey) sign.getPublic(), ramArray, (short) 0, dataLength, ramArray2, (short) 0); Util.setShort(buffer, outOffset, keyTester.getSW()); diff --git a/src/cz/crcs/ectester/reader/CardMngr.java b/src/cz/crcs/ectester/reader/CardMngr.java index aab7da9..9cdd055 100644 --- a/src/cz/crcs/ectester/reader/CardMngr.java +++ b/src/cz/crcs/ectester/reader/CardMngr.java @@ -2,11 +2,11 @@ package cz.crcs.ectester.reader; import com.licel.jcardsim.io.CAD; import com.licel.jcardsim.io.JavaxSmartCardInterface; -import java.util.List; -import java.util.Scanner; import javacard.framework.AID; import javax.smartcardio.*; +import java.util.List; +import java.util.Scanner; /** * @author Petr Svenda petr@svenda.com @@ -16,16 +16,16 @@ public class CardMngr { private CardTerminal terminal = null; private CardChannel channel = null; private Card card = null; - + // Simulator related attributes private CAD cad = null; private JavaxSmartCardInterface simulator = null; private boolean simulate = false; - + private final byte selectCM[] = { - (byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0xa0, (byte) 0x00, (byte) 0x00, - (byte) 0x00, (byte) 0x18, (byte) 0x43, (byte) 0x4d}; + (byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0xa0, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x18, (byte) 0x43, (byte) 0x4d}; public static final byte OFFSET_CLA = 0x00; public static final byte OFFSET_INS = 0x01; @@ -42,7 +42,7 @@ public class CardMngr { this(false); } - public CardMngr(boolean simulate) { + public CardMngr(boolean simulate) { this.simulate = simulate; } @@ -70,14 +70,14 @@ public class CardMngr { //reset the card System.out.println(Util.bytesToHex(card.getATR().getBytes())); - + cardFound = true; } } return cardFound; } - + public boolean connectToCardSelect() throws CardException { if (simulate) return true; @@ -113,7 +113,7 @@ public class CardMngr { terminal = terminalList.get(answ); } } - + if (terminal != null) { card = terminal.connect("*"); System.out.println("card: " + card); @@ -190,15 +190,15 @@ public class CardMngr { apdu[OFFSET_LC] = (byte) 0x00; ResponseAPDU resp = send(apdu); - - System.out.println("Response: " + Integer.toHexString(resp.getSW())); - + + System.out.println("Response: " + Integer.toHexString(resp.getSW())); + if (resp.getSW() != 0x6D00) { // Note: 0x6D00 is SW_INS_NOT_SUPPORTED // something? } } } - + public static List getReaderList() { try { TerminalFactory factory = TerminalFactory.getDefault(); @@ -242,14 +242,14 @@ public class CardMngr { CommandAPDU commandAPDU = new CommandAPDU(apdu); return sendAPDU(commandAPDU); } - + public boolean prepareLocalSimulatorApplet(byte[] appletAIDArray, byte[] installData, Class appletClass) { System.setProperty("com.licel.jcardsim.terminal.type", "2"); cad = new CAD(System.getProperties()); simulator = (JavaxSmartCardInterface) cad.getCardInterface(); AID appletAID = new AID(appletAIDArray, (short) 0, (byte) appletAIDArray.length); - AID appletAIDRes = simulator.installApplet(appletAID, appletClass, installData, (short) 0, (byte) installData.length); + AID appletAIDRes = simulator.installApplet(appletAID, appletClass, installData, (short) 0, (byte) installData.length); return simulator.selectApplet(appletAID); } diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 6d1be42..1ee0015 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -1,3 +1,24 @@ +/* + * Copyright (c) 2016-2017 Petr Svenda + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ package cz.crcs.ectester.reader; import cz.crcs.ectester.applet.ECTesterApplet; @@ -8,14 +29,17 @@ import org.apache.commons.cli.*; import javax.smartcardio.CardException; import javax.smartcardio.CommandAPDU; import javax.smartcardio.ResponseAPDU; +import java.io.File; import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; /** + * Reader part of ECTester, a tool for testing Elliptic curve support on javacards. + * * @author Petr Svenda petr@svenda.com * @author Jan Jancar johny@neuromancer.sk */ @@ -23,7 +47,6 @@ public class ECTester { private CardMngr cardManager = null; private DirtyLogger systemOutLogger = null; - private FileOutputStream outputFile = null; //Options private int optBits; @@ -56,7 +79,7 @@ public class ECTester { private static final byte[] ALLOCATE = { (byte) 0xB0, (byte) 0x5a, //INS ALLOCATE - (byte) 0x00, //P1 *byte keypair + (byte) 0x00, //P1 *byte keyPair (byte) 0x00, //P2 (byte) 0x03, //LC (byte) 0x00, //DATA *short keyLength @@ -67,7 +90,7 @@ public class ECTester { private static final byte[] SET = { (byte) 0xB0, (byte) 0x5B, //INS SET - (byte) 0x00, //P1 *byte keypair + (byte) 0x00, //P1 *byte keyPair (byte) 0x00, //P2 *byte export (byte) 0x06, //LC (byte) 0x00, //DATA *byte curve @@ -82,7 +105,7 @@ public class ECTester { private static final byte[] GENERATE = { (byte) 0xB0, (byte) 0x5C, //INS GENERATE - (byte) 0x00, //P1 *byte keypair + (byte) 0x00, //P1 *byte keyPair (byte) 0x00, //P2 *byte export (byte) 0x00 //LC }; @@ -90,7 +113,7 @@ public class ECTester { private static final byte[] ECDH = { (byte) 0xB0, (byte) 0x5D, //INS ECDH - (byte) 0x00, //P1 *byte keypair + (byte) 0x00, //P1 *byte keyPair (byte) 0x00, //P2 *byte export (byte) 0x01, //LC (byte) 0x00 //DATA *byte valid @@ -99,7 +122,7 @@ public class ECTester { private static final byte[] ECDSA = { (byte) 0xB0, (byte) 0x5E, //INS ECDSA - (byte) 0x00, //P1 *byte keypair + (byte) 0x00, //P1 *byte keyPair (byte) 0x00, //P2 *byte export (byte) 0x00, //LC //DATA [*short dataLength, byte[] data] @@ -177,6 +200,13 @@ public class ECTester { } } + /** + * Parses command-line options. + * + * @param args cli arguments + * @return parsed CommandLine object + * @throws ParseException if there are any problems encountered while parsing the command line tokens + */ private CommandLine parseArgs(String[] args) throws ParseException { /* * Actions: @@ -221,7 +251,7 @@ public class ECTester { opts.addOption(Option.builder("f2m").longOpt("binary-field").desc("Use binary field curve.").build()); opts.addOption(Option.builder("pub").longOpt("public").desc("Use public key from file [pubkey_file] (wx,wy).").hasArg().argName("pubkey_file").build()); opts.addOption(Option.builder("priv").longOpt("private").desc("Use private key from file [privkey_file] (s).").hasArg().argName("privkey_file").build()); - opts.addOption(Option.builder("k").longOpt("key").desc("Use keypair from file [key_file] (wx,wy,s).").hasArg().argName("key_file").build()); + opts.addOption(Option.builder("k").longOpt("key").desc("Use keyPair from file [key_file] (wx,wy,s).").hasArg().argName("key_file").build()); opts.addOption(Option.builder("o").longOpt("output").desc("Output into file [output_file].").hasArg().argName("output_file").build()); opts.addOption(Option.builder("l").longOpt("log").desc("Log output into file [log_file].").hasArg().argName("log_file").optionalArg(true).build()); opts.addOption(Option.builder("s").longOpt("simulate").desc("Simulate a card with jcardsim instead of using a terminal.").build()); @@ -301,6 +331,19 @@ public class ECTester { } } else if (cli.hasOption("ecdsa")) { + 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 ((optPublic == null) != (optPrivate == null)) { + System.err.println("You have cannot only specify a part of a keypair."); + return false; + } + optECDSASign = cli.getOptionValue("ecdsa"); } @@ -316,9 +359,10 @@ public class ECTester { } /** - * Generates EC keypairs and outputs them to output file. - * @throws CardException - * @throws IOException + * Generates EC keyPairs and outputs them to output file. + * + * @throws CardException if APDU transmission fails + * @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; @@ -360,9 +404,10 @@ public class ECTester { } /** - * Tests + * Tests Elliptic curve support for a given curve/curves. */ private void test() { + //TODO if (optAll) { if (optPrimeField) { //iterate over prime curve sizes used: EC_Consts.FP_SIZES @@ -404,9 +449,10 @@ public class ECTester { } /** + * Performs ECDH key exchange. * - * @throws IOException - * @throws CardException + * @throws CardException if APDU transmission fails + * @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; @@ -425,24 +471,55 @@ public class ECTester { CommandAPDU ecdh = insECDH(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_ECDH, (byte) 0); ResponseAPDU response = cardManager.send(ecdh); - //TODO output ecdh + //TODO print response SWs/error codes + //TODO output to file } /** + * Performs ECDSA signature, on random or provided data. + * + * @throws CardException if APDU transmission fails + * @throws IOException if an IO error occurs when writing to key file. */ - private void ecdsa() { - //TODO + private void ecdsa() throws CardException, IOException { + byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; + CommandAPDU[] curve = prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass); + cardManager.send(curve); + + if (optKey != null || (optPublic != null && optPrivate != null)) { + CommandAPDU set = prepareKey(ECTesterApplet.KEYPAIR_LOCAL); + cardManager.send(set); + } else { + CommandAPDU generate = insGenerate(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE); + cardManager.send(generate); + } + + //read file, if asked to sign + byte[] data = null; + if (optECDSASign != null) { + File in = new File(optECDSASign); + long len = in.length(); + if (len == 0) { + throw new FileNotFoundException("File " + optECDSASign + " not found."); + } + data = Files.readAllBytes(in.toPath()); + } + + CommandAPDU ecdsa = insECDSA(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_SIG, data); + ResponseAPDU response = cardManager.send(ecdsa); + //TODO print response SWs/error codes + //TODO output to file } /** * Creates the INS_ALLOCATE instruction. * - * @param keyPair - * @param keyLength - * @param keyClass + * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) + * @param keyLength key length to set + * @param keyClass key class to allocate * @return apdu to send */ - private CommandAPDU insAllocate(byte keyPair, short keyLength, byte keyClass) throws CardException { + private CommandAPDU insAllocate(byte keyPair, short keyLength, byte keyClass) { byte[] data = new byte[]{0, 0, keyClass}; Util.setShort(data, 0, keyLength); @@ -452,13 +529,13 @@ public class ECTester { /** * Creates the INS_SET instruction. * - * @param keyPair - * @param export - * @param curve - * @param params - * @param corrupted - * @param corruption - * @param external + * @param keyPair which keyPair to set params on, local/remote (KEYPAIR_* || ...) + * @param export whether to export set params from keyPair + * @param curve curve to set (EC_Consts.CURVE_*) + * @param params parameters to set (EC_Consts.PARAMETER_* | ...) + * @param corrupted parameters to corrupt (EC_Consts.PARAMETER_* | ...) + * @param corruption corruption type (EC_Consts.CORRUPTION_*) + * @param external external curve data, can be null * @return apdu to send */ private CommandAPDU insSet(byte keyPair, byte export, byte curve, short params, short corrupted, byte corruption, byte[] external) { @@ -478,8 +555,8 @@ public class ECTester { /** * Creates the INS_GENERATE instruction. * - * @param keyPair - * @param export + * @param keyPair which keyPair to generate, local/remote (KEYPAIR_* || ...) + * @param export whether to export generated keys from keyPair * @return apdu to send */ private CommandAPDU insGenerate(byte keyPair, byte export) { @@ -489,10 +566,10 @@ public class ECTester { /** * Creates the INS_ECDH instruction. * - * @param pubkey - * @param privkey - * @param export - * @param invalid + * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param export whether to export ECDH secret + * @param invalid whether to invalidate the pubkey before ECDH * @return apdu to send */ private CommandAPDU insECDH(byte pubkey, byte privkey, byte export, byte invalid) { @@ -504,9 +581,9 @@ public class ECTester { /** * Creates the INS_ECDSA instruction. * - * @param keyPair - * @param export - * @param raw + * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param export whether to export ECDSA signature + * @param raw data to sign, can be null, in which case random data is signed. * @return apdu to send */ private CommandAPDU insECDSA(byte keyPair, byte export, byte[] raw) { @@ -521,14 +598,13 @@ public class ECTester { } /** - * @param keyPair - * @param keyLength - * @param keyClass - * @return - * @throws CardException - * @throws FileNotFoundException + * @param keyPair which keyPair/s (local/remote) to set curve domain parameters on + * @param keyLength key length to allocate + * @param keyClass key class to allocate + * @return an array of CommandAPDUs to send in order to prepare the keypair/s. + * @throws IOException if curve file cannot be found/opened */ - private CommandAPDU[] prepareCurve(byte keyPair, short keyLength, byte keyClass) throws CardException, IOException { + private CommandAPDU[] prepareCurve(byte keyPair, short keyLength, byte keyClass) throws IOException { List commands = new ArrayList<>(); commands.add(insAllocate(keyPair, keyLength, keyClass)); @@ -548,11 +624,11 @@ public class ECTester { } /** - * @param keypair - * @return - * @throws IOException + * @param keyPair which keyPair/s to set the key params on + * @return a CommandAPDU setting params loaded on the keyPair/s + * @throws IOException if any of the key files cannot be found/opened */ - private CommandAPDU prepareKey(byte keypair) throws IOException { + private CommandAPDU prepareKey(byte keyPair) throws IOException { short params = EC_Consts.PARAMETERS_NONE; byte[] data = null; if (optKey != null) { @@ -570,9 +646,13 @@ public class ECTester { } if (data == null && params != EC_Consts.PARAMETERS_NONE) { + /* + TODO: this is not correct, in case (optPublic != null) and (optPrivate != null), + only one can actually load(return not null from ParamReader.flatten) and an exception will not be thrown + */ throw new IOException("Couldn't read the key file correctly."); } - return insSet(keypair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, params, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, data); + return insSet(keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, params, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, data); } public static void main(String[] args) { diff --git a/src/cz/crcs/ectester/reader/ParamReader.java b/src/cz/crcs/ectester/reader/ParamReader.java index 5232326..ca14d2d 100644 --- a/src/cz/crcs/ectester/reader/ParamReader.java +++ b/src/cz/crcs/ectester/reader/ParamReader.java @@ -9,6 +9,7 @@ import java.util.Scanner; import java.util.regex.Pattern; /** + * * @author Jan Jancar johny@neuromancer.sk */ public class ParamReader { @@ -18,7 +19,7 @@ public class ParamReader { * Flattens params read from String[] data into a byte[] with their lengths prepended as short entries. * @param params (EC_Consts.PARAMETER_* | ...) * @param data data read by readString, readFile, readResource - * @return byte[] with params flattened + * @return byte[] with params flattened, or null */ public static byte[] flatten(short params, String[] data) { if (!validate(data)) { @@ -42,7 +43,7 @@ public class ParamReader { if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) { //read another param (the y coord) and put into X962 format. byte[] y = parse(data[i + 1]); - param = Util.concatenate(new byte[]{4}, param, y); + param = Util.concatenate(new byte[]{4}, param, y);//<- ugly but works! i++; } if (param.length == 0) diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java index aa0dfd5..1464728 100644 --- a/src/cz/crcs/ectester/reader/Util.java +++ b/src/cz/crcs/ectester/reader/Util.java @@ -1,6 +1,12 @@ package cz.crcs.ectester.reader; +import cz.crcs.ectester.applet.ECTesterApplet; +import javacard.framework.ISO7816; +import javacard.security.CryptoException; + /** + * Utility class, some byte/hex manipulation, convenient byte[] methods. + * * @author Petr Svenda petr@svenda.com * @author Jan Jancar johny@neuromancer.sk */ @@ -79,4 +85,33 @@ public class Util { } return out; } + + public static String getPrintError(short code) { + if (code == ISO7816.SW_NO_ERROR) { + return "OK\t(0x9000)"; + } else { + String codeStr = "unknown"; + switch (code) { + case CryptoException.ILLEGAL_VALUE: + codeStr = "ILLEGAL_VALUE"; + break; + case CryptoException.UNINITIALIZED_KEY: + codeStr = "UNINITIALIZED_KEY"; + break; + case CryptoException.NO_SUCH_ALGORITHM: + codeStr = "NO_SUCH_ALG"; + break; + case CryptoException.INVALID_INIT: + codeStr = "INVALID_INIT"; + break; + case CryptoException.ILLEGAL_USE: + codeStr = "ILLEGAL_USE"; + break; + case ECTesterApplet.SW_SIG_VERIFY_FAIL: + codeStr = "SIG_VERIFY_FAIL"; + break; + } + return String.format("fail\t(%s,\t0x%4x)", codeStr, code); + } + } } -- cgit v1.3.1 From 636306e09a84ac785d2711117640efe914ae020f Mon Sep 17 00:00:00 2001 From: J08nY Date: Sun, 22 Jan 2017 03:17:36 +0100 Subject: reader: Added a Command and Response abstraction - For easier testing - Command assembles the correct instruction from params in its constructor - Command.send() sends the command and obtains the Response with timing - Response parses the ResponseAPDU in its constructor and provides convenience methods to access its contents/SWs/success /failure/print data: Added more curves --- !uploader/ectester.cap | Bin 13350 -> 13377 bytes dist/ECTester.jar | Bin 211888 -> 75369 bytes src/cz/crcs/ectester/applet/ECKeyGenerator.java | 54 ++- src/cz/crcs/ectester/applet/ECTesterApplet.java | 192 +++++----- .../ectester/data/brainpool/brainpoolP160r1.txt | 7 + .../ectester/data/brainpool/brainpoolP160t1.txt | 7 + .../ectester/data/brainpool/brainpoolP192r1.txt | 7 + .../ectester/data/brainpool/brainpoolP192t1.txt | 7 + .../ectester/data/brainpool/brainpoolP224r1.txt | 7 + .../ectester/data/brainpool/brainpoolP224t1.txt | 7 + .../ectester/data/brainpool/brainpoolP256r1.txt | 7 + .../ectester/data/brainpool/brainpoolP256t1.txt | 7 + .../ectester/data/brainpool/brainpoolP320r1.txt | 7 + .../ectester/data/brainpool/brainpoolP320t1.txt | 7 + .../ectester/data/brainpool/brainpoolP384r1.txt | 7 + .../ectester/data/brainpool/brainpoolP384t1.txt | 7 + .../ectester/data/brainpool/brainpoolP512r1.txt | 7 + .../ectester/data/brainpool/brainpoolP512t1.txt | 7 + src/cz/crcs/ectester/data/ecsp128.txt | 7 - src/cz/crcs/ectester/data/ecsp128_pub.txt | 2 - src/cz/crcs/ectester/data/ecsp160.txt | 7 - src/cz/crcs/ectester/data/ecsp160_pub.txt | 2 - src/cz/crcs/ectester/data/ecsp192.txt | 7 - src/cz/crcs/ectester/data/ecsp192_pub.txt | 2 - src/cz/crcs/ectester/data/ecsp224.txt | 7 - src/cz/crcs/ectester/data/ecsp224_pub.txt | 2 - src/cz/crcs/ectester/data/ecsp256.txt | 7 - src/cz/crcs/ectester/data/ecsp256_pub.txt | 2 - src/cz/crcs/ectester/data/ecsp384.txt | 7 - src/cz/crcs/ectester/data/ecsp384_pub.txt | 2 - src/cz/crcs/ectester/data/ecsp521.txt | 7 - src/cz/crcs/ectester/data/ecsp521_pub.txt | 2 - src/cz/crcs/ectester/data/nist/p192.txt | 7 + src/cz/crcs/ectester/data/nist/p224.txt | 7 + src/cz/crcs/ectester/data/nist/p256.txt | 7 + src/cz/crcs/ectester/data/nist/p384.txt | 7 + src/cz/crcs/ectester/data/nist/p521.txt | 7 + src/cz/crcs/ectester/data/secg/secp192k1.txt | 7 + src/cz/crcs/ectester/data/secg/secp192r1.txt | 7 + src/cz/crcs/ectester/data/secg/secp224r1.txt | 7 + src/cz/crcs/ectester/data/secg/secp256k1.txt | 7 + src/cz/crcs/ectester/data/secg/secp256r1.txt | 7 + src/cz/crcs/ectester/data/secg/secp384r1.txt | 7 + src/cz/crcs/ectester/data/secg/secp521r1.txt | 7 + src/cz/crcs/ectester/data/secg/sect163k1.txt | 9 + src/cz/crcs/ectester/data/secg/sect163r1.txt | 9 + src/cz/crcs/ectester/data/secg/sect163r2.txt | 9 + src/cz/crcs/ectester/data/secg/sect233k1.txt | 7 + src/cz/crcs/ectester/data/secg/sect233r1.txt | 7 + src/cz/crcs/ectester/data/secg/sect239k1.txt | 7 + src/cz/crcs/ectester/data/secg/sect283k1.txt | 9 + src/cz/crcs/ectester/data/secg/sect283r1.txt | 9 + src/cz/crcs/ectester/data/secg/sect409k1.txt | 7 + src/cz/crcs/ectester/data/secg/sect409r1.txt | 7 + src/cz/crcs/ectester/data/secg/sect571k1.txt | 9 + src/cz/crcs/ectester/data/secg/sect571r1.txt | 9 + src/cz/crcs/ectester/data/secp192k1.txt | 7 - src/cz/crcs/ectester/data/secp192r1.txt | 7 - src/cz/crcs/ectester/data/secp224r1.txt | 7 - src/cz/crcs/ectester/data/secp256k1.txt | 7 - src/cz/crcs/ectester/data/secp256r1.txt | 7 - src/cz/crcs/ectester/data/secp384r1.txt | 7 - src/cz/crcs/ectester/data/secp521r1.txt | 7 - src/cz/crcs/ectester/data/sect163k1.txt | 9 - src/cz/crcs/ectester/data/sect163r1.txt | 9 - src/cz/crcs/ectester/data/sect163r2.txt | 9 - src/cz/crcs/ectester/data/sect233k1.txt | 7 - src/cz/crcs/ectester/data/sect233r1.txt | 7 - src/cz/crcs/ectester/data/sect239k1.txt | 7 - src/cz/crcs/ectester/data/sect283k1.txt | 9 - src/cz/crcs/ectester/data/sect283r1.txt | 9 - src/cz/crcs/ectester/data/sect409k1.txt | 7 - src/cz/crcs/ectester/data/sect409r1.txt | 7 - src/cz/crcs/ectester/data/sect571k1.txt | 9 - src/cz/crcs/ectester/data/sect571r1.txt | 9 - src/cz/crcs/ectester/data/smallpub/ecsp128.txt | 7 + src/cz/crcs/ectester/data/smallpub/ecsp128_pub.txt | 2 + src/cz/crcs/ectester/data/smallpub/ecsp160.txt | 7 + src/cz/crcs/ectester/data/smallpub/ecsp160_pub.txt | 2 + src/cz/crcs/ectester/data/smallpub/ecsp192.txt | 7 + src/cz/crcs/ectester/data/smallpub/ecsp192_pub.txt | 2 + src/cz/crcs/ectester/data/smallpub/ecsp224.txt | 7 + src/cz/crcs/ectester/data/smallpub/ecsp224_pub.txt | 2 + src/cz/crcs/ectester/data/smallpub/ecsp256.txt | 7 + src/cz/crcs/ectester/data/smallpub/ecsp256_pub.txt | 2 + src/cz/crcs/ectester/data/smallpub/ecsp384.txt | 7 + src/cz/crcs/ectester/data/smallpub/ecsp384_pub.txt | 2 + src/cz/crcs/ectester/data/smallpub/ecsp521.txt | 7 + src/cz/crcs/ectester/data/smallpub/ecsp521_pub.txt | 2 + src/cz/crcs/ectester/reader/CardMngr.java | 11 +- src/cz/crcs/ectester/reader/Command.java | 241 ++++++++++++ src/cz/crcs/ectester/reader/DirtyLogger.java | 1 + src/cz/crcs/ectester/reader/ECTester.java | 187 +++------- src/cz/crcs/ectester/reader/Response.java | 410 +++++++++++++++++++++ src/cz/crcs/ectester/reader/Util.java | 10 +- 95 files changed, 1184 insertions(+), 475 deletions(-) create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP160r1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP160t1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP192r1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP192t1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP224r1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP224t1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP256r1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP256t1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP320r1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP320t1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP384r1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP384t1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP512r1.txt create mode 100644 src/cz/crcs/ectester/data/brainpool/brainpoolP512t1.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp128.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp128_pub.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp160.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp160_pub.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp192.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp192_pub.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp224.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp224_pub.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp256.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp256_pub.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp384.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp384_pub.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp521.txt delete mode 100644 src/cz/crcs/ectester/data/ecsp521_pub.txt create mode 100644 src/cz/crcs/ectester/data/nist/p192.txt create mode 100644 src/cz/crcs/ectester/data/nist/p224.txt create mode 100644 src/cz/crcs/ectester/data/nist/p256.txt create mode 100644 src/cz/crcs/ectester/data/nist/p384.txt create mode 100644 src/cz/crcs/ectester/data/nist/p521.txt create mode 100644 src/cz/crcs/ectester/data/secg/secp192k1.txt create mode 100644 src/cz/crcs/ectester/data/secg/secp192r1.txt create mode 100644 src/cz/crcs/ectester/data/secg/secp224r1.txt create mode 100644 src/cz/crcs/ectester/data/secg/secp256k1.txt create mode 100644 src/cz/crcs/ectester/data/secg/secp256r1.txt create mode 100644 src/cz/crcs/ectester/data/secg/secp384r1.txt create mode 100644 src/cz/crcs/ectester/data/secg/secp521r1.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect163k1.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect163r1.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect163r2.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect233k1.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect233r1.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect239k1.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect283k1.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect283r1.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect409k1.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect409r1.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect571k1.txt create mode 100644 src/cz/crcs/ectester/data/secg/sect571r1.txt delete mode 100644 src/cz/crcs/ectester/data/secp192k1.txt delete mode 100644 src/cz/crcs/ectester/data/secp192r1.txt delete mode 100644 src/cz/crcs/ectester/data/secp224r1.txt delete mode 100644 src/cz/crcs/ectester/data/secp256k1.txt delete mode 100644 src/cz/crcs/ectester/data/secp256r1.txt delete mode 100644 src/cz/crcs/ectester/data/secp384r1.txt delete mode 100644 src/cz/crcs/ectester/data/secp521r1.txt delete mode 100644 src/cz/crcs/ectester/data/sect163k1.txt delete mode 100644 src/cz/crcs/ectester/data/sect163r1.txt delete mode 100644 src/cz/crcs/ectester/data/sect163r2.txt delete mode 100644 src/cz/crcs/ectester/data/sect233k1.txt delete mode 100644 src/cz/crcs/ectester/data/sect233r1.txt delete mode 100644 src/cz/crcs/ectester/data/sect239k1.txt delete mode 100644 src/cz/crcs/ectester/data/sect283k1.txt delete mode 100644 src/cz/crcs/ectester/data/sect283r1.txt delete mode 100644 src/cz/crcs/ectester/data/sect409k1.txt delete mode 100644 src/cz/crcs/ectester/data/sect409r1.txt delete mode 100644 src/cz/crcs/ectester/data/sect571k1.txt delete mode 100644 src/cz/crcs/ectester/data/sect571r1.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp128.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp128_pub.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp160.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp160_pub.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp192.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp192_pub.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp224.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp224_pub.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp256.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp256_pub.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp384.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp384_pub.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp521.txt create mode 100644 src/cz/crcs/ectester/data/smallpub/ecsp521_pub.txt create mode 100644 src/cz/crcs/ectester/reader/Command.java create mode 100644 src/cz/crcs/ectester/reader/Response.java (limited to 'src/cz/crcs/ectester/reader/CardMngr.java') diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap index 63dd209..a7da4dc 100644 Binary files a/!uploader/ectester.cap and b/!uploader/ectester.cap differ diff --git a/dist/ECTester.jar b/dist/ECTester.jar index a5bf4e3..b0dae23 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 47f9c94..417944c 100644 --- a/src/cz/crcs/ectester/applet/ECKeyGenerator.java +++ b/src/cz/crcs/ectester/applet/ECKeyGenerator.java @@ -72,6 +72,10 @@ public class ECKeyGenerator { byte alg = EC_Consts.getCurveType(curve); sw = ISO7816.SW_NO_ERROR; + if (params == EC_Consts.PARAMETERS_NONE) { + return sw; + } + short length; if (alg == KeyPair.ALG_EC_FP && (params & EC_Consts.PARAMETER_FP) != 0) { length = EC_Consts.getCurveParameter(curve, EC_Consts.PARAMETER_FP, buffer, offset); @@ -119,6 +123,9 @@ public class ECKeyGenerator { */ public short corruptCurve(KeyPair keypair, byte key, short corruptParams, byte corruption, byte[] buffer, short offset) { sw = ISO7816.SW_NO_ERROR; + if (corruptParams == EC_Consts.PARAMETERS_NONE) { + return sw; + } //go through param bit by bit, and invalidate all selected params short paramMask = EC_Consts.PARAMETER_FP; @@ -244,6 +251,9 @@ public class ECKeyGenerator { */ public short setExternalCurve(KeyPair keypair, byte key, short params, byte[] inBuffer, short inOffset) { sw = ISO7816.SW_NO_ERROR; + if (params == EC_Consts.PARAMETERS_NONE) { + return sw; + } short paramMask = EC_Consts.PARAMETER_FP; while (paramMask <= EC_Consts.PARAMETER_S) { @@ -261,11 +271,14 @@ public class ECKeyGenerator { } /** - * @param key - * @param param - * @param outputBuffer - * @param outputOffset - * @return + * Exports a selected parameter from a given keyPairs key. + * + * @param keypair keypair to export from + * @param key key to export from (KEY_PUBLIC | KEY_PRIVATE) + * @param param parameter to export (EC_Consts.PARAMETER_* || ...) + * @param outputBuffer buffer to write to + * @param outputOffset offset to start writing in buffer + * @return length of data written */ public short exportParameter(KeyPair keypair, byte key, short param, byte[] outputBuffer, short outputOffset) { sw = ISO7816.SW_NO_ERROR; @@ -319,18 +332,25 @@ public class ECKeyGenerator { } /** - * @param keypair - * @param key - * @param params - * @param buffer - * @param offset - * @return + * Exports selected parameters from a given keyPairs key. + * Raw parameter data is always prepended by its length as a + * short value. The order of parameters is the usual one from + * EC_Consts: field,a,b,g,r,k,w,s. + * + * @param keypair keyPair to export from + * @param key key to export from (KEY_PUBLIC || KEY_PRIVATE) + * @param params params to export (EC_Consts.PARAMETER_* | ...) + * @param buffer buffer to export to + * @param offset offset to start writing in buffer + * @return length of data written */ public short exportParameters(KeyPair keypair, byte key, short params, byte[] buffer, short offset) { sw = ISO7816.SW_NO_ERROR; + if (params == EC_Consts.PARAMETERS_NONE) { + return sw; + } short length = 0; - short paramMask = EC_Consts.PARAMETER_FP; while (paramMask <= EC_Consts.PARAMETER_S) { short masked = (short) (paramMask & params); @@ -352,11 +372,11 @@ public class ECKeyGenerator { /** * Copies this KeyPairs curve parameters to another ECKeyGenerator. * - * @param from - * @param to - * @param buffer - * @param offset - * @return + * @param from keyPair to copy from + * @param to keyPair to copy to + * @param buffer buffer to use for copying + * @param offset offset to use in buffer + * @return sw */ public short copyCurve(KeyPair from, KeyPair to, byte[] buffer, short offset) { sw = ISO7816.SW_NO_ERROR; diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index dd13fc3..dfdd0f0 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -169,31 +169,6 @@ public class ECTesterApplet extends Applet { apdu.setOutgoingAndSend((short) 0, len); } - /** - * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) - * @param keyLength key length to set - * @param keyClass key class to allocate - * @param buffer apdu buffer - * @param offset offset into apdu buffer - * @return length of data written to the buffer - */ - private short allocate(byte keyPair, short keyLength, byte keyClass, byte[] buffer, short offset) { - short length = 0; - if ((keyPair & KEYPAIR_LOCAL) != 0) { - localKeypair = keyGenerator.allocatePair(keyClass, keyLength); - Util.setShort(buffer, offset, keyGenerator.getSW()); - length += 2; - } - - if ((keyPair & KEYPAIR_REMOTE) != 0) { - remoteKeypair = keyGenerator.allocatePair(keyClass, keyLength); - Util.setShort(buffer, (short) (offset + length), keyGenerator.getSW()); - length += 2; - } - - return length; - } - /** * Sets curve parameters on local and remote keyPairs. * returns setCurve SWs, set params if export @@ -235,6 +210,102 @@ public class ECTesterApplet extends Applet { apdu.setOutgoingAndSend((short) 0, len); } + /** + * Generates the local and remote keyPairs. + * returns generate SWs, pubkey and privkey if export + * + * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) + * P2 = byte export (EXPORT_* | KEYPAIR_*) + */ + private void insGenerate(APDU apdu) { + apdu.setIncomingAndReceive(); + byte[] apdubuf = apdu.getBuffer(); + + byte keyPair = apdubuf[ISO7816.OFFSET_P1]; + byte export = apdubuf[ISO7816.OFFSET_P2]; + + short len = 0; + if ((keyPair & KEYPAIR_LOCAL) != 0) + len += generate(localKeypair, apdubuf, (short) 0); + if ((keyPair & KEYPAIR_REMOTE) != 0) + len += generate(remoteKeypair, apdubuf, len); + if ((export & KEYPAIR_LOCAL) != 0) + len += export(localKeypair, export, (short) (EC_Consts.PARAMETER_W | EC_Consts.PARAMETER_S), apdubuf, len); + if ((export & KEYPAIR_REMOTE) != 0) + len += export(remoteKeypair, export, (short) (EC_Consts.PARAMETER_W | EC_Consts.PARAMETER_S), apdubuf, len); + + apdu.setOutgoingAndSend((short) 0, len); + } + + /** + * Performs ECDH, between the pubkey specified in P1(local/remote) and the privkey specified in P2(local/remote). + * returns deriveSecret SW, if export != 0 => short secretlen, byte[] secret + * + * @param apdu P1 = byte pubkey (KEYPAIR_*) + * P2 = byte privkey (KEYPAIR_*) + * DATA = byte export (EXPORT_ECDH || 0) + * byte invalid (00 = valid, !00 = invalid) + */ + private void insECDH(APDU apdu) { + apdu.setIncomingAndReceive(); + byte[] apdubuf = apdu.getBuffer(); + + byte pubkey = apdubuf[ISO7816.OFFSET_P1]; + byte privkey = apdubuf[ISO7816.OFFSET_P2]; + byte export = apdubuf[ISO7816.OFFSET_CDATA]; + byte invalid = apdubuf[(short) (ISO7816.OFFSET_CDATA + 1)]; + + short len = ecdh(pubkey, privkey, export, invalid, apdubuf, (short) 0); + + apdu.setOutgoingAndSend((short) 0, len); + } + + /** + * Performs ECDSA signature and verification on data provided or random, using the keyPair in P1(local/remote). + * returns ecdsa SW, if export != 0 => short signature_length, byte[] signature + * + * @param apdu P1 = byte keyPair (KEYPAIR_*) + * P2 = byte export (EXPORT_SIG || 0) + * DATA = short dataLength (00 = random data generated, !00 = data length) + * byte[] data + */ + private void insECDSA(APDU apdu) { + apdu.setIncomingAndReceive(); + byte[] apdubuf = apdu.getBuffer(); + + byte keyPair = apdubuf[ISO7816.OFFSET_P1]; + byte export = apdubuf[ISO7816.OFFSET_P2]; + + short len = ecdsa(keyPair, export, apdubuf, ISO7816.OFFSET_CDATA, (short) 0); + + apdu.setOutgoingAndSend((short) 0, len); + } + + /** + * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) + * @param keyLength key length to set + * @param keyClass key class to allocate + * @param buffer apdu buffer + * @param offset offset into apdu buffer + * @return length of data written to the buffer + */ + private short allocate(byte keyPair, short keyLength, byte keyClass, byte[] buffer, short offset) { + short length = 0; + if ((keyPair & KEYPAIR_LOCAL) != 0) { + localKeypair = keyGenerator.allocatePair(keyClass, keyLength); + Util.setShort(buffer, offset, keyGenerator.getSW()); + length += 2; + } + + if ((keyPair & KEYPAIR_REMOTE) != 0) { + remoteKeypair = keyGenerator.allocatePair(keyClass, keyLength); + Util.setShort(buffer, (short) (offset + length), keyGenerator.getSW()); + length += 2; + } + + return length; + } + /** * @param keyPair KeyPair to set params on * @param curve curve to set (EC_Consts.CURVE_*) @@ -269,33 +340,6 @@ public class ECTesterApplet extends Applet { return 2; } - /** - * Generates the local and remote keyPairs. - * returns generate SWs, pubkey and privkey if export - * - * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) - * P2 = byte export (EXPORT_* | KEYPAIR_*) - */ - private void insGenerate(APDU apdu) { - apdu.setIncomingAndReceive(); - byte[] apdubuf = apdu.getBuffer(); - - byte keyPair = apdubuf[ISO7816.OFFSET_P1]; - byte export = apdubuf[ISO7816.OFFSET_P2]; - - short len = 0; - if ((keyPair & KEYPAIR_LOCAL) != 0) - len += generate(localKeypair, apdubuf, (short) 0); - if ((keyPair & KEYPAIR_REMOTE) != 0) - len += generate(remoteKeypair, apdubuf, len); - if ((export & KEYPAIR_LOCAL) != 0) - len += export(localKeypair, export, (short) (EC_Consts.PARAMETER_W | EC_Consts.PARAMETER_S), apdubuf, len); - if ((export & KEYPAIR_REMOTE) != 0) - len += export(remoteKeypair, export, (short) (EC_Consts.PARAMETER_W | EC_Consts.PARAMETER_S), apdubuf, len); - - apdu.setOutgoingAndSend((short) 0, len); - } - /** * @param keyPair KeyPair to generate * @param buffer buffer to write sw to @@ -333,29 +377,6 @@ public class ECTesterApplet extends Applet { return length; } - /** - * Performs ECDH, between the pubkey specified in P1(local/remote) and the privkey specified in P2(local/remote). - * returns deriveSecret SW, if export != 0 => short secretlen, byte[] secret - * - * @param apdu P1 = byte pubkey (KEYPAIR_*) - * P2 = byte privkey (KEYPAIR_*) - * DATA = byte export (EXPORT_ECDH || 0) - * byte invalid (00 = valid, !00 = invalid) - */ - private void insECDH(APDU apdu) { - apdu.setIncomingAndReceive(); - byte[] apdubuf = apdu.getBuffer(); - - byte pubkey = apdubuf[ISO7816.OFFSET_P1]; - byte privkey = apdubuf[ISO7816.OFFSET_P2]; - byte export = apdubuf[ISO7816.OFFSET_CDATA]; - byte invalid = apdubuf[(short) (ISO7816.OFFSET_CDATA + 1)]; - - short len = ecdh(pubkey, privkey, export, invalid, apdubuf, (short) 0); - - apdu.setOutgoingAndSend((short) 0, len); - } - /** * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) @@ -391,27 +412,6 @@ public class ECTesterApplet extends Applet { return length; } - /** - * Performs ECDSA signature and verification on data provided or random, using the keyPair in P1(local/remote). - * returns ecdsa SW, if export != 0 => short signature_length, byte[] signature - * - * @param apdu P1 = byte keyPair (KEYPAIR_*) - * P2 = byte export (EXPORT_SIG || 0) - * DATA = short dataLength (00 = random data generated, !00 = data length) - * byte[] data - */ - private void insECDSA(APDU apdu) { - apdu.setIncomingAndReceive(); - byte[] apdubuf = apdu.getBuffer(); - - byte keyPair = apdubuf[ISO7816.OFFSET_P1]; - byte export = apdubuf[ISO7816.OFFSET_P2]; - - short len = ecdsa(keyPair, export, apdubuf, ISO7816.OFFSET_CDATA, (short) 0); - - apdu.setOutgoingAndSend((short) 0, len); - } - /** * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) * @param export whether to export ECDSA signature diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP160r1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP160r1.txt new file mode 100644 index 0000000..69abf52 --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP160r1.txt @@ -0,0 +1,7 @@ +E95E4A5F737059DC60DFC7AD95B3D8139515620F, +340E7BE2A280EB74E2BE61BADA745D97E8F7C300, +1E589A8595423412134FAA2DBDEC95C8D8675E58, +BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3, +1667CB477A1A8EC338F94741669C976316DA6321, +E95E4A5F737059DC60DF5991D45029409E60FC09, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP160t1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP160t1.txt new file mode 100644 index 0000000..fadafdf --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP160t1.txt @@ -0,0 +1,7 @@ +24DBFF5DEC9B986BBFE5295A29BFBAE45E0F5D0B, +E95E4A5F737059DC60DFC7AD95B3D8139515620C, +7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380, +B199B13B9B34EFC1397E64BAEB05ACC265FF2378, +ADD6718B7C7C1961F0991B842443772152C9E0AD, +E95E4A5F737059DC60DF5991D45029409E60FC09, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP192r1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP192r1.txt new file mode 100644 index 0000000..3e6bed8 --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP192r1.txt @@ -0,0 +1,7 @@ +C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297, +6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF, +469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9, +C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6, +14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F, +C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP192t1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP192t1.txt new file mode 100644 index 0000000..cd52697 --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP192t1.txt @@ -0,0 +1,7 @@ +1B6F5CC8DB4DC7AF19458A9CB80DC2295E5EB9C3732104CB, +C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294, +13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79, +3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129, +97E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9, +C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP224r1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP224r1.txt new file mode 100644 index 0000000..12e536c --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP224r1.txt @@ -0,0 +1,7 @@ +D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF, +68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43, +2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B, +D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D, +58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD, +D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP224t1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP224t1.txt new file mode 100644 index 0000000..522d09e --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP224t1.txt @@ -0,0 +1,7 @@ +2DF271E14427A346910CF7A2E6CFA7B3F484E5C2CCE1C8B730E28B3F, +D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC, +4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D, +6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580, +374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C, +D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP256r1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP256r1.txt new file mode 100644 index 0000000..e0e50ad --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP256r1.txt @@ -0,0 +1,7 @@ +A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377, +7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9, +26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6, +8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262, +547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997, +A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP256t1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP256t1.txt new file mode 100644 index 0000000..f5bb2d6 --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP256t1.txt @@ -0,0 +1,7 @@ +3E2D4BD9597B58639AE7AA669CAB9837CF5CF20A2C852D10F655668DFC150EF0, +A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374, +662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04, +A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4, +2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE, +A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP320r1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP320r1.txt new file mode 100644 index 0000000..474fa9d --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP320r1.txt @@ -0,0 +1,7 @@ +D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27, +3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4, +520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6, +43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611, +14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1, +D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP320t1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP320t1.txt new file mode 100644 index 0000000..d92d52b --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP320t1.txt @@ -0,0 +1,7 @@ +15F75CAF668077F7E85B42EB01F0A81FF56ECD6191D55CB82B7D861458A18FEFC3E5AB7496F3C7B1, +D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24, +A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353, +925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED52, +63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3, +D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP384r1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP384r1.txt new file mode 100644 index 0000000..34ed1fc --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP384r1.txt @@ -0,0 +1,7 @@ +8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53, +7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826, +4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11, +1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E, +8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315, +8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP384t1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP384t1.txt new file mode 100644 index 0000000..6bb42c9 --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP384t1.txt @@ -0,0 +1,7 @@ +41DFE8DD399331F7166A66076734A89CD0D2BCDB7D068E44E1F378F41ECBAE97D2D63DBC87BCCDDCCC5DA39E8589291C, +8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50, +7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE, +18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC, +25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928, +8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP512r1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP512r1.txt new file mode 100644 index 0000000..39e205e --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP512r1.txt @@ -0,0 +1,7 @@ +AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3, +7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA, +3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723, +81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822, +7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892, +AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069, +1 diff --git a/src/cz/crcs/ectester/data/brainpool/brainpoolP512t1.txt b/src/cz/crcs/ectester/data/brainpool/brainpoolP512t1.txt new file mode 100644 index 0000000..288c2c1 --- /dev/null +++ b/src/cz/crcs/ectester/data/brainpool/brainpoolP512t1.txt @@ -0,0 +1,7 @@ +12EE58E6764838B69782136F0F2D3BA06E27695716054092E60A80BEDB212B64E585D90BCE13761F85C3F1D2A64E3BE8FEA2220F01EBA5EEB0F35DBD29D922AB, +AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0, +7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E, +640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA, +5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332, +AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069, +1 diff --git a/src/cz/crcs/ectester/data/ecsp128.txt b/src/cz/crcs/ectester/data/ecsp128.txt deleted file mode 100644 index 29cfe3b..0000000 --- a/src/cz/crcs/ectester/data/ecsp128.txt +++ /dev/null @@ -1,7 +0,0 @@ -cfba21fd0483b1f300fa2506a5a566ef, -36d9a5acac27a008e36cbe3e9f103fde, -a67cf5fa09fb1db902068c87046ae21e, -47d78391a4b9fff6a0db1292f9cd0e6a, -9aed9c92f8bb3dbd42402165a270bd6f, -cfba21fd0483b1f333d61a5af6ada2c7, -1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp128_pub.txt b/src/cz/crcs/ectester/data/ecsp128_pub.txt deleted file mode 100644 index ee1f34d..0000000 --- a/src/cz/crcs/ectester/data/ecsp128_pub.txt +++ /dev/null @@ -1,2 +0,0 @@ -63901e122761d9c16565b2f38e991f71, -b9d99fbc3154a96ca23ecff770cbbe4f \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp160.txt b/src/cz/crcs/ectester/data/ecsp160.txt deleted file mode 100644 index 49824d9..0000000 --- a/src/cz/crcs/ectester/data/ecsp160.txt +++ /dev/null @@ -1,7 +0,0 @@ -dc13490ff9857b111f44c0500770a6457e683223, -a3ecd7d51e79d72d2700184c795aa8a6b8e66573, -8ac43592905f995cb13f3694317bf470adafb645, -5f8e88afc117c722859fe8e55647bca69ba82150, -93e6dcaee271e9f2838c98b7d06eccc5d7c800e5, -dc13490ff9857b111f446ef4a6d1e1715f6a6dff, -1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp160_pub.txt b/src/cz/crcs/ectester/data/ecsp160_pub.txt deleted file mode 100644 index e2e164e..0000000 --- a/src/cz/crcs/ectester/data/ecsp160_pub.txt +++ /dev/null @@ -1,2 +0,0 @@ -59c9c3c8aef29f1c1c500cafb4726da6086e6eb0, -d695a76005eddb26afd40ee20904778bb3497bb1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp192.txt b/src/cz/crcs/ectester/data/ecsp192.txt deleted file mode 100644 index ccb5537..0000000 --- a/src/cz/crcs/ectester/data/ecsp192.txt +++ /dev/null @@ -1,7 +0,0 @@ -ce714cc3a15ce7e5dab068c9a1f8be00aad480abccaeefc3, -597c781f64c33eb8ef919c415911518ea323be88b9437caf, -f81585a1b18f233d70add7ee1342d2035c386a92e3ab8320, -150ff0a40deac6462b5987418617fdeeb6bfd76d4d60a067, -843d577371c5dce122c2ff206b2f42fa0b842b49bdaf990f, -ce714cc3a15ce7e5dab068c9a30bc92915bd8662ae882887, -1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp192_pub.txt b/src/cz/crcs/ectester/data/ecsp192_pub.txt deleted file mode 100644 index ec7f822..0000000 --- a/src/cz/crcs/ectester/data/ecsp192_pub.txt +++ /dev/null @@ -1,2 +0,0 @@ -17047f91dbe33032c9d09bd29ceadd8a09ccc32ac6309541, -6a726de54fbd59cfc352e838b337fa005a97180816135e6a \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp224.txt b/src/cz/crcs/ectester/data/ecsp224.txt deleted file mode 100644 index 894e669..0000000 --- a/src/cz/crcs/ectester/data/ecsp224.txt +++ /dev/null @@ -1,7 +0,0 @@ -eed4c3d98f1c9b9518f116263db770366877d12df6a9cf08b96dd4bb, -8d4dddb0317d6a6bf9a4dbbed3a43fa21f79869c5ab9729d239e9282, -46873614be3dffc9218082322210c0616140286f2d160503c1a9250d, -961bbb1fc9955a71c91a50aedcd2f14fccb660af992b0030b9c90b36, -1c00f6d0bd405dd7d3016fb8c0c75e4ecec70fe61237f6d24008a5fd, -eed4c3d98f1c9b9518f116263db821c36a06adae17162ad3162f68c3, -1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp224_pub.txt b/src/cz/crcs/ectester/data/ecsp224_pub.txt deleted file mode 100644 index 0999b99..0000000 --- a/src/cz/crcs/ectester/data/ecsp224_pub.txt +++ /dev/null @@ -1,2 +0,0 @@ -cfd92aea0f79190c48ca703eb8a9baa7099a23bb39578261fe4d0f04, -257a3d98de44bd25404977a4ac7fc56d3d4e827f085b7cf5247524c4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp256.txt b/src/cz/crcs/ectester/data/ecsp256.txt deleted file mode 100644 index 17387a6..0000000 --- a/src/cz/crcs/ectester/data/ecsp256.txt +++ /dev/null @@ -1,7 +0,0 @@ -c9a803b1eaf849f1c02cfd1dbfac68623985c88b37103b338ae11d2597ee8445, -4841c5775a24a884ca36ec362b44645a2f60b25d002c4fc1d9f139870fe0cc71, -1b097456751f3534190dae568f80a2c6ff55dddfe072a7dc6467a4b6476b6880, -a1fd34a27afb1340b8e4a7db2a5ec5a1432c6dc8555af9f78fca2cf740cab2b7, -98419c698cab6c7dbb53eb2751417b52ccded4680c5e09543f93c7886c3a173e, -c9a803b1eaf849f1c02cfd1dbfac6863128c5b1fc5acd5b5e0fc0a7311fb5b1d, -1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp256_pub.txt b/src/cz/crcs/ectester/data/ecsp256_pub.txt deleted file mode 100644 index a8f0492..0000000 --- a/src/cz/crcs/ectester/data/ecsp256_pub.txt +++ /dev/null @@ -1,2 +0,0 @@ -75fce70968862d53e29548aad70582514e960d8128bd3c5f8c4dbe2cf8dad653, -55aa4b7d3882fb0a83bd00c9c3bae17f1024d64aec67e1db38ef671e6350beae \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp384.txt b/src/cz/crcs/ectester/data/ecsp384.txt deleted file mode 100644 index 9acae3f..0000000 --- a/src/cz/crcs/ectester/data/ecsp384.txt +++ /dev/null @@ -1,7 +0,0 @@ -d0df6c96cff7081be80d22b005758a2e2f046e15fe020ef886e21b492ac57257a923144bcad989ab6341bd3b700f914b, -45c64503be019afd3462b361ad2b2a3bca0aeccc5494a624fb632455e62b4f0c98f944fa97c37811da039823cd77c906, -d85583f7f11ad23ec75ed5a414153a06d6640936b8103f5df691fa95cf2afa78f3ea5addc225b144964048c9f7592ae4, -2b1341d12dff4f9cf9427c4752962b4c2bdc8fbcd80652516c421cc523212a01ea63c79d6e9a9c84933e353e212416ec, -ce416c6e75fa9fd205ed48fc4e3099cbb1d6ed031b7ddbff1d634eb97a83d9b780cfd4dedfdd2c7604d143196c08d933, -d0df6c96cff7081be80d22b005758a2e2f046e15fe020ef7664ed51d7701c86bf2a1e9f3002c26fe002314c3c92f1ca9, -1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp384_pub.txt b/src/cz/crcs/ectester/data/ecsp384_pub.txt deleted file mode 100644 index 4eb4a96..0000000 --- a/src/cz/crcs/ectester/data/ecsp384_pub.txt +++ /dev/null @@ -1,2 +0,0 @@ -a4bd575bf20300b0cf8a2f41dd5a03e908966a4229a5f22f5c190d3641ac2d32b7b24a63482cbbcd0c2257f834834ef1, -38d51c8f9e90592f567e81d0e4855e79731b5797857a4c7dc270653bc9f0c31e84693007b09cebf710d5ae3237303949 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp521.txt b/src/cz/crcs/ectester/data/ecsp521.txt deleted file mode 100644 index 1d36bd7..0000000 --- a/src/cz/crcs/ectester/data/ecsp521.txt +++ /dev/null @@ -1,7 +0,0 @@ -01d3df430924956e210a605b4dbf4a2e909d7a801658978c88ffd68dcc817f5cc79cf188d9ee82d1a51c44cbd31e9cc5b816d76d5b1312b005f7b68919e275dac99f, -00401639f36f2ee45fc164ea3e1f14f4803fd7a77ffdfb392c3f8fe95d1aea331467f4618d59aeee49d5d7c70caf320f7dd1ac166114f562413449991d3aa1a2c49e, -004a26a8c47fce204ba953015fa86708c0de720f27523988b097e774168c15f7a215aaf18a5f1b9579ab3db935d45be14c9a87b71170396909b14d06f7a09975b3a6, -01c880ae0a355a52791fc9600fd8b35726e9d799101489161c8f90a9c6631d09b3cb347584837d9deb8566a9c5846aded0d01eb947b4affd34e8ea7dbe733cbedafa, -00050f12672f163f19d5d493eb82ef777b0213dd4e0cf75a9b99724fbdb54b0cc4e037bf86a48bac28467bdd936c314ce13f6ec7ec69ea09ae4f5444df4b2a117a66, -01d3df430924956e210a605b4dbf4a2e909d7a801658978c88ffd68dcc817f5cc7ba0838717c1947f93cfdd3ed87ec2c2df181c7ada553346ec1495732a1e7ffe9b3, -1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/ecsp521_pub.txt b/src/cz/crcs/ectester/data/ecsp521_pub.txt deleted file mode 100644 index 0e3f320..0000000 --- a/src/cz/crcs/ectester/data/ecsp521_pub.txt +++ /dev/null @@ -1,2 +0,0 @@ -002844df0f31f46a40e6c7006cde99155bd5d18d0e4150178a8e307d6aec08fd02d466c03c49b49c2654b7c9a32d88ca014016a7eddd44217be915505d228efb9389, -0105921e2172c3050ba4c9d2e744fc5b7b5e8451751e6780c6de88229497be7d23550beefa0cb7fafebb4dd9fad1244c6733befe5a97710f0dc56dc08d9d9df9d846 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/nist/p192.txt b/src/cz/crcs/ectester/data/nist/p192.txt new file mode 100644 index 0000000..0402da7 --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/p192.txt @@ -0,0 +1,7 @@ +fffffffffffffffffffffffffffffffeffffffffffffffff, +fffffffffffffffffffffffffffffffefffffffffffffffc, +64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1, +188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012, +07192b95ffc8da78631011ed6b24cdd573f977a11e794811, +ffffffffffffffffffffffff99def836146bc9b1b4d22831, +1 diff --git a/src/cz/crcs/ectester/data/nist/p224.txt b/src/cz/crcs/ectester/data/nist/p224.txt new file mode 100644 index 0000000..8dca9fe --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/p224.txt @@ -0,0 +1,7 @@ +ffffffffffffffffffffffffffffffff000000000000000000000001, +fffffffffffffffffffffffffffffffefffffffffffffffffffffffe, +b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4, +b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21, +bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34, +ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d, +1 diff --git a/src/cz/crcs/ectester/data/nist/p256.txt b/src/cz/crcs/ectester/data/nist/p256.txt new file mode 100644 index 0000000..bc67187 --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/p256.txt @@ -0,0 +1,7 @@ +ffffffff00000001000000000000000000000000ffffffffffffffffffffffff, +ffffffff00000001000000000000000000000000fffffffffffffffffffffffc, +5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b, +6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296, +4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5, +ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551, +1 diff --git a/src/cz/crcs/ectester/data/nist/p384.txt b/src/cz/crcs/ectester/data/nist/p384.txt new file mode 100644 index 0000000..7808451 --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/p384.txt @@ -0,0 +1,7 @@ +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff, +fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc, +b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef, +aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7, +3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f, +ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973, +1 diff --git a/src/cz/crcs/ectester/data/nist/p521.txt b/src/cz/crcs/ectester/data/nist/p521.txt new file mode 100644 index 0000000..df7c46d --- /dev/null +++ b/src/cz/crcs/ectester/data/nist/p521.txt @@ -0,0 +1,7 @@ +1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff, +1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc, +051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00, +c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66, +11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650, +1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409, +1 diff --git a/src/cz/crcs/ectester/data/secg/secp192k1.txt b/src/cz/crcs/ectester/data/secg/secp192k1.txt new file mode 100644 index 0000000..c408b5e --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp192k1.txt @@ -0,0 +1,7 @@ +FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFEE37, +00000000 00000000 00000000 00000000 00000000 00000000, +00000000 00000000 00000000 00000000 00000000 00000003, +DB4FF10E C057E9AE 26B07D02 80B7F434 1DA5D1B1 EAE06C7D, +9B2F2F6D 9C5628A7 844163D0 15BE8634 4082AA88 D95E2F9D, +FFFFFFFF FFFFFFFF FFFFFFFE 26F2FC17 0F69466A 74DEFD8D, +1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/secg/secp192r1.txt b/src/cz/crcs/ectester/data/secg/secp192r1.txt new file mode 100644 index 0000000..29305b0 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp192r1.txt @@ -0,0 +1,7 @@ +FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFF, +FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFC, +64210519 E59C80E7 0FA7E9AB 72243049 FEB8DEEC C146B9B1, +188DA80E B03090F6 7CBF20EB 43A18800 F4FF0AFD 82FF1012, +07192B95 FFC8DA78 631011ED 6B24CDD5 73F977A1 1E794811, +FFFFFFFF FFFFFFFF FFFFFFFF 99DEF836 146BC9B1 B4D22831, +1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/secg/secp224r1.txt b/src/cz/crcs/ectester/data/secg/secp224r1.txt new file mode 100644 index 0000000..f8f592e --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp224r1.txt @@ -0,0 +1,7 @@ +FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 00000000 00000001, +FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFE, +B4050A85 0C04B3AB F5413256 5044B0B7 D7BFD8BA 270B3943 2355FFB4, +B70E0CBD 6BB4BF7F 321390B9 4A03C1D3 56C21122 343280D6 115C1D21, +BD376388 B5F723FB 4C22DFE6 CD4375A0 5A074764 44D58199 85007E34, +FFFFFFFF FFFFFFFF FFFFFFFF FFFF16A2 E0B8F03E 13DD2945 5C5C2A3D, +1 diff --git a/src/cz/crcs/ectester/data/secg/secp256k1.txt b/src/cz/crcs/ectester/data/secg/secp256k1.txt new file mode 100644 index 0000000..19eeef7 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp256k1.txt @@ -0,0 +1,7 @@ +FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F, +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000007, +79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798, +483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8, +FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141, +1 diff --git a/src/cz/crcs/ectester/data/secg/secp256r1.txt b/src/cz/crcs/ectester/data/secg/secp256r1.txt new file mode 100644 index 0000000..060f5aa --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp256r1.txt @@ -0,0 +1,7 @@ +FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFF, +FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFC, +5AC635D8 AA3A93E7 B3EBBD55 769886BC 651D06B0 CC53B0F6 3BCE3C3E 27D2604B, +6B17D1F2 E12C4247 F8BCE6E5 63A440F2 77037D81 2DEB33A0 F4A13945 D898C296, +4FE342E2 FE1A7F9B 8EE7EB4A 7C0F9E16 2BCE3357 6B315ECE CBB64068 37BF51F5, +FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551, +1 diff --git a/src/cz/crcs/ectester/data/secg/secp384r1.txt b/src/cz/crcs/ectester/data/secg/secp384r1.txt new file mode 100644 index 0000000..08472ae --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp384r1.txt @@ -0,0 +1,7 @@ +FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF 00000000 00000000 FFFFFFFF, +FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF 00000000 00000000 FFFFFFFC, +B3312FA7 E23EE7E4 988E056B E3F82D19 181D9C6E FE814112 0314088F 5013875A C656398D 8A2ED19D 2A85C8ED D3EC2AEF, +AA87CA22 BE8B0537 8EB1C71E F320AD74 6E1D3B62 8BA79B98 59F741E0 82542A38 5502F25D BF55296C 3A545E38 72760AB7, +3617DE4A 96262C6F 5D9E98BF 9292DC29 F8F41DBD 289A147C E9DA3113 B5F0B8C0 0A60B1CE 1D7E819D 7A431D7C 90EA0E5F, +FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF C7634D81 F4372DDF 581A0DB2 48B0A77A ECEC196A CCC52973, +1 diff --git a/src/cz/crcs/ectester/data/secg/secp521r1.txt b/src/cz/crcs/ectester/data/secg/secp521r1.txt new file mode 100644 index 0000000..9e0f5d3 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/secp521r1.txt @@ -0,0 +1,7 @@ +01FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF, +01FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFC, +0051 953EB961 8E1C9A1F 929A21A0 B68540EE A2DA725B 99B315F3 B8B48991 8EF109E1 56193951 EC7E937B 1652C0BD 3BB1BF07 3573DF88 3D2C34F1 EF451FD4 6B503F00, +00C6 858E06B7 0404E9CD 9E3ECB66 2395B442 9C648139 053FB521 F828AF60 6B4D3DBA A14B5E77 EFE75928 FE1DC127 A2FFA8DE 3348B3C1 856A429B F97E7E31 C2E5BD66, +0118 39296A78 9A3BC004 5C8A5FB4 2C7D1BD9 98F54449 579B4468 17AFBD17 273E662C 97EE7299 5EF42640 C550B901 3FAD0761 353C7086 A272C240 88BE9476 9FD16650, +01FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFA 51868783 BF2F966B 7FCC0148 F709A5D0 3BB5C9B8 899C47AE BB6FB71E 91386409, +1 diff --git a/src/cz/crcs/ectester/data/secg/sect163k1.txt b/src/cz/crcs/ectester/data/secg/sect163k1.txt new file mode 100644 index 0000000..6e5142e --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect163k1.txt @@ -0,0 +1,9 @@ +0007, +0006, +0003, +00 00000000 00000000 00000000 00000000 00000001, +00 00000000 00000000 00000000 00000000 00000001, +02 FE13C053 7BBC11AC AA07D793 DE4E6D5E 5C94EEE8, +02 89070FB0 5D38FF58 321F2E80 0536D538 CCDAA3D9, +04 00000000 00000000 00020108 A2E0CC0D 99F8A5EF, +2 diff --git a/src/cz/crcs/ectester/data/secg/sect163r1.txt b/src/cz/crcs/ectester/data/secg/sect163r1.txt new file mode 100644 index 0000000..879f79b --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect163r1.txt @@ -0,0 +1,9 @@ +0007, +0006, +0003, +07 B6882CAA EFA84F95 54FF8428 BD88E246 D2782AE2, +07 13612DCD DCB40AAB 946BDA29 CA91F73A F958AFD9, +03 69979697 AB438977 89566789 567F787A 7876A654, +00 435EDB42 EFAFB298 9D51FEFC E3C80988 F41FF883, +03 FFFFFFFF FFFFFFFF FFFF48AA B689C29C A710279B, +2 diff --git a/src/cz/crcs/ectester/data/secg/sect163r2.txt b/src/cz/crcs/ectester/data/secg/sect163r2.txt new file mode 100644 index 0000000..eb7d453 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect163r2.txt @@ -0,0 +1,9 @@ +0007, +0006, +0003, +00 00000000 00000000 00000000 00000000 00000001, +02 0A601907 B8C953CA 1481EB10 512F7874 4A3205FD, +03 F0EBA162 86A2D57E A0991168 D4994637 E8343E36, +00 D51FBC6C 71A0094F A2CDD545 B11C5C0C 797324F1, +04 00000000 00000000 000292FE 77E70C12 A4234C33, +2 diff --git a/src/cz/crcs/ectester/data/secg/sect233k1.txt b/src/cz/crcs/ectester/data/secg/sect233k1.txt new file mode 100644 index 0000000..b85fef0 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect233k1.txt @@ -0,0 +1,7 @@ +004A, +0000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, +0000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, +0172 32BA853A 7E731AF1 29F22FF4 149563A4 19C26BF5 0A4C9D6E EFAD6126, +01DB 537DECE8 19B7F70F 555A67C4 27A8CD9B F18AEB9B 56E0C110 56FAE6A3, +80 00000000 00000000 00000000 00069D5B B915BCD4 6EFB1AD5 F173ABDF, +4 diff --git a/src/cz/crcs/ectester/data/secg/sect233r1.txt b/src/cz/crcs/ectester/data/secg/sect233r1.txt new file mode 100644 index 0000000..d0c6f14 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect233r1.txt @@ -0,0 +1,7 @@ +004A, +0000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, +0066 647EDE6C 332C7F8C 0923BB58 213B333B 20E9CE42 81FE115F 7D8F90AD, +00FA C9DFCBAC 8313BB21 39F1BB75 5FEF65BC 391F8B36 F8F8EB73 71FD558B, +0100 6A08A419 03350678 E58528BE BF8A0BEF F867A7CA 36716F7E 01F81052, +0100 00000000 00000000 00000000 0013E974 E72F8A69 22031D26 03CFE0D7, +2 diff --git a/src/cz/crcs/ectester/data/secg/sect239k1.txt b/src/cz/crcs/ectester/data/secg/sect239k1.txt new file mode 100644 index 0000000..d01bb08 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect239k1.txt @@ -0,0 +1,7 @@ +009E, +0000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, +0000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, +29A0 B6A887A9 83E97309 88A68727 A8B2D126 C44CC2CC 7B2A6555 193035DC, +7631 0804F12E 549BDB01 1C103089 E73510AC B275FC31 2A5DC6B7 6553F0CA, +2000 00000000 00000000 00000000 005A79FE C67CB6E9 1F1C1DA8 00E478A5, +4 diff --git a/src/cz/crcs/ectester/data/secg/sect283k1.txt b/src/cz/crcs/ectester/data/secg/sect283k1.txt new file mode 100644 index 0000000..cc62698 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect283k1.txt @@ -0,0 +1,9 @@ +000C, +0007, +0005, +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, +0503213F 78CA4488 3F1A3B81 62F188E5 53CD265F 23C1567A 16876913 B0C2AC24 58492836, +01CCDA38 0F1C9E31 8D90F95D 07E5426F E87E45C0 E8184698 E4596236 4E341161 77DD2259, +01FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFE9AE 2ED07577 265DFF7F 94451E06 1E163C61, +4 diff --git a/src/cz/crcs/ectester/data/secg/sect283r1.txt b/src/cz/crcs/ectester/data/secg/sect283r1.txt new file mode 100644 index 0000000..27e2ff2 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect283r1.txt @@ -0,0 +1,9 @@ +000C, +0007, +0005, +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, +027B680A C8B8596D A5A4AF8A 19A0303F CA97FD76 45309FA2 A581485A F6263E31 3B79A2F5, +05F93925 8DB7DD90 E1934F8C 70B0DFEC 2EED25B8 557EAC9C 80E2E198 F8CDBECD 86B12053, +03676854 FE24141C B98FE6D4 B20D02B4 516FF702 350EDDB0 826779C8 13F0DF45 BE8112F4, +03FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFEF90 399660FC 938A9016 5B042A7C EFADB307, +2 diff --git a/src/cz/crcs/ectester/data/secg/sect409k1.txt b/src/cz/crcs/ectester/data/secg/sect409k1.txt new file mode 100644 index 0000000..aeb2e76 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect409k1.txt @@ -0,0 +1,7 @@ +0057, +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, +0060F05F 658F49C1 AD3AB189 0F718421 0EFD0987 E307C84C 27ACCFB8 F9F67CC2 C460189E B5AAAA62 EE222EB1 B35540CF E9023746, +01E36905 0B7C4E42 ACBA1DAC BF04299C 3460782F 918EA427 E6325165 E9EA10E3 DA5F6C42 E9C55215 AA9CA27A 5863EC48 D8E0286B, +7FFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFE5F 83B2D4EA 20400EC4 557D5ED3 E3E7CA5B 4B5C83B8 E01E5FCF, +4 diff --git a/src/cz/crcs/ectester/data/secg/sect409r1.txt b/src/cz/crcs/ectester/data/secg/sect409r1.txt new file mode 100644 index 0000000..5ac19dc --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect409r1.txt @@ -0,0 +1,7 @@ +0057, +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, +0021A5C2 C8EE9FEB 5C4B9A75 3B7B476B 7FD6422E F1F3DD67 4761FA99 D6AC27C8 A9A197B2 72822F6C D57A55AA 4F50AE31 7B13545F, +015D4860 D088DDB3 496B0C60 64756260 441CDE4A F1771D4D B01FFE5B 34E59703 DC255A86 8A118051 5603AEAB 60794E54 BB7996A7, +0061B1CF AB6BE5F3 2BBFA783 24ED106A 7636B9C5 A7BD198D 0158AA4F 5488D08F 38514F1F DF4B4F40 D2181B36 81C364BA 0273C706, +01000000 00000000 00000000 00000000 00000000 00000000 000001E2 AAD6A612 F33307BE 5FA47C3C 9E052F83 8164CD37 D9A21173, +2 diff --git a/src/cz/crcs/ectester/data/secg/sect571k1.txt b/src/cz/crcs/ectester/data/secg/sect571k1.txt new file mode 100644 index 0000000..7d5fdf4 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect571k1.txt @@ -0,0 +1,9 @@ +000A, +0005, +0002, +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, +026EB7A8 59923FBC 82189631 F8103FE4 AC9CA297 0012D5D4 60248048 01841CA4 43709584 93B205E6 47DA304D B4CEB08C BBD1BA39 494776FB 988B4717 4DCA88C7 E2945283 A01C8972, +0349DC80 7F4FBF37 4F4AEADE 3BCA9531 4DD58CEC 9F307A54 FFC61EFC 006D8A2C 9D4979C0 AC44AEA7 4FBEBBB9 F772AEDC B620B01A 7BA7AF1B 320430C8 591984F6 01CD4C14 3EF1C7A3, +02000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 131850E1 F19A63E4 B391A8DB 917F4138 B630D84B E5D63938 1E91DEB4 5CFE778F 637C1001, +4 diff --git a/src/cz/crcs/ectester/data/secg/sect571r1.txt b/src/cz/crcs/ectester/data/secg/sect571r1.txt new file mode 100644 index 0000000..850f0b9 --- /dev/null +++ b/src/cz/crcs/ectester/data/secg/sect571r1.txt @@ -0,0 +1,9 @@ +000A, +0005, +0002, +00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, +02F40E7E 2221F295 DE297117 B7F3D62F 5C6A97FF CB8CEFF1 CD6BA8CE 4A9A18AD 84FFABBD 8EFA5933 2BE7AD67 56A66E29 4AFD185A 78FF12AA 520E4DE7 39BACA0C 7FFEFF7F 2955727A, +0303001D 34B85629 6C16C0D4 0D3CD775 0A93D1D2 955FA80A A5F40FC8 DB7B2ABD BDE53950 F4C0D293 CDD711A3 5B67FB14 99AE6003 8614F139 4ABFA3B4 C850D927 E1E7769C 8EEC2D19, +037BF273 42DA639B 6DCCFFFE B73D69D7 8C6C27A6 009CBBCA 1980F853 3921E8A6 84423E43 BAB08A57 6291AF8F 461BB2A8 B3531D2F 0485C19B 16E2F151 6E23DD3C 1A4827AF 1B8AC15B, +03FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF E661CE18 FF559873 08059B18 6823851E C7DD9CA1 161DE93D 5174D66E 8382E9BB 2FE84E47, +2 diff --git a/src/cz/crcs/ectester/data/secp192k1.txt b/src/cz/crcs/ectester/data/secp192k1.txt deleted file mode 100644 index c408b5e..0000000 --- a/src/cz/crcs/ectester/data/secp192k1.txt +++ /dev/null @@ -1,7 +0,0 @@ -FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFEE37, -00000000 00000000 00000000 00000000 00000000 00000000, -00000000 00000000 00000000 00000000 00000000 00000003, -DB4FF10E C057E9AE 26B07D02 80B7F434 1DA5D1B1 EAE06C7D, -9B2F2F6D 9C5628A7 844163D0 15BE8634 4082AA88 D95E2F9D, -FFFFFFFF FFFFFFFF FFFFFFFE 26F2FC17 0F69466A 74DEFD8D, -1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/secp192r1.txt b/src/cz/crcs/ectester/data/secp192r1.txt deleted file mode 100644 index 29305b0..0000000 --- a/src/cz/crcs/ectester/data/secp192r1.txt +++ /dev/null @@ -1,7 +0,0 @@ -FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFF, -FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFC, -64210519 E59C80E7 0FA7E9AB 72243049 FEB8DEEC C146B9B1, -188DA80E B03090F6 7CBF20EB 43A18800 F4FF0AFD 82FF1012, -07192B95 FFC8DA78 631011ED 6B24CDD5 73F977A1 1E794811, -FFFFFFFF FFFFFFFF FFFFFFFF 99DEF836 146BC9B1 B4D22831, -1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/secp224r1.txt b/src/cz/crcs/ectester/data/secp224r1.txt deleted file mode 100644 index f8f592e..0000000 --- a/src/cz/crcs/ectester/data/secp224r1.txt +++ /dev/null @@ -1,7 +0,0 @@ -FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF 00000000 00000000 00000001, -FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF FFFFFFFF FFFFFFFE, -B4050A85 0C04B3AB F5413256 5044B0B7 D7BFD8BA 270B3943 2355FFB4, -B70E0CBD 6BB4BF7F 321390B9 4A03C1D3 56C21122 343280D6 115C1D21, -BD376388 B5F723FB 4C22DFE6 CD4375A0 5A074764 44D58199 85007E34, -FFFFFFFF FFFFFFFF FFFFFFFF FFFF16A2 E0B8F03E 13DD2945 5C5C2A3D, -1 diff --git a/src/cz/crcs/ectester/data/secp256k1.txt b/src/cz/crcs/ectester/data/secp256k1.txt deleted file mode 100644 index 19eeef7..0000000 --- a/src/cz/crcs/ectester/data/secp256k1.txt +++ /dev/null @@ -1,7 +0,0 @@ -FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F, -00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, -00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000007, -79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798, -483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8, -FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141, -1 diff --git a/src/cz/crcs/ectester/data/secp256r1.txt b/src/cz/crcs/ectester/data/secp256r1.txt deleted file mode 100644 index 060f5aa..0000000 --- a/src/cz/crcs/ectester/data/secp256r1.txt +++ /dev/null @@ -1,7 +0,0 @@ -FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFF, -FFFFFFFF 00000001 00000000 00000000 00000000 FFFFFFFF FFFFFFFF FFFFFFFC, -5AC635D8 AA3A93E7 B3EBBD55 769886BC 651D06B0 CC53B0F6 3BCE3C3E 27D2604B, -6B17D1F2 E12C4247 F8BCE6E5 63A440F2 77037D81 2DEB33A0 F4A13945 D898C296, -4FE342E2 FE1A7F9B 8EE7EB4A 7C0F9E16 2BCE3357 6B315ECE CBB64068 37BF51F5, -FFFFFFFF 00000000 FFFFFFFF FFFFFFFF BCE6FAAD A7179E84 F3B9CAC2 FC632551, -1 diff --git a/src/cz/crcs/ectester/data/secp384r1.txt b/src/cz/crcs/ectester/data/secp384r1.txt deleted file mode 100644 index 08472ae..0000000 --- a/src/cz/crcs/ectester/data/secp384r1.txt +++ /dev/null @@ -1,7 +0,0 @@ -FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF 00000000 00000000 FFFFFFFF, -FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFFFF 00000000 00000000 FFFFFFFC, -B3312FA7 E23EE7E4 988E056B E3F82D19 181D9C6E FE814112 0314088F 5013875A C656398D 8A2ED19D 2A85C8ED D3EC2AEF, -AA87CA22 BE8B0537 8EB1C71E F320AD74 6E1D3B62 8BA79B98 59F741E0 82542A38 5502F25D BF55296C 3A545E38 72760AB7, -3617DE4A 96262C6F 5D9E98BF 9292DC29 F8F41DBD 289A147C E9DA3113 B5F0B8C0 0A60B1CE 1D7E819D 7A431D7C 90EA0E5F, -FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF C7634D81 F4372DDF 581A0DB2 48B0A77A ECEC196A CCC52973, -1 diff --git a/src/cz/crcs/ectester/data/secp521r1.txt b/src/cz/crcs/ectester/data/secp521r1.txt deleted file mode 100644 index 9e0f5d3..0000000 --- a/src/cz/crcs/ectester/data/secp521r1.txt +++ /dev/null @@ -1,7 +0,0 @@ -01FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF, -01FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFC, -0051 953EB961 8E1C9A1F 929A21A0 B68540EE A2DA725B 99B315F3 B8B48991 8EF109E1 56193951 EC7E937B 1652C0BD 3BB1BF07 3573DF88 3D2C34F1 EF451FD4 6B503F00, -00C6 858E06B7 0404E9CD 9E3ECB66 2395B442 9C648139 053FB521 F828AF60 6B4D3DBA A14B5E77 EFE75928 FE1DC127 A2FFA8DE 3348B3C1 856A429B F97E7E31 C2E5BD66, -0118 39296A78 9A3BC004 5C8A5FB4 2C7D1BD9 98F54449 579B4468 17AFBD17 273E662C 97EE7299 5EF42640 C550B901 3FAD0761 353C7086 A272C240 88BE9476 9FD16650, -01FF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFA 51868783 BF2F966B 7FCC0148 F709A5D0 3BB5C9B8 899C47AE BB6FB71E 91386409, -1 diff --git a/src/cz/crcs/ectester/data/sect163k1.txt b/src/cz/crcs/ectester/data/sect163k1.txt deleted file mode 100644 index 6e5142e..0000000 --- a/src/cz/crcs/ectester/data/sect163k1.txt +++ /dev/null @@ -1,9 +0,0 @@ -0007, -0006, -0003, -00 00000000 00000000 00000000 00000000 00000001, -00 00000000 00000000 00000000 00000000 00000001, -02 FE13C053 7BBC11AC AA07D793 DE4E6D5E 5C94EEE8, -02 89070FB0 5D38FF58 321F2E80 0536D538 CCDAA3D9, -04 00000000 00000000 00020108 A2E0CC0D 99F8A5EF, -2 diff --git a/src/cz/crcs/ectester/data/sect163r1.txt b/src/cz/crcs/ectester/data/sect163r1.txt deleted file mode 100644 index 879f79b..0000000 --- a/src/cz/crcs/ectester/data/sect163r1.txt +++ /dev/null @@ -1,9 +0,0 @@ -0007, -0006, -0003, -07 B6882CAA EFA84F95 54FF8428 BD88E246 D2782AE2, -07 13612DCD DCB40AAB 946BDA29 CA91F73A F958AFD9, -03 69979697 AB438977 89566789 567F787A 7876A654, -00 435EDB42 EFAFB298 9D51FEFC E3C80988 F41FF883, -03 FFFFFFFF FFFFFFFF FFFF48AA B689C29C A710279B, -2 diff --git a/src/cz/crcs/ectester/data/sect163r2.txt b/src/cz/crcs/ectester/data/sect163r2.txt deleted file mode 100644 index eb7d453..0000000 --- a/src/cz/crcs/ectester/data/sect163r2.txt +++ /dev/null @@ -1,9 +0,0 @@ -0007, -0006, -0003, -00 00000000 00000000 00000000 00000000 00000001, -02 0A601907 B8C953CA 1481EB10 512F7874 4A3205FD, -03 F0EBA162 86A2D57E A0991168 D4994637 E8343E36, -00 D51FBC6C 71A0094F A2CDD545 B11C5C0C 797324F1, -04 00000000 00000000 000292FE 77E70C12 A4234C33, -2 diff --git a/src/cz/crcs/ectester/data/sect233k1.txt b/src/cz/crcs/ectester/data/sect233k1.txt deleted file mode 100644 index b85fef0..0000000 --- a/src/cz/crcs/ectester/data/sect233k1.txt +++ /dev/null @@ -1,7 +0,0 @@ -004A, -0000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, -0000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, -0172 32BA853A 7E731AF1 29F22FF4 149563A4 19C26BF5 0A4C9D6E EFAD6126, -01DB 537DECE8 19B7F70F 555A67C4 27A8CD9B F18AEB9B 56E0C110 56FAE6A3, -80 00000000 00000000 00000000 00069D5B B915BCD4 6EFB1AD5 F173ABDF, -4 diff --git a/src/cz/crcs/ectester/data/sect233r1.txt b/src/cz/crcs/ectester/data/sect233r1.txt deleted file mode 100644 index d0c6f14..0000000 --- a/src/cz/crcs/ectester/data/sect233r1.txt +++ /dev/null @@ -1,7 +0,0 @@ -004A, -0000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, -0066 647EDE6C 332C7F8C 0923BB58 213B333B 20E9CE42 81FE115F 7D8F90AD, -00FA C9DFCBAC 8313BB21 39F1BB75 5FEF65BC 391F8B36 F8F8EB73 71FD558B, -0100 6A08A419 03350678 E58528BE BF8A0BEF F867A7CA 36716F7E 01F81052, -0100 00000000 00000000 00000000 0013E974 E72F8A69 22031D26 03CFE0D7, -2 diff --git a/src/cz/crcs/ectester/data/sect239k1.txt b/src/cz/crcs/ectester/data/sect239k1.txt deleted file mode 100644 index d01bb08..0000000 --- a/src/cz/crcs/ectester/data/sect239k1.txt +++ /dev/null @@ -1,7 +0,0 @@ -009E, -0000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, -0000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, -29A0 B6A887A9 83E97309 88A68727 A8B2D126 C44CC2CC 7B2A6555 193035DC, -7631 0804F12E 549BDB01 1C103089 E73510AC B275FC31 2A5DC6B7 6553F0CA, -2000 00000000 00000000 00000000 005A79FE C67CB6E9 1F1C1DA8 00E478A5, -4 diff --git a/src/cz/crcs/ectester/data/sect283k1.txt b/src/cz/crcs/ectester/data/sect283k1.txt deleted file mode 100644 index cc62698..0000000 --- a/src/cz/crcs/ectester/data/sect283k1.txt +++ /dev/null @@ -1,9 +0,0 @@ -000C, -0007, -0005, -00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, -00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, -0503213F 78CA4488 3F1A3B81 62F188E5 53CD265F 23C1567A 16876913 B0C2AC24 58492836, -01CCDA38 0F1C9E31 8D90F95D 07E5426F E87E45C0 E8184698 E4596236 4E341161 77DD2259, -01FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFE9AE 2ED07577 265DFF7F 94451E06 1E163C61, -4 diff --git a/src/cz/crcs/ectester/data/sect283r1.txt b/src/cz/crcs/ectester/data/sect283r1.txt deleted file mode 100644 index 27e2ff2..0000000 --- a/src/cz/crcs/ectester/data/sect283r1.txt +++ /dev/null @@ -1,9 +0,0 @@ -000C, -0007, -0005, -00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, -027B680A C8B8596D A5A4AF8A 19A0303F CA97FD76 45309FA2 A581485A F6263E31 3B79A2F5, -05F93925 8DB7DD90 E1934F8C 70B0DFEC 2EED25B8 557EAC9C 80E2E198 F8CDBECD 86B12053, -03676854 FE24141C B98FE6D4 B20D02B4 516FF702 350EDDB0 826779C8 13F0DF45 BE8112F4, -03FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFEF90 399660FC 938A9016 5B042A7C EFADB307, -2 diff --git a/src/cz/crcs/ectester/data/sect409k1.txt b/src/cz/crcs/ectester/data/sect409k1.txt deleted file mode 100644 index aeb2e76..0000000 --- a/src/cz/crcs/ectester/data/sect409k1.txt +++ /dev/null @@ -1,7 +0,0 @@ -0057, -00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, -00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, -0060F05F 658F49C1 AD3AB189 0F718421 0EFD0987 E307C84C 27ACCFB8 F9F67CC2 C460189E B5AAAA62 EE222EB1 B35540CF E9023746, -01E36905 0B7C4E42 ACBA1DAC BF04299C 3460782F 918EA427 E6325165 E9EA10E3 DA5F6C42 E9C55215 AA9CA27A 5863EC48 D8E0286B, -7FFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFE5F 83B2D4EA 20400EC4 557D5ED3 E3E7CA5B 4B5C83B8 E01E5FCF, -4 diff --git a/src/cz/crcs/ectester/data/sect409r1.txt b/src/cz/crcs/ectester/data/sect409r1.txt deleted file mode 100644 index 5ac19dc..0000000 --- a/src/cz/crcs/ectester/data/sect409r1.txt +++ /dev/null @@ -1,7 +0,0 @@ -0057, -00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, -0021A5C2 C8EE9FEB 5C4B9A75 3B7B476B 7FD6422E F1F3DD67 4761FA99 D6AC27C8 A9A197B2 72822F6C D57A55AA 4F50AE31 7B13545F, -015D4860 D088DDB3 496B0C60 64756260 441CDE4A F1771D4D B01FFE5B 34E59703 DC255A86 8A118051 5603AEAB 60794E54 BB7996A7, -0061B1CF AB6BE5F3 2BBFA783 24ED106A 7636B9C5 A7BD198D 0158AA4F 5488D08F 38514F1F DF4B4F40 D2181B36 81C364BA 0273C706, -01000000 00000000 00000000 00000000 00000000 00000000 000001E2 AAD6A612 F33307BE 5FA47C3C 9E052F83 8164CD37 D9A21173, -2 diff --git a/src/cz/crcs/ectester/data/sect571k1.txt b/src/cz/crcs/ectester/data/sect571k1.txt deleted file mode 100644 index 7d5fdf4..0000000 --- a/src/cz/crcs/ectester/data/sect571k1.txt +++ /dev/null @@ -1,9 +0,0 @@ -000A, -0005, -0002, -00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000, -00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, -026EB7A8 59923FBC 82189631 F8103FE4 AC9CA297 0012D5D4 60248048 01841CA4 43709584 93B205E6 47DA304D B4CEB08C BBD1BA39 494776FB 988B4717 4DCA88C7 E2945283 A01C8972, -0349DC80 7F4FBF37 4F4AEADE 3BCA9531 4DD58CEC 9F307A54 FFC61EFC 006D8A2C 9D4979C0 AC44AEA7 4FBEBBB9 F772AEDC B620B01A 7BA7AF1B 320430C8 591984F6 01CD4C14 3EF1C7A3, -02000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 131850E1 F19A63E4 B391A8DB 917F4138 B630D84B E5D63938 1E91DEB4 5CFE778F 637C1001, -4 diff --git a/src/cz/crcs/ectester/data/sect571r1.txt b/src/cz/crcs/ectester/data/sect571r1.txt deleted file mode 100644 index 850f0b9..0000000 --- a/src/cz/crcs/ectester/data/sect571r1.txt +++ /dev/null @@ -1,9 +0,0 @@ -000A, -0005, -0002, -00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001, -02F40E7E 2221F295 DE297117 B7F3D62F 5C6A97FF CB8CEFF1 CD6BA8CE 4A9A18AD 84FFABBD 8EFA5933 2BE7AD67 56A66E29 4AFD185A 78FF12AA 520E4DE7 39BACA0C 7FFEFF7F 2955727A, -0303001D 34B85629 6C16C0D4 0D3CD775 0A93D1D2 955FA80A A5F40FC8 DB7B2ABD BDE53950 F4C0D293 CDD711A3 5B67FB14 99AE6003 8614F139 4ABFA3B4 C850D927 E1E7769C 8EEC2D19, -037BF273 42DA639B 6DCCFFFE B73D69D7 8C6C27A6 009CBBCA 1980F853 3921E8A6 84423E43 BAB08A57 6291AF8F 461BB2A8 B3531D2F 0485C19B 16E2F151 6E23DD3C 1A4827AF 1B8AC15B, -03FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF E661CE18 FF559873 08059B18 6823851E C7DD9CA1 161DE93D 5174D66E 8382E9BB 2FE84E47, -2 diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp128.txt b/src/cz/crcs/ectester/data/smallpub/ecsp128.txt new file mode 100644 index 0000000..29cfe3b --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp128.txt @@ -0,0 +1,7 @@ +cfba21fd0483b1f300fa2506a5a566ef, +36d9a5acac27a008e36cbe3e9f103fde, +a67cf5fa09fb1db902068c87046ae21e, +47d78391a4b9fff6a0db1292f9cd0e6a, +9aed9c92f8bb3dbd42402165a270bd6f, +cfba21fd0483b1f333d61a5af6ada2c7, +1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp128_pub.txt b/src/cz/crcs/ectester/data/smallpub/ecsp128_pub.txt new file mode 100644 index 0000000..ee1f34d --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp128_pub.txt @@ -0,0 +1,2 @@ +63901e122761d9c16565b2f38e991f71, +b9d99fbc3154a96ca23ecff770cbbe4f \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp160.txt b/src/cz/crcs/ectester/data/smallpub/ecsp160.txt new file mode 100644 index 0000000..49824d9 --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp160.txt @@ -0,0 +1,7 @@ +dc13490ff9857b111f44c0500770a6457e683223, +a3ecd7d51e79d72d2700184c795aa8a6b8e66573, +8ac43592905f995cb13f3694317bf470adafb645, +5f8e88afc117c722859fe8e55647bca69ba82150, +93e6dcaee271e9f2838c98b7d06eccc5d7c800e5, +dc13490ff9857b111f446ef4a6d1e1715f6a6dff, +1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp160_pub.txt b/src/cz/crcs/ectester/data/smallpub/ecsp160_pub.txt new file mode 100644 index 0000000..e2e164e --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp160_pub.txt @@ -0,0 +1,2 @@ +59c9c3c8aef29f1c1c500cafb4726da6086e6eb0, +d695a76005eddb26afd40ee20904778bb3497bb1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp192.txt b/src/cz/crcs/ectester/data/smallpub/ecsp192.txt new file mode 100644 index 0000000..ccb5537 --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp192.txt @@ -0,0 +1,7 @@ +ce714cc3a15ce7e5dab068c9a1f8be00aad480abccaeefc3, +597c781f64c33eb8ef919c415911518ea323be88b9437caf, +f81585a1b18f233d70add7ee1342d2035c386a92e3ab8320, +150ff0a40deac6462b5987418617fdeeb6bfd76d4d60a067, +843d577371c5dce122c2ff206b2f42fa0b842b49bdaf990f, +ce714cc3a15ce7e5dab068c9a30bc92915bd8662ae882887, +1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp192_pub.txt b/src/cz/crcs/ectester/data/smallpub/ecsp192_pub.txt new file mode 100644 index 0000000..ec7f822 --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp192_pub.txt @@ -0,0 +1,2 @@ +17047f91dbe33032c9d09bd29ceadd8a09ccc32ac6309541, +6a726de54fbd59cfc352e838b337fa005a97180816135e6a \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp224.txt b/src/cz/crcs/ectester/data/smallpub/ecsp224.txt new file mode 100644 index 0000000..894e669 --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp224.txt @@ -0,0 +1,7 @@ +eed4c3d98f1c9b9518f116263db770366877d12df6a9cf08b96dd4bb, +8d4dddb0317d6a6bf9a4dbbed3a43fa21f79869c5ab9729d239e9282, +46873614be3dffc9218082322210c0616140286f2d160503c1a9250d, +961bbb1fc9955a71c91a50aedcd2f14fccb660af992b0030b9c90b36, +1c00f6d0bd405dd7d3016fb8c0c75e4ecec70fe61237f6d24008a5fd, +eed4c3d98f1c9b9518f116263db821c36a06adae17162ad3162f68c3, +1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp224_pub.txt b/src/cz/crcs/ectester/data/smallpub/ecsp224_pub.txt new file mode 100644 index 0000000..0999b99 --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp224_pub.txt @@ -0,0 +1,2 @@ +cfd92aea0f79190c48ca703eb8a9baa7099a23bb39578261fe4d0f04, +257a3d98de44bd25404977a4ac7fc56d3d4e827f085b7cf5247524c4 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp256.txt b/src/cz/crcs/ectester/data/smallpub/ecsp256.txt new file mode 100644 index 0000000..17387a6 --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp256.txt @@ -0,0 +1,7 @@ +c9a803b1eaf849f1c02cfd1dbfac68623985c88b37103b338ae11d2597ee8445, +4841c5775a24a884ca36ec362b44645a2f60b25d002c4fc1d9f139870fe0cc71, +1b097456751f3534190dae568f80a2c6ff55dddfe072a7dc6467a4b6476b6880, +a1fd34a27afb1340b8e4a7db2a5ec5a1432c6dc8555af9f78fca2cf740cab2b7, +98419c698cab6c7dbb53eb2751417b52ccded4680c5e09543f93c7886c3a173e, +c9a803b1eaf849f1c02cfd1dbfac6863128c5b1fc5acd5b5e0fc0a7311fb5b1d, +1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp256_pub.txt b/src/cz/crcs/ectester/data/smallpub/ecsp256_pub.txt new file mode 100644 index 0000000..a8f0492 --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp256_pub.txt @@ -0,0 +1,2 @@ +75fce70968862d53e29548aad70582514e960d8128bd3c5f8c4dbe2cf8dad653, +55aa4b7d3882fb0a83bd00c9c3bae17f1024d64aec67e1db38ef671e6350beae \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp384.txt b/src/cz/crcs/ectester/data/smallpub/ecsp384.txt new file mode 100644 index 0000000..9acae3f --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp384.txt @@ -0,0 +1,7 @@ +d0df6c96cff7081be80d22b005758a2e2f046e15fe020ef886e21b492ac57257a923144bcad989ab6341bd3b700f914b, +45c64503be019afd3462b361ad2b2a3bca0aeccc5494a624fb632455e62b4f0c98f944fa97c37811da039823cd77c906, +d85583f7f11ad23ec75ed5a414153a06d6640936b8103f5df691fa95cf2afa78f3ea5addc225b144964048c9f7592ae4, +2b1341d12dff4f9cf9427c4752962b4c2bdc8fbcd80652516c421cc523212a01ea63c79d6e9a9c84933e353e212416ec, +ce416c6e75fa9fd205ed48fc4e3099cbb1d6ed031b7ddbff1d634eb97a83d9b780cfd4dedfdd2c7604d143196c08d933, +d0df6c96cff7081be80d22b005758a2e2f046e15fe020ef7664ed51d7701c86bf2a1e9f3002c26fe002314c3c92f1ca9, +1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp384_pub.txt b/src/cz/crcs/ectester/data/smallpub/ecsp384_pub.txt new file mode 100644 index 0000000..4eb4a96 --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp384_pub.txt @@ -0,0 +1,2 @@ +a4bd575bf20300b0cf8a2f41dd5a03e908966a4229a5f22f5c190d3641ac2d32b7b24a63482cbbcd0c2257f834834ef1, +38d51c8f9e90592f567e81d0e4855e79731b5797857a4c7dc270653bc9f0c31e84693007b09cebf710d5ae3237303949 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp521.txt b/src/cz/crcs/ectester/data/smallpub/ecsp521.txt new file mode 100644 index 0000000..1d36bd7 --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp521.txt @@ -0,0 +1,7 @@ +01d3df430924956e210a605b4dbf4a2e909d7a801658978c88ffd68dcc817f5cc79cf188d9ee82d1a51c44cbd31e9cc5b816d76d5b1312b005f7b68919e275dac99f, +00401639f36f2ee45fc164ea3e1f14f4803fd7a77ffdfb392c3f8fe95d1aea331467f4618d59aeee49d5d7c70caf320f7dd1ac166114f562413449991d3aa1a2c49e, +004a26a8c47fce204ba953015fa86708c0de720f27523988b097e774168c15f7a215aaf18a5f1b9579ab3db935d45be14c9a87b71170396909b14d06f7a09975b3a6, +01c880ae0a355a52791fc9600fd8b35726e9d799101489161c8f90a9c6631d09b3cb347584837d9deb8566a9c5846aded0d01eb947b4affd34e8ea7dbe733cbedafa, +00050f12672f163f19d5d493eb82ef777b0213dd4e0cf75a9b99724fbdb54b0cc4e037bf86a48bac28467bdd936c314ce13f6ec7ec69ea09ae4f5444df4b2a117a66, +01d3df430924956e210a605b4dbf4a2e909d7a801658978c88ffd68dcc817f5cc7ba0838717c1947f93cfdd3ed87ec2c2df181c7ada553346ec1495732a1e7ffe9b3, +1 \ No newline at end of file diff --git a/src/cz/crcs/ectester/data/smallpub/ecsp521_pub.txt b/src/cz/crcs/ectester/data/smallpub/ecsp521_pub.txt new file mode 100644 index 0000000..0e3f320 --- /dev/null +++ b/src/cz/crcs/ectester/data/smallpub/ecsp521_pub.txt @@ -0,0 +1,2 @@ +002844df0f31f46a40e6c7006cde99155bd5d18d0e4150178a8e307d6aec08fd02d466c03c49b49c2654b7c9a32d88ca014016a7eddd44217be915505d228efb9389, +0105921e2172c3050ba4c9d2e744fc5b7b5e8451751e6780c6de88229497be7d23550beefa0cb7fafebb4dd9fad1244c6733befe5a97710f0dc56dc08d9d9df9d846 \ No newline at end of file diff --git a/src/cz/crcs/ectester/reader/CardMngr.java b/src/cz/crcs/ectester/reader/CardMngr.java index 9cdd055..d95b7e5 100644 --- a/src/cz/crcs/ectester/reader/CardMngr.java +++ b/src/cz/crcs/ectester/reader/CardMngr.java @@ -255,11 +255,13 @@ public class CardMngr { public ResponseAPDU sendAPDUSimulator(CommandAPDU apdu) { System.out.println(">>>>"); + System.out.println(apdu); System.out.println(Util.bytesToHex(apdu.getBytes())); ResponseAPDU response = simulator.transmitCommand(apdu); byte[] responseBytes = response.getBytes(); + System.out.println(response); System.out.println(Util.bytesToHex(responseBytes)); System.out.println("<<<<"); @@ -285,13 +287,4 @@ public class CardMngr { CommandAPDU commandAPDU = new CommandAPDU(apdu); return send(commandAPDU); } - - public ResponseAPDU[] send(CommandAPDU... apdus) throws CardException { - ResponseAPDU[] result = new ResponseAPDU[apdus.length]; - for (int i = 0; i < apdus.length; i++) { - result[i] = send(apdus[i]); - } - return result; - } - } diff --git a/src/cz/crcs/ectester/reader/Command.java b/src/cz/crcs/ectester/reader/Command.java new file mode 100644 index 0000000..c5fd465 --- /dev/null +++ b/src/cz/crcs/ectester/reader/Command.java @@ -0,0 +1,241 @@ +package cz.crcs.ectester.reader; + +import cz.crcs.ectester.applet.ECTesterApplet; + +import javax.smartcardio.CardException; +import javax.smartcardio.CommandAPDU; +import javax.smartcardio.ResponseAPDU; +import java.util.ArrayList; +import java.util.List; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class Command { + protected CommandAPDU cmd; + protected CardMngr cardManager; + + protected Command(CardMngr cardManager) { + this.cardManager = cardManager; + } + + public CommandAPDU getAPDU() { + return cmd; + } + + /** + * + * @return + * @throws CardException + */ + public abstract Response send() throws CardException; + + public static List sendAll(List commands) throws CardException { + List result = new ArrayList<>(); + for (Command cmd : commands) { + result.add(cmd.send()); + } + return result; + } + + /** + * + */ + public static class Allocate extends Command { + private byte keyPair; + private short keyLength; + private byte keyClass; + + /** + * Creates the INS_ALLOCATE instruction. + * + * @param cardManager + * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) + * @param keyLength key length to set + * @param keyClass key class to allocate + */ + public Allocate(CardMngr cardManager, byte keyPair, short keyLength, byte keyClass) { + super(cardManager); + this.keyPair = keyPair; + this.keyLength = keyLength; + this.keyClass = keyClass; + + byte[] data = new byte[]{0, 0, keyClass}; + Util.setShort(data, 0, keyLength); + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, 0x00, data); + } + + @Override + public Response.Allocate send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Allocate(response, elapsed, keyPair, keyLength, keyClass); + } + } + + /** + * + */ + public static class Set extends Command { + private byte keyPair; + private byte export; + private byte curve; + private short params; + private short corrupted; + private byte corruption; + private byte[] external; + + /** + * Creates the INS_SET instruction. + * + * @param cardManager + * @param keyPair which keyPair to set params on, local/remote (KEYPAIR_* || ...) + * @param export whether to export set params from keyPair + * @param curve curve to set (EC_Consts.CURVE_*) + * @param params parameters to set (EC_Consts.PARAMETER_* | ...) + * @param corrupted parameters to corrupt (EC_Consts.PARAMETER_* | ...) + * @param corruption corruption type (EC_Consts.CORRUPTION_*) + * @param external external curve data, can be null + */ + public Set(CardMngr cardManager, byte keyPair, byte export, byte curve, short params, short corrupted, byte corruption, byte[] external) { + super(cardManager); + this.keyPair = keyPair; + this.export = export; + this.curve = curve; + this.params = params; + this.corrupted = corrupted; + this.corruption = corruption; + this.external = external; + + int len = external != null ? 6 + 2 + external.length : 6; + byte[] data = new byte[len]; + data[0] = curve; + Util.setShort(data, 1, params); + Util.setShort(data, 3, corrupted); + data[5] = corruption; + if (external != null) { + System.arraycopy(external, 0, data, 6, external.length); + } + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SET, keyPair, export, data); + } + + @Override + public Response.Set send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Set(response, elapsed, keyPair, export, curve, params, corrupted); + } + } + + /** + * + */ + public static class Generate extends Command { + private byte keyPair; + private byte export; + + /** + * Creates the INS_GENERATE instruction. + * + * @param cardManager + * @param keyPair which keyPair to generate, local/remote (KEYPAIR_* || ...) + * @param export whether to export generated keys from keyPair + */ + public Generate(CardMngr cardManager, byte keyPair, byte export) { + super(cardManager); + this.keyPair = keyPair; + this.export = export; + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_GENERATE, keyPair, export); + } + + @Override + public Response.Generate send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Generate(response, elapsed, keyPair, export); + } + } + + /** + * + */ + public static class ECDH extends Command { + private byte pubkey; + private byte privkey; + private byte export; + private byte invalid; + + /** + * Creates the INS_ECDH instruction. + * + * @param cardManager + * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param export whether to export ECDH secret + * @param invalid whether to invalidate the pubkey before ECDH + */ + public ECDH(CardMngr cardManager, byte pubkey, byte privkey, byte export, byte invalid) { + super(cardManager); + this.pubkey = pubkey; + this.privkey = privkey; + this.export = export; + this.invalid = invalid; + + byte[] data = new byte[]{export, invalid}; + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, pubkey, privkey, data); + } + + @Override + public Response.ECDH send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.ECDH(response, elapsed, pubkey, privkey, export, invalid); + } + } + + public static class ECDSA extends Command { + private byte keyPair; + private byte export; + private byte[] raw; + + /** + * Creates the INS_ECDSA instruction. + * + * @param cardManager + * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) + * @param export whether to export ECDSA signature + * @param raw data to sign, can be null, in which case random data is signed. + */ + public ECDSA(CardMngr cardManager, byte keyPair, byte export, byte[] raw) { + super(cardManager); + this.keyPair = keyPair; + this.export = export; + this.raw = raw; + + int len = raw != null ? raw.length : 0; + byte[] data = new byte[2 + len]; + Util.setShort(data, 0, (short) len); + if (raw != null) { + System.arraycopy(raw, 0, data, 2, len); + } + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA, keyPair, export, data); + } + + @Override + public Response.ECDSA send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.ECDSA(response, elapsed, keyPair, export, raw); + } + } +} + diff --git a/src/cz/crcs/ectester/reader/DirtyLogger.java b/src/cz/crcs/ectester/reader/DirtyLogger.java index f69557d..7a2c70d 100644 --- a/src/cz/crcs/ectester/reader/DirtyLogger.java +++ b/src/cz/crcs/ectester/reader/DirtyLogger.java @@ -2,6 +2,7 @@ package cz.crcs.ectester.reader; import java.io.FileWriter; import java.io.IOException; +import java.io.OutputStream; /** * @author Petr Svenda petr@svenda.com diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 1f70d4f..e5a2b70 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -27,15 +27,12 @@ import javacard.security.KeyPair; import org.apache.commons.cli.*; import javax.smartcardio.CardException; -import javax.smartcardio.CommandAPDU; -import javax.smartcardio.ResponseAPDU; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.util.ArrayList; -import java.util.Comparator; import java.util.List; /** @@ -187,10 +184,8 @@ public class ECTester { } } catch (MissingArgumentException maex) { System.err.println("Option, " + maex.getOption().getOpt() + " requires an argument: " + maex.getOption().getArgName()); - } catch (AlreadySelectedException asex) { - System.err.println(asex.getMessage()); } catch (ParseException | CardException pex) { - pex.printStackTrace(); + System.err.println(pex.getMessage()); } catch (NumberFormatException nfex) { System.err.println("Not a number. " + nfex.getMessage()); nfex.printStackTrace(System.err); @@ -370,8 +365,7 @@ public class ECTester { */ private void generate() throws CardException, IOException { byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; - CommandAPDU[] prepare = prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass); - cardManager.send(prepare); + List prepare = Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass)); FileWriter keysFile = new FileWriter(optOutput); keysFile.write("index;time;pubW;privS\n"); @@ -379,30 +373,27 @@ public class ECTester { int generated = 0; int retry = 0; while (generated < optGenerateAmount || optGenerateAmount == 0) { - CommandAPDU generate = insGenerate(ECTesterApplet.KEYPAIR_LOCAL, (byte) (ECTesterApplet.EXPORT_BOTH | ECTesterApplet.KEYPAIR_LOCAL)); - long elapsed = -System.nanoTime(); - ResponseAPDU response = cardManager.send(generate); - elapsed += System.nanoTime(); - - byte[] bytes = response.getData(); - if (bytes.length <= 2) { - //error, retry 10 times + Command.Generate generate = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (byte) (ECTesterApplet.EXPORT_BOTH | ECTesterApplet.KEYPAIR_LOCAL)); + Response.Generate response = generate.send(); + long elapsed = response.getDuration(); + + if (!response.successful()) { if (retry < 10) { retry++; + continue; } else { System.err.println("Keys could not be generated."); break; } - } else { - short publicLength = Util.getShort(bytes, 2); - String pubkey = Util.bytesToHex(bytes, 4, publicLength, false); - short privateLength = Util.getShort(bytes, 4 + publicLength); - String privkey = Util.bytesToHex(bytes, 6 + publicLength, privateLength, false); - - keysFile.write(String.format("%d;%d;%s;%s\n", generated, elapsed / 1000000, pubkey, privkey)); - keysFile.flush(); - generated++; } + systemOutLogger.println(response.toString()); + + String pub = Util.bytesToHex(response.getPublic(ECTesterApplet.KEYPAIR_LOCAL), false); + String priv = Util.bytesToHex(response.getPrivate(ECTesterApplet.KEYPAIR_LOCAL), false); + String line = String.format("%d;%d;%s;%s\n", generated, elapsed / 1000000, pub, priv); + keysFile.write(line); + keysFile.flush(); + generated++; } keysFile.close(); } @@ -460,23 +451,24 @@ public class ECTester { */ private void ecdh() throws IOException, CardException { byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; - CommandAPDU[] curve = prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) optBits, keyClass); - cardManager.send(curve); + List ecdh = Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) optBits, keyClass)); if (optPublic != null || optPrivate != null || optKey != null) { - CommandAPDU local = insGenerate(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE); - cardManager.send(local); - CommandAPDU remote = prepareKey(ECTesterApplet.KEYPAIR_REMOTE); - cardManager.send(remote); + Response local = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE).send(); + Response remote = prepareKey(ECTesterApplet.KEYPAIR_REMOTE).send(); + ecdh.add(local); + ecdh.add(remote); } else { - CommandAPDU both = insGenerate(ECTesterApplet.KEYPAIR_BOTH, ECTesterApplet.EXPORT_NONE); - cardManager.send(both); + Response both = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH, ECTesterApplet.EXPORT_NONE).send(); + ecdh.add(both); } - CommandAPDU ecdh = insECDH(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_ECDH, (byte) 0); - ResponseAPDU response = cardManager.send(ecdh); - //TODO print response SWs/error codes - //TODO output to file + Response.ECDH perform = new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_ECDH, (byte) 0).send(); + ecdh.add(perform); + for (Response r : ecdh) { + systemOutLogger.println(r.toString()); + } + //TODO check perform.hasSecret(), write perform.getSecret to file if -o } /** @@ -487,16 +479,15 @@ public class ECTester { */ private void ecdsa() throws CardException, IOException { byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; - CommandAPDU[] curve = prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass); - cardManager.send(curve); + List ecdsa = Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass)); + Response keys; if (optKey != null || (optPublic != null && optPrivate != null)) { - CommandAPDU set = prepareKey(ECTesterApplet.KEYPAIR_LOCAL); - cardManager.send(set); + keys = prepareKey(ECTesterApplet.KEYPAIR_LOCAL).send(); } else { - CommandAPDU generate = insGenerate(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE); - cardManager.send(generate); + keys = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE).send(); } + ecdsa.add(keys); //read file, if asked to sign byte[] data = null; @@ -509,96 +500,12 @@ public class ECTester { data = Files.readAllBytes(in.toPath()); } - CommandAPDU ecdsa = insECDSA(ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_SIG, data); - ResponseAPDU response = cardManager.send(ecdsa); - //TODO print response SWs/error codes - //TODO output to file - } - - /** - * Creates the INS_ALLOCATE instruction. - * - * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) - * @param keyLength key length to set - * @param keyClass key class to allocate - * @return apdu to send - */ - private CommandAPDU insAllocate(byte keyPair, short keyLength, byte keyClass) { - byte[] data = new byte[]{0, 0, keyClass}; - Util.setShort(data, 0, keyLength); - - return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, 0x00, data); - } - - /** - * Creates the INS_SET instruction. - * - * @param keyPair which keyPair to set params on, local/remote (KEYPAIR_* || ...) - * @param export whether to export set params from keyPair - * @param curve curve to set (EC_Consts.CURVE_*) - * @param params parameters to set (EC_Consts.PARAMETER_* | ...) - * @param corrupted parameters to corrupt (EC_Consts.PARAMETER_* | ...) - * @param corruption corruption type (EC_Consts.CORRUPTION_*) - * @param external external curve data, can be null - * @return apdu to send - */ - private CommandAPDU insSet(byte keyPair, byte export, byte curve, short params, short corrupted, byte corruption, byte[] external) { - int len = external != null ? 6 + 2 + external.length : 6; - byte[] data = new byte[len]; - data[0] = curve; - Util.setShort(data, 1, params); - Util.setShort(data, 3, corrupted); - data[5] = corruption; - if (external != null) { - System.arraycopy(external, 0, data, 6, external.length); + Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_SIG, data).send(); + ecdsa.add(perform); + for (Response r : ecdsa) { + systemOutLogger.println(r.toString()); } - - return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SET, keyPair, export, data); - } - - /** - * Creates the INS_GENERATE instruction. - * - * @param keyPair which keyPair to generate, local/remote (KEYPAIR_* || ...) - * @param export whether to export generated keys from keyPair - * @return apdu to send - */ - private CommandAPDU insGenerate(byte keyPair, byte export) { - return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_GENERATE, keyPair, export); - } - - /** - * Creates the INS_ECDH instruction. - * - * @param pubkey keyPair to use for public key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) - * @param privkey keyPair to use for private key, (KEYPAIR_LOCAL || KEYPAIR_REMOTE) - * @param export whether to export ECDH secret - * @param invalid whether to invalidate the pubkey before ECDH - * @return apdu to send - */ - private CommandAPDU insECDH(byte pubkey, byte privkey, byte export, byte invalid) { - byte[] data = new byte[]{export, invalid}; - - return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDH, pubkey, privkey, data); - } - - /** - * Creates the INS_ECDSA instruction. - * - * @param keyPair keyPair to use for signing and verification (KEYPAIR_LOCAL || KEYPAIR_REMOTE) - * @param export whether to export ECDSA signature - * @param raw data to sign, can be null, in which case random data is signed. - * @return apdu to send - */ - private CommandAPDU insECDSA(byte keyPair, byte export, byte[] raw) { - int len = raw != null ? raw.length : 0; - byte[] data = new byte[2 + len]; - Util.setShort(data, 0, (short) len); - if (raw != null) { - System.arraycopy(raw, 0, data, 2, len); - } - - return new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ECDSA, keyPair, export, data); + //TODO output to file } /** @@ -608,23 +515,23 @@ public class ECTester { * @return an array of CommandAPDUs to send in order to prepare the keypair/s. * @throws IOException if curve file cannot be found/opened */ - private CommandAPDU[] prepareCurve(byte keyPair, short keyLength, byte keyClass) throws IOException { - List commands = new ArrayList<>(); - commands.add(insAllocate(keyPair, keyLength, keyClass)); + private List prepareCurve(byte keyPair, short keyLength, byte keyClass) throws IOException { + List commands = new ArrayList<>(); + commands.add(new Command.Allocate(cardManager, keyPair, keyLength, keyClass)); short domainParams = keyClass == KeyPair.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; if (optNamed) { - commands.add(insSet(keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.getCurve(keyLength, keyClass), domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, null)); + commands.add(new Command.Set(cardManager, keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.getCurve(keyLength, keyClass), domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, null)); } if (optCurve != null) { byte[] external = ParamReader.flatten(domainParams, ParamReader.readFile(optCurve)); if (external == null) { throw new IOException("Couldn't read the curve file correctly."); } - commands.add(insSet(keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, external)); + commands.add(new Command.Set(cardManager, keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, external)); } - return commands.toArray(new CommandAPDU[commands.size()]); + return commands; } /** @@ -632,7 +539,7 @@ public class ECTester { * @return a CommandAPDU setting params loaded on the keyPair/s * @throws IOException if any of the key files cannot be found/opened */ - private CommandAPDU prepareKey(byte keyPair) throws IOException { + private Command prepareKey(byte keyPair) throws IOException { short params = EC_Consts.PARAMETERS_NONE; byte[] data = null; if (optKey != null) { @@ -656,7 +563,7 @@ public class ECTester { */ throw new IOException("Couldn't read the key file correctly."); } - return insSet(keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, params, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, data); + return new Command.Set(cardManager, keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, params, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, data); } public static void main(String[] args) { diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java new file mode 100644 index 0000000..8f9ab9b --- /dev/null +++ b/src/cz/crcs/ectester/reader/Response.java @@ -0,0 +1,410 @@ +package cz.crcs.ectester.reader; + +import cz.crcs.ectester.applet.ECTesterApplet; +import cz.crcs.ectester.applet.EC_Consts; +import javacard.framework.ISO7816; +import javacard.security.KeyPair; + +import javax.smartcardio.ResponseAPDU; + +/** + * @author Jan Jancar johny@neuromancer.sk + */ +public abstract class Response { + protected ResponseAPDU resp; + protected long time; + protected short sw1 = 0; + protected short sw2 = 0; + protected byte[][] params; + protected boolean success = true; + + protected Response(ResponseAPDU response, long time) { + this.resp = response; + this.time = time; + } + + protected void parse(int numSW, int numParams) { + byte[] data = resp.getData(); + int offset = 0; + + //parse SWs in response + if (--numSW >= 0 && getLength() >= 2) { + sw1 = Util.getShort(data, offset); + offset += 2; + if (sw1 != ISO7816.SW_NO_ERROR) + success = false; + } + if (--numSW >= 0 && getLength() >= 4) { + sw2 = Util.getShort(data, offset); + offset += 2; + if (sw2 != ISO7816.SW_NO_ERROR) + success = false; + } + + //try to parse numParams.. + params = new byte[numParams][]; + for (int i = 0; i < numParams; i++) { + if (data.length - offset < 2) { + success = false; + break; + } + short paramLength = Util.getShort(data, offset); + offset += 2; + if (data.length < offset + paramLength) { + success = false; + break; + } + params[i] = new byte[paramLength]; + System.arraycopy(data, offset, params[i], 0, paramLength); + offset += paramLength; + } + } + + protected boolean hasParam(int index) { + return params.length >= index + 1 && params[index] != null; + } + + protected int getParamLength(int index) { + return params[index].length; + } + + protected byte[] getParam(int index) { + return params[index]; + } + + public ResponseAPDU getAPDU() { + return resp; + } + + public long getDuration() { + return time; + } + + public int getNaturalSW() { + return resp.getSW(); + } + + public short getSW1() { + return sw1; + } + + public short getSW2() { + return sw2; + } + + public int getLength() { + return resp.getNr(); + } + + public boolean successful() { + return this.success; + } + + @Override + public abstract String toString(); + + + /** + * + */ + public static class Allocate extends Response { + private byte keyPair; + private short keyLength; + private byte keyClass; + + public Allocate(ResponseAPDU response, long time, byte keyPair, short keyLength, byte keyClass) { + super(response, time); + this.keyPair = keyPair; + this.keyLength = keyLength; + this.keyClass = keyClass; + + int pairs = 0; + if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; + if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; + parse(pairs, 0); + } + + @Override + public String toString() { + String field = keyClass == KeyPair.ALG_EC_FP ? "ALG_EC_FP" : "ALG_EC_F2M"; + String key; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + key = "both keypairs"; + } else { + key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + //TODO general response.toString alignment + 2 SWs + return String.format("Allocated %s %db %s: %#x", key, keyLength, field, getSW1()); + } + } + + /** + * + */ + public static class Set extends Response { + private byte keyPair; + private byte export; + private byte curve; + private short params; + private short corrupted; + + protected Set(ResponseAPDU response, long time, byte keyPair, byte export, byte curve, short params, short corrupted) { + super(response, time); + this.keyPair = keyPair; + this.export = export; + this.curve = curve; + this.params = params; + this.corrupted = corrupted; + + int pairs = 0; + if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; + if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; + int exported = 0; + if ((export & ECTesterApplet.KEYPAIR_LOCAL) != 0) exported++; + if ((export & ECTesterApplet.KEYPAIR_REMOTE) != 0) exported++; + int keys = 0; + if ((export & ECTesterApplet.EXPORT_PUBLIC) != 0) keys++; + if ((export & ECTesterApplet.EXPORT_PRIVATE) != 0) keys++; + int paramCount = 0; + short mask = EC_Consts.PARAMETER_FP; + while (mask <= EC_Consts.PARAMETER_K) { + if ((mask & params) != 0) { + paramCount++; + } + mask = (short) (mask << 1); + } + int other = 0; + if ((export & ECTesterApplet.EXPORT_PUBLIC) != 0 && (params & EC_Consts.PARAMETER_W) != 0) other++; + if ((export & ECTesterApplet.EXPORT_PRIVATE) != 0 && (params & EC_Consts.PARAMETER_S) != 0) other++; + + parse(pairs, exported * keys * paramCount + exported * other); + } + + private int getIndex(byte keyPair, short param) { + byte key = ECTesterApplet.KEYPAIR_LOCAL; + int index = 0; + while (key <= ECTesterApplet.KEYPAIR_REMOTE) { + short mask = EC_Consts.PARAMETER_FP; + while (mask <= EC_Consts.PARAMETER_S) { + if (key == keyPair && param == mask) { + return index; + } + if ((params & mask) != 0 && (key & export) != 0) { + if (mask == EC_Consts.PARAMETER_W) { + if ((export & ECTesterApplet.EXPORT_PUBLIC) != 0) + index++; + } else if (mask == EC_Consts.PARAMETER_S) { + if ((export & ECTesterApplet.EXPORT_PRIVATE) != 0) + index++; + } else { + index++; + } + } + mask = (short) (mask << 1); + } + + key = (byte) (key << 1); + } + return -1; + } + + public boolean hasParameter(byte keyPair, short param) { + return !((export & keyPair) == 0 || (params & param) == 0) && getIndex(keyPair, param) != -1; + } + + public byte[] getParameter(byte keyPair, short param) { + return getParam(getIndex(keyPair, param)); + } + + @Override + public String toString() { + String name; + switch (curve) { + case EC_Consts.CURVE_default: + name = "default"; + break; + case EC_Consts.CURVE_external: + name = "external"; + break; + default: + name = "custom"; + break; + } + String key; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + key = "both keypairs"; + } else { + key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + //TODO general response.toString alignment + 2 SWs + return String.format("Set %s curve parameters on %s: %#x", name, key, getSW1()); + } + + } + + /** + * + */ + public static class Generate extends Response { + private byte keyPair; + private byte export; + private short[] contents; + + protected Generate(ResponseAPDU response, long time, byte keyPair, byte export) { + super(response, time); + this.keyPair = keyPair; + this.export = export; + + int keys = 0; + if ((export & ECTesterApplet.EXPORT_PUBLIC) != 0) keys++; + if ((export & ECTesterApplet.EXPORT_PRIVATE) != 0) keys++; + int pairs = 0; + if ((export & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; + if ((export & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; + int generated = 0; + if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) generated++; + if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) generated++; + parse(generated, keys * pairs); + + this.contents = new short[4]; + int offset = 0; + if ((export & ECTesterApplet.KEYPAIR_LOCAL) != 0) { + if ((export & ECTesterApplet.EXPORT_PUBLIC) != 0) { + this.contents[offset] = ECTesterApplet.KEYPAIR_LOCAL | ECTesterApplet.EXPORT_PUBLIC; + offset++; + } + if ((export & ECTesterApplet.EXPORT_PRIVATE) != 0) { + this.contents[offset] = ECTesterApplet.KEYPAIR_LOCAL | ECTesterApplet.EXPORT_PRIVATE; + offset++; + } + } + if ((export & ECTesterApplet.KEYPAIR_REMOTE) != 0) { + if ((export & ECTesterApplet.EXPORT_PUBLIC) != 0) { + this.contents[offset] = ECTesterApplet.KEYPAIR_REMOTE | ECTesterApplet.EXPORT_PUBLIC; + offset++; + } + if ((export & ECTesterApplet.EXPORT_PRIVATE) != 0) { + this.contents[offset] = ECTesterApplet.KEYPAIR_REMOTE | ECTesterApplet.EXPORT_PRIVATE; + offset++; + } + } + } + + private int getIndex(byte key) { + for (int i = 0; i < contents.length; i++) { + if (key == contents[i]) + return i; + } + return -1; + } + + public boolean hasPublic(byte keyPair) { + if ((export & ECTesterApplet.EXPORT_PUBLIC) == 0 || (export & keyPair) == 0) + return false; + return getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PUBLIC)) != -1; + } + + public boolean hasPrivate(byte keyPair) { + if ((export & ECTesterApplet.EXPORT_PRIVATE) == 0 || (export & keyPair) == 0) + return false; + return getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PRIVATE)) != -1; + } + + public byte[] getPublic(byte keyPair) { + //calculate index and getParam + int index = getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PUBLIC)); + return getParam(index); + } + + public byte[] getPrivate(byte keyPair) { + //calculate index and getParam + int index = getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PRIVATE)); + return getParam(index); + } + + @Override + public String toString() { + String key; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + key = "both keypairs"; + } else { + key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + //TODO general response.toString alignment + 2 SWs + return String.format("Generated %s: %#x", key, getSW1()); + } + + } + + /** + * + */ + public static class ECDH extends Response { + private byte pubkey; + private byte privkey; + private byte export; + private byte invalid; + + protected ECDH(ResponseAPDU response, long time, byte pubkey, byte privkey, byte export, byte invalid) { + super(response, time); + this.pubkey = pubkey; + this.privkey = privkey; + this.export = export; + this.invalid = invalid; + + parse(1, (export & ECTesterApplet.EXPORT_ECDH) != 0 ? 1 : 0); + } + + public boolean hasSecret() { + return hasParam(0); + } + + public byte[] getSecret() { + return getParam(0); + } + + @Override + public String toString() { + String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + String validity = invalid != 0 ? "invalid" : "valid"; + //TODO general response.toString alignment + 2SWs + return String.format("ECDH of %s pubkey and %s privkey(%s point): %#x", pub, priv, validity, getSW1()); + } + } + + /** + * + */ + public static class ECDSA extends Response { + private byte keyPair; + private byte export; + private byte[] raw; + + protected ECDSA(ResponseAPDU response, long time, byte keyPair, byte export, byte[] raw) { + super(response, time); + this.keyPair = keyPair; + this.export = export; + this.raw = raw; + + parse(1, (export & ECTesterApplet.EXPORT_SIG) != 0 ? 1 : 0); + } + + public boolean hasSignature() { + return hasParam(0); + } + + public byte[] getSignature() { + return getParam(0); + } + + @Override + public String toString() { + String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; + String data = raw == null ? "random" : "provided"; + //TODO general response.toString alignment + 2 SWs + return String.format("ECDSA with %s keypair(%s data): %#x", key, data, getSW1()); + } + + } +} diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java index 1464728..38db3bf 100644 --- a/src/cz/crcs/ectester/reader/Util.java +++ b/src/cz/crcs/ectester/reader/Util.java @@ -50,18 +50,22 @@ public class Util { } public static String bytesToHex(byte[] data) { - return bytesToHex(data, 0, data.length, true); + return bytesToHex(data, true); + } + + public static String bytesToHex(byte[] data, boolean addSpace) { + return bytesToHex(data, 0, data.length, addSpace); } public static String bytesToHex(byte[] data, int offset, int len) { return bytesToHex(data, offset, len, true); } - public static String bytesToHex(byte[] data, int offset, int len, boolean bAddSpace) { + public static String bytesToHex(byte[] data, int offset, int len, boolean addSpace) { StringBuilder buf = new StringBuilder(); for (int i = offset; i < (offset + len); i++) { buf.append(byteToHex(data[i])); - if (bAddSpace && i != (offset + len - 1)) { + if (addSpace && i != (offset + len - 1)) { buf.append(" "); } } -- cgit v1.3.1 From c3e48df92858bad5e74e9cec69c16397b6b12481 Mon Sep 17 00:00:00 2001 From: J08nY Date: Fri, 27 Jan 2017 21:34:39 +0100 Subject: Added option to generate fresh keys(-f) also implemented basic ECC testing - Added -f/--fresh - Fixed response align - Implemented basic EC testing, more advanced/complex tests are gonna be done through pre-generated files/curves/keys inside the jar or externally. Such as the invalid curve attack test and others. --- !uploader/ectester.cap | Bin 13377 -> 13641 bytes dist/ECTester.jar | Bin 75369 -> 78703 bytes src/cz/crcs/ectester/applet/ECKeyGenerator.java | 41 +++++--- src/cz/crcs/ectester/applet/ECTesterApplet.java | 38 ++++++- src/cz/crcs/ectester/reader/CardMngr.java | 2 +- src/cz/crcs/ectester/reader/Command.java | 27 ++++- src/cz/crcs/ectester/reader/ECTester.java | 121 +++++++++++++++------- src/cz/crcs/ectester/reader/Response.java | 131 ++++++++++++++++-------- 8 files changed, 260 insertions(+), 100 deletions(-) (limited to 'src/cz/crcs/ectester/reader/CardMngr.java') diff --git a/!uploader/ectester.cap b/!uploader/ectester.cap index a7da4dc..8d1bff8 100644 Binary files a/!uploader/ectester.cap and b/!uploader/ectester.cap differ diff --git a/dist/ECTester.jar b/dist/ECTester.jar index b0dae23..f0a8c3b 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 417944c..427577b 100644 --- a/src/cz/crcs/ectester/applet/ECKeyGenerator.java +++ b/src/cz/crcs/ectester/applet/ECKeyGenerator.java @@ -44,6 +44,19 @@ public class ECKeyGenerator { return ecKeyPair; } + public short clearPair(KeyPair keypair, byte key) { + sw = ISO7816.SW_NO_ERROR; + try { + if ((key & KEY_PUBLIC) != 0) keypair.getPublic().clearKey(); + if ((key & KEY_PRIVATE) != 0) keypair.getPrivate().clearKey(); + } catch (CryptoException ce) { + sw = ce.getReason(); + } catch (Exception e) { + sw = ISO7816.SW_UNKNOWN; + } + return sw; + } + /** * @param keypair * @return @@ -73,8 +86,8 @@ public class ECKeyGenerator { sw = ISO7816.SW_NO_ERROR; if (params == EC_Consts.PARAMETERS_NONE) { - return sw; - } + return sw; + } short length; if (alg == KeyPair.ALG_EC_FP && (params & EC_Consts.PARAMETER_FP) != 0) { @@ -123,9 +136,9 @@ public class ECKeyGenerator { */ public short corruptCurve(KeyPair keypair, byte key, short corruptParams, byte corruption, byte[] buffer, short offset) { sw = ISO7816.SW_NO_ERROR; - if (corruptParams == EC_Consts.PARAMETERS_NONE) { - return sw; - } + if (corruptParams == EC_Consts.PARAMETERS_NONE) { + return sw; + } //go through param bit by bit, and invalidate all selected params short paramMask = EC_Consts.PARAMETER_FP; @@ -252,7 +265,7 @@ public class ECKeyGenerator { public short setExternalCurve(KeyPair keypair, byte key, short params, byte[] inBuffer, short inOffset) { sw = ISO7816.SW_NO_ERROR; if (params == EC_Consts.PARAMETERS_NONE) { - return sw; + return sw; } short paramMask = EC_Consts.PARAMETER_FP; @@ -273,9 +286,9 @@ public class ECKeyGenerator { /** * Exports a selected parameter from a given keyPairs key. * - * @param keypair keypair to export from - * @param key key to export from (KEY_PUBLIC | KEY_PRIVATE) - * @param param parameter to export (EC_Consts.PARAMETER_* || ...) + * @param keypair keypair to export from + * @param key key to export from (KEY_PUBLIC | KEY_PRIVATE) + * @param param parameter to export (EC_Consts.PARAMETER_* || ...) * @param outputBuffer buffer to write to * @param outputOffset offset to start writing in buffer * @return length of data written @@ -346,9 +359,9 @@ public class ECKeyGenerator { */ public short exportParameters(KeyPair keypair, byte key, short params, byte[] buffer, short offset) { sw = ISO7816.SW_NO_ERROR; - if (params == EC_Consts.PARAMETERS_NONE) { - return sw; - } + if (params == EC_Consts.PARAMETERS_NONE) { + return sw; + } short length = 0; short paramMask = EC_Consts.PARAMETER_FP; @@ -372,8 +385,8 @@ public class ECKeyGenerator { /** * Copies this KeyPairs curve parameters to another ECKeyGenerator. * - * @param from keyPair to copy from - * @param to keyPair to copy to + * @param from keyPair to copy from + * @param to keyPair to copy to * @param buffer buffer to use for copying * @param offset offset to use in buffer * @return sw diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index dfdd0f0..cb2c43f 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -44,10 +44,11 @@ public class ECTesterApplet extends Applet { //INSTRUCTIONS public static final byte INS_ALLOCATE = (byte) 0x5a; - public static final byte INS_SET = (byte) 0x5b; - public static final byte INS_GENERATE = (byte) 0x5c; - public static final byte INS_ECDH = (byte) 0x5d; - public static final byte INS_ECDSA = (byte) 0x5e; + public static final byte INS_CLEAR = (byte) 0x5b; + public static final byte INS_SET = (byte) 0x5c; + public static final byte INS_GENERATE = (byte) 0x5d; + public static final byte INS_ECDH = (byte) 0x5e; + public static final byte INS_ECDSA = (byte) 0x5f; //PARAMETERS for P1 and P2 public static final byte KEYPAIR_LOCAL = (byte) 0x01; @@ -127,6 +128,9 @@ public class ECTesterApplet extends Applet { case INS_ALLOCATE: insAllocate(apdu); break; + case INS_CLEAR: + insClear(apdu); + break; case INS_SET: insSet(apdu); break; @@ -169,6 +173,25 @@ public class ECTesterApplet extends Applet { apdu.setOutgoingAndSend((short) 0, len); } + /** + * + * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) + * P2 = + */ + private void insClear(APDU apdu) { + apdu.setIncomingAndReceive(); + byte[] apdubuf = apdu.getBuffer(); + byte keyPair = apdubuf[ISO7816.OFFSET_P1]; + + short len = 0; + if ((keyPair & KEYPAIR_LOCAL) != 0) + len += clear(localKeypair, apdubuf, (short) 0); + if ((keyPair & KEYPAIR_REMOTE) != 0) + len += clear(remoteKeypair, apdubuf, len); + + apdu.setOutgoingAndSend((short) 0, len); + } + /** * Sets curve parameters on local and remote keyPairs. * returns setCurve SWs, set params if export @@ -306,6 +329,13 @@ public class ECTesterApplet extends Applet { return length; } + private short clear(KeyPair keyPair, byte[] buffer, short offset) { + short sw = keyGenerator.clearPair(keyPair, ECKeyGenerator.KEY_BOTH); + Util.setShort(buffer, offset, sw); + + return 2; + } + /** * @param keyPair KeyPair to set params on * @param curve curve to set (EC_Consts.CURVE_*) diff --git a/src/cz/crcs/ectester/reader/CardMngr.java b/src/cz/crcs/ectester/reader/CardMngr.java index d95b7e5..6875d2e 100644 --- a/src/cz/crcs/ectester/reader/CardMngr.java +++ b/src/cz/crcs/ectester/reader/CardMngr.java @@ -23,7 +23,7 @@ public class CardMngr { private boolean simulate = false; - private final byte selectCM[] = { + private final byte[] selectCM = { (byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0xa0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x18, (byte) 0x43, (byte) 0x4d}; diff --git a/src/cz/crcs/ectester/reader/Command.java b/src/cz/crcs/ectester/reader/Command.java index c5fd465..31cde4d 100644 --- a/src/cz/crcs/ectester/reader/Command.java +++ b/src/cz/crcs/ectester/reader/Command.java @@ -23,11 +23,6 @@ public abstract class Command { return cmd; } - /** - * - * @return - * @throws CardException - */ public abstract Response send() throws CardException; public static List sendAll(List commands) throws CardException { @@ -74,6 +69,28 @@ public abstract class Command { } } + /** + * + */ + public static class Clear extends Command { + private byte keyPair; + + public Clear(CardMngr cardManager, byte keyPair) { + super(cardManager); + this.keyPair = keyPair; + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CLEAR, keyPair, 0x00); + } + + @Override + public Response.Clear send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Clear(response, elapsed, keyPair); + } + } + /** * */ diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index e5a2b70..4cb63f7 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -33,6 +33,7 @@ import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; /** @@ -58,6 +59,7 @@ public class ECTester { private String optKey = null; private String optLog = null; private String optOutput = null; + private boolean optFresh = false; private boolean optSimulate = false; private int optGenerateAmount; @@ -244,11 +246,15 @@ public class ECTester { opts.addOption(Option.builder("fp").longOpt("prime-field").desc("Use prime field curve.").build()); opts.addOption(Option.builder("f2m").longOpt("binary-field").desc("Use binary field curve.").build()); + opts.addOption(Option.builder("pub").longOpt("public").desc("Use public key from file [pubkey_file] (wx,wy).").hasArg().argName("pubkey_file").build()); opts.addOption(Option.builder("priv").longOpt("private").desc("Use private key from file [privkey_file] (s).").hasArg().argName("privkey_file").build()); opts.addOption(Option.builder("k").longOpt("key").desc("Use keyPair from file [key_file] (wx,wy,s).").hasArg().argName("key_file").build()); + opts.addOption(Option.builder("o").longOpt("output").desc("Output into file [output_file].").hasArg().argName("output_file").build()); opts.addOption(Option.builder("l").longOpt("log").desc("Log output into file [log_file].").hasArg().argName("log_file").optionalArg(true).build()); + + opts.addOption(Option.builder("f").longOpt("fresh").desc("Generate fresh keys(set domain parameters before every generation).").build()); opts.addOption(Option.builder("s").longOpt("simulate").desc("Simulate a card with jcardsim instead of using a terminal.").build()); CommandLineParser parser = new DefaultParser(); @@ -275,6 +281,7 @@ public class ECTester { optLog = cli.getOptionValue("log", String.format("ECTESTER_log_%d.log", System.currentTimeMillis() / 1000)); } optOutput = cli.getOptionValue("output"); + optFresh = cli.hasOption("fresh"); optSimulate = cli.hasOption("simulate"); if (optKey != null && (optPublic != null || optPrivate != null)) { @@ -365,7 +372,8 @@ public class ECTester { */ private void generate() throws CardException, IOException { byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; - List prepare = Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass)); + List prepare = Command.sendAll(prepareKeyPair(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass)); + prepare.addAll(Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass))); FileWriter keysFile = new FileWriter(optOutput); keysFile.write("index;time;pubW;privS\n"); @@ -373,6 +381,10 @@ public class ECTester { int generated = 0; int retry = 0; while (generated < optGenerateAmount || optGenerateAmount == 0) { + if (optFresh) { + Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass)); + } + Command.Generate generate = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, (byte) (ECTesterApplet.EXPORT_BOTH | ECTesterApplet.KEYPAIR_LOCAL)); Response.Generate response = generate.send(); long elapsed = response.getDuration(); @@ -400,47 +412,36 @@ public class ECTester { /** * Tests Elliptic curve support for a given curve/curves. + * + * @throws IOException + * @throws CardException */ - private void test() { - //TODO + private void test() throws IOException, CardException { + List commands = new LinkedList<>(); if (optAll) { if (optPrimeField) { //iterate over prime curve sizes used: EC_Consts.FP_SIZES for (short keyLength : EC_Consts.FP_SIZES) { - //prepareCurve(KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_FP); - //insGenerate(KEYPAIR_BOTH, EXPORT_NONE); - //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 00); - //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 01); - //insECDSA(KEYPAIR_LOCAL, EXPORT_NONE, null); + commands.addAll(testCurve(keyLength, KeyPair.ALG_EC_FP)); } } if (optBinaryField) { //iterate over binary curve sizes used: EC_Consts.F2M_SIZES for (short keyLength : EC_Consts.F2M_SIZES) { - //prepareCurve(KEYPAIR_BOTH, keyLength, KeyPair.ALG_EC_F2M); - //insGenerate(KEYPAIR_BOTH, EXPORT_NONE); - //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 00); - //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 01); - //insECDSA(KEYPAIR_LOCAL, EXPORT_NONE, null); + commands.addAll(testCurve(keyLength, KeyPair.ALG_EC_F2M)); } } } else { if (optPrimeField) { - //test with prepareCurve(KEYPAIR_BOTH, (short) optBits, KeyPair.ALG_EC_FP) - //insGenerate(KEYPAIR_BOTH, EXPORT_NONE); - //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 00); - //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 01); - //insECDSA(KEYPAIR_LOCAL, EXPORT_NONE, null); + commands.addAll(testCurve((short) optBits, KeyPair.ALG_EC_FP)); } if (optBinaryField) { - //test with prepareCurve(KEYPAIR_BOTH, (short) optBits, KeyPair.ALG_EC_F2M) - //insGenerate(KEYPAIR_BOTH, EXPORT_NONE); - //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 00); - //insECDH(KEYPAIR_LOCAL, KEYPAIR_REMOTE, EXPORT_NONE, 01); - //insECDSA(KEYPAIR_LOCAL, EXPORT_NONE, null); + commands.addAll(testCurve((short) optBits, KeyPair.ALG_EC_F2M)); } } + List test = Command.sendAll(commands); + systemOutLogger.println(Response.toString(test)); } /** @@ -451,7 +452,8 @@ public class ECTester { */ private void ecdh() throws IOException, CardException { byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; - List ecdh = Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) optBits, keyClass)); + List ecdh = Command.sendAll(prepareKeyPair(ECTesterApplet.KEYPAIR_BOTH, (short) optBits, keyClass)); + ecdh.addAll(Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_BOTH, (short) optBits, keyClass))); if (optPublic != null || optPrivate != null || optKey != null) { Response local = new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE).send(); @@ -465,10 +467,17 @@ public class ECTester { Response.ECDH perform = new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_ECDH, (byte) 0).send(); ecdh.add(perform); - for (Response r : ecdh) { - systemOutLogger.println(r.toString()); + systemOutLogger.println(Response.toString(ecdh)); + + if (!perform.hasSecret()) { + System.err.println("Couldn't obtain ECDH secret from card response."); + } else { + if (optOutput != null) { + FileWriter out = new FileWriter(optOutput); + out.write(Util.bytesToHex(perform.getSecret(), false)); + out.close(); + } } - //TODO check perform.hasSecret(), write perform.getSecret to file if -o } /** @@ -479,7 +488,8 @@ public class ECTester { */ private void ecdsa() throws CardException, IOException { byte keyClass = optPrimeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; - List ecdsa = Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass)); + List ecdsa = Command.sendAll(prepareKeyPair(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass)); + ecdsa.addAll(Command.sendAll(prepareCurve(ECTesterApplet.KEYPAIR_LOCAL, (short) optBits, keyClass))); Response keys; if (optKey != null || (optPublic != null && optPrivate != null)) { @@ -502,33 +512,55 @@ public class ECTester { Response.ECDSA perform = new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_SIG, data).send(); ecdsa.add(perform); - for (Response r : ecdsa) { - systemOutLogger.println(r.toString()); + systemOutLogger.println(Response.toString(ecdsa)); + + if (!perform.hasSignature()) { + System.err.println("Couldn't obtain ECDSA signature from card response."); + } else { + if (optOutput != null) { + FileWriter out = new FileWriter(optOutput); + out.write(Util.bytesToHex(perform.getSignature(), false)); + out.close(); + } } - //TODO output to file } /** - * @param keyPair which keyPair/s (local/remote) to set curve domain parameters on + * @param keyPair which keyPair/s (local/remote) to allocate * @param keyLength key length to allocate * @param keyClass key class to allocate - * @return an array of CommandAPDUs to send in order to prepare the keypair/s. + * @return a list of Commands to send in order to prepare the keyPair. + */ + private List prepareKeyPair(byte keyPair, short keyLength, byte keyClass) { + List commands = new ArrayList<>(); + commands.add(new Command.Allocate(cardManager, keyPair, keyLength, keyClass)); + return commands; + } + + /** + * @param keyPair which keyPair/s (local/remote) to set curve domain parameters on + * @param keyLength key length to choose + * @param keyClass key class to choose + * @return a list of Commands to send in order to prepare the curve on the keypairs. * @throws IOException if curve file cannot be found/opened */ private List prepareCurve(byte keyPair, short keyLength, byte keyClass) throws IOException { List commands = new ArrayList<>(); - commands.add(new Command.Allocate(cardManager, keyPair, keyLength, keyClass)); short domainParams = keyClass == KeyPair.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; if (optNamed) { + // Set named curve (one of the SECG curves embedded applet-side) commands.add(new Command.Set(cardManager, keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.getCurve(keyLength, keyClass), domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, null)); - } - if (optCurve != null) { + } else if (optCurve != null) { + // Set curve loaded from a file byte[] external = ParamReader.flatten(domainParams, ParamReader.readFile(optCurve)); if (external == null) { throw new IOException("Couldn't read the curve file correctly."); } commands.add(new Command.Set(cardManager, keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, external)); + } else { + // Set default curve + commands.add(new Command.Clear(cardManager, keyPair)); } return commands; @@ -566,6 +598,23 @@ public class ECTester { return new Command.Set(cardManager, keyPair, ECTesterApplet.EXPORT_NONE, EC_Consts.CURVE_external, params, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, data); } + /** + * @param keyLength + * @param keyClass + * @return + * @throws IOException + */ + private List testCurve(short keyLength, byte keyClass) throws IOException { + List commands = new LinkedList<>(); + commands.addAll(prepareKeyPair(ECTesterApplet.KEYPAIR_BOTH, keyLength, keyClass)); + commands.addAll(prepareCurve(ECTesterApplet.KEYPAIR_BOTH, keyLength, keyClass)); + commands.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_BOTH, ECTesterApplet.EXPORT_NONE)); + commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_NONE, (byte) 0)); + commands.add(new Command.ECDH(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.KEYPAIR_REMOTE, ECTesterApplet.EXPORT_NONE, (byte) 1)); + commands.add(new Command.ECDSA(cardManager, ECTesterApplet.KEYPAIR_LOCAL, ECTesterApplet.EXPORT_NONE, null)); + return commands; + } + public static void main(String[] args) { ECTester app = new ECTester(); app.run(args); diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java index 8f9ab9b..05cd92a 100644 --- a/src/cz/crcs/ectester/reader/Response.java +++ b/src/cz/crcs/ectester/reader/Response.java @@ -6,17 +6,19 @@ import javacard.framework.ISO7816; import javacard.security.KeyPair; import javax.smartcardio.ResponseAPDU; +import java.util.List; /** * @author Jan Jancar johny@neuromancer.sk */ public abstract class Response { - protected ResponseAPDU resp; - protected long time; - protected short sw1 = 0; - protected short sw2 = 0; - protected byte[][] params; - protected boolean success = true; + private ResponseAPDU resp; + private long time; + private short sw1 = 0; + private short sw2 = 0; + private int numSW = 0; + private byte[][] params; + private boolean success = true; protected Response(ResponseAPDU response, long time) { this.resp = response; @@ -24,6 +26,8 @@ public abstract class Response { } protected void parse(int numSW, int numParams) { + this.numSW = numSW; + byte[] data = resp.getData(); int offset = 0; @@ -31,14 +35,16 @@ public abstract class Response { if (--numSW >= 0 && getLength() >= 2) { sw1 = Util.getShort(data, offset); offset += 2; - if (sw1 != ISO7816.SW_NO_ERROR) + if (sw1 != ISO7816.SW_NO_ERROR) { success = false; + } } if (--numSW >= 0 && getLength() >= 4) { sw2 = Util.getShort(data, offset); offset += 2; - if (sw2 != ISO7816.SW_NO_ERROR) + if (sw2 != ISO7816.SW_NO_ERROR) { success = false; + } } //try to parse numParams.. @@ -60,18 +66,6 @@ public abstract class Response { } } - protected boolean hasParam(int index) { - return params.length >= index + 1 && params[index] != null; - } - - protected int getParamLength(int index) { - return params[index].length; - } - - protected byte[] getParam(int index) { - return params[index]; - } - public ResponseAPDU getAPDU() { return resp; } @@ -92,6 +86,22 @@ public abstract class Response { return sw2; } + public int getNumSW() { + return numSW; + } + + protected boolean hasParam(int index) { + return params.length >= index + 1 && params[index] != null; + } + + protected int getParamLength(int index) { + return params[index].length; + } + + protected byte[] getParam(int index) { + return params[index]; + } + public int getLength() { return resp.getNr(); } @@ -104,6 +114,21 @@ public abstract class Response { public abstract String toString(); + public static String toString(List responses) { + StringBuilder out = new StringBuilder(); + for (Response r : responses) { + String message = r.toString(); + String suffix; + if (r.getNumSW() == 1) { + suffix = String.format("%s", Util.getPrintError(r.getSW1())); + } else { + suffix = String.format("%s %s", Util.getPrintError(r.getSW1()), Util.getPrintError(r.getSW2())); + } + out.append(String.format("%-55s: %s\n", message, suffix)); + } + return out.toString(); + } + /** * */ @@ -133,8 +158,32 @@ public abstract class Response { } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - //TODO general response.toString alignment + 2 SWs - return String.format("Allocated %s %db %s: %#x", key, keyLength, field, getSW1()); + return String.format("Allocated %s %db %s", key, keyLength, field); + } + } + + public static class Clear extends Response { + private byte keyPair; + + public Clear(ResponseAPDU response, long time, byte keyPair) { + super(response, time); + this.keyPair = keyPair; + + int pairs = 0; + if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; + if ((keyPair & ECTesterApplet.KEYPAIR_REMOTE) != 0) pairs++; + parse(pairs, 0); + } + + @Override + public String toString() { + String key; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + key = "both keypairs"; + } else { + key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return String.format("Cleared %s", key); } } @@ -145,15 +194,15 @@ public abstract class Response { private byte keyPair; private byte export; private byte curve; - private short params; + private short parameters; private short corrupted; - protected Set(ResponseAPDU response, long time, byte keyPair, byte export, byte curve, short params, short corrupted) { + protected Set(ResponseAPDU response, long time, byte keyPair, byte export, byte curve, short parameters, short corrupted) { super(response, time); this.keyPair = keyPair; this.export = export; this.curve = curve; - this.params = params; + this.parameters = parameters; this.corrupted = corrupted; int pairs = 0; @@ -168,14 +217,14 @@ public abstract class Response { int paramCount = 0; short mask = EC_Consts.PARAMETER_FP; while (mask <= EC_Consts.PARAMETER_K) { - if ((mask & params) != 0) { + if ((mask & parameters) != 0) { paramCount++; } mask = (short) (mask << 1); } int other = 0; - if ((export & ECTesterApplet.EXPORT_PUBLIC) != 0 && (params & EC_Consts.PARAMETER_W) != 0) other++; - if ((export & ECTesterApplet.EXPORT_PRIVATE) != 0 && (params & EC_Consts.PARAMETER_S) != 0) other++; + if ((export & ECTesterApplet.EXPORT_PUBLIC) != 0 && (parameters & EC_Consts.PARAMETER_W) != 0) other++; + if ((export & ECTesterApplet.EXPORT_PRIVATE) != 0 && (parameters & EC_Consts.PARAMETER_S) != 0) other++; parse(pairs, exported * keys * paramCount + exported * other); } @@ -189,7 +238,7 @@ public abstract class Response { if (key == keyPair && param == mask) { return index; } - if ((params & mask) != 0 && (key & export) != 0) { + if ((parameters & mask) != 0 && (key & export) != 0) { if (mask == EC_Consts.PARAMETER_W) { if ((export & ECTesterApplet.EXPORT_PUBLIC) != 0) index++; @@ -209,7 +258,11 @@ public abstract class Response { } public boolean hasParameter(byte keyPair, short param) { - return !((export & keyPair) == 0 || (params & param) == 0) && getIndex(keyPair, param) != -1; + if ((export & keyPair) == 0 || (parameters & param) == 0) { + return false; + } + int index = getIndex(keyPair, param); + return index != -1 && hasParam(index); } public byte[] getParameter(byte keyPair, short param) { @@ -236,8 +289,7 @@ public abstract class Response { } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - //TODO general response.toString alignment + 2 SWs - return String.format("Set %s curve parameters on %s: %#x", name, key, getSW1()); + return String.format("Set %s curve parameters on %s", name, key); } } @@ -301,13 +353,15 @@ public abstract class Response { public boolean hasPublic(byte keyPair) { if ((export & ECTesterApplet.EXPORT_PUBLIC) == 0 || (export & keyPair) == 0) return false; - return getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PUBLIC)) != -1; + int index = getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PUBLIC)); + return index != -1 && hasParam(index); } public boolean hasPrivate(byte keyPair) { if ((export & ECTesterApplet.EXPORT_PRIVATE) == 0 || (export & keyPair) == 0) return false; - return getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PRIVATE)) != -1; + int index = getIndex((byte) (keyPair | ECTesterApplet.EXPORT_PRIVATE)); + return index != -1 && hasParam(index); } public byte[] getPublic(byte keyPair) { @@ -330,8 +384,7 @@ public abstract class Response { } else { key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - //TODO general response.toString alignment + 2 SWs - return String.format("Generated %s: %#x", key, getSW1()); + return String.format("Generated %s", key); } } @@ -368,8 +421,7 @@ public abstract class Response { String pub = pubkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String priv = privkey == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String validity = invalid != 0 ? "invalid" : "valid"; - //TODO general response.toString alignment + 2SWs - return String.format("ECDH of %s pubkey and %s privkey(%s point): %#x", pub, priv, validity, getSW1()); + return String.format("ECDH of %s pubkey and %s privkey(%s point)", pub, priv, validity); } } @@ -402,8 +454,7 @@ public abstract class Response { public String toString() { String key = keyPair == ECTesterApplet.KEYPAIR_LOCAL ? "local" : "remote"; String data = raw == null ? "random" : "provided"; - //TODO general response.toString alignment + 2 SWs - return String.format("ECDSA with %s keypair(%s data): %#x", key, data, getSW1()); + return String.format("ECDSA with %s keypair(%s data)", key, data); } } -- cgit v1.3.1 From c6cb9f4cda4391713bd59cc1e1e7cae8d50cf331 Mon Sep 17 00:00:00 2001 From: J08nY Date: Tue, 7 Mar 2017 23:54:16 +0100 Subject: Reader: added verbose flag, made CardMngr quiet. --- dist/ECTester.jar | Bin 208535 -> 104311 bytes src/cz/crcs/ectester/reader/CardMngr.java | 73 ++++++++++++++++++++---------- src/cz/crcs/ectester/reader/ECTester.java | 11 ++++- src/cz/crcs/ectester/reader/Response.java | 9 +++- 4 files changed, 64 insertions(+), 29 deletions(-) (limited to 'src/cz/crcs/ectester/reader/CardMngr.java') diff --git a/dist/ECTester.jar b/dist/ECTester.jar index 0f2e8c6..8201bec 100644 Binary files a/dist/ECTester.jar and b/dist/ECTester.jar differ diff --git a/src/cz/crcs/ectester/reader/CardMngr.java b/src/cz/crcs/ectester/reader/CardMngr.java index 6875d2e..e11bcb3 100644 --- a/src/cz/crcs/ectester/reader/CardMngr.java +++ b/src/cz/crcs/ectester/reader/CardMngr.java @@ -22,6 +22,7 @@ public class CardMngr { private JavaxSmartCardInterface simulator = null; private boolean simulate = false; + private boolean verbose = true; private final byte[] selectCM = { (byte) 0x00, (byte) 0xa4, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0xa0, (byte) 0x00, (byte) 0x00, @@ -39,10 +40,14 @@ public class CardMngr { public static final short NUMBER_OF_RECORDS = (short) 0x0a; // 10 records public CardMngr() { - this(false); } - public CardMngr(boolean simulate) { + public CardMngr(boolean verbose) { + this.verbose = verbose; + } + + public CardMngr(boolean verbose, boolean simulate) { + this(verbose); this.simulate = simulate; } @@ -54,22 +59,27 @@ public class CardMngr { List terminalList = getReaderList(); if (terminalList == null || terminalList.isEmpty()) { - System.out.println("No terminals found"); + System.err.println("No terminals found"); return false; } //List numbers of Card readers boolean cardFound = false; for (int i = 0; i < terminalList.size(); i++) { - System.out.println(i + " : " + terminalList.get(i)); + + if (verbose) + System.out.println(i + " : " + terminalList.get(i)); + terminal = terminalList.get(i); if (terminal.isCardPresent()) { card = terminal.connect("*"); - System.out.println("card: " + card); + if (verbose) + System.out.println("card: " + card); channel = card.getBasicChannel(); //reset the card - System.out.println(Util.bytesToHex(card.getATR().getBytes())); + if (verbose) + System.out.println(Util.bytesToHex(card.getATR().getBytes())); cardFound = true; } @@ -85,7 +95,7 @@ public class CardMngr { // Test available card - if more present, let user to select one List terminalList = CardMngr.getReaderList(); if (terminalList == null || terminalList.isEmpty()) { - System.out.println("ERROR: No suitable reader with card detected. Please check your reader connection"); + System.err.println("ERROR: No suitable reader with card detected. Please check your reader connection"); return false; } else { if (terminalList.size() == 1) { @@ -116,7 +126,8 @@ public class CardMngr { if (terminal != null) { card = terminal.connect("*"); - System.out.println("card: " + card); + if (verbose) + System.out.println("card: " + card); channel = card.getBasicChannel(); } @@ -166,7 +177,7 @@ public class CardMngr { ResponseAPDU resp = send(apdu); if (resp.getSW() != 0x9000) { // 0x9000 is "OK" - System.out.println("Fail to obtain card's response data"); + System.err.println("Fail to obtain card's response data"); data = null; } else { byte temp[] = resp.getBytes(); @@ -191,7 +202,8 @@ public class CardMngr { ResponseAPDU resp = send(apdu); - System.out.println("Response: " + Integer.toHexString(resp.getSW())); + if (verbose) + System.out.println("Response: " + Integer.toHexString(resp.getSW())); if (resp.getSW() != 0x6D00) { // Note: 0x6D00 is SW_INS_NOT_SUPPORTED // something? @@ -204,16 +216,18 @@ public class CardMngr { TerminalFactory factory = TerminalFactory.getDefault(); return factory.terminals().list(); } catch (CardException ex) { - System.out.println("Exception : " + ex); + System.err.println("Exception : " + ex); return null; } } public ResponseAPDU sendAPDU(CommandAPDU apdu) throws CardException { - System.out.println(">>>>"); - System.out.println(apdu); + if (verbose) { + System.out.println(">>>>"); + System.out.println(apdu); - System.out.println(Util.bytesToHex(apdu.getBytes())); + System.out.println(Util.bytesToHex(apdu.getBytes())); + } long elapsed = -System.nanoTime(); @@ -221,8 +235,10 @@ public class CardMngr { elapsed += System.nanoTime(); - System.out.println(responseAPDU); - System.out.println(Util.bytesToHex(responseAPDU.getBytes())); + if (verbose) { + System.out.println(responseAPDU); + System.out.println(Util.bytesToHex(responseAPDU.getBytes())); + } if (responseAPDU.getSW1() == (byte) 0x61) { CommandAPDU apduToSend = new CommandAPDU((byte) 0x00, @@ -230,11 +246,14 @@ public class CardMngr { responseAPDU.getSW1()); responseAPDU = channel.transmit(apduToSend); - System.out.println(Util.bytesToHex(responseAPDU.getBytes())); + if (verbose) + System.out.println(Util.bytesToHex(responseAPDU.getBytes())); } - System.out.println("<<<<"); - System.out.println("Elapsed time (ms): " + elapsed / 1000000); + if (verbose) { + System.out.println("<<<<"); + System.out.println("Elapsed time (ms): " + elapsed / 1000000); + } return responseAPDU; } @@ -254,16 +273,20 @@ public class CardMngr { } public ResponseAPDU sendAPDUSimulator(CommandAPDU apdu) { - System.out.println(">>>>"); - System.out.println(apdu); - System.out.println(Util.bytesToHex(apdu.getBytes())); + if (verbose) { + System.out.println(">>>>"); + System.out.println(apdu); + System.out.println(Util.bytesToHex(apdu.getBytes())); + } ResponseAPDU response = simulator.transmitCommand(apdu); byte[] responseBytes = response.getBytes(); - System.out.println(response); - System.out.println(Util.bytesToHex(responseBytes)); - System.out.println("<<<<"); + if (verbose) { + System.out.println(response); + System.out.println(Util.bytesToHex(responseBytes)); + System.out.println("<<<<"); + } return response; } diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index d94279e..c4d29a5 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -73,7 +73,8 @@ public class ECTester { private String optLog = null; - private String optInput; + private boolean optVerbose = false; + private String optInput = null; private String optOutput = null; private boolean optFresh = false; private boolean optSimulate = false; @@ -119,7 +120,7 @@ public class ECTester { } //init CardManager - cardManager = new CardMngr(optSimulate); + cardManager = new CardMngr(optVerbose, optSimulate); //connect or simulate connection if (optSimulate) { @@ -213,6 +214,9 @@ public class ECTester { * -k / --key [key_file] wx,wy,s * -nk / --named-key [cat/id] * + * -v / --verbose + * + * -i / --input [input_file] * -o / --output [output_file] * -f / --fresh * -s / --simulate @@ -260,6 +264,7 @@ public class ECTester { opts.addOption(Option.builder("i").longOpt("input").desc("Input from file [input_file], for ecdsa signing.").hasArg().argName("input_file").build()); opts.addOption(Option.builder("o").longOpt("output").desc("Output into file [output_file].").hasArg().argName("output_file").build()); opts.addOption(Option.builder("l").longOpt("log").desc("Log output into file [log_file].").hasArg().argName("log_file").optionalArg(true).build()); + opts.addOption(Option.builder("v").longOpt("verbose").desc("Turn on verbose logging.").build()); opts.addOption(Option.builder("f").longOpt("fresh").desc("Generate fresh keys(set domain parameters before every generation).").build()); opts.addOption(Option.builder("s").longOpt("simulate").desc("Simulate a card with jcardsim instead of using a terminal.").build()); @@ -295,6 +300,8 @@ public class ECTester { 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"); diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java index cdf82fc..28b6c17 100644 --- a/src/cz/crcs/ectester/reader/Response.java +++ b/src/cz/crcs/ectester/reader/Response.java @@ -119,7 +119,9 @@ public abstract class Response { public static String toString(List responses) { StringBuilder out = new StringBuilder(); - for (Response r : responses) { + for (int i = 0; i < responses.size(); ++i) { + Response r = responses.get(i); + String message = r.toString(); String suffix; if (r.getNumSW() == 1) { @@ -127,7 +129,10 @@ public abstract class Response { } else { suffix = String.format("%s %s", Util.getPrintError(r.getSW1()), Util.getPrintError(r.getSW2())); } - out.append(String.format("%-55s: %5d ms : %s\n", message, r.time/1000000, suffix)); + out.append(String.format("%-55s: %5d ms : %s", message, r.time/1000000, suffix)); + if (i < responses.size() - 1) { + out.append("\n"); + } } return out.toString(); } -- cgit v1.3.1