diff options
Diffstat (limited to 'crypto')
56 files changed, 666 insertions, 584 deletions
diff --git a/crypto/crypto.csproj b/crypto/crypto.csproj index fdd5c152b..3f713e1c0 100644 --- a/crypto/crypto.csproj +++ b/crypto/crypto.csproj @@ -2964,6 +2964,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\crypto\Check.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\crypto\CipherKeyGenerator.cs" SubType = "Code" BuildAction = "Compile" @@ -3069,6 +3074,11 @@ BuildAction = "Compile" /> <File + RelPath = "src\crypto\OutputLengthException.cs" + SubType = "Code" + BuildAction = "Compile" + /> + <File RelPath = "src\crypto\PBEParametersGenerator.cs" SubType = "Code" BuildAction = "Compile" diff --git a/crypto/src/crypto/BufferedBlockCipher.cs b/crypto/src/crypto/BufferedBlockCipher.cs index 3a98798a2..9684ed93e 100644 --- a/crypto/src/crypto/BufferedBlockCipher.cs +++ b/crypto/src/crypto/BufferedBlockCipher.cs @@ -223,13 +223,10 @@ namespace Org.BouncyCastle.Crypto if (outLength > 0) { - if ((outOff + outLength) > output.Length) - { - throw new DataLengthException("output buffer too short"); - } + Check.OutputLength(output, outOff, outLength, "output buffer too short"); } - int resultLen = 0; + int resultLen = 0; int gapLen = buf.Length - bufOff; if (length > gapLen) { @@ -339,17 +336,10 @@ namespace Org.BouncyCastle.Crypto { if (bufOff != 0) { - if (!cipher.IsPartialBlockOkay) - { - throw new DataLengthException("data not block size aligned"); - } - - if (outOff + bufOff > output.Length) - { - throw new DataLengthException("output buffer too short for DoFinal()"); - } - - // NB: Can't copy directly, or we may write too much output + Check.DataLength(!cipher.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); Array.Copy(buf, 0, output, outOff, bufOff); } diff --git a/crypto/src/crypto/Check.cs b/crypto/src/crypto/Check.cs new file mode 100644 index 000000000..96a05c64b --- /dev/null +++ b/crypto/src/crypto/Check.cs @@ -0,0 +1,25 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ + internal class Check + { + internal static void DataLength(bool condition, string msg) + { + if (condition) + throw new DataLengthException(msg); + } + + internal static void DataLength(byte[] buf, int off, int len, string msg) + { + if (off + len > buf.Length) + throw new DataLengthException(msg); + } + + internal static void OutputLength(byte[] buf, int off, int len, string msg) + { + if (off + len > buf.Length) + throw new OutputLengthException(msg); + } + } +} diff --git a/crypto/src/crypto/OutputLengthException.cs b/crypto/src/crypto/OutputLengthException.cs new file mode 100644 index 000000000..e1cf44925 --- /dev/null +++ b/crypto/src/crypto/OutputLengthException.cs @@ -0,0 +1,28 @@ +using System; + +namespace Org.BouncyCastle.Crypto +{ +#if !(NETCF_1_0 || NETCF_2_0 || SILVERLIGHT) + [Serializable] +#endif + public class OutputLengthException + : DataLengthException + { + public OutputLengthException() + { + } + + public OutputLengthException( + string message) + : base(message) + { + } + + public OutputLengthException( + string message, + Exception exception) + : base(message, exception) + { + } + } +} diff --git a/crypto/src/crypto/engines/AesEngine.cs b/crypto/src/crypto/engines/AesEngine.cs index 0cdd868fa..9d7f76c05 100644 --- a/crypto/src/crypto/engines/AesEngine.cs +++ b/crypto/src/crypto/engines/AesEngine.cs @@ -363,7 +363,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -377,41 +377,32 @@ namespace Org.BouncyCastle.Crypto.Engines this.forEncryption = forEncryption; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "AES"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BLOCK_SIZE; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, int outOff) { if (WorkingKey == null) - { throw new InvalidOperationException("AES engine not initialised"); - } - if ((inOff + (32 / 2)) > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + (32 / 2)) > output.Length) - { - throw new DataLengthException("output buffer too short"); - } + Check.DataLength(input, inOff, 16, "input buffer too short"); + Check.OutputLength(output, outOff, 16, "output buffer too short"); UnPackBlock(input, inOff); @@ -429,7 +420,7 @@ namespace Org.BouncyCastle.Crypto.Engines return BLOCK_SIZE; } - public void Reset() + public virtual void Reset() { } diff --git a/crypto/src/crypto/engines/AesFastEngine.cs b/crypto/src/crypto/engines/AesFastEngine.cs index 38d3a5841..a1b544568 100644 --- a/crypto/src/crypto/engines/AesFastEngine.cs +++ b/crypto/src/crypto/engines/AesFastEngine.cs @@ -695,7 +695,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -709,41 +709,32 @@ namespace Org.BouncyCastle.Crypto.Engines this.forEncryption = forEncryption; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "AES"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BLOCK_SIZE; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, int outOff) { if (WorkingKey == null) - { throw new InvalidOperationException("AES engine not initialised"); - } - if ((inOff + (32 / 2)) > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + (32 / 2)) > output.Length) - { - throw new DataLengthException("output buffer too short"); - } + Check.DataLength(input, inOff, 16, "input buffer too short"); + Check.OutputLength(output, outOff, 16, "output buffer too short"); UnPackBlock(input, inOff); @@ -761,7 +752,7 @@ namespace Org.BouncyCastle.Crypto.Engines return BLOCK_SIZE; } - public void Reset() + public virtual void Reset() { } diff --git a/crypto/src/crypto/engines/AesLightEngine.cs b/crypto/src/crypto/engines/AesLightEngine.cs index 54f2d2e88..a6b9e3bd4 100644 --- a/crypto/src/crypto/engines/AesLightEngine.cs +++ b/crypto/src/crypto/engines/AesLightEngine.cs @@ -258,7 +258,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -272,41 +272,32 @@ namespace Org.BouncyCastle.Crypto.Engines this.forEncryption = forEncryption; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "AES"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BLOCK_SIZE; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, int outOff) { if (WorkingKey == null) - { throw new InvalidOperationException("AES engine not initialised"); - } - if ((inOff + (32 / 2)) > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + (32 / 2)) > output.Length) - { - throw new DataLengthException("output buffer too short"); - } + Check.DataLength(input, inOff, 16, "input buffer too short"); + Check.OutputLength(output, outOff, 16, "output buffer too short"); UnPackBlock(input, inOff); @@ -324,7 +315,7 @@ namespace Org.BouncyCastle.Crypto.Engines return BLOCK_SIZE; } - public void Reset() + public virtual void Reset() { } diff --git a/crypto/src/crypto/engines/BlowfishEngine.cs b/crypto/src/crypto/engines/BlowfishEngine.cs index 8f80f712e..7b50e832f 100644 --- a/crypto/src/crypto/engines/BlowfishEngine.cs +++ b/crypto/src/crypto/engines/BlowfishEngine.cs @@ -296,7 +296,7 @@ namespace Org.BouncyCastle.Crypto.Engines //==================================== private static readonly int ROUNDS = 16; - private const int BLOCK_SIZE = 8; // bytes = 64 bits + private const int BLOCK_SIZE = 8; // bytes = 64 bits private static readonly int SBOX_SK = 256; private static readonly int P_SZ = ROUNDS+2; @@ -353,19 +353,10 @@ namespace Org.BouncyCastle.Crypto.Engines int outOff) { if (workingKey == null) - { throw new InvalidOperationException("Blowfish not initialised"); - } - if ((inOff + BLOCK_SIZE) > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + BLOCK_SIZE) > output.Length) - { - throw new DataLengthException("output buffer too short"); - } + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); if (encrypting) { diff --git a/crypto/src/crypto/engines/CamelliaEngine.cs b/crypto/src/crypto/engines/CamelliaEngine.cs index 8f4a442e9..71bd1b0dc 100644 --- a/crypto/src/crypto/engines/CamelliaEngine.cs +++ b/crypto/src/crypto/engines/CamelliaEngine.cs @@ -611,7 +611,7 @@ namespace Org.BouncyCastle.Crypto.Engines { } - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -623,22 +623,22 @@ namespace Org.BouncyCastle.Crypto.Engines initialised = true; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "Camellia"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BLOCK_SIZE; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, @@ -646,12 +646,11 @@ namespace Org.BouncyCastle.Crypto.Engines { if (!initialised) throw new InvalidOperationException("Camellia engine not initialised"); - if ((inOff + BLOCK_SIZE) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + BLOCK_SIZE) > output.Length) - throw new DataLengthException("output buffer too short"); - if (_keyIs128) + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (_keyIs128) { return processBlock128(input, inOff, output, outOff); } @@ -661,7 +660,7 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public void Reset() + public virtual void Reset() { // nothing } diff --git a/crypto/src/crypto/engines/CamelliaLightEngine.cs b/crypto/src/crypto/engines/CamelliaLightEngine.cs index a301eb55e..a132227c5 100644 --- a/crypto/src/crypto/engines/CamelliaLightEngine.cs +++ b/crypto/src/crypto/engines/CamelliaLightEngine.cs @@ -524,22 +524,22 @@ namespace Org.BouncyCastle.Crypto.Engines initialised = false; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "Camellia"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BLOCK_SIZE; } - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -551,7 +551,7 @@ namespace Org.BouncyCastle.Crypto.Engines initialised = true; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, @@ -559,12 +559,11 @@ namespace Org.BouncyCastle.Crypto.Engines { if (!initialised) throw new InvalidOperationException("Camellia engine not initialised"); - if ((inOff + BLOCK_SIZE) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + BLOCK_SIZE) > output.Length) - throw new DataLengthException("output buffer too short"); - if (_keyis128) + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (_keyis128) { return processBlock128(input, inOff, output, outOff); } @@ -574,7 +573,7 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public void Reset() + public virtual void Reset() { } } diff --git a/crypto/src/crypto/engines/Cast5Engine.cs b/crypto/src/crypto/engines/Cast5Engine.cs index 4c3f84a55..1af30a335 100644 --- a/crypto/src/crypto/engines/Cast5Engine.cs +++ b/crypto/src/crypto/engines/Cast5Engine.cs @@ -329,7 +329,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -360,12 +360,11 @@ namespace Org.BouncyCastle.Crypto.Engines int blockSize = GetBlockSize(); if (_workingKey == null) throw new InvalidOperationException(AlgorithmName + " not initialised"); - if ((inOff + blockSize) > input.Length) - throw new DataLengthException("Input buffer too short"); - if ((outOff + blockSize) > output.Length) - throw new DataLengthException("Output buffer too short"); - if (_encrypting) + Check.DataLength(input, inOff, blockSize, "input buffer too short"); + Check.OutputLength(output, outOff, blockSize, "output buffer too short"); + + if (_encrypting) { return EncryptBlock(input, inOff, output, outOff); } diff --git a/crypto/src/crypto/engines/ChaChaEngine.cs b/crypto/src/crypto/engines/ChaChaEngine.cs index f4a7b8fe1..46b59ed2e 100644 --- a/crypto/src/crypto/engines/ChaChaEngine.cs +++ b/crypto/src/crypto/engines/ChaChaEngine.cs @@ -162,7 +162,6 @@ namespace Org.BouncyCastle.Crypto.Engines x09 += x14; x04 = R(x04 ^ x09, 12); x03 += x04; x14 = R(x14 ^ x03, 8); x09 += x14; x04 = R(x04 ^ x09, 7); - } x[ 0] = x00 + input[ 0]; @@ -182,8 +181,6 @@ namespace Org.BouncyCastle.Crypto.Engines x[14] = x14 + input[14]; x[15] = x15 + input[15]; } - } - } diff --git a/crypto/src/crypto/engines/DesEdeEngine.cs b/crypto/src/crypto/engines/DesEdeEngine.cs index eec4ec59d..bc40b56a8 100644 --- a/crypto/src/crypto/engines/DesEdeEngine.cs +++ b/crypto/src/crypto/engines/DesEdeEngine.cs @@ -70,10 +70,9 @@ namespace Org.BouncyCastle.Crypto.Engines { if (workingKey1 == null) throw new InvalidOperationException("DESede engine not initialised"); - if ((inOff + BLOCK_SIZE) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + BLOCK_SIZE) > output.Length) - throw new DataLengthException("output buffer too short"); + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); byte[] temp = new byte[BLOCK_SIZE]; diff --git a/crypto/src/crypto/engines/DesEdeWrapEngine.cs b/crypto/src/crypto/engines/DesEdeWrapEngine.cs index fdc71687f..43100a9bd 100644 --- a/crypto/src/crypto/engines/DesEdeWrapEngine.cs +++ b/crypto/src/crypto/engines/DesEdeWrapEngine.cs @@ -52,7 +52,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @param forWrapping * @param param */ - public void Init( + public virtual void Init( bool forWrapping, ICipherParameters parameters) { @@ -103,7 +103,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return */ - public string AlgorithmName + public virtual string AlgorithmName { get { return "DESede"; } } @@ -116,7 +116,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @param inLen * @return */ - public byte[] Wrap( + public virtual byte[] Wrap( byte[] input, int inOff, int length) @@ -185,7 +185,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @return * @throws InvalidCipherTextException */ - public byte[] Unwrap( + public virtual byte[] Unwrap( byte[] input, int inOff, int length) diff --git a/crypto/src/crypto/engines/DesEngine.cs b/crypto/src/crypto/engines/DesEngine.cs index 067cf45e3..a6d580bb6 100644 --- a/crypto/src/crypto/engines/DesEngine.cs +++ b/crypto/src/crypto/engines/DesEngine.cs @@ -41,7 +41,7 @@ namespace Org.BouncyCastle.Crypto.Engines get { return "DES"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } @@ -59,12 +59,11 @@ namespace Org.BouncyCastle.Crypto.Engines { if (workingKey == null) throw new InvalidOperationException("DES engine not initialised"); - if ((inOff + BLOCK_SIZE) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + BLOCK_SIZE) > output.Length) - throw new DataLengthException("output buffer too short"); - DesFunc(workingKey, input, inOff, output, outOff); + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + DesFunc(workingKey, input, inOff, output, outOff); return BLOCK_SIZE; } diff --git a/crypto/src/crypto/engines/ElGamalEngine.cs b/crypto/src/crypto/engines/ElGamalEngine.cs index 3d256a087..197d7bc15 100644 --- a/crypto/src/crypto/engines/ElGamalEngine.cs +++ b/crypto/src/crypto/engines/ElGamalEngine.cs @@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Crypto.Engines private bool forEncryption; private int bitSize; - public string AlgorithmName + public virtual string AlgorithmName { get { return "ElGamal"; } } @@ -28,7 +28,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary ElGamal key parameters. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return maximum size for an input block. */ - public int GetInputBlockSize() + public virtual int GetInputBlockSize() { if (forEncryption) { @@ -88,7 +88,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return maximum size for an output block. */ - public int GetOutputBlockSize() + public virtual int GetOutputBlockSize() { if (forEncryption) { @@ -107,7 +107,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @return the result of the ElGamal process. * @exception DataLengthException the input block is too large. */ - public byte[] ProcessBlock( + public virtual byte[] ProcessBlock( byte[] input, int inOff, int length) diff --git a/crypto/src/crypto/engines/GOST28147Engine.cs b/crypto/src/crypto/engines/GOST28147Engine.cs index 8eb6f36b5..e37ddaefd 100644 --- a/crypto/src/crypto/engines/GOST28147Engine.cs +++ b/crypto/src/crypto/engines/GOST28147Engine.cs @@ -150,7 +150,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @param parameters the parameters required to set up the cipher. * @exception ArgumentException if the parameters argument is inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -187,48 +187,39 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public string AlgorithmName + public virtual string AlgorithmName { get { return "Gost28147"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BlockSize; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, int outOff) { if (workingKey == null) - { throw new InvalidOperationException("Gost28147 engine not initialised"); - } - if ((inOff + BlockSize) > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + BlockSize) > output.Length) - { - throw new DataLengthException("output buffer too short"); - } + Check.DataLength(input, inOff, BlockSize, "input buffer too short"); + Check.OutputLength(output, outOff, BlockSize, "output buffer too short"); - Gost28147Func(workingKey, input, inOff, output, outOff); + Gost28147Func(workingKey, input, inOff, output, outOff); return BlockSize; } - public void Reset() + public virtual void Reset() { } diff --git a/crypto/src/crypto/engines/HC128Engine.cs b/crypto/src/crypto/engines/HC128Engine.cs index a2d099f87..40c7a4e17 100644 --- a/crypto/src/crypto/engines/HC128Engine.cs +++ b/crypto/src/crypto/engines/HC128Engine.cs @@ -142,7 +142,7 @@ namespace Org.BouncyCastle.Crypto.Engines cnt = 0; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "HC-128"; } } @@ -156,7 +156,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @throws ArgumentException if the params argument is * inappropriate (ie. the key is not 128 bit long). */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -201,7 +201,7 @@ namespace Org.BouncyCastle.Crypto.Engines return ret; } - public void ProcessBytes( + public virtual void ProcessBytes( byte[] input, int inOff, int len, @@ -210,24 +210,23 @@ namespace Org.BouncyCastle.Crypto.Engines { if (!initialised) throw new InvalidOperationException(AlgorithmName + " not initialised"); - if ((inOff + len) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + len) > output.Length) - throw new DataLengthException("output buffer too short"); - for (int i = 0; i < len; i++) + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); + + for (int i = 0; i < len; i++) { output[outOff + i] = (byte)(input[inOff + i] ^ GetByte()); } } - public void Reset() + public virtual void Reset() { idx = 0; Init(); } - public byte ReturnByte(byte input) + public virtual byte ReturnByte(byte input) { return (byte)(input ^ GetByte()); } diff --git a/crypto/src/crypto/engines/HC256Engine.cs b/crypto/src/crypto/engines/HC256Engine.cs index da717dab7..6eb360711 100644 --- a/crypto/src/crypto/engines/HC256Engine.cs +++ b/crypto/src/crypto/engines/HC256Engine.cs @@ -126,7 +126,7 @@ namespace Org.BouncyCastle.Crypto.Engines cnt = 0; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "HC-256"; } } @@ -140,7 +140,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @throws ArgumentException if the params argument is * inappropriate (ie. the key is not 256 bit long). */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -185,7 +185,7 @@ namespace Org.BouncyCastle.Crypto.Engines return ret; } - public void ProcessBytes( + public virtual void ProcessBytes( byte[] input, int inOff, int len, @@ -194,24 +194,23 @@ namespace Org.BouncyCastle.Crypto.Engines { if (!initialised) throw new InvalidOperationException(AlgorithmName + " not initialised"); - if ((inOff + len) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + len) > output.Length) - throw new DataLengthException("output buffer too short"); - for (int i = 0; i < len; i++) + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); + + for (int i = 0; i < len; i++) { output[outOff + i] = (byte)(input[inOff + i] ^ GetByte()); } } - public void Reset() + public virtual void Reset() { idx = 0; Init(); } - public byte ReturnByte(byte input) + public virtual byte ReturnByte(byte input) { return (byte)(input ^ GetByte()); } diff --git a/crypto/src/crypto/engines/ISAACEngine.cs b/crypto/src/crypto/engines/ISAACEngine.cs index 9c58678a0..f25577130 100644 --- a/crypto/src/crypto/engines/ISAACEngine.cs +++ b/crypto/src/crypto/engines/ISAACEngine.cs @@ -35,7 +35,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the params argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -53,7 +53,7 @@ namespace Org.BouncyCastle.Crypto.Engines setKey(p.GetKey()); } - public byte ReturnByte( + public virtual byte ReturnByte( byte input) { if (index == 0) @@ -68,7 +68,7 @@ namespace Org.BouncyCastle.Crypto.Engines return output; } - public void ProcessBytes( + public virtual void ProcessBytes( byte[] input, int inOff, int len, @@ -77,10 +77,9 @@ namespace Org.BouncyCastle.Crypto.Engines { if (!initialised) throw new InvalidOperationException(AlgorithmName + " not initialised"); - if ((inOff + len) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + len) > output.Length) - throw new DataLengthException("output buffer too short"); + + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); for (int i = 0; i < len; i++) { @@ -94,12 +93,12 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public string AlgorithmName + public virtual string AlgorithmName { get { return "ISAAC"; } } - public void Reset() + public virtual void Reset() { setKey(workingKey); } diff --git a/crypto/src/crypto/engines/IdeaEngine.cs b/crypto/src/crypto/engines/IdeaEngine.cs index 46b5a787c..4909510ac 100644 --- a/crypto/src/crypto/engines/IdeaEngine.cs +++ b/crypto/src/crypto/engines/IdeaEngine.cs @@ -47,7 +47,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -58,43 +58,37 @@ namespace Org.BouncyCastle.Crypto.Engines ((KeyParameter)parameters).GetKey()); } - public string AlgorithmName + public virtual string AlgorithmName { get { return "IDEA"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BLOCK_SIZE; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, int outOff) { if (workingKey == null) - { throw new InvalidOperationException("IDEA engine not initialised"); - } - if ((inOff + BLOCK_SIZE) > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - if ((outOff + BLOCK_SIZE) > output.Length) - { - throw new DataLengthException("output buffer too short"); - } + + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + IdeaFunc(workingKey, input, inOff, output, outOff); return BLOCK_SIZE; } - public void Reset() + public virtual void Reset() { } private static readonly int MASK = 0xffff; diff --git a/crypto/src/crypto/engines/IesEngine.cs b/crypto/src/crypto/engines/IesEngine.cs index 70df3077c..961e3b038 100644 --- a/crypto/src/crypto/engines/IesEngine.cs +++ b/crypto/src/crypto/engines/IesEngine.cs @@ -72,7 +72,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @param pubParam the recipient's/sender's public key parameters * @param param encoding and derivation parameters. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters privParameters, ICipherParameters pubParameters, @@ -213,7 +213,7 @@ namespace Org.BouncyCastle.Crypto.Engines return buf; } - public byte[] ProcessBlock( + public virtual byte[] ProcessBlock( byte[] input, int inOff, int inLen) diff --git a/crypto/src/crypto/engines/NaccacheSternEngine.cs b/crypto/src/crypto/engines/NaccacheSternEngine.cs index 9ca092351..e547e0caf 100644 --- a/crypto/src/crypto/engines/NaccacheSternEngine.cs +++ b/crypto/src/crypto/engines/NaccacheSternEngine.cs @@ -33,7 +33,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @see org.bouncycastle.crypto.AsymmetricBlockCipher#init(bool, * org.bouncycastle.crypto.CipherParameters) */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -83,7 +83,7 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public bool Debug + public virtual bool Debug { set { this.debug = value; } } @@ -93,7 +93,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @see org.bouncycastle.crypto.AsymmetricBlockCipher#GetInputBlockSize() */ - public int GetInputBlockSize() + public virtual int GetInputBlockSize() { if (forEncryption) { @@ -113,7 +113,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @see org.bouncycastle.crypto.AsymmetricBlockCipher#GetOutputBlockSize() */ - public int GetOutputBlockSize() + public virtual int GetOutputBlockSize() { if (forEncryption) { @@ -134,7 +134,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @see org.bouncycastle.crypto.AsymmetricBlockCipher#ProcessBlock(byte[], * int, int) */ - public byte[] ProcessBlock( + public virtual byte[] ProcessBlock( byte[] inBytes, int inOff, int length) @@ -245,7 +245,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @return The byte[] representation of the encrypted BigInteger (i.e. * crypted.toByteArray()) */ - public byte[] Encrypt( + public virtual byte[] Encrypt( BigInteger plain) { // Always return modulus size values 0-padded at the beginning @@ -273,7 +273,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @return encrypt((block1 + block2) mod sigma) * @throws InvalidCipherTextException */ - public byte[] AddCryptedBlocks( + public virtual byte[] AddCryptedBlocks( byte[] block1, byte[] block2) { @@ -329,7 +329,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @return the data after it went through the NaccacheSternEngine. * @throws InvalidCipherTextException */ - public byte[] ProcessData( + public virtual byte[] ProcessData( byte[] data) { if (debug) diff --git a/crypto/src/crypto/engines/NoekeonEngine.cs b/crypto/src/crypto/engines/NoekeonEngine.cs index b73e696a9..dd78a4ea5 100644 --- a/crypto/src/crypto/engines/NoekeonEngine.cs +++ b/crypto/src/crypto/engines/NoekeonEngine.cs @@ -42,17 +42,17 @@ namespace Org.BouncyCastle.Crypto.Engines _initialised = false; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "Noekeon"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return GenericSize; } @@ -65,7 +65,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the params argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -80,7 +80,7 @@ namespace Org.BouncyCastle.Crypto.Engines setKey(p.GetKey()); } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, @@ -88,17 +88,16 @@ namespace Org.BouncyCastle.Crypto.Engines { if (!_initialised) throw new InvalidOperationException(AlgorithmName + " not initialised"); - if ((inOff + GenericSize) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + GenericSize) > output.Length) - throw new DataLengthException("output buffer too short"); - return _forEncryption + Check.DataLength(input, inOff, GenericSize, "input buffer too short"); + Check.OutputLength(output, outOff, GenericSize, "output buffer too short"); + + return _forEncryption ? encryptBlock(input, inOff, output, outOff) : decryptBlock(input, inOff, output, outOff); } - public void Reset() + public virtual void Reset() { // TODO This should do something in case the encryption is aborted } diff --git a/crypto/src/crypto/engines/NullEngine.cs b/crypto/src/crypto/engines/NullEngine.cs index 407b8ccc6..f883b7c29 100644 --- a/crypto/src/crypto/engines/NullEngine.cs +++ b/crypto/src/crypto/engines/NullEngine.cs @@ -18,7 +18,7 @@ namespace Org.BouncyCastle.Crypto.Engines { } - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -26,22 +26,22 @@ namespace Org.BouncyCastle.Crypto.Engines initialised = true; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "Null"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return true; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BlockSize; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, @@ -49,12 +49,11 @@ namespace Org.BouncyCastle.Crypto.Engines { if (!initialised) throw new InvalidOperationException("Null engine not initialised"); - if ((inOff + BlockSize) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + BlockSize) > output.Length) - throw new DataLengthException("output buffer too short"); - for (int i = 0; i < BlockSize; ++i) + 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]; } @@ -62,7 +61,7 @@ namespace Org.BouncyCastle.Crypto.Engines return BlockSize; } - public void Reset() + 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 aaf8c714c..b56953de5 100644 --- a/crypto/src/crypto/engines/RC2Engine.cs +++ b/crypto/src/crypto/engines/RC2Engine.cs @@ -114,7 +114,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -139,26 +139,26 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public void Reset() + public virtual void Reset() { } - public string AlgorithmName + public virtual string AlgorithmName { get { return "RC2"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BLOCK_SIZE; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, @@ -166,12 +166,11 @@ namespace Org.BouncyCastle.Crypto.Engines { if (workingKey == null) throw new InvalidOperationException("RC2 engine not initialised"); - if ((inOff + BLOCK_SIZE) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + BLOCK_SIZE) > output.Length) - throw new DataLengthException("output buffer too short"); - if (encrypting) + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) { EncryptBlock(input, inOff, output, outOff); } @@ -308,5 +307,4 @@ namespace Org.BouncyCastle.Crypto.Engines outBytes[outOff + 7] = (byte)(x76 >> 8); } } - } diff --git a/crypto/src/crypto/engines/RC2WrapEngine.cs b/crypto/src/crypto/engines/RC2WrapEngine.cs index 238c9f76a..5742aa8b7 100644 --- a/crypto/src/crypto/engines/RC2WrapEngine.cs +++ b/crypto/src/crypto/engines/RC2WrapEngine.cs @@ -51,7 +51,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @param forWrapping * @param param */ - public void Init( + public virtual void Init( bool forWrapping, ICipherParameters parameters) { @@ -101,7 +101,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return */ - public string AlgorithmName + public virtual string AlgorithmName { get { return "RC2"; } } @@ -114,7 +114,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @param inLen * @return */ - public byte[] Wrap( + public virtual byte[] Wrap( byte[] input, int inOff, int length) @@ -215,7 +215,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @return * @throws InvalidCipherTextException */ - public byte[] Unwrap( + public virtual byte[] Unwrap( byte[] input, int inOff, int length) diff --git a/crypto/src/crypto/engines/RC4Engine.cs b/crypto/src/crypto/engines/RC4Engine.cs index c65468d93..fd84b7d23 100644 --- a/crypto/src/crypto/engines/RC4Engine.cs +++ b/crypto/src/crypto/engines/RC4Engine.cs @@ -27,7 +27,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -47,12 +47,12 @@ namespace Org.BouncyCastle.Crypto.Engines throw new ArgumentException("invalid parameter passed to RC4 init - " + parameters.GetType().ToString()); } - public string AlgorithmName + public virtual string AlgorithmName { get { return "RC4"; } } - public byte ReturnByte( + public virtual byte ReturnByte( byte input) { x = (x + 1) & 0xff; @@ -67,23 +67,15 @@ namespace Org.BouncyCastle.Crypto.Engines return (byte)(input ^ engineState[(engineState[x] + engineState[y]) & 0xff]); } - public void ProcessBytes( + public virtual void ProcessBytes( byte[] input, int inOff, int length, byte[] output, - int outOff - ) + int outOff) { - if ((inOff + length) > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + length) > output.Length) - { - throw new DataLengthException("output buffer too short"); - } + 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++) { @@ -101,7 +93,7 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public void Reset() + public virtual void Reset() { SetKey(workingKey); } @@ -143,5 +135,4 @@ namespace Org.BouncyCastle.Crypto.Engines } } } - } diff --git a/crypto/src/crypto/engines/RC532Engine.cs b/crypto/src/crypto/engines/RC532Engine.cs index 1661707ef..169a60b98 100644 --- a/crypto/src/crypto/engines/RC532Engine.cs +++ b/crypto/src/crypto/engines/RC532Engine.cs @@ -48,17 +48,17 @@ namespace Org.BouncyCastle.Crypto.Engines // _S = null; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "RC5-32"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return 2 * 4; } @@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -97,7 +97,7 @@ namespace Org.BouncyCastle.Crypto.Engines this.forEncryption = forEncryption; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, @@ -108,7 +108,7 @@ namespace Org.BouncyCastle.Crypto.Engines : DecryptBlock(input, inOff, output, outOff); } - public void Reset() + public virtual void Reset() { } @@ -290,5 +290,4 @@ namespace Org.BouncyCastle.Crypto.Engines dst[dstOff + 3] = (byte)(word >> 24); } } - } diff --git a/crypto/src/crypto/engines/RC564Engine.cs b/crypto/src/crypto/engines/RC564Engine.cs index 5c69d40ff..ddcce0fa8 100644 --- a/crypto/src/crypto/engines/RC564Engine.cs +++ b/crypto/src/crypto/engines/RC564Engine.cs @@ -51,17 +51,17 @@ namespace Org.BouncyCastle.Crypto.Engines // _S = null; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "RC5-64"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return 2 * bytesPerWord; } @@ -74,7 +74,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -92,7 +92,7 @@ namespace Org.BouncyCastle.Crypto.Engines SetKey(p.GetKey()); } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, @@ -102,7 +102,7 @@ namespace Org.BouncyCastle.Crypto.Engines : DecryptBlock(input, inOff, output, outOff); } - public void Reset() + public virtual void Reset() { } @@ -291,5 +291,4 @@ namespace Org.BouncyCastle.Crypto.Engines } } } - } diff --git a/crypto/src/crypto/engines/RC6Engine.cs b/crypto/src/crypto/engines/RC6Engine.cs index d72cc2f7b..196bd8394 100644 --- a/crypto/src/crypto/engines/RC6Engine.cs +++ b/crypto/src/crypto/engines/RC6Engine.cs @@ -48,17 +48,17 @@ namespace Org.BouncyCastle.Crypto.Engines // _S = null; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "RC6"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return 4 * bytesPerWord; } @@ -71,7 +71,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -84,7 +84,7 @@ namespace Org.BouncyCastle.Crypto.Engines SetKey(p.GetKey()); } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, @@ -93,17 +93,16 @@ namespace Org.BouncyCastle.Crypto.Engines int blockSize = GetBlockSize(); if (_S == null) throw new InvalidOperationException("RC6 engine not initialised"); - if ((inOff + blockSize) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + blockSize) > output.Length) - throw new DataLengthException("output buffer too short"); - return (forEncryption) + Check.DataLength(input, inOff, blockSize, "input buffer too short"); + Check.OutputLength(output, outOff, blockSize, "output buffer too short"); + + return (forEncryption) ? EncryptBlock(input, inOff, output, outOff) : DecryptBlock(input, inOff, output, outOff); } - public void Reset() + public virtual void Reset() { } @@ -358,5 +357,4 @@ namespace Org.BouncyCastle.Crypto.Engines } } } - } diff --git a/crypto/src/crypto/engines/RFC3211WrapEngine.cs b/crypto/src/crypto/engines/RFC3211WrapEngine.cs index e520075f9..4e3af5227 100644 --- a/crypto/src/crypto/engines/RFC3211WrapEngine.cs +++ b/crypto/src/crypto/engines/RFC3211WrapEngine.cs @@ -24,7 +24,7 @@ namespace Org.BouncyCastle.Crypto.Engines this.engine = new CbcBlockCipher(engine); } - public void Init( + public virtual void Init( bool forWrapping, ICipherParameters param) { @@ -48,12 +48,12 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public string AlgorithmName + public virtual string AlgorithmName { get { return engine.GetUnderlyingCipher().AlgorithmName + "/RFC3211Wrap"; } } - public byte[] Wrap( + public virtual byte[] Wrap( byte[] inBytes, int inOff, int inLen) @@ -99,7 +99,7 @@ namespace Org.BouncyCastle.Crypto.Engines return cekBlock; } - public byte[] Unwrap( + public virtual byte[] Unwrap( byte[] inBytes, int inOff, int inLen) diff --git a/crypto/src/crypto/engines/RFC3394WrapEngine.cs b/crypto/src/crypto/engines/RFC3394WrapEngine.cs index 5615a63e5..4bb0e2114 100644 --- a/crypto/src/crypto/engines/RFC3394WrapEngine.cs +++ b/crypto/src/crypto/engines/RFC3394WrapEngine.cs @@ -32,7 +32,7 @@ namespace Org.BouncyCastle.Crypto.Engines this.engine = engine; } - public void Init( + public virtual void Init( bool forWrapping, ICipherParameters parameters) { @@ -64,12 +64,12 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public string AlgorithmName + public virtual string AlgorithmName { get { return engine.AlgorithmName; } } - public byte[] Wrap( + public virtual byte[] Wrap( byte[] input, int inOff, int inLen) @@ -119,7 +119,7 @@ namespace Org.BouncyCastle.Crypto.Engines return block; } - public byte[] Unwrap( + public virtual byte[] Unwrap( byte[] input, int inOff, int inLen) diff --git a/crypto/src/crypto/engines/RSABlindedEngine.cs b/crypto/src/crypto/engines/RSABlindedEngine.cs index cdf69ddda..037abf7e9 100644 --- a/crypto/src/crypto/engines/RSABlindedEngine.cs +++ b/crypto/src/crypto/engines/RSABlindedEngine.cs @@ -17,7 +17,7 @@ namespace Org.BouncyCastle.Crypto.Engines private RsaKeyParameters key; private SecureRandom random; - public string AlgorithmName + public virtual string AlgorithmName { get { return "RSA"; } } @@ -28,7 +28,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary RSA key parameters. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters param) { @@ -55,7 +55,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return maximum size for an input block. */ - public int GetInputBlockSize() + public virtual int GetInputBlockSize() { return core.GetInputBlockSize(); } @@ -67,7 +67,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return maximum size for an output block. */ - public int GetOutputBlockSize() + public virtual int GetOutputBlockSize() { return core.GetOutputBlockSize(); } @@ -81,7 +81,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @return the result of the RSA process. * @exception DataLengthException the input block is too large. */ - public byte[] ProcessBlock( + public virtual byte[] ProcessBlock( byte[] inBuf, int inOff, int inLen) diff --git a/crypto/src/crypto/engines/RSABlindingEngine.cs b/crypto/src/crypto/engines/RSABlindingEngine.cs index 76b57a3f7..c636627bf 100644 --- a/crypto/src/crypto/engines/RSABlindingEngine.cs +++ b/crypto/src/crypto/engines/RSABlindingEngine.cs @@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crypto.Engines private bool forEncryption; - public string AlgorithmName + public virtual string AlgorithmName { get { return "RSA"; } } @@ -32,7 +32,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @param forEncryption true if we are encrypting (blinding), false otherwise. * @param param the necessary RSA key parameters. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters param) { @@ -63,7 +63,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return maximum size for an input block. */ - public int GetInputBlockSize() + public virtual int GetInputBlockSize() { return core.GetInputBlockSize(); } @@ -75,7 +75,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return maximum size for an output block. */ - public int GetOutputBlockSize() + public virtual int GetOutputBlockSize() { return core.GetOutputBlockSize(); } @@ -89,7 +89,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @return the result of the RSA process. * @throws DataLengthException the input block is too large. */ - public byte[] ProcessBlock( + public virtual byte[] ProcessBlock( byte[] inBuf, int inOff, int inLen) diff --git a/crypto/src/crypto/engines/RSACoreEngine.cs b/crypto/src/crypto/engines/RSACoreEngine.cs index 4e64d25d6..38326371f 100644 --- a/crypto/src/crypto/engines/RSACoreEngine.cs +++ b/crypto/src/crypto/engines/RSACoreEngine.cs @@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary RSA key parameters. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -45,7 +45,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return maximum size for an input block. */ - public int GetInputBlockSize() + public virtual int GetInputBlockSize() { if (forEncryption) { @@ -62,7 +62,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return maximum size for an output block. */ - public int GetOutputBlockSize() + public virtual int GetOutputBlockSize() { if (forEncryption) { @@ -72,7 +72,7 @@ namespace Org.BouncyCastle.Crypto.Engines return (bitSize - 1) / 8; } - public BigInteger ConvertInput( + public virtual BigInteger ConvertInput( byte[] inBuf, int inOff, int inLen) @@ -90,7 +90,7 @@ namespace Org.BouncyCastle.Crypto.Engines return input; } - public byte[] ConvertOutput( + public virtual byte[] ConvertOutput( BigInteger result) { byte[] output = result.ToByteArrayUnsigned(); @@ -112,7 +112,7 @@ namespace Org.BouncyCastle.Crypto.Engines return output; } - public BigInteger ProcessBlock( + public virtual BigInteger ProcessBlock( BigInteger input) { if (key is RsaPrivateCrtKeyParameters) diff --git a/crypto/src/crypto/engines/RijndaelEngine.cs b/crypto/src/crypto/engines/RijndaelEngine.cs index df2e5baea..80f522353 100644 --- a/crypto/src/crypto/engines/RijndaelEngine.cs +++ b/crypto/src/crypto/engines/RijndaelEngine.cs @@ -571,7 +571,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -585,43 +585,34 @@ namespace Org.BouncyCastle.Crypto.Engines throw new ArgumentException("invalid parameter passed to Rijndael init - " + parameters.GetType().ToString()); } - public string AlgorithmName + public virtual string AlgorithmName { get { return "Rijndael"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BC / 2; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, int outOff) { if (workingKey == null) - { throw new InvalidOperationException("Rijndael engine not initialised"); - } - - if ((inOff + (BC / 2)) > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - if ((outOff + (BC / 2)) > output.Length) - { - throw new DataLengthException("output buffer too short"); - } + Check.DataLength(input, inOff, (BC / 2), "input buffer too short"); + Check.OutputLength(output, outOff, (BC / 2), "output buffer too short"); - UnPackBlock(input, inOff); + UnPackBlock(input, inOff); if (forEncryption) { @@ -637,11 +628,11 @@ namespace Org.BouncyCastle.Crypto.Engines return BC / 2; } - public void Reset() + public virtual void Reset() { } - private void UnPackBlock( + private void UnPackBlock( byte[] bytes, int off) { @@ -743,5 +734,4 @@ namespace Org.BouncyCastle.Crypto.Engines KeyAddition(rk[0]); } } - } diff --git a/crypto/src/crypto/engines/RsaEngine.cs b/crypto/src/crypto/engines/RsaEngine.cs index 7e6dfb163..4399b4409 100644 --- a/crypto/src/crypto/engines/RsaEngine.cs +++ b/crypto/src/crypto/engines/RsaEngine.cs @@ -10,7 +10,7 @@ namespace Org.BouncyCastle.Crypto.Engines { private RsaCoreEngine core; - public string AlgorithmName + public virtual string AlgorithmName { get { return "RSA"; } } @@ -21,7 +21,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @param forEncryption true if we are encrypting, false otherwise. * @param param the necessary RSA key parameters. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -38,7 +38,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return maximum size for an input block. */ - public int GetInputBlockSize() + public virtual int GetInputBlockSize() { return core.GetInputBlockSize(); } @@ -50,7 +50,7 @@ namespace Org.BouncyCastle.Crypto.Engines * * @return maximum size for an output block. */ - public int GetOutputBlockSize() + public virtual int GetOutputBlockSize() { return core.GetOutputBlockSize(); } @@ -64,7 +64,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @return the result of the RSA process. * @exception DataLengthException the input block is too large. */ - public byte[] ProcessBlock( + public virtual byte[] ProcessBlock( byte[] inBuf, int inOff, int inLen) diff --git a/crypto/src/crypto/engines/SEEDEngine.cs b/crypto/src/crypto/engines/SEEDEngine.cs index efea0f1fe..f615b8476 100644 --- a/crypto/src/crypto/engines/SEEDEngine.cs +++ b/crypto/src/crypto/engines/SEEDEngine.cs @@ -168,7 +168,7 @@ namespace Org.BouncyCastle.Crypto.Engines private int[] wKey; private bool forEncryption; - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -176,22 +176,22 @@ namespace Org.BouncyCastle.Crypto.Engines wKey = createWorkingKey(((KeyParameter)parameters).GetKey()); } - public string AlgorithmName + public virtual string AlgorithmName { get { return "SEED"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BlockSize; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] inBuf, int inOff, byte[] outBuf, @@ -199,12 +199,11 @@ namespace Org.BouncyCastle.Crypto.Engines { if (wKey == null) throw new InvalidOperationException("SEED engine not initialised"); - if (inOff + BlockSize > inBuf.Length) - throw new DataLengthException("input buffer too short"); - if (outOff + BlockSize > outBuf.Length) - throw new DataLengthException("output buffer too short"); - long l = bytesToLong(inBuf, inOff + 0); + Check.DataLength(inBuf, inOff, BlockSize, "input buffer too short"); + Check.OutputLength(outBuf, outOff, BlockSize, "output buffer too short"); + + long l = bytesToLong(inBuf, inOff + 0); long r = bytesToLong(inBuf, inOff + 8); if (forEncryption) @@ -234,7 +233,7 @@ namespace Org.BouncyCastle.Crypto.Engines return BlockSize; } - public void Reset() + public virtual void Reset() { } diff --git a/crypto/src/crypto/engines/Salsa20Engine.cs b/crypto/src/crypto/engines/Salsa20Engine.cs index 81884d603..9b27dc7b4 100644 --- a/crypto/src/crypto/engines/Salsa20Engine.cs +++ b/crypto/src/crypto/engines/Salsa20Engine.cs @@ -61,7 +61,7 @@ namespace Org.BouncyCastle.Crypto.Engines this.rounds = rounds; } - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -108,7 +108,7 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public byte ReturnByte( + public virtual byte ReturnByte( byte input) { if (LimitExceeded()) @@ -136,7 +136,7 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public void ProcessBytes( + public virtual void ProcessBytes( byte[] inBytes, int inOff, int len, @@ -144,26 +144,15 @@ namespace Org.BouncyCastle.Crypto.Engines int outOff) { if (!initialised) - { throw new InvalidOperationException(AlgorithmName + " not initialised"); - } - if ((inOff + len) > inBytes.Length) - { - throw new DataLengthException("input buffer too short"); - } + Check.DataLength(inBytes, inOff, len, "input buffer too short"); + Check.OutputLength(outBytes, outOff, len, "output buffer too short"); - if ((outOff + len) > outBytes.Length) - { - throw new DataLengthException("output buffer too short"); - } - - if (LimitExceeded((uint)len)) - { + if (LimitExceeded((uint)len)) throw new MaxBytesExceededException("2^70 byte limit per IV would be exceeded; Change IV"); - } - for (int i = 0; i < len; i++) + for (int i = 0; i < len; i++) { if (index == 0) { @@ -175,7 +164,7 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public void Reset() + public virtual void Reset() { index = 0; ResetLimitCounter(); diff --git a/crypto/src/crypto/engines/SerpentEngine.cs b/crypto/src/crypto/engines/SerpentEngine.cs index 92b25acc6..255c204ab 100644 --- a/crypto/src/crypto/engines/SerpentEngine.cs +++ b/crypto/src/crypto/engines/SerpentEngine.cs @@ -37,7 +37,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -48,17 +48,17 @@ namespace Org.BouncyCastle.Crypto.Engines this.wKey = MakeWorkingKey(((KeyParameter)parameters).GetKey()); } - public string AlgorithmName + public virtual string AlgorithmName { get { return "Serpent"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BLOCK_SIZE; } @@ -76,7 +76,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception InvalidOperationException if the cipher isn't initialised. * @return the number of bytes processed and produced. */ - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, @@ -84,12 +84,11 @@ namespace Org.BouncyCastle.Crypto.Engines { if (wKey == null) throw new InvalidOperationException("Serpent not initialised"); - if ((inOff + BLOCK_SIZE) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + BLOCK_SIZE) > output.Length) - throw new DataLengthException("output buffer too short"); - if (encrypting) + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) { EncryptBlock(input, inOff, output, outOff); } @@ -101,7 +100,7 @@ namespace Org.BouncyCastle.Crypto.Engines return BLOCK_SIZE; } - public void Reset() + public virtual void Reset() { } @@ -775,5 +774,4 @@ namespace Org.BouncyCastle.Crypto.Engines X0 = RotateRight(x0, 13); } } - } diff --git a/crypto/src/crypto/engines/SkipjackEngine.cs b/crypto/src/crypto/engines/SkipjackEngine.cs index 3d2a781e6..a45dc9b24 100644 --- a/crypto/src/crypto/engines/SkipjackEngine.cs +++ b/crypto/src/crypto/engines/SkipjackEngine.cs @@ -43,7 +43,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the parameters argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -71,22 +71,22 @@ namespace Org.BouncyCastle.Crypto.Engines } } - public string AlgorithmName + public virtual string AlgorithmName { get { return "SKIPJACK"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return BLOCK_SIZE; } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] input, int inOff, byte[] output, @@ -94,12 +94,11 @@ namespace Org.BouncyCastle.Crypto.Engines { if (key1 == null) throw new InvalidOperationException("SKIPJACK engine not initialised"); - if ((inOff + BLOCK_SIZE) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + BLOCK_SIZE) > output.Length) - throw new DataLengthException("output buffer too short"); - if (encrypting) + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) { EncryptBlock(input, inOff, output, outOff); } @@ -111,7 +110,7 @@ namespace Org.BouncyCastle.Crypto.Engines return BLOCK_SIZE; } - public void Reset() + public virtual void Reset() { } @@ -135,7 +134,7 @@ namespace Org.BouncyCastle.Crypto.Engines return ((g5 << 8) + g6); } - public int EncryptBlock( + public virtual int EncryptBlock( byte[] input, int inOff, byte[] outBytes, @@ -203,7 +202,7 @@ namespace Org.BouncyCastle.Crypto.Engines return ((h6 << 8) + h5); } - public int DecryptBlock( + public virtual int DecryptBlock( byte[] input, int inOff, byte[] outBytes, @@ -251,5 +250,4 @@ namespace Org.BouncyCastle.Crypto.Engines return BLOCK_SIZE; } } - } diff --git a/crypto/src/crypto/engines/TEAEngine.cs b/crypto/src/crypto/engines/TEAEngine.cs index 582dd0f73..2e1a7002b 100644 --- a/crypto/src/crypto/engines/TEAEngine.cs +++ b/crypto/src/crypto/engines/TEAEngine.cs @@ -36,17 +36,17 @@ namespace Org.BouncyCastle.Crypto.Engines _initialised = false; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "TEA"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return block_size; } @@ -59,7 +59,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the params argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -77,7 +77,7 @@ namespace Org.BouncyCastle.Crypto.Engines setKey(p.GetKey()); } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] inBytes, int inOff, byte[] outBytes, @@ -86,18 +86,15 @@ namespace Org.BouncyCastle.Crypto.Engines if (!_initialised) throw new InvalidOperationException(AlgorithmName + " not initialised"); - if ((inOff + block_size) > inBytes.Length) - throw new DataLengthException("input buffer too short"); + Check.DataLength(inBytes, inOff, block_size, "input buffer too short"); + Check.OutputLength(outBytes, outOff, block_size, "output buffer too short"); - if ((outOff + block_size) > outBytes.Length) - throw new DataLengthException("output buffer too short"); - - return _forEncryption + return _forEncryption ? encryptBlock(inBytes, inOff, outBytes, outOff) : decryptBlock(inBytes, inOff, outBytes, outOff); } - public void Reset() + public virtual void Reset() { } diff --git a/crypto/src/crypto/engines/ThreefishEngine.cs b/crypto/src/crypto/engines/ThreefishEngine.cs index 954470345..33ff3a421 100644 --- a/crypto/src/crypto/engines/ThreefishEngine.cs +++ b/crypto/src/crypto/engines/ThreefishEngine.cs @@ -155,7 +155,7 @@ namespace Org.BouncyCastle.Crypto.Engines /// <param name="forEncryption">Initialise for encryption if true, for decryption if false.</param> /// <param name="parameters">an instance of <see cref="TweakableBlockCipherParameters"/> or <see cref="KeyParameter"/> (to /// use a 0 tweak)</param> - public void Init(bool forEncryption, ICipherParameters parameters) + public virtual void Init(bool forEncryption, ICipherParameters parameters) { byte[] keyBytes; byte[] tweakBytes; @@ -266,26 +266,26 @@ namespace Org.BouncyCastle.Crypto.Engines t[4] = t[1]; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "Threefish-" + (blocksizeBytes * 8); } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return blocksizeBytes; } - public void Reset() + public virtual void Reset() { } - public int ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff) + public virtual int ProcessBlock(byte[] inBytes, int inOff, byte[] outBytes, int outOff) { if ((outOff + blocksizeBytes) > outBytes.Length) { diff --git a/crypto/src/crypto/engines/TwofishEngine.cs b/crypto/src/crypto/engines/TwofishEngine.cs index b983d9d31..04a579ced 100644 --- a/crypto/src/crypto/engines/TwofishEngine.cs +++ b/crypto/src/crypto/engines/TwofishEngine.cs @@ -293,12 +293,11 @@ namespace Org.BouncyCastle.Crypto.Engines { if (workingKey == null) throw new InvalidOperationException("Twofish not initialised"); - if ((inOff + BLOCK_SIZE) > input.Length) - throw new DataLengthException("input buffer too short"); - if ((outOff + BLOCK_SIZE) > output.Length) - throw new DataLengthException("output buffer too short"); - if (encrypting) + Check.DataLength(input, inOff, BLOCK_SIZE, "input buffer too short"); + Check.OutputLength(output, outOff, BLOCK_SIZE, "output buffer too short"); + + if (encrypting) { EncryptBlock(input, inOff, output, outOff); } diff --git a/crypto/src/crypto/engines/VMPCEngine.cs b/crypto/src/crypto/engines/VMPCEngine.cs index 1c2802a80..852901e36 100644 --- a/crypto/src/crypto/engines/VMPCEngine.cs +++ b/crypto/src/crypto/engines/VMPCEngine.cs @@ -92,15 +92,8 @@ namespace Org.BouncyCastle.Crypto.Engines byte[] output, int outOff) { - if ((inOff + len) > input.Length) - { - throw new DataLengthException("input buffer too short"); - } - - if ((outOff + len) > output.Length) - { - throw new DataLengthException("output buffer too short"); - } + Check.DataLength(input, inOff, len, "input buffer too short"); + Check.OutputLength(output, outOff, len, "output buffer too short"); for (int i = 0; i < len; i++) { diff --git a/crypto/src/crypto/engines/XSalsa20Engine.cs b/crypto/src/crypto/engines/XSalsa20Engine.cs index fc6630905..2898b46c8 100644 --- a/crypto/src/crypto/engines/XSalsa20Engine.cs +++ b/crypto/src/crypto/engines/XSalsa20Engine.cs @@ -13,7 +13,6 @@ namespace Org.BouncyCastle.Crypto.Engines public class XSalsa20Engine : Salsa20Engine { - public override string AlgorithmName { get { return "XSalsa20"; } @@ -65,7 +64,6 @@ namespace Org.BouncyCastle.Crypto.Engines // Counter reset ResetCounter(); } - } } diff --git a/crypto/src/crypto/engines/XTEAEngine.cs b/crypto/src/crypto/engines/XTEAEngine.cs index eb9291775..40d81fbe6 100644 --- a/crypto/src/crypto/engines/XTEAEngine.cs +++ b/crypto/src/crypto/engines/XTEAEngine.cs @@ -34,17 +34,17 @@ namespace Org.BouncyCastle.Crypto.Engines _initialised = false; } - public string AlgorithmName + public virtual string AlgorithmName { get { return "XTEA"; } } - public bool IsPartialBlockOkay + public virtual bool IsPartialBlockOkay { get { return false; } } - public int GetBlockSize() + public virtual int GetBlockSize() { return block_size; } @@ -57,7 +57,7 @@ namespace Org.BouncyCastle.Crypto.Engines * @exception ArgumentException if the params argument is * inappropriate. */ - public void Init( + public virtual void Init( bool forEncryption, ICipherParameters parameters) { @@ -75,7 +75,7 @@ namespace Org.BouncyCastle.Crypto.Engines setKey(p.GetKey()); } - public int ProcessBlock( + public virtual int ProcessBlock( byte[] inBytes, int inOff, byte[] outBytes, @@ -84,18 +84,15 @@ namespace Org.BouncyCastle.Crypto.Engines if (!_initialised) throw new InvalidOperationException(AlgorithmName + " not initialised"); - if ((inOff + block_size) > inBytes.Length) - throw new DataLengthException("input buffer too short"); + Check.DataLength(inBytes, inOff, block_size, "input buffer too short"); + Check.OutputLength(outBytes, outOff, block_size, "output buffer too short"); - if ((outOff + block_size) > outBytes.Length) - throw new DataLengthException("output buffer too short"); - - return _forEncryption + return _forEncryption ? encryptBlock(inBytes, inOff, outBytes, outOff) : decryptBlock(inBytes, inOff, outBytes, outOff); } - public void Reset() + public virtual void Reset() { } diff --git a/crypto/src/crypto/generators/RsaKeyPairGenerator.cs b/crypto/src/crypto/generators/RsaKeyPairGenerator.cs index e870f1c08..c46865991 100644 --- a/crypto/src/crypto/generators/RsaKeyPairGenerator.cs +++ b/crypto/src/crypto/generators/RsaKeyPairGenerator.cs @@ -11,117 +11,130 @@ namespace Org.BouncyCastle.Crypto.Generators * an RSA key pair generator. */ public class RsaKeyPairGenerator - : IAsymmetricCipherKeyPairGenerator + : IAsymmetricCipherKeyPairGenerator { - private static readonly BigInteger DefaultPublicExponent = BigInteger.ValueOf(0x10001); - private const int DefaultTests = 12; + protected static readonly BigInteger One = BigInteger.One; + protected static readonly BigInteger DefaultPublicExponent = BigInteger.ValueOf(0x10001); + protected const int DefaultTests = 100; - private RsaKeyGenerationParameters param; + protected RsaKeyGenerationParameters parameters; - public void Init( + public virtual void Init( KeyGenerationParameters parameters) { if (parameters is RsaKeyGenerationParameters) { - this.param = (RsaKeyGenerationParameters)parameters; + this.parameters = (RsaKeyGenerationParameters)parameters; } else { - this.param = new RsaKeyGenerationParameters( + this.parameters = new RsaKeyGenerationParameters( DefaultPublicExponent, parameters.Random, parameters.Strength, DefaultTests); } } - public AsymmetricCipherKeyPair GenerateKeyPair() + public virtual AsymmetricCipherKeyPair GenerateKeyPair() { - BigInteger p, q, n, d, e, pSub1, qSub1, phi; - - // - // p and q values should have a length of half the strength in bits - // - int strength = param.Strength; - int qBitlength = strength >> 1; - int pBitlength = strength - qBitlength; - int mindiffbits = strength / 3; - int minWeight = strength >> 2; - - e = param.PublicExponent; + for (;;) + { + // + // p and q values should have a length of half the strength in bits + // + int strength = parameters.Strength; + int pbitlength = (strength + 1) / 2; + int qbitlength = strength - pbitlength; + int mindiffbits = strength / 3; + int minWeight = strength >> 2; - // TODO Consider generating safe primes for p, q (see DHParametersHelper.GenerateSafePrimes) - // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") + //// d lower bound is 2^(strength / 2) + //BigInteger dLowerBound = BigInteger.Two.Pow(strength / 2); - p = ChooseRandomPrime(pBitlength, e); + BigInteger e = parameters.PublicExponent; - // - // Generate a modulus of the required length - // - for (;;) - { - q = ChooseRandomPrime(qBitlength, e); + // TODO Consider generating safe primes for p, q (see DHParametersHelper.generateSafePrimes) + // (then p-1 and q-1 will not consist of only small factors - see "Pollard's algorithm") - // p and q should not be too close together (or equal!) - BigInteger diff = q.Subtract(p).Abs(); - if (diff.BitLength < mindiffbits) - continue; + BigInteger p = ChooseRandomPrime(pbitlength, e); + BigInteger q, n; // - // calculate the modulus + // generate a modulus of the required length // - n = p.Multiply(q); - - if (n.BitLength != strength) + for (;;) { + q = ChooseRandomPrime(qbitlength, e); + + // p and q should not be too close together (or equal!) + BigInteger diff = q.Subtract(p).Abs(); + if (diff.BitLength < mindiffbits) + continue; + // - // if we get here our primes aren't big enough, make the largest - // of the two p and try again + // calculate the modulus // - p = p.Max(q); - continue; + n = p.Multiply(q); + + if (n.BitLength != strength) + { + // + // if we get here our primes aren't big enough, make the largest + // of the two p and try again + // + p = p.Max(q); + continue; + } + + /* + * Require a minimum weight of the NAF representation, since low-weight composites may + * be weak against a version of the number-field-sieve for factoring. + * + * See "The number field sieve for integers of low weight", Oliver Schirokauer. + */ + if (WNafUtilities.GetNafWeight(n) < minWeight) + { + p = ChooseRandomPrime(pbitlength, e); + continue; + } + + break; } - /* - * Require a minimum weight of the NAF representation, since low-weight composites may - * be weak against a version of the number-field-sieve for factoring. - * - * See "The number field sieve for integers of low weight", Oliver Schirokauer. - */ - if (WNafUtilities.GetNafWeight(n) < minWeight) + if (p.CompareTo(q) < 0) { - p = ChooseRandomPrime(pBitlength, e); - continue; + BigInteger tmp = p; + p = q; + q = tmp; } - break; - } - - if (p.CompareTo(q) < 0) - { - phi = p; - p = q; - q = phi; - } + BigInteger pSub1 = p.Subtract(One); + BigInteger qSub1 = q.Subtract(One); + BigInteger phi = pSub1.Multiply(qSub1); + //BigInteger lcm = phi.Divide(pSub1.Gcd(qSub1)); - pSub1 = p.Subtract(BigInteger.One); - qSub1 = q.Subtract(BigInteger.One); - phi = pSub1.Multiply(qSub1); + // + // calculate the private exponent + // + //BigInteger d = e.ModInverse(lcm); + BigInteger d = e.ModInverse(phi); - // - // calculate the private exponent - // - d = e.ModInverse(phi); + // if d is less than or equal to dLowerBound, we need to start over + // also, for backward compatibility, if d is not the same as + // e.modInverse(phi), we need to start over - // - // calculate the CRT factors - // - BigInteger dP, dQ, qInv; + if (d.BitLength <= qbitlength)// || !d.Multiply(e).Mod(phi).Equals(One)) + continue; - dP = d.Remainder(pSub1); - dQ = d.Remainder(qSub1); - qInv = q.ModInverse(p); + // + // calculate the CRT factors + // + BigInteger dP = d.Remainder(pSub1); + BigInteger dQ = d.Remainder(qSub1); + BigInteger qInv = q.ModInverse(p); - return new AsymmetricCipherKeyPair( - new RsaKeyParameters(false, n, e), - new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)); + return new AsymmetricCipherKeyPair( + new RsaKeyParameters(false, n, e), + new RsaPrivateCrtKeyParameters(n, e, d, p, q, dP, dQ, qInv)); + } } /// <summary>Choose a random prime value for use with RSA</summary> @@ -132,15 +145,15 @@ namespace Org.BouncyCastle.Crypto.Generators { for (;;) { - BigInteger p = new BigInteger(bitlength, 1, param.Random); + BigInteger p = new BigInteger(bitlength, 1, parameters.Random); - if (p.Mod(e).Equals(BigInteger.One)) + if (p.Mod(e).Equals(One)) continue; - if (!p.IsProbablePrime(param.Certainty)) + if (!p.IsProbablePrime(parameters.Certainty)) continue; - if (!e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One)) + if (!e.Gcd(p.Subtract(One)).Equals(One)) continue; return p; diff --git a/crypto/src/crypto/modes/CcmBlockCipher.cs b/crypto/src/crypto/modes/CcmBlockCipher.cs index 653d75cb9..e0b1e6b54 100644 --- a/crypto/src/crypto/modes/CcmBlockCipher.cs +++ b/crypto/src/crypto/modes/CcmBlockCipher.cs @@ -61,6 +61,7 @@ namespace Org.BouncyCastle.Crypto.Modes { this.forEncryption = forEncryption; + ICipherParameters cipherParameters; if (parameters is AeadParameters) { AeadParameters param = (AeadParameters) parameters; @@ -68,7 +69,7 @@ namespace Org.BouncyCastle.Crypto.Modes nonce = param.GetNonce(); initialAssociatedText = param.GetAssociatedText(); macSize = param.MacSize / 8; - keyParam = param.Key; + cipherParameters = param.Key; } else if (parameters is ParametersWithIV) { @@ -77,17 +78,25 @@ namespace Org.BouncyCastle.Crypto.Modes nonce = param.GetIV(); initialAssociatedText = null; macSize = macBlock.Length / 2; - keyParam = param.Parameters; + cipherParameters = param.Parameters; } else { throw new ArgumentException("invalid parameters passed to CCM"); } + // NOTE: Very basic support for key re-use, but no performance gain from it + if (cipherParameters != null) + { + keyParam = cipherParameters; + } + if (nonce == null || nonce.Length < 7 || nonce.Length > 13) { throw new ArgumentException("nonce must have length from 7 to 13 octets"); } + + Reset(); } public virtual string AlgorithmName @@ -128,6 +137,8 @@ namespace Org.BouncyCastle.Crypto.Modes byte[] outBytes, int outOff) { + Check.DataLength(inBytes, inOff, inLen, "Input buffer too short"); + data.Write(inBytes, inOff, inLen); return 0; @@ -137,13 +148,11 @@ namespace Org.BouncyCastle.Crypto.Modes byte[] outBytes, int outOff) { - byte[] enc = ProcessPacket(data.GetBuffer(), 0, (int)data.Position); - - Array.Copy(enc, 0, outBytes, outOff, enc.Length); + int len = ProcessPacket(data.GetBuffer(), 0, (int)data.Position, outBytes, outOff); Reset(); - return enc.Length; + return len; } public virtual void Reset() @@ -161,11 +170,7 @@ namespace Org.BouncyCastle.Crypto.Modes */ public virtual byte[] GetMac() { - byte[] mac = new byte[macSize]; - - Array.Copy(macBlock, 0, mac, 0, mac.Length); - - return mac; + return Arrays.CopyOfRange(macBlock, 0, macSize); } public virtual int GetUpdateOutputSize( @@ -174,7 +179,7 @@ namespace Org.BouncyCastle.Crypto.Modes return 0; } - public int GetOutputSize( + public virtual int GetOutputSize( int len) { int totalData = (int)data.Length + len; @@ -187,10 +192,51 @@ namespace Org.BouncyCastle.Crypto.Modes return totalData < macSize ? 0 : totalData - macSize; } - public byte[] ProcessPacket( - byte[] input, - int inOff, - int inLen) + /** + * Process a packet of data for either CCM decryption or encryption. + * + * @param in data for processing. + * @param inOff offset at which data starts in the input array. + * @param inLen length of the data in the input array. + * @return a byte array containing the processed input.. + * @throws IllegalStateException if the cipher is not appropriately set up. + * @throws InvalidCipherTextException if the input data is truncated or the mac check fails. + */ + public virtual byte[] ProcessPacket(byte[] input, int inOff, int inLen) + { + byte[] output; + + if (forEncryption) + { + output = new byte[inLen + macSize]; + } + else + { + if (inLen < macSize) + throw new InvalidCipherTextException("data too short"); + + output = new byte[inLen - macSize]; + } + + ProcessPacket(input, inOff, inLen, output, 0); + + return output; + } + + /** + * Process a packet of data for either CCM decryption or encryption. + * + * @param in data for processing. + * @param inOff offset at which data starts in the input array. + * @param inLen length of the data in the input array. + * @param output output array. + * @param outOff offset into output array to start putting processed bytes. + * @return the number of bytes added to output. + * @throws IllegalStateException if the cipher is not appropriately set up. + * @throws InvalidCipherTextException if the input data is truncated or the mac check fails. + * @throws DataLengthException if output buffer too short. + */ + public virtual int ProcessPacket(byte[] input, int inOff, int inLen, byte[] output, int outOff) { // TODO: handle null keyParam (e.g. via RepeatedKeySpec) // Need to keep the CTR and CBC Mac parts around and reset @@ -213,42 +259,45 @@ namespace Org.BouncyCastle.Crypto.Modes IBlockCipher ctrCipher = new SicBlockCipher(cipher); ctrCipher.Init(forEncryption, new ParametersWithIV(keyParam, iv)); - int index = inOff; - int outOff = 0; - byte[] output; + int outputLen; + int inIndex = inOff; + int outIndex = outOff; if (forEncryption) { - output = new byte[inLen + macSize]; + outputLen = inLen + macSize; + Check.OutputLength(output, outOff, outputLen, "Output buffer too short."); calculateMac(input, inOff, inLen, macBlock); ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0); // S0 - while (index < inLen - BlockSize) // S1... + while (inIndex < (inOff + inLen - BlockSize)) // S1... { - ctrCipher.ProcessBlock(input, index, output, outOff); - outOff += BlockSize; - index += BlockSize; + ctrCipher.ProcessBlock(input, inIndex, output, outIndex); + outIndex += BlockSize; + inIndex += BlockSize; } byte[] block = new byte[BlockSize]; - Array.Copy(input, index, block, 0, inLen - index); + Array.Copy(input, inIndex, block, 0, inLen + inOff - inIndex); ctrCipher.ProcessBlock(block, 0, block, 0); - Array.Copy(block, 0, output, outOff, inLen - index); + Array.Copy(block, 0, output, outIndex, inLen + inOff - inIndex); - outOff += inLen - index; - - Array.Copy(macBlock, 0, output, outOff, output.Length - outOff); + Array.Copy(macBlock, 0, output, outOff + inLen, macSize); } else { - output = new byte[inLen - macSize]; + if (inLen < macSize) + throw new InvalidCipherTextException("data too short"); - Array.Copy(input, inOff + inLen - macSize, macBlock, 0, macSize); + outputLen = inLen - macSize; + Check.OutputLength(output, outOff, outputLen, "Output buffer too short."); + + Array.Copy(input, inOff + outputLen, macBlock, 0, macSize); ctrCipher.ProcessBlock(macBlock, 0, macBlock, 0); @@ -257,30 +306,30 @@ namespace Org.BouncyCastle.Crypto.Modes macBlock[i] = 0; } - while (outOff < output.Length - BlockSize) + while (inIndex < (inOff + outputLen - BlockSize)) { - ctrCipher.ProcessBlock(input, index, output, outOff); - outOff += BlockSize; - index += BlockSize; + ctrCipher.ProcessBlock(input, inIndex, output, outIndex); + outIndex += BlockSize; + inIndex += BlockSize; } byte[] block = new byte[BlockSize]; - Array.Copy(input, index, block, 0, output.Length - outOff); + Array.Copy(input, inIndex, block, 0, outputLen - (inIndex - inOff)); ctrCipher.ProcessBlock(block, 0, block, 0); - Array.Copy(block, 0, output, outOff, output.Length - outOff); + Array.Copy(block, 0, output, outIndex, outputLen - (inIndex - inOff)); byte[] calculatedMacBlock = new byte[BlockSize]; - calculateMac(output, 0, output.Length, calculatedMacBlock); + calculateMac(output, outOff, outputLen, calculatedMacBlock); if (!Arrays.ConstantTimeAreEqual(macBlock, calculatedMacBlock)) throw new InvalidCipherTextException("mac check in CCM failed"); } - return output; + return outputLen; } private int calculateMac(byte[] data, int dataOff, int dataLen, byte[] macBlock) diff --git a/crypto/src/crypto/modes/EAXBlockCipher.cs b/crypto/src/crypto/modes/EAXBlockCipher.cs index 5ccc69b66..624f385b5 100644 --- a/crypto/src/crypto/modes/EAXBlockCipher.cs +++ b/crypto/src/crypto/modes/EAXBlockCipher.cs @@ -54,7 +54,6 @@ namespace Org.BouncyCastle.Crypto.Modes blockSize = cipher.GetBlockSize(); mac = new CMac(cipher); macBlock = new byte[blockSize]; - bufBlock = new byte[blockSize * 2]; associatedTextMac = new byte[mac.GetMacSize()]; nonceMac = new byte[mac.GetMacSize()]; this.cipher = new SicBlockCipher(cipher); @@ -65,7 +64,7 @@ namespace Org.BouncyCastle.Crypto.Modes get { return cipher.GetUnderlyingCipher().AlgorithmName + "/EAX"; } } - public IBlockCipher GetUnderlyingCipher() + public virtual IBlockCipher GetUnderlyingCipher() { return cipher; } @@ -107,6 +106,8 @@ namespace Org.BouncyCastle.Crypto.Modes throw new ArgumentException("invalid parameters passed to EAX"); } + bufBlock = new byte[forEncryption ? blockSize : (blockSize + macSize)]; + byte[] tag = new byte[blockSize]; // Key reuse implemented in CBC mode of underlying CMac @@ -117,16 +118,10 @@ namespace Org.BouncyCastle.Crypto.Modes mac.BlockUpdate(nonce, 0, nonce.Length); mac.DoFinal(nonceMac, 0); - tag[blockSize - 1] = (byte)Tag.H; - mac.BlockUpdate(tag, 0, blockSize); - - if (initialAssociatedText != null) - { - ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length); - } - - // Same BlockCipher underlies this and the mac, so reuse last key on cipher + // Same BlockCipher underlies this and the mac, so reuse last key on cipher cipher.Init(true, new ParametersWithIV(null, nonceMac)); + + Reset(); } private void InitCipher() @@ -191,16 +186,16 @@ namespace Org.BouncyCastle.Crypto.Modes { if (cipherInitialized) { - throw new InvalidOperationException("AAD data cannot be added after encryption/decription processing has begun."); + throw new InvalidOperationException("AAD data cannot be added after encryption/decryption processing has begun."); } mac.Update(input); } - public void ProcessAadBytes(byte[] inBytes, int inOff, int len) + public virtual void ProcessAadBytes(byte[] inBytes, int inOff, int len) { if (cipherInitialized) { - throw new InvalidOperationException("AAD data cannot be added after encryption/decription processing has begun."); + throw new InvalidOperationException("AAD data cannot be added after encryption/decryption processing has begun."); } mac.BlockUpdate(inBytes, inOff, len); } @@ -247,10 +242,11 @@ namespace Org.BouncyCastle.Crypto.Modes if (forEncryption) { - cipher.ProcessBlock(bufBlock, 0, tmp, 0); - cipher.ProcessBlock(bufBlock, blockSize, tmp, blockSize); + Check.OutputLength(outBytes, outOff, extra + macSize, "Output buffer too short"); + + cipher.ProcessBlock(bufBlock, 0, tmp, 0); - Array.Copy(tmp, 0, outBytes, outOff, extra); + Array.Copy(tmp, 0, outBytes, outOff, extra); mac.BlockUpdate(tmp, 0, extra); @@ -264,14 +260,18 @@ namespace Org.BouncyCastle.Crypto.Modes } else { - if (extra > macSize) + if (extra < macSize) + throw new InvalidCipherTextException("data too short"); + + Check.OutputLength(outBytes, outOff, extra - macSize, "Output buffer too short"); + + if (extra > macSize) { mac.BlockUpdate(bufBlock, 0, extra - macSize); cipher.ProcessBlock(bufBlock, 0, tmp, 0); - cipher.ProcessBlock(bufBlock, blockSize, tmp, blockSize); - Array.Copy(tmp, 0, outBytes, outOff, extra - macSize); + Array.Copy(tmp, 0, outBytes, outOff, extra - macSize); } CalculateMac(); @@ -331,6 +331,11 @@ namespace Org.BouncyCastle.Crypto.Modes if (bufOff == bufBlock.Length) { + Check.OutputLength(outBytes, outOff, blockSize, "Output buffer is too short"); + + // TODO Could move the ProcessByte(s) calls to here +// InitCipher(); + int size; if (forEncryption) @@ -346,10 +351,14 @@ namespace Org.BouncyCastle.Crypto.Modes size = cipher.ProcessBlock(bufBlock, 0, outBytes, outOff); } - bufOff = blockSize; - Array.Copy(bufBlock, blockSize, bufBlock, 0, blockSize); + bufOff = 0; + if (!forEncryption) + { + Array.Copy(bufBlock, blockSize, bufBlock, 0, macSize); + bufOff = macSize; + } - return size; + return size; } return 0; diff --git a/crypto/src/crypto/modes/GCMBlockCipher.cs b/crypto/src/crypto/modes/GCMBlockCipher.cs index 2e2ac2eca..8e6120eef 100644 --- a/crypto/src/crypto/modes/GCMBlockCipher.cs +++ b/crypto/src/crypto/modes/GCMBlockCipher.cs @@ -284,6 +284,9 @@ namespace Org.BouncyCastle.Crypto.Modes byte[] output, int outOff) { + if (input.Length < (inOff + len)) + throw new DataLengthException("Input buffer too short"); + int resultLen = 0; for (int i = 0; i < len; ++i) @@ -301,6 +304,7 @@ namespace Org.BouncyCastle.Crypto.Modes private void OutputBlock(byte[] output, int offset) { + Check.OutputLength(output, offset, BlockSize, "Output buffer too short"); if (totalLength == 0) { InitCipher(); @@ -325,12 +329,19 @@ namespace Org.BouncyCastle.Crypto.Modes } int extra = bufOff; - if (!forEncryption) + + if (forEncryption) + { + Check.OutputLength(output, outOff, extra + macSize, "Output buffer too short"); + } + else { if (extra < macSize) throw new InvalidCipherTextException("data too short"); extra -= macSize; + + Check.OutputLength(output, outOff, extra, "Output buffer too short"); } if (extra > 0) diff --git a/crypto/src/crypto/modes/OCBBlockCipher.cs b/crypto/src/crypto/modes/OCBBlockCipher.cs index 54359dfe8..e7dc466e6 100644 --- a/crypto/src/crypto/modes/OCBBlockCipher.cs +++ b/crypto/src/crypto/modes/OCBBlockCipher.cs @@ -355,6 +355,7 @@ namespace Org.BouncyCastle.Crypto.Modes Xor(mainBlock, Pad); + Check.OutputLength(output, outOff, mainBlockPos, "Output buffer too short"); Array.Copy(mainBlock, 0, output, outOff, mainBlockPos); if (!forEncryption) @@ -382,6 +383,8 @@ namespace Org.BouncyCastle.Crypto.Modes if (forEncryption) { + Check.OutputLength(output, outOff, resultLen + macSize, "Output buffer too short"); + // Append tag to the message Array.Copy(macBlock, 0, output, outOff + resultLen, macSize); resultLen += macSize; @@ -431,6 +434,8 @@ namespace Org.BouncyCastle.Crypto.Modes protected virtual void ProcessMainBlock(byte[] output, int outOff) { + Check.DataLength(output, outOff, BLOCK_SIZE, "Output buffer too short"); + /* * OCB-ENCRYPT/OCB-DECRYPT: Process any whole blocks */ diff --git a/crypto/src/crypto/modes/gcm/GcmUtilities.cs b/crypto/src/crypto/modes/gcm/GcmUtilities.cs index 0f241035f..de41d88f4 100644 --- a/crypto/src/crypto/modes/gcm/GcmUtilities.cs +++ b/crypto/src/crypto/modes/gcm/GcmUtilities.cs @@ -106,6 +106,29 @@ namespace Org.BouncyCastle.Crypto.Modes.Gcm x[3] = r13; } + internal static void Multiply(ulong[] x, ulong[] y) + { + ulong r00 = x[0], r01 = x[1], r10 = 0, r11 = 0; + + for (int i = 0; i < 2; ++i) + { + long bits = (long)y[i]; + for (int j = 0; j < 64; ++j) + { + ulong m1 = (ulong)(bits >> 63); bits <<= 1; + r10 ^= (r00 & m1); + r11 ^= (r01 & m1); + + ulong m2 = (r01 << 63) >> 8; + r01 = (r01 >> 1) | (r00 << 63); + r00 = (r00 >> 1) ^ (m2 & E1L); + } + } + + x[0] = r10; + x[1] = r11; + } + // P is the value with only bit i=1 set internal static void MultiplyP(uint[] x) { diff --git a/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs b/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs index fb8a92ba3..c291e4814 100644 --- a/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs +++ b/crypto/src/crypto/paddings/PaddedBufferedBlockCipher.cs @@ -178,10 +178,7 @@ namespace Org.BouncyCastle.Crypto.Paddings if (outLength > 0) { - if ((outOff + outLength) > output.Length) - { - throw new DataLengthException("output buffer too short"); - } + Check.OutputLength(output, outOff, outLength, "output buffer too short"); } int resultLen = 0; @@ -242,7 +239,7 @@ namespace Org.BouncyCastle.Crypto.Paddings { Reset(); - throw new DataLengthException("output buffer too short"); + throw new OutputLengthException("output buffer too short"); } resultLen = cipher.ProcessBlock(buf, 0, output, outOff); diff --git a/crypto/test/src/crypto/test/CCMTest.cs b/crypto/test/src/crypto/test/CCMTest.cs index 4a54fb4f9..8c46e11e7 100644 --- a/crypto/test/src/crypto/test/CCMTest.cs +++ b/crypto/test/src/crypto/test/CCMTest.cs @@ -81,7 +81,38 @@ namespace Org.BouncyCastle.Crypto.Tests // checkVectors(4, ccm, K4, 112, N4, A4, A4, T5, C5); - // + // decryption with output specified, non-zero offset. + ccm.Init(false, new AeadParameters(new KeyParameter(K2), 48, N2, A2)); + + byte[] inBuf = new byte[C2.Length + 10]; + byte[] outBuf = new byte[ccm.GetOutputSize(C2.Length) + 10]; + + Array.Copy(C2, 0, inBuf, 10, C2.Length); + + int len = ccm.ProcessPacket(inBuf, 10, C2.Length, outBuf, 10); + byte[] output = ccm.ProcessPacket(C2, 0, C2.Length); + + if (len != output.Length || !isEqual(output, outBuf, 10)) + { + Fail("decryption output incorrect"); + } + + // encryption with output specified, non-zero offset. + ccm.Init(true, new AeadParameters(new KeyParameter(K2), 48, N2, A2)); + + int inLen = len; + inBuf = outBuf; + outBuf = new byte[ccm.GetOutputSize(inLen) + 10]; + + len = ccm.ProcessPacket(inBuf, 10, inLen, outBuf, 10); + output = ccm.ProcessPacket(inBuf, 10, inLen); + + if (len != output.Length || !isEqual(output, outBuf, 10)) + { + Fail("encryption output incorrect"); + } + + // // exception tests // @@ -121,6 +152,17 @@ namespace Org.BouncyCastle.Crypto.Tests } } + private bool isEqual(byte[] exp, byte[] other, int off) + { + for (int i = 0; i != exp.Length; i++) + { + if (exp[i] != other[off + i]) + return false; + } + + return true; + } + private void checkVectors( int count, CcmBlockCipher ccm, @@ -203,7 +245,8 @@ namespace Org.BouncyCastle.Crypto.Tests if (!AreEqual(p, dec)) { - Fail("decrypted stream fails to match in test " + count + " with " + additionalDataType); + Fail("decrypted stream fails to match in test " + count + " with " + additionalDataType, + Hex.ToHexString(p), Hex.ToHexString(dec)); } if (!AreEqual(t, ccm.GetMac())) |