summaryrefslogtreecommitdiffstats
path: root/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java
diff options
context:
space:
mode:
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java100
1 files changed, 95 insertions, 5 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java
index 5dd47ae..fbc8bf4 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/SICBlockCipher.java
@@ -106,6 +106,27 @@ public class SICBlockCipher
return rv;
}
+ private void incrementCounterPow2(int pow2Div8)
+ {
+ // increment counter by 1 << 8 * pow2Div8
+ for (int i = counter.length - (1 + pow2Div8); i >= 0 && ++counter[i] == 0; i--)
+ {
+ ; // do nothing - pre-increment and test for 0 in counter does the job.
+ }
+ }
+
+ private void incrementCounter(int offSet)
+ {
+ byte old = counter[counter.length - 1];
+
+ counter[counter.length - 1] += offSet;
+
+ if (old != 0 && counter[counter.length - 1] < old)
+ {
+ incrementCounterPow2(1);
+ }
+ }
+
private void incrementCounter()
{
// increment counter by 1.
@@ -115,6 +136,33 @@ public class SICBlockCipher
}
}
+ private void decrementCounterPow2(int pow2Div8)
+ {
+ if (counter[pow2Div8] == 0)
+ {
+ boolean nonZero = false;
+
+ for (int i = counter.length - (1 + pow2Div8); i > 0; i--)
+ {
+ if (counter[i] != 0)
+ {
+ nonZero = true;
+ }
+ }
+
+ if (!nonZero)
+ {
+ throw new IllegalStateException("attempt to reduce counter past zero.");
+ }
+ }
+
+ // decrement counter by 1.
+ for (int i = counter.length - (1 + pow2Div8); i >= 0 && --counter[i] == -1; i--)
+ {
+ ;
+ }
+ }
+
private void decrementCounter()
{
if (counter[0] == 0)
@@ -148,9 +196,27 @@ public class SICBlockCipher
{
long numBlocks = (n + byteCount) / blockSize;
- for (long i = 0; i != numBlocks; i++)
+ if (numBlocks > 255)
+ {
+ long gap = numBlocks;
+
+ for (int i = 5; i >= 1; i--)
+ {
+ long diff = 1L << (8 * i);
+
+ while (gap >= diff)
+ {
+ incrementCounterPow2(i);
+
+ gap -= diff;
+ }
+ }
+
+ incrementCounter((int)gap);
+ }
+ else
{
- incrementCounter();
+ incrementCounter((int)numBlocks);
}
byteCount = (int)((n + byteCount) - (blockSize * numBlocks));
@@ -159,9 +225,33 @@ public class SICBlockCipher
{
long numBlocks = (-n - byteCount) / blockSize;
- for (long i = 0; i != numBlocks; i++)
+ if (numBlocks > 255)
{
- decrementCounter();
+ long gap = numBlocks;
+
+ for (int i = 5; i >= 1; i--)
+ {
+ long diff = 1L << (8 * i);
+
+ while (gap > diff)
+ {
+ decrementCounterPow2(i);
+
+ gap -= diff;
+ }
+ }
+
+ for (long i = 0; i != gap; i++)
+ {
+ decrementCounter();
+ }
+ }
+ else
+ {
+ for (long i = 0; i != numBlocks; i++)
+ {
+ decrementCounter();
+ }
}
int gap = (int)(byteCount + n + (blockSize * numBlocks));
@@ -209,7 +299,7 @@ public class SICBlockCipher
for (int i = res.length - 1; i >= 1; i--)
{
- int v = (res[i] - IV[i]);
+ int v = (res[i] & 0xff) - (IV[i] & 0xff);
if (v < 0)
{