[asterisk-dev] AstriDevCon Recap - IAX2 RENEW for encryption

Russell Bryant russell at digium.com
Thu May 31 09:14:47 MST 2007


Greetings,

One of the topics discussed at the developer conference was the method 
used for IAX2 encryption.  We wanted to ensure that the method we are 
using is actually secure.  I have summarized what came out of the 
discussion below.  Comments are welcome, as always.

 From this discussion, we need to make two changes.  One is an 
implementation issue, and the other is a protocol level issue.  The 
protocol level issue needs to get resolved quickly so that we can get it 
in the first version of the RFC, since IAX2 encryption is in there.

1) We should use a better random number generator.  Most of the places 
in Asterisk are using the ast_random() wrapper, so changing the method 
in one place should affect every usage.

Currently, we use random(), which is better than rand(), but we seed it 
with the process ID and time.  We should just change the code to open 
and read from /dev/urandom where it is available.

2) This issue is related to the key used for encryption.  Here is a 
basic rundown on how it works right now:

a)  ====== NEW =====> (not encrypted)

A NEW packet is sent to initiate a call, and this message contains the 
ENCRYPTION information element to indicate which methods of IAX2 
encryption are supported for this call.

b) <===== AUTHREQ ===== (not encrypted)

An AUTHREQ is sent to request authentication for the call.  In this 
message, there are two information elements related to encryption for 
the call.

The first is the ENCRYPTION information element.  If this is present, it 
contains a single encryption method that the peer has agreed to use for 
the call (Currently, only AES128 is defined for use).

The other is the CHALLENGE information element.  This contains random 
data.  The encryption key that both sides will begin using is the MD5 
hash of this challenge and the shared secret.

c) ====== AUTHREP =====> (encrypted)

This message is sent with the authentication credentials as normal. 
However, it is encrypted with the key generated by taking the MD5 hash 
of the CHALLENGE and the shared secret.

If the incorrect key is used, the other side will get invalid data when 
it tries to decrypt this message.

d) ... Rest of the call ... (encrypted)

Now, here is where a change needs to be made.  Once the call is 
established, there is no way to change the key being used.  An 
information element, ENCKEY has been defined for containing a new 
encryption key, but there is no message that this information element 
can be sent in.  To resolve this, we can do the following:

Add a new IAX message type, RENEW, that can be sent during a call.  If a 
RENEW is received during an encrypted call and contains the ENCKEY 
information element, immediately change the key used to decrypt the 
traffic coming from the other side to use this key.

A RENEW can be explicitly acknowledged by a peer using an ACK, or it can 
be implicitly acknowledged by the peer sending its own RENEW.  Also, it 
should be noted as a best practice to send a RENEW as soon as the call 
is established, as well as every few minutes.  (I chose a few minutes 
here arbitrarily.  If you have more insight into what would be a good 
choice here, please let me know!)

e) Transfers

Transfers are a more complicated situation.  The current RFC draft does 
not address how to handle transfers involving encrypted sessions.  Here 
is what we came up with for this.

First of all, a transfer should not even be attempted unless both legs 
involved in the transfer are using the same encryption method.

When a TXREL or TXMEDIA is sent to release the entire stream or just the 
media, it should contain the ENCKEY information element.  The key sent 
here will be the key that the peer should use to decrypt the packets 
received from the other end of the call.

-- 
Russell Bryant
Software Engineer
Digium, Inc.


More information about the asterisk-dev mailing list