Draft: draft-ietf-lake-edhoc

Commentary: First draft to address 
 Thanks . I actually thought about the text parts you commented on but I had worked too late to do something about it . About the connection i d type It should be C_x : bstr / -24 .. 23 , or do you see any reason to keep bstr / int ? 
 Maybe I would give a name ... Not enough creativity today . ( one - byte int ) ? Have n't checked that in all languages :-) Yes , that narrow range is a more accurate representation for what you are saying in the text . 
 Right , let 's first hear what people think . 
 I think the PR is ready for review ( thanks and Short summary : we may not be able to register as bstr / int . This proposal is based on ( and connection identifiers ) intrinsically being byte strings , but some can be represented as CBOR ints in EDHOC . and others , please have a look . 
 I do n't think enabling the shorter integer representation for all byte strings that parse as CBOR integers is worth it . By staying with -24 .. 23 , the integerness can easily be tested , as in b.size = = 1 & & ! ( b[0]&0xC0 ) & & ( ( b[0 ] & 0x1f ) < 0x18 ) and the integer can be extracted as ( b[0 ] & 0x1f ) ^ -((b[0 ] 4 ) & 0x1 ) ( untested code , but probably close ) . Allowing all integers means that the CBOR library needs to be called and there needs to be a way in that to handle unsuccessful results . All for a quite questionable additional benefit . 
 ( Assuming the conversion to integer is mandatory -- if it is not , this becomes an interop testing nightmare . ) 
 Thanks The changes to any length of integer representation was made for perceived simplicity by And yes , we must clarify that this is mandatory . 
 Let 's get some numbers on what we get from just - bytes ( 0 ) , -24 .. 23 ( 1 ) vs. any - integer ( 2 ): Clearly using any - integer is higher density ( and I admit to having been the one who started going about these densities initially ) , but really where is it relevant ? A system needs to use more than 257 identifiers before 1 vs 2 starts making a difference . And even then , things start to differ only for the EDHOC phase , there are ( as there have always been ) 256 1 - byte and 64k 2 - byte IDs for available for OSCORE , it 's just that some of them ( most of them , in either case ) need an extra byte to inhabit CBOR encodings . Constrained systems likely get away with picking their own identifiers exclusively from -24 .. 23 anyway . I think the larger question is " what is simpler ? " , and that depends by the use case : Picking a value from a series of pools ( sorted by preference for OSCORE use and then preference for EDHOC use ) unless it is taken : pools are h '' , ( -24 .. =23 ) , h'00 ' to h'ff ' with two holes , and the long strings . pools are h '' , ( -24 .. =23 ) , h'00 ' to h'ff ' with two holes , ( -256 .. =-25 ) , ( 24 .. 256 ) , h'0000 ' to  ' with four holes etc . Encoding a picked value is trivial either way . Verifying that the peer encoded its ID correctly -- does the party receiving the Cx really need to do this ? Decoding a peer 's byte encoded Cx -- again , does this even ever need to be done ? ( The OSCORE contexts are best stored indexed by recipient ID ) At least if the latest two are answered " no " ( but probably either way ) , I 'd say that 1 is easier to implement , and while the coding density differs by a factor of ~3 for the 2 - 3 byte values , it 's the same where it matters the most . 
 Sorry for the delay , now reverted to ( 1 ) . I did n't try to make the CDDL exclude the disallowed byte strings , but made a normative statement . Please check . 
 It looks good to me . 
 The PR looks quite clear to me . 
 There has been for some time a discussion in COSE about how to define integer - valued key identifiers : The extension of kid to bstr / int was previously agreed on the COSE mailing list but that is now revisited because of potential impact on existing COSE implementations . Three alternatives considered : Solution A ( currently assumed by EDHOC ) . kid = int / bytes   kid = bytes  = int / bytes   kid = bytes  = int At the time of writing there is one voice in preference for solution C and no objections . Does anyone see any issues with solutions B or C ( besides minor change in current implementations ) ? 
 made a proposal in the COSE mail thread above going into another direction [ 1 ] : The idea is that certain byte strings ( 48 to be precise ) should have integer representations in the interval -24 , ... , 23 ( which all have 1 - byte CBOR encoding : 37 , 36 , ... , 21 , 20 , 00 , 01 , ... , 17 ) In his mail [ 1 ] made a proposal for which these byte strings should be . [ 1 ] After an offlist discussion that part of the proposal was changed so that the byte strings which have integer representation are those for which there is an integer in the interval -24 .. 23 that happens to have this byte string as its CBOR encoding , i.e. : h'37 ' ,  ' , ... , h'21 ' , h'20 ' , h’00 ’ , h'01 ' , ... , h’17 ' 
 summary : ( 1 ) We simplify connection identifiers to only ever be byte strings . ( 2 ) credential identifiers stay CBOR maps , and we are focusing on efficiently representing the case where this map has a single kid ( which is , by the definition in COSE , a byte string ) . PLAINTEXT2 already has such an optimization for bstr ( simply unpacking that from the map value ) . In both cases , we provide a “ compact ” representation of byte strings in the range h’00 ’ to h’17 ’ and h’20 ’ to h’37 ’ ( 48 single byte strings total ) , representing the byte string as the integer -24 .. 23 that happens to have this byte string as its CBOR encoding . We define the “ preferred encoding ” of an application byte string ( connection i d or credential i d ) of this form to be the one - byte integer in these two choices . ( Did we say we need to disallow the non - preferred bstr form here ? ) So PLAINTEXT2 = ( IDCREDR / bstr / -24 .. 23 , … means that the bstr h’4711 ’ is a shortcut for { /kid/ 4 : h’4711 ’ } and that the int -13 Is a shortcut for { /kid/ 4 : h’2C ’ } 
 Following this line of thought , if Cx are ever only byte strings , then the mapping of Connection Identifiers to OSCORE Sender / Recipient ID can be simplified ; the Sender / Recipient ID equals the byte string . E.g. if CR is h'0a ' in diagnostic notation then Sender ID = 0x0a . The only complication is the format of EDHOC on the wire : C_x EDHOC bstr on the wire h ’’ 40 h’00 ’ 00 . . . h’09 ’ 09 h’0a ’ 10 . . . h’17 ’ 23 h’18 ’ 41 18 h’19 ’ 41 19 h’20 ’ -1 . . . h’37 ’ -24 h’38 ’ 41 38 . . . h’4711 ’ 42 47 11 
 See PR for a first sketch . 
 All : Note that there are two ( edit :) different # PRs ( and ) addressing this issue and identifiers in EDHOC in general . Which do you prefer ? 
 seems to be much more self - contained , keeping the onus for managing the compression from byte string to integer to the place where that compression is needed . 
 With the change proposed by  in I think there are no advantages left with , so I withdraw that proposal . 
 Resolved with merge of 
 Here 's a quick leaf - through .
Mailing list commentary: Indeed . So this is obviously an extension . Old implementations ca n’t use the new data items enabled by that extension . New implementations do n’t have problems with old data items , so we call this backwards compatible , but not forward compatible . We did n’t identify this as an extension point , so the lack of forward compatibility is likely to be universal — if you use an integer kid , old systems overwhelmingly will not understand you . Now , there is also API compatibility — can you upgrade the COSE library without upgrading the using application . I ’d like to ask those who are proposing kid = > int / bytes : are the two kid name spaces disjoint ( so you need an API extension , too ) , or is an integer kid just a way to express the same kid as was already possible to express using a byte string kid . Another way to say the latter is that all kids are byte strings and the integer representation is just a compressed way to express such a byte string . Obviously , the latter way to interpret kids is slightly less efficient , because there are now two ways to express certain kids . But the change is also local , i.e. you can do it in your library without changing anything else . If we go for the latter , we will want to make sure that in particular the integers -24 .. 23 map to useful byte strings and v.v . Note that there is no need to make these byte strings short ; e.g. , a decimal representation ( ‘ -24 ’ to ‘ -1 ’ and ‘ 0 ' to ’ 23 ’ in CBOR DN ) , or maybe an octal one ( ’ 50 ’ to ’ 77 ’ and ’ 00 ’ to ’ 27 ’ ) would work well . We do n’t even need to support integers outside -24 .. 23 . ,
For option A , tcose would reject the whole message . For option B or C , tcose would accept the message unless intkid was marked as critical , in which case it would correctly reject the message . There would be no way to get the intkid or even know it exists , though a future version of tcose will be more extensible in that regard . You can classify end - end systems using COSE kid into 3 : 1 ) mandatory — receiving app ca n’t function without a kid 2 ) kid not used 2a ) not used and reject the message if it is present 2b ) not used , do n’t care if it is present 3 ) optional , some messages can have a kid and it will be used , but there is some means other than a kid parameter for finding the key Note that this list is about kid , not about integer kid . Mandatory means it must have a kid the system can understand . Assuming tcose behavior , Option A works fine for systems 1 ) and 2a ) , but not 2b ) or 3 ) . Options B and C work for all system . Since integer kid is only for a small optimization you might be tempted to use the two - byte encoding for compatibility with all COSE libraries if the optimization is n’t absolutely critical . In coming vast spread of COSE use cases , the integer kid will only be used very rarely , so maybe better not to confuse the existing kid parameter . Now I am leaning towards B or C. LL
Paragraph (version A):
Connection identifiers in EDHOC are byte strings or integers, encoded
in CBOR.  One byte connection identifiers (the integers -24 to 23 and
the empty CBOR byte string h'') are realistic in many scenarios as
most constrained devices only have a few connections.  An endpoint
may choose to select only integer or only byte string connection
identifiers.
Paragraph (version A):
For OSCORE, the choice of connection identifier results in the
endpoint selecting its Recipient ID, see Section 3.1 of RFC8613, for
which certain uniqueness requirements apply, see Section 3.3 of
RFC8613.  Therefore, the Initiator and the Responder MUST NOT select
connection identifiers such that it results in same OSCORE Recipient
ID.  Since the Recipient ID is a byte string and an EDHOC connection
identifier is either a CBOR byte string or a CBOR integer, care must
be taken when selecting the connection identifiers and converting
them to Recipient IDs.  A mapping from EDHOC connection identifier to
OSCORE Recipient ID is specified in edhoc-to-oscore.
Paragraph (version B):
To allow identifiers with minimal overhead on the wire, certain byte
strings are defined to have integer representations.
Paragraph (version B):
As stated in Section 3.1 of I-D.ietf-cose-rfc8152bis-struct,
applications MUST NOT assume that 'kid' values are unique and several
keys associated with a 'kid' may need to be checked before the
correct one is found.  Applications might use additional information
such as 'kid context' or lower layers to determine which key to try
first.  Applications should strive to make ID_CRED_x as unique as
possible, since the recipient may otherwise have to try several keys.
Paragraph (version B):
C_I - variable length connection identifier.  Note that connection
identifiers are byte strings but certain values are represented as
integers in the message, see bstr-repr.
Paragraph (version B):
G_Y_CIPHERTEXT_2 - the concatenation of G_Y (i.e., the ephemeral
public key of the Responder) and CIPHERTEXT_2.
Paragraph (version B):
C_R - variable length connection identifier.  Note that connection
identifiers are byte strings but certain values are represented as
integers in the message, see bstr-repr.
Paragraph (version B):
Implementations MUST support 'kid' parameters.  None of the other
COSE header parameters are mandatory-to-implement.
Paragraph (version B):
Information regarding the lengths of ID_CRED_I, ID_CRED_R, EAD_2,
EAD_3, and EAD_4 are leaked to a passive attacker.  Many COSE header
parameters have variable length.  To mitigate an attacker from
differentiating endpoints with identifiers of different length, an
implementation may, e.g., only use fix length identifiers like 'kid'
with one-byte CBOR int representations for the Responders.
Alternatively padding may be used to hide the length of, e.g.,
certificates by value in 'x5chain' or 'c5c'.