aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJ08nY2019-07-10 00:49:18 +0200
committerJ08nY2019-07-10 00:49:18 +0200
commit2859e855725b9035e1d95bba8d70777fd4da19cb (patch)
tree78cef50276dc34dcf217a6b804966bacf3a818b9
parent19d09ebf00af0a09506ce3e7534bb658a8e999b9 (diff)
parent4969f63467fc92d55b8cb2448768ef43c6f74f02 (diff)
downloadECTester-2859e855725b9035e1d95bba8d70777fd4da19cb.tar.gz
ECTester-2859e855725b9035e1d95bba8d70777fd4da19cb.tar.zst
ECTester-2859e855725b9035e1d95bba8d70777fd4da19cb.zip
-rw-r--r--.editorconfig5
-rw-r--r--build-standalone.xml7
-rw-r--r--src/cz/crcs/ectester/standalone/ECTesterStandalone.java3
-rw-r--r--src/cz/crcs/ectester/standalone/libs/IppcpLib.java30
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/.clang-format90
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/Makefile11
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java6
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java6
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java20
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java19
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java10
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java21
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/ippcp.c707
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/mbedtls.c13
-rw-r--r--src/cz/crcs/ectester/standalone/libs/jni/native.h205
15 files changed, 1138 insertions, 15 deletions
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..7291f3e
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,5 @@
+root = true
+
+[*.{c,h}]
+indent_style = tab
+tab_width = 4 \ No newline at end of file
diff --git a/build-standalone.xml b/build-standalone.xml
index de01275..a686b11 100644
--- a/build-standalone.xml
+++ b/build-standalone.xml
@@ -189,6 +189,13 @@
<class name="cz.crcs.ectester.standalone.libs.jni.NativeECPrivateKey$MbedTLS"/>
<class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyAgreementSpi$MbedTLS"/>
<class name="cz.crcs.ectester.standalone.libs.jni.NativeSignatureSpi$MbedTLS"/>
+ <class name="cz.crcs.ectester.standalone.libs.IppcpLib"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeProvider$Ippcp"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyPairGeneratorSpi$Ippcp"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeECPublicKey$Ippcp"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeECPrivateKey$Ippcp"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyAgreementSpi$Ippcp"/>
+ <class name="cz.crcs.ectester.standalone.libs.jni.NativeSignatureSpi$Ippcp"/>
</javah>
</target>
</project>
diff --git a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
index 8e88461..489eb40 100644
--- a/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
+++ b/src/cz/crcs/ectester/standalone/ECTesterStandalone.java
@@ -79,7 +79,8 @@ public class ECTesterStandalone {
new GcryptLib(),
new MscngLib(),
new WolfCryptLib(),
- new MbedTLSLib()};
+ new MbedTLSLib(),
+ new IppcpLib()};
private Config cfg;
private Options opts = new Options();
diff --git a/src/cz/crcs/ectester/standalone/libs/IppcpLib.java b/src/cz/crcs/ectester/standalone/libs/IppcpLib.java
new file mode 100644
index 0000000..3c03737
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/IppcpLib.java
@@ -0,0 +1,30 @@
+package cz.crcs.ectester.standalone.libs;
+
+import java.security.Provider;
+import java.util.Set;
+
+/**
+ * @author Jan Jancar johny@neuromancer.sk
+ */
+public class IppcpLib extends NativeECLibrary {
+
+ public IppcpLib() {
+ super("ippcp_provider", "ippcp");
+ }
+
+ @Override
+ public native boolean supportsNativeTiming();
+
+ @Override
+ public native long getNativeTimingResolution();
+
+ @Override
+ public native long getLastNativeTiming();
+
+
+ @Override
+ native Provider createProvider();
+
+ @Override
+ public native Set<String> getCurves();
+}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/.clang-format b/src/cz/crcs/ectester/standalone/libs/jni/.clang-format
new file mode 100644
index 0000000..0aa8562
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/jni/.clang-format
@@ -0,0 +1,90 @@
+---
+Language: Cpp
+# BasedOnStyle: Google
+AccessModifierOffset: -1
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlinesLeft: true
+AlignOperands: true
+AlignTrailingComments: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: false
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: true
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: true
+BinPackArguments: true
+BinPackParameters: true
+BraceWrapping:
+ AfterClass: false
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: false
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: false
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+BreakBeforeBinaryOperators: None
+BreakBeforeBraces: Attach
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializersBeforeComma: false
+ColumnLimit: 140
+CommentPragmas: '^ IWYU pragma:'
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: true
+DisableFormat: false
+ExperimentalAutoDetectBinPacking: false
+ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
+IncludeCategories:
+ - Regex: '^<.*\.h>'
+ Priority: 1
+ - Regex: '^<.*'
+ Priority: 2
+ - Regex: '.*'
+ Priority: 3
+IndentCaseLabels: true
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+KeepEmptyLinesAtTheStartOfBlocks: false
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBlockIndentWidth: 2
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: false
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakString: 1000
+PenaltyExcessCharacter: 10000
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Left
+ReflowComments: true
+SortIncludes: true
+SpaceAfterCStyleCast: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: false
+SpacesInContainerLiterals: true
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+SpacesInSquareBrackets: false
+Standard: Auto
+TabWidth: 4
+UseTab: ForIndentation
+...
+
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile b/src/cz/crcs/ectester/standalone/libs/jni/Makefile
index 8b4754b..8ae8dd4 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile
+++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile
@@ -58,7 +58,7 @@ JNI_PLATFORMINCLUDEDIR ?= $(JNI_INCLUDEDIR)/$(JNI_PLATFORM)
###############################################################################
## Targets.
-all: tomcrypt_provider.so botan_provider.so cryptopp_provider.so openssl_provider.so boringssl_provider.so gcrypt_provider.so mbedtls_provider.so
+all: tomcrypt_provider.so botan_provider.so cryptopp_provider.so openssl_provider.so boringssl_provider.so gcrypt_provider.so mbedtls_provider.so ippcp_provider.so
# Common utils
c_utils.o: c_utils.c
@@ -127,6 +127,14 @@ mbedtls_provider.so: mbedtls.o c_utils.o c_timing.o
mbedtls.o: mbedtls.c
$(CC) $(CFLAGS) -c $<
+
+# Intel Performance Primitives crypto shim
+ippcp_provider.so: ippcp.o c_utils.o c_timing.o
+ $(CC) $(LFLAGS) -o $@ $^ -L. -lippcp
+
+ippcp.o: ippcp.c
+ $(CC) $(CFLAGS) -c $<
+
help:
@echo "# This makefile builds the JNI shims necessary to test native libraries."
@echo "# Targets:"
@@ -137,6 +145,7 @@ help:
@echo " - botan_provider.so"
@echo " - cryptopp_provider.so"
@echo " - mbedtls_provider.so"
+ @echo " - ippcp_provider.so"
clean:
rm -rf *.o
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
index 96f19b8..9a22c0b 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPrivateKey.java
@@ -103,6 +103,12 @@ public abstract class NativeECPrivateKey implements ECPrivateKey {
}
}
+ public static class Ippcp extends Raw {
+ public Ippcp(byte[] keyData, ECParameterSpec params) {
+ super(keyData, params);
+ }
+ }
+
public static class Mscng extends Raw {
// 0 -> implicit (meta = curveName UTF16, header = full);
// 1 -> explicit (meta = null, header = full);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
index 9e29a59..8523be4 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeECPublicKey.java
@@ -104,6 +104,12 @@ public abstract class NativeECPublicKey implements ECPublicKey {
}
}
+ public static class Ippcp extends ANSIX962 {
+ public Ippcp(byte[] keyData, ECParameterSpec params) {
+ super(keyData, params);
+ }
+ }
+
public static class Mscng extends ANSIX962 {
// 0 -> implicit (meta = curveName UTF16, header = full);
// 1 -> explicit (meta = null, header = full);
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
index b098792..662f32c 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java
@@ -333,4 +333,24 @@ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi {
}
}
+ public abstract static class Ippcp extends SimpleKeyAgreementSpi {
+ private String type;
+
+ public Ippcp(String type) {
+ this.type = type;
+ }
+
+ @Override
+ native byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params);
+
+ @Override
+ native SecretKey generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params, String algorithm);
+ }
+
+ public static class IppcpECDH extends Ippcp {
+ public IppcpECDH() {
+ super("ECDH");
+ }
+ }
+
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
index a3552cf..98e6d10 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyPairGeneratorSpi.java
@@ -268,4 +268,23 @@ public abstract class NativeKeyPairGeneratorSpi extends KeyPairGeneratorSpi {
@Override
native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random);
}
+
+ public static class Ippcp extends NativeKeyPairGeneratorSpi {
+
+ public Ippcp() {
+ initialize(256, new SecureRandom());
+ }
+
+ @Override
+ native boolean keysizeSupported(int keysize);
+
+ @Override
+ native boolean paramsSupported(AlgorithmParameterSpec params);
+
+ @Override
+ native KeyPair generate(int keysize, SecureRandom random);
+
+ @Override
+ native KeyPair generate(AlgorithmParameterSpec params, SecureRandom random);
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
index 7527463..f3e2937 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeProvider.java
@@ -103,4 +103,14 @@ public abstract class NativeProvider extends Provider {
@Override
native void setup();
}
+
+ public static class Ippcp extends NativeProvider {
+
+ public Ippcp(String name, double version, String info) {
+ super(name, version, info);
+ }
+
+ @Override
+ native void setup();
+ }
}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
index 37e87bc..4db636e 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
+++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeSignatureSpi.java
@@ -461,6 +461,27 @@ public abstract class NativeSignatureSpi extends SignatureSpi {
}
}
+ public abstract static class Ippcp extends SimpleSignatureSpi {
+ private String type;
+
+ public Ippcp(String type) {
+ this.type = type;
+ }
+
+ @Override
+ native byte[] sign(byte[] data, byte[] privkey, ECParameterSpec params);
+
+ @Override
+ native boolean verify(byte[] signature, byte[] data, byte[] pubkey, ECParameterSpec params);
+ }
+
+ public static class IppcpECDSAwithNONE extends Ippcp {
+
+ public IppcpECDSAwithNONE() {
+ super("NONEwithECDSA");
+ }
+ }
+
public abstract static class Mscng extends ExtendedSignatureSpi {
private String type;
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/ippcp.c b/src/cz/crcs/ectester/standalone/libs/jni/ippcp.c
new file mode 100644
index 0000000..2c5a747
--- /dev/null
+++ b/src/cz/crcs/ectester/standalone/libs/jni/ippcp.c
@@ -0,0 +1,707 @@
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include "native.h"
+
+#include <ippcp.h>
+
+#include "c_timing.h"
+#include "c_utils.h"
+
+#define _POSIX_C_SOURCE 200809L
+
+#include <stdio.h>
+#include <time.h>
+
+#define USE_SPEEDUP 1
+#define VALIDATE_CURVE 1
+#define VALIDATE_POINT 1
+
+static IppsPRNGState *prng_state;
+static jclass provider_class;
+
+/* This needs to be specified in this way because ippcp does not offer functionality to retrieve
+ information about supported curves in any way. */
+typedef struct {
+ const char name[128];
+ IppECCType id;
+ int size;
+ IppStatus (*context_size_func)(int *);
+ IppStatus (*init_func)(IppsECCPState *);
+ IppStatus (*set_func)(IppsECCPState *);
+ IppStatus (*precomp_func)(IppsECCPState *);
+} ippcp_curve;
+
+static const ippcp_curve CURVES[] = {
+ {"secp112r1", IppECCPStd112r1, 112, NULL, NULL, NULL, NULL},
+ {"secp112r2", IppECCPStd112r2, 112, NULL, NULL, NULL, NULL},
+ {"secp128r1", IppECCPStd128r1, 128, ippsECCPGetSizeStd128r1, ippsECCPInitStd128r1, ippsECCPSetStd128r1, NULL},
+ {"secp128r2", IppECCPStd128r2, 128, ippsECCPGetSizeStd128r2, ippsECCPInitStd128r2, ippsECCPSetStd128r2, NULL},
+ {"secp160r1", IppECCPStd160r1, 160, NULL, NULL, NULL, NULL},
+ {"secp160r2", IppECCPStd160r2, 160, NULL, NULL, NULL, NULL},
+ {"secp192r1", IppECCPStd192r1, 192, ippsECCPGetSizeStd192r1, ippsECCPInitStd192r1, ippsECCPSetStd192r1, ippsECCPBindGxyTblStd192r1},
+ {"secp224r1", IppECCPStd224r1, 224, ippsECCPGetSizeStd224r1, ippsECCPInitStd224r1, ippsECCPSetStd224r1, ippsECCPBindGxyTblStd224r1},
+ {"secp256r1", IppECCPStd256r1, 256, ippsECCPGetSizeStd256r1, ippsECCPInitStd256r1, ippsECCPSetStd256r1, ippsECCPBindGxyTblStd256r1},
+ {"secp384r1", IppECCPStd384r1, 384, ippsECCPGetSizeStd384r1, ippsECCPInitStd384r1, ippsECCPSetStd384r1, ippsECCPBindGxyTblStd384r1},
+ {"secp521r1", IppECCPStd521r1, 521, ippsECCPGetSizeStd521r1, ippsECCPInitStd521r1, ippsECCPSetStd521r1, ippsECCPBindGxyTblStd521r1}};
+
+static const int NUM_CURVES = sizeof(CURVES) / sizeof(ippcp_curve);
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_createProvider(JNIEnv *env, jobject this) {
+ /* Create the custom provider. */
+ jclass local_provider_class = (*env)->FindClass(env, "cz/crcs/ectester/standalone/libs/jni/NativeProvider$Ippcp");
+ provider_class = (*env)->NewGlobalRef(env, local_provider_class);
+
+ jmethodID init = (*env)->GetMethodID(env, local_provider_class, "<init>", "(Ljava/lang/String;DLjava/lang/String;)V");
+
+ const IppLibraryVersion *lib = ippcpGetLibVersion();
+ jstring name = (*env)->NewStringUTF(env, lib->Name);
+ double version = (double)lib->major + ((double)lib->minor / 10);
+ jstring info = (*env)->NewStringUTF(env, lib->Version);
+
+ // printf("%s\n%s\n%d.%d.%d.%d\n", lib->Name, lib->Version, lib->major, lib->minor, lib->majorBuild, lib->build);
+
+ return (*env)->NewObject(env, provider_class, init, name, version, info);
+}
+
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Ippcp_setup(JNIEnv *env, jobject this) {
+ INIT_PROVIDER(env, provider_class);
+
+ ADD_KPG(env, this, "EC", "Ippcp");
+ ADD_KA(env, this, "ECDH", "IppcpECDH");
+ ADD_SIG(env, this, "NONEwithECDSA", "IppcpECDSAwithNONE");
+
+ /* Init the PRNG. */
+ int prng_size;
+ ippsPRNGGetSize(&prng_size);
+ prng_state = malloc(prng_size);
+ ippsPRNGInit(160, prng_state);
+ /* We need to manually seed the PRNG, let's hope that everyone using ippcp does this.
+ Otherwise: nonce reuse in ECDSA, whoops! */
+ int seed_len = 8;
+ Ipp32u seed[seed_len];
+ IppStatus res = ippsTRNGenRDSEED(seed, sizeof(seed) * 8, NULL);
+ if (res != ippStsNoErr) {
+ res = ippsPRNGenRDRAND(seed, sizeof(seed) * 8, NULL);
+ }
+ if (res != ippStsNoErr) {
+ FILE *urandom = fopen("/dev/urandom", "rb");
+ if (urandom) {
+ size_t read = 0;
+ while (read < sizeof(seed)) {
+ read += fread(((uint8_t *)&seed) + read, 1, sizeof(seed) - read, urandom);
+ }
+ fclose(urandom);
+ res = ippStsNoErr;
+ }
+ }
+ if (res != ippStsNoErr) {
+ struct timespec t;
+ if (!clock_gettime(CLOCK_REALTIME, &t)) {
+ memcpy(seed, &t.tv_nsec, sizeof(t.tv_nsec) > sizeof(seed) ? sizeof(seed) : sizeof(t.tv_nsec));
+ } else {
+ time_t tim = time(NULL);
+ memcpy(seed, &tim, sizeof(time_t) > sizeof(seed) ? sizeof(seed) : sizeof(time_t));
+ }
+ }
+ int bn_size;
+ ippsBigNumGetSize(seed_len, &bn_size);
+ uint8_t bn_buf[bn_size];
+ IppsBigNumState *bn = (IppsBigNumState *)bn_buf;
+ ippsBigNumInit(seed_len, bn);
+ ippsSet_BN(IppsBigNumPOS, seed_len, seed, bn);
+ ippsPRNGSetSeed(bn, prng_state);
+
+ init_classes(env, "Ippcp");
+}
+
+static IppStatus prng_wrapper(Ipp32u *pRand, int nBits, void *pCtx) {
+ native_timing_pause();
+ IppStatus result = ippsPRNGen(pRand, nBits, pCtx);
+ native_timing_restart();
+ return result;
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_getCurves(JNIEnv *env, jobject this) {
+ jclass hash_set_class = (*env)->FindClass(env, "java/util/TreeSet");
+
+ jmethodID hash_set_ctr = (*env)->GetMethodID(env, hash_set_class, "<init>", "()V");
+ jmethodID hash_set_add = (*env)->GetMethodID(env, hash_set_class, "add", "(Ljava/lang/Object;)Z");
+
+ jobject result = (*env)->NewObject(env, hash_set_class, hash_set_ctr);
+
+ for (size_t i = 0; i < NUM_CURVES; ++i) {
+ jstring curve_name = (*env)->NewStringUTF(env, CURVES[i].name);
+ (*env)->CallBooleanMethod(env, result, hash_set_add, curve_name);
+ }
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Ippcp_keysizeSupported(JNIEnv *env,
+ jobject this,
+ jint keysize) {
+ for (size_t i = 0; i < NUM_CURVES; ++i) {
+ if (CURVES[i].size == keysize) {
+ return JNI_TRUE;
+ }
+ }
+ return JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Ippcp_paramsSupported(JNIEnv *env,
+ jobject this,
+ jobject params) {
+ if (params == NULL) {
+ return JNI_FALSE;
+ }
+
+ if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
+ jobject curve = (*env)->CallObjectMethod(env, params, get_curve);
+
+ jmethodID get_field = (*env)->GetMethodID(env, elliptic_curve_class, "getField", "()Ljava/security/spec/ECField;");
+ jobject field = (*env)->CallObjectMethod(env, curve, get_field);
+ if ((*env)->IsInstanceOf(env, field, f2m_field_class)) {
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+ } else if ((*env)->IsInstanceOf(env, params, ecgen_parameter_spec_class)) {
+ jmethodID get_name = (*env)->GetMethodID(env, ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;");
+ jstring name = (*env)->CallObjectMethod(env, params, get_name);
+ const char *utf_name = (*env)->GetStringUTFChars(env, name, NULL);
+ for (size_t i = 0; i < NUM_CURVES; ++i) {
+ if (strcasecmp(utf_name, CURVES[i].name) == 0) {
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+ return JNI_TRUE;
+ }
+ }
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+ return JNI_FALSE;
+ } else {
+ return JNI_FALSE;
+ }
+}
+
+
+static IppsECCPPointState *new_point(int size) {
+ int point_size;
+ ippsECCPPointGetSize(size, &point_size);
+ IppsECCPPointState *point = malloc(point_size);
+ ippsECCPPointInit(size, point);
+ return point;
+}
+
+static IppsBigNumState *new_bn(int bits) {
+ int bn_size;
+ int len = ((bits + 7) / 8) / sizeof(Ipp32u);
+ ippsBigNumGetSize(len, &bn_size);
+ IppsBigNumState *bn = malloc(bn_size);
+ ippsBigNumInit(len, bn);
+ return bn;
+}
+
+static void bn_get(IppsBigNumState *bn, uint8_t *buf, int lsb) {
+ int size;
+ ippsGetSize_BN(bn, &size);
+ size *= sizeof(Ipp32u);
+ uint8_t data[size];
+ ippsGetOctString_BN(data, size, bn);
+ memcpy(buf, data + (size - lsb), lsb);
+}
+
+static jobject bn_to_biginteger(JNIEnv *env, const IppsBigNumState *bn) {
+ jmethodID biginteger_init = (*env)->GetMethodID(env, biginteger_class, "<init>", "(I[B)V");
+ int bn_size;
+ ippsGetSize_BN(bn, &bn_size);
+ bn_size *= sizeof(Ipp32u);
+ jbyteArray bytes = (*env)->NewByteArray(env, bn_size);
+ jbyte *data = (*env)->GetByteArrayElements(env, bytes, NULL);
+ ippsGetOctString_BN(data, bn_size, bn);
+ (*env)->ReleaseByteArrayElements(env, bytes, data, 0);
+ jobject result = (*env)->NewObject(env, biginteger_class, biginteger_init, 1, bytes);
+ return result;
+}
+
+static IppsBigNumState *biginteger_to_bn(JNIEnv *env, jobject bigint) {
+ jmethodID to_byte_array = (*env)->GetMethodID(env, biginteger_class, "toByteArray", "()[B");
+
+ jbyteArray byte_array = (jbyteArray) (*env)->CallObjectMethod(env, bigint, to_byte_array);
+ jsize byte_length = (*env)->GetArrayLength(env, byte_array);
+ jbyte *byte_data = (*env)->GetByteArrayElements(env, byte_array, NULL);
+ IppsBigNumState *result = new_bn(byte_length * 8);
+ ippsSetOctString_BN(byte_data, byte_length, result);
+ (*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT);
+ return result;
+}
+
+static void biginteger_print(JNIEnv *env, jobject bigint) {
+ jmethodID to_string = (*env)->GetMethodID(env, biginteger_class, "toString", "(I)Ljava/lang/String;");
+ jstring big_string = (*env)->CallObjectMethod(env, bigint, to_string, (jint) 16);
+
+ jsize len = (*env)->GetStringUTFLength(env, big_string);
+ char raw_string[len + 1];
+ raw_string[len] = 0;
+ (*env)->GetStringUTFRegion(env, big_string, 0, len, raw_string);
+ printf("%s\n", raw_string);
+ fflush(stdout);
+}
+
+static IppsECCPState *create_curve(JNIEnv *env, jobject params, int *keysize) {
+ jmethodID get_curve = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCurve", "()Ljava/security/spec/EllipticCurve;");
+ jobject curve = (*env)->CallObjectMethod(env, params, get_curve);
+
+ jmethodID get_field = (*env)->GetMethodID(env, elliptic_curve_class, "getField", "()Ljava/security/spec/ECField;");
+ jobject field = (*env)->CallObjectMethod(env, curve, get_field);
+
+ jmethodID get_p = (*env)->GetMethodID(env, fp_field_class, "getP", "()Ljava/math/BigInteger;");
+ jobject p = (*env)->CallObjectMethod(env, field, get_p);
+ IppsBigNumState *p_bn = biginteger_to_bn(env, p);
+
+ jmethodID get_a = (*env)->GetMethodID(env, elliptic_curve_class, "getA", "()Ljava/math/BigInteger;");
+ jobject a = (*env)->CallObjectMethod(env, curve, get_a);
+ IppsBigNumState *a_bn = biginteger_to_bn(env, a);
+
+ jmethodID get_b = (*env)->GetMethodID(env, elliptic_curve_class, "getB", "()Ljava/math/BigInteger;");
+ jobject b = (*env)->CallObjectMethod(env, curve, get_b);
+ IppsBigNumState *b_bn = biginteger_to_bn(env, b);
+
+ jmethodID get_g = (*env)->GetMethodID(env, ec_parameter_spec_class, "getGenerator", "()Ljava/security/spec/ECPoint;");
+ jobject g = (*env)->CallObjectMethod(env, params, get_g);
+
+ jmethodID get_x = (*env)->GetMethodID(env, point_class, "getAffineX", "()Ljava/math/BigInteger;");
+ jobject gx = (*env)->CallObjectMethod(env, g, get_x);
+ IppsBigNumState *gx_bn = biginteger_to_bn(env, gx);
+
+ jmethodID get_y = (*env)->GetMethodID(env, point_class, "getAffineY", "()Ljava/math/BigInteger;");
+ jobject gy = (*env)->CallObjectMethod(env, g, get_y);
+ IppsBigNumState *gy_bn = biginteger_to_bn(env, gy);
+
+ jmethodID get_n = (*env)->GetMethodID(env, ec_parameter_spec_class, "getOrder", "()Ljava/math/BigInteger;");
+ jobject n = (*env)->CallObjectMethod(env, params, get_n);
+ IppsBigNumState *n_bn = biginteger_to_bn(env, n);
+
+ jmethodID get_h = (*env)->GetMethodID(env, ec_parameter_spec_class, "getCofactor", "()I");
+ jint h = (*env)->CallIntMethod(env, params, get_h);
+
+ jmethodID get_bitlength = (*env)->GetMethodID(env, biginteger_class, "bitLength", "()I");
+ jint prime_bits = (*env)->CallIntMethod(env, p, get_bitlength);
+ if (keysize) {
+ *keysize = prime_bits;
+ }
+
+ int size;
+ ippsECCPGetSize(prime_bits, &size);
+ IppsECCPState *result = malloc(size);
+ ippsECCPInit(prime_bits, result);
+ ippsECCPSet(p_bn, a_bn, b_bn, gx_bn, gy_bn, n_bn, h, result);
+
+ return result;
+}
+
+static jobject create_ec_param_spec(JNIEnv *env, int keysize, IppsECCPState *curve) {
+ IppsBigNumState *p_bn = new_bn(keysize);
+ IppsBigNumState *a_bn = new_bn(keysize);
+ IppsBigNumState *b_bn = new_bn(keysize);
+ int ord_bits;
+ ippsECCPGetOrderBitSize(&ord_bits, curve);
+ IppsBigNumState *gx_bn = new_bn(ord_bits);
+ IppsBigNumState *gy_bn = new_bn(ord_bits);
+ IppsBigNumState *order_bn = new_bn(ord_bits);
+ int cofactor;
+
+ IppStatus err = ippsECCPGet(p_bn, a_bn, b_bn, gx_bn, gy_bn, order_bn, &cofactor, curve);
+
+ jobject p = bn_to_biginteger(env, p_bn);
+ jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "<init>", "(Ljava/math/BigInteger;)V");
+ jobject field = (*env)->NewObject(env, fp_field_class, fp_field_init, p);
+ free(p_bn);
+
+ jobject a = bn_to_biginteger(env, a_bn);
+ jobject b = bn_to_biginteger(env, b_bn);
+ free(a_bn);
+ free(b_bn);
+
+ jmethodID elliptic_curve_init = (*env)->GetMethodID(env, elliptic_curve_class, "<init>", "(Ljava/security/spec/ECField;Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
+ jobject elliptic_curve = (*env)->NewObject(env, elliptic_curve_class, elliptic_curve_init, field, a, b);
+
+ jobject gx = bn_to_biginteger(env, gx_bn);
+ jobject gy = bn_to_biginteger(env, gy_bn);
+ jmethodID point_init = (*env)->GetMethodID(env, point_class, "<init>", "(Ljava/math/BigInteger;Ljava/math/BigInteger;)V");
+ jobject g = (*env)->NewObject(env, point_class, point_init, gx, gy);
+ free(gx_bn);
+ free(gy_bn);
+
+ jobject n = bn_to_biginteger(env, order_bn);
+ free(order_bn);
+
+ jmethodID ec_parameter_spec_init = (*env)->GetMethodID(env, ec_parameter_spec_class, "<init>", "(Ljava/security/spec/EllipticCurve;Ljava/security/spec/ECPoint;Ljava/math/BigInteger;I)V");
+ return (*env)->NewObject(env, ec_parameter_spec_class, ec_parameter_spec_init, elliptic_curve, g, n, cofactor);
+}
+
+static jobject generate_from_curve(JNIEnv *env, int keysize, IppsECCPState *curve) {
+ if (VALIDATE_CURVE) {
+ IppECResult validation;
+ ippsECCPValidate(50, &validation, curve, ippsPRNGen, prng_state);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ return NULL;
+ }
+ }
+
+ IppsECCPPointState *point = new_point(keysize);
+
+ int ord_bits;
+ ippsECCPGetOrderBitSize(&ord_bits, curve);
+ int ord_bytes = (ord_bits + 7) / 8;
+ IppsBigNumState *secret = new_bn(ord_bits);
+
+ native_timing_start();
+ IppStatus err = ippsECCPGenKeyPair(secret, point, curve, prng_wrapper, prng_state);
+ native_timing_stop();
+
+ if (err != ippStsNoErr) {
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ free(point);
+ free(secret);
+ return NULL;
+ }
+
+ int coord_bytes = (keysize + 7) / 8;
+ IppsBigNumState *x = new_bn(keysize);
+ IppsBigNumState *y = new_bn(keysize);
+
+ ippsECCPGetPoint(x, y, point, curve);
+
+ jbyteArray pub_bytes = (*env)->NewByteArray(env, 2 * coord_bytes + 1);
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pub_bytes, NULL);
+ pub_data[0] = 0x04;
+ bn_get(x, pub_data + 1, coord_bytes);
+ bn_get(y, pub_data + 1 + coord_bytes, coord_bytes);
+ (*env)->ReleaseByteArrayElements(env, pub_bytes, pub_data, 0);
+
+ jbyteArray priv_bytes = (*env)->NewByteArray(env, ord_bytes);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, priv_bytes, NULL);
+ bn_get(secret, priv_data, ord_bytes);
+ (*env)->ReleaseByteArrayElements(env, priv_bytes, priv_data, 0);
+
+ free(point);
+ free(secret);
+ free(x);
+ free(y);
+
+ jobject ec_param_spec = create_ec_param_spec(env, keysize, curve);
+
+ jobject ec_pub_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
+ jmethodID ec_pub_init = (*env)->GetMethodID(env, pubkey_class, "<init>", "([BLjava/security/spec/ECParameterSpec;)V");
+ jobject pubkey = (*env)->NewObject(env, pubkey_class, ec_pub_init, pub_bytes, ec_pub_param_spec);
+
+ jobject ec_priv_param_spec = (*env)->NewLocalRef(env, ec_param_spec);
+ jmethodID ec_priv_init = (*env)->GetMethodID(env, privkey_class, "<init>", "([BLjava/security/spec/ECParameterSpec;)V");
+ jobject privkey = (*env)->NewObject(env, privkey_class, ec_priv_init, priv_bytes, ec_priv_param_spec);
+
+ jmethodID keypair_init = (*env)->GetMethodID(env, keypair_class, "<init>", "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V");
+ return (*env)->NewObject(env, keypair_class, keypair_init, pubkey, privkey);
+}
+
+static jobject generate_from_curve_info(JNIEnv *env, const ippcp_curve *curve_info) {
+ int context_size;
+ if (curve_info->context_size_func) {
+ curve_info->context_size_func(&context_size);
+ } else {
+ ippsECCPGetSize(curve_info->size, &context_size);
+ }
+ uint8_t curve_buf[context_size];
+ IppsECCPState *curve = (IppsECCPState *)curve_buf;
+ if (curve_info->init_func) {
+ curve_info->init_func(curve);
+ } else {
+ ippsECCPInit(curve_info->size, curve);
+ }
+ if (curve_info->set_func) {
+ curve_info->set_func(curve);
+ } else {
+ ippsECCPSetStd(curve_info->id, curve);
+ }
+ if (USE_SPEEDUP && curve_info->precomp_func) {
+ curve_info->precomp_func(curve);
+ }
+ return generate_from_curve(env, curve_info->size, curve);
+}
+
+JNIEXPORT jobject JNICALL
+Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Ippcp_generate__ILjava_security_SecureRandom_2(JNIEnv *env,
+ jobject this,
+ jint keysize,
+ jobject random) {
+ for (size_t i = 0; i < NUM_CURVES; ++i) {
+ if (CURVES[i].size == keysize) {
+ return generate_from_curve_info(env, &CURVES[i]);
+ }
+ }
+ return NULL;
+}
+
+JNIEXPORT jobject JNICALL
+Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Ippcp_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2(
+ JNIEnv *env, jobject this, jobject params, jobject random) {
+
+ if ((*env)->IsInstanceOf(env, params, ec_parameter_spec_class)) {
+ int keysize;
+ IppsECCPState *curve = create_curve(env, params, &keysize);
+ jobject result = generate_from_curve(env, keysize, curve);
+ free(curve);
+ return result;
+ } else if ((*env)->IsInstanceOf(env, params, ecgen_parameter_spec_class)) {
+ jmethodID get_name = (*env)->GetMethodID(env, ecgen_parameter_spec_class, "getName", "()Ljava/lang/String;");
+ jstring name = (*env)->CallObjectMethod(env, params, get_name);
+ const char *utf_name = (*env)->GetStringUTFChars(env, name, NULL);
+ const ippcp_curve *curve_info;
+ for (size_t i = 0; i < NUM_CURVES; ++i) {
+ if (strcasecmp(utf_name, CURVES[i].name) == 0) {
+ curve_info = &CURVES[i];
+ break;
+ }
+ }
+ (*env)->ReleaseStringUTFChars(env, name, utf_name);
+ return generate_from_curve_info(env, curve_info);
+ } else {
+ return NULL;
+ }
+}
+
+static IppsECCPPointState *bytearray_to_pubkey(JNIEnv *env, jbyteArray pubkey, jint keysize, IppsECCPState *curve) {
+ IppsBigNumState *x_bn = new_bn(keysize);
+ IppsBigNumState *y_bn = new_bn(keysize);
+
+ jint coord_size = (keysize + 7) / 8;
+ jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL);
+ ippsSetOctString_BN(pub_data + 1, coord_size, x_bn);
+ ippsSetOctString_BN(pub_data + 1 + coord_size, coord_size, y_bn);
+ (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT);
+
+ IppsECCPPointState *pub = new_point(keysize);
+ ippsECCPSetPoint(x_bn, y_bn, pub, curve);
+ free(x_bn);
+ free(y_bn);
+ return pub;
+}
+
+static IppsBigNumState *bytearray_to_privkey(JNIEnv *env, jbyteArray privkey, IppsECCPState *curve) {
+ int ord_bits;
+ ippsECCPGetOrderBitSize(&ord_bits, curve);
+ IppsBigNumState *priv_bn = new_bn(ord_bits);
+ jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL);
+ ippsSetOctString_BN(priv_data, (*env)->GetArrayLength(env, privkey), priv_bn);
+ (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT);
+ return priv_bn;
+}
+
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Ippcp_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2(JNIEnv *env, jobject this, jbyteArray pubkey, jbyteArray privkey, jobject params) {
+ jint coord_size = ((*env)->GetArrayLength(env, pubkey) - 1) / 2;
+ jint keysize;
+ IppsECCPState *curve = create_curve(env, params, &keysize);
+
+ if (VALIDATE_CURVE) {
+ IppECResult validation;
+ ippsECCPValidate(50, &validation, curve, ippsPRNGen, prng_state);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ free(curve);
+ return NULL;
+ }
+ }
+ IppsECCPPointState *pub = bytearray_to_pubkey(env, pubkey, keysize, curve);
+
+ if (VALIDATE_POINT) {
+ IppECResult validation;
+ ippsECCPCheckPoint(pub, &validation, curve);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ free(curve);
+ free(pub);
+ return NULL;
+ }
+ }
+
+ IppsBigNumState *priv_bn = bytearray_to_privkey(env, privkey, curve);
+
+ IppsBigNumState *share = new_bn(keysize);
+
+ native_timing_start();
+ IppStatus err = ippsECCPSharedSecretDH(priv_bn, pub, share, curve);
+ native_timing_stop();
+
+ free(priv_bn);
+ free(pub);
+ free(curve);
+
+ if (err != ippStsNoErr) {
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ return NULL;
+ }
+
+ jbyteArray result = (*env)->NewByteArray(env, coord_size);
+ jbyte *data = (*env)->GetByteArrayElements(env, result, NULL);
+ bn_get(share, data, coord_size);
+ (*env)->ReleaseBooleanArrayElements(env, result, data, 0);
+ free(share);
+ return result;
+}
+
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Ippcp_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2(JNIEnv *env, jobject this, jbyteArray pubkey, jbyteArray privkey, jobject params, jstring algorithm) {
+ throw_new(env, "java/lang/UnsupportedOperationException", "Not supported.");
+ return NULL;
+}
+
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Ippcp_sign(JNIEnv *env, jobject this, jbyteArray data, jbyteArray privkey, jobject params) {
+ jint keysize;
+ IppsECCPState *curve = create_curve(env, params, &keysize);
+
+ if (VALIDATE_CURVE) {
+ IppECResult validation;
+ ippsECCPValidate(50, &validation, curve, ippsPRNGen, prng_state);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ free(curve);
+ return NULL;
+ }
+ }
+ IppsBigNumState *priv_bn = bytearray_to_privkey(env, privkey, curve);
+
+ IppsECCPPointState *ephemeral_point = new_point(keysize);
+ int ord_bits;
+ ippsECCPGetOrderBitSize(&ord_bits, curve);
+ int ord_bytes = (ord_bits + 7) / 8;
+ IppsBigNumState *ephemeral_secret = new_bn(ord_bits);
+ IppsBigNumState *r = new_bn(ord_bits);
+ IppsBigNumState *s = new_bn(ord_bits);
+
+ jint data_size = (*env)->GetArrayLength(env, data);
+ IppsBigNumState *data_bn = new_bn(data_size * 8);
+ jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
+ ippsSetOctString_BN(data_data, data_size, data_bn);
+ (*env)->ReleaseBooleanArrayElements(env, data, data_data, JNI_ABORT);
+
+ jbyteArray result = NULL;
+ jbyte r_buf[ord_bytes];
+ jbyte s_buf[ord_bytes];
+
+ native_timing_start();
+ IppStatus err = ippsECCPGenKeyPair(ephemeral_secret, ephemeral_point, curve, prng_wrapper, prng_state);
+ if (err != ippStsNoErr) {
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ goto error;
+ }
+ err = ippsECCPSetKeyPair(ephemeral_secret, ephemeral_point, ippFalse, curve);
+ if (err != ippStsNoErr) {
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ goto error;
+ }
+ err = ippsECCPSignDSA(data_bn, priv_bn, r, s, curve);
+ if (err != ippStsNoErr) {
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ goto error;
+ }
+ native_timing_stop();
+
+ bn_get(r, r_buf, ord_bytes);
+ bn_get(s, s_buf, ord_bytes);
+
+ result = asn1_der_encode(env, r_buf, ord_bytes, s_buf, ord_bytes);
+
+error:
+ free(curve);
+ free(priv_bn);
+ free(ephemeral_point);
+ free(ephemeral_secret);
+ free(r);
+ free(s);
+ return result;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Ippcp_verify(JNIEnv *env, jobject this, jbyteArray signature, jbyteArray data, jbyteArray pubkey, jobject params) {
+ jint keysize;
+ IppsECCPState *curve = create_curve(env, params, &keysize);
+
+ if (VALIDATE_CURVE) {
+ IppECResult validation;
+ ippsECCPValidate(50, &validation, curve, ippsPRNGen, prng_state);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ free(curve);
+ return JNI_FALSE;
+ }
+ }
+ IppsECCPPointState *pub = bytearray_to_pubkey(env, pubkey, keysize, curve);
+
+ if (VALIDATE_POINT) {
+ IppECResult validation;
+ ippsECCPCheckPoint(pub, &validation, curve);
+ if (validation != ippECValid) {
+ throw_new(env, "java/security/GeneralSecurityException", ippsECCGetResultString(validation));
+ free(curve);
+ free(pub);
+ return JNI_FALSE;
+ }
+ }
+
+ size_t r_len, s_len;
+ jbyte *r_data, *s_data;
+ bool decode = asn1_der_decode(env, signature, &r_data, &r_len, &s_data, &s_len);
+ if (!decode) {
+ throw_new(env, "java/security/GeneralSecurityException", "Error decoding sig.");
+ free(curve);
+ free(pub);
+ return JNI_FALSE;
+ }
+
+ int ord_bits;
+ ippsECCPGetOrderBitSize(&ord_bits, curve);
+
+ IppsBigNumState *r = new_bn(ord_bits);
+ ippsSetOctString_BN(r_data, r_len, r);
+ free(r_data);
+ IppsBigNumState *s = new_bn(ord_bits);
+ ippsSetOctString_BN(s_data, s_len, s);
+ free(s_data);
+
+ jint data_size = (*env)->GetArrayLength(env, data);
+ IppsBigNumState *data_bn = new_bn(data_size * 8);
+ jbyte *data_data = (*env)->GetByteArrayElements(env, data, NULL);
+ ippsSetOctString_BN(data_data, data_size, data_bn);
+ (*env)->ReleaseBooleanArrayElements(env, data, data_data, JNI_ABORT);
+
+ IppECResult result;
+
+ native_timing_start();
+ ippsECCPSetKeyPair(NULL, pub, ippTrue, curve);
+ IppStatus err = ippsECCPVerifyDSA(data_bn, r, s, &result, curve);
+ native_timing_stop();
+
+ free(curve);
+ free(pub);
+ free(r);
+ free(s);
+
+ if (err == ippStsNoErr && result == ippECValid) {
+ return JNI_TRUE;
+ }
+ if (err != ippStsNoErr) {
+ throw_new(env, "java/security/GeneralSecurityException", ippcpGetStatusString(err));
+ return JNI_FALSE;
+ }
+
+ return JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_supportsNativeTiming(JNIEnv *env, jobject this) {
+ return native_timing_supported();
+}
+
+JNIEXPORT jlong JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_getNativeTimingResolution(JNIEnv *env, jobject this) {
+ return native_timing_resolution();
+}
+
+JNIEXPORT jlong JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_getLastNativeTiming(JNIEnv *env, jobject this) {
+ return native_timing_last();
+}
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/mbedtls.c b/src/cz/crcs/ectester/standalone/libs/jni/mbedtls.c
index 71ede19..bedf084 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/mbedtls.c
+++ b/src/cz/crcs/ectester/standalone/libs/jni/mbedtls.c
@@ -52,7 +52,6 @@ static int dev_urandom(void *data, unsigned char *output, size_t len, size_t *ol
p += ret;
left -= ret;
- sleep(1);
}
fclose(file);
*olen = len;
@@ -204,18 +203,6 @@ static void mpi_from_biginteger(JNIEnv* env, jobject biginteger, mbedtls_mpi *mp
(*env)->ReleaseByteArrayElements(env, byte_array, byte_data, JNI_ABORT);
}
-static void biginteger_print(JNIEnv *env, jobject bigint) {
- jmethodID to_string = (*env)->GetMethodID(env, biginteger_class, "toString", "(I)Ljava/lang/String;");
- jstring big_string = (*env)->CallObjectMethod(env, bigint, to_string, (jint) 16);
-
- jsize len = (*env)->GetStringUTFLength(env, big_string);
- char raw_string[len + 1];
- raw_string[len] = 0;
- (*env)->GetStringUTFRegion(env, big_string, 0, len, raw_string);
- printf("%s\n", raw_string);
- fflush(stdout);
-}
-
static jobject create_ec_param_spec(JNIEnv *env, const mbedtls_ecp_group *group) {
jobject p = biginteger_from_mpi(env, &group->P);
jmethodID fp_field_init = (*env)->GetMethodID(env, fp_field_class, "<init>", "(Ljava/math/BigInteger;)V");
diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h
index 76268d8..3cbc2d1 100644
--- a/src/cz/crcs/ectester/standalone/libs/jni/native.h
+++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h
@@ -1640,3 +1640,208 @@ JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSigna
}
#endif
#endif
+/* Header for class cz_crcs_ectester_standalone_libs_IppcpLib */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_IppcpLib
+#define _Included_cz_crcs_ectester_standalone_libs_IppcpLib
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_IppcpLib
+ * Method: supportsNativeTiming
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_supportsNativeTiming
+ (JNIEnv *, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_IppcpLib
+ * Method: getNativeTimingResolution
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_getNativeTimingResolution
+ (JNIEnv *, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_IppcpLib
+ * Method: getLastNativeTiming
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_getLastNativeTiming
+ (JNIEnv *, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_IppcpLib
+ * Method: createProvider
+ * Signature: ()Ljava/security/Provider;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_createProvider
+ (JNIEnv *, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_IppcpLib
+ * Method: getCurves
+ * Signature: ()Ljava/util/Set;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_IppcpLib_getCurves
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_serialVersionUID 1421746759512286392LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_MAX_ARRAY_SIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_MAX_ARRAY_SIZE 2147483639L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_KEYS
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_KEYS 0L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_VALUES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_VALUES 1L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_ENTRIES
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_ENTRIES 2L
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_serialVersionUID 4112578634029874840LL
+#undef cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_serialVersionUID
+#define cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp_serialVersionUID -4298000515446427739LL
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeProvider_Ippcp
+ * Method: setup
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeProvider_00024Ippcp_setup
+ (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Ippcp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Ippcp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Ippcp
+#ifdef __cplusplus
+extern "C" {
+#endif
+#undef cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Ippcp_DEFAULT_KEYSIZE
+#define cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Ippcp_DEFAULT_KEYSIZE 256L
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Ippcp
+ * Method: keysizeSupported
+ * Signature: (I)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Ippcp_keysizeSupported
+ (JNIEnv *, jobject, jint);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Ippcp
+ * Method: paramsSupported
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Ippcp_paramsSupported
+ (JNIEnv *, jobject, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Ippcp
+ * Method: generate
+ * Signature: (ILjava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Ippcp_generate__ILjava_security_SecureRandom_2
+ (JNIEnv *, jobject, jint, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_Ippcp
+ * Method: generate
+ * Signature: (Ljava/security/spec/AlgorithmParameterSpec;Ljava/security/SecureRandom;)Ljava/security/KeyPair;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPairGeneratorSpi_00024Ippcp_generate__Ljava_security_spec_AlgorithmParameterSpec_2Ljava_security_SecureRandom_2
+ (JNIEnv *, jobject, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Ippcp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Ippcp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPublicKey_Ippcp
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Ippcp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Ippcp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeECPrivateKey_Ippcp
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Ippcp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Ippcp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Ippcp
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Ippcp
+ * Method: generateSecret
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Ippcp_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_Ippcp
+ * Method: generateSecret
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;Ljava/lang/String;)Ljavax/crypto/SecretKey;
+ */
+JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024Ippcp_generateSecret___3B_3BLjava_security_spec_ECParameterSpec_2Ljava_lang_String_2
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject, jstring);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Ippcp */
+
+#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Ippcp
+#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Ippcp
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Ippcp
+ * Method: sign
+ * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B
+ */
+JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Ippcp_sign
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject);
+
+/*
+ * Class: cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_Ippcp
+ * Method: verify
+ * Signature: ([B[B[BLjava/security/spec/ECParameterSpec;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeSignatureSpi_00024Ippcp_verify
+ (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif