Subject: [COSE] RAM requirements for COSE/CWT

From: Anders Rundgren <[email-masked]>
Date: Mon, 21 Feb 2022 07:17:15 +0100

Pardon the cross-posting...

A pretty strange subject line, right? :)

However, there is a reality in the form of constrained devices that in order to use COSE must either turn to yucky infinite-length encoding (https://datatracker.ietf.org/doc/html/draft-ietf-rats-eat-11#section-8.3.1) or create the entire payload in RAM, here assuming that the exact size of the payload in bytes is not known in advance.

X.509 certificates (that were created in a time when virtually all devices were constrained) do not suffer from these problems due to their reliance on deterministic encoding, followed by a separate signature item.   A further advantage of the X.509 approach compared to COSE/CWT, is that the claims are not stuffed in a blob requiring yet another layer of decoding.  However, compared to ASN.1, CBOR is much more "RAM-friendly" since it doesn't impose a byte-length over items enclosed in a map or array.  Concatenation is all you need!

I believe the time has come to seriously look into alternatives to COSE since it was "inspired" by JOSE.   CBOR <<>> JSON.

This GitHub issue elaborates a bit more on this topic: https://github.com/ietf-rats-wg/eat/issues/168

Thanx,
Anders

---

From: Carsten Bormann <[email-masked]>
Date: Mon, 21 Feb 2022 08:03:48 +0100

Hi Anders,

> On 21. Feb 2022, at 07:17, Anders Rundgren <[email-masked]> wrote:
> 
> However, there is a reality in the form of constrained devices that in order to use COSE must either turn to yucky infinite-length encoding

Indefinite-length encoding (infinite-length encoding would be much harder :-).
No, it’s not yucky; it is there so you can use it if you need it.

> (https://datatracker.ietf.org/doc/html/draft-ietf-rats-eat-11#section-8.3.1) or create the entire payload in RAM, here assuming that the exact size of the payload in bytes is not known in advance.

To sign something you need to reify the signing input.  I don’t know why you think COSE is different here.
I’m not sure what you mean by "create the entire payload in RAM” — if you mean “at once” that is not the case.

> X.509 certificates (that were created in a time when virtually all devices were constrained) do not suffer from these problems due to their reliance on deterministic encoding, followed by a separat…

ASN.1 BER and CBOR have in common that a head precedes the data items controlled by this head.
Both have definite-length and indefinite-length encoding variants.
In definite-length BER (as used in DER), you need to know the lengths in bytes, so you need complex multi-pass strategies or back patching.
In CBOR you don’t need a length in bytes (except for strings); but for CBOR’s definite length encoding you still need the to know the number of enclosed items at the time of generating the head.

> I believe the time has come to seriously look into alternatives to COSE since it was "inspired" by JOSE.   CBOR <<>> JSON.

COSE was inspired by JOSE, but it avoids most of JOSE’s disadvantages.
Either because CBOR already trivially solves them, or by conscious design based on what we learned from the JOSE experience.

Grüße, Carsten

---

From: Hannes Tschofenig <[email-masked]>
Date: Mon, 21 Feb 2022 14:31:54 +0000

Hi Anders,

I assume you are focusing on signing the CWT (rather than also encrypting it).

The size of a CWT (with relevance to RATS) is fairly small and holding the CWT in RAM is not a problem. The example in https://datatracker.ietf.org/doc/html/draft-tschofenig-rats-psa-token-08 has 417 bytes.

I could, however, imagine to write an COSE implementation that does not require the entire CWT be held in RAM since the digital signature just covers the hash of the CWT and you can use a rolling hash.

Ciao
Hannes

-----Original Message-----
From: RATS <[email-masked]> On Behalf Of Anders Rundgren
Sent: Monday, February 21, 2022 7:17 AM
To: [email-masked]; [email-masked]
Subject: [Rats] RAM requirements for COSE/CWT

Thanx,
Anders

_______________________________________________
RATS mailing list
[email-masked]
https://www.ietf.org/mailman/listinfo/rats
IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

---

From: Laurence Lundblade <[email-masked]>
Date: Mon, 21 Feb 2022 08:07:45 -0800

> I could, however, imagine to write an COSE implementation that does not require the entire CWT be held in RAM since the digital signature just covers the hash of the CWT and you can use a rolling h…

No need to imagine. For signing, t_cose  <https://github.com/laurencelundblade/t_cose>allows you to create COSE headers, then CBOR-encode the payload an item at a time and then append the signature. t_cose does require the completed COSE message be in RAM, but not the input payload.

LL

---

From: Anders Rundgren <[email-masked]>
Date: Mon, 21 Feb 2022 17:15:56 +0100

> Hi Anders,

Hi Hannes,

> I assume you are focusing on signing the CWT (rather than also encrypting it).

I have (among many things) rather tried to figure out the rationale behind having a multitude of more or less incompatible serializations options for EAT.

Since I couldn't find any valid reason for using JSON, I looked into CBOR only :)

The rationale for https://datatracker.ietf.org/doc/html/draft-ietf-rats-eat-11#section-8.3.1 must be RAM considerations, right?.  If this is the case, PureEdDSA is also a hurdle.  Is EdDSAph in scope?

> The size of a CWT (with relevance to RATS) is fairly small and holding the CWT in RAM is not a problem. The example in https://datatracker.ietf.org/doc/html/draft-tschofenig-rats-psa-token-08 has 4…

That was my assumption also.

> I could, however, imagine to write an COSE implementation that does not require the entire CWT be held in RAM since the digital signature just covers the hash of the CWT and you can use a rolling h…

You mean that only the claims (payload) would be RAM-backed?  That should of course work.

Using the enhanced "COSE" scheme I outlined in the GitHub issue, you would in some (many?, all?) EAT cases need close to zero RAM if you also use a rolling hash.  Caveat: you must beforehand know how many items you are about to produce.

Cheers,
Anders

---

From: Carsten Bormann <[email-masked]>
Date: Mon, 21 Feb 2022 17:31:02 +0100

On 2022-02-21, at 17:15, Anders Rundgren <[email-masked]> wrote:
> 
> I couldn't find any valid reason for using JSON

We seem to have found an area where we agree :-)

Grüße, Carsten

---

From: Laurence Lundblade <[email-masked]>
Date: Mon, 21 Feb 2022 08:52:07 -0800

> We seem to have found an area where we agree :-)

