Subject: Re: [6tisch] Observe for rekeying (was: Updates to minimal-security-06)

From: Mališa Vučinić <[email-masked]>
Date: Tue, 10 Apr 2018 09:13:23 +0000

Hi Christan,

Thanks for your response and apologies for the slow follow up. See inline.

Mališa

On Mon, Mar 26, 2018 at 10:42 AM Christian M. Amsüss <[email-masked]>
wrote:

> Hello Mališa,
>
> On Fri, Mar 23, 2018 at 10:12:16AM +0000, Mališa Vučinić wrote:
> > I am tempted to say that this does not prevent us from updating the
> client
> > endpoint (but not the token) based on implicit knowledge at JRC. Do you
> > agree?
>
> observation is fundamentally a hop-to-hop thing (terminated at proxies);
> both the token and the observation counter are scoped to those hops, and
> while a minimal proxy may get away with passing them on unmodified, I
> doubt that that can be used to form a stable mechanism.
>
> The topic of a delegated observe has been brought up before[1] (with a
> focus on nomadic devices), and was not followed up to after initial
> comments. If minimal-security were to do observations that hops off a
> proxy observation to a direct one, it'd need a specification similar to
> that (with its holes filled) to let that observation hop off smoothly.
>
> (Whether the observation is FETCH or GET is immaterial here, and in this
> setting it's a good approximation to say that the difference is that the
> FETCH allows binary data with a mime type to be part of the request,
> which would in a GET need to be squished into a query string).
>
>
> As I understand, even richardson-6tisch-minimal-rekey needs to transport
> that modelled data, so at any rate I can suggest two alternatives to a
> hopping observation:
>
> * Don't observe through the proxy, but establish an observation after
>   the address has been assigned.

>   This incurs cost of two additional packages, but is conceptually
>   simple and straightforward.
>

Yep, so two messages to join and two additional messages for the first
rekey to happen.

>
> * Establish a dynlink (formerly bindings) to make the JRC PUT (or PATCH)
>   the node.

>   This would take two additional messages as well (the former pledge
>   requesting a dynlink once it knows its final address, plus its
>   response). This is the less common but more versatile approach to
>   observation.

>   An advantage over plain observation is that it might be possible to
>   establish this link in another way than explicitly requesting it (eg.
>   piggy-backing an "and when you've managed, please keep me posted on /X
>   relative to whatever address I might have then", or by the JRC knowing
>   from somewhere else that such a binding is to be established)
>

What would be the advantage of establishing a dynlink over specifying in
the minimal-security draft that once the pledge joins, it needs to expose a
/j resource that the JRC may use to update the keying material? This would
essentially be a static link specified in the draft. Do you see any pitfall
with that?

6tisch-minimal-rekey sounds like it is a valid expectation that the
> nodes will use CoMI; if that is the case and this approach is followed,
> the PUT/PATCHing that would be the result of a dynlink cold probably be
> set up implicitly.
>

I don't think we have the consensus on the use of CoMI in minimal-security.
We considered it for future work, but at this point I would refrain from
pulling in new specifications..

>
> Best regards
> Christian
>
> [1]:
> https://mailarchive.ietf.org/arch/msg/core/-emsRTJmyyFHlrNwbJkqGfXQaYw
>
> --
> To use raw power is to make yourself infinitely vulnerable to greater
> powers.
>   -- Bene Gesserit axiom
>

---

From: Mališa Vučinić <[email-masked]>
Date: Tue, 10 Apr 2018 09:21:24 +0000

Hi Thomas,

See inline.

Mališa

On Mon, Mar 26, 2018 at 9:00 AM Thomas Watteyne <[email-masked]>
wrote:

