On Sat, Sep 03, 2022 at 01:47:20PM -0500, Orie Steele wrote: > Thanks for this email, responses inline: > > On Sat, Sep 3, 2022 at 9:43 AM AJITOMI Daisuke <[email protected]> wrote: > > > Hi Hannes and folks > > > > > The challenge is that the COSE WG has already defined formats for > > certain public keys and, at least at the last IETF meeting, was in favor of > > using those existing key formats. > > > > Thanks for your information, I've watched the recorded IETF114 meeting. > > Regarding Ilari's proposal, I agreed with his attempt to treat ”enc" > > (encapsulated sender's public key) as an octet string, but I did not agree > > with his attempt to force the use of the COSE_Key structure, and I thought > > the current specification format was relatively better. > > > > One point of concern during the IETF 114 meeting was there were several > > erroneous comments that the fact that enc is an octet string is > > implementation-dependent. > > The fact that the output of KEM is an octet string of the raw key is > > specified by the HPKE specification so the comments are obvious > > misunderstandings. > > > > Anyway, both Ilari's proposal and the current draft are based on the use > > of COSE_Key for representing an enc (a sender's public key), which I > > believe has the following problems: > > > > 1) There is no guarantee that enc can be mapped to COSE_Key in the future, > > so if a new HPKE cipher suite is specified, it cannot be used on COSE > > immediately. Whenever a new cipher suite is added to HPKE, it is necessary > > to develop a mapping specification for COSE_Key (including alg/crv value > > registration to IANA) and implement an additional enc->COSE_Key conversion > > process in existing many COSE libraries. As a library implementer (I'm also > > a COSE/CWT implementer https://github.com/dajiaji/python-cwt ...), > > I cannot overlook this... > > > > I agree, this is a major problem.. but it's not limited to COSE, it's also > a concern for JOSE... and PGP.... and SSH... > > It is, in general, a function of the way we define registries for "keys", > "algorithms", "signatures" and "encryptions"... > > Your libraries will almost certainly need to support several RFCs to be > useful... and you may be required to publish several new RFCs (and update > several IANA registries) to add a new capability to an existing library.
Ideally there is only one RFC to publish and one IANA registry to update. Namely the RFC that defines how the algorithm works in HPKE, and the HPKE KEM, KDF or AEAD registry. That is, COSE-HPKE can generically use HPKE, without knowing about the internal details. > There have also been several publications from NIST and others since the > JOSE and COSE conventions were established... without getting into the > details of them, here are a couple design principles that lead me to > support the unfortunate need to make so many registry updates: > > 1. Keys should be used for one purpose, and under one algorithm. > 2. From 1, follows that kty, alg should be set at the time of key > generation... not after it, when a key gets used. > 3. Explicit over implicit > 4. From 3, don't attempt to "infer" `alg`... require it... for example, > P-256 can be used for signatures and encryptions, when `alg` and `use` are > absent, inference is ambiguous without sufficient context. > 5. From 4, If you invent a new alg, you must register it and > its association to keys and signatures / encryptions. Reminds me that I had idea of having special alg value that means "pull actual alg from the key". And while many seem to dislike overloads, overloads are "get it right or it will not work at all", instead of "seems to work, but is actually dangerously broken". > There are 2 registries that will need to be updated in order for your new > "alg" to be understood. > > - https://www.iana.org/assignments/jose/jose.xhtml > - https://www.iana.org/assignments/cose/cose.xhtml Yes, but the entiere HPKE, including future algorithms can use just one alg. And HPKE has no problems mixing different encryption algorithms with the same key. > I interpret this as an answer to your question... There __is__ a guarantee > that `enc` can be mapped to `COSE_Key` in the future, but only for `enc` > and `COSE_Key` that have been properly registered, and not before that, can > they be safely used with COSE. In fact, there is much stronger guarantee: For any algorithm, present or future, enc can be trivially mapped into bstr. And in fact, my implementation absolutely relies on that guarantee. > I'm not really a COSE or HPKE expert so take this as what I would expect to > be true based on my experience... and yes, I sympathize with needing to > update registries to ensure interoperability. > > Systems that are more "open world", might have more registries or even an > unbounded number of registries... but they all still need to be updated to > ensure interoperability. It is possible to do COSE-HPKE in a way that requires no future work to accomodiate future HPKE algorithms. > > 2) When a recipient offers multiple candidates for the HPKE cipher suite, > > a sender needs to tell the recipient what the sender has chosen, and while > > AEAD and KEM are fine, there seems to be a lack of a way to tell the > > recipient about KDF in the current draft. > > > > https://datatracker.ietf.org/doc/html/rfc9180#section-11.2 > https://datatracker.ietf.org/doc/html/rfc9180#section-5.1 > > However, I am not sure this answers your question... are you expected to > see scenarios where there are multiple `kdf_id` here > https://datatracker.ietf.org/doc/html/rfc9180#appendix-A.2.3 ? Even if HPKE does not explicitly say so, for each kem_id, there is one kdf_id that should be used with it. Currently (kem -> kdf): 16 -> 1 17 -> 2 18 -> 3 32 -> 1 33 -> 3 > > 3) There is no point in specifying kty (and crv) as required parameters. > > It is a waste of bytes. > > > > It's required to represent keys in a standard manner, see my comment > above... not disagreeing with your point, but it seems not aligned with the > conventions used by the standards... This has been my comment to ilari as > well. Well, there might be confusion about which keys one is talking about. kty is required for long-term keys, it is waste of spaace for encapsulated keys. > > 4) crv is used to put in KEM algorithm information, but this is not in > > line with the original definition of crv. Isn't this an abuse of crv? > > > > wondering which "original" definition you are thinking of here... > > - https://datatracker.ietf.org/doc/html/rfc8037#section-2 > - https://datatracker.ietf.org/doc/html/rfc7518#section-6.2.1.1 > - https://datatracker.ietf.org/doc/html/rfc8152#section-13.2 > > The last one seems most relevant to your question. The name "crv" is very misleading. It is not restricted, nor was it ever meant to be restricted, to elliptic curves. > > 5) This spec needs to clearly define how COSE_Key parameters are to be > > handled, and implementations need to support this. (For example, what to > > put in key_ops, and whether to allow "deriveKey" and/or "deriveBits"? etc.) > > > > Please allow me to suggest a solution to the above problems. It is just an > > idea that is not very refined yet though: > > 1. Define 'HPKE'(COSE_ALG_HPKE) as a new 'alg' value for a COSE Header > > Parameter. Unlike the current draft, AEAD information is not included in > > the alg value. > > 2. Introduce a new 'HPKE sender information' structure including enc as a > > parameter of 'HPKE' alg, instead of using the COSE_Key structured > > ’ephemeral key'. The structure also includes the HPKE cipher suite > > information(at least KDF ID and AEAD ID are required) negotiated with the > > recipient. An example is as follows: > > > > ``` > > 96( > > [ > > / algorithm id TBD1 for COSE_ALG_HPKE / > > << {1: TBD1} >>, > > { > > / HPKE sender information structure / > > -4 (TBD2): << { > > / KEM identifier, 2bytes (optional because (the > > recipient's)kid can be mapped to a KEM id.) / > > -1: 0x0010, > > / HPKE symmetric cipher suite (KDF id + AEAD id), 4bytes > > (required) / > > 1: 0x00010001, > > / HPKE encapsulated key (required) / > > 2: h'xxxxxxxxxxxxxxxxxxxxxxxxxxx', > > } >>, > > / the recipient's public key identifier (required) / > > 4: 'kid-2' > > }, > > / encrypted plaintext / > > h'4123E7C3CD992723F0FA1CD3A903A58842B1161E02D8E7FD842C4DA3B984B9CF' > > ] > > ) > > ``` > > > > I think the problems with the current draft listed above have been > > resolved in my proposal: > > - Once the new COSE parameters above are defined, even if HPKE cipher > > suites are added, there is no need to register new alg/crv values to IANA > > registry, no need to specify how to convert to COSE_Key, and no need to > > change the existing library implementations. > > > > I'm struggling to visualize how this would actually work based on the text > in this email, and your example. > > As a developer, I'm expecting something like this: > > standard_ciphertext = encrypt ( standard_msg, standard_public_key, ?alg ) > ... where either standard_public_key contains `alg` or it is required as an > additional argument if absent... we know it can be absent, due to being > optional. Are you talking about the HPKE encrypt interface or what? At least the HPKE one does not work like that. The signature of hpke base oneshot encrypt is (ignoring errors): Inputs: - kem_id: u16 - kdf_id: u16 - aead_id: u16 - public_key: bstr - info: bstr - associated_data: bstr - plaintext: bstr Outputs: - encapsulated_key: bstr - ciphertext: bstr > standard_msg = decrypt ( standard_ciphertext, standard_private_key ) ... > where standard_ciphertext signals `alg` so it does not need to be in > `standard_private_key` or passed as an additional argument. Again, is this the HPKE API, or something else? Again, the HPKE one does not work like that. The signature of hpke base oneshot decrypt is (ignoring errors): Inputs: - kem_id: u16 - kdf_id: u16 - aead_id: u16 - private_key: bstr - info: bstr - associated_data: bstr - encapsulated_key: bstr - ciphertext: bstr Outputs: - plaintext: bstr > Assume I have a key pair in COSE_Key format... How do I use them for your > new HPKE cipher suite, with your new `alg` ? I haven't looked in detail on that proposal, but on the encoding I proposed, here is how you get the inputs needed (modulo NIST curve hacks): - kem_id: Long-term key kem field. - kdf_id: Long-term key kdf field. - aead_id: First two bytes of message ek field. - private_key: Long-term key priv field. - info: Blank (COSE-HPKE does not use this). - associated_data: Context as specified by COSE-HPKE. - encapsulated_key: The remainder of message ek field. - ciphertext: The messsage ciphertext. > Is it possible your simplifications are based on assumptions regarding the > crypto system used for the keys? Like "we can guess the `alg` for "y^2 = > x^3 + ax + b (mod p)." or similar? > > I am hearing you say, we don't need a standard way to represent the keys > for a new `alg`. > > Are you hoping to use new "unregistered alg" with existing keys in the > future? Outside hacks to compress NIST curve keys, I do not assume anything about the cryptosystems. For my code or proposals, there is absolutely no difference between X25519, compact P-521 and Kyber768. > For example: > > - ECDSA over secp256k1, alg: ES256K > > vs > > - Schnorr over secp256k1: SS256k > > ... this is not registered, but I've explored it as a concept.... > https://identity.foundation/SchnorrSecp256k1Signature2019/ > > ... Possibly, I am just too naive to HPKE... can you try to explain this > again? Those are signatures, but let's construct worst-case scenario for HPKE: Let's suppose HPKE adds KEMs based on both compact P-256 (secp256r1) and secp256k1. Both have 32 byte public/private keys, and about 25% of public key encodings are expected to overlap. However, all the COSE-HPKE implementation has to do is pull the kem and priv/pub fields out of the long-term key and stuff those raw into the HPKE library, which will do the right thing. -Ilari _______________________________________________ COSE mailing list [email protected] https://www.ietf.org/mailman/listinfo/cose
