diff options
author | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-08-25 13:08:01 +0700 |
---|---|---|
committer | Peter Dettman <peter.dettman@bouncycastle.org> | 2022-08-25 13:08:01 +0700 |
commit | 2753922dff3e341f66c8bc3852e6eeec70827e1e (patch) | |
tree | 53473c56b9f6311b284fe9244bee6b1e246108ea | |
parent | added EncapsulationLength property (diff) | |
download | BouncyCastle.NET-ed25519-2753922dff3e341f66c8bc3852e6eeec70827e1e.tar.xz |
Const-time padding improvements
-rw-r--r-- | crypto/src/crypto/paddings/ISO10126d2Padding.cs | 12 | ||||
-rw-r--r-- | crypto/src/crypto/paddings/ISO7816d4Padding.cs | 22 | ||||
-rw-r--r-- | crypto/src/crypto/paddings/Pkcs7Padding.cs | 16 | ||||
-rw-r--r-- | crypto/src/crypto/paddings/TbcPadding.cs | 15 | ||||
-rw-r--r-- | crypto/src/crypto/paddings/X923Padding.cs | 11 | ||||
-rw-r--r-- | crypto/src/crypto/paddings/ZeroBytePadding.cs | 24 |
6 files changed, 47 insertions, 53 deletions
diff --git a/crypto/src/crypto/paddings/ISO10126d2Padding.cs b/crypto/src/crypto/paddings/ISO10126d2Padding.cs index e132a62dd..92845f165 100644 --- a/crypto/src/crypto/paddings/ISO10126d2Padding.cs +++ b/crypto/src/crypto/paddings/ISO10126d2Padding.cs @@ -60,17 +60,17 @@ namespace Org.BouncyCastle.Crypto.Paddings * return the number of pad bytes present in the block. */ public int PadCount(byte[] input) - //throws InvalidCipherTextException { - int count = input[input.Length - 1] & 0xff; + int count = input[input.Length -1]; + int position = input.Length - count; - if (count > input.Length) - { + // constant time version + int failed = (position | (count - 1)) >> 31; + + if (failed != 0) throw new InvalidCipherTextException("pad block corrupted"); - } return count; } } - } diff --git a/crypto/src/crypto/paddings/ISO7816d4Padding.cs b/crypto/src/crypto/paddings/ISO7816d4Padding.cs index 016b25a81..533b9d421 100644 --- a/crypto/src/crypto/paddings/ISO7816d4Padding.cs +++ b/crypto/src/crypto/paddings/ISO7816d4Padding.cs @@ -58,22 +58,22 @@ namespace Org.BouncyCastle.Crypto.Paddings /** * return the number of pad bytes present in the block. */ - public int PadCount( - byte[] input) + public int PadCount(byte[] input) { - int count = input.Length - 1; - - while (count > 0 && input[count] == 0) + int position = -1, still00Mask = -1; + int i = input.Length; + while (--i >= 0) { - count--; + int next = input[i]; + int match00Mask = ((next ^ 0x00) - 1) >> 31; + int match80Mask = ((next ^ 0x80) - 1) >> 31; + position ^= (i ^ position) & (still00Mask & match80Mask); + still00Mask &= match00Mask; } - - if (input[count] != (byte)0x80) - { + if (position < 0) throw new InvalidCipherTextException("pad block corrupted"); - } - return input.Length - count; + return input.Length - position; } } } diff --git a/crypto/src/crypto/paddings/Pkcs7Padding.cs b/crypto/src/crypto/paddings/Pkcs7Padding.cs index 11585647a..4c192fcdf 100644 --- a/crypto/src/crypto/paddings/Pkcs7Padding.cs +++ b/crypto/src/crypto/paddings/Pkcs7Padding.cs @@ -54,23 +54,21 @@ namespace Org.BouncyCastle.Crypto.Paddings /** * return the number of pad bytes present in the block. */ - public int PadCount( - byte[] input) + public int PadCount(byte[] input) { byte countAsByte = input[input.Length - 1]; int count = countAsByte; + int position = input.Length - count; - if (count < 1 || count > input.Length) - throw new InvalidCipherTextException("pad block corrupted"); - - for (int i = 2; i <= count; i++) + int failed = (position | (count - 1)) >> 31; + for (int i = 0; i < input.Length; ++i) { - if (input[input.Length - i] != countAsByte) - throw new InvalidCipherTextException("pad block corrupted"); + failed |= (input[i] ^ countAsByte) & ~((i - position) >> 31); } + if (failed != 0) + throw new InvalidCipherTextException("pad block corrupted"); return count; } } - } diff --git a/crypto/src/crypto/paddings/TbcPadding.cs b/crypto/src/crypto/paddings/TbcPadding.cs index 74b64e8e1..8034dc8ba 100644 --- a/crypto/src/crypto/paddings/TbcPadding.cs +++ b/crypto/src/crypto/paddings/TbcPadding.cs @@ -65,15 +65,16 @@ namespace Org.BouncyCastle.Crypto.Paddings /// <summary> return the number of pad bytes present in the block.</summary> public virtual int PadCount(byte[] input) { - byte code = input[input.Length - 1]; - - int index = input.Length - 1; - while (index > 0 && input[index - 1] == code) + int i = input.Length; + int code = input[--i], count = 1, countingMask = -1; + while (--i >= 0) { - index--; + int next = input[i]; + int matchMask = ((next ^ code) - 1) >> 31; + countingMask &= matchMask; + count -= countingMask; } - - return input.Length - index; + return count; } } } diff --git a/crypto/src/crypto/paddings/X923Padding.cs b/crypto/src/crypto/paddings/X923Padding.cs index cc1b52b3e..fc9668116 100644 --- a/crypto/src/crypto/paddings/X923Padding.cs +++ b/crypto/src/crypto/paddings/X923Padding.cs @@ -66,15 +66,14 @@ namespace Org.BouncyCastle.Crypto.Paddings /** * return the number of pad bytes present in the block. */ - public int PadCount( - byte[] input) + public int PadCount(byte[] input) { - int count = input[input.Length - 1] & 0xff; + int count = input[input.Length - 1]; + int position = input.Length - count; - if (count > input.Length) - { + int failed = (position | (count - 1)) >> 31; + if (failed != 0) throw new InvalidCipherTextException("pad block corrupted"); - } return count; } diff --git a/crypto/src/crypto/paddings/ZeroBytePadding.cs b/crypto/src/crypto/paddings/ZeroBytePadding.cs index 0d55ca4c2..ab5f4a1a3 100644 --- a/crypto/src/crypto/paddings/ZeroBytePadding.cs +++ b/crypto/src/crypto/paddings/ZeroBytePadding.cs @@ -46,23 +46,19 @@ namespace Org.BouncyCastle.Crypto.Paddings return added; } - /// <summary> return the number of pad bytes present in the block.</summary> - public int PadCount( - byte[] input) + /// <summary> return the number of pad bytes present in the block.</summary> + public int PadCount(byte[] input) { - int count = input.Length; - - while (count > 0) + int count = 0, still00Mask = -1; + int i = input.Length; + while (--i >= 0) { - if (input[count - 1] != 0) - { - break; - } - - count--; + int next = input[i]; + int match00Mask = ((next ^ 0x00) - 1) >> 31; + still00Mask &= match00Mask; + count -= still00Mask; } - - return input.Length - count; + return count; } } } |