Subject: [babel] info-model: hmac

From: "STARK, BARBARA H" <[email-masked]>
Date: Mon, 18 Feb 2019 15:21:26 +0000

We had discussion in January about how to model HMAC parameters. 
Some items of discussion: 
 - parameter(s) for identifying an HMAC key as being used for sent and/or received messages 
     -> I decided after playing around with it that I actually preferred Toke's original suggestion of 2 Booleans instead of an enumeration
 - enable/disable
     -> I took enable/disable out of the HMAC objects and put a global enable/disable for HMAC in the top object of the model.
 - need to make sure keys cannot be read

Here is what I ended up with
-------------------------------------------------
Under babel-information-obj
babel-hmac-enable
babel-hmac-algorithms: : List of supported HMAC computation algorithms. Possible values include "SHA256", "Blake2B", "Blake2S".
babel-hmac: : A babel-hmac-obj object. If this object is implemented, it provides access to parameters related to the HMAC security mechanism. An implementation MAY choose to expose this object as read-only.
-------------------------------------------------
Under babel-hmac-obj
  object {
       string                rw babel-hmac-algorithm;
       boolean               rw babel-hmac-verify-received;
       string                rw babel-hmac-interfaces<0..*>;
       babel-hmac-keys-obj   rw babel-hmac-keys<0..*>;
   } babel-hmac-obj;

babel-hmac-algorithm : The name of the HMAC algorithm this object instance uses. The value MUST be the same as one of the enumerations listed in the babel-hmac-algorithms parameter. An implementation MAY choose to expose this parameter as read-only ("ro").

babel-hmac-verify-received : A boolean flag indicating whether HMAC hashes in received Babel messages are required to be present and are verified. If this parameter is "true", received messages are required to have a valid HMAC hash. An implementation MAY choose to expose this parameter as read-only ("ro").

babel-hmac-interfaces: : List of references to the babel-interfaces entries this babel-hmac entry applies to. If this list is empty, then it applies to all interfaces. An implementation MAY choose to expose this parameter as read-only ("ro").

babel-hmac-keys: : A set of babel-hmac-keys-obj objects.
----------------------------------------
Under babel-hmac-keys-obj
  object {
       string                ro babel-hmac-key-name;
       boolean               rw babel-hmac-key-use-sign;
       boolean               rw babel-hmac-key-use-verify;
       binary                -- babel-hmac-key-value;
      [operation                babel-hmac-key-test;]
   } babel-hmac-obj;

babel-hmac-key-name: : A unique name for this HMAC key that can be used to identify the key in this object instance, since the key value is not allowed to be read. This value can only be provided when this instance is created, and is not subsequently writable.

babel-key-use-sign: : Indicates whether this key value is used to sign Babel messages. Messages are signed using this key if the value is "true". An implementation MAY choose to expose this parameter as read-only ("ro").

babel-key-use-verify: : Indicates whether this key value is used to verify Babel messages. This key is used to verify messages if the value is "true". An implementation MAY choose to expose this parameter as read-only ("ro").

babel-key-value: : The value of the HMAC key. An implementation MUST NOT allow this parameter to be read. This can be done by always providing an empty string, or through permissions, or other means. This value can only be provided when this instance is created, and is not subsequently writable.

babel-hmac-test: : An operation that allows the HMAC key and hash algorithm to be tested to see if they produce an expected outcome. Input to this operation is a binary string. The implementation is expected to create a hash of this string using the babel-hmac-key-value and the babel-hmac-algorithm. The output of this operation is the resulting hash, as a binary string.

Barbara

---

From: Toke Høiland-Jørgensen <[email-masked]>
Date: Mon, 18 Feb 2019 23:05:35 +0100

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

> babel-hmac-verify-received : A boolean flag indicating whether HMAC
> hashes in received Babel messages are required to be present and are
> verified. If this parameter is "true", received messages are required
> to have a valid HMAC hash. An implementation MAY choose to expose this
> parameter as read-only ("ro").

When I read this name (before reading the description) I read it as a
verb (i.e., I expected this to be a boolean indicating whether a
verified packet was received). So maybe choose a different name? Perhaps
"babel-hmac-must-verify"?