Not out for a big debate here or to win hearts and minds, but here’s the reasons for JSON.

The overwhelming one is that JSON use in the world is something like ten times CBOR use. People and libraries that implement it well are a dime a dozen. CBOR isn’t even close.

EAT is not just for small embedded devices. People want to use it to prove one cloud service to another, to prove an Android app to a cloud service and so on.

EAT is used for both Attestation Evidence and Attestation Results. Attestation Results is a B-to-B interaction and most of them these days are JSON.

The RATS charter suggests (but does not require) work in both JSON and CBOR.

The big cross-bar diagram in RATS architecture <https://datatracker.ietf.org/doc/html/draft-ietf-rats-architecture-15#section-9> says that RATS should be adaptable to many encoding formats (CWT, JWT, TPM, X.509, other…), so we’re lucky we’re only having to do two.

I personally, would mostly be OK with CBOR/COSE/CWT, but it seems to me that JSON is so heavily used that we would be limiting RATS/EAT up take if we limited ourselves to it.

LL

---

From: Anders Rundgren <[email-masked]>
Date: Tue, 22 Feb 2022 06:59:01 +0100

> We seem to have found an area where we agree :-)

In this context, right :)
However, due to the myriad of CBOR serialization options, CWTs suffer from interoperability issues (*) making JWTs a better choice for *ubiquitous* usage :(

By *mandating* preferred serialization ("I-CBOR") you can achieve the same interoperability as with JWTs, as well as getting away from the need to bury data-to-be-signed in byte-strings.

Such solutions can also conserve buffer RAM in the case RAM is a scarce resource.  Yes, depending on the application your mileage may vary.

Cheers,
Anders

*) Looking at things from a *specification* point of view only.

---

From: Carsten Bormann <[email-masked]>
Date: Tue, 22 Feb 2022 10:08:17 +0100

Hi Anders,

> On 2022-02-22, at 06:59, Anders Rundgren <[email-masked]> wrote:
> 
> However, due to the myriad of CBOR serialization options,

Not true.
All widely used serialization formats grant the encoder some freedoms in encoding information, CBOR is not different.  There are no “options” that need to be chosen or known to the recipient; there is only one CBOR.

> CWTs suffer from interoperability issues (*)

Not true.  Pure FUD.

