Subject: [core] OSCOAP: roll-out, recipient seqno, option number, sequence numbers

From: Christian Amsüss <[email-masked]>
Date: Wed, 4 Jan 2017 10:12:29 +0100

Hello OSCOAP authors,

getting familiar enough with OSCOAP to start an implementation, there
are some areas which are not fully clear to me from reading the draft:

* At least master secret and CID are preconfigured (that's assuming
  default algorithm, sender/receiver ID). It's out of scope for this
  spec, but are there any other drafts on how those should be rolled out
  / rolled over?

  * btw, why is algorithm a "SHALL" be pre-established (3.2) and the
    role IDs a "MAY" be predefined, if (as I understand) absence of
    pre-definition in both cases means fallback to defaults?

* speaking of "role IDs" to subsume sender and recipient ID, it
  strikes me as odd that sender and recipient contexts are qualitatively
  different (the former has a sequence number, the latter a replay
  window in 3.1), but the roles of Sender and Recipient in terms of used
  IDs stay the same when roles flip mid-conversation. Does that mean
  that once my server starts "asking back", it grows a recipient
  sequence number, and the former client grows a sender replay window?

* The option numbers are "to be done". Is there one that's already in
  use in first implementations? Could we pick one now and hope that all
  concurrent drafts become aware of its use so it stays stable, and if
  not just change it when going from draft to RFC? Or agree on one to
  use from the experimenal range until RFC release?

* Replay protection: The sequence numbers follow DTLS' anti-replay
  mechanisms, where DTLS sessions are (to my limited knowledge) more or
  less ephemeral.

  When a device with a precommissioned context encounters a factory
  reset condition, or any kind of mis-match happens between
  
  * the static context memory area of the keys,
  * the frequently modified window position possibly kept in log flash
    area, and
  * the bitfield inside the window (which I'd very much prefer not to
    commit to flash memory in embedded devices),
  
  is there any way to recover from such a situation, eg roughly by the
  recipient saying "I've heard all that, start at N or I can't trust you
  at all"?
  
  It might well be a bad idea to allow such a thing (at very least, that
  information needs to be authenticated), so right now this is primarily
  a question about whether there is a mechanism I missed, and whether
  there should be guidance considering the embedded use cases.

Could you help clarify these issues?

Thanks
Christian

-- 
To use raw power is to make yourself infinitely vulnerable to greater powers.
  -- Bene Gesserit axiom

---

From: Christian Amsüss <[email-masked]>
Date: Thu, 5 Jan 2017 14:23:28 +0100

Hello OSCOAP authors,

> are some areas which are not fully clear to me from reading the draft:

some more questions came up:

* 5.2 gives the context for the Enc_structure as "Encrypted", while
  cose-msg-24 would set a "Encrypt0". Why does that differ here?

* 5. states that the '"unprotected" field [...] SHALL be empty', but
  above states that sid 'can be placed in the unprotected headers
  bucket'. How do those statements go together?

* How are sequence numbers (which are sorted integers) mapped to partial
  IVs? Which endianness is used? (The padding direction follows from
  cose-msg-24 3.1).

  I'd assume (and implement) that big-endian is used because it aligns
  naturally with COSE's left-padding, but as I see it, that does not
  strictly follow from the draft.

* I concluded that the tag is always the last bytes of the ciphertext
  from example A.4, but did not find text in the spec to support that;
  what made me especially unsure about this is that the COSE_Encrypt0
  definition of cose-msg-24 5.2 only mentions the ciphertext there,
  which may be nil.

Best regards
Christian

---

From: Jim Schaad <[email-masked]>
Date: Thu, 5 Jan 2017 18:56:43 -0800

Christian,

While not an author on the drafts, I will take a stab at giving
clarification to your points.

See response below,

Jim

> -----Original Message-----
> From: core [mailto:[email-masked]] On Behalf Of Christian Amsüss
> Sent: Wednesday, January 04, 2017 1:12 AM
> To: [email-masked]; [email-masked]
> Subject: [core] OSCOAP: roll-out, recipient seqno, option number, sequence
> numbers
> 
> Hello OSCOAP authors,
> 
> getting familiar enough with OSCOAP to start an implementation, there are
> some areas which are not fully clear to me from reading the draft:
> 

There are indeed a couple of drafts that are looking a this:

Draft-ietf-ace-oath-authz provides an overview of how authentication and
authorization is going to work.  It uses draft-ietf-ace-cbor-web-token as a
message format to carry the keys from the auth server back to the client and
resource server.  It can run over either DTLS with
draft-gerdes-ace-dtls-authorize or OACAOP with
draft-selander-ace-coap-profile.

