diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2019-09-09 20:50:52 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2019-09-09 20:50:52 +0700 |
commit | fb19d10129f16b8a54fede467d52268a32b66a50 (patch) | |
tree | 9420966c93f21c927f046d88c61c05e3a1ce34b5 /crypto/test | |
parent | Updates from bc-java (diff) | |
download | BouncyCastle.NET-ed25519-fb19d10129f16b8a54fede467d52268a32b66a50.tar.xz |
Tampering and reuse test cases for GCM
Diffstat (limited to 'crypto/test')
-rw-r--r-- | crypto/test/src/crypto/test/AeadTestUtilities.cs | 63 | ||||
-rw-r--r-- | crypto/test/src/crypto/test/GCMTest.cs | 54 |
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) |