On Thu, Nov 17, 2022 at 06:39:21PM -0600, Orie Steele wrote: > I agree that we are potentially about to see a bunch of kty or alg > registrations for both JOSE and COSE related to HPKE.
I think that base COSE-HPKE should register exactly one kty and exactly one alg, anything more is a serious mistake. However, there may be additional alg values for HPKE functionality beyond oneshot base mode. For JSON, the situation is more complicated. While base JSON-HPKE should register exactly one kty, it should register exactly _two_ alg values. There may be additional alg values for HPKE functionality beyond oneshot base mode. The reason for this is that the JWE compact serialization, and JWE JSON serialization place fundamentially incompatible demands for HPKE. - Compact serialization _prohibits_ hybrid encryption. As consequence, HPKE MUST be operated in export-only mode (aead==0xFFFF). Here enc must go into the JWE Encrypted Key field (it can not be header parameter due to hard cyclic dependency). There are two choices where to place the kdf (and optionally kem) parameter (there is no aead, because it is always fixed): + New header parameter(s). + Prepend into the JWE Encrypted Key field. I am in favor of the second (prepending to encrypted key). - JSON serialization _requires_ hybrid encryption. As consequence, HPKE MUST be operated with actual AEAD (aead!=0xFFFF). Furthermore, the HPKE enc MUST be transported as header parameter, so one needs a new parameter to encode HPKE sender structure, that contains the kdf, aead and enc (plus optionally kem). This also precludes using alg in HPKE keys. > On Thu, Nov 17, 2022 at 3:48 PM Ilari Liusvaara <[email protected]> > wrote: > > > On Thu, Nov 17, 2022 at 02:49:47PM -0600, Orie Steele wrote: > > > Interested in unpacking The COSE_Key has new *kty HPKE*, and its JWK > > cousin. > > > > > > Comments inline: > > > > > > On Thu, Nov 17, 2022 at 2:02 PM Ilari Liusvaara < > > [email protected]> > > > wrote: > > > > > > > On Thu, Nov 17, 2022 at 10:05:28AM -0600, Orie Steele wrote: > > > > > Illari answered a related question here: > > > > > > > https://mailarchive.ietf.org/arch/msg/cose/eIxt4u8ox8N35-ZbDk_vsFD9PP4/ > > > > > > > > > > I have similar questions on how HPKE, PQC KEMs, and COSE Key work > > > > together > > > > > in practice. > > > > > > > > Here is how I think it will work: > > > > > > > > - The COSE_Key has new kty HPKE, containing the algorithm used > > > > (expressed using HPKE KEM identifier), public key blob (bstr), > > > > possibly some hints and for private keys, private key blob (bstr). > > > > - When encrypting, the COSE-HPKE just passes the HPKE code the KEM > > > > identifier and the public key blob from the key (along with other > > > > stuff like the plaintext to encrypt). HPKE code knows what to do > > > > with those. > > > > > > > > > > > > > I would have assumed a slightly different interface, that pulled the > > > parameterization from the key representations, for example: > > > > > > // encrypt > > > const sender = HPKE.JOSE.sender.createSenderContext({ > > > publicKeyJwk: *kty*, ..., x, *alg: Kem.KemKyber1024HkdfSha256 - > > > Kdf.HkdfSha256 - Aead.Aes128Gcm* } > > > }) > > > const ct = await sender.seal(new TextEncoder().encode("hello world!")); > > > > > > // decrypt > > > const recipient = HPKE.JOSE.recipient.createRecipientContext({ > > > privateKeyJwk: *kty*, ..., x, d, *alg: Kem.KemKyber1024HkdfSha256 - > > > Kdf.HkdfSha256 - Aead.Aes128Gcm* }, > > > enc: sender.enc, > > > }) > > > const pt = await recipient.open(ct); > > > > This would result in a nasty combinatorial explosion and a lot of extra > > work on the COSE WG, of the kind COSE WG is ill-equipped to do. > > > > > > I understand HPKE design focuses on moving the parameterization > > > outside of the key representations, and to enable the same public > > > or private key to be used in many different ways. > > > > > > I think that's fine for folks who want that, but when designing APIs > > > I prefer to set this in stone at the time of key generation, > > > and not invite implementers to use the same key material with many > > > different parametrization of algorithms. > > > > HPKE is designed to be able to soundly use the same key material with > > multiple algorithms. > > > > Right, but how are COSE Keys or JWKs meant to support this? > > How do these keys signal their intention to be used with multiple > algorithms? > > How do they signal their intention to NOT be used with multiple algorithms? > > Compare: > > { > kid: <hint>, > kty: EC, > crv: P-256, > alg: ECDH-ES+A256KW > x, > y, > d > } > > To: > > { > kid: <hint>, > kty: HPKE, > kem: KEM(Kyber1024, HKDF-SHA256), > alg: KEM+SHA3KDF+A192KW, > x, > d > } > > `alg` could remain optional here, if not present all algs are > supported? The latter key is definitely illegal (kty and alg are incompatible). But, there is actually a worse problem with keys that are kty!=HPKE (kty=HPKE is implicitly restructed to HPKE, which can handle itself): There is no way to sanely restrict these keys from being used with both HPKE and non-HPKE modes, which is spicy. key_ops does not work because both are encryption. alg won't work because key has two legimate alg values. > > As I understand it, HPKE can support both design philosophies, but > > > as we start to register new kty, or alg values, we will be driving > > > consolidation towards one side or the other when HPKE is used in > > > JOSE or COSE. > > > > I am saying that one of those philosophies WILL lead to a mess. > > > Have I captured the right one above? You seem to have captured the one that leads to a mess. > > > - When decrypting, the COSE-HPKE just passes the HPKE code the KEM > > > > identifier and the private key blob from the key (along with other > > > > stuff like encapsulated key and the ciphertext to decrypt. HPKE code > > > > knows what to do with those. > > > > > > > > If the KEM is PQC or not is not something COSE-HPKE code needs to > > > > concern itself with. Currently HPKE does not have any PQC KEMs, but > > > > that could change at any time. > > > > > > > > As for PQC outside HPKE in COSE, that is obviously more complicated > > > > matter, that turns out to need at least some new alg values, along > > > > with new (sub)types for the keys. Those things work in way similar to > > > > ECDH-ES, however reusing the ECDH-ES codepoints is not possible due to > > > > ECDH-ES requiring ephemeral key, which just does not exist for PQC. > > > > > > > > > > Yes, agreed, but I think the developer experience should still be > > > considered. > > > > Developer experience is secondary to cryptographic soundness. > > > > > I don't see this as related to cryptographic soundness. > > If the developer gets to pick the parameters, they get to make mistakes, > but the mistakes are not in the crypto soundness, they are in the envelopes > and APIs exposed in COSE / JOSE. > > A library developer should be able to implement key generation that makes > explicit the algorithms / parameters associated with a key, and chooses the > best ones by default in case the caller is not an expert. > > const jwk = HPKE.JWK.generate(); > > kty: HPKE, > kem: KEM(Kyber1024, HKDF-SHA256), > alg: KEM+SHA3KDF+A192KW, ... required? ... default?... best to leave > empty and allow everything? That combination would be illegal (incompatible kty and alg). For the KEM, that absolutely has to be chosen when generating the key. For the KDF and AEAD (with COSE or JSON serialization), the sender should choose, first considering hints in key if present, and if not, choosing reasonable defaults. With KDF, reasonable defaults are easy: Pick KDF closest to internal structure of KEM. With AEAD, things get harder: - There is AES versus Chacha, - If one uses AES with P-256 or X25519, AES-128 is not strength- matched (due to scaling), AES-192 does not exist in HPKE and AES-256 is slower than necressary. -Ilari _______________________________________________ COSE mailing list [email protected] https://www.ietf.org/mailman/listinfo/cose
