Exemplo n.º 1
0
        private void RunTestCase(string testName, string[] testVector, int macLengthBits, byte[] K)
        {
            int pos = 0;

            byte[] N = Hex.Decode(testVector[pos++]);
            byte[] A = Hex.Decode(testVector[pos++]);
            byte[] P = Hex.Decode(testVector[pos++]);
            byte[] C = Hex.Decode(testVector[pos++]);

            int macLengthBytes = macLengthBits / 8;

            KeyParameter   keyParameter = new KeyParameter(K);
            AeadParameters parameters   = new AeadParameters(keyParameter, macLengthBits, N, A);

            IAeadBlockCipher encCipher = InitOcbCipher(true, parameters);
            IAeadBlockCipher decCipher = InitOcbCipher(false, parameters);

            CheckTestCase(encCipher, decCipher, testName, macLengthBytes, P, C);
            CheckTestCase(encCipher, decCipher, testName + " (reused)", macLengthBytes, P, C);

            // Key reuse
            AeadParameters keyReuseParams = AeadTestUtilities.ReuseKey(parameters);

            encCipher.Init(true, keyReuseParams);
            decCipher.Init(false, keyReuseParams);
            CheckTestCase(encCipher, decCipher, testName + " (key reuse)", macLengthBytes, P, C);
        }
Exemplo n.º 2
0
        private void RunTestCase(
            IGcmMultiplier encM,
            IGcmMultiplier decM,
            string testName,
            byte[]          K,
            byte[]          IV,
            byte[]          A,
            byte[]          SA,
            byte[]          P,
            byte[]          C,
            byte[]          T)
        {
            AeadParameters parameters = new AeadParameters(new KeyParameter(K), T.Length * 8, IV, A);
            GcmBlockCipher encCipher  = InitCipher(encM, true, parameters);
            GcmBlockCipher decCipher  = InitCipher(decM, false, parameters);

            CheckTestCase(encCipher, decCipher, testName, SA, P, C, T);
            encCipher = InitCipher(encM, true, parameters);
            CheckTestCase(encCipher, decCipher, testName + " (reused)", SA, P, C, T);

            // Key reuse
            AeadParameters keyReuseParams = AeadTestUtilities.ReuseKey(parameters);

            try
            {
                encCipher.Init(true, keyReuseParams);
                Fail("no exception");
            }
            catch (ArgumentException e)
            {
                IsTrue("wrong message", "cannot reuse nonce for GCM encryption".Equals(e.Message));
            }
        }
Exemplo n.º 3
0
        private void TestExceptions()
        {
            ChaCha20Poly1305 c = new ChaCha20Poly1305();

            try
            {
                c = new ChaCha20Poly1305(new SipHash());

                Fail("incorrect mac size not picked up");
            }
            catch (ArgumentException e)
            {
                // expected
            }

            try
            {
                c.Init(false, new KeyParameter(new byte[32]));

                Fail("illegal argument not picked up");
            }
            catch (ArgumentException e)
            {
                // expected
            }

            AeadTestUtilities.TestTampering(this, c, new AeadParameters(new KeyParameter(new byte[32]), 128, new byte[12]));

            byte[] P   = Strings.ToByteArray("Hello world!");
            byte[] buf = new byte[100];

            c = new ChaCha20Poly1305();
            AeadParameters aeadParameters = new AeadParameters(new KeyParameter(new byte[32]), 128, new byte[12]);

            c.Init(true, aeadParameters);

            c.ProcessBytes(P, 0, P.Length, buf, 0);

            c.DoFinal(buf, 0);

            try
            {
                c.DoFinal(buf, 0);
                Fail("no exception on reuse");
            }
            catch (InvalidOperationException e)
            {
                IsTrue("wrong message", e.Message.Equals("ChaCha20Poly1305 cannot be reused for encryption"));
            }

            try
            {
                c.Init(true, aeadParameters);
                Fail("no exception on reuse");
            }
            catch (ArgumentException e)
            {
                IsTrue("wrong message", e.Message.Equals("cannot reuse nonce for ChaCha20Poly1305 encryption"));
            }
        }
