Enable Twofish in SRTP to support ZRTP Twofish option

cusax-fix
Werner Dittmann 15 years ago
parent 20e30037da
commit 03bba9c46c

@ -2305,13 +2305,22 @@ org.apache.http.util"/>
gnu.java.zrtp.packets,
gnu.java.zrtp.utils,
gnu.java.zrtp.zidfile"/>
<attribute name="Import-Package" value="org.bouncycastle.crypto,
<attribute name="Import-Package" value="org.bouncycastle.asn1,
org.bouncycastle.asn1.nist,
org.bouncycastle.asn1.sec,
org.bouncycastle.asn1.x9,
org.bouncycastle.crypto,
org.bouncycastle.crypto.agreement,
org.bouncycastle.crypto.digests,
org.bouncycastle.crypto.engines,
org.bouncycastle.crypto.generators,
org.bouncycastle.crypto.macs,
org.bouncycastle.crypto.modes,
org.bouncycastle.crypto.params,
org.bouncycastle.crypto.prng,
org.bouncycastle.crypto.engines,
org.bouncycastle.crypto.modes"/>
org.bouncycastle.math.ec,
org.bouncycastle.util.encoders,
org.bouncycastle.util"/>
<attribute name="Bundle-Name" value="ZRTP4J"/>
<attribute name="Bundle-Description" value="ZRTP for Java library."/>
<attribute name="Bundle-Version" value="1.4.5"/>
@ -2362,15 +2371,21 @@ org.apache.http.util"/>
<jar compress="true" destfile="${bundles.dest}/bouncycastle.jar">
<zipfileset src="${lib.noinst}/lcrypto-jdk16-143.jar"/>
<manifest>
<attribute name="Export-Package" value="org.bouncycastle.crypto,
<attribute name="Export-Package" value="org.bouncycastle.asn1,
org.bouncycastle.asn1.nist,
org.bouncycastle.asn1.sec,
org.bouncycastle.asn1.x9,
org.bouncycastle.crypto,
org.bouncycastle.crypto.agreement,
org.bouncycastle.crypto.digests,
org.bouncycastle.crypto.engines,
org.bouncycastle.crypto.generators,
org.bouncycastle.crypto.macs,
org.bouncycastle.crypto.modes,
org.bouncycastle.crypto.params,
org.bouncycastle.crypto.prng,
org.bouncycastle.crypto.engines,
org.bouncycastle.crypto.modes,
org.bouncycastle.crypto.generators,
org.bouncycastle.crypto.signers,
org.bouncycastle.math.ec,
org.bouncycastle.util.encoders,
org.bouncycastle.util"/>
<attribute name="Bundle-Name" value="BouncyCastle"/>

@ -1,29 +0,0 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*
*/
package net.java.sip.communicator.impl.neomedia.transform.srtp;
/**
* SRTPCipher interface describes the abstract requirement for SRTP
* encryption algorithm. Given a byte stream and an initial vector (iv)
* process the byte stream in place (either encrypt or decrypt)
*
* @author Bing SU (nova.su@gmail.com)
*/
public interface SRTPCipher
{
/**
* Process (encrypt / decrypt) a byte stream, using the supplied
* initial vector.
*
* @param data byte array containing the byte stream to be processed
* @param offset byte stream star offset with data byte array
* @param length byte stream length in bytes
* @param iv initial vector for this operation
*/
void process(byte[] data, int offset, int length, byte[] iv);
}

