Subject: [babel] info model: rehashing hashing

From: "STARK, BARBARA H" <[email-masked]>
Date: Tue, 2 Mar 2021 17:54:12 +0000

Hi Babel,
The WG had 2 extensive discussions around configuring keys for MAC algorithms. First in January 2019 and then in August 2019. The language in the info-model draft reflects the consensus we reached after the August 2019 discussion:

   babel-mac-key-value:  ...  This
      value is of a length suitable for the associated babel-mac-key-
      algorithm.  If the algorithm is based on the HMAC construction
      [RFC2104], the length MUST be between 0 and the block size of the
      underlying hash inclusive (where "HMAC-SHA256" block size is 64
      bytes as described in [RFC4868]).  If the algorithm is "BLAKE2s-
      128", the length MUST be between 0 and 32 bytes inclusive, as
      described in [RFC7693].

Ben Kaduk is pushing back on this. I've included our conversation, at the bottom. 4 "> > > >" or  a single ">" precede my comments and nothing, 2 "> >", or 5 "> > > > >" precede Ben's. But to summarize the comment that concerns me most, he says the restriction on keys for HMAC-based algorithms to be less than the block size will not be short enough to avoid the problem we saw with the Bird implementation using OSPF code (which calculates the cryptographic key for long "Authentication Key" per OSPF RFC 5709 and not HMAC RFC 2104).

Here is that specific part of the conversation:
-------------------------------------
> The Bird (language) implementation of Babel used existing code for OSPF. That code was designed according to RFC 5709, which will hash any "Authentication Key" (K) longer than the length of the hash (L) to create a cryptographic key (Ko) that is exactly L octets long.
> 
> What RFC 5709 describes is different than what RFC 2104 (HMAC) describes. RFC 2104 says to create a hash of the authentication key (K) if it is longer than the block size of the hashing algorithm (B). For SHA-256, B != L. Therefore, using RFC 5709 will get a different value for the cryptographic key than RFC 2104, for authentication key length between L and B. This difference was noted in RFC5709 errata. RFC 7166 updated RFC 6506 wrt this. But RFC 7166 didn't update RFC 5709.  RFC 7474 updated RFC 5709 and kept the L boundary. We looked at the Bird library code which does indeed do the calculation according to RFC 5709. Fortunately, there is great consistency among the various RFCs around zero-padding short authentication keys.
> 
> Furthermore, the Bird implementation allowed the key to be provided via a GUI that treated the input sequence of characters as ASCII. This was, again, from code that already existed for OSPF. But note there is no requirement in any RFC for support of an authentication key entered in ASCII format.

Thanks; this is really helpful information to know (and pretty unfortunate
about the OSPF situation).
But if issues with how an existing Babel implementation handles input keys
longer than the output length of the hash are what motivate the key length
restrictions, shouldn't the length restrictions reflect the hash output
length rather than the hash block size?
-------------------------------------

Does the parameter description have the right length limits? Please help! Thx,
Barbara

====================== entire conversation with Ben ==================================
> > > > > Similarly (as Roman notes), we are putting requirements on the key
> > > > > length for MAC keys (relative to the block size of the underlying hash
> > > > > function) that have were once present in draft-ietf-babel-hmac but have
> > > > > been removed as of draft-ietf-babel-hmac-10.  I assume that the intent
> > > > > is not to impose additional restrictions compared to the protocol spec,
> > > > > thus we need to catch up to those changes.
> > > >
> > > > How humans interact with configuration parameters presented through
> > > > a data model instantiation of this information model is a concern. Having
> > > > experienced the horrors of the days of configuring WEP keys (which were
> > > > either ASCII or hex and caused most people not to use WEP with Wi-Fi)
> > > > and witnessed (and been party to) the discussions in
> > > > Babel where we wanted to ensure that whatever string was inputted for
> > > > the key would yield consistent MAC computation across all implementations
> > > > (i.e.,
> > > > would yield consistent "actual key"), I believe
> > > > it is imperative for the information model to constrain the input. As I
> > explained
> > > > in my response to Roman and Valery, we saw considerable variability in
> > > > how existing libraries for allowing users to supply a key value treated
> > > > values that could not be directly used as what RFC 2104 calls "the actual
> > key".
> > > > To ensure human users are successful in supplying the same "actual key"
> > value
> > > > to various
> > > > implementations, it's necessary for user interfaces to restrict what is
> > > > supplied to be "the actual key" so no extraneous hashing and processing
> > > > is needed to generate "the actual key" (other than adding zeroes if the input
> > > > key is shorter than an "actual key").
> > 
> > These are all important considerations, and I am glad that you are keeping
> > them in mind (while simultaneously being sad that they are necessary).
> > But they seem to mostly be concers with the translation layer between the
> > input layer and the cryptographic API, and the restrictions that I am
> > concerned about are ones that relate to processing done within the
> > cryptographic API boundary.
> 
> I find this statement a little confusing, since the info model is placing no restrictions on processing done within a cryptographic API boundary. It's only placing restrictions on the length and datatype of a parameter (supplied via a management protocol or user interface) that is then provided to a Babel implementation. What the Babel implementation does to or with this parameter is not something the info model cares about.

