diff --git a/lib/installer-exclude/zrtp4j-light.jar b/lib/installer-exclude/zrtp4j-light.jar index f5485391a..f0a028d55 100755 Binary files a/lib/installer-exclude/zrtp4j-light.jar and b/lib/installer-exclude/zrtp4j-light.jar differ diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPCryptoContext.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPCryptoContext.java index e819995aa..ff18988f3 100644 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPCryptoContext.java +++ b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTCPCryptoContext.java @@ -26,6 +26,8 @@ */ package net.java.sip.communicator.impl.neomedia.transform.srtp; +import java.util.Arrays; + import net.java.sip.communicator.impl.neomedia.*; import org.bouncycastle.crypto.digests.SHA1Digest; @@ -208,22 +210,22 @@ public SRTCPCryptoContext(long ssrcIn, saltKey = null; break; + case SRTPPolicy.AESF8_ENCRYPTION: + cipherF8 = new AESFastEngine(); + case SRTPPolicy.AESCM_ENCRYPTION: cipher = new AESFastEngine(); encKey = new byte[this.policy.getEncKeyLength()]; - saltKey = new byte[this.policy.getSaltKeyLength()]; - - case SRTPPolicy.AESF8_ENCRYPTION: - cipherF8 = new AESFastEngine(); + saltKey = new byte[this.policy.getSaltKeyLength()]; break; + case SRTPPolicy.TWOFISHF8_ENCRYPTION: + cipherF8 = new TwofishEngine(); + case SRTPPolicy.TWOFISH_ENCRYPTION: cipher = new TwofishEngine(); encKey = new byte[this.policy.getEncKeyLength()]; saltKey = new byte[this.policy.getSaltKeyLength()]; - - case SRTPPolicy.TWOFISHF8_ENCRYPTION: - cipherF8 = new TwofishEngine(); break; } @@ -499,7 +501,7 @@ public void processPacketAESF8(RawPacket pkt, int index) SRTPCipherF8.process(cipher, pkt.getBuffer(), pkt.getOffset() + payloadOffset, - payloadLength, ivStore, encKey, saltKey, cipherF8); + payloadLength, ivStore, cipherF8); } /** @@ -596,8 +598,9 @@ public void deriveSrtcpKeys() KeyParameter encryptionKey = new KeyParameter(masterKey); cipher.init(true, encryptionKey); - cipherCtr.getCipherStream(cipher, encKey, - policy.getEncKeyLength(), ivStore); + Arrays.fill(masterKey, (byte)0); + + cipherCtr.getCipherStream(cipher, encKey, policy.getEncKeyLength(), ivStore); if (authKey != null) { @@ -622,16 +625,20 @@ public void deriveSrtcpKeys() break; } } + Arrays.fill(authKey, (byte)0); // compute the session salt label = 5; computeIv(label); - cipherCtr.getCipherStream(cipher, saltKey, - policy.getSaltKeyLength(), ivStore); + cipherCtr.getCipherStream(cipher, saltKey, policy.getSaltKeyLength(), ivStore); + Arrays.fill(masterSalt, (byte)0); // As last step: initialize cipher with derived encryption key. + if (cipherF8 != null) + SRTPCipherF8.deriveForIV(cipherF8, encKey, saltKey); encryptionKey = new KeyParameter(encKey); cipher.init(true, encryptionKey); + Arrays.fill(encKey, (byte)0); } diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherF8.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherF8.java index bce7ea727..d72e9a1fc 100644 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherF8.java +++ b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCipherF8.java @@ -55,6 +55,7 @@ * We use AESCipher to handle basic AES encryption / decryption. * * @author Bing SU (nova.su@gmail.com) + * @author Werner Dittmann */ public class SRTPCipherF8 { @@ -74,16 +75,8 @@ class F8Context long J; } - public static void process(BlockCipher cipher, byte[] data, int off, - int len, byte[] iv, byte[] key, byte[] salt, BlockCipher f8Cipher) + public static void deriveForIV(BlockCipher f8Cipher, byte[] key, byte[] salt) { - F8Context f8ctx = new SRTPCipherF8().new F8Context(); - - /* - * Get memory for the derived IV (IV') - */ - f8ctx.ivAccent = new byte[BLKLEN]; - /* * Get memory for the special key. This is the key to compute the * derived IV (IV'). @@ -111,13 +104,24 @@ public static void process(BlockCipher cipher, byte[] data, int off, */ KeyParameter encryptionKey = new KeyParameter(maskedKey); f8Cipher.init(true, encryptionKey); + saltMask = null; + maskedKey = null; + } + + public static void process(BlockCipher cipher, byte[] data, int off, int len, + byte[] iv, BlockCipher f8Cipher) + { + F8Context f8ctx = new SRTPCipherF8().new F8Context(); + + /* + * Get memory for the derived IV (IV') + */ + f8ctx.ivAccent = new byte[BLKLEN]; /* - * Use the masked key to encrypt the original IV to produce IV'. + * Use the derived IV encryption setup to encrypt the original IV to produce IV'. */ f8Cipher.processBlock(iv, 0, f8ctx.ivAccent, 0); - saltMask = null; - maskedKey = null; f8ctx.J = 0; // initialize the counter f8ctx.S = new byte[BLKLEN]; // get the key stream buffer @@ -138,7 +142,7 @@ public static void process(BlockCipher cipher, byte[] data, int off, processBlock(cipher, f8ctx, data, off, data, off, inLen); } } - + /** * Encrypt / Decrypt a block using F8 Mode AES algorithm, read len bytes * data from in at inOff and write the output into out at outOff @@ -157,7 +161,7 @@ public static void process(BlockCipher cipher, byte[] data, int off, * length of the input data */ private static void processBlock(BlockCipher cipher, F8Context f8ctx, - byte[] in, int inOff, byte[] out, int outOff, int len) + byte[] in, int inOff, byte[] out, int outOff, int len) { /* * XOR the previous key stream with IV' diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCryptoContext.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCryptoContext.java index 2825808e7..e8f54db9c 100644 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCryptoContext.java +++ b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPCryptoContext.java @@ -26,6 +26,8 @@ */ package net.java.sip.communicator.impl.neomedia.transform.srtp; +import java.util.Arrays; + import net.java.sip.communicator.impl.neomedia.*; import org.bouncycastle.crypto.*; @@ -256,23 +258,23 @@ public SRTPCryptoContext(long ssrcIn, int rocIn, long kdr, saltKey = null; break; + case SRTPPolicy.AESF8_ENCRYPTION: + cipherF8 = new AESFastEngine(); + //$FALL-THROUGH$ + case SRTPPolicy.AESCM_ENCRYPTION: cipher = new AESFastEngine(); encKey = new byte[policy.getEncKeyLength()]; saltKey = new byte[policy.getSaltKeyLength()]; - //$FALL-THROUGH$ - - case SRTPPolicy.AESF8_ENCRYPTION: - cipherF8 = new AESFastEngine(); break; + case SRTPPolicy.TWOFISHF8_ENCRYPTION: + cipherF8 = new TwofishEngine(); + case SRTPPolicy.TWOFISH_ENCRYPTION: cipher = new TwofishEngine(); encKey = new byte[this.policy.getEncKeyLength()]; saltKey = new byte[this.policy.getSaltKeyLength()]; - - case SRTPPolicy.TWOFISHF8_ENCRYPTION: - cipherF8 = new TwofishEngine(); break; } @@ -553,9 +555,8 @@ public void processPacketAESF8(RawPacket pkt) final int payloadOffset = pkt.getHeaderLength(); final int payloadLength = pkt.getPayloadLength(); - SRTPCipherF8.process(cipher, pkt.getBuffer(), pkt.getOffset() + - payloadOffset, payloadLength, ivStore, encKey, saltKey, - cipherF8); + SRTPCipherF8.process(cipher, pkt.getBuffer(), pkt.getOffset() + payloadOffset, + payloadLength, ivStore, cipherF8); } /** @@ -675,8 +676,9 @@ public void deriveSrtpKeys(long index) KeyParameter encryptionKey = new KeyParameter(masterKey); cipher.init(true, encryptionKey); - cipherCtr.getCipherStream(cipher, encKey, policy.getEncKeyLength(), - ivStore); + Arrays.fill(masterKey, (byte)0); + + cipherCtr.getCipherStream(cipher, encKey, policy.getEncKeyLength(), ivStore); // compute the session authentication key if (authKey != null) @@ -702,15 +704,20 @@ public void deriveSrtpKeys(long index) break; } } + Arrays.fill(authKey, (byte)0); + // compute the session salt label = 0x02; computeIv(label, index); - cipherCtr.getCipherStream(cipher, saltKey, policy.getSaltKeyLength(), - ivStore); + cipherCtr.getCipherStream(cipher, saltKey, policy.getSaltKeyLength(), ivStore); + Arrays.fill(masterSalt, (byte)0); // As last step: initialize cipher with derived encryption key. + if (cipherF8 != null) + SRTPCipherF8.deriveForIV(cipherF8, encKey, saltKey); encryptionKey = new KeyParameter(encKey); cipher.init(true, encryptionKey); + Arrays.fill(encKey, (byte)0); } /** diff --git a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformEngine.java b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformEngine.java index e6a041633..47a34df30 100644 --- a/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformEngine.java +++ b/src/net/java/sip/communicator/impl/neomedia/transform/srtp/SRTPTransformEngine.java @@ -20,26 +20,6 @@ public class SRTPTransformEngine implements TransformEngine { - /** - * Master key of this SRTP session - */ - private final byte[] masterKey; - - /** - * Master salt key of this SRTP session - */ - private final byte[] masterSalt; - - /** - * SRTP processing policy - */ - private final SRTPPolicy srtpPolicy; - - /** - * SRTCP processing policy - */ - private final SRTPPolicy srtcpPolicy; - /** * The default SRTPCryptoContext, which will be used to derivate other * contexts. @@ -64,23 +44,15 @@ public class SRTPTransformEngine public SRTPTransformEngine(byte[] masterKey, byte[] masterSalt, SRTPPolicy srtpPolicy, SRTPPolicy srtcpPolicy) { - this.masterKey = new byte[masterKey.length]; - System.arraycopy(masterKey, 0, this.masterKey, 0, masterKey.length); - - this.masterSalt = new byte[masterSalt.length]; - System.arraycopy(masterSalt, 0, this.masterSalt, 0, masterSalt.length); - - this.srtpPolicy = srtpPolicy; - this.srtcpPolicy = srtcpPolicy; this.defaultContext = new SRTPCryptoContext(0, 0, 0, - this.masterKey, - this.masterSalt, - this.srtpPolicy); + masterKey, + masterSalt, + srtpPolicy); this.defaultContextControl = new SRTCPCryptoContext(0, - this.masterKey, - this.masterSalt, - this.srtcpPolicy); + masterKey, + masterSalt, + srtcpPolicy); } /** @@ -103,46 +75,6 @@ public PacketTransformer getRTPTransformer() return new SRTPTransformer(this); } - /** - * Get the master encryption key - * - * @return the master encryption key - */ - public byte[] getMasterKey() - { - return this.masterKey; - } - - /** - * Get the master salt key - * - * @return the master salt key - */ - public byte[] getMasterSalt() - { - return this.masterSalt; - } - - /** - * Get the SRTCP policy - * - * @return the SRTCP policy - */ - public SRTPPolicy getSRTCPPolicy() - { - return this.srtcpPolicy; - } - - /** - * Get the SRTP policy - * - * @return the SRTP policy - */ - public SRTPPolicy getSRTPPolicy() - { - return this.srtpPolicy; - } - /** * Get the default SRTPCryptoContext *