Additionally, draft-selnder-ace-cose-ecdhe provides for a way to get these
secrets based on pre-configured asymmetric keys or symmetric secrets.

>     pre-definition in both cases means fallback to defaults?

SHALL == MUST so there is no fallback on the algorithm.  I think that the
default on AEAD should be an MTI statement.  Yes the role IDs would default
to the default values as would the KDF function.   Given that there is no
negotiation on the replay window size, I don't think that there is really a
default here as an application can probably choose any size they want, it
will just effect the ability to cleanly pickup messages outside of the
replay window.

>   sequence number, and the former client grows a sender replay window?

In some sense, what you have stated above is correct.  The sequence number
is used for a nonce and thus needs to be unique for every message that I
send.  In another sense, what you have stated above is wrong in that for
most cases a device will be both a sender and a recipient and thus it will
have a sender context for all the messages it sends and a recipient context
for all of the messages that it can receive.  The same thing is true for
DTLS where there is a sending stream and a receiving stream and they are
handled differently.

Part of the confusion that you might be having at this point is the fact
that there is another draft running around
draft-tiloca-core-multicast-oscoap where you end up with a single sender
context, but potentially one recipient context for each of the multicast
receivers which can reply.  Since they did not want to make a clean
separation between these documents about how the context structures are
setup, I find that the section is a bit sloppy.

>   use from the experimenal range until RFC release?

I am using a dummy with mine, however I would not want to make it generally
known.  I would be willing to do one-on-one exchanges.  My assumption is
that a pre-assignment should be made something mid-month based on the F2F
conversation in Seoul.  

>   there should be guidance considering the embedded use cases.

The reset of the nonce is going to be a problem under all circumstances if
you go back to a clean factory state and you cannot store the appropriate
nonce in non-volatile memory.  Under these circumstances, the expectation
that I have is that the key you are using is also going to be lost so you no
longer have a key that can be used to encrypt messages and you will need to
go through a key establishment protocol (see the above drafts) to create a
new session encryption key.  This is going to be the same as with DTLS
either with a shared secret or an asymmetric key pair where a new session is
established.

---

From: Jim Schaad <[email-masked]>
Date: Thu, 5 Jan 2017 19:09:49 -0800

And some more possible answers

Jim

> Sent: Thursday, January 05, 2017 5:23 AM
> Subject: Re: [core] OSCOAP: roll-out, recipient seqno, option number,
sequence
>   cose-msg-24 would set a "Encrypt0". Why does that differ here?

I think that they (and I) missed a change in the COSE document.  This was
what it used to be.

>   bucket'. How do those statements go together?

Looks to me like when they address my comment on this they only got it
partly correctly.  If you look below, it says that 'sid' is going to be a
protected header field.

>   strictly follow from the draft.

I treated the sequence number as a network byte order integer packed into
the smallest possible byte string.  For the same reasons that you gave.

>   definition of cose-msg-24 5.2 only mentions the ciphertext there,

Feel free to assume that the tag is appended to the end of the cipher text.
This is going to be dependent on the algorithm that is being used and is
done in other ways for some different algorithms.  For example, there is one
algorithm (SIV mode) where the tag is the IV and is thus frequently
prepended to the cipher text.  It is true that there is a way not to include
the cipher text as part of a COSE message, however this is for a case of
detached cipher text.  Even in that case the tag is carried as part of the
cipher text it is just carried someplace else.  OSCOAP does not use detached
cipher text.

---

From: Göran Selander <[email-masked]>
Date: Mon, 9 Jan 2017 22:02:04 +0000

Hi Christian,

Thanks for very good comments, apologies for slow response. Jim has
already provided some answers, here are some more.

On 2017-01-06 03:56, "Jim Schaad" <[email-masked]> wrote:

>>are

I think Jim meant this draft:
https://tools.ietf.org/html/draft-seitz-ace-oscoap-profile

>secrets based on pre-configured asymmetric keys or symmetric secrets.

Certificate based authentication is also supported in
                   
https://tools.ietf.org/html/draft-selander-ace-cose-ecdhe

>will just effect the ability to cleanly pickup messages outside of the

The defaults should be MTI as Jim pointed out. See
https://github.com/core-wg/oscoap/issues/42

>DTLS where there is a sending stream and a receiving stream and they are

