diff options
Diffstat (limited to 'libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/CipherStreamTest.java')
-rw-r--r-- | libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/CipherStreamTest.java | 354 |
1 files changed, 354 insertions, 0 deletions
diff --git a/libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/CipherStreamTest.java b/libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/CipherStreamTest.java new file mode 100644 index 000000000..454401b8c --- /dev/null +++ b/libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/CipherStreamTest.java @@ -0,0 +1,354 @@ +package org.spongycastle.jce.provider.test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.Security; + +import javax.crypto.Cipher; +import javax.crypto.CipherInputStream; +import javax.crypto.CipherOutputStream; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.ShortBufferException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +import org.spongycastle.jce.provider.BouncyCastleProvider; +import org.spongycastle.util.encoders.Hex; +import org.spongycastle.util.test.SimpleTest; + +/** + * check that cipher input/output streams are working correctly + */ +public class CipherStreamTest + extends SimpleTest +{ + + private static byte[] RK = Hex.decode("0123456789ABCDEF"); + private static byte[] RIN = Hex.decode("4e6f772069732074"); + private static byte[] ROUT = Hex.decode("3afbb5c77938280d"); + + private static byte[] SIN = Hex.decode( + "00000000000000000000000000000000" + + "00000000000000000000000000000000" + + "00000000000000000000000000000000" + + "00000000000000000000000000000000"); + private static final byte[] SK = Hex.decode("80000000000000000000000000000000"); + private static final byte[] SIV = Hex.decode("0000000000000000"); + private static final byte[] SOUT = Hex.decode( + "4DFA5E481DA23EA09A31022050859936" + + "DA52FCEE218005164F267CB65F5CFD7F" + + "2B4F97E0FF16924A52DF269515110A07" + + "F9E460BC65EF95DA58F740B7D1DBB0AA"); + + private static final byte[] XSK = Hex.decode("d5c7f6797b7e7e9c1d7fd2610b2abf2bc5a7885fb3ff78092fb3abe8986d35e2"); + private static final byte[] XSIV = Hex.decode("744e17312b27969d826444640e9c4a378ae334f185369c95"); + private static final byte[] XSIN = Hex.decode("7758298c628eb3a4b6963c5445ef66971222be5d1a4ad839715d1188071739b77cc6e05d5410f963a64167629757"); + private static final byte[] XSOUT= Hex.decode("27b8cfe81416a76301fd1eec6a4d99675069b2da2776c360db1bdfea7c0aa613913e10f7a60fec04d11e65f2d64e"); + + private static final byte[] CHAK = Hex.decode("80000000000000000000000000000000"); + private static final byte[] CHAIV = Hex.decode("0000000000000000"); + private static final byte[] CHAIN = Hex.decode( + "00000000000000000000000000000000" + + "00000000000000000000000000000000" + + "00000000000000000000000000000000" + + "00000000000000000000000000000000"); + private static final byte[] CHAOUT = Hex.decode("FBB87FBB8395E05DAA3B1D683C422046" + + "F913985C2AD9B23CFC06C1D8D04FF213" + + "D44A7A7CDB84929F915420A8A3DC58BF" + + "0F7ECB4B1F167BB1A5E6153FDAF4493D"); + + private static final byte[] HCIN = new byte[64]; + private static final byte[] HCIV = new byte[32]; + + private static final byte[] HCK256A = new byte[32]; + private static final byte[] HC256A = Hex.decode( + "5B078985D8F6F30D42C5C02FA6B67951" + + "53F06534801F89F24E74248B720B4818" + + "CD9227ECEBCF4DBF8DBF6977E4AE14FA" + + "E8504C7BC8A9F3EA6C0106F5327E6981"); + + private static final byte[] HCK128A = new byte[16]; + private static final byte[] HC128A = Hex.decode( + "82001573A003FD3B7FD72FFB0EAF63AA" + + "C62F12DEB629DCA72785A66268EC758B" + + "1EDB36900560898178E0AD009ABF1F49" + + "1330DC1C246E3D6CB264F6900271D59C"); + + private static final byte[] GRAIN_V1 = Hex.decode("0123456789abcdef1234"); + private static final byte[] GRAIN_V1_IV = Hex.decode("0123456789abcdef"); + private static final byte[] GRAIN_V1_IN = new byte[10]; + private static final byte[] GRAIN_V1_OUT = Hex.decode("7f362bd3f7abae203664"); + + private static final byte[] GRAIN_128 = Hex.decode("0123456789abcdef123456789abcdef0"); + private static final byte[] GRAIN_128_IV = Hex.decode("0123456789abcdef12345678"); + private static final byte[] GRAIN_128_IN = new byte[16]; + private static final byte[] GRAIN_128_OUT = Hex.decode("afb5babfa8de896b4b9c6acaf7c4fbfd"); + + public CipherStreamTest() + { + } + + private void runTest( + String name) + throws Exception + { + String lCode = "ABCDEFGHIJKLMNOPQRSTUVWXY0123456789"; + KeyGenerator kGen; + + if (name.indexOf('/') < 0) + { + kGen = KeyGenerator.getInstance(name, "SC"); + } + else + { + kGen = KeyGenerator.getInstance(name.substring(0, name.indexOf('/')), "SC"); + } + + Cipher in = Cipher.getInstance(name, "SC"); + Cipher out = Cipher.getInstance(name, "SC"); + Key key = kGen.generateKey(); + ByteArrayInputStream bIn = new ByteArrayInputStream(lCode.getBytes()); + ByteArrayOutputStream bOut = new ByteArrayOutputStream(); + + in.init(Cipher.ENCRYPT_MODE, key); + if (in.getIV() != null) + { + out.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(in.getIV())); + } + else + { + out.init(Cipher.DECRYPT_MODE, key); + } + + CipherInputStream cIn = new CipherInputStream(bIn, in); + CipherOutputStream cOut = new CipherOutputStream(bOut, out); + + int c; + + while ((c = cIn.read()) >= 0) + { + cOut.write(c); + } + + cIn.close(); + + cOut.flush(); + cOut.close(); + + String res = new String(bOut.toByteArray()); + + if (!res.equals(lCode)) + { + fail("Failed - decrypted data doesn't match."); + } + } + + private void testAlgorithm(String name, byte[] keyBytes, byte[] iv, byte[] plainText, byte[] cipherText) + throws Exception + { + SecretKey key = new SecretKeySpec(keyBytes, name); + Cipher in = Cipher.getInstance(name, "SC"); + Cipher out = Cipher.getInstance(name, "SC"); + + if (iv != null) + { + in.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv)); + out.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv)); + } + else + { + in.init(Cipher.ENCRYPT_MODE, key); + out.init(Cipher.DECRYPT_MODE, key); + } + + byte[] enc = in.doFinal(plainText); + if (!areEqual(enc, cipherText)) + { + fail(name + ": cipher text doesn't match got " + new String(Hex.encode(enc))); + } + + byte[] dec = out.doFinal(enc); + + if (!areEqual(dec, plainText)) + { + fail(name + ": plain text doesn't match"); + } + } + + private void testException( + String name) + { + try + { + byte[] key128 = { + (byte)128, (byte)131, (byte)133, (byte)134, + (byte)137, (byte)138, (byte)140, (byte)143, + (byte)128, (byte)131, (byte)133, (byte)134, + (byte)137, (byte)138, (byte)140, (byte)143 }; + + byte[] key256 = { + (byte)128, (byte)131, (byte)133, (byte)134, + (byte)137, (byte)138, (byte)140, (byte)143, + (byte)128, (byte)131, (byte)133, (byte)134, + (byte)137, (byte)138, (byte)140, (byte)143, + (byte)128, (byte)131, (byte)133, (byte)134, + (byte)137, (byte)138, (byte)140, (byte)143, + (byte)128, (byte)131, (byte)133, (byte)134, + (byte)137, (byte)138, (byte)140, (byte)143 }; + + byte[] keyBytes; + if (name.equals("HC256") || name.equals("XSalsa20")) + { + keyBytes = key256; + } + else + { + keyBytes = key128; + } + + SecretKeySpec cipherKey = new SecretKeySpec(keyBytes, name); + Cipher ecipher = Cipher.getInstance(name, "SC"); + ecipher.init(Cipher.ENCRYPT_MODE, cipherKey); + + byte[] cipherText = new byte[0]; + try + { + // According specification Method engineUpdate(byte[] input, + // int inputOffset, int inputLen, byte[] output, int + // outputOffset) + // throws ShortBufferException - if the given output buffer is + // too + // small to hold the result + ecipher.update(new byte[20], 0, 20, cipherText); + + fail("failed exception test - no ShortBufferException thrown"); + } + catch (ShortBufferException e) + { + // ignore + } + + try + { + Cipher c = Cipher.getInstance(name, "SC"); + + Key k = new PublicKey() + { + + public String getAlgorithm() + { + return "STUB"; + } + + public String getFormat() + { + return null; + } + + public byte[] getEncoded() + { + return null; + } + + }; + + c.init(Cipher.ENCRYPT_MODE, k); + + fail("failed exception test - no InvalidKeyException thrown for public key"); + } + catch (InvalidKeyException e) + { + // okay + } + + try + { + Cipher c = Cipher.getInstance(name, "SC"); + + Key k = new PrivateKey() + { + + public String getAlgorithm() + { + return "STUB"; + } + + public String getFormat() + { + return null; + } + + public byte[] getEncoded() + { + return null; + } + + }; + + c.init(Cipher.DECRYPT_MODE, k); + + fail("failed exception test - no InvalidKeyException thrown for private key"); + } + catch (InvalidKeyException e) + { + // okay + } + } + catch (Exception e) + { + fail("unexpected exception.", e); + } + } + + public void performTest() + throws Exception + { + runTest("RC4"); + testException("RC4"); + testAlgorithm("RC4", RK, null, RIN, ROUT); + runTest("Salsa20"); + testException("Salsa20"); + testAlgorithm("Salsa20", SK, SIV, SIN, SOUT); + runTest("XSalsa20"); + testException("XSalsa20"); + testAlgorithm("XSalsa20", XSK, XSIV, XSIN, XSOUT); + runTest("ChaCha"); + testException("ChaCha"); + testAlgorithm("ChaCha", CHAK, CHAIV, CHAIN, CHAOUT); + runTest("HC128"); + testException("HC128"); + testAlgorithm("HC128", HCK128A, HCIV, HCIN, HC128A); + runTest("HC256"); + testException("HC256"); + testAlgorithm("HC256", HCK256A, HCIV, HCIN, HC256A); + runTest("VMPC"); + testException("VMPC"); + //testAlgorithm("VMPC", a, iv, in, a); + runTest("VMPC-KSA3"); + testException("VMPC-KSA3"); + //testAlgorithm("VMPC-KSA3", a, iv, in, a); + testAlgorithm("Grainv1", GRAIN_V1, GRAIN_V1_IV, GRAIN_V1_IN, GRAIN_V1_OUT); + testAlgorithm("Grain128", GRAIN_128, GRAIN_128_IV, GRAIN_128_IN, GRAIN_128_OUT); + runTest("DES/ECB/PKCS7Padding"); + runTest("DES/CFB8/NoPadding"); + } + + public String getName() + { + return "CipherStreamTest"; + } + + + public static void main( + String[] args) + { + Security.addProvider(new BouncyCastleProvider()); + + runTest(new CipherStreamTest()); + } +} |