Subject: [Perc] Question on diet Design?

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Mar 2017 14:48:17 -0700

I've read this document and I'm finding it hard to understand the
basic design. Ignoring all the details, we have a node i which
connects to the Key Distributor (KD), and we want to establish a
shared key for each node i = 0, 1, ... n (this is just to establish
E2E keys. I'm ignoring HBH keys for now). So, as I read it, the system
works like this.

- Node i connects to KD and establishes a DTLS connection which establishes
  a pairwise key K_d_i.
- The KD then generates a fresh EKT key K_e_i and sends it to i encrypted
  under K_d_i.
- The KD then generates a shared group key K_g and sends it individually
  to all i in SRTP/EKT encrypted under K_e_i.

Is that correct so far?

If so, my question is why you need K_e_i? You have already established
a shared secret via the DTLS connection and you can make as many fresh
pairwise encryption keys as you want from that, so why do you need
to make a new encryption key K_e_i and send it from KD to i?

-Ekr

---

From: "Paul E. Jones" <[email-masked]>
Date: Tue, 21 Mar 2017 23:48:31 +0000

Ekr,

For each endpoint, a HBH key is established using DTLS-SRTP (RFC 5764) 
procedures via an association established between the endpoint and key 
distributor.  Those procedures are (mostly) unaltered from the 
endpoint's perspective and independent of EKT.   The only aspect that is 
"alternated" is that, since we're using a "double" cipher, half of the 
bits generated for the HBH key are discarded (as they're not used).  In 
the framework document, this is referred to as Key(j).  For simplicity 
in keeping your notation below, let's call this K_h.  This is the SRTP 
master key. There is also an SRTP master salt S_h created via the 
DTLS-SRTP procedures.

Over that DTLS association, the key distributor will send an "EKTKey" 
message containing the conference key (what you called the group key, 
K_g).  The same conference key is given to each endpoint in the 
conference.  In the same message, an SRTP master salt S_g is provided by 
the key distributor.

As the "EKTKey" message is transmitted to the endpoint, the values {K_h, 
S_h} are delivered to the media distributor via the tunnel protocol.

At this point, the endpoint has {K_h, S_h, K_g, S_g} and the media 
distributor has {K_h, S_h}.  For every endpoint i, the K_h and S_h 
values differ.

Each endpoint then manufacturers a random SRTP master key E_i used for 
E2E encryption.  The endpoint then generates the various keys for RTP 
encryption, RTP authentication, RTCP encryption, and RTCP authentication 
using the KDF defined in RFC 3711 from the pair {E_i, S_g}.  This 
produces k_e, k_a, k_s (Section 4.3.1 of RFC 3711).  Since we will have 
these for both E2E and HBH, let's suffix whese with _e (for E2E).  So, 
we'll have K_e_e.

The endpoint then generates the various keys for RTP encryption, RTP 
authentication, RTCP encryption, and RTCP authentication using the KDF 
defined in RFC 3711 from the pair {K_h, S_h}.  As above, we'll have k_e, 
k_a, k_s, which let's suffix as k_e_h (for HBH).

The endpoint then performs these steps:
   1) encrypts the RTP packet using the keys derived via the KDF for E2E, 
K_e_e and salt k_s_e.
   2) encrypts the RTP packet using the keys derives via the KDF for HBH, 
namely K_e_h and k_s_h.

The EKT field is then added to the end of the packet.  If it's the 
"short EKT field", it has no keying material inside. It would just be a 
single 0 octet.

The long EKT field is used periodically to allow the endpoint to 
transmit E_i to other endpoints.  The plaintext of this field is 
constructed and then encrypted using AESKeyWrap(K_g, ekt_field).  The 
ciphertext is then appended to the packet, along with a few plaintext 
fields indicating the field type and length.

As the media distributor receives the packet, it removes the EKT field, 
then decrypts the packet using the keys derived from {K_h,S_h}.  It then 
re-encrypts the packet using {K_h',S_h'} (where ' denotes the HBH keys 
shared with the endpoint to which the media distributor intends to 
forward the packet) and then attached the EKT field to the end 
untouched.

Upon receipt of the packet, the receiving endpoint first processes the 
EKT field.  It decrypts the field using K_g.  It extracts the SRTP 
master key E_i.  It already has S_g via the EKTKey message from its own 
exchange with the key distributor.   So, using its own HBH keying 
material {K_h',S_h'} and the E2E keying material {E_i,S_g}, it can 
perform HBH and E2E decryption of the packet.

