From bc0ffbd552853d94750b842600f97b50b3cd3f4f Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Sun, 3 Jun 2018 17:58:24 -0400 Subject: [PATCH] Fix JNI write-back, bad V3 api usage, duplicate length passing. --- core/c/build.gradle | 2 +- core/c/src/mpw-jni.c | 15 +++++++++++---- core/c/src/mpw-jni.h | 5 ++--- core/java/algorithm/build.gradle | 8 ++++++++ .../lyndir/masterpassword/impl/MPAlgorithmV0.java | 6 ++---- .../lyndir/masterpassword/impl/MPAlgorithmV3.java | 2 +- .../java/com/lyndir/masterpassword/MPTests.java | 2 +- .../lyndir/masterpassword/MPMasterKeyTest.java | 2 +- 8 files changed, 27 insertions(+), 15 deletions(-) diff --git a/core/c/build.gradle b/core/c/build.gradle index ccceef1c..baabdcd4 100644 --- a/core/c/build.gradle +++ b/core/c/build.gradle @@ -29,7 +29,7 @@ library { //TODO: Cross-compiling, blocked by: https://github.com/gradle/gradle-native/issues/169 //setTargets( "arm", "arm64", "x86-64", "x86" ) eachPlatform { - cppCompiler.withArguments { addAll( ["-x", "c", "-std=c11", "-DMPW_SODIUM=1"] ) } + cppCompiler.withArguments { addAll( ["-x", "c", "-std=c11", "-Werror", "-DMPW_SODIUM=1"] ) } } } } diff --git a/core/c/src/mpw-jni.c b/core/c/src/mpw-jni.c index e40a6b9d..efcfc3d7 100644 --- a/core/c/src/mpw-jni.c +++ b/core/c/src/mpw-jni.c @@ -3,13 +3,16 @@ #include "mpw-jni.h" #include "mpw-util.h" -/** native int _scrypt(byte[] passwd, int passwdlen, byte[] salt, int saltlen, int N, int r, int p, byte[] buf, int buflen); */ +/** native int _scrypt(byte[] passwd, byte[] salt, int N, int r, int p, byte[] buf); */ JNIEXPORT jint JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1scrypt(JNIEnv *env, jobject obj, - jbyteArray passwd, jint passwdlen, jbyteArray salt, jint saltlen, jint N, jint r, jint p, jbyteArray buf, jint buflen) { + jbyteArray passwd, jbyteArray salt, jint N, jint r, jint p, jbyteArray buf) { jbyte *passwdBytes = (*env)->GetByteArrayElements( env, passwd, NULL ); jbyte *saltBytes = (*env)->GetByteArrayElements( env, salt, NULL ); - const uint8_t *key = mpw_kdf_scrypt( (size_t)buflen, (uint8_t *)passwdBytes, (size_t)passwdlen, (uint8_t *)saltBytes, (size_t)saltlen, + const size_t keyLength = (*env)->GetArrayLength( env, buf ); + const uint8_t *key = mpw_kdf_scrypt( keyLength, + (uint8_t *)passwdBytes, (size_t)(*env)->GetArrayLength( env, passwd ), + (uint8_t *)saltBytes, (size_t)(*env)->GetArrayLength( env, salt ), (uint64_t)N, (uint32_t)r, (uint32_t)p ); (*env)->ReleaseByteArrayElements( env, passwd, passwdBytes, JNI_ABORT ); (*env)->ReleaseByteArrayElements( env, salt, saltBytes, JNI_ABORT ); @@ -17,6 +20,10 @@ JNIEXPORT jint JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1scryp if (!key) return ERR; - memcpy( buf, key, buflen ); + jbyte *bufBytes = (*env)->GetByteArrayElements( env, buf, NULL ); + memcpy( bufBytes, key, keyLength ); + (*env)->ReleaseByteArrayElements( env, buf, bufBytes, JNI_OK ); + mpw_free( &key, keyLength ); + return OK; } diff --git a/core/c/src/mpw-jni.h b/core/c/src/mpw-jni.h index 09756303..e9116a74 100644 --- a/core/c/src/mpw-jni.h +++ b/core/c/src/mpw-jni.h @@ -1,5 +1,4 @@ /* DO NOT EDIT THIS FILE - it is machine generated */ -#undef __cplusplus #include /* Header for class com_lyndir_masterpassword_impl_MPAlgorithmV0 */ @@ -13,10 +12,10 @@ extern "C" { /* * Class: com_lyndir_masterpassword_impl_MPAlgorithmV0 * Method: _scrypt - * Signature: ([BI[BIIII[BI)I + * Signature: ([B[BIII[B)I */ JNIEXPORT jint JNICALL Java_com_lyndir_masterpassword_impl_MPAlgorithmV0__1scrypt - (JNIEnv *, jobject, jbyteArray, jint, jbyteArray, jint, jint, jint, jint, jbyteArray, jint); + (JNIEnv *, jobject, jbyteArray, jbyteArray, jint, jint, jint, jbyteArray); #ifdef __cplusplus } diff --git a/core/java/algorithm/build.gradle b/core/java/algorithm/build.gradle index 0b446c73..b50b2833 100644 --- a/core/java/algorithm/build.gradle +++ b/core/java/algorithm/build.gradle @@ -28,3 +28,11 @@ processResources { } } ) } + +compileJava { + doLast { + ant.javah( class: 'com.lyndir.masterpassword.impl.MPAlgorithmV0', + outputFile: '../../c/src/mpw-jni.h', + classpath: files( sourceSets.main.compileClasspath, sourceSets.main.output ).asPath ) + } +} diff --git a/core/java/algorithm/src/main/java/com/lyndir/masterpassword/impl/MPAlgorithmV0.java b/core/java/algorithm/src/main/java/com/lyndir/masterpassword/impl/MPAlgorithmV0.java index 3a5a3a1b..cef8080a 100644 --- a/core/java/algorithm/src/main/java/com/lyndir/masterpassword/impl/MPAlgorithmV0.java +++ b/core/java/algorithm/src/main/java/com/lyndir/masterpassword/impl/MPAlgorithmV0.java @@ -90,15 +90,13 @@ public class MPAlgorithmV0 extends MPAlgorithm { @Nullable protected byte[] scrypt(final byte[] secret, final byte[] salt, final int keySize) { byte[] buffer = new byte[keySize]; - if (_scrypt( - secret, secret.length, salt, salt.length, - scrypt_N(), scrypt_r(), scrypt_p(), buffer, buffer.length ) < 0) + if (_scrypt( secret, salt, scrypt_N(), scrypt_r(), scrypt_p(), buffer ) < 0) return null; return buffer; } - protected native int _scrypt(byte[] passwd, int passwdlen, byte[] salt, int saltlen, int N, int r, int p, byte[] buf, int buflen); + protected native int _scrypt(byte[] passwd, byte[] salt, int N, int r, int p, byte[] buf); @Override public byte[] siteKey(final byte[] masterKey, final String siteName, UnsignedInteger siteCounter, diff --git a/core/java/algorithm/src/main/java/com/lyndir/masterpassword/impl/MPAlgorithmV3.java b/core/java/algorithm/src/main/java/com/lyndir/masterpassword/impl/MPAlgorithmV3.java index e98db097..e6013216 100644 --- a/core/java/algorithm/src/main/java/com/lyndir/masterpassword/impl/MPAlgorithmV3.java +++ b/core/java/algorithm/src/main/java/com/lyndir/masterpassword/impl/MPAlgorithmV3.java @@ -50,7 +50,7 @@ public class MPAlgorithmV3 extends MPAlgorithmV2 { logger.trc( "masterKey: scrypt( masterPassword, masterKeySalt, N=%d, r=%d, p=%d )", scrypt_N(), scrypt_r(), scrypt_p() ); byte[] masterPasswordBytes = toBytes( masterPassword ); - byte[] masterKey = scrypt( masterKeySalt, masterPasswordBytes, mpw_dkLen() ); + byte[] masterKey = scrypt( masterPasswordBytes, masterKeySalt, mpw_dkLen() ); Arrays.fill( masterKeySalt, (byte) 0 ); Arrays.fill( masterPasswordBytes, (byte) 0 ); if (masterKey == null) diff --git a/core/java/tests/src/main/java/com/lyndir/masterpassword/MPTests.java b/core/java/tests/src/main/java/com/lyndir/masterpassword/MPTests.java index 67573c2f..c486dfb6 100644 --- a/core/java/tests/src/main/java/com/lyndir/masterpassword/MPTests.java +++ b/core/java/tests/src/main/java/com/lyndir/masterpassword/MPTests.java @@ -60,7 +60,7 @@ public class MPTests { } public Case getCase(final String identifier) { - for (final Case testCase : getCases()) + for (final Case testCase : cases) if (identifier.equals( testCase.getIdentifier() )) return testCase; diff --git a/core/java/tests/src/test/java/com/lyndir/masterpassword/MPMasterKeyTest.java b/core/java/tests/src/test/java/com/lyndir/masterpassword/MPMasterKeyTest.java index 939e2f7e..181e459c 100644 --- a/core/java/tests/src/test/java/com/lyndir/masterpassword/MPMasterKeyTest.java +++ b/core/java/tests/src/test/java/com/lyndir/masterpassword/MPMasterKeyTest.java @@ -39,7 +39,7 @@ public class MPMasterKeyTest { throws Exception { testSuite = new MPTestSuite(); - //testSuite.getTests().addFilters( "v0" ); + //testSuite.getTests().addFilters( "v3_type_maximum" ); } @Test