> There are two seperated discussions going on in this thread. @Malisa, if
> you agree, let's split the thread.
> I have clarifying questions about both.
>
> *About OBSERVE*
>
> The issue raised is that, during the join request/response exchange
> between the pledge and the JRC, the JRC never learns the IPv6 address of
> the pledge (thanks to the Stateless-Proxy CoAP option). This means that, if
> the join request is carried by a CoAP FETCH message with Observe, the JRC
> has no means of addressing the joined node when the Observe triggers.
> Doing a second GET with Observe once the pledge has joined defeats the
> purpose of going for FETCH.
> Any other option?
>

This discussion is now under the thread: *Observe for rekeing (was: Updates
to minimal-security-06).*

I agree with your summary. Right now we are discussing whether the joined
node can expose a resource (e.g. /j), that the JRC can POST to and update
the key as it knows implicitly joined node's IPv6 address.

> *About COSE_Key*
>
> The issue raised is that, during a rekey of key K2 by the JRC, the JRC
> cannot specify an ASN from which the new key is to be used.
> A strong requirement is for a node NOT have a node rejoin for each rekey.
> Must we use the COSE_Key structure?
> Is the the message sent by the JRC containing the new key end-to-end
> ACK'ed, i.e. does the JRC know it got received?
>

Moving the discussion about the rekeying mechanism to the thread: *Rekeying
for minimal-security (was: Updates to minimal-security-06).*