Exemplo n.º 4
0
        private void RunTestCase(
            string testName,
            byte[]  K,
            byte[]  N,
            byte[]  A,
            byte[]  SA,
            byte[]  P,
            byte[]  C,
            byte[]  T)
        {
            AeadParameters   parameters = new AeadParameters(new KeyParameter(K), T.Length * 8, N, A);
            ChaCha20Poly1305 encCipher  = InitCipher(true, parameters);
            ChaCha20Poly1305 decCipher  = InitCipher(false, parameters);

            CheckTestCase(encCipher, decCipher, testName, SA, P, C, T);
            encCipher = InitCipher(true, parameters);
            CheckTestCase(encCipher, decCipher, testName + " (reused)", SA, P, C, T);

            // Key reuse
            AeadParameters keyReuseParams = AeadTestUtilities.ReuseKey(parameters);

            try
            {
                encCipher.Init(true, keyReuseParams);
                Fail("no exception");
            }
            catch (ArgumentException e)
            {
                IsTrue("wrong message", "cannot reuse nonce for ChaCha20Poly1305 encryption".Equals(e.Message));
            }
        }
        private void DoTestExceptions()
        {
            GcmBlockCipher gcm = new GcmBlockCipher(CreateAesEngine());

            try
            {
                gcm = new GcmBlockCipher(new DesEngine());

                Fail("incorrect block size not picked up");
            }
            catch (ArgumentException)
            {
                // expected
            }

            try
            {
                gcm.Init(false, new KeyParameter(new byte[16]));

                Fail("illegal argument not picked up");
            }
            catch (ArgumentException)
            {
                // expected
            }

            AeadTestUtilities.TestTampering(this, gcm, new AeadParameters(new KeyParameter(new byte[16]), 128, new byte[16]));

            byte[] P   = Strings.ToByteArray("Hello world!");
            byte[] buf = new byte[100];

            GcmBlockCipher c = new GcmBlockCipher(CreateAesEngine());
            AeadParameters aeadParameters = new AeadParameters(new KeyParameter(new byte[16]), 128, new byte[16]);

            c.Init(true, aeadParameters);

            c.ProcessBytes(P, 0, P.Length, buf, 0);

            c.DoFinal(buf, 0);

            try
            {
                c.DoFinal(buf, 0);
                Fail("no exception on reuse");
            }
            catch (InvalidOperationException e)
            {
                IsTrue("wrong message", e.Message.Equals("GCM cipher cannot be reused for encryption"));
            }

            try
            {
                c.Init(true, aeadParameters);
                Fail("no exception on reuse");
            }
            catch (ArgumentException e)
            {
                IsTrue("wrong message", e.Message.Equals("cannot reuse nonce for GCM encryption"));
            }
        }
Exemplo n.º 6
0
        private void RunTestCase(
            IGcmMultiplier encM,
            IGcmMultiplier decM,
            string testName,
            byte[]          K,
            byte[]          IV,
            byte[]          A,
            byte[]          SA,
            byte[]          P,
            byte[]          C,
            byte[]          T)
        {
            AeadParameters parameters = new AeadParameters(new KeyParameter(K), T.Length * 8, IV, A);
            GcmBlockCipher encCipher  = InitCipher(encM, true, parameters);
            GcmBlockCipher decCipher  = InitCipher(decM, false, parameters);

            CheckTestCase(encCipher, decCipher, testName, SA, P, C, T);
            CheckTestCase(encCipher, decCipher, testName + " (reused)", SA, P, C, T);

            // Key reuse
            AeadParameters keyReuseParams = AeadTestUtilities.ReuseKey(parameters);

            encCipher.Init(true, keyReuseParams);
            decCipher.Init(false, keyReuseParams);
            CheckTestCase(encCipher, decCipher, testName + " (key reuse)", SA, P, C, T);
        }
Exemplo n.º 7
0
        private void RandomTest(SecureRandom srng, IGcmMultiplier m)
        {
            int kLength = 16 + 8 * srng.Next(3);

            byte[] K = new byte[kLength];
            srng.NextBytes(K);

            int pLength = srng.Next(65536);

            byte[] P = new byte[pLength];
            srng.NextBytes(P);

            int aLength = srng.Next(256);

            byte[] A = new byte[aLength];
            srng.NextBytes(A);

            int saLength = srng.Next(256);

            byte[] SA = new byte[saLength];
            srng.NextBytes(SA);

            int ivLength = 1 + srng.Next(256);

            byte[] IV = new byte[ivLength];
            srng.NextBytes(IV);

            AeadParameters parameters = new AeadParameters(new KeyParameter(K), 16 * 8, IV, A);
            GcmBlockCipher cipher     = InitCipher(m, true, parameters);

            byte[] C         = new byte[cipher.GetOutputSize(P.Length)];
            int    predicted = cipher.GetUpdateOutputSize(P.Length);

            int split = srng.Next(SA.Length + 1);

            cipher.ProcessAadBytes(SA, 0, split);
            int len = cipher.ProcessBytes(P, 0, P.Length, C, 0);

            cipher.ProcessAadBytes(SA, split, SA.Length - split);

            if (predicted != len)
            {
                Fail("encryption reported incorrect update length in randomised test");
            }

            len += cipher.DoFinal(C, len);

            if (C.Length != len)
            {
                Fail("encryption reported incorrect length in randomised test");
            }

            byte[] encT = cipher.GetMac();
            byte[] tail = new byte[C.Length - P.Length];
            Array.Copy(C, P.Length, tail, 0, tail.Length);

            if (!AreEqual(encT, tail))
            {
                Fail("stream contained wrong mac in randomised test");
            }

            cipher.Init(false, parameters);
            byte[] decP = new byte[cipher.GetOutputSize(C.Length)];
            predicted = cipher.GetUpdateOutputSize(C.Length);

            split = srng.Next(SA.Length + 1);
            cipher.ProcessAadBytes(SA, 0, split);
            len = cipher.ProcessBytes(C, 0, C.Length, decP, 0);
            cipher.ProcessAadBytes(SA, split, SA.Length - split);

            if (predicted != len)
            {
                Fail("decryption reported incorrect update length in randomised test");
            }

            len += cipher.DoFinal(decP, len);

            if (!AreEqual(P, decP))
            {
                Fail("incorrect decrypt in randomised test");
            }

            byte[] decT = cipher.GetMac();
            if (!AreEqual(encT, decT))
            {
                Fail("decryption produced different mac from encryption");
            }

            //
            // key reuse test
            //
            cipher.Init(false, AeadTestUtilities.ReuseKey(parameters));
            decP = new byte[cipher.GetOutputSize(C.Length)];

            split = NextInt(srng, SA.Length + 1);
            cipher.ProcessAadBytes(SA, 0, split);
            len = cipher.ProcessBytes(C, 0, C.Length, decP, 0);
            cipher.ProcessAadBytes(SA, split, SA.Length - split);

            len += cipher.DoFinal(decP, len);

            if (!AreEqual(P, decP))
            {
                Fail("incorrect decrypt in randomised test");
            }

            decT = cipher.GetMac();
            if (!AreEqual(encT, decT))
            {
                Fail("decryption produced different mac from encryption");
            }
        }
