Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/quite/humla-spongycastle.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Hook <dgh@cryptoworkshop.com>2013-09-13 10:27:50 +0400
committerDavid Hook <dgh@cryptoworkshop.com>2013-09-13 10:27:50 +0400
commit1c67cdcb2d9d30487efee98979ee1646a89553de (patch)
tree6b2630bc78c2cf73ae9b8c857988330fba9e5d45 /core/src/main/java
parent972c20edfaa73bf197b1665eb3c4818c01ac3934 (diff)
added support for GOST in conjunction with PBKDF2.
added support for keyMeshing with GOST block cipher (see GCFBBlockCipher). added correct encoding/decoding for GOST private keys.
Diffstat (limited to 'core/src/main/java')
-rw-r--r--core/src/main/java/org/bouncycastle/asn1/cryptopro/CryptoProObjectIdentifiers.java2
-rw-r--r--core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410PublicKeyAlgParameters.java3
-rw-r--r--core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java36
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java2
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java2
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java11
-rw-r--r--core/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java81
7 files changed, 128 insertions, 9 deletions
diff --git a/core/src/main/java/org/bouncycastle/asn1/cryptopro/CryptoProObjectIdentifiers.java b/core/src/main/java/org/bouncycastle/asn1/cryptopro/CryptoProObjectIdentifiers.java
index 108270e5..c6e8e0d1 100644
--- a/core/src/main/java/org/bouncycastle/asn1/cryptopro/CryptoProObjectIdentifiers.java
+++ b/core/src/main/java/org/bouncycastle/asn1/cryptopro/CryptoProObjectIdentifiers.java
@@ -19,7 +19,7 @@ public interface CryptoProObjectIdentifiers
static final ASN1ObjectIdentifier gostR3411Hmac = GOST_id.branch("10");
/** Gost R28147 OID: 1.2.643.2.2.21 */
- static final ASN1ObjectIdentifier gostR28147_cbc = GOST_id.branch("21");
+ static final ASN1ObjectIdentifier gostR28147_gcfb = GOST_id.branch("21");
/** Gost R28147-89-CryotoPro-A-ParamSet OID: 1.2.643.2.2.31.1 */
static final ASN1ObjectIdentifier id_Gost28147_89_CryptoPro_A_ParamSet = GOST_id.branch("31.1");
diff --git a/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410PublicKeyAlgParameters.java b/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410PublicKeyAlgParameters.java
index 0307f50f..45d78147 100644
--- a/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410PublicKeyAlgParameters.java
+++ b/core/src/main/java/org/bouncycastle/asn1/cryptopro/GOST3410PublicKeyAlgParameters.java
@@ -57,6 +57,9 @@ public class GOST3410PublicKeyAlgParameters
this.encryptionParamSet = encryptionParamSet;
}
+ /**
+ * @deprecated use getInstance()
+ */
public GOST3410PublicKeyAlgParameters(
ASN1Sequence seq)
{
diff --git a/core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
index c8e92dc9..92c4e8f1 100644
--- a/core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
+++ b/core/src/main/java/org/bouncycastle/asn1/pkcs/PBKDF2Params.java
@@ -89,6 +89,42 @@ public class PBKDF2Params
this.keyLength = new ASN1Integer(keyLength);
}
+ /**
+ * Create a PBKDF2Params with the specified salt, iteration count, keyLength, and a defined prf.
+ *
+ * @param salt input salt.
+ * @param iterationCount input iteration count.
+ * @param keyLength intended key length to be produced.
+ * @param prf the pseudo-random function to use.
+ */
+ public PBKDF2Params(
+ byte[] salt,
+ int iterationCount,
+ int keyLength,
+ AlgorithmIdentifier prf)
+ {
+ this(salt, iterationCount);
+
+ this.keyLength = new ASN1Integer(keyLength);
+ this.prf = prf;
+ }
+
+ /**
+ * Create a PBKDF2Params with the specified salt, iteration count, and a defined prf.
+ *
+ * @param salt input salt.
+ * @param iterationCount input iteration count.
+ * @param prf the pseudo-random function to use.
+ */
+ public PBKDF2Params(
+ byte[] salt,
+ int iterationCount,
+ AlgorithmIdentifier prf)
+ {
+ this(salt, iterationCount);
+ this.prf = prf;
+ }
+
private PBKDF2Params(
ASN1Sequence seq)
{
diff --git a/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
index bdb694d4..dd056aca 100644
--- a/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
+++ b/core/src/main/java/org/bouncycastle/crypto/BufferedBlockCipher.java
@@ -54,7 +54,7 @@ public class BufferedBlockCipher
}
else
{
- partialBlockOkay = (idx > 0 && (name.startsWith("CFB", idx) || name.startsWith("OFB", idx) || name.startsWith("OpenPGP", idx) || name.startsWith("SIC", idx) || name.startsWith("GCTR", idx)));
+ partialBlockOkay = (idx > 0 && (name.startsWith("CFB", idx) || name.startsWith("GCFB", idx) ||name.startsWith("OFB", idx) || name.startsWith("OpenPGP", idx) || name.startsWith("SIC", idx) || name.startsWith("GCTR", idx)));
}
}
diff --git a/core/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java b/core/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
index 640ead46..0954d481 100644
--- a/core/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
+++ b/core/src/main/java/org/bouncycastle/crypto/generators/PKCS5S2ParametersGenerator.java
@@ -58,7 +58,7 @@ public class PKCS5S2ParametersGenerator
hMac.doFinal(state, 0);
System.arraycopy(state, 0, out, outOff, state.length);
-
+
for (int count = 1; count < c; count++)
{
hMac.update(state, 0, state.length);
diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java
index d0fb9bb6..a8851690 100644
--- a/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java
+++ b/core/src/main/java/org/bouncycastle/crypto/modes/CFBBlockCipher.java
@@ -4,6 +4,7 @@ import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.params.ParametersWithIV;
+import org.bouncycastle.util.Arrays;
/**
* implements a Cipher-FeedBack (CFB) mode on top of a simple cipher.
@@ -246,6 +247,16 @@ public class CFBBlockCipher
}
/**
+ * Return the current state of the initialisation vector.
+ *
+ * @return current IV
+ */
+ public byte[] getCurrentIV()
+ {
+ return Arrays.clone(cfbV);
+ }
+
+ /**
* reset the chaining vector back to the IV and reset the underlying
* cipher.
*/
diff --git a/core/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java b/core/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java
index f441b89f..887c1697 100644
--- a/core/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java
+++ b/core/src/main/java/org/bouncycastle/crypto/modes/GCFBBlockCipher.java
@@ -3,38 +3,107 @@ package org.bouncycastle.crypto.modes;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.params.ParametersWithIV;
+import org.bouncycastle.crypto.params.ParametersWithRandom;
+import org.bouncycastle.crypto.params.ParametersWithSBox;
+/**
+ * An implementation of the GOST CFB mode with CryptoPro key meshing as described in RFC 4357.
+ */
public class GCFBBlockCipher
implements BlockCipher
{
+ private static final byte[] C =
+ {
+ 0x69, 0x00, 0x72, 0x22, 0x64, (byte)0xC9, 0x04, 0x23,
+ (byte)0x8D, 0x3A, (byte)0xDB, (byte)0x96, 0x46, (byte)0xE9, 0x2A, (byte)0xC4,
+ 0x18, (byte)0xFE, (byte)0xAC, (byte)0x94, 0x00, (byte)0xED, 0x07, 0x12,
+ (byte)0xC0, (byte)0x86, (byte)0xDC, (byte)0xC2, (byte)0xEF, 0x4C, (byte)0xA9, 0x2B
+ };
+
+ private final CFBBlockCipher cfbEngine;
+
+ private KeyParameter key;
+ private long counter = 0;
+ private boolean forEncryption;
+
public GCFBBlockCipher(BlockCipher engine)
{
-
+ this.cfbEngine = new CFBBlockCipher(engine, engine.getBlockSize() * 8);
}
+
public void init(boolean forEncryption, CipherParameters params)
throws IllegalArgumentException
{
- //To change body of implemented methods use File | Settings | File Templates.
+ counter = 0;
+ cfbEngine.init(forEncryption, params);
+
+ this.forEncryption = forEncryption;
+
+ if (params instanceof ParametersWithIV)
+ {
+ params = ((ParametersWithIV)params).getParameters();
+ }
+
+ if (params instanceof ParametersWithRandom)
+ {
+ params = ((ParametersWithRandom)params).getParameters();
+ }
+
+ if (params instanceof ParametersWithSBox)
+ {
+ params = ((ParametersWithSBox)params).getParameters();
+ }
+
+ key = (KeyParameter)params;
}
public String getAlgorithmName()
{
- return null; //To change body of implemented methods use File | Settings | File Templates.
+ return "G" + cfbEngine.getAlgorithmName();
}
public int getBlockSize()
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ return cfbEngine.getBlockSize();
}
public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
throws DataLengthException, IllegalStateException
{
- return 0; //To change body of implemented methods use File | Settings | File Templates.
+ if (counter > 0 && counter % 1024 == 0)
+ {
+ BlockCipher base = cfbEngine.getUnderlyingCipher();
+
+ base.init(false, key);
+
+ byte[] nextKey = new byte[32];
+
+ base.processBlock(C, 0, nextKey, 0);
+ base.processBlock(C, 8, nextKey, 8);
+ base.processBlock(C, 16, nextKey, 16);
+ base.processBlock(C, 24, nextKey, 24);
+
+ key = new KeyParameter(nextKey);
+
+ byte[] iv = new byte[8];
+
+ base.init(true, key);
+
+ base.processBlock(cfbEngine.getCurrentIV(), 0, iv, 0);
+
+ cfbEngine.init(forEncryption, new ParametersWithIV(key, iv));
+ }
+
+ counter += cfbEngine.getBlockSize();
+
+ return cfbEngine.processBlock(in, inOff, out, outOff);
}
public void reset()
{
- //To change body of implemented methods use File | Settings | File Templates.
+ counter = 0;
+ cfbEngine.reset();
}
}