>
> Thomas
>
> On Sat, Mar 24, 2018 at 11:36 PM, Michael Richardson <
> [email-masked]> wrote:
>
>>
>> Mališa Vučinić <[email-masked]> wrote:
>>     mcr> I think that the mechanism that was explained at:
>>     mcr>
>> https://tools.ietf.org/html/draft-richardson-6tisch-minimal-rekey-02#
>>     mcr> section-4
>>
>>     mcr> is a better workable solution.  Deploy all the new keys (it may
>> take some
>>     mcr> days on sleep networks), and then have nodes switch when they
>> see traffic
>>     mcr> with the new key.
>>
>>     > Thanks, Michael, for the reminder on this document, I have to say
>> that I forgot
>>     > about it.. IIUC, the issue you have with the mechanism I proposed
>> is that the
>>     > JRC in some cases may not know how long it could take to deploy the
>> keys so
>>     > that it cannot properly set the ASN. I think that's a valid concern
>> and that it
>>     > would indeed be better if we could decouple the JRC from the inner
>> network
>>     > specifics as much as possible.
>>
>> Exactly.
>> It does not have to change significantly what you have, it just has to
>> include the (new) keyIndex.
>>
>>     > To do this and support rekeying with your proposal, we need to
>> differentiate
>>     > between "start using this key" and "install the key but don't start
>> using it
>>     > until you see it being used in the network", for 6LBR and joined
>> nodes to
>>     > follow, respectively. We can likely do this by extending the
>> COSE_Key map with
>>     > an additional parameter for this purpose, which I prefer to pulling
>> in the
>>     > whole COMI machinery, as is suggested in the minimal-rekey draft.
>>
>> I agree, we don't need COMI, just the text about when to start using the
>> new key.
>> Shall I suggest some text it github?
>>
>>     > Essentially, the process would be:
>>     > - the JRC deploys the new key(s) to all the nodes except to the
>> 6LBR.
>>     > - nodes will install them, but keep using the old keys because the
>> new COSE_Key
>>     > parameter is set to "install the key but don't start using it until
>> you see it
>>     > being used in the network".
>>
>> I'd say that you always do this with any new key if you have no keys.
>> I don't think we need a flag.
>>
>> In fact, even for the "0th key", you would start using it as soon as you
>> see
>> something that passes with that key, such as authenticating the Beacon
>> that
>> you used to find the Proxy in the first place....
>>
>>     > - deploy the key to the 6LBR, with the COSE_Key parameter set to
>> "start using
>>     > now".
>>     > - once a node sees the new key being used and the replay protection
>> and the
>>     > authenticity check at L2 passes, it removes the old keys and starts
>> using the
>>     > new key for all outgoing traffic
>>
>> Yes.
>>
>> --
>> ]               Never tell me the odds!                 | ipv6 mesh
>> networks [
>> ]   Michael Richardson, Sandelman Software Works        | network
>> architect  [
>> ]     [email-masked]  http://www.sandelman.ca/        |   ruby on
>> rails    [
>>
>>
>> _______________________________________________
>> 6tisch mailing list
>> [email-masked]
>> https://www.ietf.org/mailman/listinfo/6tisch
>>
>>
>
>
> --
> ________________________________________
>
> Thomas Watteyne, PhD
> Research Scientist & Innovator, Inria
> Sr Networking Design Eng, Analog Devices
> Founder & co-lead, UC Berkeley OpenWSN
> Co-chair, IETF 6TiSCH
>
> www.thomaswatteyne.com
> ________________________________________
>

---

From: Mališa Vučinić <[email-masked]>
Date: Tue, 10 Apr 2018 09:43:43 +0000

See inline.

> cannot specify an ASN from which the new key is to be used.

The JRC would need to guess how long it may take for it to reach every node
in the network. I think that it makes sense that the JRC does not need to
be aware of network specifics. Instead, it can update the key of the 6LBR
last, signaling that it should start using it. Other nodes get the key
before, but don't use it until they see it in the network. Makes sense?

> A strong requirement is for a node NOT have a node rejoin for each rekey.

Agreed, this means we need to add the rekeying mechanism in the new version
of minimal-security.

> Must we use the COSE_Key structure?

The use of COSE_Key costs us 2 bytes of overhead, for the key type (kty)
parameter which is implicitly symmetric for us but we need to transport it
according to RFC8152.

All the other parameters are optional, and we can extend the COSE registry
with new parameters, if we need to.

We could also specify a 6TiSCH-specific key structure instead of COSE_Key,
going for arrays instead of maps and saving an initial estimate of 4 bytes *per
key*.

> ACK'ed, i.e. does the JRC know it got received?

The end-to-end ACK of the message carrying the new key can be issued with
all the mechanisms that we are discussing in the thread "Observe for
rekeying".

In the case of classical Observe, this would be a CON Observe notification,
followed by an empty ACK from the client.

In the case a joined node exposes a resource (e.g. /j) that the JRC POSTs
to, the ACK would be piggybacked with the 2.04 Created response.

---

From: Christian M. Amsüss <[email-masked]>
Date: Thu, 12 Apr 2018 15:15:47 +0200

> Yep, so two messages to join and two additional messages for the first

A bit more: the two messages to join, and two additional messages
(GET+Observe, 2.05 "observation accepted and here is the data you already
have because there is no re-keying in process right now") to set up the
observation for a future re-keying (where later, the re-keying itself is
again the 1-2 messages it needs anyway).

> essentially be a static link specified in the draft. Do you see any pitfall

Apart from that we should not specify statically named resources in
devices' namespaces outside `.well-known/`, I see no problem with that.

I wouldn't see it as a matter of being "an advantage of ... over", but
more of the dynlink being the theoretical background behind and
justifying what happens here; think of it as a form of compressed
exchange if you will.

> pulling in new specifications..

It might still be convenient to consider, eg. whether a future
implementor that *does* use CoMI can just treat your /j resource as an
alias to /c/abc0815 and be done with it, because a POST there with the
binary data has the desired effect.

Best regards
Christian

-- 
We are dreamers, shapers, singers, and makers.
  -- Elric

---

From: Mališa Vučinić <[email-masked]>
Date: Wed, 18 Apr 2018 15:31:02 +0000

Christian,

See inline.

Mališa

> devices' namespaces outside `.well-known/`, I see no problem with that.

So, we had /j exposed at the JRC for long time in the draft and I assumed
this is OK because ACE is using something similar, i.e /token, /authz-info.

Are you saying that we have to add 11 bytes without counting the option
encoding to the Join Request because this is a static resource? Is there
any way around this?

> justifying what happens here; think of it as a form of compressed

Sounds good, I am working on the text tomorrow and will send you the PR to
double check if it makes sense.

> binary data has the desired effect.

I am not very familiar with CoMI so it could be a dummy question, but would
we need to specify in the draft to allow this?

---

From: peter van der Stok <[email-masked]>
Date: Thu, 19 Apr 2018 09:19:47 +0200

> I am not very familiar with CoMI so it could be a dummy question, but
> would we need to specify in the draft to allow this?

In principle the the length of the path will be shorter to start off 
with. eg /c/FG0

Interesting thought to reduce the already reduced path.
If there are only so many comi data nodes in the server, say 4-5, then 
the server might make
referral to the comi data entries form the short path's like /j, or /j1 
till jn if there are n data points.
the client should also do this translation in the other direction from 
/c/FG0.

Just a note in the text that this a convoluted possibility would be 
sufficient IMO.

Peter

---

From: Mališa Vučinić <[email-masked]>
Date: Thu, 19 Apr 2018 10:57:06 +0000

(I just realized that I forgot to CC the 6tisch ML for the previous
exchanges.)

See below.

On Thu, Apr 19, 2018 at 10:55 AM Christian M. Amsüss <[email-masked]>
wrote:

> Hi Mališa,
>
> On Thu, Apr 19, 2018 at 08:24:57AM +0000, Mališa Vučinić wrote:
> > I agree that sending the path exposed at the pledge would be quite clean
> > but I don't get the benefit of it since we need to hardcode /j at the JRC
> > anyways. For the JRC and the pledge to be interoperable, pledge needs to
> be
> > hardcoded with /j to send the Join Request, and the increment for the JRC
> > to be hardcoded with /j to send the rekeying request to the pledge is
> > minimal IMO.
>
> I think it's one thing to mandate a path to the JRC (which is part of
> the "any-cast group" 6tisch.arpa, which by the way is a trick I find
> very neat), and another for the pledge.
>
> What does ease my concerns a bit is that those resources are anyway
> limited to what I'd call the virtual host induced by the OSCORE context.
>
> > > If CBOR is used to glue the two things (the request hex-stuff, I don't
> > > remember what exactly that was) and the path) together, 16 bytes of
> > > hex-stuff and 1 byte of path become 21 bytes of payload.
>
> Side note: Looking through -05 again I noted that the "hex-stuff" I
> mentioned is already in a join_request CBOR; the overhead associated
> with the path would be further decreased.
>