> making JWTs a better choice for *ubiquitous* usage :(

No

> By *mandating* preferred serialization ("I-CBOR") you can achieve the same 
> interoperability as with JWTs,

Nonsense.  
JWTs don’t use deterministic encoding, and neither does CWT need to to.

> as well as getting away from the need to bury data-to-be-signed in byte-strings.

Detached payloads solve that particular problem (if you have it).
Note that “burying” in CBOR is a simple copy (or reference), while JOSE needs to base64-encoding everything, often in a nested way.

> Such solutions can also conserve buffer RAM in the case RAM is a scarce resource.  Yes, depending on the application your mileage may vary.

CBOR saves RAM compared to JSON here.

Grüße, Carsten

---

From: Anders Rundgren <[email-masked]>
Date: Tue, 22 Feb 2022 15:00:18 +0100

On 2022-02-22 10:08, Carsten Bormann wrote:
<snip>>>

On 2022-02-22, at 06:59, Anders Rundgren <[email-masked]> wrote:
>> However, due to the myriad of CBOR serialization options,...
> 
> Not true.

Dear Carsten,

I have absolutely ZERO interest in criticizing You, CBOR, or COSE, I'm here to point out a problem which I have experienced both as an *enthusiastic* CBOR implementer and as a reviewer of various drafts.

The WebAuthn/FIDO specification details CBOR serialization requirements while the EAT draft specifies multiple alternatives.  There must be a reason for that.  To cope with (and potentially enforce/verify), different CBOR serialization variants, CBOR tools typically provide options: https://github.com/peteroupc/CBOR-Java/blob/master/api/com.upokecenter.cbor.CBOREncodeOptions.md

Anyway, it has been a while since CBOR was conceived.  In the mean time, Moore's Law has kept chugging along nicely, making previously unimaginable things like Apple's Max Pro chip with 58 Billion transistors a reality.  Obviously these developments trickle down to constrained devices as well.

The proposal is simply defining something like an "I-CBOR" that could serve as the foundation for future standards like EAT.

"I-CBOR" would (in my take on the matter), be CBOR's counterpart to ASN.1's DER.  RFC 8949 is just fine, but it doesn't take this concept the whole way: https://www.rfc-editor.org/rfc/rfc8949.html#name-additional-deterministic-en

Cheers,
Anders

---

From: Carsten Bormann <[email-masked]>
Date: Tue, 22 Feb 2022 15:50:07 +0100

Hi Anders,

> The WebAuthn/FIDO specification details CBOR serialization requirements

(As does COSE *for its internally constructed signing inputs*, not for what goes over the wire.)

> while the EAT draft specifies multiple alternatives.  

Maybe we need to fix that then.

> There must be a reason for that.  

The spirit is willing, but the flesh is weak.
Well, actually, the spirit is the problem.
We need to get better in the willpower to nail down unneeded choices.
(Of which JSON vs. CBOR is one.)

> To cope with (and potentially enforce/verify), different CBOR serialization variants, CBOR tools typically provide options: https://github.com/peteroupc/CBOR-Java/blob/master/api/com.upokecenter.cbor.CBOREncodeOptions.md

This is a bit of a Cadillac implementation with lots of options, many of which have to do with API variants as opposed to encoding options.
None of the latter ones will get in the way of EAT interoperability.

> The proposal is simply defining something like an "I-CBOR" that could serve as the foundation for future standards like EAT.

I-JSON was necessary because JSON implementations claim to have ingested something and then give you something else, unless you stay in the fold of I-JSON.
I’m not aware of a similar problem for CBOR, so I don’t know why we’d need I-CBOR.

Yes, because of historical artifacts we have different deterministic/“canonical” encoding rules — but that is of interest only where you *need* deterministic encoding.  COSE did the right thing and minimized that surface so it actually doesn’t matter which ones you are using.  (CTAP2 actually did that too, IIRC, they just wrote down some additional rules that they don’t actually need.  But I didn’t look at this for a while.)

If you really do need deterministic encoding, it’s right there in STD94 (RFC8949).  You need to remember that deterministic encoding spans all the way to the application, so slapping an I-something label on the encoder is not going to give you actual interoperability if you really do need deterministic encoding.

Do we?

Grüße, Carsten

---

From: Laurence Lundblade <[email-masked]>
Date: Tue, 22 Feb 2022 09:08:45 -0800

EAT allows for use of the different CBOR serializations just like COSE and CWT so particular deployments can choose what is best for them. It is important to continue to allow all serializations in EAT for the reasons that they exist in the first place.

The main example I can think of is EAT in pure HW (e.g., a TPM-like chip that outputs EAT). Outputting fixed length integers will make that HW simpler.

EAT goes one step further than COSE and CWT by pointing out that different serializations can cause interoperability issues and advises that a profile that specifies the serialization used be created for each use case. (Note that serialization variation is minor compared to algorithm selection and key identification and distribution)

It seems true to me that there are CBOR serialization variants that would not interoperate. Sounds a little bad and messy...

In reality, I don’t think it very bad because is very easy to support preferred serialization and because it is possible to create a decoder that supports all the serializations. Supporting these serializations doesn’t increase RAM and CPU usage much. We don’t hear any complaining from the real world about this and CBOR is getting close to ten years old.

LL

> On Feb 22, 2022, at 6:50 AM, Carsten Bormann <[email-masked]> wrote:
> 
> Hi Anders,
> 
> COSE mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/cose

---

From: Carsten Bormann <[email-masked]>
Date: Tue, 22 Feb 2022 20:09:15 +0100

> EAT allows for use of the different CBOR serializations just like COSE and CWT so particular deployments can choose what is best for them. It is important to continue to allow all serializations in…

This is confusing terminology.
You wouldn’t call putting space after a comma in JSON “different serializations”.
That is just the lenience that the format provides.

> The main example I can think of is EAT in pure HW (e.g., a TPM-like chip that outputs EAT). Outputting fixed length integers will make that HW simpler.

Any CBOR decoder will be happy with decoding this.

> EAT goes one step further than COSE and CWT by pointing out that different serializations can cause interoperability issues

There is only one place I have found so far where EAT actively causes an interoperability issue:  By ruling out preferred serialization for floating point values.  Creating a separate CBOR dialect by ruling out half-precision encoding might save 8 lines of C code in a decoder (which you can simply copy from https://www.rfc-editor.org/rfc/rfc8949.html#name-half-precision), but ensures that a standard CBOR encoder cannot be used without supplying encoding options.  Not a smart move.

> and advises that a profile that specifies the serialization used be created for each use case. (Note that serialization variation is minor compared to algorithm selection and key identification and distribution)

That is highly misleading.

> It seems true to me that there are CBOR serialization variants that would not interoperate. Sounds a little bad and messy...

If you create multiple incompatible variants by restricting the format, you can create non-interoperating dialects.  Don’t do that then.

> In reality, I don’t think it very bad because is very easy to support preferred serialization and because it is possible to create a decoder that supports all the serializations.

Absolutely.  So why do the options game here at all?

> Supporting these serializations doesn’t increase RAM and CPU usage much. We don’t hear any complaining from the real world about this and CBOR is getting close to ten years old.

Grüße, Carsten

---

From: Laurence Lundblade <[email-masked]>
Date: Tue, 22 Feb 2022 11:45:24 -0800

I’ve put the text that EAT has profiles CBOR encoding in below.

> On Feb 22, 2022, at 11:09 AM, Carsten Bormann <[email-masked]> wrote:
> 

True, but decoders aren’t actually required to so by RFC 8949, right? Second paragraph here <https://www.rfc-editor.org/rfc/rfc8949.html#name-preferred-serialization>.

> There is only one place I have found so far where EAT actively causes an interoperability issue:  By ruling out preferred serialization for floating point values.  Creating a separate CBOR dialect by ruling out half-precision encoding might save 8 lines of C code in a decoder (which you can simply copy from https://www.rfc-editor.org/rfc/rfc8949.html#name-half-precision),

It’s not just 8 line of code because it requires a floating library and/or floating-point hardware.  That isn’t available in some places. For example some implementations of Arm TrustZone don’t support it.

> but ensures that a standard CBOR encoder cannot be used without supplying encoding options.  Not a smart move.

Seems like it would be dumb for a CBOR encoder to use floating point for the cti claim. Would some really do that?

> If you create multiple incompatible variants by restricting the format, you can create non-interoperating dialects.  Don’t do that then.

The serialization that is of the most concern is indefinite lengths for strings and maps. CBOR, COSE and CWT all allow them and there is advantage to use them on the encoding side so they shouldn’t be ruled out.

The decode for them is definitely more work and makes the decoder larger.  For example, indefinite length strings need to be coalesced in to one and that requires a memory allocator or at least more memory management and copying than definite length strings. 

QCBOR’s decode API is the same for indefinite length maps and arrays as it for definite length maps and arrays, but that wasn’t easy to implement. I think some decoders require the protocol implementor to be conscious of the distinction.

I think the indefinite length interoperability problem is not large, because indefinite lengths are rarely used, but it is still something.

I’m open to suggestions on how to better handle this in EAT.

LL

Text from EAT’s profile discussion

7.2.2.  <file:///Users/lgl/Documents/EAT/eat-drafts/master-ref/draft-ietf-rats-eat.html#section-7.2.2>CBOR Map and Array Encoding <file:///Users/lgl/Documents/EAT/eat-drafts/master-ref/draft-ietf-rats-eat.html#name-cbor-map-and-array-encoding>
The profile should indicate whether definite-length arrays/maps, indefinite-length arrays/maps or both are allowed. A good default is to allow only definite-length arrays/maps. <file:///Users/lgl/Documents/EAT/eat-drafts/master-ref/draft-ietf-rats-eat.html#section-7.2.2-1>
An alternate is to allow both definite and indefinite-length arrays/maps. The decoder should accept either. Encoders that need to fit on very small hardware or be actually implement in hardware can use indefinite-length encoding. <file:///Users/lgl/Documents/EAT/eat-drafts/master-ref/draft-ietf-rats-eat.html#section-7.2.2-2>
This applies to individual EAT claims, CWT and COSE parts of the implementation. <file:///Users/lgl/Documents/EAT/eat-drafts/master-ref/draft-ietf-rats-eat.html#section-7.2.2-3>
7.2.3.  <file:///Users/lgl/Documents/EAT/eat-drafts/master-ref/draft-ietf-rats-eat.html#section-7.2.3>CBOR String Encoding <file:///Users/lgl/Documents/EAT/eat-drafts/master-ref/draft-ietf-rats-eat.html#name-cbor-string-encoding>
The profile should indicate whether definite-length strings, indefinite-length strings or both are allowed. A good default is to allow only definite-length strings. As with map and array encoding, allowing indefinite-length strings can be beneficial for some smaller implementations. <file:///Users/lgl/Documents/EAT/eat-drafts/master-ref/draft-ietf-rats-eat.html#section-7.2.3-1>
7.2.4.  <file:///Users/lgl/Documents/EAT/eat-drafts/master-ref/draft-ietf-rats-eat.html#section-7.2.4>CBOR Preferred Serialization <file:///Users/lgl/Documents/EAT/eat-drafts/master-ref/draft-ietf-rats-eat.html#name-cbor-preferred-serializatio>
The profile should indicate whether encoders must use preferred serialization. The profile should indicate whether decoders must accept non-preferred serialization.

---

From: Carsten Bormann <[email-masked]>
Date: Tue, 22 Feb 2022 22:19:22 +0100

On 2022-02-22, at 20:45, Laurence Lundblade <[email-masked]> wrote:
> True, but decoders aren’t actually required to so by RFC 8949, right? Second paragraph here.

Generic CBOR decoders are.
You might cook up an application specific decoder for an application that doesn’t need non-preferred encoding, but that would not be a full CBOR decoder.

> It’s not just 8 line of code because it requires a floating library and/or floating-point hardware.  That isn’t available in some places. For example some implementations of Arm TrustZone don’t sup…

So what do you do with the lat/lon information then?
(The half.c code doesn’t actually need floating-point hardware, BTW, if you manage to do an ldexp in software.  But you don’t need to do that if you can’t process the data at all — just keep the undecoded representation then.)

> Seems like it would be dumb for a CBOR encoder to use floating point for the cti claim. Would some really do that?

This discussion was more about lat/lon.  
cti (label 7) is a byte string, so there is no such problem there.

> The serialization that is of the most concern is indefinite lengths for strings and maps. CBOR, COSE and CWT all allow them and there is advantage to use them on the encoding side so they shouldn’t…

Right, for data objects that need “streaming” (write to network while still being generated).  Not so sure about objects that need to be signed.

But your point is that the decision to not allow indefinite length strings may be a significant win for the decoder, so that is a valid case for having an encoding option.  But the decoder doesn’t have to know that this option was enabled on the encoder side, so there is no interoperability problem.

> The decode for them is definitely more work and makes the decoder larger.  For example, indefinite length strings need to be coalesced in to one and that requires a memory allocator or at least mor…

(Or you can just use the partial strings in sequence.)

> QCBOR’s decode API is the same for indefinite length maps and arrays as it for definite length maps and arrays, but that wasn’t easy to implement. I think some decoders require the protocol impleme…

Right, a constrained decoder would usually offer the string segments in an indefinite length string separately.  I don’t know what part of the API needed to be different for maps and arrays, but you can sure define one where that is the case.

> I think the indefinite length interoperability problem is not large, because indefinite lengths are rarely used, but it is still something.

Well, rarely used is little consolation if your car door doesn’t open :-)

> I’m open to suggestions on how to better handle this in EAT.

I think you should try not to open the whole smörgåsbord, but only discuss the cases where a significant win can be made.  But for something as small as an EAT, maybe restricting strings to definite length might be a valid choice.

Grüße, Carsten

> 7.2.2. CBOR Map and Array Encoding
> The profile should indicate whether definite-length arrays/maps, indefinite-length arrays/maps or both are allowed. A good default is to allow only definite-length arrays/maps.
> An alternate is to allow both definite and indefinite-length arrays/maps. The decoder should accept either. Encoders that need to fit on very small hardware or be actually implement in hardware can use indefinite-length encoding.
> This applies to individual EAT claims, CWT and COSE parts of the implementation.
> 7.2.3. CBOR String Encoding
> The profile should indicate whether definite-length strings, indefinite-length strings or both are allowed. A good default is to allow only definite-length strings. As with map and array encoding, allowing indefinite-length strings can be beneficial for some smaller implementations.
> 7.2.4. CBOR Preferred Serialization

---

From: Anders Rundgren <[email-masked]>
Date: Wed, 23 Feb 2022 09:04:45 +0100

Hi Folks,

IMO, deterministic serialization makes no sense if decoders anyway are more or less obliged to cope with anything that smells like CBOR.

As a comparison, JavaScript's JSON object offers zero serialization options (*). This enables users to concentrate on their application. The same goes for Google's Protocol Buffer.

There is obviously (IMO of course...), room for a comparable (but potentially better) solution for CBOR.  I would be interested to hear how YOU would design such a thing.

BTW, deterministic encoding of IEEE 754 numbers can be performed without a math library:
https://github.com/cyberphone/openkeystore/blob/82543e8b7ad421e950366ed6a4acac4c3311f64d/library/src/org/webpki/cbor/CBORFloatingPoint.java#L47
https://github.com/laurencelundblade/QCBOR/blob/master/src/ieee754.c

Cheers,
Anders

*) For you nit-pickers: That 1.0 and 1 are equivalent may be regarded as a serialization option but that's not comparable to more fundamental stuff like indefinite-length encoding.

---

From: Carsten Bormann <[email-masked]>
Date: Wed, 23 Feb 2022 09:55:26 +0100

> IMO, deterministic serialization makes no sense if decoders anyway are more or less obliged to cope with anything that smells like CBOR.

The wording you use here indicates that you don’t really have a technical point.

CBOR is a precisely defined format.
We don’t have a “smells like” property; we do have “well-formed”.
A generic decoder needs to handle well-formed CBOR.
That is not complicated.

(Deterministic serialization makes sense when you need deterministic serialization.
It is *not* about reducing work for the decoder.)

> As a comparison, JavaScript's JSON object offers zero serialization options (*). This enables users to concentrate on their application. The same goes for Google's Protocol Buffer.

And for many generic CBOR encoders.

Specifications that use CBOR but somehow restrict encodings for a data item to a subset can cause complexity in the encoder.
Don’t do that, then, unless you really *need* to do it.  (Please fix EAT; stop doing this.)
What you think is a little tweak simply ensures that you can’t use generic encoders; this is a big loss.

Deterministic serialization is such a subset, which does have specific use cases, and I would expect its use to be a decision that is made being conscious of the added complexity.

> There is obviously (IMO of course...), room for a comparable (but potentially better) solution for CBOR.  I would be interested to hear how YOU would design such a thing.

It’s called STD94, and it is already done.

I’ll ignore the comments about JSON — the details here are mind-boggling, which is why I-JSON was needed.
(In the mind of Douglas Crockford, JSON is a “format” only, and the mapping between artifacts that conform to the grammar and application concepts is left as an exercise to the reader.  This led to interesting different interpretations, which tend to get in the way of interoperability.  Hence I-JSON.)

Grüße, Carsten

---

From: Anders Rundgren <[email-masked]>
Date: Wed, 23 Feb 2022 10:37:16 +0100

> On 23. Feb 2022, at 09:04, Anders Rundgren <[email-masked]> wrote:
<snip>
> Don’t do that, then, unless you really *need* to do it.  (Please fix EAT; stop doing this.)

So your advice to EAT is to scrap specific serialization requirements?

That's OK since since RATS/EAT haven't come up with any rationale for it.

Cheers,
Anders

---

From: Laurence Lundblade <[email-masked]>
Date: Wed, 23 Feb 2022 11:24:50 -0800

> On Feb 22, 2022, at 1:19 PM, Carsten Bormann <[email-masked]> wrote:
> 

I know in reality most decoders will handle non-preferred serialization, but I don’t see anything in section 5.2  <https://www.rfc-editor.org/rfc/rfc8949.html#name-generic-encoders-and-decode>that says that they must. (non-preferred is still well formed).

> (The half.c code doesn’t actually need floating-point hardware, BTW, if you manage to do an ldexp in software.  But you don’t need to do that if you can’t process the data at all — just keep the un…

Understood.

Pulling an ldexp library could be a big deal. It could increase code size by a lot.

> cti (label 7) is a byte string, so there is no such problem there.

Lat/long needs double precision float to be useful to beings the size of humans on a planet of earth's size. Half-precision has so little precision on a planet of earth's size that it is useless for location.

I mis-remembered “iat” as “cti”. Iat is a time stamp. A uint64 can represent everything needed for a time stamp, 1 second precision and +/- 500 million years. Float adds no value.

So EAT
- disallows half-precision in location, but allows doubles to relieve a decoder from implementing half-precision
- disallows float for iat to relieve a decoder from implementing float, assuming it is not implementing location (many EAT implementations will not support location)

There is no general requirement related to float for all claims in EAT. Future claims are free to do what they want.

I’m trying to be thorough and considerate of the receiver here so they know exactly what they have to do and so the requirements are minimized. Definitely open to changes here.

> I think you should try not to open the whole smörgåsbord, but only discuss the cases where a significant win can be made.  But for something as small as an EAT, maybe restricting strings to definit…

My consideration is for the whole receiving EAT stack. A generic decoder may pass string chunks up or map/array items up and still be a good generic decoder, but that doesn’t mean the receiver (a Verifier or RP) can decode the whole thing if it hasn’t done the extra work to decode indefinite length strings, maps and arrays.

At this point I assume there are some EAT use cases that will benefit from indefinite lengths. Very very few will need it, but I don’t think it should be completely excluded (COSE and CWT don’t exclude it). It would probably be an EAT encoder implemented entirely in HW with very little memory.

If we don’t exclude it completely, then a truly complete profile that truly guarantees interoperability needs to say whether it allowed or not.

So the three sections below on CBOR serialization for profiles still seem to hold to me. Overwhelmingly they will be no on indefinite lengths and yes on preferred serialization.

LL

---

From: Carsten Bormann <[email-masked]>
Date: Wed, 23 Feb 2022 22:08:34 +0100

(Pulled in CBOR WG because this is a recurring theme:)

Hi Laurence,

> 
> I know in reality most decoders will handle non-preferred serialization, but I don’t see anything in section 5.2 that says that they must. (non-preferred is still well formed).

What part of the first sentence of section 5.2:

>> A generic CBOR decoder can decode all well-formed encoded CBOR data items and present the data items to an application.

...could we have phrased better?

> Pulling an ldexp library could be a big deal. It could increase code size by a lot.

Yes. 
I should probably write some alternative C code that is a couple lines longer but doesn’t need ldexp.
(But what do you do with the binary32 then?)

> Lat/long needs double precision float to be useful to beings the size of humans on a planet of earth's size. Half-precision has so little precision on a planet of earth's size that it is useless fo…

That is not what this is about.

Saying “You need 16 bits to express the unsigned integer weight of a street vehicle in kg” does not mean that I can’t encode the weight of my bike in 8 bits.
What the current text in EAT says is equivalent to "you can’t ever use 8 bits because some vehicles need 16".  That is not smart.

> I mis-remembered “iat” as “cti”. Iat is a time stamp. A uint64 can represent everything needed for a time stamp, 1 second precision and +/- 500 million years. Float adds no value.

Right, but that is OK: It is a restriction at the data model level.  You are asking the application not to feed floats into the generic encoder.

(Note that we strengthened the little wall between integer and floating point for RFC 8949, after seeing that RFC 7049 was confusing people a lot.)

> - disallows half-precision in location, but allows doubles to relieve a decoder from implementing half-precision

Bad.  Half-precision (binary16) is not a different type at the data model level, it is just an efficient way to represent certain numbers in your data model.
Binary16 has a significand [sic] precision of 11 bits.  Binary32 has 24 bits.
So if you feed random binary32 lat/lon (~ meter precision) to your generic encoder, every 8192th will be encoded in half-precision (*).

Since lat/lon values are probably approximately evenly distributed, that by itself is not a reason to implement half-precision.
The fact that CBOR preferred encoding does employ half-precision is.
Deviating from that by disallowing binary16 is expensive: You no longer can employ generic encoders.

Don’t do that.

> - disallows float for iat to relieve a decoder from implementing float, assuming it is not implementing location (many EAT implementations will not support location)

Good(**).  That selection of integer second timestamps is a part of your data model.  
You can do that, and no generic encoder will suddenly turn your integer iat number into a float.
(Again, with RFC 7049, it possibly could have, but we fixed that.)

Grüße, Carsten

(*) Note that a similar thing happens in JSON: numbers that happen to be whole numbers will be encoded without fractional parts (10.0 becomes 10).
In certain decoder implementations, that makes them a different “type" than 10.0 or 1e1 or 0.1e2 etc., causing breakage.
But the JSON data model only has numbers, not integers as a separate, incompatible type, so these decoders are broken with applications that simply expect numbers.
(Find ISO 6093:1985 for some fascinating history in this space :-)

(**) ((I’m not making any representation on whether applications need to know with a precision of smaller than a second when your EAT was issued.  
I really can’t imagine that, but that is proof by lack of imagination; I do assess that the cost of enabling that is higher than the benefits.  
But that is true until someone has a convincing counterexample…  
Consolation is that these people can introduce a float iat = “fiat” :-)))

---

From: Laurence Lundblade <[email-masked]>
Date: Wed, 23 Feb 2022 13:36:56 -0800

> On Feb 23, 2022, at 1:08 PM, Carsten Bormann <[email-masked]> wrote:
>> 

I did that with shifts and masks and got a good education about floating point. :-)

