Subject: [AVTCORE] AES-GCM SRTP (RFC 7714) KDF implementation

From: "Paul E. Jones" <[email-masked]>
Date: Fri, 05 Aug 2016 03:45:08 +0000

AVT,

There are now at least two implementation of RFC 7714 and at least two 
interpretations of how to treat the master salt value when used with in 
KDF.  So that we can ensure consistent implementation, it was suggested 
that I bring this issue to the WG.

The issue has to do with the salt length and the KDF.  As you know, RFC 
3711 uses AES-CM for the KDF and assumes an initial SRTP master salt 
that is 14 octets in length (see section 5.3/RFC3711).  AES-GCM, though, 
utilizes a 12 octet salt value.

We have this when AES-CM is used (example taken from RFC 3711) with a 14 
octet salt:

index DIV kdr: 000000000000 label: 02 master salt: 
0EC675AD498AFEEBB6960B3AABE6 
----------------------------------------------- xor: 
0EC675AD498AFEE9B6960B3AABE6 (x, PRF input)

This value is then multiplied by 2^16 per 4.3.3/RFC3711 (i.e., pad zeros 
on the right) to produce a 16-octet salt value that is then used in the 
AES-CM KDF logic.

When the 12 octet salt used in AES-GCM is provided, libsrtp 
(https://github.com/cisco/libsrtp) will assume that zeros are padded on 
the right to produce a 14-octet salt value (to get the default master 
salt length needed per section 5.3).  Thus, assuming a salt value of 
0EC675AD498AFEEBB6960B3A, these steps are performed:

index DIV kdr: 000000000000 label: 02 master salt: 
0EC675AD498AFEEBB6960B3A0000 (two padding octets on the right) 
----------------------------------------------- xor: 
0EC675AD498AFEE9B6960B3A0000 (x, PRF input)

Again, this value is then multiplied by 2^16 per 4.3.3/RFC3711 (i.e., 
pad zeros on the right) to produce a 16-octet salt value that is then 
used in the AES-CM KDF logic.

However, there is a statement in 4.3.1/RFC3711 that says "Let x = key_id 
XOR master_salt, where key_id and master_salt are aligned so that their 
least significant bits agree (right-alignment)."  That might suggest 
that the XOR should have been performed without padding as shown above 
and as implemented in libsrtp.

If padding on the right was the wrong thing to do, that would mean that 
the XOR step using the initial 12 octet AES-GCM salt should have been 
this:

index DIV kdr: 000000000000 label: 02 master salt: 
0EC675AD498AFEEBB6960B3A ------------------------------------------- 
xor: 0EC675AD4988FEEBB6960B3A (x, PRF input)

Then the x*2^16 operation that then follows as per 4.3.3/RFC3711 would 
result in:
0EC675AD4988FEEBB6960B3A0000

However, this is only a 14 octet value and we need 16 octets for the 
AES-CM KDF (which was the reason the step in 4.3.3 exists for the 
default 14 octet salt).  Thus, we are short two octets.

We either need to pad the initial 12 octet AES-GCM input salt at the 
start in some way to form the expected 14 octet salt value expected per 
section 5.3 (the approach taken by libsrtp), or we need additional 
padding after the above x*2^16 step (e.g., introduce a second x*2^16 
step).

Given that at least two implementers interpreted the specs differently, 
I think it would be of benefit to discuss this in the WG and document 
the proper behavior.

Paul

---

From: "Cullen Jennings (fluffy)" <[email-masked]>
Date: Sat, 20 Aug 2016 13:29:16 +0000

Ekr, Martin, 

Any thoughts on this ?

Thanks

> On Aug 4, 2016, at 9:45 PM, Paul E. Jones <[email-masked]> wrote:
> 
> AVT,
> 
> There are now at least two implementation of RFC 7714 and at least two interpretations of how to treat the master salt value when used with in KDF.  So that we can ensure consistent implementation, it was suggested that I bring this issue to the WG.
> 
> The issue has to do with the salt length and the KDF.  As you know, RFC 3711 uses AES-CM for the KDF and assumes an initial SRTP master salt that is 14 octets in length (see section 5.3/RFC3711).  AES-GCM, though, utilizes a 12 octet salt value.
> 
> We have this when AES-CM is used (example taken from RFC 3711) with a 14 octet salt:
>  
>       index DIV kdr:                 000000000000
>       label:                       02
>       master salt:   0EC675AD498AFEEBB6960B3AABE6
>       -----------------------------------------------
>       xor:           0EC675AD498AFEE9B6960B3AABE6     (x, PRF input)
> 
>  
> This value is then multiplied by 2^16 per 4.3.3/RFC3711 (i.e., pad zeros on the right) to produce a 16-octet salt value that is then used in the AES-CM KDF logic.
> 
> When the 12 octet salt used in AES-GCM is provided, libsrtp (https://github.com/cisco/libsrtp) will assume that zeros are padded on the right to produce a 14-octet salt value (to get the default master salt length needed per section 5.3).  Thus, assuming a salt value of 0EC675AD498AFEEBB6960B3A, these steps are performed:
>  
>       index DIV kdr:                 000000000000
>       label:                       02
>       master salt:   0EC675AD498AFEEBB6960B3A
> 0000
>      (two padding octets on the right)
>       -----------------------------------------------
>       xor:           0EC675AD498AFEE9B6960B3A0000     (x, PRF input)
> 
>  
> Again, this value is then multiplied by 2^16 per 4.3.3/RFC3711 (i.e., pad zeros on the right) to produce a 16-octet salt value that is then used in the AES-CM KDF logic.
> 
> However, there is a statement in 4.3.1/RFC3711 that says "Let x = key_id XOR master_salt, where key_id and master_salt are aligned so that their least significant bits agree (right-alignment)."  That might suggest that the XOR should have been performed without padding as shown above and as implemented in libsrtp.
>  
> If padding on the right was the wrong thing to do, that would mean that the XOR step using the initial 12 octet AES-GCM salt should have been this:
>  
>       index DIV kdr:             000000000000
>       label:                   02
>       master salt:   0EC675AD498AFEEBB6960B3A
>       -------------------------------------------
> Then the x*2^16 operation that then follows as per 4.3.3/RFC3711 would result in:
> However, this is only a 14 octet value and we need 16 octets for the AES-CM KDF (which was the reason the step in 4.3.3 exists for the default 14 octet salt).  Thus, we are short two octets.
> 
> We either need to pad the initial 12 octet AES-GCM input salt at the start in some way to form the expected 14 octet salt value expected per section 5.3 (the approach taken by libsrtp), or we need additional padding after the above x*2^16 step (e.g., introduce a second x*2^16 step).
> 
> Given that at least two implementers interpreted the specs differently, I think it would be of benefit to discuss this in the WG and document the proper behavior.
> 
> Paul
> _______________________________________________
> Audio/Video Transport Core Maintenance
> [email-masked]
> https://www.ietf.org/mailman/listinfo/avt

---

From: Martin Thomson <[email-masked]>
Date: Mon, 22 Aug 2016 16:54:27 +1000

I've just concluded that I don't understand RFC 7714.  That is either
because I'm too frazzled to think today, or because it's awful.  I
think that there's a good slice of tired, but I'm also fairly certain
that 7714 is horrendous.  It doesn't even use the same terminology as
RFC 3711.  It doesn't even use the AES-GCM (the thing defined in RFC
5116).

How did you even conclude that AES-GCM needed a 14 octet salt?  I
think that I would have concluded that it has a 12 octet salt.

---

From: "Paul E. Jones" <[email-masked]>
Date: Mon, 22 Aug 2016 08:38:21 -0400

Martin,

RFC 7714 uses a 12 octet salt, but this same same salt must be used in AES-CM as part of the KDF.  RFC 3711 assumes the input master salt for AES-CM is a 14 octet salt that is then transformed into a 16 octet salt used by the KDF.

Somehow, that 12 octet salt in RFC 7714 needs to be transformed into a 16 octet value, too, for use in the AES-CM based KDF.  What's missing are those steps, so different implementers made different assumptions to ultimately arrive at the needed 16 octets.

I think some guidance is needed in RFC 7714, since it defines a 12 octet salt and RFC 3711 assumes an input salt of 14 octets in length.

Paul

---

From: Martin Thomson <[email-masked]>
Date: Wed, 24 Aug 2016 10:43:56 +1000

Why is the same value being used as input to two different ciphers.
That sounds like it could be a very bad idea.

On 22 August 2016 at 22:38, Paul E. Jones <[email-masked]> wrote:
> Martin,
>
> RFC 7714 uses a 12 octet salt, but this same same salt must be used in
> AES-CM as part of the KDF. RFC 3711 assumes the input master salt for AES-CM
> is a 14 octet salt that is then transformed into a 16 octet salt used by the
> KDF.
>
> Somehow, that 12 octet salt in RFC 7714 needs to be transformed into a 16
> octet value, too, for use in the AES-CM based KDF. What's missing are those
> steps, so different implementers made different assumptions to ultimately
> arrive at the needed 16 octets.
>
> I think some guidance is needed in RFC 7714, since it defines a 12 octet
> salt and RFC 3711 assumes an input salt of 14 octets in length.
>
> Paul
>
> ________________________________
>>>  On Aug 4, 2016, a!
>>>  t 9:45
>>> PM, Paul E. Jones <[email-masked]> wrote:
>>>
>>>  AVT,
>>>
>>> interpretations of how to treat the master salt value when used with in KDF.
>>> So that we can ensure consistent implementation, it was suggested that I
>>> bring this issue to the WG.
>>>
>>> 3711 uses AES-CM for the KDF and assumes an initial SRTP master salt that is
>>> 14 octets in length (see section 5.3/RFC3711).  AES-GCM, though, utilizes a
>>> 12 octet salt value.
>>>
>>> ________________________________
>>>
>>>  This value is then multiplied by !
>>>  2^16 per
>>> 4.3.3/RFC3711 (i.e., pad zeros on the right) to produce a 16-octet salt
>>> value that is then used in the AES-CM KDF logic.
>>>
>>> (https://github.com/cisco/libsrtp) will assume that zeros are padded on the
>>> right to produce a 14-octet salt value (to get the default master salt
>>> length needed per section 5.3).  Thus, assuming a salt value of
>>> ________________________________
>>>
>>> pad zeros on the right) to produce a 16-octet salt value that is then used
>>> in the AES-CM KDF log!
>>>  ic.
>>>
>>> least significant bits agree (right-alignment)."  That might suggest that
>>> the XOR should have been performed without padding as shown above and as
>>> implemented in libsrtp.
>>>
>>> the XOR step using the initial 12 octet AES-GCM salt should have been this:
>>>
>>> ________________________________
>>>
>>> AES-CM KDF (which was the reason the step in 4.3.3 exis!
>>>  ts for
>>> the default 14 octet salt).  Thus, we are short two octets.
>>>
>>> section 5.3 (the approach taken by libsrtp), or we need additional padding
>>> after the above x*2^16 step (e.g., introduce a second x*2^16 step).
>>>
>>> I think it would be of benefit to discuss this in the WG and document the
>>> proper behavior.
>>>
>>>  Paul
>>> ________________________________
>>>

---

From: "Paul E. Jones" <[email-masked]>
Date: Wed, 24 Aug 2016 01:53:50 +0000

Martin,

The same value is not used.  SRTP takes as input a master key and master 
salt.  Those values are given to a Key Derivation Function (KDF) that 
produces session encryption and salting keys.

The KDF is defined to be AES-CM.  To use AES-CM, we need the encryption 
key and a salt that is 16 octets in length.  This is where the issue 
arises and is the subject of this email thread.

RFC 3711 assumes a default salt length of 14 octets.  It specifies how 
to manipulate the salt so that it is unique for each type of key and 
salt we wish to create via the KDF.  Specifically, the master salt is 
XORed with a unique "key_id".  The salt is then padded with 2 zero 
octets on the right, forming a 16-octet value that is unique for each 
key type.

RFC 7714 specified a salt length of 12 octets.  And that's where the 
problem comes in.

One implementer padded that 12 octet salt with two zero octets on the 
right to form a 14 octet value.  Then the usual RFC 3711 procedures were 
followed.

The other implementer took the salt value given, performed the XOR step, 
then padded two zero octets on the right or left.  I don't recall which 
was done, but it's immaterial.  Both will work, but neither are 
specified.

Then both implementers padded two zero octets on the right per Section 
4.3.3 of RFC 3711 to get the required 16 octets.

So, the only issue we have is the fact that the salt length specified in 
RFC 7714 is two octets short of what we need to use the salt properly 
with the procedures defined in RFC 3711.  Two additional octets are 
needed and we need to decide where and when to add them.   We have 
several ways to fix it.  Starting with the 12 octet salt:
   1. Pad with two zero octets on the left before XORing the salt with 
the key_id
   2. Pad with two zero octets on the right before XORing the salt with 
the key_id (libsrtp behavior)
   3. Pad with two zero octets on the left after XORing the salt with the 
key_id
   4. Pad with two zero octets on the right after XORing the salt with 
the key_id
   5. Pad with any other values before or after or in between to get to 
14 octets.

Paul

------ Original Message ------
From: "Martin Thomson" <[email-masked]>
To: "Paul E. Jones" <[email-masked]>
Cc: "Cullen Jennings (fluffy)" <[email-masked]>; "Eric Rescorla" 
<[email-masked]>; "[email-masked]" <[email-masked]>
Sent: 8/23/2016 8:43:56 PM
Subject: Re: [AVTCORE] AES-GCM SRTP (RFC 7714) KDF implementation

>>  On 20 August 2016 at 23:29, Cullen Jennings (fluffy) 
>><[email-masked]>
>>  wrote:
>>>
>>>
>>>   Ekr, Martin,
>>>
>>>   Any thoughts on this ?
>>>
>>>   Thanks
>>>
>>>
>>>>   On Aug 4, 2016, a!
>>>>   t 9:45
>>>>padding

---

From: Martin Thomson <[email-masked]>
Date: Wed, 24 Aug 2016 17:21:36 +1000

On 24 August 2016 at 11:53, Paul E. Jones <[email-masked]> wrote:
> RFC 7714 specified a salt length of 12 octets.  And that's where the problem
> comes in.

If you (and 7714) were to use "master salt" consistently, the
confusion would have been easily avoided.

Either way, I agree that clarification is helpful.  My inclination is
to take option 1 here.  That matches S4.1.1 of 3711 where it defines
using right-alignment and it matches my understanding of the
mathematics used in 3711 (x is multiplied by 2^16, so presumably these
are big-endian numbers we are talking about rather than octet
sequences).

Option 2 seems like an error (assuming 7714 really does define
master_salt as being 12 octets), driven by examples rather than
normative language.  Options 3 and 4 (pad after XOR) don't fit with
the interpretation.

My guess is that 3711 doesn't define how big x is (that is, the output
of the XOR) because it assumes this to be a mere number.  It seems
like an oversight though.

