diff options
| author | J08nY | 2017-11-30 16:06:35 +0100 |
|---|---|---|
| committer | J08nY | 2017-11-30 16:06:35 +0100 |
| commit | 715dd7f068dfc9e5b90ce0c1e2d3aad0a9fe982a (patch) | |
| tree | cdecbced6df60822a8c52ae83274309b59632d92 | |
| parent | 5026cc9f03f11fc2a473124e32867f3302f901f7 (diff) | |
| download | ECTester-715dd7f068dfc9e5b90ce0c1e2d3aad0a9fe982a.tar.gz ECTester-715dd7f068dfc9e5b90ce0c1e2d3aad0a9fe982a.tar.zst ECTester-715dd7f068dfc9e5b90ce0c1e2d3aad0a9fe982a.zip | |
| -rw-r--r-- | build-standalone.xml | 1 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/standalone/libs/TomcryptLib.java | 2 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/standalone/libs/jni/Makefile | 4 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java | 62 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/standalone/libs/jni/native.h | 19 | ||||
| -rw-r--r-- | src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c | 52 |
6 files changed, 130 insertions, 10 deletions
diff --git a/build-standalone.xml b/build-standalone.xml index 7261eee..8098ce2 100644 --- a/build-standalone.xml +++ b/build-standalone.xml @@ -100,6 +100,7 @@ <class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyPairGeneratorSpi$TomCrypt"/> <class name="cz.crcs.ectester.standalone.libs.jni.NativeECPublicKey$TomCrypt"/> <class name="cz.crcs.ectester.standalone.libs.jni.NativeECPrivateKey$TomCrypt"/> + <class name="cz.crcs.ectester.standalone.libs.jni.NativeKeyAgreementSpi$TomCrypt"/> </javah> </target> </project> diff --git a/src/cz/crcs/ectester/standalone/libs/TomcryptLib.java b/src/cz/crcs/ectester/standalone/libs/TomcryptLib.java index 78db00e..57b273a 100644 --- a/src/cz/crcs/ectester/standalone/libs/TomcryptLib.java +++ b/src/cz/crcs/ectester/standalone/libs/TomcryptLib.java @@ -9,7 +9,7 @@ import java.util.Set; public class TomcryptLib extends NativeECLibrary { public TomcryptLib() { - super("tomcrypt_provider", "tommath", "tomcrypt"); + super("tomcrypt_provider", "tommath", "tomcrypt"); } @Override diff --git a/src/cz/crcs/ectester/standalone/libs/jni/Makefile b/src/cz/crcs/ectester/standalone/libs/jni/Makefile index 8750dd5..b60452f 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/Makefile +++ b/src/cz/crcs/ectester/standalone/libs/jni/Makefile @@ -36,10 +36,10 @@ JNI_PLATFORMINCLUDEDIR ?= $(JNI_INCLUDEDIR)/$(JNI_PLATFORM) all: tomcrypt_provider.so tomcrypt_provider.so: tomcrypt.o - gcc -DLTM_DESC -DUSE_LTM -fPIC -g -shared -o $@ $< -ltommath -ltomcrypt + gcc -fPIC -g -shared -o $@ $< -L. -ltommath -ltomcrypt %.o: %.c - gcc -fPIC -g -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I. -c $< + gcc -DLTM_DESC -fPIC -g -I"$(JNI_INCLUDEDIR)" -I"$(JNI_PLATFORMINCLUDEDIR)" -I. -c $< clean: rm -rf *.o diff --git a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java index d1b1f42..fee0ea8 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java +++ b/src/cz/crcs/ectester/standalone/libs/jni/NativeKeyAgreementSpi.java @@ -1,46 +1,98 @@ package cz.crcs.ectester.standalone.libs.jni; +import cz.crcs.ectester.common.util.ECUtil; + import javax.crypto.KeyAgreementSpi; import javax.crypto.SecretKey; import javax.crypto.ShortBufferException; import java.security.*; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.ECParameterSpec; /** * @author Jan Jancar johny@neuromancer.sk */ public abstract class NativeKeyAgreementSpi extends KeyAgreementSpi { + private ECPrivateKey privateKey; + private ECPublicKey publicKey; + private ECParameterSpec params; + @Override protected void engineInit(Key key, SecureRandom random) throws InvalidKeyException { - + if (!(key instanceof ECPrivateKey)) { + throw new InvalidKeyException + ("Key must be instance of PrivateKey"); + } + privateKey = (ECPrivateKey) key; + this.params = privateKey.getParams(); } @Override protected void engineInit(Key key, AlgorithmParameterSpec params, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { - + if (!(params instanceof ECParameterSpec)) { + throw new InvalidAlgorithmParameterException(); + } + engineInit(key, random); + this.params = (ECParameterSpec) params; } @Override protected Key engineDoPhase(Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException { + if (privateKey == null) { + throw new IllegalStateException("Not initialized"); + } + if (publicKey != null) { + throw new IllegalStateException("Phase already executed"); + } + if (!lastPhase) { + throw new IllegalStateException + ("Only two party agreement supported, lastPhase must be true"); + } + if (!(key instanceof ECPublicKey)) { + throw new InvalidKeyException + ("Key must be a PublicKey with algorithm EC"); + } + ECParameterSpec publicParams = ((ECPublicKey) key).getParams(); + if (!(params.getCurve().equals(publicParams.getCurve()) && + params.getGenerator().equals(publicParams.getGenerator()) && + params.getOrder().equals(publicParams.getOrder()) && + params.getCofactor() == publicParams.getCofactor())) { + throw new IllegalStateException("Mismatched parameters."); + } + publicKey = (ECPublicKey) key; return null; } @Override protected byte[] engineGenerateSecret() throws IllegalStateException { - return new byte[0]; + byte[] pubkey = ECUtil.toX962Uncompressed(publicKey.getW()); + byte[] privkey = privateKey.getS().toByteArray(); + return generateSecret(pubkey, privkey, params); } @Override protected int engineGenerateSecret(byte[] sharedSecret, int offset) throws IllegalStateException, ShortBufferException { - return 0; + byte[] secret = engineGenerateSecret(); + if (sharedSecret.length < offset + secret.length) { + throw new ShortBufferException(); + } + System.arraycopy(secret, 0, sharedSecret, offset, secret.length); + return secret.length; } @Override protected SecretKey engineGenerateSecret(String algorithm) throws IllegalStateException, NoSuchAlgorithmException, InvalidKeyException { - return null; + throw new NoSuchAlgorithmException(algorithm); } + abstract byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params); + + public static class TomCrypt extends NativeKeyAgreementSpi { + @Override + native byte[] generateSecret(byte[] pubkey, byte[] privkey, ECParameterSpec params); } } diff --git a/src/cz/crcs/ectester/standalone/libs/jni/native.h b/src/cz/crcs/ectester/standalone/libs/jni/native.h index da3a89c..7f63f61 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/native.h +++ b/src/cz/crcs/ectester/standalone/libs/jni/native.h @@ -125,3 +125,22 @@ extern "C" { } #endif #endif +/* Header for class cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt */ + +#ifndef _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt +#define _Included_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_TomCrypt + * Method: generateSecret + * Signature: ([B[BLjava/security/spec/ECParameterSpec;)[B + */ +JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024TomCrypt_generateSecret + (JNIEnv *, jobject, jbyteArray, jbyteArray, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c b/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c index f7dedce..b43b05a 100644 --- a/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c +++ b/src/cz/crcs/ectester/standalone/libs/jni/tomcrypt.c @@ -1,7 +1,6 @@ #include "native.h" #include <stdio.h> #include <string.h> -#define LTM_DESC #include <tomcrypt.h> static prng_state ltc_prng; @@ -287,7 +286,7 @@ static jobject generate_from_curve(JNIEnv *env, const ltc_ecc_set_type *curve) { jbyteArray priv_bytes = (*env)->NewByteArray(env, curve->size); jbyte *key_priv = (*env)->GetByteArrayElements(env, priv_bytes, NULL); - mp_to_unsigned_bin(key.k, key_priv); + ltc_mp.unsigned_write(key.k, key_priv); (*env)->ReleaseByteArrayElements(env, priv_bytes, key_priv, 0); jobject ec_priv_param_spec = (*env)->NewLocalRef(env, ec_param_spec); @@ -341,4 +340,53 @@ JNIEXPORT jobject JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyPai } else { return NULL; } +} + +JNIEXPORT jbyteArray JNICALL Java_cz_crcs_ectester_standalone_libs_jni_NativeKeyAgreementSpi_00024TomCrypt_generateSecret(JNIEnv *env, jobject this, jbyteArray pubkey, jbyteArray privkey, jobject params){ + ltc_ecc_set_type *curve = create_curve(env, params); + + jsize pub_size = (*env)->GetArrayLength(env, pubkey); + jbyte *pub_data = (*env)->GetByteArrayElements(env, pubkey, NULL); + jsize pub_half = (pub_size - 1) / 2; + + ecc_key pub; + pub.type = PK_PUBLIC; + pub.idx = -1; + pub.dp = curve; + ltc_init_multi(&pub.pubkey.x, &pub.pubkey.y, &pub.pubkey.z, NULL); + ltc_mp.set_int(pub.pubkey.z, 1); + ltc_mp.unsigned_read(pub.pubkey.x, pub_data + 1, (unsigned long) pub_half); + ltc_mp.unsigned_read(pub.pubkey.y, pub_data + 1 + pub_half, (unsigned long) pub_half); + + (*env)->ReleaseByteArrayElements(env, pubkey, pub_data, JNI_ABORT); + + jsize priv_size = (*env)->GetArrayLength(env, privkey); + jbyte *priv_data = (*env)->GetByteArrayElements(env, privkey, NULL); + + ecc_key priv; + priv.type = PK_PRIVATE; + priv.idx = -1; + priv.dp = curve; + ltc_mp.init(&priv.k); + ltc_mp.unsigned_read(priv.k, priv_data, (unsigned long) priv_size); + + (*env)->ReleaseByteArrayElements(env, privkey, priv_data, JNI_ABORT); + + unsigned char result[pub_half]; + + unsigned long output_len = pub_half; + int err; + if ((err = ecc_shared_secret(&priv, &pub, result, &output_len)) != CRYPT_OK) { + printf("Error during shared secret computation: %s\n", error_to_string(err)); + free(curve); + return NULL; + } + + jbyteArray output = (*env)->NewByteArray(env, pub_half); + jbyte *output_data = (*env)->GetByteArrayElements(env, output, NULL); + memcpy(output_data, result, pub_half); + (*env)->ReleaseByteArrayElements(env, output, output_data, JNI_COMMIT); + + free(curve); + return output; }
\ No newline at end of file |