> babel-hmac-interfaces: : List of references to the babel-interfaces
> entries this babel-hmac entry applies to. If this list is empty, then
> it applies to all interfaces. An implementation MAY choose to expose
> this parameter as read-only ("ro").

Why this list instead of making babel-hmac-obj a part of the interface
object?

-Toke

---

From: Juliusz Chroboczek <[email-masked]>
Date: Tue, 19 Feb 2019 09:20:01 +0100

> babel-hmac-algorithms: : List of supported HMAC computation
> algorithms. Possible values include "SHA256", "Blake2B", "Blake2S".

Should that be "HMAC-SHA256" instead?  ISAKMP uses "HMAC-SHA256-256",
while CBOR uses "HMAC 256/256".  (Blake2 does not use the HMAC
construction.)

> entries this babel-hmac entry applies to. If this list is empty, then it
> applies to all interfaces. An implementation MAY choose to expose this

I'm still not sure I like the special handling of the empty list.

> babel-key-use-verify: : Indicates whether this key value is used to
> verify Babel messages. This key is used to verify messages if the value
> is "true". An implementation MAY choose to expose this parameter as
> read-only ("ro").

I think this requires some phrasing to clarify what happens when this
value is false.

---

From: Gabriel Kerneis <[email-masked]>
Date: Tue, 19 Feb 2019 10:40:10 +0100

> I'm still not sure I like the special handling of the empty list.

I second this opinion. I know at least one real-world network-related major
outage caused by an "empty list means everything" bug, and it has made me
very nervous of similar special cases ever since.

Gabriel

---

From: "STARK, BARBARA H" <[email-masked]>
Date: Tue, 19 Feb 2019 16:19:02 +0000

> When I read this name (before reading the description) I read it as a verb
> (i.e., I expected this to be a boolean indicating whether a verified packet was
> received). So maybe choose a different name? Perhaps "babel-hmac-must-
> verify"?

How about just "babel-hmac-verify"? 

> Why this list instead of making babel-hmac-obj a part of the interface object?

There are multiple (and separate) comments on the interfaces reference for HMAC and DTLS. So I'm going to start a separate thread for that.

Barbara

---

From: "STARK, BARBARA H" <[email-masked]>
Date: Fri, 22 Feb 2019 15:29:05 +0000

