diff options
Diffstat (limited to 'libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/CipherStreamTest.java')
-rw-r--r-- | libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/CipherStreamTest.java | 542 |
1 files changed, 0 insertions, 542 deletions
diff --git a/libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/CipherStreamTest.java b/libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/CipherStreamTest.java deleted file mode 100644 index c7527db1c..000000000 --- a/libraries/spongycastle/core/src/test/java/org/spongycastle/crypto/test/CipherStreamTest.java +++ /dev/null @@ -1,542 +0,0 @@ -package org.spongycastle.crypto.test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.OutputStream; - -import org.spongycastle.crypto.BlockCipher; -import org.spongycastle.crypto.BufferedBlockCipher; -import org.spongycastle.crypto.CipherParameters; -import org.spongycastle.crypto.StreamCipher; -import org.spongycastle.crypto.engines.AESEngine; -import org.spongycastle.crypto.engines.BlowfishEngine; -import org.spongycastle.crypto.engines.CAST5Engine; -import org.spongycastle.crypto.engines.CAST6Engine; -import org.spongycastle.crypto.engines.CamelliaEngine; -import org.spongycastle.crypto.engines.ChaChaEngine; -import org.spongycastle.crypto.engines.DESEngine; -import org.spongycastle.crypto.engines.DESedeEngine; -import org.spongycastle.crypto.engines.Grain128Engine; -import org.spongycastle.crypto.engines.Grainv1Engine; -import org.spongycastle.crypto.engines.HC128Engine; -import org.spongycastle.crypto.engines.HC256Engine; -import org.spongycastle.crypto.engines.NoekeonEngine; -import org.spongycastle.crypto.engines.RC2Engine; -import org.spongycastle.crypto.engines.RC4Engine; -import org.spongycastle.crypto.engines.RC6Engine; -import org.spongycastle.crypto.engines.SEEDEngine; -import org.spongycastle.crypto.engines.Salsa20Engine; -import org.spongycastle.crypto.engines.SerpentEngine; -import org.spongycastle.crypto.engines.TEAEngine; -import org.spongycastle.crypto.engines.ThreefishEngine; -import org.spongycastle.crypto.engines.TwofishEngine; -import org.spongycastle.crypto.engines.XSalsa20Engine; -import org.spongycastle.crypto.engines.XTEAEngine; -import org.spongycastle.crypto.io.CipherInputStream; -import org.spongycastle.crypto.io.CipherOutputStream; -import org.spongycastle.crypto.io.InvalidCipherTextIOException; -import org.spongycastle.crypto.modes.AEADBlockCipher; -import org.spongycastle.crypto.modes.CBCBlockCipher; -import org.spongycastle.crypto.modes.CCMBlockCipher; -import org.spongycastle.crypto.modes.CFBBlockCipher; -import org.spongycastle.crypto.modes.CTSBlockCipher; -import org.spongycastle.crypto.modes.EAXBlockCipher; -import org.spongycastle.crypto.modes.GCMBlockCipher; -import org.spongycastle.crypto.modes.OCBBlockCipher; -import org.spongycastle.crypto.modes.OFBBlockCipher; -import org.spongycastle.crypto.modes.SICBlockCipher; -import org.spongycastle.crypto.paddings.PKCS7Padding; -import org.spongycastle.crypto.paddings.PaddedBufferedBlockCipher; -import org.spongycastle.crypto.params.KeyParameter; -import org.spongycastle.crypto.params.ParametersWithIV; -import org.spongycastle.util.Arrays; -import org.spongycastle.util.test.SimpleTest; - -public class CipherStreamTest - extends SimpleTest -{ - public String getName() - { - return "CipherStreamTest"; - } - - private void testMode(Object cipher, CipherParameters params) - throws Exception - { - testWriteRead(cipher, params, false); - testWriteRead(cipher, params, true); - testReadWrite(cipher, params, false); - testReadWrite(cipher, params, true); - - if (!(cipher instanceof CTSBlockCipher)) - { - testWriteReadEmpty(cipher, params, false); - testWriteReadEmpty(cipher, params, true); - } - - if (cipher instanceof AEADBlockCipher) - { - testTamperedRead((AEADBlockCipher)cipher, params); - testTruncatedRead((AEADBlockCipher)cipher, params); - testTamperedWrite((AEADBlockCipher)cipher, params); - } - } - - private OutputStream createCipherOutputStream(OutputStream output, Object cipher) - { - if (cipher instanceof BufferedBlockCipher) - { - return new CipherOutputStream(output, (BufferedBlockCipher)cipher); - } - else if (cipher instanceof AEADBlockCipher) - { - return new CipherOutputStream(output, (AEADBlockCipher)cipher); - } - else - { - return new CipherOutputStream(output, (StreamCipher)cipher); - } - } - - private InputStream createCipherInputStream(byte[] data, Object cipher) - { - ByteArrayInputStream input = new ByteArrayInputStream(data); - if (cipher instanceof BufferedBlockCipher) - { - return new CipherInputStream(input, (BufferedBlockCipher)cipher); - } - else if (cipher instanceof AEADBlockCipher) - { - return new CipherInputStream(input, (AEADBlockCipher)cipher); - } - else - { - return new CipherInputStream(input, (StreamCipher)cipher); - } - } - - /** - * Test tampering of ciphertext followed by read from decrypting CipherInputStream - */ - private void testTamperedRead(AEADBlockCipher cipher, CipherParameters params) - throws Exception - { - cipher.init(true, params); - - byte[] ciphertext = new byte[cipher.getOutputSize(1000)]; - cipher.doFinal(ciphertext, cipher.processBytes(new byte[1000], 0, 1000, ciphertext, 0)); - - // Tamper - ciphertext[0] += 1; - - cipher.init(false, params); - InputStream input = createCipherInputStream(ciphertext, cipher); - try - { - while (input.read() >= 0) - { - } - fail("Expected invalid ciphertext after tamper and read : " + cipher.getAlgorithmName()); - } - catch (InvalidCipherTextIOException e) - { - // Expected - } - try - { - input.close(); - } - catch (Exception e) - { - fail("Unexpected exception after tamper and read : " + cipher.getAlgorithmName()); - } - } - - /** - * Test truncation of ciphertext to make tag calculation impossible, followed by read from - * decrypting CipherInputStream - */ - private void testTruncatedRead(AEADBlockCipher cipher, CipherParameters params) - throws Exception - { - cipher.init(true, params); - - byte[] ciphertext = new byte[cipher.getOutputSize(1000)]; - cipher.doFinal(ciphertext, cipher.processBytes(new byte[1000], 0, 1000, ciphertext, 0)); - - // Truncate to just smaller than complete tag - byte[] truncated = new byte[ciphertext.length - 1000 - 1]; - System.arraycopy(ciphertext, 0, truncated, 0, truncated.length); - - cipher.init(false, params); - InputStream input = createCipherInputStream(truncated, cipher); - while (true) - { - int read = 0; - try - { - read = input.read(); - } - catch (InvalidCipherTextIOException e) - { - // Expected - break; - } - catch (Exception e) - { - fail("Unexpected exception on truncated read : " + cipher.getAlgorithmName()); - break; - } - if (read < 0) - { - fail("Expected invalid ciphertext after truncate and read : " + cipher.getAlgorithmName()); - break; - } - } - try - { - input.close(); - } - catch (Exception e) - { - fail("Unexpected exception after truncate and read : " + cipher.getAlgorithmName()); - } - } - - /** - * Test tampering of ciphertext followed by write to decrypting CipherOutputStream - */ - private void testTamperedWrite(AEADBlockCipher cipher, CipherParameters params) - throws Exception - { - cipher.init(true, params); - - byte[] ciphertext = new byte[cipher.getOutputSize(1000)]; - cipher.doFinal(ciphertext, cipher.processBytes(new byte[1000], 0, 1000, ciphertext, 0)); - - // Tamper - ciphertext[0] += 1; - - cipher.init(false, params); - ByteArrayOutputStream plaintext = new ByteArrayOutputStream(); - OutputStream output = createCipherOutputStream(plaintext, cipher); - - for (int i = 0; i < ciphertext.length; i++) - { - output.write(ciphertext[i]); - } - try - { - output.close(); - fail("Expected invalid ciphertext after tamper and write : " + cipher.getAlgorithmName()); - } - catch (InvalidCipherTextIOException e) - { - // Expected - } - } - - /** - * Test CipherOutputStream in ENCRYPT_MODE, CipherInputStream in DECRYPT_MODE - */ - private void testWriteRead(Object cipher, CipherParameters params, boolean blocks) - throws Exception - { - byte[] data = new byte[1000]; - for (int i = 0; i < data.length; i++) - { - data[i] = (byte)(i % 255); - } - - testWriteRead(cipher, params, blocks, data); - } - - /** - * Test CipherOutputStream in ENCRYPT_MODE, CipherInputStream in DECRYPT_MODE - */ - private void testWriteReadEmpty(Object cipher, CipherParameters params, boolean blocks) - throws Exception - { - byte[] data = new byte[0]; - - testWriteRead(cipher, params, blocks, data); - } - - private void testWriteRead(Object cipher, CipherParameters params, boolean blocks, byte[] data) - { - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - try - { - init(cipher, true, params); - - OutputStream cOut = createCipherOutputStream(bOut, cipher); - if (blocks) - { - int chunkSize = data.length / 8; - for (int i = 0; i < data.length; i += chunkSize) - { - cOut.write(data, i, chunkSize); - } - } - else - { - for (int i = 0; i < data.length; i++) - { - cOut.write(data[i]); - } - } - cOut.close(); - - byte[] cipherText = bOut.toByteArray(); - bOut.reset(); - init(cipher, false, params); - InputStream cIn = createCipherInputStream(cipherText, cipher); - - if (blocks) - { - byte[] block = new byte[getBlockSize(cipher) + 1]; - int c; - while ((c = cIn.read(block)) >= 0) - { - bOut.write(block, 0, c); - } - } - else - { - int c; - while ((c = cIn.read()) >= 0) - { - bOut.write(c); - } - - } - cIn.close(); - - } - catch (Exception e) - { - fail("Unexpected exception " + getName(cipher), e); - } - - byte[] decrypted = bOut.toByteArray(); - if (!Arrays.areEqual(data, decrypted)) - { - fail("Failed - decrypted data doesn't match: " + getName(cipher)); - } - } - - private String getName(Object cipher) - { - if (cipher instanceof BufferedBlockCipher) - { - return ((BufferedBlockCipher)cipher).getUnderlyingCipher().getAlgorithmName(); - } - else if (cipher instanceof AEADBlockCipher) - { - return ((AEADBlockCipher)cipher).getUnderlyingCipher().getAlgorithmName(); - } - else if (cipher instanceof StreamCipher) - { - return ((StreamCipher)cipher).getAlgorithmName(); - } - return null; - } - - private int getBlockSize(Object cipher) - { - if (cipher instanceof BlockCipher) - { - return ((BlockCipher)cipher).getBlockSize(); - } - else if (cipher instanceof BufferedBlockCipher) - { - return ((BufferedBlockCipher)cipher).getBlockSize(); - } - else if (cipher instanceof AEADBlockCipher) - { - return ((AEADBlockCipher)cipher).getUnderlyingCipher().getBlockSize(); - } - else if (cipher instanceof StreamCipher) - { - return 1; - } - return 0; - } - - private void init(Object cipher, boolean forEncrypt, CipherParameters params) - { - if (cipher instanceof BufferedBlockCipher) - { - ((BufferedBlockCipher)cipher).init(forEncrypt, params); - } - else if (cipher instanceof AEADBlockCipher) - { - ((AEADBlockCipher)cipher).init(forEncrypt, params); - } - else if (cipher instanceof StreamCipher) - { - ((StreamCipher)cipher).init(forEncrypt, params); - } - } - - protected void fail(String message, boolean authenticated, boolean bc) - { - if (bc || !authenticated) - { - super.fail(message); - } - else - { - // javax.crypto.CipherInputStream/CipherOutputStream - // are broken wrt handling AEAD failures - System.err.println("Broken JCE Streams: " + message); - } - } - - /** - * Test CipherInputStream in ENCRYPT_MODE, CipherOutputStream in DECRYPT_MODE - */ - private void testReadWrite(Object cipher, CipherParameters params, boolean blocks) - throws Exception - { - String lCode = "ABCDEFGHIJKLMNOPQRSTU"; - - ByteArrayOutputStream bOut = new ByteArrayOutputStream(); - - try - { - init(cipher, true, params); - - InputStream cIn = createCipherInputStream(lCode.getBytes(), cipher); - ByteArrayOutputStream ct = new ByteArrayOutputStream(); - - if (blocks) - { - byte[] block = new byte[getBlockSize(cipher) + 1]; - int c; - while ((c = cIn.read(block)) >= 0) - { - ct.write(block, 0, c); - } - } - else - { - int c; - while ((c = cIn.read()) >= 0) - { - ct.write(c); - } - } - cIn.close(); - - init(cipher, false, params); - ByteArrayInputStream dataIn = new ByteArrayInputStream(ct.toByteArray()); - OutputStream cOut = createCipherOutputStream(bOut, cipher); - - if (blocks) - { - byte[] block = new byte[getBlockSize(cipher) + 1]; - int c; - while ((c = dataIn.read(block)) >= 0) - { - cOut.write(block, 0, c); - } - } - else - { - int c; - while ((c = dataIn.read()) >= 0) - { - cOut.write(c); - } - } - cOut.flush(); - cOut.close(); - - } - catch (Exception e) - { - fail("Unexpected exception " + getName(cipher), e); - } - - String res = new String(bOut.toByteArray()); - if (!res.equals(lCode)) - { - fail("Failed read/write - decrypted data doesn't match: " + getName(cipher), lCode, res); - } - } - - public void performTest() - throws Exception - { - testModes(new BlowfishEngine(), new BlowfishEngine(), 16); - testModes(new DESEngine(), new DESEngine(), 8); - testModes(new DESedeEngine(), new DESedeEngine(), 24); - testModes(new TEAEngine(), new TEAEngine(), 16); - testModes(new CAST5Engine(), new CAST5Engine(), 16); - testModes(new RC2Engine(), new RC2Engine(), 16); - testModes(new XTEAEngine(), new XTEAEngine(), 16); - - testModes(new AESEngine(), new AESEngine(), 16); - testModes(new NoekeonEngine(), new NoekeonEngine(), 16); - testModes(new TwofishEngine(), new TwofishEngine(), 16); - testModes(new CAST6Engine(), new CAST6Engine(), 16); - testModes(new SEEDEngine(), new SEEDEngine(), 16); - testModes(new SerpentEngine(), new SerpentEngine(), 16); - testModes(new RC6Engine(), new RC6Engine(), 16); - testModes(new CamelliaEngine(), new CamelliaEngine(), 16); - testModes(new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512), - new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512), 64); - - testMode(new RC4Engine(), new KeyParameter(new byte[16])); - testMode(new Salsa20Engine(), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[8])); - testMode(new XSalsa20Engine(), new ParametersWithIV(new KeyParameter(new byte[32]), new byte[24])); - testMode(new ChaChaEngine(), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[8])); - testMode(new Grainv1Engine(), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[8])); - testMode(new Grain128Engine(), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[12])); - testMode(new HC128Engine(), new KeyParameter(new byte[16])); - testMode(new HC256Engine(), new ParametersWithIV(new KeyParameter(new byte[16]), new byte[16])); - - } - - private void testModes(BlockCipher cipher1, BlockCipher cipher2, int keySize) - throws Exception - { - final KeyParameter key = new KeyParameter(new byte[keySize]); - final int blockSize = getBlockSize(cipher1); - final CipherParameters withIv = new ParametersWithIV(key, new byte[blockSize]); - - if (blockSize > 1) - { - testMode(new PaddedBufferedBlockCipher(cipher1, new PKCS7Padding()), key); - - testMode(new PaddedBufferedBlockCipher(new CBCBlockCipher(cipher1), new PKCS7Padding()), withIv); - - testMode(new BufferedBlockCipher(new OFBBlockCipher(cipher1, blockSize)), withIv); - testMode(new BufferedBlockCipher(new CFBBlockCipher(cipher1, blockSize)), withIv); - testMode(new BufferedBlockCipher(new SICBlockCipher(cipher1)), withIv); - } - if (blockSize <= 16) - { - testMode(new CTSBlockCipher(cipher1), key); - } - if (blockSize == 8 || blockSize == 16) - { - testMode(new EAXBlockCipher(cipher1), withIv); - } - if (blockSize == 16) - { - testMode(new CCMBlockCipher(cipher1), new ParametersWithIV(key, new byte[7])); - testMode(new GCMBlockCipher(cipher1), withIv); - testMode(new OCBBlockCipher(cipher1, cipher2), new ParametersWithIV(key, new byte[15])); - } - } - - public static void main(String[] args) - { - runTest(new CipherStreamTest()); - } - -} |