summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2022-01-13 17:26:12 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2022-01-13 17:26:12 +0700
commit4ba96ce3ef67eff82e0b76288e96d9068729c6fe (patch)
tree36c2c050bbea48c7268733d4cffc10aeaf170fc7
parentadded key length check (diff)
downloadBouncyCastle.NET-ed25519-4ba96ce3ef67eff82e0b76288e96d9068729c6fe.tar.xz
Improve OAEP const-time decoding
-rw-r--r--crypto/src/crypto/encodings/OaepEncoding.cs34
1 files changed, 17 insertions, 17 deletions
diff --git a/crypto/src/crypto/encodings/OaepEncoding.cs b/crypto/src/crypto/encodings/OaepEncoding.cs
index 295a43aac..f3550b9cd 100644
--- a/crypto/src/crypto/encodings/OaepEncoding.cs
+++ b/crypto/src/crypto/encodings/OaepEncoding.cs
@@ -213,7 +213,8 @@ namespace Org.BouncyCastle.Crypto.Encodings
             // on encryption, we need to make sure our decrypted block comes back
             // the same size.
             //
-            bool wrongData = (block.Length < (2 * defHash.Length) + 1);
+            // i.e. wrong when block.length < (2 * defHash.length) + 1
+            int wrongMask = (block.Length - ((2 * defHash.Length) + 1)) >> 31;
 
             if (data.Length <= block.Length)
             {
@@ -222,7 +223,7 @@ namespace Org.BouncyCastle.Crypto.Encodings
             else
             {
                 Array.Copy(data, 0, block, 0, block.Length);
-                wrongData = true;
+                wrongMask |= 1;
             }
 
             //
@@ -250,39 +251,38 @@ namespace Org.BouncyCastle.Crypto.Encodings
             // check the hash of the encoding params.
             // long check to try to avoid this been a source of a timing attack.
             //
-            bool defHashWrong = false;
-
             for (int i = 0; i != defHash.Length; i++)
             {
-                if (defHash[i] != block[defHash.Length + i])
-                {
-                    defHashWrong = true;
-                }
+                wrongMask |= defHash[i] ^ block[defHash.Length + i];
             }
 
             //
             // find the data block
             //
-            int start = block.Length;
+            int start = -1;
 
             for (int index = 2 * defHash.Length; index != block.Length; index++)
             {
-                if (block[index] != 0 & start == block.Length)
-                {
-                    start = index;
-                }
-            }
+                int octet = block[index];
 
-            bool dataStartWrong = (start > (block.Length - 1) | block[start] != 1);
+                // i.e. mask will be 0xFFFFFFFF if octet is non-zero and start is (still) negative, else 0.
+                int shouldSetMask = (-octet & start) >> 31;
 
-            start++;
+                start += index & shouldSetMask;
+            }
 
-            if (defHashWrong | wrongData | dataStartWrong)
+            wrongMask |= start >> 31;
+            ++start;
+            wrongMask |= block[start] ^ 1;
+
+            if (wrongMask != 0)
             {
                 Arrays.Fill(block, 0);
                 throw new InvalidCipherTextException("data wrong");
             }
 
+            ++start;
+
             //
             // extract the data block
             //