Sorry it's taken me so long to reply to these. Sometimes I just need time to let comments soak in, so I can try to appreciate their full meaning and where the commenter might be coming from. I responded to the first part of Toke's comment earlier, so this is to reply to the interface question (and I realized all the interface reference questions were distinct so I'll be replying to each individually, after all).

> -----Original Message-----
> From: Toke Høiland-Jørgensen <[email-masked]>

------- snip ------------ 
> Why this list instead of making babel-hmac-obj a part of the interface object?

If it's under the interface object, then I have to manage each interface separately. This means each instance needs to know which keys are used for that specific interface (even if multiple interfaces use the same key). Where multiple interfaces use the same key(s), the keys either have to be duplicated under each interface, or I need to change the model to have a central key store (and then put references either in each HMAC-interface instance as to the keys it uses, or put references in the key store as to which HMAC-interface instances use that key). I considered "same key for multiple interfaces" to be a likely scenario, so I wanted this to be easy to manage. The current model still allows for HMAC instance per interface (each HMAC instance points to exactly one interface). If this is the chosen deployment scenario, it's no more effort to manage the scenario with interface as a reference rather than a parent. Where all interfaces use the same HMAC instance (same keys, same settings), it's much easier to manage it this way.

Barbara

---

From: "STARK, BARBARA H" <[email-masked]>
Date: Fri, 22 Feb 2019 16:49:51 +0000

> while CBOR uses "HMAC 256/256".  (Blake2 does not use the HMAC

So looking at the current babel-hmac-03 draft, it seems this should be: Possible values include "HMAC-SHA256" and "BLAKE2s". 
Of course, this doesn't preclude other enumeration values. It's just the only ones that need to have enumerations specified are the ones listed in the draft.
Does that seem right?

> I'm still not sure I like the special handling of the empty list.

OK. So would it be better to either
1. If the instance applies to all interfaces, all interfaces must be listed
or
2. Have a Boolean "babel-hmac-apply-all" where if true, this overrides whatever is in the interface list and the instance applies to all interfaces. If false, then the interface list is used; and if the interface list is empty and "apply-all" is false, then the instance applies to no interfaces.

> > verify Babel messages. This key is used to verify messages if the
> > value is "true". An implementation MAY choose to expose this parameter
> > as read-only ("ro").
> 
> I think this requires some phrasing to clarify what happens when this value is
> false.

Would this be better? :
babel-key-use-verify: : Indicates whether this key value is used to
verify received Babel packets. This key is used to verify received packets if the
value is "true". If the value is "false", no HMAC is computed from this key
for comparing a received packet.
An implementation MAY choose to expose this parameter
as read-only ("ro").

Barbara

---

From: Juliusz Chroboczek <[email-masked]>
Date: Fri, 22 Feb 2019 17:57:57 +0100

> 2. Have a Boolean "babel-hmac-apply-all" where if true, this overrides
> whatever is in the interface list and the instance applies to all
> interfaces. If false, then the interface list is used; and if the
> interface list is empty and "apply-all" is false, then the instance
> applies to no interfaces.

Yeah, I think that's less error-prone.

> verify received Babel packets. This key is used to verify received
> packets if the value is "true". If the value is "false", no HMAC is
> computed from this key for comparing a received packet.

Perhaps "incoming" instead of "received"?

I still feel there's something missing, though -- I feel you need to say
explicitly that if the value is false, the HMAC is still used for signing
outgoing packets.  (I assume that's the intent.)

-- Juliusz

---

From: "STARK, BARBARA H" <[email-masked]>
Date: Fri, 22 Feb 2019 17:23:31 +0000

> > 1. If the instance applies to all interfaces, all interfaces must be
> > listed or 2. Have a Boolean "babel-hmac-apply-all" where if true, this
> > overrides whatever is in the interface list and the instance applies
> > to all interfaces. If false, then the interface list is used; and if
> > the interface list is empty and "apply-all" is false, then the
> > instance applies to no interfaces.
> 

Do you prefer option 1 (to apply to all interfaces, list all interfaces) or option 2 (Boolean to apply to all interfaces)?
 
> Perhaps "incoming" instead of "received"?

Hmph. I used "received" because the section of babel-hmac-03 that 
discusses the related behavior is "4.3.  Packet Reception 
When a packet is received..."
But I can change to "incoming", if that's preferred.
 
> I still feel there's something missing, though -- I feel you need to say explicitly
> that if the value is false, the HMAC is still used for signing outgoing packets.  (I
> assume that's the intent.)

The parameter listed right before this one is
babel-key-use-sign: : Indicates whether this key value
is used to sign Babel messages. Messages are signed using
this key if the value is "true". An implementation MAY choose
to expose this parameter as read-only ("ro").

I can change this similar to the "babel-key-use-verify", to 
Indicates whether this key value
is used to sign sent Babel packets. Sent packets are signed using
this key if the value is "true". If the value is "false", this key
is not used to sign sent Babel packets.

Both use-sign and use-verify parameters are Booleans, and they're independent. So, no, there's no intent that if use-verify is false this implies it's still used for signing. Only if use-sign = true is it used for signing. It's possible for one or the other to be true, both true, or both false.

Barbara

---

From: Juliusz Chroboczek <[email-masked]>
Date: Sat, 23 Feb 2019 12:50:22 +0100

> Do you prefer option 1 (to apply to all interfaces, list all interfaces)
> or option 2 (Boolean to apply to all interfaces)?

I think it's good to be able to say that a key applies to all interfaces,
especially if the set of available interfaces can vary dynamically.
 
> Both use-sign and use-verify parameters are Booleans, and they're
> independent. So, no, there's no intent that if use-verify is false this
> implies it's still used for signing. Only if use-sign = true is it used
> for signing. It's possible for one or the other to be true, both true,
> or both false.

Right.  Looking at your prose again, nihil obstat.

-- Juliusz