diff options
author | David Hook <dgh@cryptoworkshop.com> | 2014-03-22 06:52:01 +0400 |
---|---|---|
committer | David Hook <dgh@cryptoworkshop.com> | 2014-03-22 06:52:01 +0400 |
commit | 5b7b93114c553bb156576a6852cd36109327bcce (patch) | |
tree | 588d078aeb056943a6f46625b782ab3441c326a4 /core | |
parent | 35c4034d4448312c5ac3dacb99d418dd932249a0 (diff) |
added CBC support to JCE ECIES, added IV support to IESEngine
Diffstat (limited to 'core')
-rwxr-xr-x | core/src/main/java/org/bouncycastle/crypto/engines/IESEngine.java | 75 | ||||
-rw-r--r-- | core/src/test/java/org/bouncycastle/crypto/test/ECIESTest.java | 36 |
2 files changed, 56 insertions, 55 deletions
diff --git a/core/src/main/java/org/bouncycastle/crypto/engines/IESEngine.java b/core/src/main/java/org/bouncycastle/crypto/engines/IESEngine.java index d146d832..479dc44f 100755 --- a/core/src/main/java/org/bouncycastle/crypto/engines/IESEngine.java +++ b/core/src/main/java/org/bouncycastle/crypto/engines/IESEngine.java @@ -19,7 +19,6 @@ import org.bouncycastle.crypto.params.IESWithCipherParameters; import org.bouncycastle.crypto.params.KDFParameters; import org.bouncycastle.crypto.params.KeyParameter; import org.bouncycastle.crypto.params.ParametersWithIV; -import org.bouncycastle.crypto.prng.RandomGenerator; import org.bouncycastle.crypto.util.Pack; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.BigIntegers; @@ -35,7 +34,6 @@ public class IESEngine DerivationFunction kdf; Mac mac; BufferedBlockCipher cipher; - RandomGenerator nonceGenerator; byte[] macBuf; boolean forEncryption; @@ -45,7 +43,7 @@ public class IESEngine byte[] V; private EphemeralKeyPairGenerator keyPairGenerator; private KeyParser keyParser; - + private byte[] IV; /** * set up for use with stream mode, where the key derivation function @@ -91,50 +89,25 @@ public class IESEngine } /** - * set up for use in conjunction with a block cipher mode of operating using - * a nonce/IV to handle the message. - * - * @param agree the key agreement used as the basis for the encryption - * @param kdf the key derivation function used for byte generation - * @param mac the message authentication code generator for the message - * @param cipher the cipher to used for encrypting the message - * @param nonceGenerator the random generator that produces IVs used by the - * block cipher, must be initialized. - */ - public IESEngine( - BasicAgreement agree, - DerivationFunction kdf, - Mac mac, - BufferedBlockCipher cipher, - RandomGenerator nonceGenerator) - { - this.agree = agree; - this.kdf = kdf; - this.mac = mac; - this.macBuf = new byte[mac.getMacSize()]; - this.cipher = cipher; - this.nonceGenerator = nonceGenerator; - } - - /** * Initialise the encryptor. * * @param forEncryption whether or not this is encryption/decryption. * @param privParam our private key parameters * @param pubParam the recipient's/sender's public key parameters - * @param param encoding and derivation parameters. + * @param params encoding and derivation parameters, may be wrapped to include an IV for an underlying block cipher. */ public void init( boolean forEncryption, CipherParameters privParam, CipherParameters pubParam, - CipherParameters param) + CipherParameters params) { this.forEncryption = forEncryption; this.privParam = privParam; this.pubParam = pubParam; - this.param = (IESParameters)param; this.V = new byte[0]; + + extractParams(params); } @@ -142,30 +115,46 @@ public class IESEngine * Initialise the encryptor. * * @param publicKey the recipient's/sender's public key parameters - * @param params encoding and derivation parameters. + * @param params encoding and derivation parameters, may be wrapped to include an IV for an underlying block cipher. * @param ephemeralKeyPairGenerator the ephemeral key pair generator to use. */ public void init(AsymmetricKeyParameter publicKey, CipherParameters params, EphemeralKeyPairGenerator ephemeralKeyPairGenerator) { this.forEncryption = true; this.pubParam = publicKey; - this.param = (IESParameters)params; this.keyPairGenerator = ephemeralKeyPairGenerator; + + extractParams(params); } /** * Initialise the encryptor. * * @param privateKey the recipient's private key. - * @param params encoding and derivation parameters. + * @param params encoding and derivation parameters, may be wrapped to include an IV for an underlying block cipher. * @param publicKeyParser the parser for reading the ephemeral public key. */ public void init(AsymmetricKeyParameter privateKey, CipherParameters params, KeyParser publicKeyParser) { this.forEncryption = false; this.privParam = privateKey; - this.param = (IESParameters)params; this.keyParser = publicKeyParser; + + extractParams(params); + } + + private void extractParams(CipherParameters params) + { + if (params instanceof ParametersWithIV) + { + this.IV = ((ParametersWithIV)params).getIV(); + this.param = (IESParameters)((ParametersWithIV)params).getParameters(); + } + else + { + this.IV = null; + this.param = (IESParameters)params; + } } public BufferedBlockCipher getCipher() @@ -226,12 +215,9 @@ public class IESEngine System.arraycopy(K, 0, K1, 0, K1.length); System.arraycopy(K, K1.length, K2, 0, K2.length); - // If nonceGenerator provided get an IV and initialize the cipher - if (nonceGenerator != null) + // If iv provided use it to initialise the cipher + if (IV != null) { - byte[] IV = new byte[K1.length]; - - nonceGenerator.nextBytes(IV); cipher.init(true, new ParametersWithIV(new KeyParameter(K1), IV)); } else @@ -333,12 +319,9 @@ public class IESEngine System.arraycopy(K, 0, K1, 0, K1.length); System.arraycopy(K, K1.length, K2, 0, K2.length); - // If nonceGenerator provided get an IV and initialize the cipher - if (nonceGenerator != null) + // If IV provide use it to initialize the cipher + if (IV != null) { - byte[] IV = new byte[K1.length]; - - nonceGenerator.nextBytes(IV); cipher.init(false, new ParametersWithIV(new KeyParameter(K1), IV)); } else diff --git a/core/src/test/java/org/bouncycastle/crypto/test/ECIESTest.java b/core/src/test/java/org/bouncycastle/crypto/test/ECIESTest.java index 488cb697..737cd860 100644 --- a/core/src/test/java/org/bouncycastle/crypto/test/ECIESTest.java +++ b/core/src/test/java/org/bouncycastle/crypto/test/ECIESTest.java @@ -5,6 +5,7 @@ import java.security.SecureRandom; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.BufferedBlockCipher; +import org.bouncycastle.crypto.CipherParameters; import org.bouncycastle.crypto.KeyEncoder; import org.bouncycastle.crypto.KeyGenerationParameters; import org.bouncycastle.crypto.agreement.ECDHBasicAgreement; @@ -24,6 +25,7 @@ import org.bouncycastle.crypto.params.ECPrivateKeyParameters; import org.bouncycastle.crypto.params.ECPublicKeyParameters; import org.bouncycastle.crypto.params.IESParameters; import org.bouncycastle.crypto.params.IESWithCipherParameters; +import org.bouncycastle.crypto.params.ParametersWithIV; import org.bouncycastle.crypto.parsers.ECIESPublicKeyParser; import org.bouncycastle.math.ec.ECConstants; import org.bouncycastle.math.ec.ECCurve; @@ -36,6 +38,8 @@ import org.bouncycastle.util.test.SimpleTest; public class ECIESTest extends SimpleTest { + private static byte[] TWOFISH_IV = Hex.decode("000102030405060708090a0b0c0d0e0f"); + ECIESTest() { } @@ -45,7 +49,7 @@ public class ECIESTest return "ECIES"; } - private void staticTest() + private void doStaticTest(byte[] iv) throws Exception { BigInteger n = new BigInteger("6277101735386680763835789423176059013767194773182842284081"); @@ -85,7 +89,7 @@ public class ECIESTest new HMac(new SHA1Digest())); byte[] d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; byte[] e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; - IESParameters p = new IESParameters(d, e, 64); + CipherParameters p = new IESParameters(d, e, 64); i1.init(true, p1.getPrivate(), p2.getPublic(), p); i2.init(false, p2.getPrivate(), p1.getPublic(), p); @@ -127,6 +131,11 @@ public class ECIESTest e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; p = new IESWithCipherParameters(d, e, 64, 128); + if (iv != null) + { + p = new ParametersWithIV(p, iv); + } + i1.init(true, p1.getPrivate(), p2.getPublic(), p); i2.init(false, p2.getPrivate(), p1.getPublic(), p); @@ -134,7 +143,9 @@ public class ECIESTest out1 = i1.processBlock(message, 0, message.length); - if (!areEqual(out1, Hex.decode("b8a06ea5c2b9df28b58a0a90a734cde8c9c02903e5c220021fe4417410d1e53a32a71696"))) + if (!areEqual(out1, (iv == null) ? + Hex.decode("b8a06ea5c2b9df28b58a0a90a734cde8c9c02903e5c220021fe4417410d1e53a32a71696") + : Hex.decode("f246b0e26a2711992cac9c590d08e45c5e730b7c0f4218bb064e27b7dd7c8a3bd8bf01c3"))) { fail("twofish cipher test failed on enc"); } @@ -147,7 +158,7 @@ public class ECIESTest } } - private void doEphemeralTest() + private void doEphemeralTest(byte[] iv) throws Exception { BigInteger n = new BigInteger("6277101735386680763835789423176059013767194773182842284081"); @@ -198,9 +209,9 @@ public class ECIESTest new KDF2BytesGenerator(new SHA1Digest()), new HMac(new SHA1Digest())); - byte[] d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; - byte[] e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; - IESParameters p = new IESParameters(d, e, 64); + byte[] d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; + byte[] e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; + CipherParameters p = new IESParameters(d, e, 64); i1.init(p2.getPublic(), p, ephKeyGen); i2.init(p2.getPrivate(), p, new ECIESPublicKeyParser(params)); @@ -237,6 +248,11 @@ public class ECIESTest e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 }; p = new IESWithCipherParameters(d, e, 64, 128); + if (iv != null) + { + p = new ParametersWithIV(p, iv); + } + i1.init(p2.getPublic(), p, ephKeyGen); i2.init(p2.getPrivate(), p, new ECIESPublicKeyParser(params)); @@ -323,7 +339,8 @@ public class ECIESTest public void performTest() throws Exception { - staticTest(); + doStaticTest(null); + doStaticTest(TWOFISH_IV); BigInteger n = new BigInteger("6277101735386680763835789423176059013767194773182842284081"); @@ -348,7 +365,8 @@ public class ECIESTest doTest(p1, p2); - doEphemeralTest(); + doEphemeralTest(null); + doEphemeralTest(TWOFISH_IV); } public static void main( |