summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2019-09-09 20:50:52 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2019-09-09 20:50:52 +0700
commitfb19d10129f16b8a54fede467d52268a32b66a50 (patch)
tree9420966c93f21c927f046d88c61c05e3a1ce34b5
parentUpdates from bc-java (diff)
downloadBouncyCastle.NET-ed25519-fb19d10129f16b8a54fede467d52268a32b66a50.tar.xz
Tampering and reuse test cases for GCM
-rw-r--r--crypto/test/src/crypto/test/AeadTestUtilities.cs63
-rw-r--r--crypto/test/src/crypto/test/GCMTest.cs54
2 files changed, 90 insertions, 27 deletions
diff --git a/crypto/test/src/crypto/test/AeadTestUtilities.cs b/crypto/test/src/crypto/test/AeadTestUtilities.cs
index 40f334202..a5e21552f 100644
--- a/crypto/test/src/crypto/test/AeadTestUtilities.cs
+++ b/crypto/test/src/crypto/test/AeadTestUtilities.cs
@@ -1,11 +1,74 @@
 using System;
 
+using Org.BouncyCastle.Crypto.Modes;
 using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Utilities.Test;
 
 namespace Org.BouncyCastle.Crypto.Tests
 {
     public class AeadTestUtilities
     {
+        internal static void TestTampering(ITest test, IAeadCipher cipher, ICipherParameters parameters)
+        {
+            byte[] plaintext = new byte[1000];
+            for (int i = 0; i < plaintext.Length; i++)
+            {
+                plaintext[i] = (byte)i;
+            }
+            cipher.Init(true, parameters);
+
+            byte[] ciphertext = new byte[cipher.GetOutputSize(plaintext.Length)];
+            int len = cipher.ProcessBytes(plaintext, 0, plaintext.Length, ciphertext, 0);
+            cipher.DoFinal(ciphertext, len);
+
+            int macLength = cipher.GetMac().Length;
+
+            // Test tampering with a single byte
+            cipher.Init(false, parameters);
+            byte[] tampered = new byte[ciphertext.Length];
+            byte[] output = new byte[plaintext.Length];
+            Array.Copy(ciphertext, 0, tampered, 0, tampered.Length);
+            tampered[0] += 1;
+
+            cipher.ProcessBytes(tampered, 0, tampered.Length, output, 0);
+            try
+            {
+                cipher.DoFinal(output, 0);
+                throw new TestFailedException(
+                    new SimpleTestResult(false, test + " : tampering of ciphertext not detected."));
+            }
+            catch (InvalidCipherTextException e)
+            {
+                // Expected
+            }
+
+            // Test truncation of ciphertext to < tag length
+            cipher.Init(false, parameters);
+            byte[] truncated = new byte[macLength - 1];
+            Array.Copy(ciphertext, 0, truncated, 0, truncated.Length);
+
+            cipher.ProcessBytes(truncated, 0, truncated.Length, output, 0);
+            try
+            {
+                cipher.DoFinal(output, 0);
+                Fail(test, "tampering of ciphertext not detected.");
+            }
+            catch (InvalidCipherTextException e)
+            {
+                // Expected
+            }
+        }
+
+        private static void Fail(ITest test, string message)
+        {
+            throw new TestFailedException(SimpleTestResult.Failed(test, message));
+        }
+
+        private static void Fail(ITest test, string message, string expected, string result)
+        {
+            throw new TestFailedException(SimpleTestResult.Failed(test, message, expected, result));
+        }
+
         internal static AeadParameters ReuseKey(AeadParameters p)
         {
             return new AeadParameters(null, p.MacSize, p.GetNonce(), p.GetAssociatedText());
diff --git a/crypto/test/src/crypto/test/GCMTest.cs b/crypto/test/src/crypto/test/GCMTest.cs
index e5e5fc43e..2ab5c6216 100644
--- a/crypto/test/src/crypto/test/GCMTest.cs
+++ b/crypto/test/src/crypto/test/GCMTest.cs
@@ -9,6 +9,7 @@ using Org.BouncyCastle.Crypto.Modes;
 using Org.BouncyCastle.Crypto.Modes.Gcm;
 using Org.BouncyCastle.Crypto.Parameters;
 using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
 using Org.BouncyCastle.Utilities.Date;
 using Org.BouncyCastle.Utilities.Encoders;
 using Org.BouncyCastle.Utilities.Test;
@@ -356,39 +357,38 @@ namespace Org.BouncyCastle.Crypto.Tests
                 // expected
             }
 
-            // TODO
-            //AEADTestUtil.testTampering(this, gcm, new AEADParameters(new KeyParameter(new byte[16]), 128, new byte[16]));
+            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];
+            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);
+            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.ProcessBytes(P, 0, P.Length, buf, 0);
 
-            //c.doFinal(buf, 0);
+            c.DoFinal(buf, 0);
 
-            //try
-            //{
-            //    c.doFinal(buf, 0);
-            //    fail("no exception on reuse");
-            //}
-            //catch (IllegalStateException e)
-            //{
-            //    isTrue("wrong message", e.getMessage().equals("GCM cipher cannot be reused for encryption"));
-            //}
+            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 (IllegalArgumentException e)
-            //{
-            //    isTrue("wrong message", e.getMessage().equals("cannot reuse nonce for GCM 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"));
+            }
         }
 
         private void RunTestCase(string[] testVector)