I hope that helps.  As you can see, EKT plays a very limited role in the 
overall architecture.  We're still very much relying on DTLS-SRTP 
procedures and on standard SRTP procedures.  Juggling all these keys is 
certainly confusing, though.  I guess a pretty picture showing all the 
pieces would be useful.

Paul

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Mar 2017 17:04:14 -0700

On Tue, Mar 21, 2017 at 4:48 PM, Paul E. Jones <[email-masked]>
wrote:

> distributor.  Those procedures are (mostly) unaltered from the endpoint's
> perspective and independent of EKT.   The only aspect that is "alternated"
> is that, since we're using a "double" cipher, half of the bits generated
> for the HBH key are discarded (as they're not used).  In the framework
> document, this is referred to as Key(j).  For simplicity in keeping your
> notation below, let's call this K_h.  This is the SRTP master key. There is
> also an SRTP master salt S_h created via the DTLS-SRTP procedures.
>

Let's ignore salts for now. I'd also like to ignore all the hop-by-hop
keys, because I'm
primarily concerned with the e2e keys.

> distributor has {K_h, S_h}.  For every endpoint i, the K_h and S_h values
> differ.
>
> Each endpoint then manufacturers a random SRTP master key E_i used for E2E
> encryption.  The endpoint then generates the various keys for RTP
> using the KDF defined in RFC 3711 from the pair {E_i, S_g}.  This produces
> k_e, k_a, k_s (Section 4.3.1 of RFC 3711).  Since we will have these for
> both E2E and HBH, let's suffix whese with _e (for E2E).  So, we'll have
> K_e_e.
>
> The EKT field is then added to the end of the packet.  If it's the "short
> EKT field", it has no keying material inside. It would just be a single 0
> octet.
>
> The long EKT field is used periodically to allow the endpoint to transmit
> E_i to other endpoints.  The plaintext of this field is constructed and
> then encrypted using AESKeyWrap(K_g, ekt_field).  The ciphertext is then
> appended to the packet, along with a few plaintext fields indicating the
> field type and length.
>

I'm going to stop here, because I think this is the relevant point, that I
had misunderstood
and I want to summarize looking just at the E2E portion.

1. You start out with every agent i having a pairwise key K_d_i (the DTLS
traffic key) with the
KD.

2. The KD then generates a single shared key K_g which it provides to each
agent i under
K_d_i (in DTLS).

2. Each agent then generates its own transmission key E_i which it
transmits to everyone
under K_g.

Do I have this right?

If so, my question is. Why? In particular, why can't we use K_g directly to
encrypt SRTP
packets (i.e., as one ginormous SRTP session). I am assuming your answer
here is going
to be that then if you have SSRC collisions then we get two-time pad [0]?
If not, then
is there some other reason I am missing?

-Ekr

[0] If so, I have another way to address this.

> shared with the endpoint to which the media distributor intends to forward
> the packet) and then attached the EKT field to the end untouched.
>
> Upon receipt of the packet, the receiving endpoint first processes the EKT
> field.  It decrypts the field using K_g.  It extracts the SRTP master key
> E_i.  It already has S_g via the EKTKey message from its own exchange with
> the key distributor.   So, using its own HBH keying material {K_h',S_h'}
> and the E2E keying material {E_i,S_g}, it can perform HBH and E2E
> decryption of the packet.
>

---

From: "Paul E. Jones" <[email-masked]>
Date: Wed, 22 Mar 2017 00:35:32 +0000

Ekr,

>>encryption, RTP authentication, RTCP encryption, and RTCP 
>>authentication using the KDF defined in RFC 3711 from the pair {E_i, 
>>S_g}.  This produces k_e, k_a, k_s (Section 4.3.1 of RFC 3711).  Since 
>>we will have these for both E2E and HBH, let's suffix whese with _e 
>>(for E2E).  So, we'll have K_e_e.
>>
>>defined in RFC 3711 from the pair {K_h, S_h}.  As above, we'll have 
>>k_e, k_a, k_s, which let's suffix as k_e_h (for HBH).
>>
>>   1) encrypts the RTP packet using the keys derived via the KDF for 
>>E2E, K_e_e and salt k_s_e.
>>   2) encrypts the RTP packet using the keys derives via the KDF for 
>>HBH, namely K_e_h and k_s_h.
>>
>>"short EKT field", it has no keying material inside. It would just be 
>>a single 0 octet.
>>
>I'm going to stop here, because I think this is the relevant point, 
>that I had misunderstood
>1. You start out with every agent i having a pairwise key K_d_i (the 
>DTLS traffic key) with the
>KD.

