summaryrefslogtreecommitdiffstats
path: root/bcprov/src/main/java/org/bouncycastle/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'bcprov/src/main/java/org/bouncycastle/crypto')
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/AndroidDigestFactory.java7
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/LongDigest.java9
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java21
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/OpenSSLDigest.java2
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java21
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java21
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java14
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java13
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeEngine.java4
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/RC2Engine.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/RC4Engine.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/engines/TwofishEngine.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java179
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java3
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java49
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/macs/HMac.java95
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java59
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java80
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/DSAValidationParameters.java15
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java25
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java6
-rw-r--r--bcprov/src/main/java/org/bouncycastle/crypto/util/Pack.java122
29 files changed, 599 insertions, 211 deletions
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java
index 2543b59..18cc648 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/PBEParametersGenerator.java
@@ -130,7 +130,14 @@ public abstract class PBEParametersGenerator
public static byte[] PKCS5PasswordToUTF8Bytes(
char[] password)
{
- return Strings.toUTF8ByteArray(password);
+ if (password != null)
+ {
+ return Strings.toUTF8ByteArray(password);
+ }
+ else
+ {
+ return new byte[0];
+ }
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/AndroidDigestFactory.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/AndroidDigestFactory.java
index 3dc7059..b7bac28 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/AndroidDigestFactory.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/AndroidDigestFactory.java
@@ -34,15 +34,18 @@ public final class AndroidDigestFactory {
try {
factoryImplementationClass = Class.forName(OpenSSLFactoryClassName);
// Double check for NativeCrypto in case we are running on RI for testing
- Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto");
+ Class.forName("com.android.org.conscrypt.NativeCrypto");
} catch (ClassNotFoundException e1) {
try {
factoryImplementationClass = Class.forName(BouncyCastleFactoryClassName);
} catch (ClassNotFoundException e2) {
- throw new AssertionError("Failed to load AndroidDigestFactoryInterface "
+ AssertionError e = new AssertionError("Failed to load "
+ + "AndroidDigestFactoryInterface "
+ "implementation. Looked for "
+ OpenSSLFactoryClassName + " and "
+ BouncyCastleFactoryClassName);
+ e.initCause(e1);
+ throw e;
}
}
if (!AndroidDigestFactoryInterface.class.isAssignableFrom(factoryImplementationClass)) {
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java
index f2c9967..15f3ebb 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/GeneralDigest.java
@@ -1,13 +1,14 @@
package org.bouncycastle.crypto.digests;
import org.bouncycastle.crypto.ExtendedDigest;
+import org.bouncycastle.util.Memoable;
/**
* base implementation of MD4 family style digest as outlined in
* "Handbook of Applied Cryptography", pages 344 - 347.
*/
public abstract class GeneralDigest
- implements ExtendedDigest
+ implements ExtendedDigest, Memoable
{
private static final int BYTE_LENGTH = 64;
private byte[] xBuf;
@@ -32,6 +33,12 @@ public abstract class GeneralDigest
protected GeneralDigest(GeneralDigest t)
{
xBuf = new byte[t.xBuf.length];
+
+ copyIn(t);
+ }
+
+ protected void copyIn(GeneralDigest t)
+ {
System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
xBufOff = t.xBufOff;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/LongDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/LongDigest.java
index 22d457b..5c79e4e 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/LongDigest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/LongDigest.java
@@ -2,12 +2,13 @@ package org.bouncycastle.crypto.digests;
import org.bouncycastle.crypto.ExtendedDigest;
import org.bouncycastle.crypto.util.Pack;
+import org.bouncycastle.util.Memoable;
/**
* Base class for SHA-384 and SHA-512.
*/
public abstract class LongDigest
- implements ExtendedDigest
+ implements ExtendedDigest, Memoable
{
private static final int BYTE_LENGTH = 128;
@@ -41,6 +42,12 @@ public abstract class LongDigest
protected LongDigest(LongDigest t)
{
xBuf = new byte[t.xBuf.length];
+
+ copyIn(t);
+ }
+
+ protected void copyIn(LongDigest t)
+ {
System.arraycopy(t.xBuf, 0, xBuf, 0, t.xBuf.length);
xBufOff = t.xBufOff;
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java
index 05ed27a..ff9cedf 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/MD5Digest.java
@@ -1,6 +1,8 @@
package org.bouncycastle.crypto.digests;
+import org.bouncycastle.util.Memoable;
+
/**
* implementation of MD5 as outlined in "Handbook of Applied Cryptography", pages 346 - 347.
*/
@@ -30,6 +32,13 @@ public class MD5Digest
{
super(t);
+ copyIn(t);
+ }
+
+ private void copyIn(MD5Digest t)
+ {
+ super.copyIn(t);
+
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
@@ -299,4 +308,16 @@ public class MD5Digest
X[i] = 0;
}
}
+
+ public Memoable copy()
+ {
+ return new MD5Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ MD5Digest d = (MD5Digest)other;
+
+ copyIn(d);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/OpenSSLDigest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/OpenSSLDigest.java
index 3e7c0e7..07b4e50 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/OpenSSLDigest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/OpenSSLDigest.java
@@ -16,7 +16,7 @@
package org.bouncycastle.crypto.digests;
-import org.apache.harmony.xnet.provider.jsse.NativeCrypto;
+import com.android.org.conscrypt.NativeCrypto;
import org.bouncycastle.crypto.ExtendedDigest;
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java
index 7f8d30a..21b1024 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA1Digest.java
@@ -1,12 +1,13 @@
package org.bouncycastle.crypto.digests;
import org.bouncycastle.crypto.util.Pack;
+import org.bouncycastle.util.Memoable;
/**
* implementation of SHA-1 as outlined in "Handbook of Applied Cryptography", pages 346 - 349.
*
* It is interesting to ponder why the, apart from the extra IV, the other difference here from MD5
- * is the "endienness" of the word processing!
+ * is the "endianness" of the word processing!
*/
public class SHA1Digest
extends GeneralDigest
@@ -34,6 +35,11 @@ public class SHA1Digest
{
super(t);
+ copyIn(t);
+ }
+
+ private void copyIn(SHA1Digest t)
+ {
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
@@ -283,6 +289,19 @@ public class SHA1Digest
X[i] = 0;
}
}
+
+ public Memoable copy()
+ {
+ return new SHA1Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ SHA1Digest d = (SHA1Digest)other;
+
+ super.copyIn(d);
+ copyIn(d);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
index abd9c1b..a2ceda3 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA256Digest.java
@@ -1,8 +1,8 @@
package org.bouncycastle.crypto.digests;
-import org.bouncycastle.crypto.digests.GeneralDigest;
import org.bouncycastle.crypto.util.Pack;
+import org.bouncycastle.util.Memoable;
/**
@@ -42,6 +42,13 @@ public class SHA256Digest
{
super(t);
+ copyIn(t);
+ }
+
+ private void copyIn(SHA256Digest t)
+ {
+ super.copyIn(t);
+
H1 = t.H1;
H2 = t.H2;
H3 = t.H3;
@@ -291,5 +298,17 @@ public class SHA256Digest
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
+
+ public Memoable copy()
+ {
+ return new SHA256Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ SHA256Digest d = (SHA256Digest)other;
+
+ copyIn(d);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java
index cdd979a..75d195d 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA384Digest.java
@@ -1,6 +1,7 @@
package org.bouncycastle.crypto.digests;
import org.bouncycastle.crypto.util.Pack;
+import org.bouncycastle.util.Memoable;
/**
@@ -17,7 +18,6 @@ import org.bouncycastle.crypto.util.Pack;
public class SHA384Digest
extends LongDigest
{
-
private static final int DIGEST_LENGTH = 48;
/**
@@ -84,4 +84,16 @@ public class SHA384Digest
H7 = 0xdb0c2e0d64f98fa7l;
H8 = 0x47b5481dbefa4fa4l;
}
+
+ public Memoable copy()
+ {
+ return new SHA384Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ SHA384Digest d = (SHA384Digest)other;
+
+ super.copyIn(d);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java
index 34a8e4e..7db63ad 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/digests/SHA512Digest.java
@@ -1,6 +1,7 @@
package org.bouncycastle.crypto.digests;
import org.bouncycastle.crypto.util.Pack;
+import org.bouncycastle.util.Memoable;
/**
@@ -85,5 +86,17 @@ public class SHA512Digest
H7 = 0x1f83d9abfb41bd6bL;
H8 = 0x5be0cd19137e2179L;
}
+
+ public Memoable copy()
+ {
+ return new SHA512Digest(this);
+ }
+
+ public void reset(Memoable other)
+ {
+ SHA512Digest d = (SHA512Digest)other;
+
+ copyIn(d);
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
index c4719cf..4dbfbff 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/encodings/OAEPEncoding.java
@@ -1,5 +1,7 @@
package org.bouncycastle.crypto.encodings;
+import java.security.SecureRandom;
+
import org.bouncycastle.crypto.AsymmetricBlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
@@ -9,8 +11,6 @@ import org.bouncycastle.crypto.digests.AndroidDigestFactory;
// END android-changed
import org.bouncycastle.crypto.params.ParametersWithRandom;
-import java.security.SecureRandom;
-
/**
* Optimal Asymmetric Encryption Padding (OAEP) - see PKCS 1 V 2.
*/
@@ -18,7 +18,6 @@ public class OAEPEncoding
implements AsymmetricBlockCipher
{
private byte[] defHash;
- private Digest hash;
private Digest mgf1Hash;
private AsymmetricBlockCipher engine;
@@ -55,10 +54,11 @@ public class OAEPEncoding
byte[] encodingParams)
{
this.engine = cipher;
- this.hash = hash;
this.mgf1Hash = mgf1Hash;
this.defHash = new byte[hash.getDigestSize()];
+ hash.reset();
+
if (encodingParams != null)
{
hash.update(encodingParams, 0, encodingParams.length);
@@ -256,15 +256,23 @@ public class OAEPEncoding
//
// check the hash of the encoding params.
+ // long check to try to avoid this been a source of a timing attack.
//
+ boolean defHashWrong = false;
+
for (int i = 0; i != defHash.length; i++)
{
if (defHash[i] != block[defHash.length + i])
{
- throw new InvalidCipherTextException("data hash wrong");
+ defHashWrong = true;
}
}
+ if (defHashWrong)
+ {
+ throw new InvalidCipherTextException("data hash wrong");
+ }
+
//
// find the data block
//
@@ -322,9 +330,9 @@ public class OAEPEncoding
byte[] C = new byte[4];
int counter = 0;
- hash.reset();
+ mgf1Hash.reset();
- do
+ while (counter < (length / hashBuf.length))
{
ItoOSP(counter, C);
@@ -333,8 +341,9 @@ public class OAEPEncoding
mgf1Hash.doFinal(hashBuf, 0);
System.arraycopy(hashBuf, 0, mask, counter * hashBuf.length, hashBuf.length);
+
+ counter++;
}
- while (++counter < (length / hashBuf.length));
if ((counter * hashBuf.length) < length)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java
index 1bc9aae..756197c 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESEngine.java
@@ -3,6 +3,7 @@ package org.bouncycastle.crypto.engines;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.params.KeyParameter;
/**
@@ -392,7 +393,7 @@ private static final int[] Tinv0 =
if ((outOff + (32 / 2)) > out.length)
{
- throw new DataLengthException("output buffer too short");
+ throw new OutputLengthException("output buffer too short");
}
if (forEncryption)
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
index 7e91973..ff4b2f8 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/AESFastEngine.java
@@ -3,9 +3,7 @@ package org.bouncycastle.crypto.engines;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
-// BEGIN android-added
import org.bouncycastle.crypto.OutputLengthException;
-// END android-added
import org.bouncycastle.crypto.params.KeyParameter;
/**
@@ -726,9 +724,7 @@ public class AESFastEngine
if ((outOff + (32 / 2)) > out.length)
{
- // BEGIN android-changed
throw new OutputLengthException("output buffer too short");
- // END android-changed
}
if (forEncryption)
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java
index 6ee1c49..cfe7f1f 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/BlowfishEngine.java
@@ -3,6 +3,7 @@ package org.bouncycastle.crypto.engines;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.params.KeyParameter;
/**
@@ -363,7 +364,7 @@ implements BlockCipher
if ((outOff + BLOCK_SIZE) > out.length)
{
- throw new DataLengthException("output buffer too short");
+ throw new OutputLengthException("output buffer too short");
}
if (encrypting)
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java
index b04911c..9b1e404 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESEngine.java
@@ -3,6 +3,7 @@ package org.bouncycastle.crypto.engines;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.params.KeyParameter;
/**
@@ -78,7 +79,7 @@ public class DESEngine
if ((outOff + BLOCK_SIZE) > out.length)
{
- throw new DataLengthException("output buffer too short");
+ throw new OutputLengthException("output buffer too short");
}
desFunc(workingKey, in, inOff, out, outOff);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeEngine.java
index c908218..513eccd 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/DESedeEngine.java
@@ -2,9 +2,7 @@ package org.bouncycastle.crypto.engines;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
-// BEGIN android-added
import org.bouncycastle.crypto.OutputLengthException;
-// END android-added
import org.bouncycastle.crypto.params.KeyParameter;
/**
@@ -102,9 +100,7 @@ public class DESedeEngine
if ((outOff + BLOCK_SIZE) > out.length)
{
- // BEGIN android-changed
throw new OutputLengthException("output buffer too short");
- // END android-changed
}
byte[] temp = new byte[BLOCK_SIZE];
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC2Engine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC2Engine.java
index 62240ea..02cb881 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC2Engine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC2Engine.java
@@ -3,6 +3,7 @@ package org.bouncycastle.crypto.engines;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.RC2Parameters;
@@ -174,7 +175,7 @@ public class RC2Engine
if ((outOff + BLOCK_SIZE) > out.length)
{
- throw new DataLengthException("output buffer too short");
+ throw new OutputLengthException("output buffer too short");
}
if (encrypting)
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC4Engine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC4Engine.java
index e7a9cdd..4de7ea6 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC4Engine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/RC4Engine.java
@@ -2,6 +2,7 @@ package org.bouncycastle.crypto.engines;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.StreamCipher;
import org.bouncycastle.crypto.params.KeyParameter;
@@ -81,7 +82,7 @@ public class RC4Engine implements StreamCipher
if ((outOff + len) > out.length)
{
- throw new DataLengthException("output buffer too short");
+ throw new OutputLengthException("output buffer too short");
}
for (int i = 0; i < len ; i++)
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/engines/TwofishEngine.java b/bcprov/src/main/java/org/bouncycastle/crypto/engines/TwofishEngine.java
index bf43ff2..31ac087 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/engines/TwofishEngine.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/engines/TwofishEngine.java
@@ -3,6 +3,7 @@ package org.bouncycastle.crypto.engines;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.params.KeyParameter;
/**
@@ -303,7 +304,7 @@ public final class TwofishEngine
if ((outOff + BLOCK_SIZE) > out.length)
{
- throw new DataLengthException("output buffer too short");
+ throw new OutputLengthException("output buffer too short");
}
if (encrypting)
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
index 98dd0f7..50baa4d 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/DSAParametersGenerator.java
@@ -1,23 +1,25 @@
package org.bouncycastle.crypto.generators;
+import java.math.BigInteger;
+import java.security.SecureRandom;
+
import org.bouncycastle.crypto.Digest;
// BEGIN android-changed
import org.bouncycastle.crypto.digests.AndroidDigestFactory;
// END android-changed
+import org.bouncycastle.crypto.params.DSAParameterGenerationParameters;
import org.bouncycastle.crypto.params.DSAParameters;
import org.bouncycastle.crypto.params.DSAValidationParameters;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.BigIntegers;
+import org.bouncycastle.util.encoders.Hex;
-import java.math.BigInteger;
-import java.security.SecureRandom;
-
-// TODO Update javadoc to mention FIPS 186-3 when done
/**
- * generate suitable parameters for DSA, in line with FIPS 186-2.
+ * Generate suitable parameters for DSA, in line with FIPS 186-2, or FIPS 186-3.
*/
public class DSAParametersGenerator
{
+ private Digest digest;
private int L, N;
private int certainty;
private SecureRandom random;
@@ -26,6 +28,21 @@ public class DSAParametersGenerator
private static final BigInteger ONE = BigInteger.valueOf(1);
private static final BigInteger TWO = BigInteger.valueOf(2);
+ private boolean use186_3;
+ private int usageIndex;
+
+ public DSAParametersGenerator()
+ {
+ // BEGIN android-changed
+ this(AndroidDigestFactory.getSHA1());
+ // END android-changed
+ }
+
+ public DSAParametersGenerator(Digest digest)
+ {
+ this.digest = digest;
+ }
+
/**
* initialise the key generator.
*
@@ -38,23 +55,53 @@ public class DSAParametersGenerator
int certainty,
SecureRandom random)
{
- init(size, getDefaultN(size), certainty, random);
+ this.use186_3 = false;
+ this.L = size;
+ this.N = getDefaultN(size);
+ this.certainty = certainty;
+ this.random = random;
}
- // TODO Make public to enable support for DSA keys > 1024 bits
- private void init(
- int L,
- int N,
- int certainty,
- SecureRandom random)
+ /**
+ * Initialise the key generator for DSA 2.
+ * <p>
+ * Use this init method if you need to generate parameters for DSA 2 keys.
+ * </p>
+ *
+ * @param params DSA 2 key generation parameters.
+ */
+ public void init(
+ DSAParameterGenerationParameters params)
{
- // TODO Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2)
// TODO Should we enforce the minimum 'certainty' values as per C.3 Table C.1?
+ this.use186_3 = true;
+ this.L = params.getL();
+ this.N = params.getN();
+ this.certainty = params.getCertainty();
+ this.random = params.getRandom();
+ this.usageIndex = params.getUsageIndex();
+
+ if ((L < 1024 || L > 3072) || L % 1024 != 0)
+ {
+ throw new IllegalArgumentException("L values must be between 1024 and 3072 and a multiple of 1024");
+ }
+ else if (L == 1024 && N != 160)
+ {
+ throw new IllegalArgumentException("N must be 160 for L = 1024");
+ }
+ else if (L == 2048 && (N != 224 && N != 256))
+ {
+ throw new IllegalArgumentException("N must be 224 or 256 for L = 2048");
+ }
+ else if (L == 3072 && N != 256)
+ {
+ throw new IllegalArgumentException("N must be 256 for L = 3072");
+ }
- this.L = L;
- this.N = N;
- this.certainty = certainty;
- this.random = random;
+ if (digest.getDigestSize() * 8 < N)
+ {
+ throw new IllegalStateException("Digest output size too small for value of N");
+ }
}
/**
@@ -65,7 +112,7 @@ public class DSAParametersGenerator
*/
public DSAParameters generateParameters()
{
- return L > 1024
+ return (use186_3)
? generateParameters_FIPS186_3()
: generateParameters_FIPS186_2();
}
@@ -76,20 +123,24 @@ public class DSAParametersGenerator
byte[] part1 = new byte[20];
byte[] part2 = new byte[20];
byte[] u = new byte[20];
- // BEGIN android-changed
- Digest sha1 = AndroidDigestFactory.getSHA1();
- // END android-changed
int n = (L - 1) / 160;
byte[] w = new byte[L / 8];
+ // BEGIN android-changed
+ if (!(digest.getAlgorithmName().equals("SHA-1")))
+ // END android-changed
+ {
+ throw new IllegalStateException("can only use SHA-1 for generating FIPS 186-2 parameters");
+ }
+
for (;;)
{
random.nextBytes(seed);
- hash(sha1, seed, part1);
+ hash(digest, seed, part1);
System.arraycopy(seed, 0, part2, 0, seed.length);
inc(part2);
- hash(sha1, part2, part2);
+ hash(digest, part2, part2);
for (int i = 0; i != u.length; i++)
{
@@ -114,12 +165,12 @@ public class DSAParametersGenerator
for (int k = 0; k < n; k++)
{
inc(offset);
- hash(sha1, offset, part1);
+ hash(digest, offset, part1);
System.arraycopy(part1, 0, w, w.length - (k + 1) * part1.length, part1.length);
}
inc(offset);
- hash(sha1, offset, part1);
+ hash(digest, offset, part1);
System.arraycopy(part1, part1.length - ((w.length - (n) * part1.length)), w, 0, w.length - n * part1.length);
w[0] |= (byte)0x80;
@@ -169,9 +220,7 @@ public class DSAParametersGenerator
{
// A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
// FIXME This should be configurable (digest size in bits must be >= N)
- // BEGIN android-changed
- Digest d = AndroidDigestFactory.getSHA256();
- // END android-changed
+ Digest d = digest;
int outlen = d.getDigestSize() * 8;
// 1. Check that the (L, N) pair is in the list of acceptable (L, N pairs) (see Section 4.2). If
@@ -197,6 +246,7 @@ public class DSAParametersGenerator
// 6. U = Hash (domain_parameter_seed) mod 2^(Nā€“1).
hash(d, seed, output);
+
BigInteger U = new BigInteger(1, output).mod(ONE.shiftLeft(N - 1));
// 7. q = 2^(Nā€“1) + U + 1 ā€“ ( U mod 2).
@@ -258,16 +308,17 @@ public class DSAParametersGenerator
{
// 11.8 If p is determined to be prime, then return VALID and the values of p, q and
// (optionally) the values of domain_parameter_seed and counter.
- // TODO Make configurable (8-bit unsigned)?
-// int index = 1;
-// BigInteger g = calculateGenerator_FIPS186_3_Verifiable(d, p, q, seed, index);
-// if (g != null)
-// {
-// // TODO Should 'index' be a part of the validation parameters?
-// return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter));
-// }
+ if (usageIndex >= 0)
+ {
+ BigInteger g = calculateGenerator_FIPS186_3_Verifiable(d, p, q, seed, usageIndex);
+ if (g != null)
+ {
+ return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter, usageIndex));
+ }
+ }
BigInteger g = calculateGenerator_FIPS186_3_Unverifiable(p, q, random);
+
return new DSAParameters(p, q, g, new DSAValidationParameters(seed, counter));
}
@@ -286,34 +337,34 @@ public class DSAParametersGenerator
return calculateGenerator_FIPS186_2(p, q, r);
}
-// private static BigInteger calculateGenerator_FIPS186_3_Verifiable(Digest d, BigInteger p, BigInteger q,
-// byte[] seed, int index)
-// {
-//// A.2.3 Verifiable Canonical Generation of the Generator g
-// BigInteger e = p.subtract(ONE).divide(q);
-// byte[] ggen = Hex.decode("6767656E");
-//
-// // 7. U = domain_parameter_seed || "ggen" || index || count.
-// byte[] U = new byte[seed.length + ggen.length + 1 + 2];
-// System.arraycopy(seed, 0, U, 0, seed.length);
-// System.arraycopy(ggen, 0, U, seed.length, ggen.length);
-// U[U.length - 3] = (byte)index;
-//
-// byte[] w = new byte[d.getDigestSize()];
-// for (int count = 1; count < (1 << 16); ++count)
-// {
-// inc(U);
-// hash(d, U, w);
-// BigInteger W = new BigInteger(1, w);
-// BigInteger g = W.modPow(e, p);
-// if (g.compareTo(TWO) >= 0)
-// {
-// return g;
-// }
-// }
-//
-// return null;
-// }
+ private static BigInteger calculateGenerator_FIPS186_3_Verifiable(Digest d, BigInteger p, BigInteger q,
+ byte[] seed, int index)
+ {
+// A.2.3 Verifiable Canonical Generation of the Generator g
+ BigInteger e = p.subtract(ONE).divide(q);
+ byte[] ggen = Hex.decode("6767656E");
+
+ // 7. U = domain_parameter_seed || "ggen" || index || count.
+ byte[] U = new byte[seed.length + ggen.length + 1 + 2];
+ System.arraycopy(seed, 0, U, 0, seed.length);
+ System.arraycopy(ggen, 0, U, seed.length, ggen.length);
+ U[U.length - 3] = (byte)index;
+
+ byte[] w = new byte[d.getDigestSize()];
+ for (int count = 1; count < (1 << 16); ++count)
+ {
+ inc(U);
+ hash(d, U, w);
+ BigInteger W = new BigInteger(1, w);
+ BigInteger g = W.modPow(e, p);
+ if (g.compareTo(TWO) >= 0)
+ {
+ return g;
+ }
+ }
+
+ return null;
+ }
private static void hash(Digest d, byte[] input, byte[] output)
{
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java
index 8fb1cc8..d9b82c3 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS12ParametersGenerator.java
@@ -125,11 +125,10 @@ public class PKCS12ParametersGenerator
byte[] B = new byte[v];
int c = (n + u - 1) / u;
+ byte[] A = new byte[u];
for (int i = 1; i <= c; i++)
{
- byte[] A = new byte[u];
-
digest.update(D, 0, D.length);
digest.update(I, 0, I.length);
digest.doFinal(A, 0);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java b/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
index a6d87b9..316de64 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
@@ -23,6 +23,7 @@ public class PKCS5S2ParametersGenerator
extends PBEParametersGenerator
{
private Mac hMac;
+ private byte[] state;
/**
* construct a PKCS5 Scheme 2 Parameters generator.
@@ -30,27 +31,27 @@ public class PKCS5S2ParametersGenerator
public PKCS5S2ParametersGenerator()
{
// BEGIN android-changed
- this(AndroidDigestFactory.getSHA1());
+ this(AndroidDigestFactory.getSHA1());
// END android-changed
}
public PKCS5S2ParametersGenerator(Digest digest)
{
hMac = new HMac(digest);
+ state = new byte[hMac.getMacSize()];
}
private void F(
- byte[] P,
byte[] S,
int c,
byte[] iBuf,
byte[] out,
int outOff)
{
- byte[] state = new byte[hMac.getMacSize()];
- CipherParameters param = new KeyParameter(P);
-
- hMac.init(param);
+ if (c == 0)
+ {
+ throw new IllegalArgumentException("iteration count must be at least 1.");
+ }
if (S != null)
{
@@ -58,19 +59,12 @@ public class PKCS5S2ParametersGenerator
}
hMac.update(iBuf, 0, iBuf.length);
-
hMac.doFinal(state, 0);
System.arraycopy(state, 0, out, outOff, state.length);
-
- if (c == 0)
- {
- throw new IllegalArgumentException("iteration count must be at least 1.");
- }
for (int count = 1; count < c; count++)
{
- hMac.init(param);
hMac.update(state, 0, state.length);
hMac.doFinal(state, 0);
@@ -81,32 +75,33 @@ public class PKCS5S2ParametersGenerator
}
}
- private void intToOctet(
- byte[] buf,
- int i)
- {
- buf[0] = (byte)(i >>> 24);
- buf[1] = (byte)(i >>> 16);
- buf[2] = (byte)(i >>> 8);
- buf[3] = (byte)i;
- }
-
private byte[] generateDerivedKey(
int dkLen)
{
int hLen = hMac.getMacSize();
int l = (dkLen + hLen - 1) / hLen;
byte[] iBuf = new byte[4];
- byte[] out = new byte[l * hLen];
+ byte[] outBytes = new byte[l * hLen];
+ int outPos = 0;
+
+ CipherParameters param = new KeyParameter(password);
+
+ hMac.init(param);
for (int i = 1; i <= l; i++)
{
- intToOctet(iBuf, i);
+ // Increment the value in 'iBuf'
+ int pos = 3;
+ while (++iBuf[pos] == 0)
+ {
+ --pos;
+ }
- F(password, salt, iterationCount, iBuf, out, (i - 1) * hLen);
+ F(salt, iterationCount, iBuf, outBytes, outPos);
+ outPos += hLen;
}
- return out;
+ return outBytes;
}
/**
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/macs/HMac.java b/bcprov/src/main/java/org/bouncycastle/crypto/macs/HMac.java
index f5b931d..c70a981 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/macs/HMac.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/macs/HMac.java
@@ -8,6 +8,7 @@ import org.bouncycastle.crypto.ExtendedDigest;
import org.bouncycastle.crypto.Mac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.Integers;
+import org.bouncycastle.util.Memoable;
/**
* HMAC implementation based on RFC2104
@@ -23,9 +24,11 @@ public class HMac
private Digest digest;
private int digestSize;
private int blockLength;
-
+ private Memoable ipadState;
+ private Memoable opadState;
+
private byte[] inputPad;
- private byte[] outputPad;
+ private byte[] outputBuf;
private static Hashtable blockLengths;
@@ -95,14 +98,12 @@ public class HMac
int byteLength)
{
this.digest = digest;
- digestSize = digest.getDigestSize();
-
+ this.digestSize = digest.getDigestSize();
this.blockLength = byteLength;
-
- inputPad = new byte[blockLength];
- outputPad = new byte[blockLength];
+ this.inputPad = new byte[blockLength];
+ this.outputBuf = new byte[blockLength + digestSize];
}
-
+
public String getAlgorithmName()
{
return digest.getAlgorithmName() + "/HMAC";
@@ -119,39 +120,43 @@ public class HMac
digest.reset();
byte[] key = ((KeyParameter)params).getKey();
+ int keyLength = key.length;
- if (key.length > blockLength)
+ if (keyLength > blockLength)
{
- digest.update(key, 0, key.length);
+ digest.update(key, 0, keyLength);
digest.doFinal(inputPad, 0);
- for (int i = digestSize; i < inputPad.length; i++)
- {
- inputPad[i] = 0;
- }
+
+ keyLength = digestSize;
}
else
{
- System.arraycopy(key, 0, inputPad, 0, key.length);
- for (int i = key.length; i < inputPad.length; i++)
- {
- inputPad[i] = 0;
- }
+ System.arraycopy(key, 0, inputPad, 0, keyLength);
}
- outputPad = new byte[inputPad.length];
- System.arraycopy(inputPad, 0, outputPad, 0, inputPad.length);
-
- for (int i = 0; i < inputPad.length; i++)
+ for (int i = keyLength; i < inputPad.length; i++)
{
- inputPad[i] ^= IPAD;
+ inputPad[i] = 0;
}
- for (int i = 0; i < outputPad.length; i++)
+ System.arraycopy(inputPad, 0, outputBuf, 0, blockLength);
+
+ xorPad(inputPad, blockLength, IPAD);
+ xorPad(outputBuf, blockLength, OPAD);
+
+ if (digest instanceof Memoable)
{
- outputPad[i] ^= OPAD;
+ opadState = ((Memoable)digest).copy();
+
+ ((Digest)opadState).update(outputBuf, 0, blockLength);
}
digest.update(inputPad, 0, inputPad.length);
+
+ if (digest instanceof Memoable)
+ {
+ ipadState = ((Memoable)digest).copy();
+ }
}
public int getMacSize()
@@ -177,15 +182,33 @@ public class HMac
byte[] out,
int outOff)
{
- byte[] tmp = new byte[digestSize];
- digest.doFinal(tmp, 0);
+ digest.doFinal(outputBuf, blockLength);
- digest.update(outputPad, 0, outputPad.length);
- digest.update(tmp, 0, tmp.length);
+ if (opadState != null)
+ {
+ ((Memoable)digest).reset(opadState);
+ digest.update(outputBuf, blockLength, digest.getDigestSize());
+ }
+ else
+ {
+ digest.update(outputBuf, 0, outputBuf.length);
+ }
- int len = digest.doFinal(out, outOff);
+ int len = digest.doFinal(out, outOff);
- reset();
+ for (int i = blockLength; i < outputBuf.length; i++)
+ {
+ outputBuf[i] = 0;
+ }
+
+ if (ipadState != null)
+ {
+ ((Memoable)digest).reset(ipadState);
+ }
+ else
+ {
+ digest.update(inputPad, 0, inputPad.length);
+ }
return len;
}
@@ -205,4 +228,12 @@ public class HMac
*/
digest.update(inputPad, 0, inputPad.length);
}
+
+ private static void xorPad(byte[] pad, int len, byte n)
+ {
+ for (int i = 0; i < len; ++i)
+ {
+ pad[i] ^= n;
+ }
+ }
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
index 18a3425..9a6e2e0 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/modes/CCMBlockCipher.java
@@ -87,6 +87,11 @@ public class CCMBlockCipher
{
throw new IllegalArgumentException("invalid parameters passed to CCM");
}
+
+ if (nonce == null || nonce.length < 7 || nonce.length > 13)
+ {
+ throw new IllegalArgumentException("nonce must have length from 7 to 13 octets");
+ }
}
public String getAlgorithmName()
@@ -183,22 +188,31 @@ public class CCMBlockCipher
throw new IllegalStateException("CCM cipher unitialized.");
}
- BlockCipher ctrCipher = new SICBlockCipher(cipher);
- byte[] iv = new byte[blockSize];
- byte[] out;
-
- iv[0] = (byte)(((15 - nonce.length) - 1) & 0x7);
+ int n = nonce.length;
+ int q = 15 - n;
+ if (q < 4)
+ {
+ int limitLen = 1 << (8 * q);
+ if (inLen >= limitLen)
+ {
+ throw new IllegalStateException("CCM packet too large for choice of q.");
+ }
+ }
+ byte[] iv = new byte[blockSize];
+ iv[0] = (byte)((q - 1) & 0x7);
System.arraycopy(nonce, 0, iv, 1, nonce.length);
+ BlockCipher ctrCipher = new SICBlockCipher(cipher);
ctrCipher.init(forEncryption, new ParametersWithIV(keyParam, iv));
+ int index = inOff;
+ int outOff = 0;
+ byte[] output;
+
if (forEncryption)
{
- int index = inOff;
- int outOff = 0;
-
- out = new byte[inLen + macSize];
+ output = new byte[inLen + macSize];
calculateMac(in, inOff, inLen, macBlock);
@@ -206,7 +220,7 @@ public class CCMBlockCipher
while (index < inLen - blockSize) // S1...
{
- ctrCipher.processBlock(in, index, out, outOff);
+ ctrCipher.processBlock(in, index, output, outOff);
outOff += blockSize;
index += blockSize;
}
@@ -217,18 +231,15 @@ public class CCMBlockCipher
ctrCipher.processBlock(block, 0, block, 0);
- System.arraycopy(block, 0, out, outOff, inLen - index);
+ System.arraycopy(block, 0, output, outOff, inLen - index);
outOff += inLen - index;
- System.arraycopy(macBlock, 0, out, outOff, out.length - outOff);
+ System.arraycopy(macBlock, 0, output, outOff, output.length - outOff);
}
else
{
- int index = inOff;
- int outOff = 0;
-
- out = new byte[inLen - macSize];
+ output = new byte[inLen - macSize];
System.arraycopy(in, inOff + inLen - macSize, macBlock, 0, macSize);
@@ -239,24 +250,24 @@ public class CCMBlockCipher
macBlock[i] = 0;
}
- while (outOff < out.length - blockSize)
+ while (outOff < output.length - blockSize)
{
- ctrCipher.processBlock(in, index, out, outOff);
+ ctrCipher.processBlock(in, index, output, outOff);
outOff += blockSize;
index += blockSize;
}
byte[] block = new byte[blockSize];
- System.arraycopy(in, index, block, 0, out.length - outOff);
+ System.arraycopy(in, index, block, 0, output.length - outOff);
ctrCipher.processBlock(block, 0, block, 0);
- System.arraycopy(block, 0, out, outOff, out.length - outOff);
+ System.arraycopy(block, 0, output, outOff, output.length - outOff);
byte[] calculatedMacBlock = new byte[blockSize];
- calculateMac(out, 0, out.length, calculatedMacBlock);
+ calculateMac(output, 0, output.length, calculatedMacBlock);
if (!Arrays.constantTimeAreEqual(macBlock, calculatedMacBlock))
{
@@ -264,7 +275,7 @@ public class CCMBlockCipher
}
}
- return out;
+ return output;
}
private int calculateMac(byte[] data, int dataOff, int dataLen, byte[] macBlock)
@@ -340,13 +351,13 @@ public class CCMBlockCipher
extra = (extra + textLength) % 16;
if (extra != 0)
{
- for (int i = 0; i != 16 - extra; i++)
+ for (int i = extra; i != 16; i++)
{
cMac.update((byte)0x00);
}
}
}
-
+
//
// add the text
//
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java
new file mode 100644
index 0000000..ba841b8
--- /dev/null
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/DSAParameterGenerationParameters.java
@@ -0,0 +1,80 @@
+package org.bouncycastle.crypto.params;
+
+import java.security.SecureRandom;
+
+public class DSAParameterGenerationParameters
+{
+ public static final int DIGITAL_SIGNATURE_USAGE = 1;
+ public static final int KEY_ESTABLISHMENT_USAGE = 2;
+
+ private final int l;
+ private final int n;
+ private final int usageIndex;
+ private final int certainty;
+ private final SecureRandom random;
+
+ /**
+ * Construct without a usage index, this will do a random construction of G.
+ *
+ * @param L desired length of prime P in bits (the effective key size).
+ * @param N desired length of prime Q in bits.
+ * @param certainty certainty level for prime number generation.
+ * @param random the source of randomness to use.
+ */
+ public DSAParameterGenerationParameters(
+ int L,
+ int N,
+ int certainty,
+ SecureRandom random)
+ {
+ this(L, N, certainty, random, -1);
+ }
+
+ /**
+ * Construct for a specific usage index - this has the effect of using verifiable canonical generation of G.
+ *
+ * @param L desired length of prime P in bits (the effective key size).
+ * @param N desired length of prime Q in bits.
+ * @param certainty certainty level for prime number generation.
+ * @param random the source of randomness to use.
+ * @param usageIndex a valid usage index.
+ */
+ public DSAParameterGenerationParameters(
+ int L,
+ int N,
+ int certainty,
+ SecureRandom random,
+ int usageIndex)
+ {
+ this.l = L;
+ this.n = N;
+ this.certainty = certainty;
+ this.usageIndex = usageIndex;
+ this.random = random;
+ }
+
+ public int getL()
+ {
+ return l;
+ }
+
+ public int getN()
+ {
+ return n;
+ }
+
+ public int getCertainty()
+ {
+ return certainty;
+ }
+
+ public SecureRandom getRandom()
+ {
+ return random;
+ }
+
+ public int getUsageIndex()
+ {
+ return usageIndex;
+ }
+}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/DSAValidationParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/DSAValidationParameters.java
index 1cc4b93..07d93d0 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/DSAValidationParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/DSAValidationParameters.java
@@ -4,6 +4,7 @@ import org.bouncycastle.util.Arrays;
public class DSAValidationParameters
{
+ private int usageIndex;
private byte[] seed;
private int counter;
@@ -11,8 +12,17 @@ public class DSAValidationParameters
byte[] seed,
int counter)
{
+ this(seed, counter, -1);
+ }
+
+ public DSAValidationParameters(
+ byte[] seed,
+ int counter,
+ int usageIndex)
+ {
this.seed = seed;
this.counter = counter;
+ this.usageIndex = usageIndex;
}
public int getCounter()
@@ -25,6 +35,11 @@ public class DSAValidationParameters
return seed;
}
+ public int getUsageIndex()
+ {
+ return usageIndex;
+ }
+
public int hashCode()
{
return counter ^ Arrays.hashCode(seed);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java
index 95a3ec9..05a1327 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/params/ECDomainParameters.java
@@ -5,26 +5,23 @@ import java.math.BigInteger;
import org.bouncycastle.math.ec.ECConstants;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
+import org.bouncycastle.util.Arrays;
public class ECDomainParameters
implements ECConstants
{
- ECCurve curve;
- byte[] seed;
- ECPoint G;
- BigInteger n;
- BigInteger h;
+ private ECCurve curve;
+ private byte[] seed;
+ private ECPoint G;
+ private BigInteger n;
+ private BigInteger h;
public ECDomainParameters(
ECCurve curve,
ECPoint G,
BigInteger n)
{
- this.curve = curve;
- this.G = G;
- this.n = n;
- this.h = ONE;
- this.seed = null;
+ this(curve, G, n, ONE, null);
}
public ECDomainParameters(
@@ -33,11 +30,7 @@ public class ECDomainParameters
BigInteger n,
BigInteger h)
{
- this.curve = curve;
- this.G = G;
- this.n = n;
- this.h = h;
- this.seed = null;
+ this(curve, G, n, h, null);
}
public ECDomainParameters(
@@ -76,6 +69,6 @@ public class ECDomainParameters
public byte[] getSeed()
{
- return seed;
+ return Arrays.clone(seed);
}
}
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java b/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
index dac6efe..a80c574 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/signers/ECDSASigner.java
@@ -137,6 +137,12 @@ public class ECDSASigner
ECPoint point = ECAlgorithms.sumOfTwoMultiplies(G, u1, Q, u2);
+ // components must be bogus.
+ if (point.isInfinity())
+ {
+ return false;
+ }
+
BigInteger v = point.getX().toBigInteger().mod(n);
return v.equals(r);
diff --git a/bcprov/src/main/java/org/bouncycastle/crypto/util/Pack.java b/bcprov/src/main/java/org/bouncycastle/crypto/util/Pack.java
index 857b765..f0da0bf 100644
--- a/bcprov/src/main/java/org/bouncycastle/crypto/util/Pack.java
+++ b/bcprov/src/main/java/org/bouncycastle/crypto/util/Pack.java
@@ -20,6 +20,13 @@ public abstract class Pack
}
}
+ public static byte[] intToBigEndian(int n)
+ {
+ byte[] bs = new byte[4];
+ intToBigEndian(n, bs, 0);
+ return bs;
+ }
+
public static void intToBigEndian(int n, byte[] bs, int off)
{
bs[ off] = (byte)(n >>> 24);
@@ -28,6 +35,13 @@ public abstract class Pack
bs[++off] = (byte)(n );
}
+ public static byte[] intToBigEndian(int[] ns)
+ {
+ byte[] bs = new byte[4 * ns.length];
+ intToBigEndian(ns, bs, 0);
+ return bs;
+ }
+
public static void intToBigEndian(int[] ns, byte[] bs, int off)
{
for (int i = 0; i < ns.length; ++i)
@@ -44,12 +58,44 @@ public abstract class Pack
return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL);
}
+ public static void bigEndianToLong(byte[] bs, int off, long[] ns)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = bigEndianToLong(bs, off);
+ off += 8;
+ }
+ }
+
+ public static byte[] longToBigEndian(long n)
+ {
+ byte[] bs = new byte[8];
+ longToBigEndian(n, bs, 0);
+ return bs;
+ }
+
public static void longToBigEndian(long n, byte[] bs, int off)
{
intToBigEndian((int)(n >>> 32), bs, off);
intToBigEndian((int)(n & 0xffffffffL), bs, off + 4);
}
+ public static byte[] longToBigEndian(long[] ns)
+ {
+ byte[] bs = new byte[8 * ns.length];
+ longToBigEndian(ns, bs, 0);
+ return bs;
+ }
+
+ public static void longToBigEndian(long[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ longToBigEndian(ns[i], bs, off);
+ off += 8;
+ }
+ }
+
public static int littleEndianToInt(byte[] bs, int off)
{
int n = bs[ off] & 0xff;
@@ -60,13 +106,20 @@ public abstract class Pack
}
public static void littleEndianToInt(byte[] bs, int off, int[] ns)
- {
- for (int i = 0; i < ns.length; ++i)
- {
- ns[i] = littleEndianToInt(bs, off);
- off += 4;
- }
- }
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = littleEndianToInt(bs, off);
+ off += 4;
+ }
+ }
+
+ public static byte[] intToLittleEndian(int n)
+ {
+ byte[] bs = new byte[4];
+ intToLittleEndian(n, bs, 0);
+ return bs;
+ }
public static void intToLittleEndian(int n, byte[] bs, int off)
{
@@ -76,14 +129,21 @@ public abstract class Pack
bs[++off] = (byte)(n >>> 24);
}
- public static void intToLittleEndian(int[] ns, byte[] bs, int off)
- {
- for (int i = 0; i < ns.length; ++i)
- {
- intToLittleEndian(ns[i], bs, off);
- off += 4;
- }
- }
+ public static byte[] intToLittleEndian(int[] ns)
+ {
+ byte[] bs = new byte[4 * ns.length];
+ intToLittleEndian(ns, bs, 0);
+ return bs;
+ }
+
+ public static void intToLittleEndian(int[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ intToLittleEndian(ns[i], bs, off);
+ off += 4;
+ }
+ }
public static long littleEndianToLong(byte[] bs, int off)
{
@@ -92,9 +152,41 @@ public abstract class Pack
return ((long)(hi & 0xffffffffL) << 32) | (long)(lo & 0xffffffffL);
}
+ public static void littleEndianToLong(byte[] bs, int off, long[] ns)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ ns[i] = littleEndianToLong(bs, off);
+ off += 8;
+ }
+ }
+
+ public static byte[] longToLittleEndian(long n)
+ {
+ byte[] bs = new byte[8];
+ longToLittleEndian(n, bs, 0);
+ return bs;
+ }
+
public static void longToLittleEndian(long n, byte[] bs, int off)
{
intToLittleEndian((int)(n & 0xffffffffL), bs, off);
intToLittleEndian((int)(n >>> 32), bs, off + 4);
}
+
+ public static byte[] longToLittleEndian(long[] ns)
+ {
+ byte[] bs = new byte[8 * ns.length];
+ longToLittleEndian(ns, bs, 0);
+ return bs;
+ }
+
+ public static void longToLittleEndian(long[] ns, byte[] bs, int off)
+ {
+ for (int i = 0; i < ns.length; ++i)
+ {
+ longToLittleEndian(ns[i], bs, off);
+ off += 8;
+ }
+ }
}