According to RFC 5116... If the AD input is constructed out of multiple data elements, then it is essential that it be unambiguously parseable into its constituent elements, without the use of any unauthenticated data in the parsing process. (In mathematical terms, the AD input must be an injective function of the data elements.) If an application constructs its AD input in such a way that there are two distinct sets of data elements that result in the same AD value, then an attacker could cause a receiver to accept a bogus set by substituting one set for the other. The requirement that the AD be uniquely parseable ensures that this attack is not possible. This requirement is trivially met if the AD is composed of fixed-width elements. If the AD contains a variable-length string, for example, this requirement can be met by also including the length of the string in the AD.
I’m using an AEAD to confirm integrity on a message and occasionally decrypt a payload if it exists, but my issue should apply to any arbitrary data in CRC to HMAC. How do you take arbitrary data and unambiguously order it
Imagine I have some serialization (example JSON) that can have 1-100 fields I’ll assemble into data to be get a MAC (my AD in AEAD). The receiving end has no idea which ones are coming, and the ordering of decode is not guaranteed.
It seems my options are to order the object data in some predetermined way like apple’s value is placed into a byte array before bannana’s value is. But then there is an issue of types, in my system apples will only ever be 0-12 so one byte works great, but bananas can get to 65000, so two bytes, carrots need a 32bit, and I am owe dates so I need signed there. Or I have the option of using the serialized container without parsing it at all but there are other problems with that.
Without getting too over the top in examples, I see the issue even if I gave everything a 64bit space and put its length in front, I quickly end up with a confining system - or I end up with a schema that needs to be shared on both sides.
So are there any standards or even formally recommended practices for this?