aboutsummaryrefslogtreecommitdiff
path: root/src/cz/crcs/ectester/common
diff options
context:
space:
mode:
authorJ08nY2017-11-26 23:27:07 +0100
committerJ08nY2017-11-26 23:27:07 +0100
commit83943c809c56c1856038b21fd91f50cc709310aa (patch)
tree5c832a8eff94794ec364bd0de5022e13aba3f88b /src/cz/crcs/ectester/common
parent23bd6d8439e9e536d5de672a556211b896b9e98d (diff)
downloadECTester-83943c809c56c1856038b21fd91f50cc709310aa.tar.gz
ECTester-83943c809c56c1856038b21fd91f50cc709310aa.tar.zst
ECTester-83943c809c56c1856038b21fd91f50cc709310aa.zip
Split Util class into a package.
Diffstat (limited to '')
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_Curve.java54
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_Data.java31
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_KAResult.java4
-rw-r--r--src/cz/crcs/ectester/common/ec/EC_Params.java24
-rw-r--r--src/cz/crcs/ectester/common/util/ByteUtil.java122
-rw-r--r--src/cz/crcs/ectester/common/util/CardUtil.java (renamed from src/cz/crcs/ectester/common/Util.java)124
6 files changed, 210 insertions, 149 deletions
diff --git a/src/cz/crcs/ectester/common/ec/EC_Curve.java b/src/cz/crcs/ectester/common/ec/EC_Curve.java
index 478ce7d..19228dc 100644
--- a/src/cz/crcs/ectester/common/ec/EC_Curve.java
+++ b/src/cz/crcs/ectester/common/ec/EC_Curve.java
@@ -1,7 +1,7 @@
package cz.crcs.ectester.common.ec;
import cz.crcs.ectester.applet.EC_Consts;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.ByteUtil;
import javacard.security.KeyPair;
import java.math.BigInteger;
@@ -60,10 +60,10 @@ public class EC_Curve extends EC_Params {
field = new ECFieldFp(new BigInteger(1, getData(0)));
} else {
byte[][] fieldData = getParam(EC_Consts.PARAMETER_F2M);
- int m = Util.getShort(fieldData[0], 0);
- int e1 = Util.getShort(fieldData[1], 0);
- int e2 = Util.getShort(fieldData[2], 0);
- int e3 = Util.getShort(fieldData[3], 0);
+ int m = ByteUtil.getShort(fieldData[0], 0);
+ int e1 = ByteUtil.getShort(fieldData[1], 0);
+ int e2 = ByteUtil.getShort(fieldData[2], 0);
+ int e3 = ByteUtil.getShort(fieldData[3], 0);
int[] powers = new int[]{e1, e2, e3};
field = new ECFieldF2m(m, powers);
}
@@ -80,8 +80,50 @@ public class EC_Curve extends EC_Params {
BigInteger n = new BigInteger(1, getParam(EC_Consts.PARAMETER_R)[0]);
- int h = Util.getShort(getParam(EC_Consts.PARAMETER_K)[0], 0);
+ int h = ByteUtil.getShort(getParam(EC_Consts.PARAMETER_K)[0], 0);
return new ECParameterSpec(curve, generator, n, h);
}
+
+ public static EC_Curve fromSpec(ECParameterSpec spec) {
+ EllipticCurve curve = spec.getCurve();
+ ECField field = curve.getField();
+
+ short bits = (short) field.getFieldSize();
+ byte[][] params;
+ int paramIndex = 0;
+ byte fieldType;
+ if (field instanceof ECFieldFp) {
+ ECFieldFp primeField = (ECFieldFp) field;
+ params = new byte[5][];
+ params[paramIndex++] = primeField.getP().toByteArray();
+ fieldType = KeyPair.ALG_EC_FP;
+ } else if (field instanceof ECFieldF2m) {
+ ECFieldF2m binaryField = (ECFieldF2m) field;
+ params = new byte[8][];
+ params[paramIndex] = new byte[2];
+ ByteUtil.setShort(params[paramIndex++], 0, (short) binaryField.getM());
+ int[] powers = binaryField.getMidTermsOfReductionPolynomial();
+ for (int i = 0; i < 3; ++i) {
+ params[paramIndex] = new byte[2];
+ ByteUtil.setShort(params[paramIndex++], 0, (short) powers[i]);
+ }
+ fieldType = KeyPair.ALG_EC_F2M;
+ } else {
+ throw new IllegalArgumentException("ECParameterSpec with an unknnown field.");
+ }
+
+ ECPoint generator = spec.getGenerator();
+
+ params[paramIndex++] = generator.getAffineX().toByteArray();
+ params[paramIndex++] = generator.getAffineY().toByteArray();
+
+ params[paramIndex++] = spec.getOrder().toByteArray();
+ params[paramIndex] = new byte[2];
+ ByteUtil.setShort(params[paramIndex], 0, (short) spec.getCofactor());
+
+ EC_Curve result = new EC_Curve(bits, fieldType);
+ result.readByteArray(params);
+ return result;
+ }
}
diff --git a/src/cz/crcs/ectester/common/ec/EC_Data.java b/src/cz/crcs/ectester/common/ec/EC_Data.java
index acd282a..c048ef7 100644
--- a/src/cz/crcs/ectester/common/ec/EC_Data.java
+++ b/src/cz/crcs/ectester/common/ec/EC_Data.java
@@ -1,6 +1,6 @@
package cz.crcs.ectester.common.ec;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.ByteUtil;
import java.io.*;
import java.util.*;
@@ -8,9 +8,10 @@ import java.util.regex.Pattern;
/**
* A list of byte arrays for holding EC data.
- *
+ * <p>
* The data can be read from a byte array via <code>readBytes()</code>, from a CSV via <code>readCSV()</code>.
* The data can be exported to a byte array via <code>flatten()</code> or to a string array via <code>expand()</code>.
+ *
* @author Jan Jancar johny@neuromancer.sk
*/
public abstract class EC_Data {
@@ -67,7 +68,7 @@ public abstract class EC_Data {
ByteArrayOutputStream out = new ByteArrayOutputStream();
for (byte[] param : data) {
byte[] length = new byte[2];
- Util.setShort(length, 0, (short) param.length);
+ ByteUtil.setShort(length, 0, (short) param.length);
out.write(length, 0, 2);
out.write(param, 0, param.length);
@@ -79,7 +80,7 @@ public abstract class EC_Data {
public String[] expand() {
List<String> out = new ArrayList<>(count);
for (byte[] param : data) {
- out.add(Util.bytesToHex(param, false));
+ out.add(ByteUtil.bytesToHex(param, false));
}
return out.toArray(new String[out.size()]);
@@ -97,9 +98,9 @@ public abstract class EC_Data {
private static byte[] parse(String param) {
byte[] data;
if (param.startsWith("0x") || param.startsWith("0X")) {
- data = Util.hexToBytes(param.substring(2));
+ data = ByteUtil.hexToBytes(param.substring(2));
} else {
- data = Util.hexToBytes(param);
+ data = ByteUtil.hexToBytes(param);
}
if (data == null)
return new byte[0];
@@ -141,12 +142,16 @@ public abstract class EC_Data {
}
public boolean readBytes(byte[] bytes) {
+ if (bytes == null) {
+ return false;
+ }
+
int offset = 0;
for (int i = 0; i < count; i++) {
if (bytes.length - offset < 2) {
return false;
}
- short paramLength = Util.getShort(bytes, offset);
+ short paramLength = ByteUtil.getShort(bytes, offset);
offset += 2;
if (bytes.length < offset + paramLength) {
return false;
@@ -158,6 +163,18 @@ public abstract class EC_Data {
return true;
}
+ public boolean readByteArray(byte[][] bytes) {
+ if (bytes == null || count != bytes.length) {
+ return false;
+ }
+
+ for (int i = 0; i < count; ++i) {
+ data[i] = new byte[bytes[i].length];
+ System.arraycopy(bytes[i], 0, data[i], 0, bytes[i].length);
+ }
+ return true;
+ }
+
public void writeCSV(OutputStream out) throws IOException {
Writer w = new OutputStreamWriter(out);
w.write(String.join(",", expand()));
diff --git a/src/cz/crcs/ectester/common/ec/EC_KAResult.java b/src/cz/crcs/ectester/common/ec/EC_KAResult.java
index 3b74c57..a7b3cd5 100644
--- a/src/cz/crcs/ectester/common/ec/EC_KAResult.java
+++ b/src/cz/crcs/ectester/common/ec/EC_KAResult.java
@@ -1,6 +1,6 @@
package cz.crcs.ectester.common.ec;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.CardUtil;
/**
* A result of EC based Key agreement operation.
@@ -56,7 +56,7 @@ public class EC_KAResult extends EC_Data {
@Override
public String toString() {
- String algo = Util.getKA(ka);
+ String algo = CardUtil.getKA(ka);
return "<" + getId() + "> " + algo + " result over " + curve + ", " + oneKey + " + " + otherKey + (desc == null ? "" : ": " + desc);
}
diff --git a/src/cz/crcs/ectester/common/ec/EC_Params.java b/src/cz/crcs/ectester/common/ec/EC_Params.java
index 3fada93..1c066e7 100644
--- a/src/cz/crcs/ectester/common/ec/EC_Params.java
+++ b/src/cz/crcs/ectester/common/ec/EC_Params.java
@@ -1,7 +1,7 @@
package cz.crcs.ectester.common.ec;
import cz.crcs.ectester.applet.EC_Consts;
-import cz.crcs.ectester.common.Util;
+import cz.crcs.ectester.common.util.ByteUtil;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
@@ -125,12 +125,12 @@ public class EC_Params extends EC_Data {
byte[] param = data[i];
if (masked == EC_Consts.PARAMETER_F2M) {
//add m, e_1, e_2, e_3
- param = Util.concatenate(param, data[i + 1]);
- if (!Util.allValue(data[i + 2], (byte) 0)) {
- param = Util.concatenate(param, data[i + 2]);
+ param = ByteUtil.concatenate(param, data[i + 1]);
+ if (!ByteUtil.allValue(data[i + 2], (byte) 0)) {
+ param = ByteUtil.concatenate(param, data[i + 2]);
}
- if (!Util.allValue(data[i + 3], (byte) 0)) {
- param = Util.concatenate(param, data[i + 3]);
+ if (!ByteUtil.allValue(data[i + 3], (byte) 0)) {
+ param = ByteUtil.concatenate(param, data[i + 3]);
}
if (!(param.length == 4 || param.length == 8))
throw new RuntimeException("PARAMETER_F2M length is not 8.(should be)");
@@ -138,14 +138,14 @@ public class EC_Params extends EC_Data {
if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) {
//read another param (the y coord) and put into X962 format.
byte[] y = data[i + 1];
- param = Util.concatenate(new byte[]{4}, param, y); //<- ugly but works!
+ param = ByteUtil.concatenate(new byte[]{4}, param, y); //<- ugly but works!
}
if (param.length == 0)
throw new RuntimeException("Empty parameter read?");
//write length
byte[] length = new byte[2];
- Util.setShort(length, 0, (short) param.length);
+ ByteUtil.setShort(length, 0, (short) param.length);
out.write(length, 0, 2);
//write data
out.write(param, 0, param.length);
@@ -175,15 +175,15 @@ public class EC_Params extends EC_Data {
byte[] param = data[index];
if (masked == EC_Consts.PARAMETER_F2M) {
for (int i = 0; i < 4; ++i) {
- out.add(Util.bytesToHex(data[index + i], false));
+ out.add(ByteUtil.bytesToHex(data[index + i], false));
}
index += 4;
} else if (masked == EC_Consts.PARAMETER_G || masked == EC_Consts.PARAMETER_W) {
- out.add(Util.bytesToHex(param, false));
- out.add(Util.bytesToHex(data[index + 1], false));
+ out.add(ByteUtil.bytesToHex(param, false));
+ out.add(ByteUtil.bytesToHex(data[index + 1], false));
index += 2;
} else {
- out.add(Util.bytesToHex(param, false));
+ out.add(ByteUtil.bytesToHex(param, false));
index++;
}
}
diff --git a/src/cz/crcs/ectester/common/util/ByteUtil.java b/src/cz/crcs/ectester/common/util/ByteUtil.java
new file mode 100644
index 0000000..939e487
--- /dev/null
+++ b/src/cz/crcs/ectester/common/util/ByteUtil.java
@@ -0,0 +1,122 @@
+package cz.crcs.ectester.common.util;
+
+/**
+ * Utility class, some byte/hex manipulation, convenient byte[] methods.
+ *
+ * @author Petr Svenda petr@svenda.com
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class ByteUtil {
+ public static short getShort(byte[] array, int offset) {
+ return (short) (((array[offset] & 0xFF) << 8) | (array[offset + 1] & 0xFF));
+ }
+
+ public static void setShort(byte[] array, int offset, short value) {
+ array[offset + 1] = (byte) (value & 0xFF);
+ array[offset] = (byte) ((value >> 8) & 0xFF);
+ }
+
+ public static int diffBytes(byte[] one, int oneOffset, byte[] other, int otherOffset, int length) {
+ for (int i = 0; i < length; ++i) {
+ byte a = one[i + oneOffset];
+ byte b = other[i + otherOffset];
+ if (a != b) {
+ return i;
+ }
+ }
+ return length;
+ }
+
+ public static boolean compareBytes(byte[] one, int oneOffset, byte[] other, int otherOffset, int length) {
+ return diffBytes(one, oneOffset, other, otherOffset, length) == length;
+ }
+
+ public static boolean allValue(byte[] array, byte value) {
+ for (byte a : array) {
+ if (a != value)
+ return false;
+ }
+ return true;
+ }
+
+ public static byte[] hexToBytes(String hex) {
+ return hexToBytes(hex, true);
+ }
+
+ public static byte[] hexToBytes(String hex, boolean bigEndian) {
+ hex = hex.replace(" ", "");
+ int len = hex.length();
+ StringBuilder sb = new StringBuilder();
+
+ if (len % 2 == 1) {
+ sb.append("0");
+ ++len;
+ }
+
+ if (bigEndian) {
+ sb.append(hex);
+ } else {
+ for (int i = 0; i < len / 2; ++i) {
+ if (sb.length() >= 2) {
+ sb.insert(sb.length() - 2, hex.substring(2 * i, 2 * i + 2));
+ } else {
+ sb.append(hex.substring(2 * i, 2 * i + 2));
+ }
+
+ }
+ }
+
+ String data = sb.toString();
+ byte[] result = new byte[len / 2];
+ for (int i = 0; i < len; i += 2) {
+ result[i / 2] = (byte) ((Character.digit(data.charAt(i), 16) << 4)
+ + (Character.digit(data.charAt(i + 1), 16)));
+ }
+ return result;
+ }
+
+ public static String byteToHex(byte data) {
+ return String.format("%02x", data);
+ }
+
+ public static String bytesToHex(byte[] data) {
+ 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 addSpace) {
+ StringBuilder buf = new StringBuilder();
+ for (int i = offset; i < (offset + len); i++) {
+ buf.append(byteToHex(data[i]));
+ if (addSpace && i != (offset + len - 1)) {
+ buf.append(" ");
+ }
+ }
+ return (buf.toString());
+ }
+
+ public static byte[] concatenate(byte[]... arrays) {
+ int len = 0;
+ for (byte[] array : arrays) {
+ if (array == null)
+ continue;
+ len += array.length;
+ }
+ byte[] out = new byte[len];
+ int offset = 0;
+ for (byte[] array : arrays) {
+ if (array == null || array.length == 0)
+ continue;
+ System.arraycopy(array, 0, out, offset, array.length);
+ offset += array.length;
+ }
+ return out;
+ }
+}
diff --git a/src/cz/crcs/ectester/common/Util.java b/src/cz/crcs/ectester/common/util/CardUtil.java
index 0136493..a94c773 100644
--- a/src/cz/crcs/ectester/common/Util.java
+++ b/src/cz/crcs/ectester/common/util/CardUtil.java
@@ -1,4 +1,4 @@
-package cz.crcs.ectester.common;
+package cz.crcs.ectester.common.util;
import cz.crcs.ectester.applet.ECTesterApplet;
import cz.crcs.ectester.applet.EC_Consts;
@@ -7,127 +7,7 @@ import javacard.security.CryptoException;
import static cz.crcs.ectester.applet.ECTesterApplet.*;
-/**
- * Utility class, some byte/hex manipulation, convenient byte[] methods.
- *
- * @author Petr Svenda petr@svenda.com
- * @author Jan Jancar johny@neuromancer.sk
- */
-public class Util {
-
- public static short getShort(byte[] array, int offset) {
- return (short) (((array[offset] & 0xFF) << 8) | (array[offset + 1] & 0xFF));
- }
-
- public static void setShort(byte[] array, int offset, short value) {
- array[offset + 1] = (byte) (value & 0xFF);
- array[offset] = (byte) ((value >> 8) & 0xFF);
- }
-
- public static int diffBytes(byte[] one, int oneOffset, byte[] other, int otherOffset, int length) {
- for (int i = 0; i < length; ++i) {
- byte a = one[i + oneOffset];
- byte b = other[i + otherOffset];
- if (a != b) {
- return i;
- }
- }
- return length;
- }
-
- public static boolean compareBytes(byte[] one, int oneOffset, byte[] other, int otherOffset, int length) {
- return diffBytes(one, oneOffset, other, otherOffset, length) == length;
- }
-
- public static boolean allValue(byte[] array, byte value) {
- for (byte a : array) {
- if (a != value)
- return false;
- }
- return true;
- }
-
- public static byte[] hexToBytes(String hex) {
- return hexToBytes(hex, true);
- }
-
- public static byte[] hexToBytes(String hex, boolean bigEndian) {
- hex = hex.replace(" ", "");
- int len = hex.length();
- StringBuilder sb = new StringBuilder();
-
- if (len % 2 == 1) {
- sb.append("0");
- ++len;
- }
-
- if (bigEndian) {
- sb.append(hex);
- } else {
- for (int i = 0; i < len / 2; ++i) {
- if (sb.length() >= 2) {
- sb.insert(sb.length() - 2, hex.substring(2 * i, 2 * i + 2));
- } else {
- sb.append(hex.substring(2 * i, 2 * i + 2));
- }
-
- }
- }
-
- String data = sb.toString();
- byte[] result = new byte[len / 2];
- for (int i = 0; i < len; i += 2) {
- result[i / 2] = (byte) ((Character.digit(data.charAt(i), 16) << 4)
- + (Character.digit(data.charAt(i + 1), 16)));
- }
- return result;
- }
-
- public static String byteToHex(byte data) {
- return String.format("%02x", data);
- }
-
- public static String bytesToHex(byte[] data) {
- 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 addSpace) {
- StringBuilder buf = new StringBuilder();
- for (int i = offset; i < (offset + len); i++) {
- buf.append(byteToHex(data[i]));
- if (addSpace && i != (offset + len - 1)) {
- buf.append(" ");
- }
- }
- return (buf.toString());
- }
-
- public static byte[] concatenate(byte[]... arrays) {
- int len = 0;
- for (byte[] array : arrays) {
- if (array == null)
- continue;
- len += array.length;
- }
- byte[] out = new byte[len];
- int offset = 0;
- for (byte[] array : arrays) {
- if (array == null || array.length == 0)
- continue;
- System.arraycopy(array, 0, out, offset, array.length);
- offset += array.length;
- }
- return out;
- }
-
+public class CardUtil {
public static String getSWSource(short sw) {
switch (sw) {
case ISO7816.SW_NO_ERROR: