diff options
author | David Hook <dgh@cryptoworkshop.com> | 2013-09-13 10:27:50 +0400 |
---|---|---|
committer | David Hook <dgh@cryptoworkshop.com> | 2013-09-13 10:27:50 +0400 |
commit | 1c67cdcb2d9d30487efee98979ee1646a89553de (patch) | |
tree | 6b2630bc78c2cf73ae9b8c857988330fba9e5d45 /core/src/main | |
parent | 972c20edfaa73bf197b1665eb3c4818c01ac3934 (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')
8 files changed, 131 insertions, 13 deletions
diff --git a/core/src/main/j2me/java/util/AbstractList.java b/core/src/main/j2me/java/util/AbstractList.java index 42dda96e..dbb1dffc 100644 --- a/core/src/main/j2me/java/util/AbstractList.java +++ b/core/src/main/j2me/java/util/AbstractList.java @@ -57,7 +57,7 @@ public abstract class AbstractList { int index = li.nextIndex(); e = li.next(); - System.out.println(e); + if (o == null) { if (e == null) @@ -217,14 +217,13 @@ public abstract class AbstractList protected void removeRange(int fromIndex, int toIndex) { - System.out.println("breakpoint 1"); if (fromIndex == toIndex) { return; } - System.out.println("breakpoint 2"); + ListIterator li = listIterator(fromIndex); - System.out.println("breakpoint 3"); + int i = fromIndex; do { 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(); } } |