Subject: [6tisch] My comments to the draft-ietf-6tisch-minimal-security-06

From: Tero Kivinen <[email-masked]>
Date: Thu, 28 Jun 2018 01:23:20 +0300

In section 3 there is text saying:

   The "network identifier" uniquely identifies the 6TiSCH network in
   the namespace managed by a JRC.  Typically, this is the 16-bit
   Personal Area Network Identifier (PAN ID) defined in [IEEE802.15.4].

Note, that the PAN ID is not stable. The PAN coordinator is expected
to change to use new PAN ID if it detect another network using the
same PAN ID, i.e., if there is PAN ID conflict. See section 6.3.2 of
the IEEE 802.15.4-2015.

Because of this it might be better to use something else as PAN ID if
stable network identifier is needed. Also in quite many cases the PAN
ID is not known beforehand, so configuring the PAN ID to the pledge is
challenging, as is describied in the section 4.

Using something like Network ID from the
draft-richardson-6tisch-enrollment-enhanced-beacon, would provide
better alternative.

--

In section 4 there is text saying:

    o Pre-Shared Key (PSK).  The JRC additionally needs to store the
      pledge identifier bound to the given PSK.  The PSK SHOULD be at
      least 128 bits in length, generated uniformly at random.  It is
      RECOMMENDED to generate the PSK with a cryptographically secure
      pseudorandom number generator.  Each (6LBR) pledge SHOULD be
      provisioned with a unique PSK.

This text is fine, but knowing that most of the vendors in this space
have been known to use unsafe methods like scrambling, encrypting,
hashing, or macing serial number or EUI-64 address to generate "random
unique PSKs" (or simply using fixed PSK for all devices), it might be
good idea to provide bit more emphasis on the unique properly
generated PSK, even when it is outside the actual scope of this
document. Or add something like that to the security considerations
section.

--

In section 5.2 there is text saying "How JP accepts these unprotected
frames is discussed in Section 6. ", but this same thing also applies
to the section 5.3.1 too. I.e., the Join request from the pledge to JP
is also unauthenticated and unencrypted.

Perhaps that should be noted also there.

--

In section 5.3.2 there is text saying:

                            The JP operates as the application-
   layer proxy, and does not keep any state to forward the message.

This is not completely true. It needs to keep state to know when the
pledge starts joining process and it needs to keep it until the pledge
finishes it as it needs to allow pledge to send unencrypted and
unauthenticated frames through it as explained in section 6.

I.e., JP do store state for each pledge, at least for the secExempt.
Also during this phase the pledge will be using its extended address,
so that is also used by the JP to know which pledges are in progess of
joining.

Also section 7 says that JP does keep separate neighbor cache for
untrusted entries, so that is even more state it will keep...

--

In section 6 there is text saying:

                                           How the JP learns
   whether the join process is ongoing is out of scope of this
   specification.

This is very important part of the process, and I think it should be
part of this document, and not out of scope for this document. Which
document will specify this if not this?

My guess is that JP willing to act as JP will receive first frame from
pledge and when it sees it, it will start joining process, start
forwarding the frames and mark that given extended address as
something that is allowed to bypass security by setting secExempt for
that extended address.

The question is how can the JP know when the pledge is done. Can it
just trust that there will be exactly one Join Response, and forward
that and then clear out the secExempt flag from its tables and forget
the pledge? Or should it just timeout the secExempt entries after
certain number of seconds of inactivity? Or even pledge sending some
kind of notify to JP using its extended address and link key to tell
he is done?

Fixing this here by specifying method for is solves the issue for
good, leaving it out of scope will make hard to debug problems when
different JPs uses different methods to know when pledge is done.

--

Again the section 7 says that it is out of scope how JP decides to
transtion from "untrusted to trusted cache".

The proposed solution given there does not work. The text says:

    	     	      	    	       One implementation
   technique is to use the information whether the incoming frames are
   secured at the link layer.

The unauthenticated and unencrypted frames use extended address as
their level 2 addresses. After joining process the pledge might move
to use short address provided to it by the JRC. As far as I understand
the message from JRC to pledge is encrypted, and JP cannot read it,
thus JP cannot learn what will be the short address matching the
pledge it has in its tables.

