]> git.deb.at Git - rhonda/impostor.hazel.git/commitdiff
Add a few constant-time utilities
authorMatthew Endsley <mendsley@gmail.com>
Sat, 19 Dec 2020 02:02:49 +0000 (18:02 -0800)
committerMatthew Endsley <mendsley@gmail.com>
Tue, 2 Feb 2021 16:53:30 +0000 (08:53 -0800)
Hazel/Crypto/Const.cs [new file with mode: 0644]
Hazel/Hazel.csproj

diff --git a/Hazel/Crypto/Const.cs b/Hazel/Crypto/Const.cs
new file mode 100644 (file)
index 0000000..4dfef47
--- /dev/null
@@ -0,0 +1,82 @@
+using System.Diagnostics;
+
+namespace Hazel.Crypto
+{
+    public static class Const
+    {
+
+        /// <summary>
+        /// Compare two bytes for equality.
+        ///
+        /// This takes care to always use a constant amount of time to prevent
+        /// leaking information through side-channel attacks.
+        ///
+        /// This is aceived by collapsing the xor bits down into a single bit.
+        ///
+        /// Ported from:
+        /// https://github.com/mendsley/tiny/blob/master/include/tiny/crypto/constant.h
+        /// </summary>
+        /// <returns>
+        /// Returns `1` is the two bytes or equivalent. Otherwise, returns `0`
+        /// </returns>
+        public static byte ConstantCompareByte(byte a, byte b)
+        {
+            byte result = (byte)(~(a ^ b));
+
+            // collapse bits down to the LSB
+            result &= (byte)(result >> 4);
+            result &= (byte)(result >> 2);
+            result &= (byte)(result >> 1);
+
+            return result;
+        }
+
+        /// <summary>
+        /// Compare two equal length spans for equality.
+        ///
+        /// This takes care to always use a constant amount of time to prevent
+        /// leaking information through side-channel attacks.
+        ///
+        /// Ported from:
+        /// https://github.com/mendsley/tiny/blob/master/include/tiny/crypto/constant.h
+        /// </summary>
+        /// <returns>
+        /// Returns `1` if the spans are equivalent. Others, returns `0`.
+        /// </returns>
+        public static byte ConstantCompareSpans(ByteSpan a, ByteSpan b)
+        {
+            Debug.Assert(a.Length == b.Length);
+
+            byte value = 0;
+            for (int ii = 0, nn = a.Length; ii != nn; ++ii)
+            {
+                value |= (byte)(a[ii] ^ b[ii]);
+            }
+
+            return ConstantCompareByte(value, 0);
+        }
+
+        /// <summary>
+        /// Compare a span against an all zero span
+        ///
+        /// This takes care to always use a constant amount of time to prevent
+        /// leaking information through side-channel attacks.
+        ///
+        /// Ported from:
+        /// https://github.com/mendsley/tiny/blob/master/include/tiny/crypto/constant.h
+        /// </summary>
+        /// <returns>
+        /// Returns `1` if the spans is all zeros. Others, returns `0`.
+        /// </returns>
+        public static byte ConstantCompareZeroSpan(ByteSpan a)
+        {
+            byte value = 0;
+            for (int ii = 0, nn = a.Length; ii != nn; ++ii)
+            {
+                value |= (byte)(a[ii] ^ 0);
+            }
+
+            return ConstantCompareByte(value, 0);
+        }
+    }
+}
index 79ad6e82a3cbc97efc59a092585f2709806b4021..9c49e9637c03dda12d7ab7201729537bbe7c7fe2 100644 (file)
@@ -73,6 +73,7 @@
     <Compile Include="Connection.cs" />
     <Compile Include="ConnectionListener.cs" />
     <Compile Include="ConnectionState.cs" />
+    <Compile Include="Crypto\Const.cs" />
     <Compile Include="DataReceivedEventArgs.cs" />
     <Compile Include="DisconnectedEventArgs.cs" />
     <Compile Include="FewerThreads\HazelThreadPool.cs" />