Well, my reasoning is basically that the information model is imposing a
limitation on the inputs to the cryptographic API that is more stringent
then the documented requirements for that API.  The only vaguely plausible
reason that I know of that one might want to impose this specific
requirement is to affect the internal processing of that API (to avoid the
extra "hash the key input" step).  So, picking this specific limit on the
input to the cryptographic API comes across as attempting to force a
specific behavior path within the cryptographic API.

IMO, if you are going to use HMAC, use the HMAC interface as documented and
let HMAC determine which of its internal paths to take.  If you need to
impose some restriction on the inputs, do so for reasons related to
processing at the application layer (including, potentially, existing
implementations that do the wrong thing) and document it as such.

> > > > The restrictions provided for the length of an input key are consistent with
> > > > what the HMAC and BLAKE RFCs indicate for "actual key" length.
> > > >
> > > > This allows implementations of draft-ietf-babel-hmac to use existing HMAC
> > > > and BLAKE2s libraries without worrying about what inconsistent
> > manipulations
> > > > the libraries or associated libraries for inputting keys do to strings that are
> > > > too long to be directly used as "actual keys".
> > 
> > In particular, the procedures for using an HMAC key longer than the block
> > length of the underlying hash function (hash the key first) are
> > longstanding and well-implemented.  Are you saying that you have
> > experiences with buggy HMAC implementations that don't do this?  (If so,
> > that would be a great tidbit to mention in the document as motivation.)
> 
> The Bird (language) implementation of Babel used existing code for OSPF. That code was designed according to RFC 5709, which will hash any "Authentication Key" (K) longer than the length of the hash (L) to create a cryptographic key (Ko) that is exactly L octets long.
> 
> What RFC 5709 describes is different than what RFC 2104 (HMAC) describes. RFC 2104 says to create a hash of the authentication key (K) if it is longer than the block size of the hashing algorithm (B). For SHA-256, B != L. Therefore, using RFC 5709 will get a different value for the cryptographic key than RFC 2104, for authentication key length between L and B. This difference was noted in RFC5709 errata. RFC 7166 updated RFC 6506 wrt this. But RFC 7166 didn't update RFC 5709.  RFC 7474 updated RFC 5709 and kept the L boundary. We looked at the Bird library code which does indeed do the calculation according to RFC 5709. Fortunately, there is great consistency among the various RFCs around zero-padding short authentication keys.
> 
> Furthermore, the Bird implementation allowed the key to be provided via a GUI that treated the input sequence of characters as ASCII. This was, again, from code that already existed for OSPF. But note there is no requirement in any RFC for support of an authentication key entered in ASCII format.

Thanks; this is really helpful information to know (and pretty unfortunate
about the OSPF situation).
But if issues with how an existing Babel implementation handles input keys
longer than the output length of the hash are what motivate the key length
restrictions, shouldn't the length restrictions reflect the hash output
length rather than the hash block size?

> The C implementation of Babel was designed with the expectation that a centralized system would push the key out to all the routers. It assumed the supplied key was in binary format. Preferably, the centralized system would randomly generate the binary value. But if there were a user entering an ASCII string at the centralized system, the centralized system would be able to do whatever desired manipulation and push a suitable binary out to all routers. The C implementation does not accept ASCII input.

