diff --git a/NoiseJava/src/com/southernstorm/noise/protocol/Noise.java b/NoiseJava/src/com/southernstorm/noise/protocol/Noise.java index cb24efe..a950a3f 100644 --- a/NoiseJava/src/com/southernstorm/noise/protocol/Noise.java +++ b/NoiseJava/src/com/southernstorm/noise/protocol/Noise.java @@ -56,6 +56,23 @@ public final class Noise { random.nextBytes(data); } + private static boolean forceFallbacks = false; + + /** + * Force the use of plain Java fallback crypto implementations. + * + * @param force Set to true for force fallbacks, false to + * try to use the system implementation before falling back. + * + * This function is intended for testing purposes to toggle between + * the system JCA/JCE implementations and the plain Java fallback + * reference implementations. + */ + public static void setForceFallbacks(boolean force) + { + forceFallbacks = force; + } + /** * Creates a Diffie-Hellman object from its Noise protocol name. * @@ -90,6 +107,8 @@ public final class Noise { public static CipherState createCipher(String name) throws NoSuchAlgorithmException { if (name.equals("AESGCM")) { + if (forceFallbacks) + return new AESGCMFallbackCipherState(); // AESGCMCipherState doesn't seem to work yet - FIXME. //try { // return new AESGCMCipherState(); @@ -128,12 +147,16 @@ public final class Noise { // The only algorithm that is required to be implemented by a // JDK is "SHA-256", although "SHA-512" is fairly common as well. if (name.equals("SHA256")) { + if (forceFallbacks) + return new SHA256MessageDigest(); try { return MessageDigest.getInstance("SHA-256"); } catch (NoSuchAlgorithmException e) { return new SHA256MessageDigest(); } } else if (name.equals("SHA512")) { + if (forceFallbacks) + return new SHA512MessageDigest(); try { return MessageDigest.getInstance("SHA-512"); } catch (NoSuchAlgorithmException e) { @@ -142,6 +165,8 @@ public final class Noise { } else if (name.equals("BLAKE2b")) { // Bouncy Castle registers the BLAKE2b variant we // want under the name "BLAKE2B-512". + if (forceFallbacks) + return new Blake2bMessageDigest(); try { return MessageDigest.getInstance("BLAKE2B-512"); } catch (NoSuchAlgorithmException e) { @@ -151,6 +176,8 @@ public final class Noise { // Bouncy Castle doesn't currently (June 2016) have an // implementation of BLAKE2s, but look for the most // obvious provider name in case one is added in the future. + if (forceFallbacks) + return new Blake2sMessageDigest(); try { return MessageDigest.getInstance("BLAKE2S-256"); } catch (NoSuchAlgorithmException e) { diff --git a/NoiseJavaTests/src/com/southernstorm/noise/tests/CipherStateTests.java b/NoiseJavaTests/src/com/southernstorm/noise/tests/CipherStateTests.java index 92f68ca..3265404 100644 --- a/NoiseJavaTests/src/com/southernstorm/noise/tests/CipherStateTests.java +++ b/NoiseJavaTests/src/com/southernstorm/noise/tests/CipherStateTests.java @@ -43,7 +43,7 @@ public class CipherStateTests { private void testCipher(String name, int keyLen, int macLen, String key, long nonce, String ad, String plaintext, String ciphertext, - String mac) + String mac, boolean forceFallbacks) { byte[] keyBytes = TestUtils.stringToData(key); byte[] adBytes = TestUtils.stringToData(ad); @@ -57,6 +57,7 @@ public class CipherStateTests { // Create the cipher object and check its properties. CipherState cipher = null; + Noise.setForceFallbacks(forceFallbacks); try { cipher = Noise.createCipher(name); } catch (NoSuchAlgorithmException e) { @@ -173,6 +174,15 @@ public class CipherStateTests { } } + private void testCipher(String name, int keyLen, int macLen, + String key, long nonce, String ad, + String plaintext, String ciphertext, + String mac) + { + testCipher(name, keyLen, macLen, key, nonce, ad, plaintext, ciphertext, mac, true); + testCipher(name, keyLen, macLen, key, nonce, ad, plaintext, ciphertext, mac, false); + } + @Test public void AESGCM() { /* Test vectors for AES in GCM mode from Appendix B of: diff --git a/NoiseJavaTests/src/com/southernstorm/noise/tests/HashTests.java b/NoiseJavaTests/src/com/southernstorm/noise/tests/HashTests.java index caec386..824d14b 100644 --- a/NoiseJavaTests/src/com/southernstorm/noise/tests/HashTests.java +++ b/NoiseJavaTests/src/com/southernstorm/noise/tests/HashTests.java @@ -65,57 +65,56 @@ public class HashTests { assertArrayEquals(hashBytes, result); } + private void testHash(String name, String input, String hash) + { + MessageDigest digest = null; + + Noise.setForceFallbacks(true); + try { + digest = Noise.createHash(name); + } catch (NoSuchAlgorithmException e) { + fail("No crypto provider for " + name); + } finally { + Noise.setForceFallbacks(false); + } + testHash(digest, input, hash); + + Noise.setForceFallbacks(false); + try { + digest = Noise.createHash(name); + } catch (NoSuchAlgorithmException e) { + fail("No crypto provider for " + name); + } + testHash(digest, input, hash); + } + @Test public void blake2b() { - MessageDigest digest = null; - try { - digest = Noise.createHash("BLAKE2b"); - } catch (NoSuchAlgorithmException e) { - fail("No crypto provider for BLAKE2b"); - } - testHash(digest, "", "0x786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"); - testHash(digest, "abc", "0xba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"); - testHash(digest, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "0x7285ff3e8bd768d69be62b3bf18765a325917fa9744ac2f582a20850bc2b1141ed1b3e4528595acc90772bdf2d37dc8a47130b44f33a02e8730e5ad8e166e888"); - testHash(digest, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "0xce741ac5930fe346811175c5227bb7bfcd47f42612fae46c0809514f9e0e3a11ee1773287147cdeaeedff50709aa716341fe65240f4ad6777d6bfaf9726e5e52"); + testHash("BLAKE2b", "", "0x786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce"); + testHash("BLAKE2b", "abc", "0xba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923"); + testHash("BLAKE2b", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "0x7285ff3e8bd768d69be62b3bf18765a325917fa9744ac2f582a20850bc2b1141ed1b3e4528595acc90772bdf2d37dc8a47130b44f33a02e8730e5ad8e166e888"); + testHash("BLAKE2b", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "0xce741ac5930fe346811175c5227bb7bfcd47f42612fae46c0809514f9e0e3a11ee1773287147cdeaeedff50709aa716341fe65240f4ad6777d6bfaf9726e5e52"); } @Test public void blake2s() { - MessageDigest digest = null; - try { - digest = Noise.createHash("BLAKE2s"); - } catch (NoSuchAlgorithmException e) { - fail("No crypto provider for BLAKE2s"); - } - testHash(digest, "", "0x69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"); - testHash(digest, "abc", "0x508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982"); - testHash(digest, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "0x6f4df5116a6f332edab1d9e10ee87df6557beab6259d7663f3bcd5722c13f189"); - testHash(digest, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "0x358dd2ed0780d4054e76cb6f3a5bce2841e8e2f547431d4d09db21b66d941fc7"); + testHash("BLAKE2s", "", "0x69217a3079908094e11121d042354a7c1f55b6482ca1a51e1b250dfd1ed0eef9"); + testHash("BLAKE2s", "abc", "0x508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982"); + testHash("BLAKE2s", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "0x6f4df5116a6f332edab1d9e10ee87df6557beab6259d7663f3bcd5722c13f189"); + testHash("BLAKE2s", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "0x358dd2ed0780d4054e76cb6f3a5bce2841e8e2f547431d4d09db21b66d941fc7"); } @Test public void sha256() { - MessageDigest digest = null; - try { - digest = Noise.createHash("SHA256"); - } catch (NoSuchAlgorithmException e) { - fail("No crypto provider for SHA256"); - } - testHash(digest, "", "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); - testHash(digest, "abc", "0xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); - testHash(digest, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "0x248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"); + testHash("SHA256", "", "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); + testHash("SHA256", "abc", "0xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); + testHash("SHA256", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "0x248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1"); } @Test public void sha512() { - MessageDigest digest = null; - try { - digest = Noise.createHash("SHA512"); - } catch (NoSuchAlgorithmException e) { - fail("No crypto provider for SHA512"); - } - testHash(digest, "", "0xcf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"); - testHash(digest, "abc", "0xddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"); - testHash(digest, "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "0x8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"); + testHash("SHA512", "", "0xcf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e"); + testHash("SHA512", "abc", "0xddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"); + testHash("SHA512", "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "0x8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909"); } }