Paul,
my answers in the usual style included inline below.
With kind regards
Martin Euchner. ----------------------------------------------------------------------- | Dipl.-Inf. Rapporteur Q.G/SG16 | Martin Euchner Phone: +49 89 722 55790 | Siemens AG.....................Fax : +49 89 722 47713 | ICN M SR 3 mailto:Martin.Euchner@icn.siemens.de | mailto:martin.euchner@ties.itu.int | Hofmannstr. 51 Intranet: http://intranet.icn.siemens.de/marketing/cs27/topics/security/ | D-81359 Muenchen Internet: http://www.siemens.de/ | __________________ | Germany -----------------------------------------------------------------------
-----Original Message----- From: Paul Long [mailto:plong@packetizer.com] Sent: Thursday, August 22, 2002 3:58 AM To: ITU-SG16@echo.jf.INTEL.COM Cc: Euchner Martin ICN M SR 3 Subject: Re: Flaws in H.235 media encryption
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@echo.jf.intel.com Cc: Euchner Martin ICN M SR 3 Subject: Flaws in H.235 media encryption
[snip]
- 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?
MEU:> To be precise, Annex D requires a key refresh at some point in time (upper bound for expired key as given in your citation), but does not actually mandate the exact method (it is a MAY) and other methods than described (like replacementFor, close/reopen) could be applied as well. Nevertheless, key update is a good practice in those cases, where the key has been compromised or is believed having been compromised; this could happen far before the key actually expires. Such situations might arise anytime but clearly are an issue of security policy how to handle. As you assumed, key update for voice would rarely occur under realistic situations as far as voice telephony is concerned. Annex E.2 conveys a tiny footnote giving an example how long a key may be used for a particular voice codec: "key-update for secure G.711 speech coding should occur latest after transmission of 2**30 64-bit blocks, that's more than 12 days of ongoing conversation.". As it becomes apparent, that turns out to be a pretty long time for ongoing secure conversation; and thus, the key update method probably is not implemented as a high priority feature. Let me note however, that the key refresh period depends on the codec and the amount of transmitted traffic, thus, the situation for video may be completely different than for G.711 voice.
[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).
MEU:> ok agreed. We need such a mechanism.
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.
MEU:> I can agree to this basically. I'm not fully convinced if it is a good idea to use the synchFlag as a "transaction id"; mainly for the reason, that I believe that the dyn. PT is not guaranteed to be unique over a set of logical channels (outgoing or incoming).
So you are saying that the encryptionUpdate should also be used as an ACK from the slave to the master?
I can see another alternative assuming the each entity knows the LCNs of the peer and is able to associate them to the channels (for the originating channels that should be true anyway, but also for the reverse channels), namely:
a) to use the LCN field in the MiscelleaneousCommand, b) enhance the encryptionSync with the master/slave CHOICE structure as you proposed, c) let the master apply his/her LCN for the logical channel in the direction master->slave, let the master apply the slave LCN for the logical channel in the direction slave-> master d) let the slave acknowledge an encryptionUpdate by another encryptionUpdate (acting as encryptionUpdateAck) or preferably use a separate encryptionUpdateAck for that purpose, e) the slave reflects the received LCN (indicating master or slave choice) in the ACK.
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), ... },
MEU:> Using a separate ACK command appears clean and understandable for everyone and avoids the overloaded use of encryptionUpdate. Thus, for the sake of clarity, if would prefer such a solution unless H.245 blow-up is a concern.
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. :-)
MEU:> ok, I see that my assumption is a bit far fetched. ;-)
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.
MEU:> Ok I recognize that you don't like replacementFor procedure for purpose of key update for understandable reasons. So I agree, a better solution is required.
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.
MEU: correct. That's what I found as well. Still, I believe that the time to wait has to be guessed due to some criteria (e.g. network delay etc). So that solution appears to have similar problems as H.235.
- 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.
MEU:> correct. We could make those extensions optional and allow the use only for the purpose for key update, but otherwise prohibit the use of the key update extensions.
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, ... }
MEU:> This sounds fine!
and add this to the type CHOICE of the MiscellaneousCommand type:
encryptionUpdateCommand SEQUENCE { encryptionSync EncryptionSync, direction EncryptionUpdateDirection, ... }
MEU:> ok (or have this CHOICE be part of encryptionSync).
The request type would be extended thusly:
EncryptionUpdateRequest ::=SEQUENCE { keyProtectionMethod KeyProtectionMethod OPTIONAL, ..., direction EncryptionUpdateDirection OPTIONAL, }
MEU:> ok; agreed.
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.
MEU: ok.
[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.
MEU:> ok let's forget about replacementFor; it was never made actually for key update, so we cannot expect a perfect solution here.
- 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 }
MEU:> I'm missing the master/slave direction choice here....
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.
MEU:> I fully agree, I should have said "indicated" instead of proposed.
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)) - - -
MEU:> Paul, I'm not certain, if I fully understand what you're saying here, or for what that is exactly good for. Let me ask: is it to avoid that there might be some sort of race condition such that two key update events overlap: one key update issued by the master to the slave for a slave-to-master logical channel while at the same time the slave requests a new key from for that particular channel from the master? This appears as a tricky situation...
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.
MEU:> ok we should do that. Any suggestions, proposals?
In any way: I see that we are converging in the same direction and soon agree on a common solution :)
So this calls action for me as editor. I think that I/we should write down all this in a contribution and fix it, making the method clear, and further include the stuff in H.235 and highlight the H.245 changes for Mike Nilsson (H.245 editor). If you want I would be pleased to make this a joint contribution between IPdialoge (?) and Siemens. What do you think?
Paul
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For help on this mail list, send "HELP ITU-SG16" in a message to listserv@lists.intel.com