More on the other parts later. Appreciate the discussion.

LL

---

From: Michael Richardson <[email-masked]>
Date: Wed, 23 Feb 2022 17:42:58 -0500

I've read the exchange between Laurence and Carsten and Anders.

If we accept that the only constrained part will be the Attesting Environment
on the Attester, and that all other systems (Verifier, RP) are at least >
class 2 (RFC7228), then we clearly should be optimizing for ease of encoding.

While my experiences with Op-Tee is rather shallow (I compiled it once),
my impression is that it is at least class 2 in size.  A bit of memory
allocation won't be a problem, or pre-allocating a few kilobytes for the CWT
won't be a problem.

I have experience with QCBOR, TinyCBOR and NanoCBR.
My experience is that indefinite length strings are not really needed as long
as one is encoding into a memory buffer.  Noting where the length box is and
filling it in later isn't impossible, but it certainly is harder if one
doesn't have an estimate of the size to know which integer size to use.
Worst case, one can assume that the strings can't exceed the size of the
output buffer!

My claim that an output buffer is needed is that we are going to sign it all,
and while one can construct SHA256 hash calculators that don't need the bytes all
in a row, it's such a pain to do generically, that if one is doing it, one is
creating a bespoke hasher.

I see no strong reason to rule indefinite encodings out: Verifiers and RPs should be
prepared to process them.  I would not encourage their use by encoders.

