DH *DH_new();
void DH_free(dh)
DH *dh;
int DH_size(dh)
DH *dh;
DH *DH_generate_parameters(prime_len, generator, callback, cb_arg)
int prime_len, generator;
void (*callback)(int,int);
char *cb_arg;
int DH_check(dh, codes)
DH *dh;
int *codes;
int DH_generate_key(dh)
DH *dh;
int DH_compute_key(key, pub_key, dh)
unsigned char *key;
BIGNUM *pub_key;
DH *dh;
int DHparams_print_fp(fp, x)
FILE *fp;
DH *x;
int DHparams_print(bp, x)
BIO *bp;
DH *x;
void ERR_load_DH_strings()
Note: these routines aren't used anywhere in the SSL-level routines. As far as I know, no browser supports DH certificates even though they are required by the SSL v3.0 specs and both MSIE and Netscape (for example) claim to support SSLv3.0.
Warning: these routines should not be used as is to build a signature scheme until they are revised. See Ross Anderson's paper, "Minding your p's and q's", which describes a forgery attack which can be used when the parameter g is picked to be a generator of Z_p rather than of a large subgroup; this is especially effective when g is fixed at 2, as these routines permit.
All of these functions operate on a DH structure which contains the following:
typedef struct dh_st
{
/* This first argument is used to pick up errors when
* a DH is passed instead of a EVP_PKEY */
int pad;
int version;
BIGNUM *p;
BIGNUM *g;
int length; /* optional */
BIGNUM *pub_key;
BIGNUM *priv_key;
} DH;
As you can see from the structure, both the private and the public key may be stored in this structure.
Key generation g is a generator of the multiplicative group Z_p, priv_key is chosen randomly on the order of p in length (but guaranteed to be less than p), pub_key = g^priv_key mod p.
DH_new allocates a new DH structure which it returns on success; NULL is returned on error.
DH_free frees a DH structure and its subfields if they are not NULL.
DH_size returns the number of bytes in dh->p. This number can be used to figure out how large an array you need to pass to DH_compute_key when you are doing session key generation. See dhtest.c for details.
DH_generate_parameters expects the caller to pass the length in bits of the prime p to be found in prime_len and the generator g of the multiplicative group Z_p in generator. Expected values for the generator are 2 (DH_GENERATOR_2) or 5 (DH_GENERATOR_5).
The prime p that is chosen will be of the form 2*q +1 where q is also prime. Depending on the choice of generator, p will either be chosen with p mod 24 == 11 (g=2) or with p mod 10 == 3 or 7 (g=5). This ensures that g is not a quadratic residue mod p, which in turn ensures (since g is small compared to p) that it is a generator of Z_p. For an explanation of the quadratic residue condition, see e.g. Hardy and Wright, An Introduction to the Theory of Numbers, pp 73-78.
The callback is called whenever a possible prime passes a round of the Miller-Rabin primality test; application writers may use this callback to update some message on the screen that lets the user know how the computations are progressing. It is called as
callback(3,0,cb_arg)
The function returns a DH structure with subfields p and g filled in on success, or NULL on error.
DH_check checks the subfields of a DH structure passed to it to be sure that they are valid DH parameters. Specifically:
the generator dh->g is checked to see that is actually a generator of Z_p by using the test mentioned earlier; if g=2 then we want p=11 mod 24 and if g=5 then we want p=3 or 7 mod 10. If g has some other value then this is noted in the value returned to the caller. in ret.
dh->p is checked to be sure it is prime, and (p-1)/2 is also checked to be sure that it is prime.
This function returns 0 on a good check and 1 on error.
DH_generate_key expects a DH structure with at least the fields g and p filled in. If the private_key subfield is NULL, one is generated randomly; if the public_key subfield is NULL, it is computed as g^private_key; if it is not NULL it is computed in the same way anyways. Hmmm...
DH_compute_key, which should really be called DH_compute_shared_key, is used to generate a shared key between two parties who share DH parameters g and p.
The routine expects the caller to pass a DH structure with at least the private_key, g and p filled in. The <>pub_key argument should be another party's DH public key.
This function computes public_key^private_key mod p ((g^x2)^x1 where party 1, the caller, has x1 as a private key, and party 2 has x2 as a private key) and returns it.
DHparams_print_fp reqires the inclusion of "asn1.h" since it is actually defined in the ASN1 library.
This function prints out the DH parameters passed in dh to the file specified by fp. It calls DHparams_print to do the most of the work.
DHparams_print reqires the inclusion of "asn1.h" since it is actually defined in the ASN1 library.
This function prints out the DH parameters passed in dh to the BIO file specified by bp. The format is fixed and looks like this:
Diffie-Hellman-Parameters: (xx bit) prime: xxxxxxxxxxxx generator: xxxxxxxxxxxxxx recommended-private-length: xxxxxxxx
where the xxxxxxx are hex numbers.
ERR_load_DH_strings initializes arrays for the error-handling library with messages specific to the DH library
The following defines are also provided for the programmer's convenience:
#define DHparams_dup(x) (DH *)ASN1_dup((int (*)())i2d_DHparams, \
(char *(*)())d2i_DHparams,(char *)(x))
#define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
(char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
#define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
(unsigned char *)(x))
#define d2i_DHparams_bio(bp,x) (DH *)ASN1_d2i_bio((char *(*)())DH_new, \
(char *(*)())d2i_DHparams,(bp),(unsigned char **)(x))
#define i2d_DHparams_bio(bp,x) ASN1_i2d_bio(i2d_DHparams,(bp), \
(unsigned char *)(x))
See ASN1 format manipulation routines for information on the ASN1_dup() fuction.
See ASN1 io routines for information on the i2d and d2i io routines.