Skip to content

Commit 7826300

Browse files
committed
Const-time padding improvements
1 parent 9ce0432 commit 7826300

File tree

6 files changed

+41
-39
lines changed

6 files changed

+41
-39
lines changed

core/src/main/java/org/bouncycastle/crypto/paddings/ISO10126d2Padding.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ public int addPadding(
6161
public int padCount(byte[] in)
6262
throws InvalidCipherTextException
6363
{
64-
int count = in[in.length - 1] & 0xff;
64+
int count = in[in.length - 1] & 0xFF;
65+
int position = in.length - count;
6566

66-
if (count > in.length)
67+
int failed = (position | (count - 1)) >> 31;
68+
if (failed != 0)
6769
{
6870
throw new InvalidCipherTextException("pad block corrupted");
6971
}

core/src/main/java/org/bouncycastle/crypto/paddings/ISO7816d4Padding.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,18 +60,20 @@ public int addPadding(
6060
public int padCount(byte[] in)
6161
throws InvalidCipherTextException
6262
{
63-
int count = in.length - 1;
64-
65-
while (count > 0 && in[count] == 0)
63+
int position = -1, still00Mask = -1;
64+
int i = in.length;
65+
while (--i >= 0)
6666
{
67-
count--;
67+
int next = in[i] & 0xFF;
68+
int match00Mask = ((next ^ 0x00) - 1) >> 31;
69+
int match80Mask = ((next ^ 0x80) - 1) >> 31;
70+
position ^= (i ^ position) & (still00Mask & match80Mask);
71+
still00Mask &= match00Mask;
6872
}
69-
70-
if (in[count] != (byte)0x80)
73+
if (position < 0)
7174
{
7275
throw new InvalidCipherTextException("pad block corrupted");
7376
}
74-
75-
return in.length - count;
77+
return in.length - position;
7678
}
7779
}

core/src/main/java/org/bouncycastle/crypto/paddings/PKCS7Padding.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,16 @@ public int addPadding(
5656
public int padCount(byte[] in)
5757
throws InvalidCipherTextException
5858
{
59-
int count = in[in.length - 1] & 0xff;
60-
byte countAsbyte = (byte)count;
59+
byte countAsByte = in[in.length - 1];
60+
int count = countAsByte & 0xFF;
61+
int position = in.length - count;
6162

62-
// constant time version
63-
boolean failed = (count > in.length | count == 0);
64-
65-
for (int i = 0; i < in.length; i++)
63+
int failed = (position | (count - 1)) >> 31;
64+
for (int i = 0; i < in.length; ++i)
6665
{
67-
failed |= (in.length - i <= count) & (in[i] != countAsbyte);
66+
failed |= (in[i] ^ countAsByte) & ~((i - position) >> 31);
6867
}
69-
70-
if (failed)
68+
if (failed != 0)
7169
{
7270
throw new InvalidCipherTextException("pad block corrupted");
7371
}

core/src/main/java/org/bouncycastle/crypto/paddings/TBCPadding.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,15 @@ public int addPadding(
7676
public int padCount(byte[] in)
7777
throws InvalidCipherTextException
7878
{
79-
byte code = in[in.length - 1];
80-
81-
int index = in.length - 1;
82-
while (index > 0 && in[index - 1] == code)
79+
int i = in.length;
80+
int code = in[--i] & 0xFF, count = 1, countingMask = -1;
81+
while (--i >= 0)
8382
{
84-
index--;
83+
int next = in[i] & 0xFF;
84+
int matchMask = ((next ^ code) - 1) >> 31;
85+
countingMask &= matchMask;
86+
count -= countingMask;
8587
}
86-
87-
return in.length - index;
88+
return count;
8889
}
8990
}

core/src/main/java/org/bouncycastle/crypto/paddings/X923Padding.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,11 @@ public int addPadding(
6868
public int padCount(byte[] in)
6969
throws InvalidCipherTextException
7070
{
71-
int count = in[in.length - 1] & 0xff;
71+
int count = in[in.length - 1] & 0xFF;
72+
int position = in.length - count;
7273

73-
if (count > in.length)
74+
int failed = (position | (count - 1)) >> 31;
75+
if (failed != 0)
7476
{
7577
throw new InvalidCipherTextException("pad block corrupted");
7678
}

core/src/main/java/org/bouncycastle/crypto/paddings/ZeroBytePadding.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,15 @@ public int addPadding(
5656
public int padCount(byte[] in)
5757
throws InvalidCipherTextException
5858
{
59-
int count = in.length;
60-
61-
while (count > 0)
59+
int count = 0, still00Mask = -1;
60+
int i = in.length;
61+
while (--i >= 0)
6262
{
63-
if (in[count - 1] != 0)
64-
{
65-
break;
66-
}
67-
68-
count--;
63+
int next = in[i] & 0xFF;
64+
int match00Mask = ((next ^ 0x00) - 1) >> 31;
65+
still00Mask &= match00Mask;
66+
count -= still00Mask;
6967
}
70-
71-
return in.length - count;
68+
return count;
7269
}
7370
}

0 commit comments

Comments
 (0)