Improve OAEP const-time decoding
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
//
|