Oh, I forgot to cc it. ;-p
---------- Forwarded message ----------
From: Bing Su <firstname.lastname@example.org>
Date: Jun 21, 2007 4:22 AM
Subject: Re: [sip-comm-dev] [gsoc] SRTP work status update
To: Werner Dittmann <Werner.Dittmann@t-online.de>
Your comments are fantastic!
In fact I was a little confused by some details of SRTP these days. I
wanted to solve them by reading RFCs, wikis and other project's codes.
But after reading your mail, I found many of my efforts could be
Thank you for your help, Werner.
On 6/21/07, Werner Dittmann <Werner.Dittmann@t-online.de> wrote:
just my thoughts here regarding SRTP and associated stuff:
After looking at JMF and its RTP implementation I would
also use some sort of RTPConnector to implement SRTP because,
as Su wrote, SRTP is a transformation of existing RTP packets.
How to do that? My rough ideas here:
- define and implement a class that can handle SRTP packtes,
probably a superset of RTP (if a RTP class exists in JMF, haven't
checked this, otherwise a brand new class). In GNU ccRTP I just
added some functions to IncomingRTPPacket and OutgoingRTPPacket
classes that control encryption/decryption (protect/unprotect) of
AFAIK, the handling of RTP packet in JMF is done by some classes
hidden deeply in the library's implementation. Though JMF has a SCSL
licensed source zip, the RTP related source code are unavailable -
only interfaces are provided. So, perhaps the only way to intercept
RTP packet is to use RTPConnector.
- define and implement a SRTP Crypto Context class (you may have
a look at the CryptoContext C++ class in GNU ccRTP). This
class stores all necessary SRTP crypto context data as per
RFC3711 and contains the necessary crypto, hash, replay
detection, and HMAC functions.
Thank you again, Werner. I used to look at libsrtp's srtp_stream_ctx_t
structure, but didn't realize the importance of "crypto context"
concept. Now I think this class should be the key class of SRTP
implementation. My previous design was to put all these data in a self
"SRTPTransformEngine" class, which is unique for each RTPManager. But
obviously, the data should be kept in CryptoContext class. Because one
RTPManager could handle mutiple RTP streams, and each stream will have
one set of data, thus one CryptoContext object.
- before an application can use SRTP the app has to create a
SRTP CryptoContext and intialize it with necessary data, such
as master key, master salt, authentication length, etc. The
application must provide this CryptoContext to the SRTP
transformation. It is the task of the application to negotiate
the keys and other data with its peer. Usually the application
has to create 2 CryptoContexts: one to send and one to receive
You mean the one send stream, one receive stream scenario, am I right?
The pure SRTP implementation is IMHO fairly straight forward .
Be aware that SRTP uses its own encryption modes: a specific
Integer Counter Mode (ICM) and a so called F8 mode. Both modes are
AFAIK not available in generic crypto libraries such a BouncyCastle
or alike. The ICM is commonly used (somewhere I have a F8
implementation in Java). It should be quite simple to copy the
counter mode code from C++ to Java.
Oh, this is part of my confusion.
Wikipedia says SRTP is using Segmented Integer Counter Mode.
bouncy castle has a Segmented Integer Counter Cipher class,
SICBlockCipher. I took a look at its code, its algorithm seems
different from the one implemented in libsrtp. If I'm right, then
which one shall we use, the SICBlockCipher or libsrtp's algorithm?
Maybe I shall have take a look at ccRtp's implementation and RFC3711.
Then make this clear.
In contrast to libsrtp which uses own (or copied) AES, SHA1
implementations I would propose to use the basic AES
crypto algorithm (simple AES codebook mode because the counter mode
is done by SRTP itself) and the SHA1 either using BouncyCastle or
the standard Java JCE implementation - both work for this purpose.
Sure, we don't need to reinvent the wheel.
The real hard part is the key and parameter negotiation. Currently
two (three) ways are common:
- MIKEY which uses SIP/SDP and signed X.509 cerificates to negotiate
- ZRTP which does not use any certificate, does not depend on SIP or
any other signaling protocol.
- DTLS-SRTP which depends on:
- TLS (DTLS) with a specific extension,
- self-signed certificates and the
- SIP Identity service (RFC4474)
to negotiate keys.
The current state is: MIKEY seems to be out of the game; ZRTP is
available, also in several products; DTLS-SRTP is discussed as the
proposed IETF standard to SRTP key negotiation (it will take some time
to get there), ZRTP will be an informational RFC.
DTLS-SRTP is IMO insecure by design because it opens several attack
vectors and is also somewhat hard to use for real P2P applications such
as P2PSIP (attention: I'm biased here in favour of ZRTP). If you need
more information about the vulnerabilities of DTLS-SRTP or ZRTP just
give me a ping.
I'm not aware of the key management protocols until recently. So I
don't have a clear thought on this. I did a little research, it seems
that ZRTP has some benefits: it supports Forking, Media-before-SDP,
and does not depend on the signaling protocol or PKI. From wikipedia,
I see "Ekiga, Twinkle and Asterisk also implement ZRTP and are
available under GPL. X-Lite and eyeBeam implement ZRTP but are
And there is a comparison PPT on various key management protocols:
I think we should have more discussion regarding which key management
protocol we will use.
Sending a packet (the "write" part):
- create a SRTP object and parse the "data" byte array into this
object to initialize it. Have getter/setter methods for
required data fields, such as SSRC etc.
I think I will have this done in SRTPTransformEngine. And it will have
a table for mapping SSRC to CryptoContext. When new rtp streams are
added, we shall create corresponding CryptoContexts and update the
- get the SSRC of the RTP packet and check if a crypto context is
available for this SSRC (crypto contexts are identified using SSRC).
This is done using the mapping table.
- If no crypto context is available just send the data without
any modification (pure RTP).
- otherwise encrypt the data and compute the authentication HMAC.
The authentication HMAC is the only data field that is usually
added (recommended) to the plain RTP data. SRTP does not extend
RTP data otherwise, it just encrypts the data (payload).
- serialize the encrypted data again, including optional HMAC
authentication data, and send it as usual using UDP.
Receiving a packet (the "read" part):
- similar to write, just the other way around: get the SSRC of
the incoming RTP data (RTP header is not encrypted) and check
if a crypto context is available.
- if yes, perform SRTP processing to perform authentication, replay
check, and decrypt it. The return the data.
Thank you, Werner.
Your detailed thoughts make me more clear about what I am going to do.
Su, if you like to discuss in more detail I'm glad to do so.
I surely like to discuss more about SIP Communicator's SRTP
implementation with you as this project goes on. Your experience is
invaluable to me.
Romain KUNTZ wrote:
> Hi Werner,
> I'm glad to hear we have someone with a strong experience in SRTP
> implementation! Su Bing is currently working on RTP Encryption for SIP
> Communicator as part of a Google Summer of Code project. He regularly
> reports his work on this ML, so feel free to jump into the discussion. I
> guess he'll be happy to hear from you.
> Thanks for the pointers,
> On 2007/06/19, at 18:52, Werner Dittmann wrote:
>> just jumping in here. Regarding SRTP I'm not aware of any Java
>> implementation. But it may help to look at a C++ implementation.
>> I've done (together with code from the minisip project) SRTP
>> implementation in GNU ccRTP library. The C++ code is tested against
>> the C implementation libsrtp.
>> Also available in the GNU ccRTP is an implememtation of ZRTP, a
>> protocol specified by Phil Zimmermann to enable key negotiation
>> for SRTP (for some later stage ).
>> As crypto libraries the SRTP implementation uses openSSL or
>> libgcrypt. Just as a side note: I've done a project inside
>> Apache (in the incubator) called JuiCE, an implementation of
>> a Java JCE that uses openSSL as its backend crypto engine.
>> I'm not actively involved in development of SIP communicator,
>> but I would be available to help during a Java implementation of
>> SRTP etc.
>> Jean Lorchat wrote:
>>> Hi Su,
>>>> I am looking at some reference implementation -- in fact, in JCE and
>>>> bouncy castle, they have their abstraction. But that would be much
>>>> more complicated than we would need. So, I think maybe I can borrow a
>>>> subset of their abstraction and then define ours.
>>> Also, do not try to rewrite something already done. If bouncycastle/JCE
>>> is too big, we can solve this later. I think the most interesting part
>>> is to get it to work first. Also, you say that we do not need such
>>> complications. Is it because we plan to begin with simple ciphers, or do
>>> you mean that we will never need large parts of these abstractions ?
>>>>>> 3. NULL Transform is simply copy the input data into the output
>>>>>> buffer. So, this work is done within minutes.
>>>>> OK. I am still curious to see the code. Do you think you'd be able to
>>>>> publish some of it one of these days?
>>>> Yes, they are in the attachments. If there is any problem, please tell
>>>> I'm wondering if my understanding is correct, because from wikipedia,
>>>> I know there two
>>>> definitions of Null Cipher. (http://en.wikipedia.org/wiki/Null_cipher)
>>>> But in libsrtp, their implementation is simply leave the plain text
>>>> untouched, i.e. my current "copy" implementation.
>>> Yes, this is what we mean in this project. Null cipher as "no cipher at
>>> all", how secure !
>>> Keep up the good work !
>>> To unsubscribe, e-mail: email@example.com
>>> For additional commands, e-mail: firstname.lastname@example.org
>> To unsubscribe, e-mail: email@example.com
>> For additional commands, e-mail: firstname.lastname@example.org
> --Romain KUNTZ
> Louis Pasteur University - Networks and Protocols Team
> To unsubscribe, e-mail: email@example.com
> For additional commands, e-mail: firstname.lastname@example.org
To unsubscribe, e-mail: email@example.com
For additional commands, e-mail: firstname.lastname@example.org