Of course it can guess, that if there is pledge with extended address
of 0x1234567812345678 and then suddenly there is new node with short
address of 0x0010, then most likely they are same, but this might not
be good idea to try to do guessing of the identities. Also outsiders
can also do the same guess, so they will be able to coordinate the
short address 0x0010 to the extended address quite easily, even when
the section 11 claims otherwise.

I think the overall protocol would be better if the JP would get
information about the successful completion of the joining process.
I.e., if the JRC sending frame to be forwarded to pledge by JP, would
also indicate something in the frame that tells JP that this pledge is
now done, and it can be removed from the untrusted neighbor cache, and
from the secExempt list.

--

In section 8.1. the ID of the pledge is 0x00, but ID of JRC is
0x4a5243. As far as I understood the OSCORE for the security it would
be enough to just use any different value for them, i.e., using 0x00
for pledge and 0x01 for JRC. Why does the JRC use 0x4a5243 ("JRC")
instead of just 0x01?

The pledge identifier is used as ID context, which is added to both
sender and recipient key generation so in all cases the final keys are
different even if the PSK is same as long as the pledge identifier is
unique. If pledge identifier and PSK are not unique, then we do have
nonce collision as both devices start with sequence number of 0. 

--

I was just about to point out about the persistency of the sequence
numbers, and I was more than happy to see that it was actually already
mentioned in the draft. Good work!

(My guess is that there is huge number of IoT devices which do not do
that properly)

--

In section 9.3.2 there is description about the rekey algorithm which
has following sentence:

							Upon
      reception and successful security processing of a link-layer frame
      secured with a key from the new key set, a non-6LBR node MUST
      remove any old keys it has installed from the previous key set.

I think it would be better to wait for a while before deleting the old
set, but immediately move to use the new set for transmissions. I.e.,
we might have node B and C, which both have old and new keys, their
parent A sends an EB with new keys out, but node C is not able to
receive it correctly. Now if C wants to send frame to A or B, it will
still be using old key as it has not yet seen any new frames. Both A
and B will throw that frame out as it is using old key. If this would
be changed to say that "node MUST remove any old keys after delay of N
seconds" (or delay of N slotframes or whatever). 

--

In section 9.3.2 there is text about link-layer short address, but
there is no requirement for the JRC, that mandates it to ensure that
it will be unique at any given time. I.e., the security of the network
will depend that there is never two sort address using same keys at
the same time. I.e., if JRC is restarted and its loosing the state of
which short addresses are allocated it MUST rekey the whole network
with newly generated key (and as it cannot do that by sending updates,
as it does not know who is part of network, it must force everybody to
rejoin).

If JRC gives out the short address without giving lease_time, it MUST
not ever reuse those short addresses. If it does give lease time it
should wait for some guard time before reusing short address that has
already been expired. This guard time should include cases where node
has sent out message and the message is waiting in transmit queue, but
has not been sent out yet, while the address expires, and node might
not have code to purge the tranmission from the queue. So adding guard
time that is in order of maximum wait time for sending frame or so,
would be good.

--

In section 9.3.2.2 there is text saying that "short address is unique
LOCALLY in the network". This is incorrect. It needs to be unique in
the whole network using the same key, i.e., globally in the network
using the same key and part of the same TSCH network. I know that some
vendors have been using duplicate short addresses for different parts
of the network, when there is no risk of them overhearing each other
for other 802.15.4 networks, but that is not safe to do in TSCH when
short addresses are used in the nonce.

I do understand that the text is trying to say it does not need to be
unique in the global internet, but in the local network it needs to be
unique globally inside the whole network.

Note, that short address of 0xfffe (associated, but not given short
address) and 0xffff (broadcast) are reserved in 802.15.4-2015 and
cannot be used. Also some other 802.15.4 extensions like L2R (layer 2
routing) 802.15.10 do reserve additional set of short addresses for
example for multicast (0xff00-0xfffd).

Most likely this text should be reflected to that, saying that if
address is 0xfffe, then pledge has joined the network, but JRC decided
not to give him short address (for example it is running out of them),
and the device should use extended address to talk to others.

If JRC gives out short address of 0xffff, then it should be considered
invalid. 
-- 
[email-masked]