--
Michael Richardson <[email-masked]>   . o O ( IPv6 IøT consulting )
           Sandelman Software Works Inc, Ottawa and Worldwide

---

From: Laurence Lundblade <[email-masked]>
Date: Wed, 23 Feb 2022 17:46:21 -0800

I believe the targets motivating full encoding variance for EAT are pure hardware implementations. Think of a TPM-like chip that outputs EAT. Or a HW IP core that ARM sells for your SoC.

I’m pretty sure this is quite possible without any SW (except the driver SW for the EAT attestation core, network stack and such that doesn’t need to be secure).

Experience with SW implementation like QCBOR is not particularly relevant.

LL

> On Feb 23, 2022, at 2:42 PM, Michael Richardson <[email-masked]> wrote:
> 
>

---

From: Anders Rundgren <[email-masked]>
Date: Thu, 24 Feb 2022 06:54:46 +0100

On 2022-02-24 2:46, Laurence Lundblade wrote:

> I believe the targets motivating full encoding variance for EAT are pure hardware implementations.

Although I may have misinterpreted Carsten, I think he rather objected to not have this as a default for *all* EAT objects since (in his mind) decoders are *obliged* to deal with this:
https://datatracker.ietf.org/doc/html/draft-ietf-rats-eat#section-8.3.1