Yea, but the key is only used for DTLS exchanges, so independent of 
anything SRTP related (except for the DTLS-SRTP key derivation for HBH 
that you wanted to ignore for now).

>2. The KD then generates a single shared key K_g which it provides to 
>each agent i under
>K_d_i (in DTLS).

Correct.

>2. Each agent then generates its own transmission key E_i which it 

Yes, that's correct.

>If so, my question is. Why? In particular, why can't we use K_g 
>directly to encrypt SRTP
>packets (i.e., as one ginormous SRTP session). I am assuming your 
>answer here is going
>to be that then if you have SSRC collisions then we get two-time pad 
>[0]? If not, then

Avoiding the one-time pad is a primary concern, but not the only issue.  
A secondary issue is that in a conferencing environment where each 
sender is transmitting independently, endpoints need to be able to 
synchronize the crypto context of the sender.  The ROC value is conveyed 
in the EKT field, which facilitates this synchronization.  (The ROC for 
the HBH encryption always starts at 0, so no synchronization is 
required.  But, the ROC for any transmitted flow in an existing 
conferencing might be any value.  So, EKT carries the E2E cipher and the 
ROC for that flow.)

>[0] If so, I have another way to address this.

Assuming we could still convey the ROC in the clear (it's not really 
secret), then I'd like to hear your suggestion.

I'll note that there was an alternative some time ago 
(draft-mcgrew-srtp-aero), but that work did not progress.  Since I 
wasn't involved, I do not know why.  Perhaps because it moved away from 
SRTP and defining an SRTP replacement would have been a pretty high 
barrier?

Paul

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 21 Mar 2017 17:56:40 -0700

On Tue, Mar 21, 2017 at 5:35 PM, Paul E. Jones <[email-masked]>
wrote:

> anything SRTP related (except for the DTLS-SRTP key derivation for HBH that
> you wanted to ignore for now).
>

Well, you're using it to encipher K_g. Right now, I'm primarily concerned
with the key hierarchy
and not which specific protocol is being used.

> If so, my question is. Why? In particular, why can't we use K_g directly
> to encrypt SRTP
> Avoiding the one-time pad is a primary concern, but not the only issue.  A
> secondary issue is that in a conferencing environment where each sender is
> transmitting independently, endpoints need to be able to synchronize the
> crypto context of the sender.  The ROC value is conveyed in the EKT
> field, which facilitates this synchronization.  (The ROC for the HBH
> encryption always starts at 0, so no synchronization is required.  But, the
> ROC for any transmitted flow in an existing conferencing might be any
> value.  So, EKT carries the E2E cipher and the ROC for that flow.)
>
>

Replace EKT with a fixed block consisting of:

1. A centrally assigned endpoint ID [you need this to avoid two-time pad]
2. The ROC (if needed)

The per-sender key then can be computed as KDF(K_g, ID) [0]. Note that you
don't need to
send this block that frequently, you can use the same algorithm you use for
EKT, though it's
also pretty small, so maybe easier to just send all the time.

I haven't been thinking about this for very long, so I could of course have
something grievously
wrong and insecure, in which people should point and laugh. One potential
concern is
that an attacker can send some incredibly large ROC and thus cause you to
crank the KDF
forward a zillion times. I believe that currently anyone who has K_g can do
this, so requiring
this block to be MACed with K_g should address this problem.

-Ekr

[0] Note, this assumes I am remembering how the ROC works, which, IIRC, is
just that it tells you which generation of SRTP keys to derive from the
master.

---

From: "Paul E. Jones" <[email-masked]>
Date: Wed, 22 Mar 2017 17:42:46 +0000

Ekr,

>The per-sender key then can be computed as KDF(K_g, ID) [0]. Note that 
>you don't need to
>send this block that frequently, you can use the same algorithm you use 
>for EKT, though it's
>I haven't been thinking about this for very long, so I could of course 
>have something grievously
>wrong and insecure, in which people should point and laugh. One 
>potential concern is
>that an attacker can send some incredibly large ROC and thus cause you 
>to crank the KDF
>forward a zillion times. I believe that currently anyone who has K_g 
>can do this, so requiring