@ -1,142 +1,127 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*
* Some of the code in this class is derived from ccRtp's SRTP implementation,
* which has the following copyright notice:
*
Copyright (C) 2004-2006 the Minisip Team
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package net.java.sip.communicator.impl.neomedia.transform.srtp;
import org.bouncycastle.crypto.engines.AESFastEngine;
/**
* SRTPCipherCTR implements SRTP Counter Mode AES Encryption (AES-CM).
* Counter Mode AES Encryption algorithm is defined in RFC3711, section 4.1.1.
*
* Other than Null Cipher, RFC3711 defined two two encryption algorithms:
* Counter Mode AES Encryption and F8 Mode AES encryption. Both encryption
* algorithms are capable to encrypt / decrypt arbitrary length data, and the
* size of packet data is not required to be a multiple of the AES block
* size (128bit). So, no padding is needed.
*
* Please note: these two encryption algorithms are specially defined by SRTP.
* They are not common AES encryption modes, so you will not be able to find a
* replacement implementation in common cryptographic libraries.
*
* As defined by RFC3711: Counter Mode Encryption is mandatory..
*
* mandatory to impl optional default
* -------------------------------------------------------------------------
* encryption AES-CM, NULL AES-f8 AES-CM
* message integrity HMAC-SHA1 - HMAC-SHA1
* key derivation (PRF) AES-CM - AES-CM
*
* We use AESCipher to handle basic AES encryption / decryption.
*
* @author Bing SU (nova.su@gmail.com)
*/
public class SRTPCipherCTR
{
/**
* AES block size, just a short name.
*/
private final static int BLKLEN = 16;
/**
* Buffer defined maximum size.
*/
private final static int MAX_BUFFER_LENGTH = 10*1024;
private final byte[] cipherInBlock = new byte[BLKLEN];
private final byte[] tmpCipherBlock = new byte[BLKLEN];
private byte[] streamBuf = new byte[1024];
/**
* Process (encrypt / decrypt) a byte stream, using the supplied
* initial vector.
*
* @param aesCipher the cipher
* @param data byte array containing the byte stream to be processed
* @param off byte stream star offset with data byte array
* @param len byte stream length in bytes
* @param iv initial vector for this operation
*/
public void process(AESFastEngine aesCipher, byte[] data, int off, int len,
byte[] iv) {
if (off + len > data.length) {
return;
}
// if data fits in inter buffer - use it. Otherwise allocate bigger
// buffer store it to use it for later processing - up to a defined
// maximum size.
byte[] cipherStream = null;
if (len > streamBuf.length) {
cipherStream = new byte[len];
if (cipherStream.length <= MAX_BUFFER_LENGTH) {
streamBuf = cipherStream;
}
}
else {
cipherStream = streamBuf;
}
getCipherStream(aesCipher, cipherStream, len, iv);
for (int i = 0; i < len; i++) {
data[i + off] ^= cipherStream[i];
}
}
/**
* Computes the cipher stream for AES CM mode. See section 4.1.1 in RFC3711
* for detailed description.
*
* @param aesCipher the cipher
* @param out
* byte array holding the output cipher stream
* @param length
* length of the cipher stream to produce, in bytes
* @param iv
* initialization vector used to generate this cipher stream
*/
public void getCipherStream(AESFastEngine aesCipher,
byte[] out, int length, byte[] iv)
{
System.arraycopy(iv, 0, cipherInBlock, 0, 14);
int ctr;
for (ctr = 0; ctr < length / BLKLEN; ctr++) {
// compute the cipher stream
cipherInBlock[14] = (byte) ((ctr & 0xFF00) >> 8);
cipherInBlock[15] = (byte) ((ctr & 0x00FF));
aesCipher.processBlock(cipherInBlock, 0, out, ctr * BLKLEN);
}
// Treat the last bytes:
cipherInBlock[14] = (byte) ((ctr & 0xFF00) >> 8);
cipherInBlock[15] = (byte) ((ctr & 0x00FF));
aesCipher.processBlock(cipherInBlock, 0, tmpCipherBlock, 0);
System.arraycopy(tmpCipherBlock, 0, out, ctr * BLKLEN, length % BLKLEN);
}
}
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*
* Some of the code in this class is derived from ccRtp's SRTP implementation,
* which has the following copyright notice:
*
Copyright (C) 2004-2006 the Minisip Team
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package net.java.sip.communicator.impl.neomedia.transform.srtp;
import org.bouncycastle.crypto.BlockCipher;
/**
* SRTPCipherCTR implements SRTP Counter Mode AES Encryption (AES-CM).
* Counter Mode AES Encryption algorithm is defined in RFC3711, section 4.1.1.
*
* Other than Null Cipher, RFC3711 defined two two encryption algorithms:
* Counter Mode AES Encryption and F8 Mode AES encryption. Both encryption
* algorithms are capable to encrypt / decrypt arbitrary length data, and the
* size of packet data is not required to be a multiple of the AES block
* size (128bit). So, no padding is needed.
*
* Please note: these two encryption algorithms are specially defined by SRTP.
* They are not common AES encryption modes, so you will not be able to find a
* replacement implementation in common cryptographic libraries.
*
* As defined by RFC3711: Counter Mode Encryption is mandatory..
*
* mandatory to impl optional default
* -------------------------------------------------------------------------
* encryption AES-CM, NULL AES-f8 AES-CM
* message integrity HMAC-SHA1 - HMAC-SHA1
* key derivation (PRF) AES-CM - AES-CM
*
* We use AESCipher to handle basic AES encryption / decryption.
*
* @author Werner Dittmann (Werner.Dittmann@t-online.de)
* @author Bing SU (nova.su@gmail.com)
*/
public class SRTPCipherCTR
{
private final static int BLKLEN = 16;
private final static int MAX_BUFFER_LENGTH = 10*1024;
private final byte[] cipherInBlock = new byte[BLKLEN];
private final byte[] tmpCipherBlock = new byte[BLKLEN];
private byte[] streamBuf = new byte[1024];
public SRTPCipherCTR() {
}
public void process(BlockCipher cipher, byte[] data, int off, int len,
byte[] iv) {
if (off + len > data.length) {
return;
}
// if data fits in inter buffer - use it. Otherwise allocate bigger
// buffer store it to use it for later processing - up to a defined
// maximum size.
byte[] cipherStream = null;
if (len > streamBuf.length) {
cipherStream = new byte[len];
if (cipherStream.length <= MAX_BUFFER_LENGTH) {
streamBuf = cipherStream;
}
}
else {
cipherStream = streamBuf;
}
getCipherStream(cipher, cipherStream, len, iv);
for (int i = 0; i < len; i++) {
data[i + off] ^= cipherStream[i];
}
}
/**
* Computes the cipher stream for AES CM mode. See section 4.1.1 in RFC3711
* for detailed description.
*
* @param out
* byte array holding the output cipher stream
* @param length
* length of the cipher stream to produce, in bytes
* @param iv
* initialization vector used to generate this cipher stream
*/
public void getCipherStream(BlockCipher aesCipher, byte[] out, int length, byte[] iv)
{
System.arraycopy(iv, 0, cipherInBlock, 0, 14);
int ctr;
for (ctr = 0; ctr < length / BLKLEN; ctr++) {
// compute the cipher stream
cipherInBlock[14] = (byte) ((ctr & 0xFF00) >> 8);
cipherInBlock[15] = (byte) ((ctr & 0x00FF));
aesCipher.processBlock(cipherInBlock, 0, out, ctr * BLKLEN);
}
// Treat the last bytes:
cipherInBlock[14] = (byte) ((ctr & 0xFF00) >> 8);
cipherInBlock[15] = (byte) ((ctr & 0x00FF));
aesCipher.processBlock(cipherInBlock, 0, tmpCipherBlock, 0);
System.arraycopy(tmpCipherBlock, 0, out, ctr * BLKLEN, length % BLKLEN);
}
}

