cfrg / draft-irtf-cfrg-opaque

The OPAQUE Asymmetric PAKE Protocol
https://cfrg.github.io/draft-irtf-cfrg-opaque/draft-irtf-cfrg-opaque.html
Other
100 stars 20 forks source link

Proposal: Completely remove all mention of idU and idS for the sake of simplicity #90

Closed kevinlewi closed 3 years ago

kevinlewi commented 3 years ago

I'd like to open a discussion on the following proposal: to completely remove all mention of idU and idS from the OPAQUE spec (aside from places where we can refer to it as guidance for an implementor of a wrapper protocol that calls OPAQUE). To be clear, this change would mean that we set idU = pkU and idS = pkS in all locations where idU and idS appear in the current draft (not to completely remove their inclusion from the draft).

(Note: Past discussion on this issue occurred in #74, spawned from the question of "Can we simply set idU = static pkU and idS = static pkS?". This will be a continuation of some of the discussion in that issue.)

The current state of the draft suggests that we involve idU and idS in the following places: 1) As potential parameters which can be supplied to the envelope as either secret or cleartext credentials 2) If they are specified in the envelope, then they must be input as parameters to the AKE login (by at least the server). If they were not specified in the envelope, then pkU and pkS are used in their place. They are then used to affect the AKE key derivation. 3) In the past there have also been discussions around potentially incorporating idU as part of the initial input to the OPRF: namely, instead of doing OPRF(key, password), do something like OPRF(key, HKDF(password, idU)).

Proposal

Defer all mention of idU and idS to the wrapper protocol that calls OPAQUE, do not allow them to be specified in the envelope, and use pkU and pkS in their place within the AKE section.

For wrapper protocols that wish to supply an idU and idS which should be protected by the security guarantees of the OPRF, we should instead recommend these wrapper protocols to take advantage of the export_key parameter to do custom encryption/authentication for the bindings between idU/pkU and idS/pkS.

Pros

The advantage to this proposal is that we can remove all of this complexity and potential for errors from the implementation side. The result is that OPAQUE no longer references any application-specific idU and idS parameters, which to me feels much cleaner than our current state where there are many conditionals and optional parameters to check (a nightmare for generating test vectors and verifying that an implementation can support all possible settings bug-free).

Cons

The main worry for removing idU and idS is the potential for a loss of generality (what if a wrapper protocol wants to tie idU and idS into the OPRF/AKE security guarantees?). I propose that we recommend wrapper protocols to use export_key for this purpose, so the details of idU and idS can remain outside of the OPAQUE protocol. There is still a cost here, because previously we used HKDF(RwdU, ...) to encrypt idU and idS, whereas now they would be using export_key, which would amount to an extra HKDF computation or two. But I think this price is totally worth the simplicity that it brings the OPAQUE protocol, especially since this is a client-side operation, and we are already recommending clients to compute a memory-hard hash function which will be way more expensive.

And finally, to address (3), we should recommend wrapper protocols to pre-hash idU and the password before starting the OPAQUE protocol, again so that we can avoid incorporating the idU parameter within the OPAQUE protocol.

cc: @hugokraw , @chris-wood

hugokraw commented 3 years ago

I strongly oppose this for several reasons. Here are some:

The result is that OPAQUE no longer references any application-specific idU and idS parameters

OPAQUE is an authenticated key exchange protocol and there is no meaning to authentication without identities. Who you are exchanging a key with is not less important than the secrecy and randomness of the key. As such, OPAQUE must have idU and idS as essential elements, and indeed you cannot derive a key without them. So the only question is who determines these identities and how they are communicated in the protocol. We simplified the treatment by setting defaults (pkU and pkS) and providing a native mechanism to change this in an authenticated way if so desired. If you eliminate the use of the envelope for this transmission of identities you need to either say "sorry, you can only use pkU and pkS as identities" (which is too restrictive) or create yet another mechanism for this authenticated transmission. I find this more complex and prone to error than including the id's in the envelope. In particular, the export key is intended for extensions to OPAQUE, not to serve a prime functionality as authenticating identities.

the server must remember how the envelope was constructed

The server is the one to set these mechanisms at registration and there is no reason it forgets them. Moreover, the server stores the identities and it never needs to look at the envelope (except as a space optimization in case the identities contained in the envelope are not encrypted).

we should recommend wrapper protocols to pre-hash idU and the password before starting the OPAQUE protocol, again so that we can avoid incorporating the idU parameter within the OPAQUE protocol.

