summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2023-02-16 23:44:57 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2023-02-16 23:44:57 +0700
commit70d2286398471704b5c494665e55b8ea2bf88a6b (patch)
tree5de091d225964230bd1a21a28009e2464d00fab0
parentGCM perf. opts. (diff)
downloadBouncyCastle.NET-ed25519-70d2286398471704b5c494665e55b8ea2bf88a6b.tar.xz
TLS: Process CCM packet directly
-rw-r--r--crypto/src/crypto/modes/CcmBlockCipher.cs14
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs6
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsCcmImpl.cs31
-rw-r--r--crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs15
4 files changed, 52 insertions, 14 deletions
diff --git a/crypto/src/crypto/modes/CcmBlockCipher.cs b/crypto/src/crypto/modes/CcmBlockCipher.cs
index c2d3e7e76..7784e7cca 100644
--- a/crypto/src/crypto/modes/CcmBlockCipher.cs
+++ b/crypto/src/crypto/modes/CcmBlockCipher.cs
@@ -166,10 +166,10 @@ namespace Org.BouncyCastle.Crypto.Modes
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
         public virtual int DoFinal(Span<byte> output)
         {
-            byte[] input = data.GetBuffer();
-            int inLen = Convert.ToInt32(data.Length);
+            if (!data.TryGetBuffer(out var buffer))
+                throw new UnauthorizedAccessException();
 
-            int len = ProcessPacket(input.AsSpan(0, inLen), output);
+            int len = ProcessPacket(buffer, output);
 
             Reset();
 
@@ -223,6 +223,8 @@ namespace Org.BouncyCastle.Crypto.Modes
          */
         public virtual byte[] ProcessPacket(byte[] input, int inOff, int inLen)
         {
+            Check.DataLength(input, inOff, inLen, "input buffer too short");
+
             byte[] output;
 
             if (forEncryption)
@@ -257,6 +259,11 @@ namespace Org.BouncyCastle.Crypto.Modes
          */
         public virtual int ProcessPacket(byte[] input, int inOff, int inLen, byte[] output, int outOff)
         {
+            Check.DataLength(input, inOff, inLen, "input buffer too short");
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+            return ProcessPacket(input.AsSpan(inOff, inLen), output.AsSpan(outOff));
+#else
             // TODO: handle null keyParam (e.g. via RepeatedKeySpec)
             // Need to keep the CTR and CBC Mac parts around and reset
             if (keyParam == null)
@@ -350,6 +357,7 @@ namespace Org.BouncyCastle.Crypto.Modes
             }
 
             return outputLen;
+#endif
         }
 
 #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs b/crypto/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs
index 4965c92bd..82f1382bd 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsAeadCipherImpl.cs
@@ -6,11 +6,11 @@ using Org.BouncyCastle.Crypto.Parameters;
 
 namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
 {
-    internal sealed class BcTlsAeadCipherImpl
+    internal class BcTlsAeadCipherImpl
         : TlsAeadCipherImpl
     {
         private readonly bool m_isEncrypting;
-        private readonly IAeadCipher m_cipher;
+        internal readonly IAeadCipher m_cipher;
 
         private KeyParameter key;
 
@@ -42,7 +42,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
             return m_cipher.GetOutputSize(inputLength);
         }
 
-        public int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset)
+        public virtual int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset)
         {
             int len = m_cipher.ProcessBytes(input, inputOffset, inputLength, output, outputOffset);
 
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsCcmImpl.cs b/crypto/src/tls/crypto/impl/bc/BcTlsCcmImpl.cs
new file mode 100644
index 000000000..641ad0ab0
--- /dev/null
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsCcmImpl.cs
@@ -0,0 +1,31 @@
+using System;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Modes;
+
+namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
+{
+    internal class BcTlsCcmImpl
+        : BcTlsAeadCipherImpl
+    {
+        internal BcTlsCcmImpl(CcmBlockCipher cipher, bool isEncrypting)
+            : base(cipher, isEncrypting)
+        {
+        }
+
+        public override int DoFinal(byte[] input, int inputOffset, int inputLength, byte[] output, int outputOffset)
+        {
+            if (!(m_cipher is CcmBlockCipher ccm))
+                throw new InvalidOperationException();
+
+            try
+            {
+                return ccm.ProcessPacket(input, inputOffset, inputLength, output, outputOffset);
+            }
+            catch (InvalidCipherTextException e)
+            {
+                throw new TlsFatalAlert(AlertDescription.bad_record_mac, e);
+            }
+        }
+    }
+}
diff --git a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs
index 0cad3e10d..39df32ed8 100644
--- a/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs
+++ b/crypto/src/tls/crypto/impl/bc/BcTlsCrypto.cs
@@ -540,8 +540,8 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
         protected virtual TlsAeadCipher CreateCipher_Aes_Ccm(TlsCryptoParameters cryptoParams, int cipherKeySize,
             int macSize)
         {
-            BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Ccm(), true);
-            BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_Aes_Ccm(), false);
+            var encrypt = new BcTlsCcmImpl(CreateAeadCipher_Aes_Ccm(), true);
+            var decrypt = new BcTlsCcmImpl(CreateAeadCipher_Aes_Ccm(), false);
 
             return new TlsAeadCipher(cryptoParams, encrypt, decrypt, cipherKeySize, macSize, TlsAeadCipher.AEAD_CCM);
         }
@@ -587,8 +587,8 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
 
         protected virtual TlsAeadCipher CreateCipher_SM4_Ccm(TlsCryptoParameters cryptoParams)
         {
-            BcTlsAeadCipherImpl encrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Ccm(), true);
-            BcTlsAeadCipherImpl decrypt = new BcTlsAeadCipherImpl(CreateAeadCipher_SM4_Ccm(), false);
+            var encrypt = new BcTlsCcmImpl(CreateAeadCipher_SM4_Ccm(), true);
+            var decrypt = new BcTlsCcmImpl(CreateAeadCipher_SM4_Ccm(), false);
 
             return new TlsAeadCipher(cryptoParams, encrypt, decrypt, 16, 16, TlsAeadCipher.AEAD_CCM);
         }
@@ -637,18 +637,17 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
             return new SM4Engine();
         }
 
-        protected virtual IAeadCipher CreateCcmMode(IBlockCipher engine)
+        protected virtual CcmBlockCipher CreateCcmMode(IBlockCipher engine)
         {
             return new CcmBlockCipher(engine);
         }
 
         protected virtual IAeadCipher CreateGcmMode(IBlockCipher engine)
         {
-            // TODO Consider allowing custom configuration of multiplier
             return new GcmBlockCipher(engine);
         }
 
-        protected virtual IAeadCipher CreateAeadCipher_Aes_Ccm()
+        protected virtual CcmBlockCipher CreateAeadCipher_Aes_Ccm()
         {
             return CreateCcmMode(CreateAesEngine());
         }
@@ -668,7 +667,7 @@ namespace Org.BouncyCastle.Tls.Crypto.Impl.BC
             return CreateGcmMode(CreateCamelliaEngine());
         }
 
-        protected virtual IAeadCipher CreateAeadCipher_SM4_Ccm()
+        protected virtual CcmBlockCipher CreateAeadCipher_SM4_Ccm()
         {
             return CreateCcmMode(CreateSM4Engine());
         }