comments inline (and boy are they long this time)
> Paul,
>
> first of all: thanks to the very good and detailed observations
pointing out
> some problematic issues with H.235 key update. As I argue below,
items #2
> and #3 hit a weak point and should be corrected in some fashion and
> documented. I consider item #1 less critical (but let's see).
> Second: sorry for the long delay, but I was quite busy with other
things and
> emails...
>
> Generally, I would like to point out that using the replacementFor
mechanism
> should thwart against all three problems; but please my more detailed
> comments and answers below.
>
>
>
> With kind regards
>
>
> Martin Euchner.
[snip]
>
> -----Original Message-----
> From: Paul Long [mailto:plong@packetizer.com]
> Sent: Monday, August 12, 2002 7:39 PM
> To: itu-sg16(a)echo.jf.intel.com
> Cc: Euchner Martin ICN M SR 3
> Subject: Flaws in H.235 media encryption
>
[snip]
> 1. After distributing a new key via an encryptionUpdate command for a
> master-to-slave RTP stream, how long should the master wait before
> transmitting packets with the new payload type? The problem is that
> packets with the new payload type (and therefore using the new key)
may
> arrive before the encryptionUpdate command that tells the slave what
> payload-type/key pair to expect! There are three solutions as I see
it:
> A. The slave discards new packets until the encryptionUpdate
> command arrives.
> B. The master uses prior network behavior to predict when the
slave
> will receive the command and then waits so that packets using the new
> payload type will (hopefully) arrive sometime after that. The slave
> should still implement A because this prediction is imprecise.
> C. We require a three-way handshake by adding an
> encryptionUpdateAck command for master-to-slave streams (would be
> redundant for slave-to-master streams). This would be backwards
> compatible because existing implementations would simply ignore this
> new command which is sent from slave to master.
>
> A and B are local workarounds; C is the ultimate solution. Discarding
> packets is especially problematic for video because video compression
> schemes rely on inter-packet dependencies. I believe H.233 anticipated
> this problem by providing a codepoint in H.245 to define how long the
> transmitter must wait before using the new key. H.235 also needs
> something to address this problem, preferably C.
>
> MEU:> In general, I agree that this might be a problem. However, in
> practice, situation should not be that worse.
> First of all, question is, if you really need encryptionUpdate. For
what
> I've heard so far is, that for secure IPVoiceTelephony,
encryptionUpdate can
> probably be omitted (but for video the situation may be different).
PL:> But the Voice Encryption Security Profile requires re-key:
D.7.2/H.235v2: "The key refresh rate shall be such that no more than 2
[^]32 blocks are encrypted using the same key." Besides this
requirement, I just thought that re-keying was good practice in
general, but I'm new to the field of security. What is best practice
for this and what are the considerations? Hmmm... doing some quick
calculations, it looks like it could take at least a few years to reach
2^32 blocks. Is your point that, since most calls don't last months or
years, it's probably okay not to ever re-key?
[snip (A and B sound okay)]
> Your solution C with a 3-way handshake acknowledging the reception of
the
> new key appears as a robust solution.
PL:> So that we don't have to add another codepoint to the H.245 ASN.1
syntax tree, I suppose we could require, starting with H.235v3, that
the slave echo back the encryptionUpdate command for a master-to-slave
logical channel (the master would never otherwise receive this
message). The synchFlag would act as a transaction id so that the
master would know which of its encryptionUpdate commands this was in
response to. The master would ignore the ack's h235Key field.
Otherwise, we should add an encryptionUpdateAck component to the type
CHOICE of the MiscellaneousCommand type. It would look like this:
encryptionUpdateAck SEQUENCE { synchFlag INTEGER(0..255), ... },
> However, assuming that H.245 is being transported over TCP/IP, there
should
> be an implicit acknowledge (at the TCP layer) for issued
encyptionUpdate.
> Couldn't that information be helpful to the master in deciding when
to apply
> the new key?
PL:> Remember that TCP is a streaming protocol, so I doubt whether
there is any way to know whether a particular sequence of bytes, e.g.,
a TPKT, has been received at the far end. Even if there were, I doubt
whether all TCP implementations would provide this mechanism.
Therefore, we cannot rely on the transport layer to ack receipt of the
new key. Nice try, though. :-)
> Instead of introducing a new handshake, using replacementFor by
opening a
> new logical channel with a new key and then closing down the former
channel
> should provide a reliable means for key update. That way, the problem
should
> be covered.
PL:> That would sort of work. It also has the benefit of not having to
change the RTP payload type for the new logical channel.
There are disadvantages, however:
1. H.235 requires the use of encryptionUpdate (11.1/H.235v2: "After
receiving an encryptionUpdateRequest, a master shall send out
encryptionUpdate.").
2. replacementFor requires a LOT more signaling, i.e.,
OLC/OLCAck/CLC/CLCAck.
3. Possible (effective) packet loss if the first packet of the new
channel arrives before the last packet of the old channel, thereby
possibly causing noticeable media artifact or delay.
4. Requires twice the resources temporarilly while the two logical
channels overlap, e.g., two sockets.
5. Overall increased complexity.
We would basically be trading the lack of synchronicity between the
control channel and the media logical channel for the lack of
synchronicity between two media logical channels. I vote, no.
> Regarding H.233 mechanism, I wasn't able to identify such a mechanism
as
> claimed (I'm not even sure that H.233 features a key update method).
PL:> You are correct--H.233 does not re-key, but it does have an
analogous mechanism to update the initialization vector. H.324 added
the codepoint, h233IVResponseTime, to H.245 to express how long the
transmitter should wait between transmitting a new IV and transmitting
frames based on that IV. This is what I was referring to.
> 2. H.235 says that "[the slave, acting as] a receiver (or transmitter)
> may request a new key [from the master]" and "The master may also
> decide asynchronously to distribute new key(s)." However, there is no
> codepoint in either the encryptionUpdate or encryptionUpdateRequest
> command to indicate whether it refers to a slave-to-master or master-
to-
> slave RTP stream. The MiscellaneousCommand.logicalChannelNumber field
> is no help either because its values are assigned independently by
each
> transmitter--both EPs may be using the same LCN.
>
> MEU:> It is correct that the key update works in both directions:
either the
> master distributes a new key or the slave requests a new key from the
> master.
> I fear that you discovered a valid problem here that deserves some
fix. As
> you said it is ambiguous for the slave to which LC the
encryptionUpdate
> actually refers to.
> Thus, we will have to consider some solution; e.g., by adding
a "direction
> flag" in encryptionUpdateRequest.... (apart from some semantical
description
> that should appear in H.235v3 and IG).
PL:> Yeah, we gotta fix this. Unfortunately, encryptionUpdate does not
have a type of its own that we can extend. We would have to extend the
EncryptionSync type, but this is used in other contexts where the
extensions would have no meaning. The alternative is to add a new
codepoint that obsoletes encryptionUpdate. We would define a new
direction type, e.g.,
EncryptionUpdateDirection ::=CHOICE
{
masterToSlave NULL,
slaveToMaster NULL,
...
}
and add this to the type CHOICE of the MiscellaneousCommand type:
encryptionUpdateCommand SEQUENCE
{
encryptionSync EncryptionSync,
direction EncryptionUpdateDirection,
...
}
The request type would be extended thusly:
EncryptionUpdateRequest ::=SEQUENCE
{
keyProtectionMethod KeyProtectionMethod OPTIONAL,
...,
direction EncryptionUpdateDirection OPTIONAL,
}
> Nevertheless, would it help if one
> may assume that the allocated logical channel numbers at the peer
side are
> known? This information should at least be available in principle at
the
> endpoints from monitoring the OpenLogicalChannel and
CloseLogicalChannel
> commends.
PL:> The problem is not that LCNs are not know--they are all indeed
know by both sides--but that they are ambiguous.
[snip]
> As it is, IMO, key resynchs should not be attempted for channels that
> have the same LCN; however, that would be difficult for equipment from
> the same vendor because, depending on the LCN-assignment scheme, the
> same values may always be used.
>
> MEU:> I hope that the solution that we figure out would not prohibit
this
> case.
>
> Again as above, replacementFor when applied would allow key update
without
> the identified problem.
PL:> No, there are four re-key scenarios, and replacementFor would only
address the one where the master asynchronously updates the key for a
master-to-slave logical channel. Plus, there are the general problems
that I pointed out, above, with the replacementFor solution.
> 3. When the master sends an encryptionUpdate command, it specifies the
> new dynamic payload type, or DPT, in the synchFlag field; however,
this
> presents problems for a slave-to-master stream because the transmitter
> otherwise manages its own DPTs.
[snip]
> MEU:> I agree that this appears a problem that should be fixed as
well. One
> potential solution could be that the slave provides a proposed new
dynamic
> PT for the LC (to be added in EncryptionUpdateRequest).
PL:> I like that a lot. So I suppose this is what we'd have:
EncryptionUpdateRequest ::=SEQUENCE
{
keyProtectionMethod KeyProtectionMethod OPTIONAL,
...,
synchFlag INTEGER(0..255) OPTIONAL -- New PT component
}
I would prefer that we _require_ the master to use the PT provided by
the slave and that this value therefore not be a _proposed_ PT. I
simply see no reason to allow this kind of flexibility in the master.
Then there is the issue of the master asynchronously updating the key
for a slave-to-master logical channel. To be consistent, I would prefer
that we have the master request the PT from the slave. We could hi-jack
the encryptionUpdateRequest command for this because it otherwise isn't
conveyed from master to slave. The master in effect requests that the
slave request a new key from it. We would move from the current dialog:
slave master
<- encryptionUpdate(1, 97, AES(sharedSecretKey, sessionKey2))
<- - - RTP(96, AES(sessionKey1, payload)) - - -
<- - - RTP(97, AES(sessionKey2, payload)) - - -
to this one (I also included the proposed Ack, discussed above):
slave master
<- encryptionUpdateRequest(1)
encryptionUpdateRequest(1, sharedSecret, 97) ->
<- encryptionUpdate(1, 97, AES(sharedSecretKey, sessionKey2))
<- - - RTP(96, AES(sessionKey1, payload)) - - -
encryptionUpdateAck(97) ->
<- - - RTP(97, AES(sessionKey2, payload)) - - -
More signaling and another (inconsequential) round-trip delay, but it
would be bullet-proof. No conflicts, no synch problems. In the mean
time, we should at least identify the possibility of a conflict in the
current standard and suggest how to deal with it.
Paul
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For help on this mail list, send "HELP ITU-SG16" in a message to
listserv(a)lists.intel.com