So I guess that my conclusion is that no one is right.

---

From: "Paul E. Jones" <[email-masked]>
Date: Wed, 24 Aug 2016 22:08:26 +0000

Martin,

I think you were referring to section 4.3.1 of RFC 3711, right?  That's 
where it talks about right-alignment.  They key_id is generally shorter 
than the salt (and is in all defined uses of RFC 3711), so the 
right-alignment statement was to ensure that the key_id aligned with the 
master salt at a particular place.

If we followed RFC 3711, we would take whatever salt we have (12 octets 
in this case), align it with the key_id and XOR.  We would then multiply 
that by 2*16 (to effectively pad two octets on the right).  
Unfortunately, we'd be two octets short of what we need.

If we take option (1), the right-alignment will result in the same 
numeric value as if no padding is introduced.  Thus the output would be 
precisely the same as option (3), since the salt is longer than the 
key_id.  Those options work, though I'll note that nowhere does RFC 3711 
ever pad on the left.

Option (2) does padding in a way that is consistent with RFC 3711 and, 
as with option (1), padding at the outset addresses any issues had the 
salt been shorter than the key_id.

Option (4) is actually a logical choice to make given the way RFC 3711 
is defined.  What could have been stated in section 4.3.3 is that the IV 
is equal to ((x*2^8n), where n is 16 - length of x in octets).  That 
might be confusing language and perhaps better worded.  It also would 
not consider the case where the salt length is less than the key_id 
length.  (In reality, it's not likely anyone would ever specify such a 
short salt, but I like to be complete.)