I think what you propose would work, but each stream from a given 
endpoint would need to have a unique key since we do not want the any 
two media flows using the same key. Thus, I think we'd need:
   KDF(K_g, ID || stream_id)

The ID, steam_id, and ROC values would need to be conveyed in the RTP 
packet (or RTCP packet -- though I'd prefer to try to avoid putting such 
info into RTCP) to ensure that the receiver gets the information it 
needs to decrypt the flow.  So, it's not clear that there is an 
advantage to this approach.  The size of the EKT field might be smaller, 
but we could make it smaller now if we wanted (removing extensibility 
and length fields).

Perhaps I'm missing an important advantage?

Paul

---

From: Eric Rescorla <[email-masked]>
Date: Wed, 22 Mar 2017 11:33:59 -0700

On Wed, Mar 22, 2017 at 10:42 AM, Paul E. Jones <[email-masked]>
wrote:

> forward a zillion times. I believe that currently anyone who has K_g can
> do this, so requiring
> I think what you propose would work, but each stream from a given endpoint
> would need to have a unique key since we do not want the any two media
> flows using the same key. Thus, I think we'd need:

The SSRC addresses that, no?

-Ekr

> info into RTCP) to ensure that the receiver gets the information it needs
> to decrypt the flow.  So, it's not clear that there is an advantage to this
> approach.  The size of the EKT field might be smaller, but we could make it
> smaller now if we wanted (removing extensibility and length fields).
>

---

From: "Paul E. Jones" <[email-masked]>
Date: Thu, 23 Mar 2017 04:42:07 +0000

Eric,

>The SSRC addresses that, no?

Yeah, SSRC is fine for that.  We just need to ensure it is a part of the 
KDF input.

Paul

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 23 Mar 2017 04:12:51 -0700

It's part of the SRTP KDF.

-Ekr

---

From: "Paul E. Jones" <[email-masked]>
Date: Thu, 23 Mar 2017 23:31:09 +0000

Ekr,

The SSRC is used in the IV when encrypting packets, but not directly in 
the KDF to derive k_e, k_a, or k_s.  That said, that will avoid the 
two-time pad problem.

Current guidance is that a given key should not be used more than 2^48 
times.  By how much would having 1,000 participants in a conference 
sending a total of 2,000 media flows using keys derived from the same 
K_g reduce key lifetime?

I'm still struggling with the overall benefit, though.  With both, we 
have a need to exchange keying material, thus a need for DTLS-SRTP + EKT 
(or other) procedures.

With EKT, an endpoint sends its SRTP master key and ROC  periodically.  
AES_Keywrap() doesn't have to be called on every packet, since the 
ciphertext is static.  Other than the size of the EKT field (which we 
could reduce and which is only sent periodically), it doesn't seem like 
a burden.

What you're proposing will require assignment of a unique participant 
identifier (which we can do over the DTLS tunnel) and sending that ID 
and the ROC periodically in packets.

It seems roughly the same in terms of complexity, with the K_g approach 
(ID || ROC) perhaps using slightly fewer bits on the wire compared to 
the the EKT field.

I'd like to hear others weigh in on pros/cons.  I don't want to send 
negative signals if others favor this approach.  Other than my question 
on key lifetime impact, the K_g approach seems fine.

Paul

------ Original Message ------
From: "Eric Rescorla" <[email-masked]>
To: "Paul E. Jones" <[email-masked]>
Cc: [email-masked]
Sent: 3/23/2017 7:12:51 AM
Subject: Re: [Perc] Question on diet Design?

>>>>endpoint would need to have a unique key since we do not want the 
>>>>any two media flows using the same key. Thus, I think we'd need:
>>Yeah, SSRC is fine for that.  We just need to ensure it is a part of 
>>the KDF input.
>>
>>Paul
>

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 23 Mar 2017 16:45:27 -0700

> the KDF to derive k_e, k_a, or k_s.  That said, that will avoid the

Sure, my mistake. In any case, it's not a problem for multiple SSRCs.

> times.  By how much would having 1,000 participants in a conference sending
> a total of 2,000 media flows using keys derived from the same K_g reduce
> key lifetime?
>

These are totally unrelated. The guidance is about the lifetime of a single
GCM key, not about
the keying material from which it was derived.