@ -1,208 +1,191 @@
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*
* Some of the code in this class is derived from ccRtp's SRTP implementation,
* which has the following copyright notice:
*
Copyright (C) 2004-2006 the Minisip Team
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package net.java.sip.communicator.impl.neomedia.transform.srtp;
import java.util.*;
import org.bouncycastle.crypto.engines.AESFastEngine;
import org.bouncycastle.crypto.params.KeyParameter;
/**
* SRTPCipherF8 implements SRTP F8 Mode AES Encryption (AES-f8).
* F8 Mode AES Encryption algorithm is defined in RFC3711, section 4.1.2.
*
* Other than Null Cipher, RFC3711 defined two two encryption algorithms:
* Counter Mode AES Encryption and F8 Mode AES encryption. Both encryption
* algorithms are capable to encrypt / decrypt arbitrary length data, and the
* size of packet data is not required to be a multiple of the AES block
* size (128bit). So, no padding is needed.
*
* Please note: these two encryption algorithms are specially defined by SRTP.
* They are not common AES encryption modes, so you will not be able to find a
* replacement implementation in common cryptographic libraries.
*
* As defined by RFC3711: F8 mode encryption is optional.
*
* mandatory to impl optional default
* -------------------------------------------------------------------------
* encryption AES-CM, NULL AES-f8 AES-CM
* message integrity HMAC-SHA1 - HMAC-SHA1
* key derivation (PRF) AES-CM - AES-CM
*
* We use AESCipher to handle basic AES encryption / decryption.
*
* @author Werner Dittmann (Werner.Dittmann@t-online.de)
* @author Bing SU (nova.su@gmail.com)
*/
public class SRTPCipherF8
{
/**
* AES block size, just a short name.
*/
private final static int BLKLEN = 16;
/**
* F8 mode encryption context, see RFC3711 section 4.1.2 for detailed
* description.
*/
static class F8Context
{
public byte[] S;
public byte[] ivAccent;
long J;
}
/**
* Process (encrypt / decrypt) a byte stream, using the supplied
* initial vector.
*
* @param aesCipher the cipher
* @param data byte array containing the byte stream to be processed
* @param off byte stream star offset with data byte array
* @param len byte stream length in bytes
* @param iv initial vector for this operation
* @param key the key
* @param salt the salt
* @param f8Cipher the f8cipher
*/
public static void process(AESFastEngine aesCipher,
byte[] data, int off, int len,
byte[] iv, byte[] key, byte[] salt, AESFastEngine f8Cipher) {
F8Context f8ctx = 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').
*/
byte[] saltMask = new byte[key.length];
byte[] maskedKey = new byte[key.length];
/*
* First copy the salt into the mask field, then fill with 0x55 to get a
* full key.
*/
System.arraycopy(salt, 0, saltMask, 0, salt.length);
for (int i = salt.length; i < saltMask.length; ++i) {
saltMask[i] = 0x55;
}
/*
* XOR the original key with the above created mask to get the special
* key.
*/
for (int i = 0; i < key.length; i++) {
maskedKey[i] = (byte) (key[i] ^ saltMask[i]);
}
/*
* Prepare the f8Cipher with the special key to compute IV'
*/
KeyParameter encryptionKey = new KeyParameter(maskedKey);
f8Cipher.init(true, encryptionKey);
/*
* Use the masked key 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
Arrays.fill(f8ctx.S, (byte) 0);
int inLen = len;
while (inLen >= BLKLEN) {
processBlock(aesCipher, f8ctx, data, off, data, off, BLKLEN);
inLen -= BLKLEN;
off += BLKLEN;
}
if (inLen > 0) {
processBlock(aesCipher, 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
*
* @param aesCipher the cipher
* @param f8ctx
* F8 encryption context
* @param in
* byte array holding the data to be processed
* @param inOff
* start offset of the data to be processed inside in array
* @param out
* byte array that will hold the processed data
* @param outOff
* start offset of output data in out
* @param len
* length of the input data
*/
private static void processBlock(AESFastEngine aesCipher, F8Context f8ctx,
byte[] in, int inOff, byte[] out, int outOff, int len) {
/*
* XOR the previous key stream with IV'
* ( S(-1) xor IV' )
*/
for (int i = 0; i < BLKLEN; i++) {
f8ctx.S[i] ^= f8ctx.ivAccent[i];
}
/*
* Now XOR (S(n-1) xor IV') with the current counter, then increment
* the counter
*/
f8ctx.S[12] ^= f8ctx.J >> 24;
f8ctx.S[13] ^= f8ctx.J >> 16;
f8ctx.S[14] ^= f8ctx.J >> 8;
f8ctx.S[15] ^= f8ctx.J >> 0;
f8ctx.J++;
/*
* Now compute the new key stream using AES encrypt
*/
aesCipher.processBlock(f8ctx.S, 0, f8ctx.S, 0);
/*
* As the last step XOR the plain text with the key stream to produce
* the cipher text.
*/
for (int i = 0; i < len; i++) {
out[outOff + i] = (byte) (in[inOff + i] ^ f8ctx.S[i]);
}
}
}
/*
* SIP Communicator, the OpenSource Java VoIP and Instant Messaging client.
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*
* Some of the code in this class is derived from ccRtp's SRTP implementation,
* which has the following copyright notice:
*
Copyright (C) 2004-2006 the Minisip Team
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package net.java.sip.communicator.impl.neomedia.transform.srtp;
import java.util.*;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
/**
* SRTPCipherF8 implements SRTP F8 Mode AES Encryption (AES-f8).
* F8 Mode AES Encryption algorithm is defined in RFC3711, section 4.1.2.
*
* Other than Null Cipher, RFC3711 defined two two encryption algorithms:
* Counter Mode AES Encryption and F8 Mode AES encryption. Both encryption
* algorithms are capable to encrypt / decrypt arbitrary length data, and the
* size of packet data is not required to be a multiple of the AES block
* size (128bit). So, no padding is needed.
*
* Please note: these two encryption algorithms are specially defined by SRTP.
* They are not common AES encryption modes, so you will not be able to find a
* replacement implementation in common cryptographic libraries.
*
* As defined by RFC3711: F8 mode encryption is optional.
*
* mandatory to impl optional default
* -------------------------------------------------------------------------
* encryption AES-CM, NULL AES-f8 AES-CM
* message integrity HMAC-SHA1 - HMAC-SHA1
* key derivation (PRF) AES-CM - AES-CM
*
* We use AESCipher to handle basic AES encryption / decryption.
*
* @author Bing SU (nova.su@gmail.com)
*/
public class SRTPCipherF8
{
/**
* AES block size, just a short name.
*/
private final static int BLKLEN = 16;
/**
* F8 mode encryption context, see RFC3711 section 4.1.2 for detailed
* description.
*/
class F8Context
{
public byte[] S;
public byte[] ivAccent;
long J;
}
public static void process(BlockCipher cipher, byte[] data, int off, int len,
byte[] iv, byte[] key, byte[] salt, BlockCipher f8Cipher) {
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').
*/
byte[] saltMask = new byte[key.length];
byte[] maskedKey = new byte[key.length];
/*
* First copy the salt into the mask field, then fill with 0x55 to get a
* full key.
*/
System.arraycopy(salt, 0, saltMask, 0, salt.length);
for (int i = salt.length; i < saltMask.length; ++i) {
saltMask[i] = 0x55;
}
/*
* XOR the original key with the above created mask to get the special
* key.
*/
for (int i = 0; i < key.length; i++) {
maskedKey[i] = (byte) (key[i] ^ saltMask[i]);
}
/*
* Prepare the f8Cipher with the special key to compute IV'
*/
KeyParameter encryptionKey = new KeyParameter(maskedKey);
f8Cipher.init(true, encryptionKey);
/*
* Use the masked key 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
Arrays.fill(f8ctx.S, (byte) 0);
int inLen = len;
while (inLen >= BLKLEN) {
processBlock(cipher, f8ctx, data, off, data, off, BLKLEN);
inLen -= BLKLEN;
off += BLKLEN;
}
if (inLen > 0) {
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
*
* @param f8ctx
* F8 encryption context
* @param in
* byte array holding the data to be processed
* @param inOff
* start offset of the data to be processed inside in array
* @param out
* byte array that will hold the processed data
* @param outOff
* start offset of output data in out
* @param len
* length of the input data
*/
private static void processBlock(BlockCipher cipher, F8Context f8ctx,
byte[] in, int inOff, byte[] out, int outOff, int len) {
/*
* XOR the previous key stream with IV'
* ( S(-1) xor IV' )
*/
for (int i = 0; i < BLKLEN; i++) {
f8ctx.S[i] ^= f8ctx.ivAccent[i];
}
/*
* Now XOR (S(n-1) xor IV') with the current counter, then increment
* the counter
*/
f8ctx.S[12] ^= f8ctx.J >> 24;
f8ctx.S[13] ^= f8ctx.J >> 16;
f8ctx.S[14] ^= f8ctx.J >> 8;
f8ctx.S[15] ^= f8ctx.J >> 0;
f8ctx.J++;
/*
* Now compute the new key stream using AES encrypt
*/
cipher.processBlock(f8ctx.S, 0, f8ctx.S, 0);
/*
* As the last step XOR the plain text with the key stream to produce
* the cipher text.
*/
for (int i = 0; i < len; i++) {
out[outOff + i] = (byte) (in[inOff + i] ^ f8ctx.S[i]);
}
}
}

@ -143,12 +143,12 @@ public class SRTPCryptoContext
/**
* The symmetric cipher engines we need here
*/
private AESFastEngine AEScipher = null;
private BlockCipher cipher = null;
/**
* Used inside F8 mode only
*/
private AESFastEngine AEScipherF8 = null;
private BlockCipher cipherF8 = null;
/**
* implements the counter cipher mode for RTP according to RFC 3711
@ -248,7 +248,6 @@ public SRTPCryptoContext(long ssrcIn, int rocIn, long kdr,
.getSaltKeyLength());
mac = new HMac(new SHA1Digest());
AEScipher = new AESFastEngine();
switch (policy.getEncType()) {
case SRTPPolicy.NULL_ENCRYPTION:
@ -256,13 +255,23 @@ public SRTPCryptoContext(long ssrcIn, int rocIn, long kdr,
saltKey = null;
break;
case SRTPPolicy.AESF8_ENCRYPTION:
AEScipherF8 = 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.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;
}
@ -358,11 +367,13 @@ public void setROC(int rocIn) {
public void transformPacket(RawPacket pkt)
{
/* Encrypt the packet using Counter Mode encryption */
if (policy.getEncType() == SRTPPolicy.AESCM_ENCRYPTION)
if (policy.getEncType() == SRTPPolicy.AESCM_ENCRYPTION ||
policy.getEncType() == SRTPPolicy.TWOFISH_ENCRYPTION)
{
processPacketAESCM(pkt);
}
else if (policy.getEncType() == SRTPPolicy.AESF8_ENCRYPTION)
else if (policy.getEncType() == SRTPPolicy.AESF8_ENCRYPTION ||
policy.getEncType() == SRTPPolicy.TWOFISHF8_ENCRYPTION)
{
/* Encrypt the packet using F8 Mode encryption */
processPacketAESF8(pkt);
@ -439,12 +450,14 @@ public boolean reverseTransformPacket(RawPacket pkt)
}
/* Decrypt the packet using Counter Mode encryption*/
if (policy.getEncType() == SRTPPolicy.AESCM_ENCRYPTION) {
if (policy.getEncType() == SRTPPolicy.AESCM_ENCRYPTION ||
policy.getEncType() == SRTPPolicy.TWOFISH_ENCRYPTION) {
processPacketAESCM(pkt);
}
/* Decrypt the packet using F8 Mode encryption*/
else if (policy.getEncType() == SRTPPolicy.AESF8_ENCRYPTION) {
else if (policy.getEncType() == SRTPPolicy.AESF8_ENCRYPTION ||
policy.getEncType() == SRTPPolicy.TWOFISHF8_ENCRYPTION) {
processPacketAESF8(pkt);
}
@ -482,7 +495,7 @@ public void processPacketAESCM(RawPacket pkt) {
final int payloadOffset = pkt.getHeaderLength();
final int payloadLength = pkt.getPayloadLength();
cipherCtr.process(AEScipher, pkt.getBuffer(), pkt.getOffset() + payloadOffset,
cipherCtr.process(cipher, pkt.getBuffer(), pkt.getOffset() + payloadOffset,
payloadLength, ivStore);
}
@ -508,8 +521,8 @@ public void processPacketAESF8(RawPacket pkt) {
final int payloadOffset = pkt.getHeaderLength();
final int payloadLength = pkt.getPayloadLength();
SRTPCipherF8.process(AEScipher, pkt.getBuffer(), pkt.getOffset() + payloadOffset,
payloadLength, ivStore, encKey, saltKey, AEScipherF8);
SRTPCipherF8.process(cipher, pkt.getBuffer(), pkt.getOffset() + payloadOffset,
payloadLength, ivStore, encKey, saltKey, cipherF8);
}
/**
@ -609,14 +622,14 @@ public void deriveSrtpKeys(long index) {
computeIv(label, index);
KeyParameter encryptionKey = new KeyParameter(masterKey);
AEScipher.init(true, encryptionKey);
cipherCtr.getCipherStream(AEScipher, encKey, policy.getEncKeyLength(), ivStore);
cipher.init(true, encryptionKey);
cipherCtr.getCipherStream(cipher, encKey, policy.getEncKeyLength(), ivStore);
// compute the session authentication key
if (authKey != null) {
label = 0x01;
computeIv(label, index);
cipherCtr.getCipherStream(AEScipher, authKey, policy.getAuthKeyLength(), ivStore);
cipherCtr.getCipherStream(cipher, authKey, policy.getAuthKeyLength(), ivStore);
switch ((policy.getAuthType())) {
case SRTPPolicy.HMACSHA1_AUTHENTICATION:
@ -635,11 +648,11 @@ public void deriveSrtpKeys(long index) {
// compute the session salt
label = 0x02;
computeIv(label, index);
cipherCtr.getCipherStream(AEScipher, saltKey, policy.getSaltKeyLength(), ivStore);
cipherCtr.getCipherStream(cipher, saltKey, policy.getSaltKeyLength(), ivStore);
// As last step: initialize AES cipher with derived encryption key.
// As last step: initialize cipher with derived encryption key.
encryptionKey = new KeyParameter(encKey);
AEScipher.init(true, encryptionKey);
cipher.init(true, encryptionKey);
}
/**

@ -34,13 +34,17 @@ public class SRTPPolicy
*/
public final static int AESF8_ENCRYPTION = 2;
/**
* F8 Mode TwoFish Cipher
*/
public final static int TWOFISHF8_ENCRYPTION = 4;
/**
* Null Authentication, no authentication
*/
public final static int NULL_AUTHENTICATION = 0;
/**
* HMC SHA1 Authentication, defined in Section 4.2.1, RFC3711
* HAMC SHA1 Authentication, defined in Section 4.2.1, RFC3711
*/
public final static int HMACSHA1_AUTHENTICATION = 1;

Loading…
Cancel
Save