Skip to content
This repository has been archived by the owner on Sep 18, 2019. It is now read-only.

Should XSTREAM bind identities? (Yes) #15

Open
tarcieri opened this issue Jan 5, 2018 · 5 comments
Open

Should XSTREAM bind identities? (Yes) #15

tarcieri opened this issue Jan 5, 2018 · 5 comments

Comments

@tarcieri
Copy link
Contributor

tarcieri commented Jan 5, 2018

The key derivation used by XSTREAM is inspired by the NaCl crypto_box() function, which does the following (for "curve25519xsalsa20poly1305"):

  • sk: private scalar
  • pk: X25519 public key (i.e. Montgomery-u coordinate)
s = scalarmult(sk, pk)
k = hsalsa20(0, s)

Notable about both this construction and XSTREAM is that they do not bind the identity of the static D-H key when performing key derivation. Considering the use case (offline/data-at-rest encryption) I am not particularly concerned, but perhaps it's worth re-evaluating and e.g. including the static D-H key as an input to HKDF.

@tarcieri
Copy link
Contributor Author

tarcieri commented Jan 5, 2018

One option would be to eliminate the user-supplied salt and use the static D-H public key as the HKDF salt. There aren't particularly compelling use cases for the salt otherwise: a random user-supplied salt would most likely come from the same RNG as the ephemeral key and therefore would not help in the event of an RNG failure.

Alternatively, rather than completely eliminating the salt parameter, we could do something like this for the HKDF salt:

static_key || user_salt

Personally I'm in favor of eliminating the salt parameter from the user-facing API. XSTREAM is intended to provide a simple, high-level API which is hard to misuse, and as such eliminating parameters that provide dubious value while being one more thing to learn seems good to me.

@eternaleye
Copy link

eternaleye commented Jan 5, 2018

I'm going to draw a distinction here - HKDF exposes salt and info, and this has only discussed salt.

I definitely agree that salt shouldn't be exposed to the user, in part because it has some subtle properties that are not suited for end users (specifically, secret salts aren't kosher salt :P). Feeding the public key in via salt seems like something with little to no downside, and has the potential to mitigate a risk.

At that point, it's worth asking whether info should be exposed instead. While salt shouldn't be used for secret inputs, I don't know if the same is true for info (I don't think it is?). Having a user-specified parameter for key generation allows them to make the entire stream depend on whatever other data is passed; randomness is far from the only valid input. While CHAIN could get the same effect by including that data in the first chunk's AD, STREAM requires it be included in every chunk's AD.

@tarcieri
Copy link
Contributor Author

tarcieri commented Jan 6, 2018

There are three relevant parameters:

  • salt and info: HKDF parameters
  • nonce: 8-byte nonce prefix used by STREAM

They are presently:

  • salt: optional (per HKDF spec, with zeros as a default) user-supplied value
  • info: the string XSTREAM_X25519_HKDF as a domain separation/personalization measure
  • nonce: 8-bytes of 0 (since we always generate a random ephemeral D-H key)

I'm open to changing any of them. I'm somewhat leaning toward:

  • salt: static D-H key of the recipient
  • info: XSTREAM_X25519_HKDF
  • nonce: optional user-supplied 8-byte value, defaulting to 8-bytes of 0

Though I could see the value in a user-supplied info parameter as well, as otherwise if we use salt for binding the static D-H key used, there is no option for any user-supplied input to the KDF, be it a random nonce, personalization string, mutually committed upon public value, or what have you.

One thing to keep in mind here is I am trying to keep the end-user API as high level as possible and would like to minimize unnecessary knobs. That said I'm not sure there's value in exposing the nonce in a construction which derives a unique key per usage, and perhaps only like exposing it to the user because it feels slightly less dirty as an optional parameter instead of a hardcoded constant.

@tarcieri tarcieri changed the title Should XSTREAM bind identities? Should XSTREAM bind identities? (Yes) Jan 6, 2018
@xorxornop
Copy link

Why not just an aggregate impl, with methods to change anything that doesn't justify being in the "constructor"? (e.g. the salt)

@eternaleye
Copy link

@xorxornop: Because that's a colossal footgun that undermines the entire point of this library.

The point of the miscreant project as a whole is an extension of the NaCl intent to provide a carefully-curated selection of sensible tools that, as much as is possible, avoid exposing footguns to the user. One of the few places NaCl fell down in that goal is nonces; this is pretty much exactly what this library aims to fix.

While the decision of what to pass here has multiple options with tradeoffs, it also has nontrivial security implications, and that is exactly why it'd be a failure in the goals of this library to abdicate responsibility and shove the burden of that choice (and of correctly implementing that choice) onto the user.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants