188
An integer that will be treated as a bit mask by
DH_check
and will contain the results of the check when the function returns successfully.
If the function encounters an error unrelated to the validity of the generated prime, the return will be zero; otherwise, it will be nonzero. When the function returns successfully, the
codes
argument will contain a bit mask that indicates whether the parameters are suitable for use or not. If none of the bits is set, the parameters should be considered suitable for use. If any of the
following bits are set, the parameters may not be suitable for use. In most cases, the parameters should be thrown away, and new ones should be generated.
DH_CHECK_P_NOT_PRIME If this bit is set, it indicates that the generated prime is not actually a prime number.
Ordinarily, this bit should never be set when the parameters are generated using
DH_generate_parameters
, but it could very well be set when checking parameters retrieved from disk or from a peer.
DH_CHECK_P_NOT_SAFE_PRIME If this bit is set, it indicates that the generated prime is not safe. That is,
p-12
is not also a prime number. As with
DH_CHECK_P_NOT_PRIME
, this bit should never be set when the parameters were generated using
DH_generate_parameters
, but it could very well be set when checking parameters retrieved from disk or from a peer.
DH_NOT_SUITABLE_GENERATOR If this bit is set, it indicates that the generated prime and the generator are not suitable for
use together. The parameters dont necessarily need to be thrown away and regenerated if this bit is set. Instead, the generator could be changed and the check retried.
DH_UNABLE_TO_CHECK_GENERATOR If this bit is set, a nonstandard generator is being used, so the
DH_check
function is unable to check to see that the prime and the generator are suitable for use. If you know
that youve set a nonstandard generator intentionally, its up to you to decide whether it is safe to ignore this bit being set or not.
Once the parameters have been generated, they can be transmitted to the peer. The details of how the data is sent depend on the medium that is being used for the exchange. To transmit the
parameters over a TCP connection, the BIGNUM functions
BN_bn2bin
and
BN_bin2bn
are obvious candidates.
The party that generates the parameters calls
DH_generate_parameters
to obtain a
DH
object. The party that is receiving the parameters must also obtain a
DH
object. This is easily done by calling the function
DH_new
, which will allocate and initialize a new
DH
object. The parameters that are received from the peer can then be directly assigned to the
DH
objects
p
and
g
data members, using the appropriate BIGNUM functions.
When were done with a
DH
object, we must be sure to destroy it by calling the function
DH_free
, and passing the pointer returned by either
DH_generate_parameters
or
DH_new
as the only argument.
8.2.3 Computing Shared Secrets
189
Now that parameters have been generated and received by the two peers, each peer must generate a key pair and exchange their public keys. Remember that the private key must not be shared at all.
Once this is done, each peer can independently compute the shared secret, and the algorithm will have done its job. With authenticated Diffie-Hellman, the publicprivate key pairs can persist
beyond usage for a single key-agreement. In these cases, we must be wary of a special class of attack against Diffie-Hellman, which is discussed at the end of this section.
OpenSSL provides the function
DH_generate_key
for generating public and private keys. It requires as its only argument a
DH
object that has the parameters,
p
and
g
, filled in. If the keys are generated successfully, the return from the function will be nonzero. If an error occurs, the return
will be zero. Once the keys have been generated successfully, each peer must exchange their public key with
the other peer. The details of how to exchange the value of the public key varies depending on the medium that is being used, but in a typical case in which the communication is taking place over
an established TCP connection, the functions
BN_bn2bin
and
BN_bin2bn
will once again work for the exchange of the
DH
objects
pub_key
data member. With the parameters and public key now exchanged, each party in the exchange can use his own
private key and the peers public key to compute the shared secret using the function
DH_compute_key
.
int DH_compute_keyunsigned char secret, BIGNUM pub_key, DH dh;
secret A buffer that will be used to hold the shared secret. It must be allocated by the caller and
should be big enough to hold the secret. The number of bytes required to hold the secret can be determined with a call to
DH_size
, passing the
DH
object as the only argument. pub_key
The peers public key. dh
The
DH
object that contains the parameters and the callers private key. After the shared secret is computed, the DH object is no longer needed unless more secrets will be
generated and exchanged. It can be safely destroyed using the
DH_free
function. In certain cases, Diffie-Hellman can be subject to a type of attack known as a small-subgroup
attack . This attack results in a reduction of the computational complexity of brute-forcing the
peers private key value. Essentially, a small-subgroup attack can result in the victims private key being discovered. There are several different methods of protecting Diffie-Hellman against this
type of attack. The simplest method is to use ephemeral keying. If both parties stick to ephemeral keying and use a separate method of authentication, small-subgroup attacks are thwarted. This
isnt always feasible, however, mostly due to computational expense. If static keys will be used, two simple mathematical checks can be performed on the public key received from a peer to
ensure these attacks arent possible. If the key passes both tests, its safe to use. The first test verifies that the supplied key is greater than 1 and less than the value of the
p
parameter. The second test computes
y
q
mod p
, in which
y
is the key to test and
q
is another large prime. If the result of this operation is 1, the key is safe; otherwise, it is not. The
q
parameter is not generated by OpenSSL even though there is a placeholder for it in the
DH
structure. An algorithm for generating
q
can be found in RFC 2631. If youre interested in the other methods or more detailed information on the attack, we recommend that you read RFC 2785.
TE AM
FL Y
Team-Fly
®
190
8.2.4 Practical Applications