I would not remove idU from the AKE key derivation even if you included it under the OPRF. It is important to keep the modular composition of OPRF and AKE where each part delivers what is expected from such component. Also, one has to be careful (actually we may want to have a note on this) to avoid any replacement or instantiation of a user's identity with something like H(uid, password). If someone thinks of this as an identity then it is likely to think it does not require secrecy. Of course, if you publish H(id, password) you broke aPAKE completely as you can do an offline attack on the password just given idU.

kevinlewi commented 3 years ago

Hi Hugo, in reading your response, I realize that my original proposal might have been slightly unclear -- I am not advocating for removing idU and idS, but instead advocating for fixing idU = pkU, idS = pkS, and not allowing for the wrapper protocol to set idU and idS to anything else. (I will edit the original text to clarify this.) In other words, I am proposing to say:

"sorry, you can only use pkU and pkS as identities" (which is too restrictive)

Can you elaborate a bit more on why this is too restrictive, and why export_key cannot be used in the manner I suggested?

In particular, the export key is intended for extensions to OPAQUE, not to serve a prime functionality as authenticating identities.

I see the use of export_key in my proposal not as authenticating identities, but simply allowing for a binding between the wrapper protocol's understanding of idU, and pkU.


By the way, I want to place emphasis on the simplicity that I am aiming for with this proposal. I agree that by not allowing for custom idU and idS, we are making it more difficult for a wrapper protocol to get the security benefits of using custom idU and idS. I just want us to be cognizant of the costs that come with the increased complexity of supporting a custom idU and idS. If we come to an agreement that this increased complexity is worth the support for the feature, then we should definitely support it.

One way that I see the complexity being increased by supporting custom idU and idS here is the following. Let's say we come across an OPAQUE implementation in the wild. How difficult is it to check whether or not it complies with this specification? How many edge cases does one need to verify with the OPAQUE implementation (adding custom idU, putting idU in the envelope but not reusing it in the AKE section, etc.) in order for the community to be able to confidently say that it is in compliance? At the very least, we would need to provide a set of test vectors which test each edge case. I'd like for us to keep in mind that we do not want the complexity of correctness verification to be too large. Otherwise, we may end up in a situation where we produce a complete specification, but implementations frequently have bugs.

hugokraw commented 3 years ago

I appreciate any simplification but not enough in this case to "outsource" the management of identities outside the protocol. The identities need to be communicated in an authenticated way and I prefer not to trust wrappers or random implementers to take good care of it. Is the complexity we are talking about coming from letting wrappers choose identities that are neither pkU, pkS or those included in the envelope? Would it be ok if we limit implementations to reduce flexibility of choosing identities to the following line: If Envelope.Ids != null set IdU=envelope.idU, idS=envelope.idS else set idU=pkU, idS=pkS and everywhere else use idU and idS as set in this line? Would that still leave corner cases?

kevinlewi commented 3 years ago

Is the complexity we are talking about coming from letting wrappers choose identities that are neither pkU, pkS or those included in the envelope?

No, I believe that we are already disallowing for this to occur. The identities must be set in the envelope, or if not set, then default to pkU and pkS. So, this is not where the extra complexity would be coming from.

After some more thought on this + your suggestions, @hugokraw, I think I can reduce my concerns down to the following: 1) There is a lot of flexibility in how the envelope is configured. What if the server says that the envelope contains an idU but no idS, or vice versa? We would need to produce test vectors for each possible setting and check that the appropriate behavior occurs in the AKE section, which is quite cumbersome. 2) Setting idU and idS to be the empty string in the envelope is very different from not setting idU and idS in the envelope. I'm worried that implementations will get this wrong, since often the empty string is syntactically similar to "not being set", and so we may need to add test vectors to address this as well.

Essentially both of these issues can be boiled down to reducing the complexity of setting the structure of the envelope. One solution I can think of for addressing this potential ambiguity is to take note from the VOPRF RFC and perhaps define "modes" for the envelope, either a "base mode" which does not set idU and idS, and a "custom identifier mode" which requires idU and idS to be set in the envelope.

I have some other concerns about the customizability of the envelope, which I plan to create an issue about to address all at once. So I will close out this issue and instead defer further discussion of the above two points to a new issue about simplifying the complexity of the envelope itself.

Thanks for the fruitful discussions -- hope this makes sense!