summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2019-09-09 20:49:26 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2019-09-09 20:49:26 +0700
commit1c698faafd3eb5f65a80fc0323f43dcdb83ca657 (patch)
tree2c43ee7a582d480a2b259ef5fbc51399c048c10c
parentRewrite conditionals to avoid overflow (diff)
downloadBouncyCastle.NET-ed25519-1c698faafd3eb5f65a80fc0323f43dcdb83ca657.tar.xz
Updates from bc-java
-rw-r--r--crypto/src/util/Arrays.cs61
1 files changed, 51 insertions, 10 deletions
diff --git a/crypto/src/util/Arrays.cs b/crypto/src/util/Arrays.cs
index 7b060bf3c..6f2503d2d 100644
--- a/crypto/src/util/Arrays.cs
+++ b/crypto/src/util/Arrays.cs
@@ -81,20 +81,45 @@ namespace Org.BouncyCastle.Utilities
         /// <param name="a">first array</param>
         /// <param name="b">second array</param>
         /// <returns>true if arrays equal, false otherwise.</returns>
-        public static bool ConstantTimeAreEqual(
-            byte[]	a,
-            byte[]	b)
+        public static bool ConstantTimeAreEqual(byte[] a, byte[] b)
         {
-            int i = a.Length;
-            if (i != b.Length)
+            if (null == a || null == b)
                 return false;
-            int cmp = 0;
-            while (i != 0)
+            if (a == b)
+                return true;
+
+            int len = System.Math.Min(a.Length, b.Length);
+            int nonEqual = a.Length ^ b.Length;
+            for (int i = 0; i < len; ++i)
             {
-                --i;
-                cmp |= (a[i] ^ b[i]);
+                nonEqual |= (a[i] ^ b[i]);
+            }
+            for (int i = len; i < b.Length; ++i)
+            {
+                nonEqual |= (b[i] ^ ~b[i]);
             }
-            return cmp == 0;
+            return 0 == nonEqual;
+        }
+
+        public static bool ConstantTimeAreEqual(int len, byte[] a, int aOff, byte[] b, int bOff)
+        {
+            if (null == a)
+                throw new ArgumentNullException("a");
+            if (null == b)
+                throw new ArgumentNullException("b");
+            if (len < 0)
+                throw new ArgumentException("cannot be negative", "len");
+            if (aOff > (a.Length - len))
+                throw new IndexOutOfRangeException("'aOff' value invalid for specified length");
+            if (bOff > (b.Length - len))
+                throw new IndexOutOfRangeException("'bOff' value invalid for specified length");
+
+            int d = 0;
+            for (int i = 0; i < len; ++i)
+            {
+                d |= (a[aOff + i] ^ b[bOff + i]);
+            }
+            return 0 == d;
         }
 
         public static bool AreEqual(
@@ -713,6 +738,22 @@ namespace Org.BouncyCastle.Utilities
             return result;
         }
 
+        public static void Clear(byte[] data)
+        {
+            if (null != data)
+            {
+                Array.Clear(data, 0, data.Length);
+            }
+        }
+
+        public static void Clear(int[] data)
+        {
+            if (null != data)
+            {
+                Array.Clear(data, 0, data.Length);
+            }
+        }
+
         public static bool IsNullOrContainsNull(object[] array)
         {
             if (null == array)