lp-wan / coap-compression

IETF LPWAN WG drafts for header compression
2 stars 6 forks source link

Protect the YANG model used to compress the message to maintain OSCORE results #9

Open chrysn opened 5 years ago

chrysn commented 5 years ago

When the device and the SCHC server subtly disagree on the compression rules applied, OSCORE decompression can still succeed, but the server arrives at a wrong unprotected message. This can happen because neither the expanded ciphertext nor the rules used wind up anywhere in the AAD.

I propose that a Class-I option be specified that contains a secure hash of a canonical representation of the rules used (probably "the rules used to compress the plaintext" to avoid circularity). On the LPWAN link, it would be compressed away completely by the rules for unprotected parts. If an ultra-small client is built that has all the SCHC rules compiled in, all that'll need is the static hash that gets fed into the external AAD at the right point in time.

As a nice side effect, the outer options can now be uncompressed at the SCHC server, and forwarded without tunneling to the host that actually has the key material. That host would still need to understand SCHC and have rules that produce the given hash, but it won't need to deal with all the rest of UDP compression or tunneling.

chrysn commented 4 years ago

To illustrate this for the benefit of readers of https://github.com/RustCrypto/traits/issues/62, SCHC would happen in two conceptional steps like this (probably with complete disregard for realistic compression):

On the LoRA "wire":

01 23 <19 bytes of ciphertext+tag>

gets decompressed into

PUT coap://oscore-server/                   # from LoRA address and "01"
OSCORE: { 'kid': '....',                    # still from LoRA address and "01"
         'piv': 35 }                        # from 0x23
Inner-SCHC: hash of "Set code to PUT,       \ # from LoRA address and "01"
    append Uri-Path 'temperature', take     \
    the first byte and place it in another  \
    Uri-Path, take the remainder as integer \
    X and place it in in JSON {'value': X}"
Payload: <19 byts of ciphertext+tag>

where the Inner-SCHC hash goes into the AAD, and only if that matches, the payload decrypts to

38 01 00

which decompresses by the hashed rules into

PUT
Uri-Path: /temperature/8
Payload: {'value': 256}

and then gets processed by the usual OSCORE merging rules into

PUT coap://oscore-server/temperature/8
Payload: {'value': 256}

which can be processed with all its relevant parts authenticated.

chrysn commented 4 years ago

An alternative to the Class-I option would be to commit a single OSCORE context to a single set of compression rules only. In that case, they need to be agreed on beforehand, and might go into the OSCORE info instead (or, possibly, it's even sufficient to not secure them cryptographically in OSCORE).