diff options
| -rw-r--r-- | README.md | 110 | ||||
| -rw-r--r-- | docs/LIBS.md | 7 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/AppletBase.java | 22 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/applet/ECKeyGenerator.java | 34 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/ECTesterReader.java | 11 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/reader/command/Command.java | 11 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/standalone/libs/jni/c_timing.c | 4 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/standalone/libs/jni/c_utils.c | 8 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/standalone/libs/jni/mscng.c | 45 | ||||
| -rw-r--r-- | util/utils.py | 18 |
10 files changed, 186 insertions, 84 deletions
@@ -103,6 +103,7 @@ See `java -jar ECTesterReader.jar -h`, `java -jar ECTesterReader.jar -ls` and [D it for later ECDH. --fixed-public Generate public key only once, keep it for later ECDH. + -kb,--key-builder Allocate KeyPair using KeyBuilder. -f,--fresh Generate fresh keys (set domain parameters before every generation). --time Output better timing values, by @@ -293,6 +294,9 @@ Currently supported libraries include: - [libgcrypt](https://www.gnupg.org/related_software/libgcrypt/) - [Botan](https://botan.randombit.net/) - [Microsoft CNG](https://msdn.microsoft.com/en-us/library/windows/desktop/aa376210(v=vs.85).aspx) + - [Intel Performance Primitives Crypto](https://github.com/intel/ipp-crypto) + - [MatrixSSL](https://github.com/matrixssl/matrixssl) + - [MbedTLS](https://github.com/ARMmbed/mbedtls) For more information on ECC libraries see [LIBS](docs/LIBS.md). @@ -316,24 +320,23 @@ To install, place them in `${java.home}/jre/lib/security/`. ``` usage: ECTesterStandalone.jar [-V] [-h <command>] [-C] [ -(ecdh [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-t <type>] [--key-type <algorithm>] [-n <amount>] - [-npriv <cat/id>] [--fixed-private] [-npub <cat/id>] [--fixed-public]) | -(ecdsa [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-npriv <cat/id>] [-npub <cat/id>] [-t <type>] - [-n <amount>] [-f <file>]) | -(export [-b <n>] [-o <output_file>] [-t <type>]) | -(generate [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-n <amount>] [-t <type>]) | -(list-data [what]) | -(list-libs) | -(list-suites) | -(test [-b <n>] [-nc <cat/id>] [-cn <name>] [-gt <type>] [-kt <type>] [-st <type>] [-f <format>] [--key-type <algorithm>] <test-suite>) ] -[lib] + (ecdh [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-t <type>] [--key-type <algorithm>] [-n <amount>] [-npub <cat/id> | -pub <pubkey>] [--fixed-private] [-npriv <cat/id> | -priv <privkey>] [--fixed-public]) | + (ecdsa [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-npriv <cat/id> | -priv <privkey>] [-npub <cat/id> | -pub <pubkey>] [-t <type>] [-n <amount>] [-f <file>]) | + (export [-b <n>] [-o <output_file>] [-t <type>]) | + (generate [-b <n>] [-nc <cat/id>] [-cn <name>] [-o <output_file>] [-n <amount>] [-t <type>]) | + (list-data [what]) | + (list-libs) | + (list-suites) | + (list-types) | + (test [-b <n>] [-nc <cat/id>] [-cn <name>] [-gt <type>] [-kt <type>] [-st <type>] [-f <format>] [--key-type <algorithm>] <test-suite>) +] [lib] - -V,--version Print version info. - -h,--help <command> Print help(about <command>). - -C,--color Print stuff with color, requires ANSI terminal. - [lib] What library to use. + -V,--version Print version info. + -h,--help <command> Print help(about <command>). + -C,--color Print stuff with color, requires ANSI terminal. + [lib] What library to use. - ecdh: | Perform EC based KeyAgreement. | + ecdh: | Perform EC based KeyAgreement. | -b,--bits <n> What size of curve to use. -nc,--named-curve <cat/id> Use a named curve, from CurveDB: <cat/id> @@ -343,17 +346,18 @@ usage: ECTesterStandalone.jar [-V] [-h <command>] [-C] [ -t,--type <type> Set KeyAgreement object [type]. --key-type <algorithm> Set the key [algorithm] for which the key should be derived in - KeyAgreements with KDF. Default is - "AES". + KeyAgreements with KDF. Default is "AES". -n,--amount <amount> Do ECDH [amount] times. - -npriv,--named-private <cat/id> Use a named private key, from - CurveDB: <cat/id> - --fixed-private Perform ECDH with fixed private key. -npub,--named-public <cat/id> Use a named public key, from CurveDB: <cat/id> + -pub,--public <pubkey> Use a given public key from file. + --fixed-private Perform ECDH with fixed private key. + -npriv,--named-private <cat/id> Use a named private key, from + CurveDB: <cat/id> + -priv,--private <privkey> Use a given private key from file. --fixed-public Perform ECDH with fixed public key. - ecdsa: | Perform EC based Signature. | + ecdsa: | Perform EC based Signature. | -b,--bits <n> What size of curve to use. -nc,--named-curve <cat/id> Use a named curve, from CurveDB: <cat/id> @@ -362,46 +366,50 @@ usage: ECTesterStandalone.jar [-V] [-h <command>] [-C] [ -o,--output <output_file> Output into file <output_file>. -npriv,--named-private <cat/id> Use a named private key, from CurveDB: <cat/id> + -priv,--private <privkey> Use a given private key from file. -npub,--named-public <cat/id> Use a named public key, from CurveDB: <cat/id> + -pub,--public <pubkey> Use a given public key from file. -t,--type <type> Set Signature object [type]. -n,--amount <amount> Do ECDSA [amount] times. -f,--file <file> Input [file] to sign. - export: | Export default curve parameters. | - -b,--bits <n> What size of curve to use. - -o,--output <output_file> Output into file <output_file>. - -t,--type <type> Set KeyPair object [type]. + export: | Export default curve parameters. | + -b,--bits <n> What size of curve to use. + -o,--output <output_file> Output into file <output_file>. + -t,--type <type> Set KeyPair object [type]. - generate: | Generate EC keypairs. | - -b,--bits <n> What size of curve to use. - -nc,--named-curve <cat/id> Use a named curve, from CurveDB: <cat/id> - -cn,--curve-name <name> Use a named curve, search from curves - supported by the library: <name> - -o,--output <output_file> Output into file <output_file>. - -n,--amount <amount> Generate [amount] of EC keys. - -t,--type <type> Set KeyPairGenerator object [type]. + generate: | Generate EC keypairs. | + -b,--bits <n> What size of curve to use. + -nc,--named-curve <cat/id> Use a named curve, from CurveDB: <cat/id> + -cn,--curve-name <name> Use a named curve, search from curves + supported by the library: <name> + -o,--output <output_file> Output into file <output_file>. + -n,--amount <amount> Generate [amount] of EC keys. + -t,--type <type> Set KeyPairGenerator object [type]. - list-data: | List/show contained EC domain parameters/keys. | + list-data: | List/show contained EC domain parameters/keys. | [what] what to list. - list-libs: | List supported libraries. | + list-libs: | List supported libraries. | + + list-suites: | List supported test suites. | - list-suites: | List supported test suites. | + list-types: | List KeyPairGenerator, KeyAgreement and Signature types. | - test: | Test a library. | - -b,--bits <n> What size of curve to use. - -nc,--named-curve <cat/id> Use a named curve, from CurveDB: <cat/id> - -cn,--curve-name <name> Use a named curve, search from curves - supported by the library: <name> - -gt,--kpg-type <type> Set the KeyPairGenerator object [type]. - -kt,--ka-type <type> Set the KeyAgreement object [type]. - -st,--sig-type <type> Set the Signature object [type]. - -f,--format <format> Set the output format, one of - text,yaml,xml. - --key-type <algorithm> Set the key [algorithm] for which the key - should be derived in KeyAgreements with - KDF. Default is "AES". - <test-suite> The test suite to run. + test: | Test a library. | + -b,--bits <n> What size of curve to use. + -nc,--named-curve <cat/id> Use a named curve, from CurveDB: <cat/id> + -cn,--curve-name <name> Use a named curve, search from curves + supported by the library: <name> + -gt,--kpg-type <type> Set the KeyPairGenerator object [type]. + -kt,--ka-type <type> Set the KeyAgreement object [type]. + -st,--sig-type <type> Set the Signature object [type]. + -f,--format <format> Set the output format, one of + text,yaml,xml. + --key-type <algorithm> Set the key [algorithm] for which the key + should be derived in KeyAgreements with + KDF. Default is "AES". + <test-suite> The test suite to run. ``` diff --git a/docs/LIBS.md b/docs/LIBS.md index ab6779f..0987656 100644 --- a/docs/LIBS.md +++ b/docs/LIBS.md @@ -5,6 +5,8 @@ Popular libraries with at least some ECC support, that ECTester does not yet sup - [NSS](https://hg.mozilla.org/projects/nss) - [LibreSSL](https://www.libressl.org/) - [Nettle](http://www.lysator.liu.se/~nisse/nettle/) + - [BearSSL](https://bearssl.org/) + - [cryptlib](https://www.cryptlib.com/) - [OpenSSL (FIPS mode)](https://www.openssl.org/docs/fipsnotes.html) - [Microsoft .NET crypto](https://docs.microsoft.com/en-us/dotnet/standard/security/cryptography-model) - [Linux kernel](https://kernel.org), test via [libkcapi](http://chronox.de/libkcapi.html) @@ -119,6 +121,11 @@ ninja - Uses comb method for short Weierstrass curves, using (randomized) Jacobian coordinates. - <http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2> - Uses Montgomery ladder with xz coordinates for Montgomery curves. + - [MatrixSSL](https://github.com/matrixssl/matrixssl) + - C + - Only supports prime field curves. + - Uses 4 bit sliding window. + - Uses projective coordinates. - [Intel Performance Primitives](https://software.intel.com/en-us/ipp-crypto-reference-2019) - C - Only supports prime field curves. diff --git a/src/cz/crcs/ectester/applet/AppletBase.java b/src/cz/crcs/ectester/applet/AppletBase.java index 4669352..dc0f50d 100644 --- a/src/cz/crcs/ectester/applet/AppletBase.java +++ b/src/cz/crcs/ectester/applet/AppletBase.java @@ -39,6 +39,8 @@ public abstract class AppletBase 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 BUILD_KEYPAIR = (byte) 0x00; + public static final byte BUILD_KEYBUILDER = (byte) 0x01; public static final byte EXPORT_TRUE = (byte) 0xff; public static final byte EXPORT_FALSE = (byte) 0x00; public static final byte MODE_NORMAL = (byte) 0xaa; @@ -352,17 +354,18 @@ public abstract class AppletBase extends Applet { * returns allocate SWs * * @param apdu P1 = byte keyPair (KEYPAIR_* | ...) - * P2 = + * P2 = byte build * DATA = short keyLength * byte keyClass * @return length of response */ private short insAllocate(APDU apdu) { byte keyPair = apduArray[ISO7816.OFFSET_P1]; + byte build = apduArray[ISO7816.OFFSET_P2]; short keyLength = Util.getShort(apduArray, cdata); byte keyClass = apduArray[(short) (cdata + 2)]; - return allocate(keyPair, keyLength, keyClass, apdu.getBuffer(), (short) 0); + return allocate(keyPair, build, keyLength, keyClass, apdu.getBuffer(), (short) 0); } /** @@ -657,22 +660,31 @@ public abstract class AppletBase extends Applet { /** * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) + * @param build whether to use KeyBuilder or Keypair alloc * @param keyLength key length to set * @param keyClass key class to allocate * @param outBuffer buffer to write sw to * @param outOffset offset into buffer * @return length of data written to the buffer */ - private short allocate(byte keyPair, short keyLength, byte keyClass, byte[] outBuffer, short outOffset) { + private short allocate(byte keyPair, byte build, short keyLength, byte keyClass, byte[] outBuffer, short outOffset) { short length = 0; if ((keyPair & KEYPAIR_LOCAL) != 0) { - localKeypair = keyGenerator.allocatePair(keyClass, keyLength); + if (build == BUILD_KEYPAIR) { + localKeypair = keyGenerator.allocatePair(keyClass, keyLength); + } else { + localKeypair = keyGenerator.constructPair(keyClass, keyLength); + } Util.setShort(outBuffer, outOffset, keyGenerator.getSW()); length += 2; } if ((keyPair & KEYPAIR_REMOTE) != 0) { - remoteKeypair = keyGenerator.allocatePair(keyClass, keyLength); + if (build == BUILD_KEYPAIR) { + remoteKeypair = keyGenerator.allocatePair(keyClass, keyLength); + } else { + remoteKeypair = keyGenerator.constructPair(keyClass, keyLength); + } Util.setShort(outBuffer, (short) (outOffset + length), keyGenerator.getSW()); length += 2; } diff --git a/src/cz/crcs/ectester/applet/ECKeyGenerator.java b/src/cz/crcs/ectester/applet/ECKeyGenerator.java index 30910ca..601654a 100644 --- a/src/cz/crcs/ectester/applet/ECKeyGenerator.java +++ b/src/cz/crcs/ectester/applet/ECKeyGenerator.java @@ -4,9 +4,7 @@ import javacard.framework.CardRuntimeException; import javacard.framework.ISO7816; import javacard.framework.ISOException; import javacard.framework.Util; -import javacard.security.ECPrivateKey; -import javacard.security.ECPublicKey; -import javacard.security.KeyPair; +import javacard.security.*; /** * @author Jan Jancar johny@neuromancer.sk @@ -42,6 +40,36 @@ public class ECKeyGenerator { } /** + * @param keyClass + * @param keyLength + * @return + */ + public KeyPair constructPair(byte keyClass, short keyLength) { + sw = ISO7816.SW_NO_ERROR; + KeyPair ecKeyPair = null; + byte privKeyType; + byte pubKeyType; + if (keyClass == KeyPair.ALG_EC_FP) { + privKeyType = KeyBuilder.TYPE_EC_FP_PRIVATE; + pubKeyType = KeyBuilder.TYPE_EC_FP_PUBLIC; + } else { + privKeyType = KeyBuilder.TYPE_EC_F2M_PRIVATE; + pubKeyType = KeyBuilder.TYPE_EC_F2M_PUBLIC; + } + try { + if (!dryRun) { + ECPrivateKey privateKey = (ECPrivateKey) KeyBuilder.buildKey(privKeyType, keyLength, false); + ECPublicKey publicKey = (ECPublicKey) KeyBuilder.buildKey(pubKeyType, keyLength, false); + + ecKeyPair = new KeyPair(publicKey, privateKey); + } + } catch (CardRuntimeException ce) { + sw = ce.getReason(); + } + return ecKeyPair; + } + + /** * @param keypair * @param key * @return diff --git a/src/cz/crcs/ectester/reader/ECTesterReader.java b/src/cz/crcs/ectester/reader/ECTesterReader.java index 6e34f6a..07bdb2f 100644 --- a/src/cz/crcs/ectester/reader/ECTesterReader.java +++ b/src/cz/crcs/ectester/reader/ECTesterReader.java @@ -327,6 +327,7 @@ public class ECTesterReader { opts.addOption(Option.builder("v").longOpt("verbose").desc("Turn on verbose logging.").build()); opts.addOption(Option.builder().longOpt("format").desc("Output format to use. One of: text,yml,xml.").hasArg().argName("format").build()); + opts.addOption(Option.builder("kb").longOpt("key-builder").desc("Allocate KeyPair using KeyBuilder.").build()); opts.addOption(Option.builder().longOpt("fixed").desc("Generate key(s) only once, keep them for later operations.").build()); opts.addOption(Option.builder().longOpt("fixed-private").desc("Generate private key only once, keep it for later ECDH.").build()); opts.addOption(Option.builder().longOpt("fixed-public").desc("Generate public key only once, keep it for later ECDH.").build()); @@ -394,7 +395,7 @@ public class ECTesterReader { byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; List<Response> sent = new LinkedList<>(); - sent.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send()); + sent.add(new Command.Allocate(cardManager, cfg.keyBuilder, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send()); //sent.add(new Command.Clear(cardManager, ECTesterApplet.KEYPAIR_LOCAL).send()); sent.add(new Command.Generate(cardManager, ECTesterApplet.KEYPAIR_LOCAL).send()); @@ -444,7 +445,7 @@ public class ECTesterReader { byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; Command curve = Command.prepareCurve(cardManager, cfg, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass); - Response allocate = new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send(); + Response allocate = new Command.Allocate(cardManager, cfg.keyBuilder, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send(); respWriter.outputResponse(allocate); OutputStreamWriter keysFile = FileUtil.openFiles(cfg.outputs); @@ -577,7 +578,7 @@ public class ECTesterReader { Command curve = Command.prepareCurve(cardManager, cfg, ECTesterApplet.KEYPAIR_BOTH, cfg.bits, keyClass); List<Response> prepare = new LinkedList<>(); prepare.add(new Command.AllocateKeyAgreement(cardManager, cfg.ECKAType).send()); // Prepare KeyAgreement or required type - prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_BOTH, cfg.bits, keyClass).send()); + prepare.add(new Command.Allocate(cardManager, cfg.keyBuilder, ECTesterApplet.KEYPAIR_BOTH, cfg.bits, keyClass).send()); if (curve != null) prepare.add(curve.send()); @@ -703,7 +704,7 @@ public class ECTesterReader { byte keyClass = cfg.primeField ? KeyPair.ALG_EC_FP : KeyPair.ALG_EC_F2M; List<Response> prepare = new LinkedList<>(); prepare.add(new Command.AllocateSignature(cardManager, cfg.ECDSAType).send()); - prepare.add(new Command.Allocate(cardManager, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send()); + prepare.add(new Command.Allocate(cardManager, cfg.keyBuilder, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass).send()); Command curve = Command.prepareCurve(cardManager, cfg, ECTesterApplet.KEYPAIR_LOCAL, cfg.bits, keyClass); if (curve != null) prepare.add(curve.send()); @@ -835,6 +836,7 @@ public class ECTesterReader { public boolean fixedKey = false; public boolean fixedPrivate = false; public boolean fixedPublic = false; + public byte keyBuilder; public String log; @@ -894,6 +896,7 @@ public class ECTesterReader { fixedKey = cli.hasOption("fixed"); fixedPrivate = cli.hasOption("fixed-private"); fixedPublic = cli.hasOption("fixed-public"); + keyBuilder = cli.hasOption("key-builder") ? ECTesterApplet.BUILD_KEYBUILDER : ECTesterApplet.BUILD_KEYPAIR; if (cli.hasOption("log")) { log = cli.getOptionValue("log", String.format("ECTESTER_log_%d.log", System.currentTimeMillis() / 1000)); diff --git a/src/cz/crcs/ectester/reader/command/Command.java b/src/cz/crcs/ectester/reader/command/Command.java index 1789451..cd015df 100644 --- a/src/cz/crcs/ectester/reader/command/Command.java +++ b/src/cz/crcs/ectester/reader/command/Command.java @@ -255,6 +255,7 @@ public abstract class Command implements Cloneable { */ public static class Allocate extends Command { private byte keyPair; + private byte build; private short keyLength; private byte keyClass; @@ -263,18 +264,24 @@ public abstract class Command implements Cloneable { * * @param cardManager cardManager to send APDU through * @param keyPair which keyPair to use, local/remote (KEYPAIR_* | ...) + * @param build whether to use KeyBuilder or Keypair alloc * @param keyLength key length to set * @param keyClass key class to allocate */ - public Allocate(CardMngr cardManager, byte keyPair, short keyLength, byte keyClass) { + public Allocate(CardMngr cardManager, byte keyPair, byte build, short keyLength, byte keyClass) { super(cardManager); this.keyPair = keyPair; + this.build = build; this.keyLength = keyLength; this.keyClass = keyClass; byte[] data = new byte[]{0, 0, keyClass}; ByteUtil.setShort(data, 0, keyLength); - this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, 0x00, data); + this.cmd = new CommandAPDU(ECTesterApplet.CLA_ECTESTERAPPLET, ECTesterApplet.INS_ALLOCATE, keyPair, build, data); + } + + public Allocate(CardMngr cardManager, byte keyPair, short keyLength, byte keyClass) { + this(cardManager, keyPair, ECTesterApplet.BUILD_KEYPAIR, keyLength, keyClass); } @Override diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_timing.c b/src/cz/crcs/ectester/standalone/libs/jni/c_timing.c index a6ffc7e..941cee6 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/c_timing.c +++ b/src/cz/crcs/ectester/standalone/libs/jni/c_timing.c @@ -1,5 +1,9 @@ #include "c_timing.h" +#if __linux || __posix +#include<unistd.h> +#endif + #if _POSIX_TIMERS > 0 #include <time.h> diff --git a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c index a5bc14d..46286fd 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c +++ b/src/cz/crcs/ectester/standalone/libs/jni/c_utils.c @@ -3,6 +3,10 @@ #include <string.h> #include <stdlib.h> +#if defined(__WIN32__) || defined(_MSC_VER) +#include <windows.h> +#endif + jclass ec_parameter_spec_class; jclass ecgen_parameter_spec_class; jclass secret_key_spec_class; @@ -228,7 +232,11 @@ char *biginteger_to_hex(JNIEnv *env, jobject big, jint bytes) { jstring big_string = (*env)->CallObjectMethod(env, big, to_string, (jint) 16); jsize len = (*env)->GetStringUTFLength(env, big_string); +#if defined(__WIN32__) || defined(_MSC_VER) + char *raw_string = _alloca(len); +#else char raw_string[len]; +#endif (*env)->GetStringUTFRegion(env, big_string, 0, len, raw_string); char *result = calloc(bytes, 2); diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c index 2b38860..7f3ff5d 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/mscng.c +++ b/src/cz/crcs/ectester/standalone/libs/jni/mscng.c @@ -1,12 +1,10 @@ -#include <bcrypt.h>
#include <windows.h>
+#include <bcrypt.h>
#include "native.h"
#include "c_timing.h"
#include "c_utils.h"
-#include <stdio.h>
-
// BCRYPT and NT things.
#define NT_SUCCESS(status) (((NTSTATUS)(status)) >= 0)
#define NT_FAILURE(status) !NT_SUCCESS(status)
@@ -17,8 +15,7 @@ typedef struct {
ULONG dwVersion; // Version of the structure
ECC_CURVE_TYPE_ENUM dwCurveType; // Supported curve types.
- ECC_CURVE_ALG_ID_ENUM
- dwCurveGenerationAlgId; // For X.592 verification purposes, if we include Seed we will need to include the algorithm ID.
+ ECC_CURVE_ALG_ID_ENUM dwCurveGenerationAlgId; // For X.592 verification purposes, if we include Seed we will need to include the algorithm ID.
ULONG cbFieldLength; // Byte length of the fields P, A, B, X, Y.
ULONG cbSubgroupOrder; // Byte length of the subgroup.
ULONG cbCofactor; // Byte length of cofactor of G in E.
@@ -1203,6 +1200,12 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna return JNI_FALSE;
}
(*env)->ReleaseByteArrayElements(env, pubkey_barray, pub_data, JNI_ABORT);
+
+ jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;");
+ jobject n = (*env)->CallObjectMethod(env, params, get_n);
+ jmethodID get_bitlength = (*env)->GetMethodID(env, biginteger_class, "bitLength", "()I");
+ jint ord_bits = (*env)->CallIntMethod(env, n, get_bitlength);
+ jint ord_bytes = (ord_bits + 7) / 8;
jint sig_len = (*env)->GetArrayLength(env, sig);
jbyte *sig_data = (*env)->GetByteArrayElements(env, sig, NULL);
@@ -1224,20 +1227,24 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna jbyte *r_cpy = r;
jbyte *s_cpy = s;
- if (rlen > slen) {
- r_cpy += rlen - slen;
- rlen = slen;
- } else if (slen > rlen) {
- s_cpy += slen - rlen;
- slen = rlen;
- } else {
- if (r[0] == 0 && s[0] == 0) {
- r_cpy++;
- s_cpy++;
- rlen--;
- slen--;
- }
- }
+ if (rlen > ord_bytes) {
+ r_cpy += ord_bytes - rlen;
+ }
+ if (slen > ord_bytes) {
+ s_cpy += ord_bytes - slen;
+ }
+ if (rlen < ord_bytes) {
+ r_cpy = _alloca(ord_bytes);
+ memset(r_cpy, 0, ord_bytes);
+ memcpy(r_cpy, r + (ord_bytes - rlen), ord_bytes);
+ }
+ if (slen < ord_bytes) {
+ s_cpy = _alloca(ord_bytes);
+ memset(s_cpy, 0, ord_bytes);
+ memcpy(s_cpy, s + (ord_bytes - slen), ord_bytes);
+ }
+ rlen = ord_bytes;
+ slen = ord_bytes;
UCHAR *sig_full = calloc(rlen + slen, 1);
memcpy(sig_full, r_cpy, rlen);
diff --git a/util/utils.py b/util/utils.py index 670e7c2..1c620ef 100644 --- a/util/utils.py +++ b/util/utils.py @@ -69,3 +69,21 @@ def plot_hist(axes, data, xlabel=None, log=False, avg=True, median=True, bins=No def miller_correction(entropy, samples, bins): return entropy + (bins - 1)/(2*samples) + + +def egcd(a, b): + if a == 0: + return b, 0, 1 + else: + g, y, x = egcd(b % a, a) + return g, x - (b // a) * y, y + + +def mod_inv(a, p): + if a < 0: + return p - mod_inv(-a, p) + g, x, y = egcd(a, p) + if g != 1: + raise ArithmeticError("Modular inverse does not exist") + else: + return x % p |
