Closed JRTI closed 6 years ago
Thanks for comments! Allow us to come back with a detailed answer but just briefly on Size-SID: That allows distinction between e.g. 0x00 and 0x0000 -- i.e. more SIDs available.
We are trying to finalize the draft now, so if you have more good comments, please consider make them soon!
Ohh, the choice of the association {SID, size(SID)} rather then SID only does indeed make sense, thanks for the clear-up !
I don't really have more comments, but at least one question that is not really editorial:
When that happens, we can probably do a signal for this either as an option or in the key context. I think that it should be solvable
Expanding a little. Both these parameters deal with information that needs to be available on encrypting and decrypting side. Currently they are established out of band to save overhead, but the external_aad make sure they are the same on both sides.
oscore_version is an extension point that is expected to be used e.g. if there will be security issues with rolling back from a future version to an older version of OSCORE (or CoAP). "algorithms" is another extension point to handle e.g. signatures in Group OSCORE. As Jim says, if we need to signal these parameters we can solve that later. With oscore_version, depending on the issue, it may be handled by "version" in CoAP. For algorithms my preference would be in flag bits: This is the analogue of the COSE header where we actually have omitted "alg".
BTW: Send me a email if you are interested in interop-testing your code.
Thank you both for the explanations !
I re-read it one last time and three things come to my mind:
first, regarding what you just explained here, you might want to add exactly what you told me "Currently [the "oscore_version" and the "algorithms" parameters] are established out of band to save overhead [and are thus never transported], but the external_aad make sure they are the same on both sides." to section 5.4. Since they are never mentionned anywhere else it is understandable that they are not to be transported, but stating this clearly would clarify things in my opinion.
second, you should probably rephrase part of the Sender Sequence Number bullet point in section 3.1. The sequence number is said to be "used by the sender to protect requests and Observe notifications", however no mention is made of the case of a non-Observe answer, and the reader has to wait until section 8.3 to learn that "If Observe is not used, either the nonce from the request is used or a new Partial IV is used (see bullet on 'Partial IV' in Section 5)." Adding something regarding the non-Observe answer, and qualifying this whole bullet-point using the IETF MUST/SHOULD/MAY might be a good idea here. I.E transforming it into something along the lines of:
"Sender Sequence Number. Non-negative integer used as 'Partial IV' [RFC8152] to generate unique nonces for the AEAD. The nonces generated from the Sender Sequence Number SHALL be used by the sender to protect requests and Observe notifications. If Observe is not used, the nonce from the request [SHOULD/MAY?] be used or a new nonce [SHOULD/MAY?] be generated fron the Sender Sequence Number. The maximum value is determined by the AEAD Algorithm."
To me, it seems like if the request nonce is not always used, the client needs a replay-window for answers if he has to keep track of the server's PIV. If this mechanism is not in place, a fraudulent proxy could just change the client CoAP token of an old answer and re-use it as many times as he wants as far as I can see, but maybe I'm overlooking something.
If we know in advance the request nonce is always used, either the server will actually answer directly using it, and since we know in advance which nonce it is going to use, we can choose to only accept this one for an answer, or the server will send an empty acknowledgement response and then send a request with the actual response in it, as is specified in Section 2.2 of the RFC for CoAP's, and this "separable response" is then covered by the recipient replay-window of the client. (I know only the server is required to have one, but I think most implementations will actually use one for both, even if it might have a smaller size.)
EDIT: regarding the interop-testing, this sadly won't be an open-source implementation that I own, and as such it is not my call to make, a decision will be made by the company I work for.
Hi,
Thank for giving us all the good feedback! I have now implemented many changes based on your comments:
changed Figure 8 to separate the padding and the padded information such as.
Added info about the single byte S in several sections
Added a note that some parameters (such as nonce and external_aad) are derived from the request.
Added the suggested text "if the partial IV is not present..." and some more info regarding this. Including more info when, and what the security implications are.
Added the suggested text on out-of-band
Regarding interop-testing, open-source is not necessary, we can arrange a online interop. Mališa Vucinic has also made an online cloud based interop-testing, so as long as you can give away pcap traces, it's fully possible to easily interop-test your code with other implementations.
@JRTI, I would like to add you to the Acknowledgments section but we don't know your name. If you send us your name, we add it to the acknowledgments section
The various additions look good to me! I don't really have much more comments, the rest would be unimportant nitpick ( ex: section 5.1 "The kid context is implicitly integrity protected, as manipulation that leads to the wrong key (or no key) being retrieved which results in an error, as described in Section 8.2." => I am not a native English-speaker, but to my knowledge there is a problem in this sentence's construction and it should be something like "The kid context is implicitly integrity protected, as [a] manipulation that leads to the wrong key (or no key) being retrieved [-] results in an error, as described in Section 8.2.") and I'm sure you'll have people proof-reading all of this.
Regarding the interop-test, I will wait for a decision from my Company and get back to you
@emanjon Thank you very much, it would be an honor!
I doubt the next part will be useful to the working group, however should a Google search return this page for people that have a few uncertainties:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
_______________________________________________________Test Vector 3: OSCORE Request, Client________________________________________________________
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
####################################################### ORIGINAL COAP: ########################################################
0x440149c60000f2a7396c6f63616c686f737483747631
COAP header token-value Options 1 2 3
440149c6 0000f2a7 39 6c6f63616 c6 86f737 483747631
Header: 440149c6 = 01 00 0100 000 00001 0100100111000110
version Type Token Length CoAP code Message ID
1 CON 4bytes 0.01(request.GET) 0x49C6
Options: 39 6c6f63616c686f7374 83 747631
1:
option-delta value-length option-delta-ext value-length-ext value
0x3+>0x03=>Uri-Host 9bytes / / 6c6f63616c686f7374="localhost"
2:
option-delta value-length option-delta-ext value-length-ext value
0x8+>0x0B=>Uri-Path 3bytes / / 747631="tv1"
####################################################### PROTECTED OSCORE: ########################################################
0x44026dd30000acc5396c6f63616c686f7374d305091400ff55b3710d47c611cd3924838a44
COAP header token-value Options OSCORE option payload-delimiter ciphertext (+MAC)
44026dd3 0000acc5 39 6c6f63616c686f7374 d305 091400 ff 55b3710d47c611cd3924838a44
Header: 44026DD3 = 01 00 0100 000 00010 0110110111010011
version Type Token Length Code Message ID
1 CON 4bytes 0.02(request.POST) 0x6DD3
Options: 39 6c6f63616c686f7374 d305 091400
1:
option-delta value-length option-delta-ext value-length-ext value
0x3+>0x03=>Uri-Host 9bytes / / 6c6f63616c686f7374="localhost"
2:
option-delta value-length option-delta-ext value-length-ext value
0xD=>8bit-delta-ext with -0xD+>0x15=>OSCORE 3bytes 0x05+0x0D=>0x12+>0x15=>OSCORE / 091400
OSCORE Option value: 09 1400
Reserved kid-context-flag kid-flag size-partial-IV Partial-IV kid-context-length kid-context kid
000 0+>no 1+>yes 001 00010100=0x14 / / 00000000=0x00
OSCORE message: 55b3710d47 c611cd3924838a44
Payload MAC
55b3710d47 c611cd3924838a44
=>decryption=> 01b3747631
=>
=> 01 b3747631
Inner CoAP code: 01
000 00001=0.01=> request.GET
InnerOption: b3 747631
option-delta value-length option-delta-ext value-length-ext value
0x0B+>0x0B=>Uri-Path 3bytes / / 747631="tv1"
EDIT: there was an error in the oscore option number calculation
Thanks! More comments or nits are welcome.
Hello, I am starting the very first tests of my implementation with the test vectors and I have some doubts regarding test vector 4 (https://core-wg.github.io/oscoap/draft-ietf-core-object-security.html#rfc.appendix.C.4) :
First of all : As far as I can see, the kid flag is redundant given that the size of the oscore option value is known beforehand (deserialization of the option's header), therefore the presence or not of the kid can always be known by checking whether or not the oscore option value contains more than what has already been deserialized.
In this test vector, the kid is "0x (0 byte)" and is as such not present in the OSCORE option value, however the actual option value is 0x0914 and 0x09 means
Reserved kid-context-flag kid-flag size-partial-IV
000 0 1 001
false true
^
|
surprising --------------------------------------+
so despite the kid not actually appearing in the message since it has a length of 0 bytes, the kid-flag is set to true.
Is this normal ?
If it is then I really don't understand the purpose of the kid flag : in which case would it be unset ?
EDIT 2: Side question just to be certain: section 5 (https://core-wg.github.io/oscoap/draft-ietf-core-object-security.html#cose-object ) specifies
All leading zeroes SHALL be removed when encoding the Partial IV, except in the case of value 0 which is encoded to the byte string 0x00
I am postulating this is all (leading) bytes having the value zero that are not serialized onto the medium, not literally all leading zeroes in the binary or hex representation ? Example where it matters: piv=0x00000001FF => Will it be serialized as '0x01FF' (size 16bits) or '0x1FF' (size 12 bits) or even '1b 0xFF' (size 9 bits)
From the way size is always given in bytes I hardly see how it could be the second or third case, but that's just to be certain
Hi,
To answer your question: the 0-length byte string (expressed as "0x" or "empty string" in the doc) is a correct Sender ID. This is different from "kid not present". The empty byte string is used as any non-0-length kid would, for example to find the correct keying material, or to derive the keys.
This is why we need the kid-flag: to distinguish between empty byte string and no kid at all.
The kid flag is unset if no kid is sent, which is the case for responses ( e.g. test vector 5 ) In this case the Client has already derived the keying material, and knows what context to use, see sect 8.1 point 6 :
Store the attribute-value pair (Token, {Security Context, PIV}) in order to be able to find the Recipient Context and the request_piv from the Token in the response."
I hope this answer your question.
Hi,
Thank you for this answer, it makes more sense, is the same also true for the kid-context, i.e. is an empty string valid for the kid-context ?
(I made a mistake when I postulated the question in the first edit from the previous message, so I removed it)
Yes that's right, empty string is valid for kid context too.
And about your side question: yes you are right, 0x00000001FF will be serialized as 0x01FF, we will rephrase that to something more precise. Thanks!
Very well, thank you!
Hello,
As far as I can see, there seems to be a problem on the 4 test-vectors of C1 and C2 (https://core-wg.github.io/oscoap/draft-ietf-core-object-security.html#key-der-tv-ms ) when it comes to the calculation of the common_iv. I do get the same result for sender and recipient key, but each time the common IV is not the same. I do obtain the same info for the common iV, but in the end the result of HKDF is just not the same. I am coding in C using this HKDF library (https://github.com/massar/rfc6234/blob/master/hkdf.c) and I have tested and obtained the same results in python with the following script (using the hkdf library from https://pypi.org/project/hkdf/) that I invite you to test.
from hkdf import Hkdf
import hashlib
from binascii import unhexlify,hexlify
print("C.1.1. Client\n")
kdf = Hkdf(unhexlify(b"9e7ca92223786340"),unhexlify(b"0102030405060708090a0b0c0d0e0f10"), hash=hashlib.sha256)
sender_key = kdf.expand( unhexlify(b"84400A634b657910"), 16)
recipient_key = kdf.expand( unhexlify(b"8441010A634b657910") , 16)
common_iv = kdf.expand( unhexlify(b"84400a6249560d") , 13)
print("sender_key:\t\t 0x"+ hexlify(sender_key)+"\nexpected:\t\t 0x7230aab3b549d94c9224aacc744e93ab\n")
print("recipient_key:\t\t 0x"+ hexlify(recipient_key)+"\nexpected:\t\t 0xe534a26a64aa3982e988e31f1e401e65\n")
print("common_iv:\t\t 0x"+ hexlify(common_iv)+"\nexpected:\t\t 0x01727733ab49ead385b18f7d91\n")
print("C.1.2. Server\n")
kdf = Hkdf(unhexlify(b"9e7ca92223786340"),unhexlify(b"0102030405060708090a0b0c0d0e0f10"), hash=hashlib.sha256)
sender_key = kdf.expand( unhexlify(b"8441010A634b657910"), 16)
recipient_key = kdf.expand( unhexlify(b"84400A634b657910") , 16)
common_iv = kdf.expand( unhexlify(b"84400a6249560d") , 13)
print("sender_key:\t\t 0x"+ hexlify(sender_key)+"\nexpected:\t\t 0xe534a26a64aa3982e988e31f1e401e65\n")
print("recipient_key:\t\t 0x"+ hexlify(recipient_key)+"\nexpected:\t\t 0x7230aab3b549d94c9224aacc744e93ab\n")
print("common_iv:\t\t 0x"+ hexlify(common_iv)+"\nexpected:\t\t 0x01727733ab49ead385b18f7d91\n")
print("C.2.1. Client\n")
kdf = Hkdf(unhexlify(b""),unhexlify(b"0102030405060708090a0b0c0d0e0f10"), hash=hashlib.sha256)
sender_key = kdf.expand( unhexlify(b"8441000A634b657910"), 16)
recipient_key = kdf.expand( unhexlify(b"8441010A634b657910") , 16)
common_iv = kdf.expand( unhexlify(b"84400a6249560d") , 13)
print("sender_key:\t\t 0x"+ hexlify(sender_key)+"\nexpected:\t\t 0xf8f3b887436285ed5a66f6026ac2cdc1\n")
print("recipient_key:\t\t 0x"+ hexlify(recipient_key)+"\nexpected:\t\t 0xd904cb101f7341c3f4c56c300fa69941\n")
print("common_iv:\t\t 0x"+ hexlify(common_iv)+"\nexpected:\t\t 0xd1a1949aa253278f34c528d2cc\n")
print("C.2.2. Server\n")
kdf = Hkdf(unhexlify(b""),unhexlify(b"0102030405060708090a0b0c0d0e0f10"), hash=hashlib.sha256)
sender_key = kdf.expand( unhexlify(b"8441010A634b657910"), 16)
recipient_key = kdf.expand( unhexlify(b"8441000A634b657910") , 16)
common_iv = kdf.expand( unhexlify(b"84400a6249560d") , 13)
print("sender_key:\t\t 0x"+ hexlify(sender_key)+"\nexpected:\t\t 0xd904cb101f7341c3f4c56c300fa69941\n")
print("recipient_key:\t\t 0x"+ hexlify(recipient_key)+"\nexpected:\t\t 0xf8f3b887436285ed5a66f6026ac2cdc1\n")
print("common_iv:\t\t 0x"+ hexlify(common_iv)+"\nexpected:\t\t 0xd1a1949aa253278f34c528d2cc\n")
Example of the difference at the bit level for the first one :
obtained :
0x9091b60715f92b3de49a011911 10010000100100011011011000000111000101011111100100101011001111011110010010011010000000010001100100010001
expected:
0x01727733ab49ead385b18f7d91 00000001011100100111011100110011101010110100100111101010110100111000010110110001100011110111110110010001
Hello,
Sorry for the double-post, I just wanted to make sure the previous message got your attention since a test-vector issue could be quite problematic. (I really hope I didn't just do a stupid mistake but as far as I can see there isn't one.)
I still haven't found the problem regarding the discrepancy between the common IV obtained by using HKDF on the data provided and the expected result for the 4 test-vectors of C1 and C2. (please look at my previous message for a more in-depth explanation)
For all those interested, please also find an additional test vector containing inner and outer CoAP options, an encrypted payload, a kid-context, and longer kid and partial IV below.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
____________________Unofficial Test Vector 1: OSCORE Request, Client____________________
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
This section contains a test vector for an OSCORE protected CoAP GET request using the
security context derived in Appendix C.1. The unprotected request contains the Uri-Host
"localhost" and Uri-Path "tv1" options and the payload "Hello World!". The kid-context
is present and has the value 0xDEADBEEF (4 bytes).
Unprotected CoAP request: 0x440149c60000f2a7396c6f63616c686f737483747631ff48656c6c6f20576f726c6421 (35 bytes)
kid-context: 0xDEADBEEF (4 bytes)
Common Context:
AEAD Algorithm: 10 (AES-CCM-16-64-128)
Key Derivation Function: HKDF SHA-256
Common IV: 0xd1a1949aa253278f34c528d2cc (13 bytes)
Sender Context:
Sender ID: 0x00 (1 byte)
Sender Key: 0xf8f3b887436285ed5a66f6026ac2cdc1 (16 bytes)
Sender Sequence Number: 20
The following COSE and cryptographic parameters are derived:
Partial IV: 0x150014 (3 bytes)
kid: 0x01253E (3 bytes)
external_aad: 0x8501810a4100411440 (9 bytes)
AAD: 0x8368456E637279707430404D8501810A4301253E4315001440 (21 bytes)
plaintext: 0x01b3747631 (5 bytes)
encryption key: 0xf8f3b887436285ed5a66f6026ac2cdc1 (16 bytes)
nonce: 0xd0a1949aa253278f34c53dd2d8 (13 bytes)
From the previous parameters, the following is derived:
OSCORE option value: 0x1B15001404DEADBEEF01253E (12 bytes)
ciphertext: 0x2F04C56B60DEE08352D61C5C2B00EB5A0C10102AE5BFD9D67997 (26 bytes)
From there:
Protected CoAP request (OSCORE message):
0x440249C60000F2A7396C6F63616C686F7374DC051B15001404DEADBEEF01253EFF2F04C56B60DEE08352D61C5C2B00EB5A0C10102AE5BFD9D67997 (59 bytes)
The complete rundown of the deserializaton of this test vector is as follows:
####################################################### ORIGINAL COAP: ########################################################
0x440149c60000f2a7396c6f63616c686f737483747631ff48656c6c6f20576f726c6421
COAP header token-value Options 1 2 3 payload marker payload
440149c6 0000f2a7 39 6c6f63616 c6 86f737 483747631 ff 48656c6c6f20576f726c6421
Header: 440149c6 = 01 00 0100 000 00001 0100100111000110
version Type Token Length CoAP code Message ID
1 CON 4bytes 0.01(request.GET) 0x49C6
Options: 39 6c6f63616c686f7374 83 747631
1:
option-delta value-length option-delta-ext value-length-ext value
0x3+>0x03=>Uri-Host 9bytes / / 6c6f63616c686f7374="localhost"
2:
option-delta value-length option-delta-ext value-length-ext value
0x8+>0x0B=>Uri-Path 3bytes / / 747631="tv1"
Payload: 48656c6c6f20576f726c6421 = "Hello World!"
####################################################### PROTECTED OSCORE: ########################################################
obtained:
0x440249C60000F2A7396C6F63616C686F7374DC051B15001404DEADBEEF01253EFF2F04C56B60DEE08352D61C5C2B00EB5A0C10102AE5BFD9D67997
COAP header token-value Options OSCORE option payload-delimiter ciphertext (+MAC)
440249C6 0000F2A7 39 6C6F63616C686F7374 DC05 1B15001404DEADBEEF01253E FF 55B3710D476F3CB38E45498876049B4795705FC85FBE5F631E25
Header: 440249C6 =
01 00 0100 000 00010 0100100111000110
version Type Token Length Code Message ID
1 CON 4bytes 0.02(request.POST) 0x49c6
Options: 39 6C6F63616C686F7374 DC05 1B15001404DEADBEEF01253E
1:
option-delta value-length option-delta-ext value-length-ext value
0x3+>0x03=>Uri-Host 9bytes / / 6c6f63616c686f7374="localhost"
2:
option-delta value-length option-delta-ext value-length-ext value
0xD=>8bit-delta-ext with -0xD+>0x15=>OSCORE 12 bytes 0x05+0x0D=>0x12+>0x15=>OSCORE / 1B15001404DEADBEEF01253E
OSCORE Option value: 1B 150014 04 DEADBEEF 01253E
Reserved kid-context-flag kid-flag size-partial-IV Partial-IV kid-context-length kid-context kid
000 1+>yes 1+>yes 011->3 0x150014 4bytes 0xDEADBEEF 0x01253e
OSCORE message: 2F04C56B60DEE08352D61C5C2B00EB5A0C10 102AE5BFD9D67997
Payload MAC
2F04C56B60DEE08352D61C5C2B00EB5A0C10 102AE5BFD9D67997
(AAD=0x8368456E637279707430404D8501810A4301253E4315001440)
=>decryption=> 01B3747631FF48656C6C6F20576F726C6421
=>
=> 01 B3747631 FF 48656C6C6F20576F726C6421
Inner CoAP code: 01
000 00001=0.01=> request.GET
Inner Option: B3 747631
option-delta value-length option-delta-ext value-length-ext value
0x0B+>0x0B=>Uri-Path 3bytes / / 747631="tv1"
Inner Payload: 48656C6C6F20576F726C6421 => "Hello World!"
EDIT: There needs to be changes to the above vector, because the kid is supposed to be the SID, meaning that the common iv needs to be changed with this kid
@JRTI: Sorry for the delay. Martin Gunnarsson had also confirmed an issue and has worked on new test vectors. May 1st is public holiday but hopefully there is an update here on the day after.
No problem, very well thank you !
Thank you @JRTI for pointing this out! It should be fixed now (re-created also the following test vectors to match the correction, as well as to match the ref that were not correct). Please let me know if you see any other oversights!
You're very welcome ! Small potential issue: since C5 and C6 are supposed to both be answers to C3, shouldn't they all have the same token as C3 ? C6 does have the same msg ID and token, but C5 does not which seems peculiar:
C3
CoAP: 0x4401 5d1f 00003974 396c6f63616c686f737483747631
OSCORE: 0x4402 5d1f 00003974 396c6f63616c686f7374d2050914ff1103eba88aee253823fe52f14b
C5
CoAP: 0x6445 39f8 0000b421 ff48656c6c6f20576f726c6421
OSCORE: 0x6444 39f8 0000b421 d008ff4e4f25d4179124f8f35a7c84b7bd989d0f063c5667fd
C6
CoAP: 0x6445 5d1f 00003974 ff48656c6c6f20576f726c6421
OSCORE: 0x6444 5d1f 00003974 d2080100fff27bab77519d76e016c03a4c4e6b1dd5f371d3e690ae
Good catch! Yes they should, I will fix that right away. And since the responses are piggybacked on an Ack (Type 2), the message ID should match too.
Hello,
Since I will start a test-implementation of the of the draft shortly, I tried to read the paper thoroughly, and here are a few suggestions from an outside perspective.
Same section 5.2 =>To be honest I don't understand the need for the Size-SID that you dubbed 'S' in the nonce construction: an SID is semantically a number, so the fact it is left padded with zeroes or not doesn't change anything semantically to retrieve it, therefore, since the length of the Partial-IV with its pad is fixed at 5 bytes, we know that the rest is the SID, why bother adding a size ?
In the appendix C.5 "test Vector 5: OSCORE Response, Server": As far as I can see, since the answer doesn't contain a partial IV, it uses the nonce of the request instead of computing a new one. However I think it should be clearly mentioned for this example, because the nonce is in the section named "The following COSE and cryptographic parameters are derived:" which would lead people to believe that the nonce is being calculated from the information of the two previous section. Should they then try to XOR the common IV 0xd1a1949aa253278f34c528d2cc and the output nonce 0xd0a1949aa253278f34c528d2d8 to check their prediction they would get 0x01000000000000000000000014 instead of 0x01000000000000010000000014 even thought the sender ID is 0x01 and not 0x00 here.
Personally, I found the text to be lacking a brief diagram reviewing the order in which things are supposed to be constructed. I have thus created the following tables showing the layout of the different additions based on my understanding of the message structure. Feel free to use/modify them as much as you want !
+=-=-=-=+=-=-=-=+-=-=-=-+-=-=-=-=+=-=-=-=+-=-=--=+=-=-=-=-=-+ | CoAP | CoAP | Class | OSCORE | Class |Payload|Ciphertext| | Header| Token | U&I | Option | U&I |Marker | | | | Value | CoAP | | CoAP | byte | | | | |Options| |Options|(0xFF) | | +=-=-=-=+=--=-=-+-=-=-=-+-=-=-=-=+=-=-=-=+-=-=-=-+=-=-=-=-=-+ | 4B | + | - | + | - | 1B | + | +-------+-------+-------+--------+-------+-------+----------+
OSCORE Message
+=-=-=-=-=-=-+=-=-=-=-=-+-=-=-=-=-=-=-+-=-=-=-=-=+ | Inner CoAP | Class E | Payload | CoAP | | Msg Code | CoAP | Marker | Payload | | | Options | byte (0xFF) | | +=-=-=-=-=-=-+=-=-=-=-=-+-=-=-=-=-=-=-+-=-=-=-=-=+ | 1B | - | 0/1B | - | +------------+----------+-------------+----------+
Plaintext to be encrypted to get the Ciphertext
+--=-=-=-+-=-=-=-=+-=-=-=+=-=-=-=+=-=-=-=+-=-=-=-=+-=-=-=-=+-=-+ |Reserved| kid- | kid- | Size |Partial| kid- | kid- |kid| | (000) |context-| flag |Partial| IV |context-|context-| | | | flag | | IV | | length | | | | | | |(bytes)| | | | | +--=-=-=-+-=-=-=-=+-=-=-=+=-=-=-=+=-=-=-=+-=-=-=-=+-=-=-=-=+-=-+ | 3b | 1b | 1b | 3b | - | 0/1B | - | - | +--------+--------+------+-------+-------+--------+--------+---+ OSCORE Option value
*if the partial IV is not present in an answer, it means the nonce of the request is used for the answer as well.