Exemplo n.º 8
0
        private void RandomTest(SecureRandom random)
        {
            int kLength = 32;

            byte[] K = new byte[kLength];
            random.NextBytes(K);

            int pHead   = random.Next(256);
            int pLength = random.Next(65536);
            int pTail   = random.Next(256);

            byte[] P = new byte[pHead + pLength + pTail];
            random.NextBytes(P);

            int aLength = random.Next(256);

            byte[] A = new byte[aLength];
            random.NextBytes(A);

            int saLength = random.Next(256);

            byte[] SA = new byte[saLength];
            random.NextBytes(SA);

            int nonceLength = 12;

            byte[] nonce = new byte[nonceLength];
            random.NextBytes(nonce);

            AeadParameters   parameters = new AeadParameters(new KeyParameter(K), 16 * 8, nonce, A);
            ChaCha20Poly1305 cipher     = InitCipher(true, parameters);

            int ctLength = cipher.GetOutputSize(pLength);

            byte[] C = new byte[saLength + ctLength];
            Array.Copy(SA, 0, C, 0, saLength);

            int split = NextInt(random, saLength + 1);

            cipher.ProcessAadBytes(C, 0, split);
            cipher.ProcessAadBytes(C, split, saLength - split);

            int predicted = cipher.GetUpdateOutputSize(pLength);
            int len       = cipher.ProcessBytes(P, pHead, pLength, C, saLength);

            if (predicted != len)
            {
                Fail("encryption reported incorrect update length in randomised test");
            }

            len += cipher.DoFinal(C, saLength + len);
            if (ctLength != len)
            {
                Fail("encryption reported incorrect length in randomised test");
            }

            byte[] encT = cipher.GetMac();
            byte[] tail = new byte[ctLength - pLength];
            Array.Copy(C, saLength + pLength, tail, 0, tail.Length);

            if (!AreEqual(encT, tail))
            {
                Fail("stream contained wrong mac in randomised test");
            }

            cipher.Init(false, parameters);

            int decPHead   = random.Next(256);
            int decPLength = cipher.GetOutputSize(ctLength);
            int decPTail   = random.Next(256);

            byte[] decP = new byte[decPHead + decPLength + decPTail];

            split = NextInt(random, saLength + 1);
            cipher.ProcessAadBytes(C, 0, split);
            cipher.ProcessAadBytes(C, split, saLength - split);

            predicted = cipher.GetUpdateOutputSize(ctLength);
            len       = cipher.ProcessBytes(C, saLength, ctLength, decP, decPHead);
            if (predicted != len)
            {
                Fail("decryption reported incorrect update length in randomised test");
            }

            len += cipher.DoFinal(decP, decPHead + len);

            if (!AreEqual(P, pHead, pHead + pLength, decP, decPHead, decPHead + decPLength))
            {
                Fail("incorrect decrypt in randomised test");
            }

            byte[] decT = cipher.GetMac();
            if (!AreEqual(encT, decT))
            {
                Fail("decryption produced different mac from encryption");
            }

            //
            // key reuse test
            //
            cipher.Init(false, AeadTestUtilities.ReuseKey(parameters));

            decPHead   = random.Next(256);
            decPLength = cipher.GetOutputSize(ctLength);
            decPTail   = random.Next(256);
            decP       = new byte[decPHead + decPLength + decPTail];

            split = NextInt(random, saLength + 1);
            cipher.ProcessAadBytes(C, 0, split);
            cipher.ProcessAadBytes(C, split, saLength - split);

            len  = cipher.ProcessBytes(C, saLength, ctLength, decP, decPHead);
            len += cipher.DoFinal(decP, decPHead + len);

            if (!AreEqual(P, pHead, pHead + pLength, decP, decPHead, decPHead + decPLength))
            {
                Fail("incorrect decrypt in randomised test");
            }

            decT = cipher.GetMac();
            if (!AreEqual(encT, decT))
            {
                Fail("decryption produced different mac from encryption");
            }
        }