diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECTesterApplet.java | 88 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/EC_Consts.java | 19 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Command.java | 59 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/ECTester.java | 18 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Response.java | 51 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/Util.java | 32 |
6 files changed, 205 insertions, 62 deletions
diff --git a/src/cz/crcs/ectester/applet/ECTesterApplet.java b/src/cz/crcs/ectester/applet/ECTesterApplet.java index 323b971..6623647 100644 --- a/src/cz/crcs/ectester/applet/ECTesterApplet.java +++ b/src/cz/crcs/ectester/applet/ECTesterApplet.java @@ -46,10 +46,11 @@ public class ECTesterApplet extends Applet { public static final byte INS_ALLOCATE = (byte) 0x5a; 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_EXPORT = (byte) 0x5e; - public static final byte INS_ECDH = (byte) 0x5f; - public static final byte INS_ECDSA = (byte) 0x60; + public static final byte INS_CORRUPT = (byte) 0x5d; + public static final byte INS_GENERATE = (byte) 0x5e; + public static final byte INS_EXPORT = (byte) 0x5f; + public static final byte INS_ECDH = (byte) 0x60; + public static final byte INS_ECDSA = (byte) 0x61; // PARAMETERS for P1 and P2 public static final byte KEYPAIR_LOCAL = (byte) 0x01; @@ -132,6 +133,9 @@ public class ECTesterApplet extends Applet { case INS_SET: insSet(apdu); break; + case INS_CORRUPT: + insCorrupt(apdu); + break; case INS_GENERATE: insGenerate(apdu); break; @@ -199,13 +203,11 @@ public class ECTesterApplet extends Applet { /** * Sets curve parameters on local and remote keyPairs. - * returns setCurve SWs, set params if export + * returns setCurve SWs * * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) * P2 = byte curve (EC_Consts.CURVE_*) * DATA = short params (EC_Consts.PARAMETER_* | ...) - * short corruptedParams (EC_Consts.PARAMETER_* | ...) - * byte corruptionType (EC_Consts.CORRUPTION_*) * <p> * if curveID = CURVE_EXTERNAL: * [short paramLength, byte[] param], @@ -219,16 +221,44 @@ public class ECTesterApplet extends Applet { byte keyPair = apdubuf[ISO7816.OFFSET_P1]; byte curve = apdubuf[ISO7816.OFFSET_P2]; short params = Util.getShort(apdubuf, ISO7816.OFFSET_CDATA); - short corruptedParams = Util.getShort(apdubuf, (short) (ISO7816.OFFSET_CDATA + 2)); - byte corruptionType = apdubuf[(short) (ISO7816.OFFSET_CDATA + 4)]; short len = 0; if ((keyPair & KEYPAIR_LOCAL) != 0) { - len += set(localKeypair, curve, params, corruptedParams, corruptionType, apdubuf, (short) (ISO7816.OFFSET_CDATA + 5), (short) 0); + len += set(localKeypair, curve, params, apdubuf, (short) (ISO7816.OFFSET_CDATA + 2), (short) 0); + } + if ((keyPair & KEYPAIR_REMOTE) != 0) { + len += set(remoteKeypair, curve, params, apdubuf, (short) (ISO7816.OFFSET_CDATA + 2), len); + } + + apdu.setOutgoingAndSend((short) 0, len); + } + + /** + * Corrupts curve paramaters of local and remote keyPairs. + * returns corruptCurve SWs + * + * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) + * P2 = byte key (EC_Consts.KEY_* | ...) + * DATA = short params (EC_Consts.PARAMETER_* | ...) + * byte corruption (EC_Consts.CORRUPTION_* || ...) + */ + private void insCorrupt(APDU apdu) { + apdu.setIncomingAndReceive(); + byte[] apdubuf = apdu.getBuffer(); + + byte keyPair = apdubuf[ISO7816.OFFSET_P1]; + byte key = apdubuf[ISO7816.OFFSET_P2]; + short params = Util.getShort(apdubuf, ISO7816.OFFSET_CDATA); + byte corruption = apdubuf[(short) (ISO7816.OFFSET_CDATA + 2)]; + + short len = 0; + if ((keyPair & KEYPAIR_LOCAL) != 0) { + len += corrupt(localKeypair, key, params, corruption, apdubuf, (short) 0); } + if ((keyPair & KEYPAIR_REMOTE) != 0) { - len += set(remoteKeypair, curve, params, corruptedParams, corruptionType, apdubuf, (short) (ISO7816.OFFSET_CDATA + 5), len); + len += corrupt(remoteKeypair, key, params, corruption, apdubuf, len); } apdu.setOutgoingAndSend((short) 0, len); @@ -236,7 +266,7 @@ public class ECTesterApplet extends Applet { /** * Generates the local and remote keyPairs. - * returns generate SWs, pubkey and privkey if export + * returns generate SWs * * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) * P2 = @@ -376,17 +406,15 @@ public class ECTesterApplet extends Applet { } /** - * @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_* | ...) - * @param corruption corruption type (EC_Consts.CORRUPTION_*) - * @param buffer buffer to read params from and write sw to - * @param inOffset input offset in buffer - * @param outOffset output offset in buffer + * @param keyPair KeyPair to set params on + * @param curve curve to set (EC_Consts.CURVE_*) + * @param params parameters to set (EC_Consts.PARAMETER_* | ...) + * @param buffer buffer to read params from and write sw to + * @param inOffset input offset in buffer + * @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, byte[] buffer, short inOffset, short outOffset) { short sw = ISO7816.SW_NO_ERROR; switch (curve) { @@ -403,13 +431,27 @@ public class ECTesterApplet extends Applet { break; } - if (sw == ISO7816.SW_NO_ERROR) - sw = keyGenerator.corruptCurve(keyPair, corrupted, corruption, ramArray, (short) 0); Util.setShort(buffer, outOffset, sw); return 2; } /** + * + * @param keyPair KeyPair to corrupt + * @param key key to corrupt (EC_Consts.KEY_* | ...) + * @param params parameters to corrupt (EC_Consts.PARAMETER_* | ...) + * @param corruption corruption type (EC_Consts.CORRUPTION_*) + * @param buffer buffer to output sw to + * @param offset output offset in buffer + * @return length of data written to the buffer + */ + private short corrupt(KeyPair keyPair, byte key, short params, byte corruption, byte[] buffer, short offset) { + short sw = keyGenerator.corruptCurve(keyPair, key, params, corruption, ramArray, (short) 0); + Util.setShort(buffer, offset, sw); + return 2; + } + + /** * @param keyPair KeyPair to generate * @param buffer buffer to write sw to * @param offset output offset in buffer diff --git a/src/cz/crcs/ectester/applet/EC_Consts.java b/src/cz/crcs/ectester/applet/EC_Consts.java index fc62c67..68fb4c9 100644 --- a/src/cz/crcs/ectester/applet/EC_Consts.java +++ b/src/cz/crcs/ectester/applet/EC_Consts.java @@ -947,6 +947,7 @@ public class EC_Consts { public static final byte CORRUPTION_ONEBYTERANDOM = (byte) 0x03; public static final byte CORRUPTION_ZERO = (byte) 0x04; public static final byte CORRUPTION_ONE = (byte) 0x05; + public static final byte CORRUPTION_INCREMENT = (byte) 0x06; // Supported embedded curves, getCurveParameter @@ -1269,18 +1270,16 @@ public class EC_Consts { case CORRUPTION_ONE: Util.arrayFillNonAtomic(buffer, offset, length, (byte) 1); break; + case CORRUPTION_INCREMENT: + short index = (short) (offset + length - 1); + byte value; + do { + value = buffer[index]; + buffer[index--] = ++value; + } while (value == (byte) 0 && index >= offset); + break; default: ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED); - /* //TODO implement CORRUPT_B_LASTBYTEINCREMENT somehow - case CORRUPT_B_LASTBYTEINCREMENT: - m_ramArray2[(short) (m_lenB - 1)] += 1; - // Make sure its not the valid byte again - if (m_ramArray[(short) (m_lenB - 1)] == m_ramArray2[(short) (m_lenB - 1)]) { - m_ramArray2[(short) (m_lenB - 1)] += 1; // if yes, increment once more - } - break; - } - */ } } diff --git a/src/cz/crcs/ectester/reader/Command.java b/src/cz/crcs/ectester/reader/Command.java index c6ce2b5..cb2321a 100644 --- a/src/cz/crcs/ectester/reader/Command.java +++ b/src/cz/crcs/ectester/reader/Command.java @@ -75,6 +75,10 @@ public abstract class Command { public static class Clear extends Command { private byte keyPair; + /** + * @param cardManager + * @param keyPair which keyPair clear, local/remote (KEYPAIR_* || ...) + */ public Clear(CardMngr cardManager, byte keyPair) { super(cardManager); this.keyPair = keyPair; @@ -98,8 +102,6 @@ public abstract class Command { private byte keyPair; private byte curve; private short params; - private short corrupted; - private byte corruption; private byte[] external; /** @@ -109,26 +111,20 @@ public abstract class Command { * @param keyPair which keyPair to set params on, local/remote (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 curve, short params, short corrupted, byte corruption, byte[] external) { + public Set(CardMngr cardManager, byte keyPair, byte curve, short params, byte[] external) { super(cardManager); this.keyPair = keyPair; this.curve = curve; this.params = params; - this.corrupted = corrupted; - this.corruption = corruption; this.external = external; - int len = external != null ? 5 + 2 + external.length : 5; + int len = external != null ? 2 + external.length : 2; byte[] data = new byte[len]; Util.setShort(data, 0, params); - Util.setShort(data, 2, corrupted); - data[4] = corruption; if (external != null) { - System.arraycopy(external, 0, data, 5, external.length); + System.arraycopy(external, 0, data, 2, external.length); } this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_SET, keyPair, curve, data); @@ -139,7 +135,46 @@ public abstract class Command { long elapsed = -System.nanoTime(); ResponseAPDU response = cardManager.send(cmd); elapsed += System.nanoTime(); - return new Response.Set(response, elapsed, keyPair, curve, params, corrupted); + return new Response.Set(response, elapsed, keyPair, curve, params); + } + } + + /** + * + */ + public static class Corrupt extends Command { + private byte keyPair; + private byte key; + private short params; + private byte corruption; + + /** + * @param cardManager + * @param keyPair which keyPair to corrupt, local/remote (KEYPAIR_* || ...) + * @param key + * @param params parameters to corrupt (EC_Consts.PARAMETER_* | ...) + * @param corruption corruption type (EC_Consts.CORRUPTION_*) + */ + protected Corrupt(CardMngr cardManager, byte keyPair, byte key, short params, byte corruption) { + super(cardManager); + this.keyPair = keyPair; + this.key = key; + this.params = params; + this.corruption = corruption; + + byte[] data = new byte[3]; + Util.setShort(data, 0, params); + data[2] = corruption; + + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_CORRUPT, keyPair, key, data); + } + + @Override + public Response.Corrupt send() throws CardException { + long elapsed = -System.nanoTime(); + ResponseAPDU response = cardManager.send(cmd); + elapsed += System.nanoTime(); + return new Response.Corrupt(response, elapsed, keyPair, key, params, corruption); } } diff --git a/src/cz/crcs/ectester/reader/ECTester.java b/src/cz/crcs/ectester/reader/ECTester.java index 86588df..35982d7 100644 --- a/src/cz/crcs/ectester/reader/ECTester.java +++ b/src/cz/crcs/ectester/reader/ECTester.java @@ -233,14 +233,14 @@ public class ECTester { opts.addOptionGroup(actions); OptionGroup size = new OptionGroup(); - size.addOption(Option.builder("b").longOpt("bit-size").desc("Set curve size.").hasArg().argName("b").build()); + size.addOption(Option.builder("b").longOpt("bit-size").desc("Set curve size.").hasArg().argName("bits").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.").hasArg().argName("cat/id").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()); - curve.addOption(Option.builder("u").longOpt("custom").desc("Use a custom curve(applet-side embedded, SECG curves).").build()); + curve.addOption(Option.builder("u").longOpt("custom").desc("Use a custom curve(applet-side embedded, SECG curvgites).").build()); opts.addOptionGroup(curve); opts.addOption(Option.builder("fp").longOpt("prime-field").desc("Use prime field curve.").build()); @@ -257,7 +257,7 @@ public class ECTester { opts.addOptionGroup(priv); OptionGroup key = new OptionGroup(); - key.addOption(Option.builder("nk").longOpt("named-key").desc("Use keyPair from KeyDB: [cat/id|id|cat]").hasArg().argName("[cat/id|id|cat]").build()); + key.addOption(Option.builder("nk").longOpt("named-key").desc("Use keyPair from KeyDB: [cat/id]").hasArg().argName("cat/id").build()); key.addOption(Option.builder("k").longOpt("key").desc("Use keyPair from fileĀ [key_file] (wx,wy,s).").hasArg().argName("key_file").build()); opts.addOptionGroup(key); @@ -529,7 +529,7 @@ public class ECTester { if (curve.getField() == KeyPair.ALG_EC_FP) { commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), KeyPair.ALG_EC_FP)); byte[] external = curve.flatten(); - commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, external)); + commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), external)); commands.addAll(testCurve()); } } @@ -540,7 +540,7 @@ public class ECTester { if (curve.getField() == KeyPair.ALG_EC_F2M) { commands.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, curve.getBits(), KeyPair.ALG_EC_F2M)); byte[] external = curve.flatten(); - commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, external)); + commands.add(new Command.Set(cardManager, ECTesterApplet.KEYPAIR_BOTH, EC_Consts.CURVE_external, curve.getParams(), external)); commands.addAll(testCurve()); } } @@ -719,7 +719,7 @@ public class ECTester { short domainParams = keyClass == KeyPair.ALG_EC_FP ? EC_Consts.PARAMETERS_DOMAIN_FP : EC_Consts.PARAMETERS_DOMAIN_F2M; if (optCustomCurve) { // Set custom curve (one of the SECG curves embedded applet-side) - commands.add(new Command.Set(cardManager, keyPair, EC_Consts.getCurve(keyLength, keyClass), domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, null)); + commands.add(new Command.Set(cardManager, keyPair, EC_Consts.getCurve(keyLength, keyClass), domainParams, null)); } else if (optNamedCurve != null) { // Set a named curve. // parse optNamedCurve -> cat / id | cat | id @@ -735,7 +735,7 @@ public class ECTester { if (external == null) { throw new IOException("Couldn't read named curve data."); } - commands.add(new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, external)); + commands.add(new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, domainParams, external)); } else if (optCurveFile != null) { // Set curve loaded from a file EC_Params params = new EC_Params(domainParams); @@ -748,7 +748,7 @@ public class ECTester { if (external == null) { throw new IOException("Couldn't read the curve file correctly."); } - commands.add(new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, domainParams, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, external)); + commands.add(new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, domainParams, external)); } else { // Set default curve commands.add(new Command.Clear(cardManager, keyPair)); @@ -823,7 +823,7 @@ public class ECTester { } data = Util.concatenate(data, privkey); } - return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, params, EC_Consts.PARAMETERS_NONE, EC_Consts.CORRUPTION_NONE, data); + return new Command.Set(cardManager, keyPair, EC_Consts.CURVE_external, params, data); } /** diff --git a/src/cz/crcs/ectester/reader/Response.java b/src/cz/crcs/ectester/reader/Response.java index e76d35c..25b5817 100644 --- a/src/cz/crcs/ectester/reader/Response.java +++ b/src/cz/crcs/ectester/reader/Response.java @@ -129,7 +129,7 @@ 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", 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"); } @@ -202,14 +202,12 @@ public abstract class Response { private byte keyPair; private byte curve; private short parameters; - private short corrupted; - protected Set(ResponseAPDU response, long time, byte keyPair, byte curve, short parameters, short corrupted) { + protected Set(ResponseAPDU response, long time, byte keyPair, byte curve, short parameters) { super(response, time); this.keyPair = keyPair; this.curve = curve; this.parameters = parameters; - this.corrupted = corrupted; int pairs = 0; if ((keyPair & ECTesterApplet.KEYPAIR_LOCAL) != 0) pairs++; @@ -232,13 +230,13 @@ public abstract class Response { name = "custom"; break; } - String key; + String pair; if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { - key = "both keypairs"; + pair = "both keypairs"; } else { - key = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; } - return String.format("Set %s curve parameters on %s", name, key); + return String.format("Set %s curve parameters on %s", name, pair); } } @@ -246,6 +244,43 @@ public abstract class Response { /** * */ + public static class Corrupt extends Response { + private byte keyPair; + private byte key; + private short params; + private byte corruption; + + protected Corrupt(ResponseAPDU response, long time, byte keyPair, byte key, short params, byte corruption) { + super(response, time); + this.keyPair = keyPair; + this.key = key; + this.params = params; + this.corruption = corruption; + + 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 corrupt = Util.getCorruption(corruption); + + String pair; + if (keyPair == ECTesterApplet.KEYPAIR_BOTH) { + pair = "both keypairs"; + } else { + pair = ((keyPair == ECTesterApplet.KEYPAIR_LOCAL) ? "local" : "remote") + " keypair"; + } + return String.format("Corrupted params of %s, %s", pair, corrupt); + } + } + + /** + * + */ public static class Generate extends Response { private byte keyPair; diff --git a/src/cz/crcs/ectester/reader/Util.java b/src/cz/crcs/ectester/reader/Util.java index e297ab1..91a34d7 100644 --- a/src/cz/crcs/ectester/reader/Util.java +++ b/src/cz/crcs/ectester/reader/Util.java @@ -1,6 +1,7 @@ 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.CryptoException; @@ -130,4 +131,35 @@ public class Util { return String.format("fail\t(%s,\t0x%04x)", codeStr, code); } } + + public static String getCorruption(byte corruptionType) { + String corrupt; + switch (corruptionType) { + case EC_Consts.CORRUPTION_NONE: + corrupt = "NONE"; + break; + case EC_Consts.CORRUPTION_FIXED: + corrupt = "FIXED"; + break; + case EC_Consts.CORRUPTION_ONE: + corrupt = "ONE"; + break; + case EC_Consts.CORRUPTION_ZERO: + corrupt = "ZERO"; + break; + case EC_Consts.CORRUPTION_ONEBYTERANDOM: + corrupt = "ONE_BYTE_RANDOM"; + break; + case EC_Consts.CORRUPTION_FULLRANDOM: + corrupt = "FULL_RANDOM"; + break; + case EC_Consts.CORRUPTION_INCREMENT: + corrupt = "INCREMENT"; + break; + default: + corrupt = "UNKNOWN"; + break; + } + return corrupt; + } } |
