aws / aws-lc-rs

aws-lc-rs is a cryptographic library using AWS-LC for its cryptographic operations. The library strives to be API-compatible with the popular Rust library named ring.
Other
237 stars 40 forks source link

HPKE base mode support or ephemeral-static ECDH API #300

Closed ctz closed 5 months ago

ctz commented 6 months ago

Problem:

Over in rustls, we'd like to implement Encrypted Client Hello. This uses HPKE "Base" mode. We've defined traits to generalise over this use, and would like to implement these traits on top of aws-lc-rs. HPKE is a pretty straightforward construction and I think the existing AEAD and HKDF APIs can be reused for this. Unfortunately the ECDH API cannot, because it only supports ephemeral-ephemeral key exchange -- the server key in ECH is static.

Solution:

I think there are two possible solutions:

  1. aws-lc-rs exposes HPKE base mode as a first-class API, and we use this directly.
  2. aws-lc-rs exposes an ephemeral-static ECDH API (and we do the glueing-together and known-answer testing in rustls.)

For reference these have issues/PRs in ring:

  1. https://github.com/briansmith/ring/pull/1462
  2. https://github.com/briansmith/ring/issues/331
justsmth commented 6 months ago

Seeing as AWS-LC has API to support HPKE, we'll pursue "option 1" and provide a first-class API for HPKE.

justsmth commented 6 months ago

A PR for "option 2" is here: https://github.com/aws/aws-lc-rs/pull/302

justsmth commented 5 months ago

Hi @ctz -- as of aws-lc-rs v1.6.0 we support agreement with non-ephemeral keys. Does this resolve this issue for you?

cpu commented 1 month ago

:wave: Hi folks,

Just wanted to report back that we implemented HPKE in Rustls using the non-ephemeral key agreement support added in 1.6.0+ - thanks again!

In case it's interesting I also bumped into a challenge w.r.t the HKDF API: in short, the *ring* inspired API is fairly tightly coupled to the TLS 1.3 use-case in which the PRK extracted using the HKDF extract step can only be used directly for an expand (via the returned Prk's Prk::expand fn) - the extracted PRK is opaque/inaccessible to the caller.

In RFC 9180 there's one place (In Section 5.1, while computing the key_schedule_context) where one has to extract two PRKs, concatenate them along with the HPKE mode, and then use the produced concatenated value in a couple HKDF expands:

  psk_id_hash = LabeledExtract("", "psk_id_hash", psk_id)
  info_hash = LabeledExtract("", "info_hash", info)
  key_schedule_context = concat(mode, psk_id_hash, info_hash)
  <snipped>
  key = LabeledExpand(secret, "key", key_schedule_context, Nk)

The existing HKDF API doesn't allow access to extract PRKs for this purpose, and so we had to implement this using our in-crate HKDF-Using-HMAC algorithms instead of using the native AWS HKDF algorithms.

There's no change required from our end, I think we're happy with the arrangement we landed on. I just wanted to share this in case it was helpful for considering future API adjustments.

Thanks again for your support!