> Think of a TPM-like chip that outputs EAT. Or a HW IP core that ARM sells for your SoC.

AFAIK, TPMs currently use DER-encoding which is way more complex than preferred serialization a la CBOR.  My guess is that these systems use precomputed data structures and only fill the blanks. In the early days of Android I had to create an XML Dsig.  I started with porting a pretty complex canoncalization library but later replaced it with a handful of "printf"-like lines.

You may not be aware of this, but there are hordes of people who do not like having their precious data wrapped in base64url (JWT) or bstr (CWT) unless it is proven necessary:
https://github.com/ietf-rats-wg/eat/issues/168#issuecomment-1045958031
This is another side of the coin which stretches far outside the scope of EAT.

Anyway, since you will only get one shot at this topic, I thought it was worth a discussion even if we don't come to the same conclusion :)

I leave it there.  In case you have a minute or two you may try out an on-line CBOR encoder+decoder+signature system that is not burdened by legacy:
https://test.webpki.org/csf-lab/home

Cheers,
Anders

---

From: Laurence Lundblade <[email-masked]>
Date: Mon, 28 Feb 2022 21:39:41 -0800

> ...could we have phrased better?

Well, um, maybe.  :-)

It’s a small sentence with potentially big implications. 

If your generic decoder is like the pseudo code the implications aren’t big, but for decoders like QCBOR that do a lot more work for you, the implications are large — deep combined nesting of interleaved definite length and indefinite lengths maps and arrays, huge indefinite length strings, multiple levels of tag nesting for a data item that is a map label, a nested set of maps that is used as a map label,…

I haven’t checked, but there might not be very many truly conformant generic decoders. QCBOR definitely isn’t, because it has limits like a max of 4GB for encoded input, max levels of map, array and tag nesting and such to be efficient with code size and memory.

That said, probably most decoders can handle non-preferred integers, the topic at hand, just fine because it is trivial.

Yes you are of course right that 5.2 that defines generic decoders says non-preferred serialization must be supported.

LL