diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-09-12 13:37:38 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-09-12 13:37:38 +0700 |
commit | 1298385506df2df9f8fd9c1ceacfaf952e02fd5d (patch) | |
tree | 5725137d5bdd744127a7cb91f7822949f85cbf7d | |
parent | Add basic support for JKS keystores (diff) | |
download | BouncyCastle.NET-ed25519-1298385506df2df9f8fd9c1ceacfaf952e02fd5d.tar.xz |
Separate out new IBlockCipherMode from IBlockCipher
58 files changed, 302 insertions, 713 deletions
diff --git a/crypto/src/crypto/BufferedBlockCipher.cs b/crypto/src/crypto/BufferedBlockCipher.cs index eaaae255e..788ab138b 100644 --- a/crypto/src/crypto/BufferedBlockCipher.cs +++ b/crypto/src/crypto/BufferedBlockCipher.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; namespace Org.BouncyCastle.Crypto @@ -16,10 +17,10 @@ namespace Org.BouncyCastle.Crypto public class BufferedBlockCipher : BufferedCipherBase { - internal byte[] buf; - internal int bufOff; - internal bool forEncryption; - internal IBlockCipher cipher; + internal byte[] buf; + internal int bufOff; + internal bool forEncryption; + internal IBlockCipherMode m_cipherMode; /** * constructor for subclasses @@ -28,26 +29,30 @@ namespace Org.BouncyCastle.Crypto { } - /** + public BufferedBlockCipher(IBlockCipher cipher) + : this(EcbBlockCipher.GetBlockCipherMode(cipher)) + { + } + + /** * Create a buffered block cipher without padding. * * @param cipher the underlying block cipher this buffering object wraps. * false otherwise. */ - public BufferedBlockCipher( - IBlockCipher cipher) + public BufferedBlockCipher(IBlockCipherMode cipherMode) { - if (cipher == null) - throw new ArgumentNullException("cipher"); + if (cipherMode == null) + throw new ArgumentNullException(nameof(cipherMode)); - this.cipher = cipher; - buf = new byte[cipher.GetBlockSize()]; + m_cipherMode = cipherMode; + buf = new byte[cipherMode.GetBlockSize()]; bufOff = 0; } public override string AlgorithmName { - get { return cipher.AlgorithmName; } + get { return m_cipherMode.AlgorithmName; } } /** @@ -60,19 +65,18 @@ namespace Org.BouncyCastle.Crypto * inappropriate. */ // Note: This doubles as the Init in the event that this cipher is being used as an IWrapper - public override void Init( - bool forEncryption, - ICipherParameters parameters) + public override void Init(bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; - ParametersWithRandom pwr = parameters as ParametersWithRandom; - if (pwr != null) - parameters = pwr.Parameters; + if (parameters is ParametersWithRandom withRandom) + { + parameters = withRandom.Parameters; + } Reset(); - cipher.Init(forEncryption, parameters); + m_cipherMode.Init(forEncryption, parameters); } /** @@ -82,7 +86,7 @@ namespace Org.BouncyCastle.Crypto */ public override int GetBlockSize() { - return cipher.GetBlockSize(); + return m_cipherMode.GetBlockSize(); } /** @@ -93,8 +97,7 @@ namespace Org.BouncyCastle.Crypto * @return the space required to accommodate a call to update * with len bytes of input. */ - public override int GetUpdateOutputSize( - int length) + public override int GetUpdateOutputSize(int length) { int total = length + bufOff; int leftOver = total % buf.Length; @@ -109,8 +112,7 @@ namespace Org.BouncyCastle.Crypto * @return the space required to accommodate a call to update and doFinal * with len bytes of input. */ - public override int GetOutputSize( - int length) + public override int GetOutputSize(int length) { // Note: Can assume IsPartialBlockOkay is true for purposes of this calculation return length + bufOff; @@ -136,14 +138,13 @@ namespace Org.BouncyCastle.Crypto throw new DataLengthException("output buffer too short"); bufOff = 0; - return cipher.ProcessBlock(buf, 0, output, outOff); + return m_cipherMode.ProcessBlock(buf, 0, output, outOff); } return 0; } - public override byte[] ProcessByte( - byte input) + public override byte[] ProcessByte(byte input) { int outLength = GetUpdateOutputSize(1); @@ -171,20 +172,17 @@ namespace Org.BouncyCastle.Crypto Check.OutputLength(output, buf.Length, "output buffer too short"); bufOff = 0; - return cipher.ProcessBlock(buf, output); + return m_cipherMode.ProcessBlock(buf, output); } return 0; } #endif - public override byte[] ProcessBytes( - byte[] input, - int inOff, - int length) - { - if (input == null) - throw new ArgumentNullException("input"); + public override byte[] ProcessBytes(byte[] input, int inOff, int length) + { + if (input == null) + throw new ArgumentNullException(nameof(input)); if (length < 1) return null; @@ -204,7 +202,7 @@ namespace Org.BouncyCastle.Crypto return outBytes; } - /** + /** * process an array of bytes, producing output if necessary. * * @param in the input byte array. @@ -216,14 +214,9 @@ namespace Org.BouncyCastle.Crypto * @exception DataLengthException if there isn't enough space in out. * @exception InvalidOperationException if the cipher isn't initialised. */ - public override int ProcessBytes( - byte[] input, - int inOff, - int length, - byte[] output, - int outOff) - { - if (length < 1) + public override int ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff) + { + if (length < 1) { if (length < 0) throw new ArgumentException("Can't have a negative input length!"); @@ -244,13 +237,13 @@ namespace Org.BouncyCastle.Crypto if (length >= gapLen) { Array.Copy(input, inOff, buf, bufOff, gapLen); - resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + resultLen = m_cipherMode.ProcessBlock(buf, 0, output, outOff); bufOff = 0; length -= gapLen; inOff += gapLen; while (length >= buf.Length) { - resultLen += cipher.ProcessBlock(input, inOff, output, outOff + resultLen); + resultLen += m_cipherMode.ProcessBlock(input, inOff, output, outOff + resultLen); length -= blockSize; inOff += blockSize; } @@ -279,12 +272,12 @@ namespace Org.BouncyCastle.Crypto if (input.Length >= gapLen) { input[..gapLen].CopyTo(buf.AsSpan(bufOff)); - resultLen = cipher.ProcessBlock(buf, output); + resultLen = m_cipherMode.ProcessBlock(buf, output); bufOff = 0; input = input[gapLen..]; while (input.Length >= buf.Length) { - resultLen += cipher.ProcessBlock(input, output[resultLen..]); + resultLen += m_cipherMode.ProcessBlock(input, output[resultLen..]); input = input[blockSize..]; } } @@ -319,13 +312,10 @@ namespace Org.BouncyCastle.Crypto return outBytes; } - public override byte[] DoFinal( - byte[] input, - int inOff, - int inLen) - { - if (input == null) - throw new ArgumentNullException("input"); + public override byte[] DoFinal(byte[] input, int inOff, int inLen) + { + if (input == null) + throw new ArgumentNullException(nameof(input)); int length = GetOutputSize(inLen); @@ -356,7 +346,7 @@ namespace Org.BouncyCastle.Crypto return outBytes; } - /** + /** * Process the last block in the buffer. * * @param out the array the block currently being held is copied into. @@ -370,19 +360,17 @@ namespace Org.BouncyCastle.Crypto * @exception DataLengthException if the input is not block size * aligned. */ - public override int DoFinal( - byte[] output, - int outOff) - { - try + public override int DoFinal(byte[] output, int outOff) + { + try { if (bufOff != 0) { - Check.DataLength(!cipher.IsPartialBlockOkay, "data not block size aligned"); + Check.DataLength(!m_cipherMode.IsPartialBlockOkay, "data not block size aligned"); Check.OutputLength(output, outOff, bufOff, "output buffer too short for DoFinal()"); // NB: Can't copy directly, or we may write too much output - cipher.ProcessBlock(buf, 0, buf, 0); + m_cipherMode.ProcessBlock(buf, 0, buf, 0); Array.Copy(buf, 0, output, outOff, bufOff); } @@ -401,11 +389,11 @@ namespace Org.BouncyCastle.Crypto { if (bufOff != 0) { - Check.DataLength(!cipher.IsPartialBlockOkay, "data not block size aligned"); + Check.DataLength(!m_cipherMode.IsPartialBlockOkay, "data not block size aligned"); Check.OutputLength(output, bufOff, "output buffer too short for DoFinal()"); // NB: Can't copy directly, or we may write too much output - cipher.ProcessBlock(buf, buf); + m_cipherMode.ProcessBlock(buf, buf); buf.AsSpan(0, bufOff).CopyTo(output); } @@ -427,7 +415,7 @@ namespace Org.BouncyCastle.Crypto Array.Clear(buf, 0, buf.Length); bufOff = 0; - cipher.Reset(); + m_cipherMode.Reset(); } } } diff --git a/crypto/src/crypto/IBlockCipher.cs b/crypto/src/crypto/IBlockCipher.cs index b26aaa49f..36f10d3e8 100644 --- a/crypto/src/crypto/IBlockCipher.cs +++ b/crypto/src/crypto/IBlockCipher.cs @@ -16,9 +16,6 @@ namespace Org.BouncyCastle.Crypto /// <returns>The block size for this cipher, in bytes.</returns> int GetBlockSize(); - /// <summary>Indicates whether this cipher can handle partial blocks.</summary> - bool IsPartialBlockOkay { get; } - /// <summary>Process a block.</summary> /// <param name="inBuf">The input buffer.</param> /// <param name="inOff">The offset into <paramref>inBuf</paramref> that the input block begins.</param> @@ -37,10 +34,5 @@ namespace Org.BouncyCastle.Crypto /// <returns>The number of bytes processed and produced.</returns> int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output); #endif - - /// <summary> - /// Reset the cipher to the same state as it was after the last init (if there was one). - /// </summary> - void Reset(); } } diff --git a/crypto/src/crypto/StreamBlockCipher.cs b/crypto/src/crypto/StreamBlockCipher.cs index 0cd9d110a..f7e76e6cf 100644 --- a/crypto/src/crypto/StreamBlockCipher.cs +++ b/crypto/src/crypto/StreamBlockCipher.cs @@ -1,5 +1,7 @@ using System; +using Org.BouncyCastle.Crypto.Modes; + namespace Org.BouncyCastle.Crypto { /** @@ -9,7 +11,7 @@ namespace Org.BouncyCastle.Crypto public class StreamBlockCipher : IStreamCipher { - private readonly IBlockCipher cipher; + private readonly IBlockCipherMode m_cipherMode; private readonly byte[] oneByte = new byte[1]; /** @@ -19,28 +21,25 @@ namespace Org.BouncyCastle.Crypto * @exception ArgumentException if the cipher has a block size other than * one. */ - public StreamBlockCipher( - IBlockCipher cipher) + public StreamBlockCipher(IBlockCipherMode cipherMode) { - if (cipher == null) - throw new ArgumentNullException("cipher"); - if (cipher.GetBlockSize() != 1) - throw new ArgumentException("block cipher block size != 1.", "cipher"); + if (cipherMode == null) + throw new ArgumentNullException(nameof(cipherMode)); + if (cipherMode.GetBlockSize() != 1) + throw new ArgumentException("block cipher block size != 1.", nameof(cipherMode)); - this.cipher = cipher; + m_cipherMode = cipherMode; } - /** + /** * initialise the underlying cipher. * * @param forEncryption true if we are setting up for encryption, false otherwise. * @param param the necessary parameters for the underlying cipher to be initialised. */ - public void Init( - bool forEncryption, - ICipherParameters parameters) - { - cipher.Init(forEncryption, parameters); + public void Init(bool forEncryption, ICipherParameters parameters) + { + m_cipherMode.Init(forEncryption, parameters); } /** @@ -50,7 +49,7 @@ namespace Org.BouncyCastle.Crypto */ public string AlgorithmName { - get { return cipher.AlgorithmName; } + get { return m_cipherMode.AlgorithmName; } } /** @@ -59,17 +58,16 @@ namespace Org.BouncyCastle.Crypto * @param in the byte to be processed. * @return the result of processing the input byte. */ - public byte ReturnByte( - byte input) + public byte ReturnByte(byte input) { oneByte[0] = input; - cipher.ProcessBlock(oneByte, 0, oneByte, 0); + m_cipherMode.ProcessBlock(oneByte, 0, oneByte, 0); return oneByte[0]; } - /** + /** * process a block of bytes from in putting the result into out. * * @param in the input byte array. @@ -79,19 +77,14 @@ namespace Org.BouncyCastle.Crypto * @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[] input, - int inOff, - int length, - byte[] output, - int outOff) - { - Check.DataLength(input, inOff, length, "input buffer too short"); + public void ProcessBytes(byte[] input, int inOff, int length, byte[] output, int outOff) + { + Check.DataLength(input, inOff, length, "input buffer too short"); Check.OutputLength(output, outOff, length, "output buffer too short"); for (int i = 0; i != length; i++) { - cipher.ProcessBlock(input, inOff + i, output, outOff + i); + m_cipherMode.ProcessBlock(input, inOff + i, output, outOff + i); } } @@ -102,7 +95,7 @@ namespace Org.BouncyCastle.Crypto for (int i = 0; i != input.Length; i++) { - cipher.ProcessBlock(input[i..], output[i..]); + m_cipherMode.ProcessBlock(input[i..], output[i..]); } } #endif @@ -113,7 +106,7 @@ namespace Org.BouncyCastle.Crypto */ public void Reset() { - cipher.Reset(); + m_cipherMode.Reset(); } } } diff --git a/crypto/src/crypto/engines/AesEngine.cs b/crypto/src/crypto/engines/AesEngine.cs index 21daf06d8..8ccadf1bf 100644 --- a/crypto/src/crypto/engines/AesEngine.cs +++ b/crypto/src/crypto/engines/AesEngine.cs @@ -468,11 +468,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "AES"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BLOCK_SIZE; @@ -531,10 +526,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private void EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output, uint[][] KW) { diff --git a/crypto/src/crypto/engines/AesEngine_X86.cs b/crypto/src/crypto/engines/AesEngine_X86.cs index cc362ff52..aeaf9317c 100644 --- a/crypto/src/crypto/engines/AesEngine_X86.cs +++ b/crypto/src/crypto/engines/AesEngine_X86.cs @@ -152,8 +152,6 @@ namespace Org.BouncyCastle.Crypto.Engines public string AlgorithmName => "AES"; - public bool IsPartialBlockOkay => false; - public int GetBlockSize() => 16; public void Init(bool forEncryption, ICipherParameters parameters) @@ -219,10 +217,6 @@ namespace Org.BouncyCastle.Crypto.Engines return 64; } - public void Reset() - { - } - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] private void ImplRounds(ref Vector128<byte> state) { diff --git a/crypto/src/crypto/engines/AesLightEngine.cs b/crypto/src/crypto/engines/AesLightEngine.cs index f34901fac..6ce714fde 100644 --- a/crypto/src/crypto/engines/AesLightEngine.cs +++ b/crypto/src/crypto/engines/AesLightEngine.cs @@ -362,11 +362,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "AES"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BLOCK_SIZE; @@ -425,10 +420,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private void EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output, uint[][] KW) { diff --git a/crypto/src/crypto/engines/AriaEngine.cs b/crypto/src/crypto/engines/AriaEngine.cs index 75af84320..c52fd30bf 100644 --- a/crypto/src/crypto/engines/AriaEngine.cs +++ b/crypto/src/crypto/engines/AriaEngine.cs @@ -157,11 +157,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "ARIA"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BlockSize; @@ -225,11 +220,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - // Empty - } - protected static void A(byte[] z) { byte x0 = z[0], x1 = z[1], x2 = z[2], x3 = z[3], x4 = z[4], x5 = z[5], x6 = z[6], x7 = z[7], x8 = z[8], diff --git a/crypto/src/crypto/engines/BlowfishEngine.cs b/crypto/src/crypto/engines/BlowfishEngine.cs index aa323581a..1152e3d78 100644 --- a/crypto/src/crypto/engines/BlowfishEngine.cs +++ b/crypto/src/crypto/engines/BlowfishEngine.cs @@ -342,11 +342,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "Blowfish"; } } - public bool IsPartialBlockOkay - { - get { return false; } - } - public int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) { if (workingKey == null) @@ -400,10 +395,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public void Reset() - { - } - public int GetBlockSize() { return BLOCK_SIZE; diff --git a/crypto/src/crypto/engines/CamelliaEngine.cs b/crypto/src/crypto/engines/CamelliaEngine.cs index 512448a27..80d15ad99 100644 --- a/crypto/src/crypto/engines/CamelliaEngine.cs +++ b/crypto/src/crypto/engines/CamelliaEngine.cs @@ -653,11 +653,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "Camellia"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BLOCK_SIZE; @@ -711,10 +706,5 @@ namespace Org.BouncyCastle.Crypto.Engines } } #endif - - public virtual void Reset() - { - // nothing - } } } diff --git a/crypto/src/crypto/engines/CamelliaLightEngine.cs b/crypto/src/crypto/engines/CamelliaLightEngine.cs index 03611f137..3111a8ddf 100644 --- a/crypto/src/crypto/engines/CamelliaLightEngine.cs +++ b/crypto/src/crypto/engines/CamelliaLightEngine.cs @@ -554,11 +554,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "Camellia"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BLOCK_SIZE; @@ -624,9 +619,5 @@ namespace Org.BouncyCastle.Crypto.Engines } } #endif - - public virtual void Reset() - { - } } } diff --git a/crypto/src/crypto/engines/Cast5Engine.cs b/crypto/src/crypto/engines/Cast5Engine.cs index 93288a237..c53c8909a 100644 --- a/crypto/src/crypto/engines/Cast5Engine.cs +++ b/crypto/src/crypto/engines/Cast5Engine.cs @@ -347,11 +347,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "CAST5"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) { if (_workingKey == null) @@ -403,10 +398,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - public virtual int GetBlockSize() { return BLOCK_SIZE; diff --git a/crypto/src/crypto/engines/Cast6Engine.cs b/crypto/src/crypto/engines/Cast6Engine.cs index c3f379fcf..b73398191 100644 --- a/crypto/src/crypto/engines/Cast6Engine.cs +++ b/crypto/src/crypto/engines/Cast6Engine.cs @@ -46,10 +46,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "CAST6"; } } - public override void Reset() - { - } - public override int GetBlockSize() { return BLOCK_SIZE; diff --git a/crypto/src/crypto/engines/DesEdeEngine.cs b/crypto/src/crypto/engines/DesEdeEngine.cs index ffb18d753..a9185d295 100644 --- a/crypto/src/crypto/engines/DesEdeEngine.cs +++ b/crypto/src/crypto/engines/DesEdeEngine.cs @@ -125,9 +125,5 @@ namespace Org.BouncyCastle.Crypto.Engines return BLOCK_SIZE; } #endif - - public override void Reset() - { - } } } diff --git a/crypto/src/crypto/engines/DesEngine.cs b/crypto/src/crypto/engines/DesEngine.cs index 25f559652..084fa1049 100644 --- a/crypto/src/crypto/engines/DesEngine.cs +++ b/crypto/src/crypto/engines/DesEngine.cs @@ -42,11 +42,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "DES"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BLOCK_SIZE; @@ -92,10 +87,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - /** * what follows is mainly taken from "Applied Cryptography", by * Bruce Schneier, however it also bears great resemblance to Richard diff --git a/crypto/src/crypto/engines/Dstu7624Engine.cs b/crypto/src/crypto/engines/Dstu7624Engine.cs index a0ff8ebd4..26c3ee586 100644 --- a/crypto/src/crypto/engines/Dstu7624Engine.cs +++ b/crypto/src/crypto/engines/Dstu7624Engine.cs @@ -292,6 +292,7 @@ namespace Org.BouncyCastle.Crypto.Engines } AddRoundKey(roundsAmount); Pack.UInt64_To_LE(internalState, output, outOff); + Array.Clear(internalState, 0, internalState.Length); break; } } @@ -327,6 +328,7 @@ namespace Org.BouncyCastle.Crypto.Engines } SubRoundKey(0); Pack.UInt64_To_LE(internalState, output, outOff); + Array.Clear(internalState, 0, internalState.Length); break; } } @@ -371,6 +373,7 @@ namespace Org.BouncyCastle.Crypto.Engines } AddRoundKey(roundsAmount); Pack.UInt64_To_LE(internalState, output); + Array.Clear(internalState, 0, internalState.Length); break; } } @@ -402,6 +405,7 @@ namespace Org.BouncyCastle.Crypto.Engines } SubRoundKey(0); Pack.UInt64_To_LE(internalState, output); + Array.Clear(internalState, 0, internalState.Length); break; } } @@ -1280,15 +1284,5 @@ namespace Org.BouncyCastle.Crypto.Engines { return wordsInBlock << 3; } - - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - - public virtual void Reset() - { - Array.Clear(internalState, 0, internalState.Length); - } } } diff --git a/crypto/src/crypto/engines/GOST28147Engine.cs b/crypto/src/crypto/engines/GOST28147Engine.cs index ee5a1ba53..ef566618f 100644 --- a/crypto/src/crypto/engines/GOST28147Engine.cs +++ b/crypto/src/crypto/engines/GOST28147Engine.cs @@ -189,11 +189,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "Gost28147"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BlockSize; @@ -231,10 +226,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - private int[] GenerateWorkingKey(bool forEncryption, byte[] userKey) { this.forEncryption = forEncryption; diff --git a/crypto/src/crypto/engines/IdeaEngine.cs b/crypto/src/crypto/engines/IdeaEngine.cs index c5d3eb36f..a61ba03ab 100644 --- a/crypto/src/crypto/engines/IdeaEngine.cs +++ b/crypto/src/crypto/engines/IdeaEngine.cs @@ -54,11 +54,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "IDEA"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BLOCK_SIZE; @@ -94,10 +89,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - private static readonly int MASK = 0xffff; private static readonly int BASE = 0x10001; diff --git a/crypto/src/crypto/engines/NoekeonEngine.cs b/crypto/src/crypto/engines/NoekeonEngine.cs index 2866d8d75..eca1ee04b 100644 --- a/crypto/src/crypto/engines/NoekeonEngine.cs +++ b/crypto/src/crypto/engines/NoekeonEngine.cs @@ -36,11 +36,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "Noekeon"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return Size; @@ -126,10 +121,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private int EncryptBlock(ReadOnlySpan<byte> input, Span<byte> output) { diff --git a/crypto/src/crypto/engines/NullEngine.cs b/crypto/src/crypto/engines/NullEngine.cs deleted file mode 100644 index b79cfba93..000000000 --- a/crypto/src/crypto/engines/NullEngine.cs +++ /dev/null @@ -1,80 +0,0 @@ -using System; - -using Org.BouncyCastle.Crypto.Parameters; - -namespace Org.BouncyCastle.Crypto.Engines -{ - /** - * The no-op engine that just copies bytes through, irrespective of whether encrypting and decrypting. - * Provided for the sake of completeness. - */ - public class NullEngine - : IBlockCipher - { - private bool initialised; - private const int BlockSize = 1; - - public NullEngine() - { - } - - public virtual void Init( - bool forEncryption, - ICipherParameters parameters) - { - // we don't mind any parameters that may come in - initialised = true; - } - - public virtual string AlgorithmName - { - get { return "Null"; } - } - - public virtual bool IsPartialBlockOkay - { - get { return true; } - } - - public virtual int GetBlockSize() - { - return BlockSize; - } - - public virtual int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) - { - if (!initialised) - throw new InvalidOperationException("Null engine not initialised"); - - Check.DataLength(input, inOff, BlockSize, "input buffer too short"); - Check.OutputLength(output, outOff, BlockSize, "output buffer too short"); - - for (int i = 0; i < BlockSize; ++i) - { - output[outOff + i] = input[inOff + i]; - } - - return BlockSize; - } - -#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER - public virtual int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output) - { - if (!initialised) - throw new InvalidOperationException("Null engine not initialised"); - - Check.DataLength(input, BlockSize, "input buffer too short"); - Check.OutputLength(output, BlockSize, "output buffer too short"); - - input[..BlockSize].CopyTo(output); - - return BlockSize; - } -#endif - - public virtual void Reset() - { - // nothing needs to be done - } - } -} diff --git a/crypto/src/crypto/engines/RC2Engine.cs b/crypto/src/crypto/engines/RC2Engine.cs index 7fe1cbc3b..42b29c9b0 100644 --- a/crypto/src/crypto/engines/RC2Engine.cs +++ b/crypto/src/crypto/engines/RC2Engine.cs @@ -140,20 +140,11 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public virtual void Reset() - { - } - public virtual string AlgorithmName { get { return "RC2"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BLOCK_SIZE; diff --git a/crypto/src/crypto/engines/RC532Engine.cs b/crypto/src/crypto/engines/RC532Engine.cs index aa3da5870..e3d0708a8 100644 --- a/crypto/src/crypto/engines/RC532Engine.cs +++ b/crypto/src/crypto/engines/RC532Engine.cs @@ -54,11 +54,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "RC5-32"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return 2 * 4; @@ -114,10 +109,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - /** * Re-key the cipher. * diff --git a/crypto/src/crypto/engines/RC564Engine.cs b/crypto/src/crypto/engines/RC564Engine.cs index 8d524f420..8dffc3f43 100644 --- a/crypto/src/crypto/engines/RC564Engine.cs +++ b/crypto/src/crypto/engines/RC564Engine.cs @@ -55,11 +55,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "RC5-64"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return 16; @@ -107,10 +102,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - /** * Re-key the cipher. * diff --git a/crypto/src/crypto/engines/RC6Engine.cs b/crypto/src/crypto/engines/RC6Engine.cs index 316bae65e..e6a3f8176 100644 --- a/crypto/src/crypto/engines/RC6Engine.cs +++ b/crypto/src/crypto/engines/RC6Engine.cs @@ -51,11 +51,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "RC6"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return 16; @@ -115,10 +110,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - /** * Re-key the cipher. * diff --git a/crypto/src/crypto/engines/RFC3211WrapEngine.cs b/crypto/src/crypto/engines/RFC3211WrapEngine.cs index 86480145c..3fc7b3191 100644 --- a/crypto/src/crypto/engines/RFC3211WrapEngine.cs +++ b/crypto/src/crypto/engines/RFC3211WrapEngine.cs @@ -53,7 +53,7 @@ namespace Org.BouncyCastle.Crypto.Engines public virtual string AlgorithmName { - get { return engine.GetUnderlyingCipher().AlgorithmName + "/RFC3211Wrap"; } + get { return engine.UnderlyingCipher.AlgorithmName + "/RFC3211Wrap"; } } public virtual byte[] Wrap( diff --git a/crypto/src/crypto/engines/RijndaelEngine.cs b/crypto/src/crypto/engines/RijndaelEngine.cs index 2bd404973..422664ce0 100644 --- a/crypto/src/crypto/engines/RijndaelEngine.cs +++ b/crypto/src/crypto/engines/RijndaelEngine.cs @@ -591,11 +591,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "Rijndael"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BC / 2; @@ -659,10 +654,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER private void UnPackBlock(ReadOnlySpan<byte> input) { diff --git a/crypto/src/crypto/engines/SEEDEngine.cs b/crypto/src/crypto/engines/SEEDEngine.cs index 6b511e4cc..07ffe06bb 100644 --- a/crypto/src/crypto/engines/SEEDEngine.cs +++ b/crypto/src/crypto/engines/SEEDEngine.cs @@ -181,11 +181,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "SEED"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BlockSize; @@ -269,10 +264,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - private int[] CreateWorkingKey(byte[] inKey) { if (inKey.Length != 16) diff --git a/crypto/src/crypto/engines/SM4Engine.cs b/crypto/src/crypto/engines/SM4Engine.cs index 6a7206a01..ddfc76e51 100644 --- a/crypto/src/crypto/engines/SM4Engine.cs +++ b/crypto/src/crypto/engines/SM4Engine.cs @@ -143,11 +143,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "SM4"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BlockSize; @@ -212,9 +207,5 @@ namespace Org.BouncyCastle.Crypto.Engines return BlockSize; } #endif - - public virtual void Reset() - { - } } } diff --git a/crypto/src/crypto/engines/SerpentEngineBase.cs b/crypto/src/crypto/engines/SerpentEngineBase.cs index 5d665fbbc..0ce3a0e4f 100644 --- a/crypto/src/crypto/engines/SerpentEngineBase.cs +++ b/crypto/src/crypto/engines/SerpentEngineBase.cs @@ -44,11 +44,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "Serpent"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BlockSize; @@ -120,10 +115,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - /* * The sboxes below are based on the work of Brian Gladman and * Sam Simpson, whose original notice appears below. diff --git a/crypto/src/crypto/engines/SkipjackEngine.cs b/crypto/src/crypto/engines/SkipjackEngine.cs index e78111abd..4a5355963 100644 --- a/crypto/src/crypto/engines/SkipjackEngine.cs +++ b/crypto/src/crypto/engines/SkipjackEngine.cs @@ -77,11 +77,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "SKIPJACK"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return BLOCK_SIZE; @@ -140,10 +135,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - /** * The G permutation */ diff --git a/crypto/src/crypto/engines/TEAEngine.cs b/crypto/src/crypto/engines/TEAEngine.cs index bb6ae6dcc..062fd7b7a 100644 --- a/crypto/src/crypto/engines/TEAEngine.cs +++ b/crypto/src/crypto/engines/TEAEngine.cs @@ -42,11 +42,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "TEA"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return block_size; @@ -108,10 +103,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - /** * Re-key the cipher. * diff --git a/crypto/src/crypto/engines/ThreefishEngine.cs b/crypto/src/crypto/engines/ThreefishEngine.cs index c22691fc2..d1adb2e61 100644 --- a/crypto/src/crypto/engines/ThreefishEngine.cs +++ b/crypto/src/crypto/engines/ThreefishEngine.cs @@ -269,20 +269,11 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "Threefish-" + (blocksizeBytes * 8); } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return blocksizeBytes; } - public virtual void Reset() - { - } - public virtual int ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff) { Check.DataLength(inBytes, inOff, blocksizeBytes, "input buffer too short"); diff --git a/crypto/src/crypto/engines/TwofishEngine.cs b/crypto/src/crypto/engines/TwofishEngine.cs index cb3e35b0a..09c7114f2 100644 --- a/crypto/src/crypto/engines/TwofishEngine.cs +++ b/crypto/src/crypto/engines/TwofishEngine.cs @@ -294,11 +294,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "Twofish"; } } - public bool IsPartialBlockOkay - { - get { return false; } - } - public int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) { if (workingKey == null) @@ -352,14 +347,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public void Reset() - { - if (this.workingKey != null) - { - SetKey(this.workingKey); - } - } - public int GetBlockSize() { return BLOCK_SIZE; diff --git a/crypto/src/crypto/engines/XTEAEngine.cs b/crypto/src/crypto/engines/XTEAEngine.cs index e70498a5f..0f028e9dd 100644 --- a/crypto/src/crypto/engines/XTEAEngine.cs +++ b/crypto/src/crypto/engines/XTEAEngine.cs @@ -40,11 +40,6 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "XTEA"; } } - public virtual bool IsPartialBlockOkay - { - get { return false; } - } - public virtual int GetBlockSize() { return block_size; @@ -110,10 +105,6 @@ namespace Org.BouncyCastle.Crypto.Engines } #endif - public virtual void Reset() - { - } - /** * Re-key the cipher. * diff --git a/crypto/src/crypto/macs/CMac.cs b/crypto/src/crypto/macs/CMac.cs index 342dbd93d..dd4281f8f 100644 --- a/crypto/src/crypto/macs/CMac.cs +++ b/crypto/src/crypto/macs/CMac.cs @@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Crypto.Macs private byte[] buf; private int bufOff; - private IBlockCipher cipher; + private IBlockCipherMode m_cipherMode; private int macSize; @@ -88,7 +88,7 @@ namespace Org.BouncyCastle.Crypto.Macs "Block size must be either 64 or 128 bits"); } - this.cipher = new CbcBlockCipher(cipher); + m_cipherMode = new CbcBlockCipher(cipher); this.macSize = macSizeInBits / 8; mac = new byte[cipher.GetBlockSize()]; @@ -102,7 +102,7 @@ namespace Org.BouncyCastle.Crypto.Macs public string AlgorithmName { - get { return cipher.AlgorithmName; } + get { return m_cipherMode.AlgorithmName; } } private static int ShiftLeft(byte[] block, byte[] output) @@ -136,11 +136,11 @@ namespace Org.BouncyCastle.Crypto.Macs { if (parameters is KeyParameter) { - cipher.Init(true, parameters); + m_cipherMode.Init(true, parameters); //initializes the L, Lu, Lu2 numbers L = new byte[ZEROES.Length]; - cipher.ProcessBlock(ZEROES, 0, L, 0); + m_cipherMode.ProcessBlock(ZEROES, 0, L, 0); Lu = DoubleLu(L); Lu2 = DoubleLu(Lu); } @@ -162,7 +162,7 @@ namespace Org.BouncyCastle.Crypto.Macs { if (bufOff == buf.Length) { - cipher.ProcessBlock(buf, 0, mac, 0); + m_cipherMode.ProcessBlock(buf, 0, mac, 0); bufOff = 0; } @@ -177,14 +177,14 @@ namespace Org.BouncyCastle.Crypto.Macs #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER BlockUpdate(inBytes.AsSpan(inOff, len)); #else - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); int gapLen = blockSize - bufOff; if (len > gapLen) { Array.Copy(inBytes, inOff, buf, bufOff, gapLen); - cipher.ProcessBlock(buf, 0, mac, 0); + m_cipherMode.ProcessBlock(buf, 0, mac, 0); bufOff = 0; len -= gapLen; @@ -192,7 +192,7 @@ namespace Org.BouncyCastle.Crypto.Macs while (len > blockSize) { - cipher.ProcessBlock(inBytes, inOff, mac, 0); + m_cipherMode.ProcessBlock(inBytes, inOff, mac, 0); len -= blockSize; inOff += blockSize; @@ -208,21 +208,21 @@ namespace Org.BouncyCastle.Crypto.Macs #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public void BlockUpdate(ReadOnlySpan<byte> input) { - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); int gapLen = blockSize - bufOff; if (input.Length > gapLen) { input[..gapLen].CopyTo(buf.AsSpan(bufOff)); - cipher.ProcessBlock(buf, mac); + m_cipherMode.ProcessBlock(buf, mac); bufOff = 0; input = input[gapLen..]; while (input.Length > blockSize) { - cipher.ProcessBlock(input, mac); + m_cipherMode.ProcessBlock(input, mac); input = input[blockSize..]; } } @@ -238,7 +238,7 @@ namespace Org.BouncyCastle.Crypto.Macs #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER return DoFinal(outBytes.AsSpan(outOff)); #else - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); byte[] lu; if (bufOff == blockSize) @@ -256,7 +256,7 @@ namespace Org.BouncyCastle.Crypto.Macs buf[i] ^= lu[i]; } - cipher.ProcessBlock(buf, 0, mac, 0); + m_cipherMode.ProcessBlock(buf, 0, mac, 0); Array.Copy(mac, 0, outBytes, outOff, macSize); @@ -269,7 +269,7 @@ namespace Org.BouncyCastle.Crypto.Macs #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public int DoFinal(Span<byte> output) { - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); byte[] lu; if (bufOff == blockSize) @@ -287,7 +287,7 @@ namespace Org.BouncyCastle.Crypto.Macs buf[i] ^= lu[i]; } - cipher.ProcessBlock(buf, mac); + m_cipherMode.ProcessBlock(buf, mac); mac.AsSpan(0, macSize).CopyTo(output); @@ -311,7 +311,7 @@ namespace Org.BouncyCastle.Crypto.Macs /* * Reset the underlying cipher. */ - cipher.Reset(); + m_cipherMode.Reset(); } } } diff --git a/crypto/src/crypto/macs/CbcBlockCipherMac.cs b/crypto/src/crypto/macs/CbcBlockCipherMac.cs index abf06170c..c660c0dc3 100644 --- a/crypto/src/crypto/macs/CbcBlockCipherMac.cs +++ b/crypto/src/crypto/macs/CbcBlockCipherMac.cs @@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Crypto.Macs { private byte[] buf; private int bufOff; - private IBlockCipher cipher; + private IBlockCipherMode m_cipherMode; private IBlockCipherPadding padding; private int macSize; @@ -86,7 +86,7 @@ namespace Org.BouncyCastle.Crypto.Macs if ((macSizeInBits % 8) != 0) throw new ArgumentException("MAC size must be multiple of 8"); - this.cipher = new CbcBlockCipher(cipher); + this.m_cipherMode = new CbcBlockCipher(cipher); this.padding = padding; this.macSize = macSizeInBits / 8; @@ -96,14 +96,14 @@ namespace Org.BouncyCastle.Crypto.Macs public string AlgorithmName { - get { return cipher.AlgorithmName; } + get { return m_cipherMode.AlgorithmName; } } public void Init(ICipherParameters parameters) { Reset(); - cipher.Init(true, parameters); + m_cipherMode.Init(true, parameters); } public int GetMacSize() @@ -115,7 +115,7 @@ namespace Org.BouncyCastle.Crypto.Macs { if (bufOff == buf.Length) { - cipher.ProcessBlock(buf, 0, buf, 0); + m_cipherMode.ProcessBlock(buf, 0, buf, 0); bufOff = 0; } @@ -130,14 +130,14 @@ namespace Org.BouncyCastle.Crypto.Macs #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER BlockUpdate(input.AsSpan(inOff, len)); #else - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); int gapLen = blockSize - bufOff; if (len > gapLen) { Array.Copy(input, inOff, buf, bufOff, gapLen); - cipher.ProcessBlock(buf, 0, buf, 0); + m_cipherMode.ProcessBlock(buf, 0, buf, 0); bufOff = 0; len -= gapLen; @@ -145,7 +145,7 @@ namespace Org.BouncyCastle.Crypto.Macs while (len > blockSize) { - cipher.ProcessBlock(input, inOff, buf, 0); + m_cipherMode.ProcessBlock(input, inOff, buf, 0); len -= blockSize; inOff += blockSize; @@ -161,21 +161,21 @@ namespace Org.BouncyCastle.Crypto.Macs #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public void BlockUpdate(ReadOnlySpan<byte> input) { - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); int gapLen = blockSize - bufOff; if (input.Length > gapLen) { input[..gapLen].CopyTo(buf.AsSpan(bufOff)); - cipher.ProcessBlock(buf, buf); + m_cipherMode.ProcessBlock(buf, buf); bufOff = 0; input = input[gapLen..]; while (input.Length > blockSize) { - cipher.ProcessBlock(input, buf); + m_cipherMode.ProcessBlock(input, buf); input = input[blockSize..]; } } @@ -191,7 +191,7 @@ namespace Org.BouncyCastle.Crypto.Macs #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER return DoFinal(output.AsSpan(outOff)); #else - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); if (padding == null) { @@ -205,14 +205,14 @@ namespace Org.BouncyCastle.Crypto.Macs { if (bufOff == blockSize) { - cipher.ProcessBlock(buf, 0, buf, 0); + m_cipherMode.ProcessBlock(buf, 0, buf, 0); bufOff = 0; } padding.AddPadding(buf, bufOff); } - cipher.ProcessBlock(buf, 0, buf, 0); + m_cipherMode.ProcessBlock(buf, 0, buf, 0); Array.Copy(buf, 0, output, outOff, macSize); @@ -225,7 +225,7 @@ namespace Org.BouncyCastle.Crypto.Macs #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public int DoFinal(Span<byte> output) { - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); if (padding == null) { @@ -239,14 +239,14 @@ namespace Org.BouncyCastle.Crypto.Macs { if (bufOff == blockSize) { - cipher.ProcessBlock(buf, buf); + m_cipherMode.ProcessBlock(buf, buf); bufOff = 0; } padding.AddPadding(buf, bufOff); } - cipher.ProcessBlock(buf, buf); + m_cipherMode.ProcessBlock(buf, buf); buf.AsSpan(0, macSize).CopyTo(output); @@ -265,8 +265,8 @@ namespace Org.BouncyCastle.Crypto.Macs Array.Clear(buf, 0, buf.Length); bufOff = 0; - // Reset the underlying cipher. - cipher.Reset(); + // Reset the underlying cipher. + m_cipherMode.Reset(); } } } diff --git a/crypto/src/crypto/macs/CfbBlockCipherMac.cs b/crypto/src/crypto/macs/CfbBlockCipherMac.cs index a4d005700..8f3f89993 100644 --- a/crypto/src/crypto/macs/CfbBlockCipherMac.cs +++ b/crypto/src/crypto/macs/CfbBlockCipherMac.cs @@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Crypto.Macs * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher. */ internal class MacCfbBlockCipher - : IBlockCipher + : IBlockCipherMode { private byte[] IV; private byte[] cfbV; @@ -81,7 +81,9 @@ namespace Org.BouncyCastle.Crypto.Macs get { return cipher.AlgorithmName + "/CFB" + (blockSize * 8); } } - public bool IsPartialBlockOkay + public IBlockCipher UnderlyingCipher => cipher; + + public bool IsPartialBlockOkay { get { return true; } } @@ -153,8 +155,6 @@ namespace Org.BouncyCastle.Crypto.Macs public void Reset() { IV.CopyTo(cfbV, 0); - - cipher.Reset(); } public void GetMacBlock( diff --git a/crypto/src/crypto/macs/DSTU7624Mac.cs b/crypto/src/crypto/macs/DSTU7624Mac.cs index 8fecb1915..f96bdec98 100644 --- a/crypto/src/crypto/macs/DSTU7624Mac.cs +++ b/crypto/src/crypto/macs/DSTU7624Mac.cs @@ -214,7 +214,6 @@ namespace Org.BouncyCastle.Crypto.Macs Arrays.Fill(cTemp, (byte)0x00); Arrays.Fill(kDelta, (byte)0x00); Arrays.Fill(buf, (byte)0x00); - engine.Reset(); engine.ProcessBlock(kDelta, 0, kDelta, 0); bufOff = 0; } diff --git a/crypto/src/crypto/macs/ISO9797Alg3Mac.cs b/crypto/src/crypto/macs/ISO9797Alg3Mac.cs index 40a68007e..1b9562bda 100644 --- a/crypto/src/crypto/macs/ISO9797Alg3Mac.cs +++ b/crypto/src/crypto/macs/ISO9797Alg3Mac.cs @@ -13,7 +13,8 @@ namespace Org.BouncyCastle.Crypto.Macs * This could as well be derived from CBCBlockCipherMac, but then the property mac in the base * class must be changed to protected */ - public class ISO9797Alg3Mac : IMac + public class ISO9797Alg3Mac + : IMac { private byte[] mac; private byte[] buf; @@ -343,9 +344,6 @@ namespace Org.BouncyCastle.Crypto.Macs { Array.Clear(buf, 0, buf.Length); bufOff = 0; - - // reset the underlying cipher. - cipher.Reset(); } } } diff --git a/crypto/src/crypto/modes/CbcBlockCipher.cs b/crypto/src/crypto/modes/CbcBlockCipher.cs index eb89c81ee..2a2db2437 100644 --- a/crypto/src/crypto/modes/CbcBlockCipher.cs +++ b/crypto/src/crypto/modes/CbcBlockCipher.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Crypto.Modes * implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher. */ public class CbcBlockCipher - : IBlockCipher + : IBlockCipherMode { private byte[] IV, cbcV, cbcNextV; private int blockSize; @@ -36,10 +36,7 @@ namespace Org.BouncyCastle.Crypto.Modes * * @return the underlying block cipher that we are wrapping. */ - public IBlockCipher GetUnderlyingCipher() - { - return cipher; - } + public IBlockCipher UnderlyingCipher => cipher; /** * Initialise the cipher and, possibly, the initialisation vector (IV). @@ -139,8 +136,6 @@ namespace Org.BouncyCastle.Crypto.Modes { Array.Copy(IV, 0, cbcV, 0, IV.Length); Array.Clear(cbcNextV, 0, cbcNextV.Length); - - cipher.Reset(); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER diff --git a/crypto/src/crypto/modes/CcmBlockCipher.cs b/crypto/src/crypto/modes/CcmBlockCipher.cs index 0a2adb57d..fdd664a32 100644 --- a/crypto/src/crypto/modes/CcmBlockCipher.cs +++ b/crypto/src/crypto/modes/CcmBlockCipher.cs @@ -191,7 +191,6 @@ namespace Org.BouncyCastle.Crypto.Modes public virtual void Reset() { - cipher.Reset(); associatedText.SetLength(0); data.SetLength(0); } diff --git a/crypto/src/crypto/modes/CfbBlockCipher.cs b/crypto/src/crypto/modes/CfbBlockCipher.cs index bcbffcfb6..abcdca959 100644 --- a/crypto/src/crypto/modes/CfbBlockCipher.cs +++ b/crypto/src/crypto/modes/CfbBlockCipher.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Crypto.Modes * implements a Cipher-FeedBack (CFB) mode on top of a simple cipher. */ public class CfbBlockCipher - : IBlockCipher + : IBlockCipherMode { private byte[] IV; private byte[] cfbV; @@ -43,10 +43,8 @@ namespace Org.BouncyCastle.Crypto.Modes * * @return the underlying block cipher that we are wrapping. */ - public IBlockCipher GetUnderlyingCipher() - { - return cipher; - } + public IBlockCipher UnderlyingCipher => 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. @@ -223,7 +221,6 @@ namespace Org.BouncyCastle.Crypto.Modes public void Reset() { Array.Copy(IV, 0, cfbV, 0, IV.Length); - cipher.Reset(); } } } diff --git a/crypto/src/crypto/modes/CtsBlockCipher.cs b/crypto/src/crypto/modes/CtsBlockCipher.cs index 5a1682568..022e86675 100644 --- a/crypto/src/crypto/modes/CtsBlockCipher.cs +++ b/crypto/src/crypto/modes/CtsBlockCipher.cs @@ -12,21 +12,24 @@ namespace Org.BouncyCastle.Crypto.Modes { private readonly int blockSize; + public CtsBlockCipher(IBlockCipher cipher) + : this(EcbBlockCipher.GetBlockCipherMode(cipher)) + { + } + /** * Create a buffered block cipher that uses Cipher Text Stealing * * @param cipher the underlying block cipher this buffering object wraps. */ - public CtsBlockCipher( - IBlockCipher cipher) + public CtsBlockCipher(IBlockCipherMode cipherMode) { - // TODO Should this test for acceptable ones instead? - if (cipher is OfbBlockCipher || cipher is CfbBlockCipher) + if (!(cipherMode is CbcBlockCipher || cipherMode is EcbBlockCipher)) throw new ArgumentException("CtsBlockCipher can only accept ECB, or CBC ciphers"); - this.cipher = cipher; + m_cipherMode = cipherMode; - blockSize = cipher.GetBlockSize(); + blockSize = cipherMode.GetBlockSize(); buf = new byte[blockSize * 2]; bufOff = 0; @@ -83,7 +86,7 @@ namespace Org.BouncyCastle.Crypto.Modes if (bufOff == buf.Length) { - resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + resultLen = m_cipherMode.ProcessBlock(buf, 0, output, outOff); Debug.Assert(resultLen == blockSize); Array.Copy(buf, blockSize, buf, 0, blockSize); @@ -102,7 +105,7 @@ namespace Org.BouncyCastle.Crypto.Modes if (bufOff == buf.Length) { - resultLen = cipher.ProcessBlock(buf, output); + resultLen = m_cipherMode.ProcessBlock(buf, output); Debug.Assert(resultLen == blockSize); Array.Copy(buf, blockSize, buf, 0, blockSize); @@ -147,7 +150,7 @@ namespace Org.BouncyCastle.Crypto.Modes { Array.Copy(input, inOff, buf, bufOff, gapLen); - resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + resultLen = m_cipherMode.ProcessBlock(buf, 0, output, outOff); Array.Copy(buf, blockSize, buf, 0, blockSize); bufOff = blockSize; @@ -158,7 +161,7 @@ namespace Org.BouncyCastle.Crypto.Modes while (length > blockSize) { Array.Copy(input, inOff, buf, bufOff, blockSize); - resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); + resultLen += m_cipherMode.ProcessBlock(buf, 0, output, outOff + resultLen); Array.Copy(buf, blockSize, buf, 0, blockSize); length -= blockSize; @@ -191,7 +194,7 @@ namespace Org.BouncyCastle.Crypto.Modes { input[..gapLen].CopyTo(buf.AsSpan(bufOff)); - resultLen = cipher.ProcessBlock(buf, output); + resultLen = m_cipherMode.ProcessBlock(buf, output); Array.Copy(buf, blockSize, buf, 0, blockSize); bufOff = blockSize; @@ -201,7 +204,7 @@ namespace Org.BouncyCastle.Crypto.Modes while (input.Length > blockSize) { input[..blockSize].CopyTo(buf.AsSpan(bufOff)); - resultLen += cipher.ProcessBlock(buf, output[resultLen..]); + resultLen += m_cipherMode.ProcessBlock(buf, output[resultLen..]); Array.Copy(buf, blockSize, buf, 0, blockSize); input = input[blockSize..]; @@ -234,13 +237,13 @@ namespace Org.BouncyCastle.Crypto.Modes if (bufOff + outOff > output.Length) throw new DataLengthException("output buffer too small in DoFinal"); - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); int length = bufOff - blockSize; byte[] block = new byte[blockSize]; if (forEncryption) { - cipher.ProcessBlock(buf, 0, block, 0); + m_cipherMode.ProcessBlock(buf, 0, block, 0); if (bufOff < blockSize) throw new DataLengthException("need at least one block of input for CTS"); @@ -255,11 +258,7 @@ namespace Org.BouncyCastle.Crypto.Modes buf[i] ^= block[i - blockSize]; } - IBlockCipher c = (cipher is CbcBlockCipher) - ? ((CbcBlockCipher)cipher).GetUnderlyingCipher() - : cipher; - - c.ProcessBlock(buf, blockSize, output, outOff); + m_cipherMode.UnderlyingCipher.ProcessBlock(buf, blockSize, output, outOff); Array.Copy(block, 0, output, outOff + blockSize, length); } @@ -267,11 +266,7 @@ namespace Org.BouncyCastle.Crypto.Modes { byte[] lastBlock = new byte[blockSize]; - IBlockCipher c = (cipher is CbcBlockCipher) - ? ((CbcBlockCipher)cipher).GetUnderlyingCipher() - : cipher; - - c.ProcessBlock(buf, 0, block, 0); + m_cipherMode.UnderlyingCipher.ProcessBlock(buf, 0, block, 0); for (int i = blockSize; i != bufOff; i++) { @@ -280,7 +275,7 @@ namespace Org.BouncyCastle.Crypto.Modes Array.Copy(buf, blockSize, block, 0, length); - cipher.ProcessBlock(block, 0, output, outOff); + m_cipherMode.ProcessBlock(block, 0, output, outOff); Array.Copy(lastBlock, 0, output, outOff + blockSize, length); } @@ -297,13 +292,13 @@ namespace Org.BouncyCastle.Crypto.Modes if (bufOff > output.Length) throw new DataLengthException("output buffer too small in DoFinal"); - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); int length = bufOff - blockSize; Span<byte> block = stackalloc byte[blockSize]; if (forEncryption) { - cipher.ProcessBlock(buf, block); + m_cipherMode.ProcessBlock(buf, block); if (bufOff < blockSize) throw new DataLengthException("need at least one block of input for CTS"); @@ -318,11 +313,7 @@ namespace Org.BouncyCastle.Crypto.Modes buf[i] ^= block[i - blockSize]; } - IBlockCipher c = (cipher is CbcBlockCipher) - ? ((CbcBlockCipher)cipher).GetUnderlyingCipher() - : cipher; - - c.ProcessBlock(buf.AsSpan(blockSize), output); + m_cipherMode.UnderlyingCipher.ProcessBlock(buf.AsSpan(blockSize), output); block[..length].CopyTo(output[blockSize..]); } @@ -330,11 +321,7 @@ namespace Org.BouncyCastle.Crypto.Modes { Span<byte> lastBlock = stackalloc byte[blockSize]; - IBlockCipher c = (cipher is CbcBlockCipher) - ? ((CbcBlockCipher)cipher).GetUnderlyingCipher() - : cipher; - - c.ProcessBlock(buf, block); + m_cipherMode.UnderlyingCipher.ProcessBlock(buf, block); for (int i = blockSize; i != bufOff; i++) { @@ -343,7 +330,7 @@ namespace Org.BouncyCastle.Crypto.Modes buf.AsSpan(blockSize, length).CopyTo(block); - cipher.ProcessBlock(block, output); + m_cipherMode.ProcessBlock(block, output); lastBlock[..length].CopyTo(output[blockSize..]); } diff --git a/crypto/src/crypto/modes/EAXBlockCipher.cs b/crypto/src/crypto/modes/EAXBlockCipher.cs index e63826159..acf33ccb7 100644 --- a/crypto/src/crypto/modes/EAXBlockCipher.cs +++ b/crypto/src/crypto/modes/EAXBlockCipher.cs @@ -61,7 +61,7 @@ namespace Org.BouncyCastle.Crypto.Modes public virtual string AlgorithmName { - get { return cipher.GetUnderlyingCipher().AlgorithmName + "/EAX"; } + get { return cipher.UnderlyingCipher.AlgorithmName + "/EAX"; } } public virtual IBlockCipher GetUnderlyingCipher() diff --git a/crypto/src/crypto/modes/EcbBlockCipher.cs b/crypto/src/crypto/modes/EcbBlockCipher.cs new file mode 100644 index 000000000..96f9811dd --- /dev/null +++ b/crypto/src/crypto/modes/EcbBlockCipher.cs @@ -0,0 +1,58 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Modes +{ + public class EcbBlockCipher + : IBlockCipherMode + { + internal static IBlockCipherMode GetBlockCipherMode(IBlockCipher blockCipher) + { + if (blockCipher is IBlockCipherMode blockCipherMode) + return blockCipherMode; + + return new EcbBlockCipher(blockCipher); + } + + private readonly IBlockCipher m_cipher; + + public EcbBlockCipher(IBlockCipher cipher) + { + if (cipher == null) + throw new ArgumentNullException(nameof(cipher)); + + m_cipher = cipher; + } + + public bool IsPartialBlockOkay => false; + + public string AlgorithmName => m_cipher.AlgorithmName + "/ECB"; + + public int GetBlockSize() + { + return m_cipher.GetBlockSize(); + } + + public IBlockCipher UnderlyingCipher => m_cipher; + + public void Init(bool forEncryption, ICipherParameters parameters) + { + m_cipher.Init(forEncryption, parameters); + } + + public int ProcessBlock(byte[] inBuf, int inOff, byte[] outBuf, int outOff) + { + return m_cipher.ProcessBlock(inBuf, inOff, outBuf, outOff); + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + public int ProcessBlock(ReadOnlySpan<byte> input, Span<byte> output) + { + return m_cipher.ProcessBlock(input, output); + } +#endif + + public void Reset() + { + } + } +} diff --git a/crypto/src/crypto/modes/GCMBlockCipher.cs b/crypto/src/crypto/modes/GCMBlockCipher.cs index 2ab406fc3..58e83c257 100644 --- a/crypto/src/crypto/modes/GCMBlockCipher.cs +++ b/crypto/src/crypto/modes/GCMBlockCipher.cs @@ -867,11 +867,8 @@ namespace Org.BouncyCastle.Crypto.Modes Reset(true); } - private void Reset( - bool clearMac) + private void Reset(bool clearMac) { - cipher.Reset(); - // note: we do not reset the nonce. S = new byte[BlockSize]; diff --git a/crypto/src/crypto/modes/GOFBBlockCipher.cs b/crypto/src/crypto/modes/GOFBBlockCipher.cs index 4c8576a58..cfcbe4fcd 100644 --- a/crypto/src/crypto/modes/GOFBBlockCipher.cs +++ b/crypto/src/crypto/modes/GOFBBlockCipher.cs @@ -9,8 +9,8 @@ namespace Org.BouncyCastle.Crypto.Modes * implements the GOST 28147 OFB counter mode (GCTR). */ public class GOfbBlockCipher - : IBlockCipher - { + : IBlockCipherMode + { private byte[] IV; private byte[] ofbV; private byte[] ofbOutV; @@ -46,15 +46,12 @@ namespace Org.BouncyCastle.Crypto.Modes this.ofbOutV = new byte[cipher.GetBlockSize()]; } - /** + /** * return the underlying block cipher that we are wrapping. * * @return the underlying block cipher that we are wrapping. */ - public IBlockCipher GetUnderlyingCipher() - { - return cipher; - } + public IBlockCipher UnderlyingCipher => cipher; /** * Initialise the cipher and, possibly, the initialisation vector (IV). @@ -228,8 +225,6 @@ namespace Org.BouncyCastle.Crypto.Modes public void Reset() { Array.Copy(IV, 0, ofbV, 0, IV.Length); - - cipher.Reset(); } } } diff --git a/crypto/src/crypto/modes/IBlockCipherMode.cs b/crypto/src/crypto/modes/IBlockCipherMode.cs new file mode 100644 index 000000000..f6e3991c6 --- /dev/null +++ b/crypto/src/crypto/modes/IBlockCipherMode.cs @@ -0,0 +1,19 @@ +using System; + +namespace Org.BouncyCastle.Crypto.Modes +{ + public interface IBlockCipherMode + : IBlockCipher + { + /// <summary>Return the <code cref="IBlockCipher"/> underlying this cipher mode.</summary> + IBlockCipher UnderlyingCipher { get; } + + /// <summary>Indicates whether this cipher mode can handle partial blocks.</summary> + bool IsPartialBlockOkay { get; } + + /// <summary> + /// Reset the cipher mode to the same state as it was after the last init (if there was one). + /// </summary> + void Reset(); + } +} diff --git a/crypto/src/crypto/modes/KCtrBlockCipher.cs b/crypto/src/crypto/modes/KCtrBlockCipher.cs index 79b74f84c..b0c4054e0 100644 --- a/crypto/src/crypto/modes/KCtrBlockCipher.cs +++ b/crypto/src/crypto/modes/KCtrBlockCipher.cs @@ -7,7 +7,8 @@ namespace Org.BouncyCastle.Crypto.Modes /** * Implements a Gamming or Counter (CTR) mode on top of a DSTU 7624 block cipher. */ - public class KCtrBlockCipher : IStreamCipher, IBlockCipher + public class KCtrBlockCipher + : IStreamCipher, IBlockCipherMode { private byte[] IV; private byte[] ofbV; @@ -40,10 +41,8 @@ namespace Org.BouncyCastle.Crypto.Modes * * @return the underlying block cipher that we are wrapping. */ - public IBlockCipher GetUnderlyingCipher() - { - return cipher; - } + public IBlockCipher UnderlyingCipher => 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. @@ -213,7 +212,6 @@ namespace Org.BouncyCastle.Crypto.Modes { cipher.ProcessBlock(IV, 0, ofbV, 0); } - cipher.Reset(); byteCount = 0; } diff --git a/crypto/src/crypto/modes/OCBBlockCipher.cs b/crypto/src/crypto/modes/OCBBlockCipher.cs index a4eaa08bd..ee327f200 100644 --- a/crypto/src/crypto/modes/OCBBlockCipher.cs +++ b/crypto/src/crypto/modes/OCBBlockCipher.cs @@ -643,9 +643,6 @@ namespace Org.BouncyCastle.Crypto.Modes protected virtual void Reset(bool clearMac) { - hashCipher.Reset(); - mainCipher.Reset(); - Clear(hashBlock); Clear(mainBlock); diff --git a/crypto/src/crypto/modes/OfbBlockCipher.cs b/crypto/src/crypto/modes/OfbBlockCipher.cs index ac9b9a06c..9bf4c25c7 100644 --- a/crypto/src/crypto/modes/OfbBlockCipher.cs +++ b/crypto/src/crypto/modes/OfbBlockCipher.cs @@ -8,7 +8,7 @@ namespace Org.BouncyCastle.Crypto.Modes * implements a Output-FeedBack (OFB) mode on top of a simple cipher. */ public class OfbBlockCipher - : IBlockCipher + : IBlockCipherMode { private byte[] IV; private byte[] ofbV; @@ -41,10 +41,7 @@ namespace Org.BouncyCastle.Crypto.Modes * * @return the underlying block cipher that we are wrapping. */ - public IBlockCipher GetUnderlyingCipher() - { - return cipher; - } + public IBlockCipher UnderlyingCipher => cipher; /** * Initialise the cipher and, possibly, the initialisation vector (IV). @@ -176,9 +173,6 @@ namespace Org.BouncyCastle.Crypto.Modes public void Reset() { Array.Copy(IV, 0, ofbV, 0, IV.Length); - - cipher.Reset(); } } - } diff --git a/crypto/src/crypto/modes/OpenPgpCfbBlockCipher.cs b/crypto/src/crypto/modes/OpenPgpCfbBlockCipher.cs index 45998248c..4e6e0ffaa 100644 --- a/crypto/src/crypto/modes/OpenPgpCfbBlockCipher.cs +++ b/crypto/src/crypto/modes/OpenPgpCfbBlockCipher.cs @@ -14,7 +14,7 @@ namespace Org.BouncyCastle.Crypto.Modes * </p> */ public class OpenPgpCfbBlockCipher - : IBlockCipher + : IBlockCipherMode { private byte[] IV; private byte[] FR; @@ -43,15 +43,12 @@ namespace Org.BouncyCastle.Crypto.Modes this.FRE = new byte[blockSize]; } - /** + /** * return the underlying block cipher that we are wrapping. * * @return the underlying block cipher that we are wrapping. */ - public IBlockCipher GetUnderlyingCipher() - { - return cipher; - } + public IBlockCipher UnderlyingCipher => cipher; /** * return the algorithm name and mode. @@ -110,8 +107,6 @@ namespace Org.BouncyCastle.Crypto.Modes count = 0; Array.Copy(IV, 0, FR, 0, FR.Length); - - cipher.Reset(); } /** diff --git a/crypto/src/crypto/modes/SicBlockCipher.cs b/crypto/src/crypto/modes/SicBlockCipher.cs index 431e2952c..fee8bb028 100644 --- a/crypto/src/crypto/modes/SicBlockCipher.cs +++ b/crypto/src/crypto/modes/SicBlockCipher.cs @@ -12,7 +12,7 @@ namespace Org.BouncyCastle.Crypto.Modes * block cipher. */ public class SicBlockCipher - : IBlockCipher + : IBlockCipherMode { private readonly IBlockCipher cipher; private readonly int blockSize; @@ -39,10 +39,7 @@ namespace Org.BouncyCastle.Crypto.Modes * * @return the underlying block cipher that we are wrapping. */ - public virtual IBlockCipher GetUnderlyingCipher() - { - return cipher; - } + public IBlockCipher UnderlyingCipher => cipher; public virtual void Init( bool forEncryption, //ignored by this CTR mode @@ -133,7 +130,6 @@ namespace Org.BouncyCastle.Crypto.Modes { Arrays.Fill(counter, (byte)0); Array.Copy(IV, 0, counter, 0, IV.Length); - cipher.Reset(); } } } diff --git a/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs b/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs index a2d4dcc32..fb000ff8b 100644 --- a/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs +++ b/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs @@ -1,5 +1,6 @@ using System; +using Org.BouncyCastle.Crypto.Modes; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; @@ -15,22 +16,25 @@ namespace Org.BouncyCastle.Crypto.Paddings public class PaddedBufferedBlockCipher : BufferedBlockCipher { - private readonly IBlockCipherPadding padding; + private readonly IBlockCipherPadding padding; - /** + public PaddedBufferedBlockCipher(IBlockCipher cipher, IBlockCipherPadding padding) + : this(EcbBlockCipher.GetBlockCipherMode(cipher), padding) + { + } + + /** * Create a buffered block cipher with the desired padding. * * @param cipher the underlying block cipher this buffering object wraps. * @param padding the padding type. */ - public PaddedBufferedBlockCipher( - IBlockCipher cipher, - IBlockCipherPadding padding) + public PaddedBufferedBlockCipher(IBlockCipherMode cipherMode, IBlockCipherPadding padding) { - this.cipher = cipher; + m_cipherMode = cipherMode; this.padding = padding; - buf = new byte[cipher.GetBlockSize()]; + buf = new byte[m_cipherMode.GetBlockSize()]; bufOff = 0; } @@ -39,9 +43,8 @@ namespace Org.BouncyCastle.Crypto.Paddings * * @param cipher the underlying block cipher this buffering object wraps. */ - public PaddedBufferedBlockCipher( - IBlockCipher cipher) - : this(cipher, new Pkcs7Padding()) + public PaddedBufferedBlockCipher(IBlockCipherMode cipherMode) + : this(cipherMode, new Pkcs7Padding()) { } @@ -54,23 +57,20 @@ namespace Org.BouncyCastle.Crypto.Paddings * @exception ArgumentException if the parameters argument is * inappropriate. */ - public override void Init( - bool forEncryption, - ICipherParameters parameters) + public override void Init(bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; SecureRandom initRandom = null; - if (parameters is ParametersWithRandom) + if (parameters is ParametersWithRandom withRandom) { - ParametersWithRandom p = (ParametersWithRandom)parameters; - initRandom = p.Random; - parameters = p.Parameters; + initRandom = withRandom.Random; + parameters = withRandom.Parameters; } Reset(); padding.Init(initRandom); - cipher.Init(forEncryption, parameters); + m_cipherMode.Init(forEncryption, parameters); } /** @@ -138,7 +138,7 @@ namespace Org.BouncyCastle.Crypto.Paddings if (bufOff == buf.Length) { - resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + resultLen = m_cipherMode.ProcessBlock(buf, 0, output, outOff); bufOff = 0; } @@ -154,7 +154,7 @@ namespace Org.BouncyCastle.Crypto.Paddings if (bufOff == buf.Length) { - resultLen = cipher.ProcessBlock(buf, output); + resultLen = m_cipherMode.ProcessBlock(buf, output); bufOff = 0; } @@ -196,7 +196,7 @@ namespace Org.BouncyCastle.Crypto.Paddings { Array.Copy(input, inOff, buf, bufOff, gapLen); - resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + resultLen = m_cipherMode.ProcessBlock(buf, 0, output, outOff); bufOff = 0; length -= gapLen; @@ -204,7 +204,7 @@ namespace Org.BouncyCastle.Crypto.Paddings while (length > buf.Length) { - resultLen += cipher.ProcessBlock(input, inOff, output, outOff + resultLen); + resultLen += m_cipherMode.ProcessBlock(input, inOff, output, outOff + resultLen); length -= blockSize; inOff += blockSize; @@ -236,14 +236,14 @@ namespace Org.BouncyCastle.Crypto.Paddings { input[..gapLen].CopyTo(buf.AsSpan(bufOff)); - resultLen = cipher.ProcessBlock(buf, output); + resultLen = m_cipherMode.ProcessBlock(buf, output); bufOff = 0; input = input[gapLen..]; while (input.Length > buf.Length) { - resultLen += cipher.ProcessBlock(input, output[resultLen..]); + resultLen += m_cipherMode.ProcessBlock(input, output[resultLen..]); input = input[blockSize..]; } @@ -273,7 +273,7 @@ namespace Org.BouncyCastle.Crypto.Paddings */ public override int DoFinal(byte[] output, int outOff) { - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); int resultLen = 0; if (forEncryption) @@ -287,13 +287,13 @@ namespace Org.BouncyCastle.Crypto.Paddings throw new OutputLengthException("output buffer too short"); } - resultLen = cipher.ProcessBlock(buf, 0, output, outOff); + resultLen = m_cipherMode.ProcessBlock(buf, 0, output, outOff); bufOff = 0; } padding.AddPadding(buf, bufOff); - resultLen += cipher.ProcessBlock(buf, 0, output, outOff + resultLen); + resultLen += m_cipherMode.ProcessBlock(buf, 0, output, outOff + resultLen); Reset(); } @@ -301,7 +301,7 @@ namespace Org.BouncyCastle.Crypto.Paddings { if (bufOff == blockSize) { - resultLen = cipher.ProcessBlock(buf, 0, buf, 0); + resultLen = m_cipherMode.ProcessBlock(buf, 0, buf, 0); bufOff = 0; } else @@ -329,7 +329,7 @@ namespace Org.BouncyCastle.Crypto.Paddings #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER public override int DoFinal(Span<byte> output) { - int blockSize = cipher.GetBlockSize(); + int blockSize = m_cipherMode.GetBlockSize(); int resultLen = 0; if (forEncryption) @@ -343,13 +343,13 @@ namespace Org.BouncyCastle.Crypto.Paddings throw new OutputLengthException("output buffer too short"); } - resultLen = cipher.ProcessBlock(buf, output); + resultLen = m_cipherMode.ProcessBlock(buf, output); bufOff = 0; } padding.AddPadding(buf, bufOff); - resultLen += cipher.ProcessBlock(buf, output[resultLen..]); + resultLen += m_cipherMode.ProcessBlock(buf, output[resultLen..]); Reset(); } @@ -362,7 +362,7 @@ namespace Org.BouncyCastle.Crypto.Paddings throw new DataLengthException("last block incomplete in decryption"); } - resultLen = cipher.ProcessBlock(buf, buf); + resultLen = m_cipherMode.ProcessBlock(buf, buf); bufOff = 0; try diff --git a/crypto/src/crypto/util/CipherFactory.cs b/crypto/src/crypto/util/CipherFactory.cs index 2e8c44bb4..56f57c545 100644 --- a/crypto/src/crypto/util/CipherFactory.cs +++ b/crypto/src/crypto/util/CipherFactory.cs @@ -110,7 +110,7 @@ namespace Org.BouncyCastle.Crypto.Utilities private static BufferedBlockCipher CreateCipher(DerObjectIdentifier algorithm) { - IBlockCipher cipher; + IBlockCipherMode cipher; if (NistObjectIdentifiers.IdAes128Cbc.Equals(algorithm) || NistObjectIdentifiers.IdAes192Cbc.Equals(algorithm) diff --git a/crypto/src/security/CipherUtilities.cs b/crypto/src/security/CipherUtilities.cs index 8ed5d8d41..929040e2c 100644 --- a/crypto/src/security/CipherUtilities.cs +++ b/crypto/src/security/CipherUtilities.cs @@ -620,6 +620,7 @@ namespace Org.BouncyCastle.Security } string mode = ""; + IBlockCipherMode blockCipherMode = null; if (parts.Length > 1) { mode = parts[1]; @@ -639,7 +640,7 @@ namespace Org.BouncyCastle.Security case CipherMode.NONE: break; case CipherMode.CBC: - blockCipher = new CbcBlockCipher(blockCipher); + blockCipherMode = new CbcBlockCipher(blockCipher); break; case CipherMode.CCM: aeadBlockCipher = new CcmBlockCipher(blockCipher); @@ -650,15 +651,15 @@ namespace Org.BouncyCastle.Security ? 8 * blockCipher.GetBlockSize() : int.Parse(mode.Substring(di)); - blockCipher = new CfbBlockCipher(blockCipher, bits); + blockCipherMode = new CfbBlockCipher(blockCipher, bits); break; } case CipherMode.CTR: - blockCipher = new SicBlockCipher(blockCipher); + blockCipherMode = new SicBlockCipher(blockCipher); break; case CipherMode.CTS: cts = true; - blockCipher = new CbcBlockCipher(blockCipher); + blockCipherMode = new CbcBlockCipher(blockCipher); break; case CipherMode.EAX: aeadBlockCipher = new EaxBlockCipher(blockCipher); @@ -667,7 +668,7 @@ namespace Org.BouncyCastle.Security aeadBlockCipher = new GcmBlockCipher(blockCipher); break; case CipherMode.GOFB: - blockCipher = new GOfbBlockCipher(blockCipher); + blockCipherMode = new GOfbBlockCipher(blockCipher); break; case CipherMode.OCB: aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm)); @@ -678,18 +679,18 @@ namespace Org.BouncyCastle.Security ? 8 * blockCipher.GetBlockSize() : int.Parse(mode.Substring(di)); - blockCipher = new OfbBlockCipher(blockCipher, bits); + blockCipherMode = new OfbBlockCipher(blockCipher, bits); break; } case CipherMode.OPENPGPCFB: - blockCipher = new OpenPgpCfbBlockCipher(blockCipher); + blockCipherMode = new OpenPgpCfbBlockCipher(blockCipher); break; case CipherMode.SIC: if (blockCipher.GetBlockSize() < 16) { throw new ArgumentException("Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)"); } - blockCipher = new SicBlockCipher(blockCipher); + blockCipherMode = new SicBlockCipher(blockCipher); break; default: throw new SecurityUtilityException("Cipher " + algorithm + " not recognised."); @@ -713,22 +714,27 @@ namespace Org.BouncyCastle.Security if (blockCipher != null) { + if (blockCipherMode == null) + { + blockCipherMode = EcbBlockCipher.GetBlockCipherMode(blockCipher); + } + if (cts) { - return new CtsBlockCipher(blockCipher); + return new CtsBlockCipher(blockCipherMode); } if (padding != null) { - return new PaddedBufferedBlockCipher(blockCipher, padding); + return new PaddedBufferedBlockCipher(blockCipherMode, padding); } - if (!padded || blockCipher.IsPartialBlockOkay) + if (!padded || blockCipherMode.IsPartialBlockOkay) { - return new BufferedBlockCipher(blockCipher); + return new BufferedBlockCipher(blockCipherMode); } - return new PaddedBufferedBlockCipher(blockCipher); + return new PaddedBufferedBlockCipher(blockCipherMode); } if (asymBlockCipher != null) diff --git a/crypto/test/src/crypto/io/test/CipherStreamTest.cs b/crypto/test/src/crypto/io/test/CipherStreamTest.cs index 799b44521..9dc1f4c2a 100644 --- a/crypto/test/src/crypto/io/test/CipherStreamTest.cs +++ b/crypto/test/src/crypto/io/test/CipherStreamTest.cs @@ -144,8 +144,8 @@ namespace Org.BouncyCastle.Crypto.IO.Tests IBlockCipher blockCipher = AesUtilities.CreateEngine(); int bits = 8 * blockCipher.GetBlockSize(); // TODO Is this right? - blockCipher = new CfbBlockCipher(blockCipher, bits); - IBufferedCipher cipher = new BufferedBlockCipher(blockCipher); + IBlockCipherMode blockCipherMode = new CfbBlockCipher(blockCipher, bits); + IBufferedCipher cipher = new BufferedBlockCipher(blockCipherMode); // SecureRandom random = new SecureRandom(); byte[] keyBytes = new byte[32]; diff --git a/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs b/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs index 3e90c5752..047405c77 100644 --- a/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs +++ b/crypto/test/src/crypto/prng/test/CtrDrbgTest.cs @@ -497,11 +497,6 @@ namespace Org.BouncyCastle.Crypto.Prng.Test get { return cipher.AlgorithmName; } } - public bool IsPartialBlockOkay - { - get { return false; } - } - public int GetBlockSize() { return cipher.GetBlockSize(); @@ -520,11 +515,6 @@ namespace Org.BouncyCastle.Crypto.Prng.Test return cipher.ProcessBlock(input, output); } #endif - - public void Reset() - { - cipher.Reset(); - } } } } diff --git a/crypto/test/src/crypto/test/NullTest.cs b/crypto/test/src/crypto/test/NullTest.cs deleted file mode 100644 index 0bc9d28cf..000000000 --- a/crypto/test/src/crypto/test/NullTest.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; - -using NUnit.Framework; - -using Org.BouncyCastle.Crypto.Engines; -using Org.BouncyCastle.Crypto.Parameters; -using Org.BouncyCastle.Utilities.Encoders; -using Org.BouncyCastle.Utilities.Test; - -namespace Org.BouncyCastle.Crypto.Tests -{ - [TestFixture] - public class NullTest - : CipherTest - { - static SimpleTest[] tests = - { - new BlockCipherVectorTest(0, new NullEngine(), - new KeyParameter(Hex.Decode("00")), "00", "00") - }; - - public NullTest() - : base(tests, new NullEngine(), new KeyParameter(new byte[2])) - { - } - - public override string Name - { - get { return "Null"; } - } - - public override void PerformTest() - { - base.PerformTest(); - - IBlockCipher engine = new NullEngine(); - - engine.Init(true, null); - - byte[] buf = new byte[1]; - - engine.ProcessBlock(buf, 0, buf, 0); - - if (buf[0] != 0) - { - Fail("NullCipher changed data!"); - } - - byte[] shortBuf = new byte[0]; - - try - { - engine.ProcessBlock(shortBuf, 0, buf, 0); - - Fail("failed short input check"); - } - catch (DataLengthException) - { - // expected - } - - try - { - engine.ProcessBlock(buf, 0, shortBuf, 0); - - Fail("failed short output check"); - } - catch (DataLengthException) - { - // expected - } - } - - [Test] - public void TestFunction() - { - string resultText = Perform().ToString(); - - Assert.AreEqual(Name + ": Okay", resultText); - } - } -} |