Re: Flaws in H.235 media encryption
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
Dear Mr. Euchner,
This is for your information.
At 17:16 +0200 02/08/23, Euchner Martin ICN M SR 3 wrote:
[...] 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. [...]
In the H.320 system, the encryption control signal and the media to be encrypted are transmitted in the same H.221 framed channel, while in the H.323 system they are transmitted in separate channels (H.245 and RTP). H.233 Initialization Vector is transmitted in one or more blocks of H.221 ECS (Encryption Control Signal) having a 160 msperiod (H.221 multiframe = 10 ms x 16 frames), and takes effect from the start of the next multiframe as described in Section 5.1.3/H.233. The operation is synchronous, thus we need no guess for the time to wait.
Best regards,
OKUBO Sakae e-mail: okubo@giti.waseda.ac.jp ******************************************************************* YRP Office Global Information and Telecommunication Institute (GITI) Waseda University YRP Ichibankan 312 Tel: +81 468 47 5406 3-4 Hikarinooka, Yokosuka-shi, Kanagawa-ken Fax: +81 468 47 5413 239-0847 Japan
GITI Headquarter 29-7 Waseda University Bldg. Tel: +81 3 5286 3831 1-3-10 Nishi-Waseda, Shinjuku-ku, Tokyo Fax: +81 3 5286 3832 169-0051 Japan *******************************************************************
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For help on this mail list, send "HELP ITU-SG16" in a message to listserv@lists.intel.com
comments inline; not too long; concern #3 of mine isn't really a problem so I nuked it altogether
Paul,
my answers in the usual style included inline below.
[snip]
MEU:> [snip] key update is a good practice in those cases, where the key has been compromised or is believed having been compromised;
PL:> I don't understand this. How could such a thing happen? How could I detect that my security has been compromised? Sounds like such a bizarre, obscure thing that I should never worry about it.
[snip]
[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).
PL:> Good point. PT is typically but not necessarilly different. Bad idea.
So you are saying that the encryptionUpdate should also be used as an ACK from the slave to the master?
PL:> Yes.
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,
PL:> I see three ways to do this. 1. add an OPTIONAL "direction" component to encryptionSync, like you suggest, 2. define a complete replacement for encryptionUpdate, e.g,. encryptionUpdateCommand, that contains encryptionSync and a "direction" component (and is extensible while we're at it), and 3. add an OPTIONAL "direction" component to the outer level of MiscellaneousCommand. I like #3 the best but don't know if we will be able to add something so high up in the H.245 syntax tree to basically fix a bug. What do you think?
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.
PL:> I could go either way about using encryptionUpdate for the Ack or defining a new command. I guess this is what an Ack would look like: encryptionUpdateAck SEQUENCE { synchFlag INTEGER(0..255), direction EncryptionUpdateDirection, ... }, (The relevant LCN is at the outer level of MiscellaneousCommand, so it's not shown here.) We need synchFlag because we could theoretically have multiple outstanding encryptionUpdate commands for the same LCN but each with a new, different PT. This is a typical exchange using these codepoints:
slave master <- encryptionUpdate(1, 97, AES(sharedSecretKey, sessionKey2), masterToSlave) <- - - RTP(96, AES(sessionKey1, payload)) - - - encryptionUpdateAck(1, 97, masterToSlave) -> <- - - RTP(97, AES(sessionKey2, payload)) - - -
[snip: we agree on adding a "direction" codepoint]
- 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]
PL:> Forget this whole PT-conflict thing. It's not a problem. I was somehow thinking that PTs we like LCNs in that they had to be unique across an EP's outgoing channels. This is simply not true. Sorry for propagating the confusion.
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).
[snip]
PL:> Yeah, I could help.
PL:> BTW, I just realized that H.235 media privacy conflicts with other schemes that also manipulate PT. For example, Cisco inserts PT=13 into their audio streams for a proprietary silence frame (I think this is based on an expired I-D). Also, RFC2833 multiplexes packets for, e.g., DTMF in the audio stream based on PT. Since H.235 assumes that the PT would otherwise be the same throughout a stream, it simply won't work for these and possibly other upcoming PT-manipulation schemes. We need to consider another media-privacy mechanism for these cases, e.g., maintain the original PT by saving it in the RTP payload. Bummer.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For help on this mail list, send "HELP ITU-SG16" in a message to listserv@lists.intel.com
participants (3)
-
Euchner Martin ICN M SR 3
-
OKUBO Sakae
-
Paul Long