There may be some confusion here indicating that further clarification is
needed in the draft: Both nodes have all parts of the context;  common,
sender and recipient. Thus when a node sends it always uses the sender
part and when it receives the recipient part, regardless of its initial
role. Sender and recipient parts are mirrored between the two nodes,
oversimplifying: Node 1: SenderCtx=A RecipientCtx=B; Node 2: SenderCtx=B
RecipientCtx=A

See https://github.com/core-wg/oscoap/issues/43

>setup, I find that the section is a bit sloppy.

As Jim points out, the multicast case is covered in a separate draft. We
wanted to separate the security solutions for the different use cases
(unicast request-response, group communication/multicast with unicast
response, caching, pub-sub etc.) since otherwise the draft would be
unwieldy. The focus of OSCOAP is unicast request-response, but since group
communication/multicast can be supported with essentially the same
construct, we also wanted to prepare for that use case. Therefore this
draft defines recipient ID which is redundant in unicast but necessary
when there may be different unicast responses to one request. I think this
one thing Jim finds sloppy. The alternative would be to make different
message protection processing for unicast OSCOAP and multicast OSCOAP.

>that a pre-assignment should be made something mid-month based on the F2F

I think it would be useful if some authoritative person would propose a
tentative option number in the 0..255 range to use for this purpose, which
could later be confirmed or replaced.

>either with a shared secret or an asymmetric key pair where a new session

As Jim said, the security context should not be reused when a device is
reset. I agree that we should at least have some considerations in the
case of PSK in embedded devices and perhaps make some recommendations.

See https://github.com/core-wg/oscoap/issues/48

Göran

---

From: Göran Selander <[email-masked]>
Date: Mon, 9 Jan 2017 22:34:40 +0000

Additional answers.

>I think that they (and I) missed a change in the COSE document.  This was

Correct, a remnant from an older version of COSE.

>partly correctly.  If you look below, it says that 'sid' is going to be a

One statement is about the security requirements, the other is about the
format used. We already tried to clarify this (issue #15) but apparently
not sufficiently well so it is reopened:

https://github.com/core-wg/oscoap/issues/15

>the smallest possible byte string.  For the same reasons that you gave.

Indeed, this was not defined, we will update the document to require
network byte order. See  https://github.com/core-wg/oscoap/issues/44

>prepended to the cipher text.

As Jim says, this is algorithm dependent. We will clarify this.
https://github.com/core-wg/oscoap/issues/49

Göran

>It is true that there is a way not to include

---

From: Christian Amsüss <[email-masked]>
Date: Tue, 10 Jan 2017 08:08:58 +0100

On Mon, Jan 09, 2017 at 10:02:04PM +0000, Göran Selander wrote:
> >The reset of the nonce is going to be a problem under all
> >circumstances if you go back to a clean factory state and you cannot
> >store the appropriate nonce in non-volatile memory.
> 

My concern is not only for resets, but for persistence in general; flash
based devices (as in embedded flash with a few thousand erase cycles).
Writing to persistent memory on every transaction (shutdowns are not
clean on those devices in my experience) is not practical there.

In its sender context, a device could just lease out sequence numbers
from flash and leap ahead on reboot; eg. it would read the last used
sequence number as 1024 on reboot, write 2048, and count from 1025 to
2048 in RAM while sending until flash gets written to again. A power
outage then does no more harm than wasting some sequence numbers.

In its recipient context, if the device only stores something like the
end of its receive window on flash, it'll take the communication partner
up to window-size failed attempts (which it might not even be allowed to
repeat) to get in the clear.

Best regards
Christian

---

From: Göran Selander <[email-masked]>
Date: Fri, 13 Jan 2017 17:46:22 +0000

Hi Christian,

Inline:

>outage then does no more harm than wasting some sequence numbers.

Good proposal. Unless a new security context  is established, we should
mandate the sender to do something like this to prevent key and sequence
number/IV re-use. This applies both to client and server.

>repeat) to get in the clear.

But the replay window mechanism OSCOAP has inherited from DTLS and ESP is
sliding, so maintaining this state in the event of a shutdown would
require writing the “right" edge of the window to flash each time a new
highest sequence number has been received. I guess this is not desirable?

However, in this case replay protection can be addressed with the Repeat
option defined in 
https://tools.ietf.org/html/draft-mattsson-core-coap-actuators-02
On reboot, a server must not accept the first message received in a stored
security context, but respond with a Repeat option asking the client if it
recently made the request, and if so, to repeat the request using its
current sequence number, and include the same Repeat parameter for server
to verify freshness.

