Background
It is not uncommon to use concatenation in the ikm
parameter of HKDF-Extract
and info
parameter of HKDF-Expand
to achieve context binding. See for example, the use of the LabeledExtract
and LabeledExpand
functions in the HPKE specfication and HKDF-Expand-Label
function in the MLS and TLS 1.3 specifications.
Problem
Some of these labeled methods take inputs of arbitrary length, which requires me to allocate on every call, given the current Hkdf
API. Concretely, if I wanted to HKDF-Extract with ikm = "mycontextstr" || input
where input
is some user-inputted, arbitrary-length string, I would have to compute Hkdf::extract(None, &[b"mycontextstr", input].concat())
, which is an allocation of unbounded size.
Obviously, this is extremely undesirable if I want to make HPKE work on embedded devices. In fact, as of right now, this issue is the only thing preventing rust-hpke from being alloc-free.
Solution
Implement streaming support for HKDF-Extract and HKDF-Expand.
For HKDF-Extract, we can do proper iterative streaming, since the underlying MAC supports this kind of streaming. This is implemented using the new HkdfExtract
struct.
Due to the structure of HKDF-Expand, streaming with iterators isn't possible. At the very least, one needs an iterator that can be cycled an arbitrary number of times. I chose to represent this as a simple slice over bytestrings, but you may want to generalize to an input that is Iterator<Item = &[u8]> + Clone
. If you'd prefer this, let me know and I'll make the change.