Subject: [Cfrg] Why zero checks?

From: Watson Ladd <[email-masked]>
Date: Wed, 25 Mar 2015 20:19:56 -0700

Draft-irtf-cfrg-02 contains the following sentence: "Both MUST check,
without leaking extra information about the value of K, whether K is
the all-zero value and abort if so (see below)."

This check isn't currently implemented by any Curve25519
implementation. It's also not necessary in most protocols, as the
exchanged DH parameters will either be signed or authenticated some
other way. Why has this been added?

Sincerely,
Watson Ladd

---

From: Damien Miller <[email-masked]>
Date: Thu, 26 Mar 2015 14:31:21 +1100 (AEDT)

> other way. Why has this been added?

It's so cheap, that it seems to make sense to make part of all
primitive implementations rather than leaving it for protocol
implementors to forget to do later.

---

From: lfw_frank <[email-masked]>
Date: Thu, 26 Mar 2015 20:08:53 +0800 (CST)

Exchanged DH parameters in some protocols are not signed or authenticated, such as Password authentication protocol EC-SRP5. Zero checks is a MUST in such kind of protocol.

Fuwen Liu

At 2015-03-26 11:31:21, "Damien Miller" <[email-masked]> wrote:
>_______________________________________________
>Cfrg mailing list
>[email-masked]
>http://www.irtf.org/mailman/listinfo/cfrg

---

From: Adam Langley <[email-masked]>
Date: Thu, 26 Mar 2015 07:18:06 -0500

> other way. Why has this been added?

While any well designed protocol won't care, it's a cheap check and it
might save somebody a problem. I think this is in the same fashion
with our use of a Montgomery ladder, twist-secure curves etc. These
are features that are at least partly motivated by making the
primitive hard to misuse.

Cheers

AGL

-- 
Adam Langley [email-masked] https://www.imperialviolet.org

---

From: Adam Langley <[email-masked]>
Date: Thu, 26 Mar 2015 07:34:15 -0500

> primitive hard to misuse.

p.s. there might well be better ways of doing this. At the moment it
suggests to abort the protocol, which probably means a return value
that might not be checked. Perhaps a better answer is to return a
random shared secret? And since having implicit randomness in code
creates headaches and makes testing harder, perhaps generate the
"random" shared key from the secret scalar given to the code?

Cheers

AGL

---

From: CodesInChaos <[email-masked]>
Date: Fri, 27 Mar 2015 16:01:42 +0100

It may be cheap performance wise, but it's not cheap API wise. It
turns an API that always succeeds into an API with error conditions.
One of the main selling points of the common Curve25519 APIs is that
they simply work. I strongly dislike pushing this down to primitive as
a requirement.

I'd rather add a security-consideration note that mentions that you
need those checks if your protocol requires contributory behaviour,

---

From: Nick Mathewson <[email-masked]>
Date: Fri, 27 Mar 2015 12:30:48 -0400

> they simply work. I strongly dislike pushing this down to primitive as

As an application developer, I have a slightly different concern.

Even if we take Adam's recommendation here and make the function *not*
have an error condition (by making it return a random value instead),
we'll still be forking the ecosystem of curve25519 implementations so
that some will check for zero and some won't.

Any applications that come to rely on the behavior specified here will
reach an unpleasant outcome when they try to use (most of) the
existing curve25519 code.

Perhaps suitable naming of functions could solve this in practice?  Or
a differentiation between the "DH" and "DH-and-check" functions?

-- 
Nick

---

From: "D. J. Bernstein" <[email-masked]>
Date: 27 Mar 2015 22:48:13 -0000

If the goal is to protect mediocre protocol designs then arguing for an
API that checks shared==0 (and raises an exception or uses randomness)
seems considerably more difficult than arguing for an API that returns
H(shared,clientpk,serverpk). But I've heard patent FUD both ways. Surely
it's better to use protocols that have clear authentication structures
and that don't need any of these complications in the first place.

In any event, this is a layer above the pure ECDH operation. The layers
shouldn't be confused, and certainly shouldn't be given the same name.

---Dan

---

From: Andy Lutomirski <[email-masked]>
Date: Fri, 27 Mar 2015 16:23:37 -0700

> a differentiation between the "DH" and "DH-and-check" functions?

Can we solve this differently?  Rather than using:

new_ecdh_function(a, bG) = abG

could we use something like:

new_ecdh_function(a, bG) = hash(aG, bG, abG)

This seems silly, but I think it ensures contributory behavior in the
result and may have negligible performance cost.

--Andy

---

From: Watson Ladd <[email-masked]>
Date: Sun, 29 Mar 2015 12:01:14 -0700

> result and may have negligible performance cost.

Notice how your function can be specified in terms of the existing
Curve25519 function, while the reverse isn't true. It's not even clear that
it fixes everything: prime field DH is not contributory, and I don't know
of IETF protocols which require contributory behavior that got correctly
how to require it.

---

From: Nico Williams <[email-masked]>
Date: Mon, 30 Mar 2015 11:40:42 -0500

> shouldn't be confused, and certainly shouldn't be given the same name.

I find this a convincing argument.

We can have the zero-checks: in an API layered above a lower-level ECDH
API that doesn't have them.  Then the only question remaining is: the
APIs' names (we'll need standard names for them for use in RFCs and
other descriptions of application protocols).

Speaking of which, allow me to repeat myself: we need abstract APIs for
many Internet protocols, including (especially!) TLS.  Arguably, the TLS
renego bug arose from a lack of APIs, which lack hid the now-obvious
need for channel binding between the inner and outer connections.
Abstract APIs need not be so detailed as -for example- RFC2743
(GSS-API), but they ought to be a lot more detailed than RFC4422 (SASL),
though even then, RFC4422 is a lot more of an abstract API than RFC5246
(TLS) is.

Nico
--