Computing Shared Secrets Diffie-Hellman

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