(I assume that "does not accept ASCII input" just means "does not do
processing on input to take a human-presentable ASCII representation of a
binary key and convert it into the underlying binary key", as opposed to
"checks for the condition where all octets of the input are in the ASCII
printable range and rejects that input".)

> The WG discussed all of this extensively in January of 2019. And then re-hashed it (haha) in August of 2019. There was discussion of imposing either RFC 5709 or RFC 2104 calculation for long "authentication keys" on the Babel implementations (in the babel-mac draft). There was discussion of requiring the key supplied to an implementation to be exactly the cryptographic key (so all manipulation was done external to Babel). And other ideas (I can point to the emails in the archive, if you like; there were many emails). The August 2019 decision was for the babel-mac draft not to impose additional restrictions on the format of provided keys (other than restrictions imposed by SHA-256 and BLAKE2s RFCs on keys) and not to choose between RFC 5709 or RFC 2104. So the Bird and C implementations did not need to change what they were doing. But the info model would restrict the length and datatype of "authentication key" values it supplied so the cryptographic keys the implementations ended up calculating from the input binary authentication key would always be the same. The values supplied by the info model will simply never invoke code that would result in inconsistent cryptographic key values.

Thank you very much for the summary of the prior WG discussions; I cannot
hope to try to repeat the depth of consideration that was already given.
As above, though, my reading of the -13 is that it does allow hitting the
code that would result in inconsistent key values, since the stated limit
for HMAC-SHA256 is 64 bytes, not 32.

> > The situation for Blake2s-128 (which is being used directly and not via
> > HMAC) is not quite so clear to me since it's a more recent innovation, and
> > RFC 7693 seems rather unclear about what to do if the input key is larger
> > than 64 bytes (it talks only of padding the key and setting as d[0], where
> > d[0] is a 16-word block, and for Blake2s words are 32 bits).  So while
> > limiting the length of the Blake2s key may be justified in fact, (1) that
> > justification should probably be in the document, and (2) I don't see a
> > factual basis for limiting HMAC keys to the block length.
> 
> And we also could find nothing that described what to do for long keys in BLAKE2s. So the datatype and length restriction would again ensure consistent cryptographic key calculation.

I would strongly encourage adding some discussion of the motivation for the
length limits into the draft itself.

> > (For what it's worth I did do a bit of math, and even if the "actual key"
> > is limited to uppercase letters plus digits, a 64-character string can
> > still contain some 330 bits of entropy, which is stronger than a 32-byte
> > random string.  You'd have to be really limited in what characters can be
> > used, e.g., to only digits, in order to have the maximum theoretical
> > entropy of the 64-character string fall below 256 bits.)

If the limit is actually going to be 32 characters, the numbers go down
accordingly, but 165 bits is not shabby, and adding in lowercase letters
gets you up to 190 bits, and the full 95 ASCII printables cap out at 210
bits.

---

From: Toke Høiland-Jørgensen <[email-masked]>
Date: Wed, 03 Mar 2021 00:27:45 +0100

"STARK, BARBARA H" <[email-masked]> writes:

> Hi Babel,
>
> The WG had 2 extensive discussions around configuring keys for MAC
> algorithms. First in January 2019 and then in August 2019. The
> language in the info-model draft reflects the consensus we reached
> after the August 2019 discussion:
>
> Ben Kaduk is pushing back on this. I've included our conversation, at
> the bottom. 4 "> > > >" or a single ">" precede my comments and
> nothing, 2 "> >", or 5 "> > > > >" precede Ben's. But to summarize the
> comment that concerns me most, he says the restriction on keys for
> HMAC-based algorithms to be less than the block size will not be short
> enough to avoid the problem we saw with the Bird implementation using
> OSPF code (which calculates the cryptographic key for long
> "Authentication Key" per OSPF RFC 5709 and not HMAC RFC 2104).
>

Couple of comments on this:

>> The Bird (language) implementation of Babel used existing code for
>> OSPF. That code was designed according to RFC 5709, which will hash
>> any "Authentication Key" (K) longer than the length of the hash (L)
>> to create a cryptographic key (Ko) that is exactly L octets long.
>> 
>> What RFC 5709 describes is different than what RFC 2104 (HMAC)
>> describes. RFC 2104 says to create a hash of the authentication key
>> (K) if it is longer than the block size of the hashing algorithm (B).
>> For SHA-256, B != L. Therefore, using RFC 5709 will get a different
>> value for the cryptographic key than RFC 2104, for authentication key
>> length between L and B. This difference was noted in RFC5709 errata.
>> RFC 7166 updated RFC 6506 wrt this. But RFC 7166 didn't update RFC
>> 5709. RFC 7474 updated RFC 5709 and kept the L boundary. We looked at
>> the Bird library code which does indeed do the calculation according
>> to RFC 5709.

This is not accurate wrt the Bird code. The relevant bit is here:

https://gitlab.nic.cz/labs/bird/-/blob/master/lib/mac.c#L105

It's hashing keys longer than the block length, not the output length,
which is not what RFC5709 says (unless I'm misreading something).

>> Fortunately, there is great consistency among the various RFCs around
>> zero-padding short authentication keys.
>> 
>> Furthermore, the Bird implementation allowed the key to be provided
>> via a GUI that treated the input sequence of characters as ASCII.
>> This was, again, from code that already existed for OSPF. But note
>> there is no requirement in any RFC for support of an authentication
>> key entered in ASCII format.

The latest version of my Bird patch series lifts this restriction, BTW;
it is now possible to enter raw hex bytes as well as ASCII text when
specifying the key.

> length rather than the hash block size?

I believe it does (see above). The Bird implementation is stricter,
though: it enforces exactly 32 bytes as the key size for Blake2s, and
between 32 and 64 bytes for HMAC-SHA256.

-Toke