diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-01-13 17:26:12 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-01-13 17:26:12 +0700 |
commit | 4ba96ce3ef67eff82e0b76288e96d9068729c6fe (patch) | |
tree | 36c2c050bbea48c7268733d4cffc10aeaf170fc7 | |
parent | added key length check (diff) | |
download | BouncyCastle.NET-ed25519-4ba96ce3ef67eff82e0b76288e96d9068729c6fe.tar.xz |
Improve OAEP const-time decoding
-rw-r--r-- | crypto/src/crypto/encodings/OaepEncoding.cs | 34 |
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 // |