aboutsummaryrefslogtreecommitdiffstats
path: root/libraries/spongycastle/prov/src/test/java/org/spongycastle/jce/provider/test/CipherStreamTest.java
diff options
context:
space:
mode:
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.java354
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());
+ }
+}