(The client reception behaviour after reboot is straightforward since the
client should only accept responses for requests made after reboot.)

I’ll make issues and draft text on this.

Göran

---

From: chrysn <[email-masked]>
Date: Tue, 17 Jan 2017 14:38:45 +0100

Hello Göran,

> highest sequence number has been received. I guess this is not desirable?

My impression was that the requirements of OSCOAP are only that
duplicate sequence numbers must not be accepted, and that all numbers
much smaller than the highest seen one may be considered seen. ("much
smaller" here means the window size, nothing should break if it's not
implemented as a bitfield but for example as a sufficiently long list of
numbers). Anyway, ...

> client should only accept responses for requests made after reboot.)

..., I don't see how either of this would help in the situation I
envisioned, which I might not have outlined to match my state of mind,
so I'd try again:

* We have a server and a client.
* Both can face unannounced shutdowns with no reserve to do a
  last-moment persistent write.
* Neither have the capability to do persistent writes after every
  network transaction. WLOG I'll assume that they'll only write to flash
  every 1000 network transactions.

(I'll focus on the server side of those constraints).

* The client starts using its seqno 1. The server accepts it, and marks
  all sequence numbers up to 1000 as seen in persistent memory, in order
  to function for 999 more transactions without flash writing. (It does
  keep a more detailed state in RAM).
* The server responds with its seqno 1, marking all seqnos up to 1000 as
  used.

The server now faces a power outage as above, and the client (none the
wiser) asks again:

* The client sends a request with seqno 2. The server discards it,
  because it was marked as "possibly already used".
* The server responds with unproteted 4.01[1], because it stopped
  processing the request as per 6.3 par. 1.

Even if the server used the actuators-02 Repeat option early enough (ie.
before OSCOAP validation kicks in and discards the message), it would
still not tell the client that it needs to advance it sequence number.
(And if it were to tell that, it'd need to be tightly interleaved with
the OSCOAP verification, because the "advance your seqno" information
could only be given to a client whose request passes all checks *except*
the early Partial IV check.)

How can we go about this?

All the best
Christian

[1]: or whatever is actually appropriate here, see
https://github.com/core-wg/oscoap/issues/53

---

From: Göran Selander <[email-masked]>
Date: Wed, 18 Jan 2017 10:19:35 +0000

Hi Christian, 

Inline

On 2017-01-17 14:38, "chrysn" <[email-masked]> wrote:

>duplicate sequence numbers must not be accepted,

Just to clarify, different messages created with the same security context
and IV/sequence number must be prevented because it breaks the security of
the encryption algorithm. Replay of old messages must be prevented to
protect from unnecessary message handling.

>and that all numbers
>  all sequence numbers up to 1000 as seen in persistent memory in order

Thanks for spelling out the details. I think you are right we need
something slightly more elaborate here. I believe there are two ways to
resolve the issue: Either the server gets verifiable information about the
current sequence number by the client, or the client gets information that
it should continue counting from the persistently stored sequence number.
Here is an attempt to address the latter:

When the server reboots and loads the sequence number from persistent
storage it is in a sequence number “ignorant" state and this state must be
monitored by OSCOAP: Assume a sequence number state parameter kept in the
recipient context and read out from persistent storage (where it is a
constant set to "ignorant”) when the security context is loaded into RAM.

If the a sequence number state parameter is set to “ignorant” and a
message is received and verified having a sequence number higher than that
in the recipient context, then the state is set to “not ignorant”. If the
state is set to "not ignorant” then the currently defined processing
applies. 

If the a sequence number state parameter is set to “ignorant” and a
message is received which has a sequence number lower that than that of
the recipient context (and greater than 0 to avoid this procedure when the
first message is sent using this context), then the server responds with
an error message TBD indicating that it has lost track of its recipient
sequence numbers.

The client receiving this error message loads the sequence number for this
context from persistent storage and resends the request.

Would something like that make sense?

(We would need to think more about the content of the error message, since
that may either require the server to produce a verifiable response even
though the request is not verified, or expose the client to sequence
number jump attacks from active attackers. The former is possible since
the server has loaded the sequence number for the sender context from the
persistent storage, and seems most relevant since this should be an
exceptional state of the server. Note that this works also in the case of
the client rebooting, e.g. due to the same power outage.)

Thanks
Göran

---

From: Göran Selander <[email-masked]>
Date: Mon, 23 Jan 2017 15:48:46 +0000

Hi Christian,

Another take on the sequence numbers, inline.

On 2017-01-17 14:38, "chrysn" <[email-masked]> wrote:

>* The client starts using its seqno 1.

This is the client sender seqno.

> The server accepts it,

This is the server recipient seqno.

>and marks
>  all sequence numbers up to 1000 as seen in persistent memory,

The client should mark sender seqno up to 1000 as seen in persistent
storage. The server recipient seqno is not stored in persistent memory.

> in order

This is the server sender seqno, all sequence numbers up to 1000 is marked
as seen in persistent storage. The client recipient seqno is not stored in
persistent memory.

>  because it was marked as "possibly already used".

Since the server has rebooted, it is aware of its ignorance of sequence
numbers, e.g. using the ignorance state parameter previously described in
security contexts existing before reboot. For requests to security context
where it is ignorant, it  includes in the OSCOAP response the Repeat
option with random value.

>the early Partial IV check.)

If the client can verify the response, it sends a new request with the
received value of the Repeat option (and stepped sequence number). The
client does not need to advance its sequence number, since there was no
sequence number advanced on the server side.

Instead the server only accepts the repeated OSCOAP request if it can be
verified and the Repeat option has same value as that previously sent in
response to the previous request. In this case the server updates the
sequence number in the recipient context to that of the verified request.

So, in summary, the procedure of persistently storing a new starting point
for sequence numbers in case of restart is only applied to sender sequence
numbers, and recipient sequence numbers are re-synchronised with a
challenge-response protocol.

Does this make more sense?

Göran

---

From: Jim Schaad <[email-masked]>
Date: Wed, 25 Jan 2017 13:18:25 -0800

I want to say that for the problem given, the only potential issue that needs to be address is the question of replay of messages.  That is if the server crashes, loads up the advanced sequence number and continues in a normal fashion, the only possible downside is that it will process the same request a second time because it failed to notice that it had already been processed.  Given the jump forward in sequence numbers, the server will never generate two messages with the same key, sequence number pair.  

This is not a problem for any idempotent message (i.e. a get).  A new response would be generated with a new sender sequence number and things would continue as normal.  The client would presumably ignore the duplicate response as it would not have any outstanding requests with that message id.  Replay would only be an issue for those requests which may cause a state change. In these cases, the client may have issued a request to get a change accomplished and the change was done but the notification was lost due to the crash.  The state change could also have been lost due to the crash.

This means that the repeat option solution given below for replay prevention need only to be use for those resources and requests that are potentially a problem with replay and only for long enough to flush any current messges that are active in the system.

Jim

> From: core [mailto:[email-masked]] On Behalf Of Göran Selander
> Sent: 23 January 2017 07:49
> To: chrysn <[email-masked]>
> Cc: [email-masked]; [email-masked]
> Subject: Re: [core] OSCOAP: [...], sequence numbers
> 
> Hi Christian,
> 
> >> >In its recipient context, if the device only stores something like
> >> >the end of its receive window on flash, it'll take the communication
> >>partner
> >> >up to window-size failed attempts (which it might not even be
> >> >allowed
> >>to
> >> But the replay window mechanism OSCOAP has inherited from DTLS and
> >>ESP is  sliding, so maintaining this state in the event of a shutdown
> >>would  require writing the “right" edge of the window to flash each
> >>time a new  highest sequence number has been received. I guess this is
> >>not desirable?
> >
> >implemented as a bitfield but for example as a sufficiently long list
> >of numbers). Anyway, ...
> >
> >> However, in this case replay protection can be addressed with the
> >>Repeat  option defined in
> >> On reboot, a server must not accept the first message received in a
> >>stored  security context, but respond with a Repeat option asking the
> >>client if it  recently made the request, and if so, to repeat the
> >>request using its  current sequence number, and include the same
> >>Repeat parameter for server  to verify freshness.
> >>
> >> (The client reception behaviour after reboot is straightforward since
> >>the  client should only accept responses for requests made after
> >>reboot.)
> >
> where it is ignorant, it  includes in the OSCOAP response the Repeat option
> with random value.
> 
> 
> >could only be given to a client whose request passes all checks
> >*except* the early Partial IV check.)
> 
> 
> If the client can verify the response, it sends a new request with the received
> value of the Repeat option (and stepped sequence number). The client does
> not need to advance its sequence number, since there was no sequence
> number advanced on the server side.
> 
> So, in summary, the procedure of persistently storing a new starting point for
> sequence numbers in case of restart is only applied to sender sequence
> _______________________________________________
> core mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/core