diff options
author | David Hook <dgh@cryptoworkshop.com> | 2014-05-19 15:56:24 +0400 |
---|---|---|
committer | David Hook <dgh@cryptoworkshop.com> | 2014-05-19 15:56:24 +0400 |
commit | 49555ece84b685bddbbbb5e48d3f7715452aab2f (patch) | |
tree | fde2d89c32e65f3518a0d06c021b077d6c5aed81 /core/src | |
parent | d2b9dc8867a39980a817177f2225277000410fdd (diff) |
further work on streams and block ciphers.
Diffstat (limited to 'core/src')
8 files changed, 52 insertions, 156 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java index e10e5ae3..8e41e492 100644 --- a/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java @@ -54,7 +54,7 @@ public class BufferedBlockCipher } else { - partialBlockOkay = (idx > 0 && (name.startsWith("GCFB", idx) ||name.startsWith("OFB", idx) || name.startsWith("OpenPGP", idx))); + partialBlockOkay = (idx > 0 && (name.startsWith("OpenPGP", idx))); } } diff --git a/core/src/main/java/org/bouncycastle/crypto/StreamBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/StreamBlockCipher.java index 8fdd2324..5d4050a6 100644 --- a/core/src/main/java/org/bouncycastle/crypto/StreamBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/StreamBlockCipher.java @@ -1,108 +1,56 @@ package org.bouncycastle.crypto; /** - * a wrapper for block ciphers with a single byte block size, so that they - * can be treated like stream ciphers. + * A parent class for block cipher modes that do not require block aligned data to be processed, but can function in + * a streaming mode. */ -public class StreamBlockCipher - implements StreamCipher +public abstract class StreamBlockCipher + implements BlockCipher, StreamCipher { - private BlockCipher cipher; + private final BlockCipher cipher; - private byte[] oneByte = new byte[1]; - - /** - * basic constructor. - * - * @param cipher the block cipher to be wrapped. - * @exception IllegalArgumentException if the cipher has a block size other than - * one. - */ - public StreamBlockCipher( - BlockCipher cipher) + protected StreamBlockCipher(BlockCipher cipher) { - if (cipher.getBlockSize() != 1) - { - throw new IllegalArgumentException("block cipher block size != 1."); - } - this.cipher = cipher; } /** - * initialise the underlying cipher. + * return the underlying block cipher that we are wrapping. * - * @param forEncryption true if we are setting up for encryption, false otherwise. - * @param params the necessary parameters for the underlying cipher to be initialised. + * @return the underlying block cipher that we are wrapping. */ - public void init( - boolean forEncryption, - CipherParameters params) + public BlockCipher getUnderlyingCipher() { - cipher.init(forEncryption, params); + return cipher; } - /** - * return the name of the algorithm we are wrapping. - * - * @return the name of the algorithm we are wrapping. - */ - public String getAlgorithmName() - { - return cipher.getAlgorithmName(); - } - - /** - * encrypt/decrypt a single byte returning the result. - * - * @param in the byte to be processed. - * @return the result of processing the input byte. - */ - public byte returnByte( - byte in) + public final byte returnByte(byte in) { - oneByte[0] = in; - - cipher.processBlock(oneByte, 0, oneByte, 0); - - return oneByte[0]; + return processByte(in); } - /** - * process a block of bytes from in putting the result into out. - * - * @param in the input byte array. - * @param inOff the offset into the in array where the data to be processed starts. - * @param len the number of bytes to be processed. - * @param out the output buffer the processed bytes go into. - * @param outOff the offset into the output byte array the processed data stars at. - * @exception DataLengthException if the output buffer is too small. - */ - public void processBytes( - byte[] in, - int inOff, - int len, - byte[] out, - int outOff) + public void processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) throws DataLengthException { if (outOff + len > out.length) { - throw new DataLengthException("output buffer too small in processBytes()"); + throw new DataLengthException("output buffer too short"); } - for (int i = 0; i != len; i++) + if (inOff + len > in.length) { - cipher.processBlock(in, inOff + i, out, outOff + i); + throw new DataLengthException("input buffer too small"); } - } - /** - * reset the underlying cipher. This leaves it in the same state - * it was at after the last init (if there was one). - */ - public void reset() - { - cipher.reset(); + int inStart = inOff; + int inEnd = inOff + len; + int outStart = outOff; + + while (inStart < inEnd) + { + out[outStart++] = processByte(in[inStart++]); + } } -} + + protected abstract byte processByte(byte b); +}
\ No newline at end of file diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java index 02f82f21..a82fae5f 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java @@ -3,6 +3,7 @@ package org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.StreamBlockCipher; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.util.Arrays; @@ -10,7 +11,7 @@ import org.bouncycastle.util.Arrays; * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher. */ public class CFBBlockCipher - extends StreamBlockCipherMode + extends StreamBlockCipher { private byte[] IV; private byte[] cfbV; @@ -45,16 +46,6 @@ public class CFBBlockCipher } /** - * return the underlying block cipher that we are wrapping. - * - * @return the underlying block cipher that we are wrapping. - */ - public BlockCipher getUnderlyingCipher() - { - return cipher; - } - - /** * Initialise the cipher and, possibly, the initialisation vector (IV). * If an IV isn't passed as part of the parameter, the IV will be all zeros. * An IV which is too short is handled in FIPS compliant fashion. diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java index 2d0c164f..2f84bc5a 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java @@ -3,6 +3,7 @@ package org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.StreamBlockCipher; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.params.ParametersWithRandom; @@ -12,7 +13,7 @@ import org.bouncycastle.crypto.params.ParametersWithSBox; * An implementation of the GOST CFB mode with CryptoPro key meshing as described in RFC 4357. */ public class GCFBBlockCipher - implements BlockCipher + extends StreamBlockCipher { private static final byte[] C = { @@ -30,6 +31,8 @@ public class GCFBBlockCipher public GCFBBlockCipher(BlockCipher engine) { + super(engine); + this.cfbEngine = new CFBBlockCipher(engine, engine.getBlockSize() * 8); } @@ -73,6 +76,13 @@ public class GCFBBlockCipher public int processBlock(byte[] in, int inOff, byte[] out, int outOff) throws DataLengthException, IllegalStateException { + this.processBytes(in, inOff, cfbEngine.getBlockSize(), out, outOff); + + return cfbEngine.getBlockSize(); + } + + protected byte processByte(byte b) + { if (counter > 0 && counter % 1024 == 0) { BlockCipher base = cfbEngine.getUnderlyingCipher(); @@ -88,18 +98,18 @@ public class GCFBBlockCipher key = new KeyParameter(nextKey); - byte[] iv = new byte[8]; - base.init(true, key); - base.processBlock(cfbEngine.getCurrentIV(), 0, iv, 0); + byte[] iv = cfbEngine.getCurrentIV(); + + base.processBlock(iv, 0, iv, 0); cfbEngine.init(forEncryption, new ParametersWithIV(key, iv)); } - counter += cfbEngine.getBlockSize(); + counter++; - return cfbEngine.processBlock(in, inOff, out, outOff); + return cfbEngine.processByte(b); } public void reset() diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/GOFBBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/GOFBBlockCipher.java index 1745fc7e..ccd9e0f7 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/GOFBBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/GOFBBlockCipher.java @@ -3,13 +3,14 @@ package org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.StreamBlockCipher; import org.bouncycastle.crypto.params.ParametersWithIV; /** * implements the GOST 28147 OFB counter mode (GCTR). */ public class GOFBBlockCipher - extends StreamBlockCipherMode + extends StreamBlockCipher { private byte[] IV; private byte[] ofbV; diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java index 97828105..7655535f 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/OFBBlockCipher.java @@ -3,13 +3,14 @@ package org.bouncycastle.crypto.modes; import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; +import org.bouncycastle.crypto.StreamBlockCipher; import org.bouncycastle.crypto.params.ParametersWithIV; /** * implements a Output-FeedBack (OFB) mode on top of a simple cipher. */ public class OFBBlockCipher - extends StreamBlockCipherMode + extends StreamBlockCipher { private int byteCount; private byte[] IV; diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java index e7a66af5..3edd96a0 100644 --- a/core/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java +++ b/core/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java @@ -4,6 +4,7 @@ import org.bouncycastle.crypto.BlockCipher; import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.DataLengthException; import org.bouncycastle.crypto.SkippingCipher; +import org.bouncycastle.crypto.StreamBlockCipher; import org.bouncycastle.crypto.params.ParametersWithIV; /** @@ -11,7 +12,7 @@ import org.bouncycastle.crypto.params.ParametersWithIV; * block cipher. This mode is also known as CTR mode. */ public class SICBlockCipher - extends StreamBlockCipherMode + extends StreamBlockCipher implements SkippingCipher { private final BlockCipher cipher; diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/StreamBlockCipherMode.java b/core/src/main/java/org/bouncycastle/crypto/modes/StreamBlockCipherMode.java deleted file mode 100644 index d91edacf..00000000 --- a/core/src/main/java/org/bouncycastle/crypto/modes/StreamBlockCipherMode.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.bouncycastle.crypto.modes; - -import org.bouncycastle.crypto.BlockCipher; -import org.bouncycastle.crypto.DataLengthException; -import org.bouncycastle.crypto.StreamCipher; - -public abstract class StreamBlockCipherMode - implements BlockCipher, StreamCipher -{ - private final BlockCipher cipher; - - protected StreamBlockCipherMode(BlockCipher cipher) - { - this.cipher = cipher; - } - - /** - * return the underlying block cipher that we are wrapping. - * - * @return the underlying block cipher that we are wrapping. - */ - public BlockCipher getUnderlyingCipher() - { - return cipher; - } - - public final byte returnByte(byte in) - { - return processByte(in); - } - - public void processBytes(byte[] in, int inOff, int len, byte[] out, int outOff) - throws DataLengthException - { - if (outOff + len > out.length) - { - throw new DataLengthException("output buffer too short"); - } - - if (inOff + len > in.length) - { - throw new DataLengthException("input buffer too small"); - } - - int inStart = inOff; - int inEnd = inOff + len; - int outStart = outOff; - - while (inStart < inEnd) - { - out[outStart++] = processByte(in[inStart++]); - } - } - - protected abstract byte processByte(byte b); -} |