So as to avoid complicating what is in RFC 3711, my though was to modify 
the text in  Section 11 of RFC 7714 where it refers to using KDFs 
defined in RFC 3711 and RFC 6188.  RFC 6188 states "both AES_192_CM and 
AES_256_CM use a 112-bit salt as an input, as does AES_CM."  So I think 
the simplest thing is to explain in this section that the salt value 
used in the KDF for RFC 3711 and RFC 6188 assume a 112 bit value and 
suggest to either add two zero octets to the front or the end.  
Consistent with language in RFC 3711, we would say:

"Since the KDF functions in those RFCs assume as input a 112-bit master 
salt, the 96-bit master salt specified in this document must be 
multiplied by 2^16 to form the 112-bit salt used as the master salt for 
those key derivation functions."

In effect, that language results in the use of option 2 in my previous 
email.  It's fairly concise language and then resolves how to use the 
shorter salt with the existing text that assumes a longer salt.

Paul

------ Original Message ------
From: "Martin Thomson" <[email-masked]>
To: "Paul E. Jones" <[email-masked]>
Cc: "Cullen Jennings (fluffy)" <[email-masked]>; "Eric Rescorla" 
<[email-masked]>; "[email-masked]" <[email-masked]>
Sent: 8/24/2016 3:21:36 AM
Subject: Re: [AVTCORE] AES-GCM SRTP (RFC 7714) KDF implementation