Yes, that's right, we could extend the join_request struct, if we get
pushback on this.

> But yeah, sticking with /j with the option of adding that to
> join_request if there is pushback sounds like a viable option right now.
>

Sounds good!

> > I am considering POST for both the initial Join Request, and for the
> > rekeying request. That should be fine, right?
>
> The requests for join and re-join from the node to the JRC sound good
> with POST. Who would send a re-keying request -- the node or the JRC?
>

Current text specifies that rekeying is triggered by the joined node, but I
am talking about the update to the text where the rekeying request is sent
by the JRC to /j resource exposed by the joined node. POST should be fine
there, as well, right?

---

From: Mališa Vučinić <[email-masked]>
Date: Thu, 19 Apr 2018 11:37:24 +0000

Michael,

Reviving the discussion on the rekeying mechanism. See below.

Mališa

>>> you used to find the Proxy in the first place....
Authenticating a beacon that was received long time ago would require the
pledge to store the beacon(s) for potentially an extensive period... I
don't think we need to do that.

But, you are right, we do not need a flag in the response, just to specify
the special handling for different roles:

Essentially:
- 6LBR: installs the new key, starts using it for outgoing traffic
*immediately*, removing old keys, if any.
- joined node and pledge: installs the new key, keeps using the old keys
for outgoing traffic until it receives incoming traffic secured with the
new key, with all L2 security checks passed. In the special case of a
pledge, there shouldn't be any outgoing traffic before it decrypts DIO(s)
and selects a preferred parent.

