From 90f34fcc9c3a5b6cc1f33e8eef3da21eb9a01e82 Mon Sep 17 00:00:00 2001 From: Alan Evans Date: Thu, 23 Jan 2020 13:00:42 -0500 Subject: [PATCH] Improved JNI error handling. Added new verify overload which determines type from encoded. --- android/argon2/build.gradle | 1 + android/argon2/deploy.gradle | 2 +- .../jni/org_signal_argon2_Argon2Native.c | 97 ++++++++++++------ android/argon2/libs/arm64-v8a/libargon2.so | Bin 38760 -> 38760 bytes android/argon2/libs/armeabi-v7a/libargon2.so | Bin 38568 -> 38568 bytes android/argon2/libs/x86/libargon2.so | Bin 42604 -> 46700 bytes android/argon2/libs/x86_64/libargon2.so | Bin 47224 -> 47224 bytes .../signal/argon2/Argon2BadParameterTest.java | 52 ++++++++++ .../org/signal/argon2/Argon2BuilderTest.java | 45 ++++---- .../java/org/signal/argon2/TypeTest.java | 40 ++++++++ .../java/org/signal/argon2/VerifyTests.java | 49 +++++++++ .../main/java/org/signal/argon2/Argon2.java | 42 ++++++-- .../org/signal/argon2/Argon2Exception.java | 6 +- .../src/main/java/org/signal/argon2/Type.java | 10 ++ .../signal/argon2/UnknownTypeException.java | 6 ++ 15 files changed, 290 insertions(+), 60 deletions(-) create mode 100644 android/argon2/src/androidTest/java/org/signal/argon2/Argon2BadParameterTest.java create mode 100644 android/argon2/src/androidTest/java/org/signal/argon2/TypeTest.java create mode 100644 android/argon2/src/androidTest/java/org/signal/argon2/VerifyTests.java create mode 100644 android/argon2/src/main/java/org/signal/argon2/UnknownTypeException.java diff --git a/android/argon2/build.gradle b/android/argon2/build.gradle index b8c4a29..b2496fe 100644 --- a/android/argon2/build.gradle +++ b/android/argon2/build.gradle @@ -6,6 +6,7 @@ android { defaultConfig { minSdkVersion 19 + targetSdkVersion 28 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/android/argon2/deploy.gradle b/android/argon2/deploy.gradle index 8055fae..d94d368 100644 --- a/android/argon2/deploy.gradle +++ b/android/argon2/deploy.gradle @@ -1,7 +1,7 @@ apply plugin: 'maven' apply plugin: 'signing' -version = '13.0' +version = '13.1' group = 'org.signal' archivesBaseName = 'argon2' diff --git a/android/argon2/jni/org_signal_argon2_Argon2Native.c b/android/argon2/jni/org_signal_argon2_Argon2Native.c index aca417c..74888f6 100644 --- a/android/argon2/jni/org_signal_argon2_Argon2Native.c +++ b/android/argon2/jni/org_signal_argon2_Argon2Native.c @@ -1,9 +1,11 @@ #include -#include +#include #include "org_signal_argon2_Argon2Native.h" #include "argon2.h" -#define ENCODED_LEN 512 +#define SIGNAL_ERROR_NULL_INPUT -100 +#define SIGNAL_ERROR_BUFFER_ALLOCATION -101 +#define SIGNAL_ERROR_JNI_METHOD -102 JNIEXPORT jint JNICALL Java_org_signal_argon2_Argon2Native_hash (JNIEnv *env, @@ -18,54 +20,89 @@ JNIEXPORT jint JNICALL Java_org_signal_argon2_Argon2Native_hash jint argon_type, jint version) { - jsize pwd_size = (*env)->GetArrayLength(env, jPwd); - jsize salt_size = (*env)->GetArrayLength(env, jSalt); - jsize outLen = (*env)->GetArrayLength(env, jHash); - jbyte* pwdElements = (*env)->GetByteArrayElements(env, jPwd, NULL); - jbyte* saltElements = (*env)->GetByteArrayElements(env, jSalt, NULL); + if (jPwd == NULL) return SIGNAL_ERROR_NULL_INPUT; + if (jSalt == NULL) return SIGNAL_ERROR_NULL_INPUT; + if (jHash == NULL) return SIGNAL_ERROR_NULL_INPUT; - unsigned char out[outLen]; - char encoded[ENCODED_LEN]; + jsize pwd_size = (*env)->GetArrayLength(env, jPwd); + jsize salt_size = (*env)->GetArrayLength(env, jSalt); + jsize hash_size = (*env)->GetArrayLength(env, jHash); - int ret = argon2_hash(t, m, parallelism, - pwdElements, pwd_size, - saltElements, salt_size, - out, outLen, - encoded, ENCODED_LEN, - argon_type, - version); + char * encoded = NULL; + jbyte* pwdElements = NULL; + jbyte* saltElements = NULL; + jbyte* hashElements = NULL; - (*env)->ReleaseByteArrayElements(env, jPwd, pwdElements, JNI_ABORT); - (*env)->ReleaseByteArrayElements(env, jSalt, saltElements, JNI_ABORT); + const int encoded_size = jEncoded == NULL ? 0 : 512; - if (ret == ARGON2_OK) { - (*env)->SetByteArrayRegion(env, jHash, 0, outLen, (jbyte *)out); + if (encoded_size > 0) encoded = (char *) malloc(encoded_size); + if (encoded_size == 0 || encoded != NULL) pwdElements = (*env)->GetByteArrayElements(env, jPwd, NULL); + if (pwdElements != NULL) saltElements = (*env)->GetByteArrayElements(env, jSalt, NULL); + if (saltElements != NULL) hashElements = (*env)->GetByteArrayElements(env, jHash, NULL); + int result = (encoded_size > 0 && encoded == NULL) || pwdElements == NULL || saltElements == NULL || hashElements == NULL + ? SIGNAL_ERROR_BUFFER_ALLOCATION + : argon2_hash(t, m, parallelism, + pwdElements, pwd_size, + saltElements, salt_size, + hashElements, hash_size, + encoded, encoded_size, + argon_type, + version); + + if (result == ARGON2_OK && jEncoded != NULL && encoded != NULL) { jclass stringBufferClass = (*env)->GetObjectClass(env, jEncoded); jmethodID appendMethod = (*env)->GetMethodID(env, stringBufferClass, "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;"); - (*env)->CallObjectMethod(env, jEncoded, appendMethod, (*env)->NewStringUTF(env, encoded)); + + if (appendMethod == NULL) { + result = SIGNAL_ERROR_JNI_METHOD; + } else { + (*env)->CallObjectMethod(env, jEncoded, appendMethod, (*env)->NewStringUTF(env, encoded)); + } } - return ret; + if (pwdElements != NULL) (*env)->ReleaseByteArrayElements(env, jPwd, pwdElements, JNI_ABORT); + if (saltElements != NULL) (*env)->ReleaseByteArrayElements(env, jSalt, saltElements, JNI_ABORT); + if (hashElements != NULL) (*env)->ReleaseByteArrayElements(env, jHash, hashElements, result == ARGON2_OK ? 0 : JNI_ABORT); + if (encoded != NULL) free(encoded); + + return result; } JNIEXPORT jint JNICALL Java_org_signal_argon2_Argon2Native_verify (JNIEnv *env, jclass clazz, jstring jEncoded, jbyteArray jPwd, jint argon_type) { - const char *encoded = (*env)->GetStringUTFChars(env, jEncoded, NULL); - jsize pwd_size = (*env)->GetArrayLength(env, jPwd); - jbyte *pwd = (*env)->GetByteArrayElements(env, jPwd, NULL); + if (jEncoded == NULL) return SIGNAL_ERROR_NULL_INPUT; + if (jPwd == NULL) return SIGNAL_ERROR_NULL_INPUT; - int ret = argon2_verify((char *)encoded, pwd, pwd_size, argon_type); + const char *encoded = NULL; - (*env)->ReleaseByteArrayElements(env, jPwd, pwd, JNI_ABORT); - (*env)->ReleaseStringUTFChars(env, jEncoded, encoded); + jsize pwd_size = (*env)->GetArrayLength(env, jPwd); + jbyte *pwd = (*env)->GetByteArrayElements(env, jPwd, NULL); - return ret; + if (pwd != NULL) encoded = (*env)->GetStringUTFChars(env, jEncoded, NULL); + + int result = pwd == NULL || encoded == NULL + ? SIGNAL_ERROR_BUFFER_ALLOCATION + : argon2_verify((char *)encoded, pwd, pwd_size, argon_type); + + if (pwd != NULL) (*env)->ReleaseByteArrayElements(env, jPwd, pwd, JNI_ABORT); + if (encoded != NULL) (*env)->ReleaseStringUTFChars(env, jEncoded, encoded); + + return result; } JNIEXPORT jstring JNICALL Java_org_signal_argon2_Argon2Native_resultToString (JNIEnv *env, jclass clazz, jint argonResult) { - return (*env)->NewStringUTF(env, argon2_error_message(argonResult)); + const char *message; + + switch (argonResult) { + case SIGNAL_ERROR_NULL_INPUT: message = "Input parameter was NULL"; break; + case SIGNAL_ERROR_BUFFER_ALLOCATION: message = "Failed to allocate input buffers"; break; + case SIGNAL_ERROR_JNI_METHOD: message = "Failed to find method"; break; + default: message = argon2_error_message(argonResult); + } + + return (*env)->NewStringUTF(env, message); } diff --git a/android/argon2/libs/arm64-v8a/libargon2.so b/android/argon2/libs/arm64-v8a/libargon2.so index bef5be2dcbc86991c9403aca9573df26a595ca93..da072ae3c0bd4504fea30f7909c0deaac34f86fb 100755 GIT binary patch delta 9018 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 QWZJh~H>zw8{&j`)e~Pj*8UO$Q delta 8749 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 diff --git a/android/argon2/libs/armeabi-v7a/libargon2.so b/android/argon2/libs/armeabi-v7a/libargon2.so index f11a770a209a13e7ed5974b6b6afd5c3e33dfa47..ebb445931d255f9956d1af26481b1db3a92ab01b 100755 GIT binary patch delta 8442 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 delta 9899 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 diff --git a/android/argon2/libs/x86_64/libargon2.so b/android/argon2/libs/x86_64/libargon2.so index 2f504673568762ace2cf69112e05e653e0f251ea..8e379f601298c6b690136aef43dec0cf452c5413 100755 GIT binary patch delta 12088 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 diff --git a/android/argon2/src/androidTest/java/org/signal/argon2/Argon2BadParameterTest.java b/android/argon2/src/androidTest/java/org/signal/argon2/Argon2BadParameterTest.java new file mode 100644 index 0000000..901bc5f --- /dev/null +++ b/android/argon2/src/androidTest/java/org/signal/argon2/Argon2BadParameterTest.java @@ -0,0 +1,52 @@ +package org.signal.argon2; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.signal.argon2.TestUtils.utf8; +import static org.signal.argon2.Type.Argon2id; + +public final class Argon2BadParameterTest { + + @Test + public void null_password() { + Argon2 argon2 = new Argon2.Builder(Version.V13) + .type(Argon2id) + .memoryCost(MemoryCost.MiB(32)) + .parallelism(1) + .iterations(1) + .build(); + //noinspection ConstantConditions + assertThatThrownBy(()-> argon2.hash(null, utf8("somesalt"))) + .isExactlyInstanceOf(IllegalArgumentException.class); + } + + @Test + public void null_salt() { + Argon2 argon2 = new Argon2.Builder(Version.V13) + .type(Argon2id) + .memoryCost(MemoryCost.MiB(32)) + .parallelism(1) + .iterations(1) + .build(); + //noinspection ConstantConditions + assertThatThrownBy(() -> argon2.hash(utf8("signal"), null)) + .isExactlyInstanceOf(IllegalArgumentException.class); + } + + @Test + public void verify_with_null_password() { + //noinspection ConstantConditions + assertThatThrownBy(() -> + Argon2.verify("$argon2id$v=19$m=32768,t=1,p=1$c29tZXNhbHQ$5d38aTyOwp6kx3ALaN/k04OsQ98uO6FRLo5XYsy9gZ4", null, Argon2id) + ).isExactlyInstanceOf(IllegalArgumentException.class); + } + + @Test + public void verify_with_null_encoded() { + //noinspection ConstantConditions + assertThatThrownBy(() -> + Argon2.verify(null, utf8("signal"), Argon2id) + ).isExactlyInstanceOf(IllegalArgumentException.class); + } +} diff --git a/android/argon2/src/androidTest/java/org/signal/argon2/Argon2BuilderTest.java b/android/argon2/src/androidTest/java/org/signal/argon2/Argon2BuilderTest.java index 489c4d0..a4407a4 100644 --- a/android/argon2/src/androidTest/java/org/signal/argon2/Argon2BuilderTest.java +++ b/android/argon2/src/androidTest/java/org/signal/argon2/Argon2BuilderTest.java @@ -6,6 +6,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.signal.argon2.TestUtils.utf8; import static org.signal.argon2.Type.Argon2id; @@ -32,25 +33,33 @@ public final class Argon2BuilderTest { } @Test - public void using_MemoryCost() throws Argon2Exception { - String hash1 = new Argon2.Builder(Version.V13) - .type(Argon2id) - .memoryCost(MemoryCost.MiB(20)) - .parallelism(1) - .iterations(1) - .build() - .hash(utf8("signal"), utf8("somesalt")) - .getEncoded(); + public void using_MemoryCost_object() throws Argon2Exception { + String hash = new Argon2.Builder(Version.V13) + .type(Argon2id) + .memoryCost(MemoryCost.MiB(32)) + .parallelism(1) + .iterations(1) + .build() + .hash(utf8("signal"), utf8("somesalt")) + .getEncoded(); - String hash2 = new Argon2.Builder(Version.V13) - .type(Argon2id) - .memoryCostKiB(20 * 1024) - .parallelism(1) - .iterations(1) - .build() - .hash(utf8("signal"), utf8("somesalt")) - .getEncoded(); + assertEquals("$argon2id$v=19$m=32768,t=1,p=1$c29tZXNhbHQ$5d38aTyOwp6kx3ALaN/k04OsQ98uO6FRLo5XYsy9gZ4", hash); + } - assertEquals(hash1, hash2); + @Test + public void password_and_salt_are_unmodified() throws Argon2Exception { + byte[] password = utf8("signal"); + byte[] salt = utf8("somesalt"); + + new Argon2.Builder(Version.V13) + .type(Argon2id) + .memoryCost(MemoryCost.MiB(1)) + .parallelism(1) + .iterations(1) + .build() + .hash(password, salt); + + assertArrayEquals(utf8("signal"), password); + assertArrayEquals(utf8("somesalt"), salt); } } diff --git a/android/argon2/src/androidTest/java/org/signal/argon2/TypeTest.java b/android/argon2/src/androidTest/java/org/signal/argon2/TypeTest.java new file mode 100644 index 0000000..80caea8 --- /dev/null +++ b/android/argon2/src/androidTest/java/org/signal/argon2/TypeTest.java @@ -0,0 +1,40 @@ +package org.signal.argon2; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; +import static org.signal.argon2.Type.Argon2d; +import static org.signal.argon2.Type.Argon2i; +import static org.signal.argon2.Type.Argon2id; + +public final class TypeTest { + + @Test + public void can_parse_argon2id() throws UnknownTypeException { + assertEquals(Argon2id, Type.fromEncoded("$argon2id$v=19$m=32768,t=1,p=1$c29tZXNhbHQ$5d38aTyOwp6kx3ALaN/k04OsQ98uO6FRLo5XYsy9gZ4")); + } + + @Test + public void can_parse_argon2i() throws UnknownTypeException { + assertEquals(Argon2i, Type.fromEncoded("$argon2i$v=19$m=1024,t=1,p=1$c29tZXNhbHQ$F1TwhdCXduq6IqFH+gob2M5rpSok5w2c1YdaTKm6wvw")); + } + + @Test + public void can_parse_argon2d() throws UnknownTypeException { + assertEquals(Argon2d, Type.fromEncoded("$argon2d$v=19$m=1024,t=1,p=1$c29tZXNhbHQ$AQZ5maf/c48fwRjlcN4vwK7AXDAwtfwe7MTYI8+27T8")); + } + + @Test + public void cant_parse_unknown() { + assertThatThrownBy(() -> Type.fromEncoded("$argon2idx$v=19$m=1024,t=1,p=1$c29tZXNhbHQ$AQZ5maf/c48fwRjlcN4vwK7AXDAwtfwe7MTYI8+27T8")) + .isExactlyInstanceOf(UnknownTypeException.class); + } + + @Test + public void cant_parse_null() { + //noinspection ConstantConditions + assertThatThrownBy(() -> Type.fromEncoded(null)) + .isExactlyInstanceOf(IllegalArgumentException.class); + } +} diff --git a/android/argon2/src/androidTest/java/org/signal/argon2/VerifyTests.java b/android/argon2/src/androidTest/java/org/signal/argon2/VerifyTests.java new file mode 100644 index 0000000..e46886f --- /dev/null +++ b/android/argon2/src/androidTest/java/org/signal/argon2/VerifyTests.java @@ -0,0 +1,49 @@ +package org.signal.argon2; + +import org.junit.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertTrue; +import static org.signal.argon2.TestUtils.utf8; +import static org.signal.argon2.Type.Argon2d; +import static org.signal.argon2.Type.Argon2i; +import static org.signal.argon2.Type.Argon2id; + +public final class VerifyTests { + + @Test + public void verify_argon2d_specifying_type() { + assertTrue(Argon2.verify("$argon2d$v=19$m=1024,t=1,p=1$c29tZXNhbHQ$AQZ5maf/c48fwRjlcN4vwK7AXDAwtfwe7MTYI8+27T8", utf8("signal"), Argon2d)); + } + + @Test + public void verify_argon2d_not_specifying_type() throws UnknownTypeException { + assertTrue(Argon2.verify("$argon2d$v=19$m=1024,t=1,p=1$c29tZXNhbHQ$AQZ5maf/c48fwRjlcN4vwK7AXDAwtfwe7MTYI8+27T8", utf8("signal"))); + } + + @Test + public void verify_argon2i_specifying_type() { + assertTrue(Argon2.verify("$argon2i$v=19$m=1024,t=1,p=1$c29tZXNhbHQ$F1TwhdCXduq6IqFH+gob2M5rpSok5w2c1YdaTKm6wvw", utf8("signal"), Argon2i)); + } + + @Test + public void verify_argon2i_not_specifying_type() throws UnknownTypeException { + assertTrue(Argon2.verify("$argon2i$v=19$m=1024,t=1,p=1$c29tZXNhbHQ$F1TwhdCXduq6IqFH+gob2M5rpSok5w2c1YdaTKm6wvw", utf8("signal"))); + } + + @Test + public void verify_argon2id_specifying_type() { + assertTrue(Argon2.verify("$argon2id$v=19$m=32768,t=1,p=1$c29tZXNhbHQ$5d38aTyOwp6kx3ALaN/k04OsQ98uO6FRLo5XYsy9gZ4", utf8("signal"), Argon2id)); + } + + @Test + public void verify_argon2id_not_specifying_type() throws UnknownTypeException { + assertTrue(Argon2.verify("$argon2id$v=19$m=32768,t=1,p=1$c29tZXNhbHQ$5d38aTyOwp6kx3ALaN/k04OsQ98uO6FRLo5XYsy9gZ4", utf8("signal"))); + } + + @Test + public void unknown() { + assertThatThrownBy(() -> Argon2.verify("$argon2dx$v=19$m=1024,t=1,p=1$c29tZXNhbHQ$AQZ5maf/c48fwRjlcN4vwK7AXDAwtfwe7MTYI8+27T8", utf8("signal"))) + .isExactlyInstanceOf(UnknownTypeException.class); + } +} diff --git a/android/argon2/src/main/java/org/signal/argon2/Argon2.java b/android/argon2/src/main/java/org/signal/argon2/Argon2.java index 36feab7..3d04a5f 100644 --- a/android/argon2/src/main/java/org/signal/argon2/Argon2.java +++ b/android/argon2/src/main/java/org/signal/argon2/Argon2.java @@ -20,8 +20,24 @@ public final class Argon2 { this.version = builder.version; } + /** + * Finds the type from the encoded hash. + * @param encoded + * @param password + * @return + * @throws UnknownTypeException If it cannot determine the type from the encoded hash. + */ + public static boolean verify(String encoded, byte[] password) throws UnknownTypeException { + return verify(encoded, password, Type.fromEncoded(encoded)); + } + public static boolean verify(String encoded, byte[] password, Type type) { - return Argon2Native.verify(encoded, password, type.nativeValue) == Argon2Native.OK; + if (encoded == null) throw new IllegalArgumentException(); + if (password == null) throw new IllegalArgumentException(); + + byte[] defensivePasswordCopy = password.clone(); + + return Argon2Native.verify(encoded, defensivePasswordCopy, type.nativeValue) == Argon2Native.OK; } public static class Builder { @@ -103,15 +119,21 @@ public final class Argon2 { } public Result hash(byte[] password, byte[] salt) throws Argon2Exception { - StringBuffer encoded = new StringBuffer(); - byte[] hash = new byte[hashLength]; - int result = Argon2Native.hash(tCostIterations, mCostKiB, parallelism, - password, - salt, - hash, - encoded, - type.nativeValue, - version.nativeValue); + if (salt == null) throw new IllegalArgumentException(); + if (password == null) throw new IllegalArgumentException(); + + StringBuffer encoded = new StringBuffer(); + byte[] hash = new byte[hashLength]; + byte[] defensivePasswordCopy = password.clone(); + byte[] defensiveSaltCopy = salt.clone(); + + int result = Argon2Native.hash(tCostIterations, mCostKiB, parallelism, + defensivePasswordCopy, + defensiveSaltCopy, + hash, + encoded, + type.nativeValue, + version.nativeValue); if (result != Argon2Native.OK) { throw new Argon2Exception(result, Argon2Native.resultToString(result)); diff --git a/android/argon2/src/main/java/org/signal/argon2/Argon2Exception.java b/android/argon2/src/main/java/org/signal/argon2/Argon2Exception.java index a45dc01..e741988 100644 --- a/android/argon2/src/main/java/org/signal/argon2/Argon2Exception.java +++ b/android/argon2/src/main/java/org/signal/argon2/Argon2Exception.java @@ -4,7 +4,11 @@ import java.util.Locale; public final class Argon2Exception extends Exception { + Argon2Exception(String message) { + super(message); + } + Argon2Exception(int nativeErrorValue, String nativeErrorMessage) { - super(String.format(Locale.US, "Argon failed %d: %s", nativeErrorValue, nativeErrorMessage)); + this(String.format(Locale.US, "Argon failed %d: %s", nativeErrorValue, nativeErrorMessage)); } } diff --git a/android/argon2/src/main/java/org/signal/argon2/Type.java b/android/argon2/src/main/java/org/signal/argon2/Type.java index 59dcb56..15ff2b0 100644 --- a/android/argon2/src/main/java/org/signal/argon2/Type.java +++ b/android/argon2/src/main/java/org/signal/argon2/Type.java @@ -13,4 +13,14 @@ public enum Type { Type(int nativeValue) { this.nativeValue = nativeValue; } + + public static Type fromEncoded(String encoded) throws UnknownTypeException { + if (encoded == null) throw new IllegalArgumentException(); + + if (encoded.startsWith("$argon2id$")) return Argon2id; + if (encoded.startsWith("$argon2i$" )) return Argon2i; + if (encoded.startsWith("$argon2d$" )) return Argon2d; + + throw new UnknownTypeException(); + } } diff --git a/android/argon2/src/main/java/org/signal/argon2/UnknownTypeException.java b/android/argon2/src/main/java/org/signal/argon2/UnknownTypeException.java new file mode 100644 index 0000000..8a7fd82 --- /dev/null +++ b/android/argon2/src/main/java/org/signal/argon2/UnknownTypeException.java @@ -0,0 +1,6 @@ +package org.signal.argon2; + +public final class UnknownTypeException extends Exception { + UnknownTypeException() { + } +}