>>problem

---

From: "Cullen Jennings (fluffy)" <[email-masked]>
Date: Thu, 25 Aug 2016 14:38:26 +0000

So to be pragmatic about this ... how much running code will either choice A or B break? Do we need to make a new version this somehow if we are breaking deployed code so that running code knows which version it is dealing with and what to do?

> On Aug 24, 2016, at 1:21 AM, Martin Thomson <[email-masked]> wrote:
>

---

From: "Paul E. Jones" <[email-masked]>
Date: Fri, 26 Aug 2016 19:31:41 +0000

Cullen,

Cisco has a fairly large number of IP phones and videoconferencing 
endpoints using the logic currently implemented in libSRTP (which is #2 
in my list of options).

Paul

------ Original Message ------
From: "Cullen Jennings (fluffy)" <[email-masked]>
To: "Martin Thomson" <[email-masked]>
Cc: "Paul Jones" <[email-masked]>; "[email-masked]" <[email-masked]>
Sent: 8/25/2016 10:38:26 AM
Subject: Re: [AVTCORE] AES-GCM SRTP (RFC 7714) KDF implementation

>So to be pragmatic about this ... how much running code will either 
>choice A or B break? Do we need to make a new version this somehow if 
>we are breaking deployed code so that running code knows which version 
>it is dealing with and what to do?
>
>