I'm still struggling with the overall benefit, though.  With both, we have
> a need to exchange keying material, thus a need for DTLS-SRTP + EKT (or
> other) procedures.
>
> ciphertext is static.  Other than the size of the EKT field (which we could
> reduce and which is only sent periodically), it doesn't seem like a burden.
>
> identifier (which we can do over the DTLS tunnel) and sending that ID and
> the ROC periodically in packets.
>
> (ID || ROC) perhaps using slightly fewer bits on the wire compared to the
> the EKT field.
>
> negative signals if others favor this approach.  Other than my question on
> key lifetime impact, the K_g approach seems fine.
>

Well, at the moment, I'm just trying to understand what the current design
is supposed
to achieve, and that means getting clear on what keying material you are
trying to
establish.

In that process, I am seeing some things that make me sad in particular;

- Having two key transport phases, which is pretty hard to wrap your head
around,
though perhaps it's just a writing issue.
- Grabbing a DTLS code point (why can't you just shove this in the
application data),
so I'm trying to remove that [0].

So I'm trying to push on what's really needed.

-Ekr

[0] I concede that what I wrote above doesn't do that, but reducing the
number of
key wrap phases might let us do so, for instance by carrying K_g in EKT.

>>> endpoint would need to have a unique key since we do not want the any two
>>> media flows using the same key. Thus, I think we'd need:

---

From: Cullen Jennings <[email-masked]>
Date: Sat, 25 Mar 2017 15:32:22 -0500

EKT was deployed and shipped before the PERC WG was started. It was easy to reuse it from an implementation point of view and it remains useful for conferencing even without PERC or DTLS-SRTP because it allows the conference server to move all the participants to same same key to reduce outbound encryption load. 

The other issue driving the design is scheduling when to use keys. We can't easily synchronize when key changes happen, but we can make sure that everyone gets the intermedia key over DTLS and waits a few seconds before they start using it. That way they know everyone has likely received it before thy start using it. 

> On Mar 23, 2017, at 6:45 PM, Eric Rescorla <[email-masked]> wrote:
> 
> 
> 
> On Thu, Mar 23, 2017 at 4:31 PM, Paul E. Jones <[email-masked] <mailto:[email-masked]>> wrote:
> Ekr,
> 
> The SSRC is used in the IV when encrypting packets, but not directly in the KDF to derive k_e, k_a, or k_s.  That said, that will avoid the two-time pad problem.
> 
> Current guidance is that a given key should not be used more than 2^48 times.  By how much would having 1,000 participants in a conference sending a total of 2,000 media flows using keys derived from the same K_g reduce key lifetime?
> 
> These are totally unrelated. The guidance is about the lifetime of a single GCM key, not about
> I'm still struggling with the overall benefit, though.  With both, we have a need to exchange keying material, thus a need for DTLS-SRTP + EKT (or other) procedures.
> 
> With EKT, an endpoint sends its SRTP master key and ROC  periodically.  AES_Keywrap() doesn't have to be called on every packet, since the ciphertext is static.  Other than the size of the EKT field (which we could reduce and which is only sent periodically), it doesn't seem like a burden.
> 
> What you're proposing will require assignment of a unique participant identifier (which we can do over the DTLS tunnel) and sending that ID and the ROC periodically in packets. 
> 
> It seems roughly the same in terms of complexity, with the K_g approach (ID || ROC) perhaps using slightly fewer bits on the wire compared to the the EKT field.
> 
> I'd like to hear others weigh in on pros/cons.  I don't want to send negative signals if others favor this approach.  Other than my question on key lifetime impact, the K_g approach seems fine.
> 
> Well, at the moment, I'm just trying to understand what the current design is supposed
> to achieve, and that means getting clear on what keying material you are trying to
> establish. 
> 
> - Having two key transport phases, which is pretty hard to wrap your head around,
> - Grabbing a DTLS code point (why can't you just shove this in the application data),
> [0] I concede that what I wrote above doesn't do that, but reducing the number of
> From: "Eric Rescorla" <[email-masked] <mailto:[email-masked]>>
> To: "Paul E. Jones" <[email-masked] <mailto:[email-masked]>>
> Cc: [email-masked] <mailto:[email-masked]>
>> On Wed, Mar 22, 2017 at 9:42 PM, Paul E. Jones <[email-masked] <mailto:[email-masked]>> wrote:
>> Eric,
>> 
>>> I think what you propose would work, but each stream from a given endpoint would need to have a unique key since we do not want the any two media flows using the same key. Thus, I think we'd need:
>> Yeah, SSRC is fine for that.  We just need to ensure it is a part of the KDF input.
>> 
>> Paul
>> 
> 
> _______________________________________________
> Perc mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/perc