---

From: Michael Richardson <[email-masked]>
Date: Tue, 24 Apr 2018 17:02:52 -0400

Mališa Vučinić <[email-masked]> wrote:
    > The JRC would need to guess how long it may take for it to reach every
    > node in the network. I think that it makes sense that the JRC does not
    > need to be aware of network specifics. Instead, it can update the key
    > of the 6LBR last, signaling that it should start using it. Other nodes
    > get the key before, but don't use it until they see it in the network.
    > Makes sense?

I made a pull request with this text, which was from the rekeying
document.  I am not happy with the text yet.

### Rekeying

A node MAY have multiple L2 keys, identified by different secKeyId.  The
"kid" in the Join Response tells the node which key to update.

A particular key slot is considered active, and all transmitted traffic should be sent
using the active key.

Nodes decrypt any packets for which they have keys: both older and new keys.
Upon receipt of a packet which is encrypted (or authenticated in the
case of a broadcast) with a secKeyId larger (taking consideration that
secKeyId wraps at 254) than the active slot causes the node to change active slot pairs. 

This mechanism permits the JRC to provision new keys into all the nodes
while the network continues to use the existing keys. When the JRC is
certain that all (or enough) nodes have been provisioned with the new
keys, then the JRC causes a packet to be sent using the new key.  This
can be the JRC sending the next Enhanced Beacon or unicast traffic using
the new key if the JRC is also a regular member of the LLN.  

The frame goes out with the new keys, and upon receipt (and decryption)
of the new frame all receiving nodes will switch to the new active key.
Beacons or unicast traffic leaving those nodes will then use the new
key, which causes an update of additional peers, and the network will
switch over in a flood-fill fashion. 

    > In the case of classical Observe, this would be a CON Observe
    > notification, followed by an empty ACK from the client.

    > In the case a joined node exposes a resource (e.g. /j) that the JRC
    > POSTs to, the ACK would be piggybacked with the 2.04 Created response.

I'm unclear if you want to stick with OBSERVE, or if you want to expose
a management interface.

-- 
]               Never tell me the odds!                 | ipv6 mesh networks [ 
]   Michael Richardson, Sandelman Software Works        | network architect  [ 
]     [email-masked]  http://www.sandelman.ca/        |   ruby on rails    [

---

From: Michael Richardson <[email-masked]>
Date: Tue, 24 Apr 2018 17:06:43 -0400

Mališa Vučinić <[email-masked]> wrote:
    mcr> I'd say that you always do this with any new key if you
    mcr> have no keys.
    mcr> I don't think we need a flag.
            
    mcr> In fact, even for the "0th key", you would start using it
    mcr> as soon as you see
    mcr> something that passes with that key, such as
    mcr> authenticating the Beacon that
    mcr> you used to find the Proxy in the first place....
            
    > Authenticating a beacon that was received long time ago would require
    > the pledge to store the beacon(s) for potentially an extensive
    > period... I don't think we need to do that.

No, I'm not suggesting one keeps it for along time.

What I'm saying is that, just after getting the Join Response, a pledge now has
some set of keys.  It will have an authentication key.  It could immediately
authenticate the Beacon that it used to find the Proxy.  That does a few things:

1) validate the Beacon!
2) since the key successfully validates the Beacon, it proves that the key the
   pledge got is a current key, and so the key would be marked as activated.

Of course, if the pledge doesn't have enough ram to keep the beacon around, then
it shouldn't do that.  It can validate the next beacon instead.

    > immediately, removing old keys, if any.
    
    > - joined node and pledge: installs the new key, keeps using the old
    > keys for outgoing traffic until it receives incoming traffic secured
    > with the new key, with all L2 security checks passed. In the special
    > case of a pledge, there shouldn't be any outgoing traffic before it
    > decrypts DIO(s) and selects a preferred parent.

Exactly.