In my application I'm doing a DH key exchange, where both sides generate their own ephemeral key. No static keys are used. I am trying to make my application resistant against an active attack and therefore need to validate the public key that my counterpart is sending me.
Below I'm using standard DH variable names: DH parameters $g$ and $p$. Party $A$ has a private key $x_a$ and public key $y_a = g^{x_a} \bmod p$. Party $B$ has a private key $x_b$ and public key $y_b = g^{x_b} \bmod p$. The calculated secret is then $z = g^{x_ax_b} \bmod p$. Also $p$ is a safe prime $p = 2q+1$.
In my application I will authenticate the shared secret $z$ via an out of bounds way (basically a user verifying a fingerprint).
OpenSSL has a function to validate a DH public key (DH_check_pub_key()) which does the following check:
$$2 \leq y_b \leq p-2$$
I believe this always excludes the generators that generate the order-2 subgroup. Because $p$ is a safe prime, I think these generators are always $1$ and $p-1$. Is this correct? Is it also correct that all integers in $[2, p-2]$ either generate an order-$q$ or an order-$2q$ subgroup?
Secondly, in NIST SP800-56, section 5.6.2.4, it is mentioned that I should also check:
$$y_b^q \bmod p = 1$$
I don't understand the background of this check. Is it needed when $p$ is a safe prime? OpenSSL does not implement this.
p
from the other site, you could also run a probably prime test on it (or if you also know q, you can check the safe prime relation). But it is rather slow, so maybe cache the result or rely on static p tables. Besides that, the same range tests are defined for IKE DH exponent reuse implementations in tools.ietf.org/html/rfc6989 $\endgroup$