summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crypto/src/crypto/modes/KCcmBlockCipher.cs475
-rw-r--r--crypto/test/src/crypto/test/DSTU7624Test.cs306
2 files changed, 757 insertions, 24 deletions
diff --git a/crypto/src/crypto/modes/KCcmBlockCipher.cs b/crypto/src/crypto/modes/KCcmBlockCipher.cs
new file mode 100644
index 000000000..b5f121cef
--- /dev/null
+++ b/crypto/src/crypto/modes/KCcmBlockCipher.cs
@@ -0,0 +1,475 @@
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Utilities;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace Org.BouncyCastle.Crypto.Modes
+{
+    public class KCcmBlockCipher: IAeadBlockCipher
+    {
+        private static readonly int BYTES_IN_INT = 4;
+        private static readonly int BITS_IN_BYTE = 8;
+
+        private static readonly int MAX_MAC_BIT_LENGTH = 512;
+        private static readonly int MIN_MAC_BIT_LENGTH = 64;
+
+        private IBlockCipher engine;
+
+        private int macSize;
+        private bool forEncryption;
+
+        private byte[] initialAssociatedText;
+        private byte[] mac;
+        private byte[] macBlock;
+
+        private byte[] nonce;
+
+        private byte[] G1;
+        private byte[] buffer;
+
+        private byte[] s;
+        private byte[] counter;
+
+        private readonly MemoryStream associatedText = new MemoryStream();
+        private readonly MemoryStream data = new MemoryStream();
+
+        /*
+        *  Nb is a parameter specified in CCM mode of DSTU7624 standard.
+        *  This parameter specifies maximum possible length of input. It should
+        *  be calculated as follows: Nb = 1/8 * (-3 + log[2]Nmax) + 1,
+        *  where Nmax - length of input message in bits. For practical reasons
+        *  Nmax usually less than 4Gb, e.g. for Nmax = 2^32 - 1, Nb = 4.
+        *
+        */
+        private int Nb_ = 4;
+
+        public void setNb(int Nb)
+        {
+            if (Nb == 4 || Nb == 6 || Nb == 8)
+            {
+                Nb_ = Nb;
+            }
+            else
+            {
+                throw new ArgumentException("Nb = 4 is recommended by DSTU7624 but can be changed to only 6 or 8 in this implementation");
+            }
+        }
+
+        public KCcmBlockCipher(IBlockCipher engine)
+        {
+            this.engine = engine;
+            this.macSize = engine.GetBlockSize();
+            this.nonce = new byte[engine.GetBlockSize()];
+            this.initialAssociatedText = new byte[engine.GetBlockSize()];
+            this.mac = new byte[engine.GetBlockSize()];
+            this.macBlock = new byte[engine.GetBlockSize()];
+            this.G1 = new byte[engine.GetBlockSize()];
+            this.buffer = new byte[engine.GetBlockSize()];
+            this.s = new byte[engine.GetBlockSize()];
+            this.counter = new byte[engine.GetBlockSize()];
+        }
+
+        public virtual void Init(bool forEncryption, ICipherParameters parameters)
+        {
+
+                ICipherParameters cipherParameters;
+            if (parameters is AeadParameters)
+            {
+
+                    AeadParameters param = (AeadParameters)parameters;
+
+                    if (param.MacSize > MAX_MAC_BIT_LENGTH || param.MacSize < MIN_MAC_BIT_LENGTH || param.MacSize % 8 != 0)
+                    {
+                        throw new ArgumentException("Invalid mac size specified");
+                    }
+
+                    nonce = param.GetNonce();
+                    macSize = param.MacSize / BITS_IN_BYTE;
+                    initialAssociatedText = param.GetAssociatedText();
+                    cipherParameters = param.Key;
+            }
+            else if (parameters is ParametersWithIV)
+            {
+                    nonce = ((ParametersWithIV)parameters).GetIV();
+                    macSize = engine.GetBlockSize(); // use default blockSize for MAC if it is not specified
+                    initialAssociatedText = null;
+                    cipherParameters = ((ParametersWithIV)parameters).Parameters;
+            }
+            else
+            {
+                    throw new ArgumentException("Invalid parameters specified");
+            }
+
+            this.mac = new byte[macSize];
+            this.forEncryption = forEncryption;
+            engine.Init(true, cipherParameters);
+
+            counter[0] = 0x01; // defined in standard
+
+            if (initialAssociatedText != null)
+            {
+                ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length);
+            }
+        }
+
+        public virtual String AlgorithmName
+        {
+            get
+            {
+                return engine.AlgorithmName + "/KCCM";
+            }
+        }
+
+        public virtual int GetBlockSize()
+        {
+            return engine.GetBlockSize();
+        }
+
+        public virtual IBlockCipher GetUnderlyingCipher()
+        {
+            return engine;
+        }
+
+        public virtual void ProcessAadByte(byte input)
+        {
+            associatedText.WriteByte(input);
+        }
+
+        public virtual void ProcessAadBytes(byte[] input, int inOff, int len)
+        {
+            associatedText.Write(input, inOff, len);
+        }
+
+        private void ProcessAAD(byte[] assocText, int assocOff, int assocLen, int dataLen)
+        {
+            if (assocLen - assocOff < engine.GetBlockSize())
+            {
+                throw new ArgumentException("authText buffer too short");
+            }
+            if (assocLen % engine.GetBlockSize() != 0)
+            {
+                throw new ArgumentException("padding not supported");
+            }
+
+            Array.Copy(nonce, 0, G1, 0, nonce.Length - Nb_ - 1);
+
+            intToBytes(dataLen, buffer, 0); // for G1
+
+            Array.Copy(buffer, 0, G1, nonce.Length - Nb_ - 1, BYTES_IN_INT);
+
+            G1[G1.Length - 1] = getFlag(true, macSize);
+
+            engine.ProcessBlock(G1, 0, macBlock, 0);
+
+            intToBytes(assocLen, buffer, 0); // for G2
+
+            if (assocLen <= engine.GetBlockSize() - Nb_)
+            {
+                for (int byteIndex = 0; byteIndex < assocLen; byteIndex++)
+                {
+                    buffer[byteIndex + Nb_] ^= assocText[assocOff + byteIndex];
+                }
+
+                for (int byteIndex = 0; byteIndex < engine.GetBlockSize(); byteIndex++)
+                {
+                    macBlock[byteIndex] ^= buffer[byteIndex];
+                }
+
+                engine.ProcessBlock(macBlock, 0, macBlock, 0);
+
+                return;
+            }
+
+            for (int byteIndex = 0; byteIndex < engine.GetBlockSize(); byteIndex++)
+            {
+                macBlock[byteIndex] ^= buffer[byteIndex];
+            }
+
+            engine.ProcessBlock(macBlock, 0, macBlock, 0);
+
+            int authLen = assocLen;
+            while (authLen != 0)
+            {
+                for (int byteIndex = 0; byteIndex < engine.GetBlockSize(); byteIndex++)
+                {
+                    macBlock[byteIndex] ^= assocText[byteIndex + assocOff];
+                }
+
+                engine.ProcessBlock(macBlock, 0, macBlock, 0);
+
+                assocOff += engine.GetBlockSize();
+                authLen -= engine.GetBlockSize();
+            }
+        }
+
+        public virtual int ProcessByte(byte input, byte[] output, int outOff)
+        {
+            data.WriteByte(input);
+
+            return 0;
+        }
+
+        public virtual int ProcessBytes(byte[] input, int inOff, int inLen, byte[] output, int outOff)
+        {
+            if (input.Length< (inOff + inLen))
+            {
+                throw new DataLengthException("input buffer too short");
+            }
+            data.Write(input, inOff, inLen);
+
+            return 0;
+        }
+
+        public int ProcessPacket(byte[] input, int inOff, int len, byte[] output, int outOff)
+        {
+            if (input.Length - inOff<len)
+            {
+                throw new ArgumentException("input buffer too short");
+            }
+
+            if (output.Length - outOff<len)
+            {
+                throw new ArgumentException("output buffer too short");
+            }
+
+            if (associatedText.Length > 0)
+            {
+                if (forEncryption)
+                {
+                    ProcessAAD(associatedText.GetBuffer(), 0, (int)associatedText.Length, (int)data.Length);
+                }
+                else
+                {
+                    ProcessAAD(associatedText.GetBuffer(), 0, (int)associatedText.Length, (int)data.Length - macSize);
+                }
+            }
+
+            if (forEncryption)
+            {
+                if ((len % engine.GetBlockSize()) != 0)
+                {
+                    throw new DataLengthException("partial blocks not supported");
+                }
+
+                CalculateMac(input, inOff, len);
+                engine.ProcessBlock(nonce, 0, s, 0);
+
+                int totalLength = len;
+                while (totalLength > 0)
+                {
+                    ProcessBlock(input, inOff, len, output, outOff);
+                    totalLength -= engine.GetBlockSize();
+                    inOff += engine.GetBlockSize();
+                    outOff += engine.GetBlockSize();
+                }
+
+                for (int byteIndex = 0; byteIndex<counter.Length; byteIndex++)
+                {
+                    s[byteIndex] += counter[byteIndex];
+                }
+
+                engine.ProcessBlock(s, 0, buffer, 0);
+
+                for (int byteIndex = 0; byteIndex<macSize; byteIndex++)
+                {
+                    output[outOff + byteIndex] = (byte)(buffer[byteIndex] ^ macBlock[byteIndex]);
+                }
+
+                Reset();
+
+                return len + macSize;
+            }
+            else
+            {
+                if ((len - macSize) % engine.GetBlockSize() != 0)
+                {
+                    throw new DataLengthException("partial blocks not supported");
+                }
+
+                engine.ProcessBlock(nonce, 0, s, 0);
+
+                int blocks = len / engine.GetBlockSize();
+
+                for (int blockNum = 0; blockNum<blocks; blockNum++)
+                {
+                    ProcessBlock(input, inOff, len, output, outOff);
+
+                    inOff += engine.GetBlockSize();
+                    outOff += engine.GetBlockSize();
+                }
+
+                if (len > inOff)
+                {
+                    for (int byteIndex = 0; byteIndex<counter.Length; byteIndex++)
+                    {
+                        s[byteIndex] += counter[byteIndex];
+                    }
+
+                    engine.ProcessBlock(s, 0, buffer, 0);
+
+                    for (int byteIndex = 0; byteIndex<macSize; byteIndex++)
+                    {
+                        output[outOff + byteIndex] = (byte)(buffer[byteIndex] ^ input[inOff + byteIndex]);
+                    }
+                    outOff += macSize;
+                }
+
+                for (int byteIndex = 0; byteIndex<counter.Length; byteIndex++)
+                {
+                    s[byteIndex] += counter[byteIndex];
+                }
+
+                engine.ProcessBlock(s, 0, buffer, 0);
+
+                Array.Copy(output, outOff - macSize, buffer, 0, macSize);
+
+                CalculateMac(output, 0, outOff - macSize);
+
+                Array.Copy(macBlock, 0, mac, 0, macSize);
+
+                byte[] calculatedMac = new byte[macSize];
+
+                Array.Copy(buffer, 0, calculatedMac, 0, macSize);
+
+                if (!Arrays.ConstantTimeAreEqual(mac, calculatedMac))
+                {
+                    throw new InvalidCipherTextException("mac check failed");
+                }
+
+                Reset();
+
+                return len;
+            }
+        }
+
+        private void ProcessBlock(byte[] input, int inOff, int len, byte[] output, int outOff)
+        {
+
+            for (int byteIndex = 0; byteIndex < counter.Length; byteIndex++)
+            {
+                s[byteIndex] += counter[byteIndex];
+            }
+
+            engine.ProcessBlock(s, 0, buffer, 0);
+
+            for (int byteIndex = 0; byteIndex < engine.GetBlockSize(); byteIndex++)
+            {
+                output[outOff + byteIndex] = (byte)(buffer[byteIndex] ^ input[inOff + byteIndex]);
+            }
+        }
+
+        private void CalculateMac(byte[] authText, int authOff, int len)
+        {
+            int totalLen = len;
+            while (totalLen > 0)
+            {
+                for (int byteIndex = 0; byteIndex < engine.GetBlockSize(); byteIndex++)
+                {
+                    macBlock[byteIndex] ^= authText[authOff + byteIndex];
+                }
+
+                engine.ProcessBlock(macBlock, 0, macBlock, 0);
+
+                totalLen -= engine.GetBlockSize();
+                authOff += engine.GetBlockSize();
+            }
+        }
+
+        public virtual int DoFinal(byte[] output, int outOff)
+        {
+            int len = ProcessPacket(data.GetBuffer(), 0, (int)data.Length, output, outOff);
+
+            Reset();
+
+            return len;
+        }
+
+        public virtual byte[] GetMac()
+        {
+            Array.Copy(macBlock, 0, mac, 0, macSize);
+            return Arrays.Clone(mac);
+        }
+
+        public virtual int GetUpdateOutputSize(int len)
+        {
+            return len;
+        }
+
+        public virtual int GetOutputSize(int len)
+        {
+            return len + macSize;
+        }
+
+        public virtual void Reset()
+        {
+            Arrays.Fill(G1, (byte)0);
+            Arrays.Fill(buffer, (byte)0);
+            Arrays.Fill(counter, (byte)0);
+            counter[0] = 0x01;
+            data.SetLength(0);
+            associatedText.SetLength(0);
+
+            if (initialAssociatedText != null)
+            {
+                ProcessAadBytes(initialAssociatedText, 0, initialAssociatedText.Length);
+            }
+        }
+
+        private void intToBytes(
+            int num,
+            byte[] outBytes,
+            int outOff)
+        {
+            outBytes[outOff + 3] = (byte)(num >> 24);
+            outBytes[outOff + 2] = (byte)(num >> 16);
+            outBytes[outOff + 1] = (byte)(num >> 8);
+            outBytes[outOff] = (byte)num;
+        }
+
+        private byte getFlag(bool authTextPresents, int macSize)
+        {
+            StringBuilder flagByte = new StringBuilder();
+
+            if (authTextPresents)
+            {
+                flagByte.Append("1");
+            }
+            else
+            {
+                flagByte.Append("0");
+            }
+
+
+            switch (macSize)
+            {
+                case 8:
+                    flagByte.Append("010"); // binary 2
+                    break;
+                case 16:
+                    flagByte.Append("011"); // binary 3
+                    break;
+                case 32:
+                    flagByte.Append("100"); // binary 4
+                    break;
+                case 48:
+                    flagByte.Append("101"); // binary 5
+                    break;
+                case 64:
+                    flagByte.Append("110"); // binary 6
+                    break;
+            }
+
+            String binaryNb = Convert.ToString(Nb_ - 1, 2);
+            while (binaryNb.Length < 4)
+            {
+                binaryNb = new StringBuilder(binaryNb).Insert(0, "0").ToString();
+            }
+
+            flagByte.Append(binaryNb);
+
+            return (byte)Convert.ToInt32(flagByte.ToString(), 2);
+        }
+    }
+}
diff --git a/crypto/test/src/crypto/test/DSTU7624Test.cs b/crypto/test/src/crypto/test/DSTU7624Test.cs
index 67dcd4420..599a3d61f 100644
--- a/crypto/test/src/crypto/test/DSTU7624Test.cs
+++ b/crypto/test/src/crypto/test/DSTU7624Test.cs
@@ -27,26 +27,12 @@ namespace Org.BouncyCastle.Crypto.Tests
           {
 
                //ECB mode
-               /*
-               new KBlockCipherVectorTest(0, new Dstu7624Engine(128, 128), new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F")), "101112131415161718191A1B1C1D1E1F", "81BF1C7D779BAC20E1C9EA39B4D2AD06"),
-               new KBlockCipherVectorTest(1, new Dstu7624Engine(128, 256), new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")), "202122232425262728292A2B2C2D2E2F", "58EC3E091000158A1148F7166F334F14"),
-               new KBlockCipherVectorTest(2, new Dstu7624Engine(256, 256), new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")), "202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F", "F66E3D570EC92135AEDAE323DCBD2A8CA03963EC206A0D5A88385C24617FD92C"),
-               new KBlockCipherVectorTest(3, new Dstu7624Engine(256, 512), new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F", "606990E9E6B7B67A4BD6D893D72268B78E02C83C3CD7E102FD2E74A8FDFE5DD9"),
-               new KBlockCipherVectorTest(4, new Dstu7624Engine(512, 512), new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F", "4A26E31B811C356AA61DD6CA0596231A67BA8354AA47F3A13E1DEEC320EB56B895D0F417175BAB662FD6F134BB15C86CCB906A26856EFEB7C5BC6472940DD9D9"),
-            */
-               //CTR mode
-              // new BlockCipherVectorTest(5, new KCtrBlockCipher(new Dstu7624Engine(128, 128)), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F")), Hex.Decode("101112131415161718191A1B1C1D1E1F")), "202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748", "A90A6B9780ABDFDFF64D14F5439E88F266DC50EDD341528DD5E698E2F000CE21F872DAF9FE1811844A"),
-                  /*      
-               //CFB mode (THERE ARE DIFFERENCE IN LAST BLOCK PROCESSING, SO KBufferedBlockCipher WRAPPER IS USED)
-               new KBlockCipherVectorTest(6, new KCfbBlockCipher(new Dstu7624Engine(128, 128), 128), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F")), Hex.Decode("101112131415161718191A1B1C1D1E1F")), "202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F", "A19E3E5E53BE8A07C9E0C01298FF83291F8EE6212110BE3FA5C72C88A082520B265570FE28680719D9B4465E169BC37A"),
-               new KBlockCipherVectorTest(7, new KCfbBlockCipher(new Dstu7624Engine(256, 256), 128), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")), Hex.Decode("202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90", "E07821AF642F4B1DC071166F2D329763C2CF3B9E39CD0B52BDD33A0DC7B6B6BB201C4A1CD0F5DCB693ABEEA120DACA3A29C73D1D6E87FD75B7DE9E3BE4D256791C2E44583DE8E061E45834A24262BDEBBE"),
-               new KBlockCipherVectorTest(8, new KCfbBlockCipher(new Dstu7624Engine(128, 256), 64), new ParametersWithIV(new KeyParameter(Hex.Decode("1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("2F2E2D2C2B2A29282726252423222120")), "26319A368D85DE43DD5FDB928D91A441493D8CE07B64797C8F9676C5921CD1EA743F5E2777C327AC58", "5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A393837"),
-               new KBlockCipherVectorTest(9, new KCfbBlockCipher(new Dstu7624Engine(256, 256), 256), new ParametersWithIV(new KeyParameter(Hex.Decode("1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A29282726252423222120")), "7758A939DD6BD00CAF9153E5A5D5A66129105CA1EA54A97C06FA4A40960A068F61C3E424DE950151AC46879D84A3BCC24EC8FB69008DAF016EF9832FFD3DB39D02185FDB782DC28EAC27B35179FCA40640", "9F9E9D9C9B9A999897969594939291908F8E8D8C8B8A898887868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F"),
-               new KBlockCipherVectorTest(10, new KCfbBlockCipher(new Dstu7624Engine(256, 512), 256), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), Hex.Decode("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F")), "606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0", "0008F28A82D2D01D23BFB2F8BB4F06D8FE73BA4F48A2977585570ED3818323A6DBAD3D9DD580D9D8F787CE55FAB90735F6B2D6152D56C0C787E6F4B6A2F557DF707A671D06AED196DD7D7E2320D8E45C4C"),
-               new KBlockCipherVectorTest(11, new KCfbBlockCipher(new Dstu7624Engine(256, 512), 256), new ParametersWithIV(new KeyParameter(Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746454443424140")), "98E122708FDABB1B1A5765C396DC79D7573221EC486ADDABD1770B147A6DD00BDD5E4F1496D4D573923F9809EEEEF46B063C64A5E875E77E65EC6832ECE3C24A4B8FD40B04088CBEE2CDECE4DC3CC5573A", "BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A898887868584838281807F7E7D7C7B7A797877767574737271706F"),
-               new KBlockCipherVectorTest(12, new KCfbBlockCipher(new Dstu7624Engine(512, 512), 512), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), Hex.Decode("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F")), "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0", "CAA761980599B3ED2E945C41891BAD95F72B11C73ED26536A6847458BC76C827357156B4B3FE0DC1877F5B9F17B866C37B21D89531DB48007D05DEC928B06766C67D6F3F4C2B82D7A836FAD160905C1C7576243877DC3ADE4AA057966E0023F069"),
-               new KBlockCipherVectorTest(13, new KCfbBlockCipher(new Dstu7624Engine(512, 512), 512), new ParametersWithIV(new KeyParameter(Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("7F7E7D7C7B7A797877767574737271706F6E6D6C6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746454443424140")), "06C061A4A66DFC0910034B3CFBDC4206D8908241C56BF41C4103CFD6DF322210B87F57EAE9F9AD815E606a7D1E8E6BD7CB1EBFBDBCB085C2D06BF3CC1586CB2E88C9155E95B4872D86B49D80F5745B605EAF488AA520A717A92F4D68838E42C995", "EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F"),
-               */
+               new BlockCipherVectorTest(0, new Dstu7624Engine(128), new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F")), "101112131415161718191A1B1C1D1E1F", "81BF1C7D779BAC20E1C9EA39B4D2AD06"),
+               new BlockCipherVectorTest(1, new Dstu7624Engine(128), new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")), "202122232425262728292A2B2C2D2E2F", "58EC3E091000158A1148F7166F334F14"),
+               new BlockCipherVectorTest(2, new Dstu7624Engine(256), new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")), "202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F", "F66E3D570EC92135AEDAE323DCBD2A8CA03963EC206A0D5A88385C24617FD92C"),
+               new BlockCipherVectorTest(3, new Dstu7624Engine(256), new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F", "606990E9E6B7B67A4BD6D893D72268B78E02C83C3CD7E102FD2E74A8FDFE5DD9"),
+               new BlockCipherVectorTest(4, new Dstu7624Engine(512), new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F", "4A26E31B811C356AA61DD6CA0596231A67BA8354AA47F3A13E1DEEC320EB56B895D0F417175BAB662FD6F134BB15C86CCB906A26856EFEB7C5BC6472940DD9D9"),
+
                //CBC mode (PADDING NOT SUPPORTED)
                new BlockCipherVectorTest(14, new CbcBlockCipher(new Dstu7624Engine(128)), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F")), Hex.Decode("101112131415161718191A1B1C1D1E1F")), "202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F", "A73625D7BE994E85469A9FAABCEDAAB6DBC5F65DD77BB35E06BD7D1D8EAFC8624D6CB31CE189C82B8979F2936DE9BF14"),
                new BlockCipherVectorTest(15, new CbcBlockCipher(new Dstu7624Engine(128)), new ParametersWithIV(new KeyParameter(Hex.Decode("0F0E0D0C0B0A09080706050403020100")), Hex.Decode("1F1E1D1C1B1A19181716151413121110")), "88F2F048BA696170E3818915E0DBC0AFA6F141FEBC2F817138DA4AAB2DBF9CE490A488C9C82AC83FB0A6C0EEB64CFD22", "4F4E4D4C4B4A494847464544434241403F3E3D3C3B3A393837363534333231302F2E2D2C2B2A29282726252423222120"),
@@ -54,9 +40,12 @@ namespace Org.BouncyCastle.Crypto.Tests
                new BlockCipherVectorTest(17, new CbcBlockCipher(new Dstu7624Engine(128)), new ParametersWithIV(new KeyParameter(Hex.Decode("1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("2F2E2D2C2B2A29282726252423222120")), "BC8F026FC603ECE05C24FDE87542730999B381870882AC0535D4368C4BABD81B884E96E853EE7E055262D9D204FBE212", "5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A494847464544434241403F3E3D3C3B3A39383736353433323130"),
                new BlockCipherVectorTest(18, new CbcBlockCipher(new Dstu7624Engine(256)), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")), Hex.Decode("202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F", "9CDFDAA75929E7C2A5CFC1BF16B42C5AE3886D0258E8C577DC01DAF62D185FB999B9867736B87110F5F1BC7481912C593F48FF79E2AFDFAB9F704A277EC3E557B1B0A9F223DAE6ED5AF591C4F2D6FB22E48334F5E9B96B1A2EA5200F30A406CE"),
                new BlockCipherVectorTest(19, new CbcBlockCipher(new Dstu7624Engine(256)), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), Hex.Decode("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F")), "606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF", "B8A2474578C2FEBF3F94703587BD5FDC3F4A4D2F43575B6144A1E1031FB3D1452B7FD52F5E3411461DAC506869FF8D2FAEF4FEE60379AE00B33AA3EAF911645AF8091CD8A45D141D1FB150E5A01C1F26FF3DBD26AC4225EC7577B2CE57A5B0FF"),
-               new BlockCipherVectorTest(20, new CbcBlockCipher(new Dstu7624Engine(256)), new ParametersWithIV(new KeyParameter(Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746454443424140")), "C69A59E10D00F087319B62288A57417C074EAD07C732A87055F0A5AD2BB288105705C45E091A9A6726E9672DC7D8C76FC45C782BCFEF7C39D94DEB84B17035BC8651255A0D34373451B6E1A2C827DB97566C9FF5506C5579F982A0EFC5BA7C28", "BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A898887868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160"),
+               new BlockCipherVectorTest(20, new CbcBlockCipher(new Dstu7624Engine(256)), new ParametersWithIV(new KeyParameter(Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746454443424140")), "C69A59E10D00F087319B62288A57417C074EAD07C732A87055F0A5AD2BB288105705C45E091A9A6726E9672DC7D8C76FC45C782BCFEF7C39D94DEB84B17035BC8651255A0D34373451B6E1A2C827DB97566C9FF5506C5579F982A0EFC5BA7C28", "BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAeadACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A898887868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A69686766656463626160"),
                new BlockCipherVectorTest(21, new CbcBlockCipher(new Dstu7624Engine(512)), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), Hex.Decode("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F")), "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF", "D4739B829EF901B24C1162AE4FDEF897EDA41FAC7F5770CDC90E1D1CDF124E8D7831E06B4498A4B6F6EC815DF2461DC99BB0449B0F09FCAA2C84090534BCC9329626FD74EF8F0A0BCB5765184629C3CBF53B0FB134F6D0421174B1C4E884D1CD1069A7AD19752DCEBF655842E79B7858BDE01390A760D85E88925BFE38B0FA57"),
-               new BlockCipherVectorTest(22, new CbcBlockCipher(new Dstu7624Engine(512)), new ParametersWithIV(new KeyParameter(Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("7F7E7D7C7B7A797877767574737271706F6E6D6C6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746454443424140")), "5D5B3E3DE5BAA70E0A0684D458856CE759C6018D0B3F087FC1DAC101D380236DD934F2880B02D56A575BCA35A0CE4B0D9BA1F4A39C16CA7D80D59956630F09E54EC91E32B6830FE08323ED393F8028D150BF03CAD0629A5AFEEFF6E44257980618DB2F32B7B2B65B96E8451F1090829D2FFFC615CC1581E9221438DCEAD1FD12", "FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A89888786858483828180"),
+               new BlockCipherVectorTest(22, new CbcBlockCipher(new Dstu7624Engine(512)), new ParametersWithIV(new KeyParameter(Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("7F7E7D7C7B7A797877767574737271706F6E6D6C6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746454443424140")), "5D5B3E3DE5BAA70E0A0684D458856CE759C6018D0B3F087FC1DAC101D380236DD934F2880B02D56A575BCA35A0CE4B0D9BA1F4A39C16CA7D80D59956630F09E54EC91E32B6830FE08323ED393F8028D150BF03CAD0629A5AFEEFF6E44257980618DB2F32B7B2B65B96E8451F1090829D2FFFC615CC1581E9221438DCEAD1FD12", "FFFEFDFCFBFAF9F8F7F6F5F4F3F2F1F0EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAeadACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A89888786858483828180"),
+
+               //CFB mode
+               new BlockCipherVectorTest(14, new CfbBlockCipher(new Dstu7624Engine(128), 128), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F")), Hex.Decode("101112131415161718191A1B1C1D1E1F")), "202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F", "A19E3E5E53BE8A07C9E0C01298FF83291F8EE6212110BE3FA5C72C88A082520B265570FE28680719D9B4465E169BC37A"),
 
                //OFB mode
                new BlockCipherVectorTest(23, new OfbBlockCipher(new Dstu7624Engine(128), 128), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F")), Hex.Decode("101112131415161718191A1B1C1D1E1F")), "202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F", "A19E3E5E53BE8A07C9E0C01298FF832953205C661BD85A51F3A94113BC785CAB634B36E89A8FDD16A12E4467F5CC5A26"),
@@ -65,9 +54,9 @@ namespace Org.BouncyCastle.Crypto.Tests
                new BlockCipherVectorTest(26, new OfbBlockCipher(new Dstu7624Engine(256), 256), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F")), Hex.Decode("202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), "404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F90", "B62F7F144A8C6772E693A96890F064C3F06831BF743F5B0DD061067F3D22877331AA6A99D939F05B7550E9402BD1615CC7B2D4A167E83EC0D8A894F92C72E176F3880B61C311D69CE1210C59184E818E19"),
                new BlockCipherVectorTest(27, new OfbBlockCipher(new Dstu7624Engine(256), 256), new ParametersWithIV(new KeyParameter(Hex.Decode("1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A29282726252423222120")), "7758A939DD6BD00CAF9153E5A5D5A66129105CA1EA54A97C06FA4A40960A068F55E34F9339A14436216948F92FA2FB5286D3AB1E81543FC0018A0C4E8C493475F4D35DCFB0A7A5377F6669B857CDC978E4", "9F9E9D9C9B9A999897969594939291908F8E8D8C8B8A898887868584838281807F7E7D7C7B7A797877767574737271706F6E6D6C6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F"),
                new BlockCipherVectorTest(28, new OfbBlockCipher(new Dstu7624Engine(256), 256), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), Hex.Decode("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F")), "606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0", "0008F28A82D2D01D23BFB2F8BB4F06D8FE73BA4F48A2977585570ED3818323A668883C9DCFF610CC7E3EA5C025FBBC5CA6520F8F11CA35CEB9B07031E6DBFABE39001E9A3CC0A24BBC565939592B4DEDBD"),
-               new BlockCipherVectorTest(29, new OfbBlockCipher(new Dstu7624Engine(256), 256), new ParametersWithIV(new KeyParameter(Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746454443424140")), "98E122708FDABB1B1A5765C396DC79D7573221EC486ADDABD1770B147A6DD00B5FBC4F1EC68C59775B7AAA4D43C4CCE4F396D982DF64D30B03EF6C3B997BA0ED940BBC590BD30D64B5AE207147D71086B5", "BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A898887868584838281807F7E7D7C7B7A797877767574737271706F"),
+               new BlockCipherVectorTest(29, new OfbBlockCipher(new Dstu7624Engine(256), 256), new ParametersWithIV(new KeyParameter(Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("5F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746454443424140")), "98E122708FDABB1B1A5765C396DC79D7573221EC486ADDABD1770B147A6DD00B5FBC4F1EC68C59775B7AAA4D43C4CCE4F396D982DF64D30B03EF6C3B997BA0ED940BBC590BD30D64B5AE207147D71086B5", "BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAeadACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F8E8D8C8B8A898887868584838281807F7E7D7C7B7A797877767574737271706F"),
                new BlockCipherVectorTest(30, new OfbBlockCipher(new Dstu7624Engine(512), 512), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F")), Hex.Decode("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F")), "808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0", "CAA761980599B3ED2E945C41891BAD95F72B11C73ED26536A6847458BC76C827357156B4B3FE0DC1877F5B9F17B866C37B21D89531DB48007D05DEC928B06766C014BB9080385EDF0677E48A0A39B5E7489E28E82FFFD1F84694F17296CB701656"),
-               new BlockCipherVectorTest(31, new OfbBlockCipher(new Dstu7624Engine(512), 512), new ParametersWithIV(new KeyParameter(Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("7F7E7D7C7B7A797877767574737271706F6E6D6C6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746454443424140")), "06C061A4A66DFC0910034B3CFBDC4206D8908241C56BF41C4103CFD6DF322210B87F57EAE9F9AD815E606A7D1E8E6BD7CB1EBFBDBCB085C2D06BF3CC1586CB2EE1D81D38437F425131321647E42F5DE309D33F25B89DE37124683E4B44824FC56D", "EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAEADACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F"),
+               new BlockCipherVectorTest(31, new OfbBlockCipher(new Dstu7624Engine(512), 512), new ParametersWithIV(new KeyParameter(Hex.Decode("3F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524232221201F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100")), Hex.Decode("7F7E7D7C7B7A797877767574737271706F6E6D6C6B6A696867666564636261605F5E5D5C5B5A595857565554535251504F4E4D4C4B4A49484746454443424140")), "06C061A4A66DFC0910034B3CFBDC4206D8908241C56BF41C4103CFD6DF322210B87F57EAE9F9AD815E606A7D1E8E6BD7CB1EBFBDBCB085C2D06BF3CC1586CB2EE1D81D38437F425131321647E42F5DE309D33F25B89DE37124683E4B44824FC56D", "EFEEEDECEBEAE9E8E7E6E5E4E3E2E1E0DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBCAC9C8C7C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B2B1B0AFAeadACABAAA9A8A7A6A5A4A3A2A1A09F9E9D9C9B9A999897969594939291908F"),
 
                //CTR mode
                new BlockCipherVectorTest(24, new KCtrBlockCipher(new Dstu7624Engine(128)), new ParametersWithIV(new KeyParameter(Hex.Decode("000102030405060708090A0B0C0D0E0F")), Hex.Decode("101112131415161718191A1B1C1D1E1F")), "202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748", "A90A6B9780ABDFDFF64D14F5439E88F266DC50EDD341528DD5E698E2F000CE21F872DAF9FE1811844A"),
@@ -81,8 +70,20 @@ namespace Org.BouncyCastle.Crypto.Tests
 
             ITestResult result = base.Perform();
 
+            if (!result.IsSuccessful())
+            {
+                return result;
+            }
+
             result = MacTests(); //Mac tests
 
+            if (!result.IsSuccessful())
+            {
+                return result;
+            }
+
+            CCMModeTests();
+
             result = KeyWrapTests(); //Key wrapping tests
 
             if (!result.IsSuccessful())
@@ -154,6 +155,7 @@ namespace Org.BouncyCastle.Crypto.Tests
         
             return new SimpleTestResult(true, Name + ": Okay");
         }
+
         private ITestResult KeyWrapTests()
         {
             //KW mode (PADDING NOT SUPPORTED)
@@ -455,6 +457,262 @@ namespace Org.BouncyCastle.Crypto.Tests
             return new SimpleTestResult(true, Name + ": Okay");
         }
 
+        private void CCMModeTests()
+        {
+            //test 1
+            byte[] key = Hex.Decode("000102030405060708090a0b0c0d0e0f");
+            byte[] iv = Hex.Decode("101112131415161718191a1b1c1d1e1f");
+            byte[] input = Hex.Decode("303132333435363738393a3b3c3d3e3f");
+            byte[] authText = Hex.Decode("202122232425262728292a2b2c2d2e2f");
+
+            byte[] expectedMac = Hex.Decode("26a936173a4dc9160d6e3fda3a974060");
+            byte[] expectedEncrypted = Hex.Decode("b91a7b8790bbcfcfe65d04e5538e98e2704454c9dd39adace0b19d03f6aab07e");
+
+            byte[] mac;
+            byte[] encrypted = new byte[expectedEncrypted.Length];
+
+            byte[] decrypted = new byte[encrypted.Length];
+            byte[] expectedDecrypted = new byte[input.Length + expectedMac.Length];
+            Array.Copy(input, 0, expectedDecrypted, 0, input.Length);
+            Array.Copy(expectedMac, 0, expectedDecrypted, input.Length, expectedMac.Length);
+            int len;
+
+
+            AeadParameters param = new AeadParameters(new KeyParameter(key), 128, iv);
+
+            KCcmBlockCipher dstu7624ccm = new KCcmBlockCipher(new Dstu7624Engine(128));
+
+            dstu7624ccm.setNb(4);
+            dstu7624ccm.Init(true, param);
+
+            dstu7624ccm.ProcessAadBytes(authText, 0, authText.Length);
+
+            len = dstu7624ccm.ProcessBytes(input, 0, input.Length, encrypted, 0);
+
+
+            dstu7624ccm.DoFinal(encrypted, len);
+
+            mac = dstu7624ccm.GetMac();
+
+            if (!Arrays.AreEqual(mac, expectedMac))
+            {
+                Fail("Failed CCM mac test 1 - expected "
+                    + Hex.ToHexString(expectedMac)
+                    + " got " + Hex.ToHexString(mac));
+            }
+
+            if (!Arrays.AreEqual(encrypted, expectedEncrypted))
+            {
+                Fail("Failed CCM encrypt test 1 - expected "
+                    + Hex.ToHexString(expectedEncrypted)
+                    + " got " + Hex.ToHexString(encrypted));
+            }
+
+            dstu7624ccm.setNb(4);
+            dstu7624ccm.Init(false, param);
+
+            dstu7624ccm.ProcessAadBytes(authText, 0, authText.Length);
+
+            len = dstu7624ccm.ProcessBytes(expectedEncrypted, 0, expectedEncrypted.Length, decrypted, 0);
+
+            dstu7624ccm.DoFinal(decrypted, len);
+
+            if (!Arrays.AreEqual(decrypted, expectedDecrypted))
+            {
+                Fail("Failed CCM decrypt/verify mac test 1 - expected "
+                    + Hex.ToHexString(expectedDecrypted)
+                    + " got " + Hex.ToHexString(decrypted));
+            }
+
+            //test 2
+            key = Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
+            iv = Hex.Decode("202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F");
+            input = Hex.Decode("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9F");
+            authText = Hex.Decode("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F");
+
+            expectedMac = Hex.Decode("9AB831B4B0BF0FDBC36E4B4FD58F0F00");
+            expectedEncrypted = Hex.Decode("7EC15C54BB553CB1437BE0EFDD2E810F6058497EBCE4408A08A73FADF3F459D56B0103702D13AB73ACD2EB33A8B5E9CFFF5EB21865A6B499C10C810C4BAEBE809C48AD90A9E12A68380EF1C1B7C83EE1");
+
+            mac = new byte[expectedMac.Length];
+            encrypted = new byte[expectedEncrypted.Length];
+
+            decrypted = new byte[encrypted.Length];
+            expectedDecrypted = new byte[input.Length + expectedMac.Length];
+            Array.Copy(input, 0, expectedDecrypted, 0, input.Length);
+            Array.Copy(expectedMac, 0, expectedDecrypted, input.Length, expectedMac.Length);
+
+
+            param = new AeadParameters(new KeyParameter(key), 128, iv);
+
+            dstu7624ccm = new KCcmBlockCipher(new Dstu7624Engine(256));
+
+            dstu7624ccm.setNb(4);
+            dstu7624ccm.Init(true, param);
+
+            dstu7624ccm.ProcessAadBytes(authText, 0, authText.Length);
+
+            len = dstu7624ccm.ProcessBytes(input, 0, input.Length, encrypted, 0);
+
+            dstu7624ccm.DoFinal(encrypted, len);
+
+            mac = dstu7624ccm.GetMac();
+
+            if (!Arrays.AreEqual(mac, expectedMac))
+            {
+                Fail("Failed CCM mac test 2 - expected "
+                    + Hex.ToHexString(expectedMac)
+                    + " got " + Hex.ToHexString(mac));
+            }
+
+            if (!Arrays.AreEqual(encrypted, expectedEncrypted))
+            {
+                Fail("Failed CCM encrypt test 2 - expected "
+                    + Hex.ToHexString(expectedEncrypted)
+                    + " got " + Hex.ToHexString(encrypted));
+            }
+
+            dstu7624ccm.setNb(4);
+            dstu7624ccm.Init(false, param);
+
+            dstu7624ccm.ProcessAadBytes(authText, 0, authText.Length);
+
+            len = dstu7624ccm.ProcessBytes(expectedEncrypted, 0, expectedEncrypted.Length, decrypted, 0);
+
+            dstu7624ccm.DoFinal(decrypted, len);
+
+            if (!Arrays.AreEqual(decrypted, expectedDecrypted))
+            {
+                Fail("Failed CCM decrypt/verify mac test 2 - expected "
+                    + Hex.ToHexString(expectedDecrypted)
+                    + " got " + Hex.ToHexString(decrypted));
+            }
+
+            //test 3
+            key = Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F");
+            iv = Hex.Decode("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F");
+            input = Hex.Decode("808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF");
+            authText = Hex.Decode("606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F");
+
+            expectedMac = Hex.Decode("924FA0326824355595C98028E84D86279CEA9135FAB35F22054AE3203E68AE46");
+            expectedEncrypted = Hex.Decode("3EBDB4584B5169A26FBEBA0295B4223F58D5D8A031F2950A1D7764FAB97BA058E9E2DAB90FF0C519AA88435155A71B7B53BB100F5D20AFFAC0552F5F2813DEE8DD3653491737B9615A5CCD83DB32F1E479BF227C050325BBBFF60BCA9558D7FE");
+
+            mac = new byte[expectedMac.Length];
+            encrypted = new byte[expectedEncrypted.Length];
+
+            decrypted = new byte[encrypted.Length];
+            expectedDecrypted = new byte[input.Length + expectedMac.Length];
+            Array.Copy(input, 0, expectedDecrypted, 0, input.Length);
+            Array.Copy(expectedMac, 0, expectedDecrypted, input.Length, expectedMac.Length);
+
+
+            param = new AeadParameters(new KeyParameter(key), 256, iv);
+
+            dstu7624ccm = new KCcmBlockCipher(new Dstu7624Engine(256));
+
+            dstu7624ccm.setNb(6);
+            dstu7624ccm.Init(true, param);
+
+            dstu7624ccm.ProcessAadBytes(authText, 0, authText.Length);
+
+            len = dstu7624ccm.ProcessBytes(input, 0, input.Length, encrypted, 0);
+
+            dstu7624ccm.DoFinal(encrypted, len);
+
+            mac = dstu7624ccm.GetMac();
+
+            if (!Arrays.AreEqual(mac, expectedMac))
+            {
+                Fail("Failed CCM mac test 3 - expected "
+                    + Hex.ToHexString(expectedMac)
+                    + " got " + Hex.ToHexString(mac));
+            }
+
+            if (!Arrays.AreEqual(encrypted, expectedEncrypted))
+            {
+                Fail("Failed CCM encrypt test 3 - expected "
+                    + Hex.ToHexString(expectedEncrypted)
+                    + " got " + Hex.ToHexString(encrypted));
+            }
+
+            dstu7624ccm.setNb(6);
+            dstu7624ccm.Init(false, param);
+
+            dstu7624ccm.ProcessAadBytes(authText, 0, authText.Length);
+
+            len = dstu7624ccm.ProcessBytes(expectedEncrypted, 0, expectedEncrypted.Length, decrypted, 0);
+
+            dstu7624ccm.DoFinal(decrypted, len);
+
+            if (!Arrays.AreEqual(decrypted, expectedDecrypted))
+            {
+                Fail("Failed CCM decrypt/verify mac test 3 - expected "
+                    + Hex.ToHexString(expectedDecrypted)
+                    + " got " + Hex.ToHexString(decrypted));
+            }
+
+            //test 4
+            key = Hex.Decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F");
+            iv = Hex.Decode("404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F");
+            input = Hex.Decode("C0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF");
+            authText = Hex.Decode("808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBF");
+
+            expectedMac = Hex.Decode("D4155EC3D888C8D32FE184AC260FD60F567705E1DF362A6F1F9C287156AA96D91BC4C56F9709E72F3D79CF0A9AC8BDC2BA836BE50E823AB50FB1B39080390923");
+            expectedEncrypted = Hex.Decode("220642D7277D104788CF97B10210984F506435512F7BF153C5CDABFECC10AFB4A2E2FC51F616AF80FFDD0607FAD4F542B8EF0667717CE3EAAA8FBC303CE76C99BD8F80CE149143C04FC2490272A31B029DDADA82F055FE4ABEF452A7D438B21E59C1D8B3DD4606BAD66A6F36300EF3CE0E5F3BB59F11416E80B7FC5A8E8B057A");
+
+            mac = new byte[expectedMac.Length];
+            encrypted = new byte[expectedEncrypted.Length];
+
+            decrypted = new byte[encrypted.Length];
+            expectedDecrypted = new byte[input.Length + expectedMac.Length];
+            Array.Copy(input, 0, expectedDecrypted, 0, input.Length);
+            Array.Copy(expectedMac, 0, expectedDecrypted, input.Length, expectedMac.Length);
+
+
+            param = new AeadParameters(new KeyParameter(key), 512, iv);
+
+            dstu7624ccm = new KCcmBlockCipher(new Dstu7624Engine(512));
+
+            dstu7624ccm.setNb(8);
+            dstu7624ccm.Init(true, param);
+
+            dstu7624ccm.ProcessAadBytes(authText, 0, authText.Length);
+
+            len = dstu7624ccm.ProcessBytes(input, 0, input.Length, encrypted, 0);
+
+            dstu7624ccm.DoFinal(encrypted, len);
+
+            mac = dstu7624ccm.GetMac();
+
+            if (!Arrays.AreEqual(mac, expectedMac))
+            {
+                Fail("Failed CCM mac test 4 - expected "
+                    + Hex.ToHexString(expectedMac)
+                    + " got " + Hex.ToHexString(mac));
+            }
+
+            if (!Arrays.AreEqual(encrypted, expectedEncrypted))
+            {
+                Fail("Failed CCM encrypt test 4 - expected "
+                    + Hex.ToHexString(expectedEncrypted)
+                    + " got " + Hex.ToHexString(encrypted));
+            }
+
+            dstu7624ccm.setNb(8);
+            dstu7624ccm.Init(false, param);
+
+            dstu7624ccm.ProcessAadBytes(authText, 0, authText.Length);
+
+            len = dstu7624ccm.ProcessBytes(expectedEncrypted, 0, expectedEncrypted.Length, decrypted, 0);
+
+            dstu7624ccm.DoFinal(decrypted, len);
+
+            if (!Arrays.AreEqual(decrypted, expectedDecrypted))
+            {
+                Fail("Failed CCM decrypt/verify mac test 4 - expected "
+                    + Hex.ToHexString(expectedDecrypted)
+                    + " got " + Hex.ToHexString(decrypted));
+            }
+        }
 
         [Test]
         public void Dstu7624TestFunction()