summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlf Möller <ulf@openssl.org>2000-01-22 20:05:23 +0000
committerUlf Möller <ulf@openssl.org>2000-01-22 20:05:23 +0000
commit4486d0cd7a715aed7ca3728aa24413d91666bb68 (patch)
tree36342c32d8bd73c31ea5e3d33e9ee7796bab873c
parent09483c58e3b21841d2761ce90b1f12b24f814881 (diff)
downloadopenssl-new-4486d0cd7a715aed7ca3728aa24413d91666bb68.tar.gz
Document the DH library, and make some minor changes along the way.
-rw-r--r--CHANGES15
-rw-r--r--crypto/bn/bn.h19
-rw-r--r--crypto/bn/bn_prime.c35
-rw-r--r--crypto/dh/dh.h8
-rw-r--r--crypto/dh/dh_check.c14
-rw-r--r--crypto/dh/dh_gen.c6
-rw-r--r--crypto/mem_dbg.c2
-rw-r--r--crypto/rsa/rsa_chk.c4
-rw-r--r--doc/crypto/BN_generate_prime.pod87
-rw-r--r--doc/crypto/DH_generate_key.pod50
-rw-r--r--doc/crypto/DH_generate_parameters.pod67
-rw-r--r--doc/crypto/DH_get_ex_new_index.pod34
-rw-r--r--doc/crypto/DH_new.pod38
-rw-r--r--doc/crypto/DH_set_method.pod99
-rw-r--r--doc/crypto/DH_size.pod33
-rw-r--r--doc/crypto/DHparams_print.pod31
-rw-r--r--doc/crypto/RSA_size.pod2
-rw-r--r--doc/crypto/bn.pod138
-rw-r--r--doc/crypto/d2i_DHparams.pod30
-rw-r--r--doc/crypto/dh.pod65
20 files changed, 737 insertions, 40 deletions
diff --git a/CHANGES b/CHANGES
index b1bb986994..d9be214926 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,17 @@
Changes between 0.9.4 and 0.9.5 [xx XXX 1999]
+ *) Make BN_generate_prime() return NULL on error if ret!=NULL.
+ [Ulf Möller]
+
+ *) Retain source code compatibility for BN_prime_checks macro.
+ [Ulf Möller]
+
+ *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to
+ DH_CHECK_P_NOT_SAFE_PRIME.
+ (Check if this is true? OpenPGP calls them "strong".)
+ [Ulf Möller]
+
*) Merge the functionality of "dh" and "gendh" programs into a new program
"dhparam". The old programs are retained for now but will handle DH keys
(instead of parameters) in future.
@@ -57,8 +68,8 @@
*) Do more iterations of Rabin-Miller probable prime test (specifically,
3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes
- instead of only 2 for all lengths; see BN_prime_checks definition
- in crypto/bn/bn.h for the complete table). This guarantees a
+ instead of only 2 for all lengths; see BN_prime_checks_size definition
+ in crypto/bn/bn_prime.c for the complete table). This guarantees a
false-positive rate of at most 2^-80 (actually less because we are
additionally doing trial division) for random input.
[Bodo Moeller]
diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h
index dd1d263098..f803f0fea1 100644
--- a/crypto/bn/bn.h
+++ b/crypto/bn/bn.h
@@ -283,23 +283,8 @@ typedef struct bn_recp_ctx_st
#define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\
r,a,&((mont)->RR),(mont),ctx)
-/* number of Miller-Rabin iterations for an error rate of less than 2^-80
- * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
- * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
- * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
- * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
-#define BN_prime_checks(b) ((b) >= 1300 ? 2 : \
- (b) >= 850 ? 3 : \
- (b) >= 650 ? 4 : \
- (b) >= 550 ? 5 : \
- (b) >= 450 ? 6 : \
- (b) >= 400 ? 7 : \
- (b) >= 350 ? 8 : \
- (b) >= 300 ? 9 : \
- (b) >= 250 ? 12 : \
- (b) >= 200 ? 15 : \
- (b) >= 150 ? 18 : \
- /* b >= 100 */ 27)
+#define BN_prime_checks 0 /* default: select number of iterations
+ based on the size of the number */
#define BN_num_bytes(a) ((BN_num_bits(a)+7)/8)
#define BN_is_word(a,w) (((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w)))
diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c
index f4f596a481..f82cc1f605 100644
--- a/crypto/bn/bn_prime.c
+++ b/crypto/bn/bn_prime.c
@@ -62,12 +62,30 @@
#include "bn_lcl.h"
#include <openssl/rand.h>
-/* The quick seive algorithm approach to weeding out primes is
+/* The quick sieve algorithm approach to weeding out primes is
* Philip Zimmermann's, as implemented in PGP. I have had a read of
* his comments and implemented my own version.
*/
#include "bn_prime.h"
+/* number of Miller-Rabin iterations for an error rate of less than 2^-80
+ * for random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook
+ * of Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996];
+ * original paper: Damgaard, Landrock, Pomerance: Average case error estimates
+ * for the strong probable prime test. -- Math. Comp. 61 (1993) 177-194) */
+#define BN_prime_checks_size(b) ((b) >= 1300 ? 2 : \
+ (b) >= 850 ? 3 : \
+ (b) >= 650 ? 4 : \
+ (b) >= 550 ? 5 : \
+ (b) >= 450 ? 6 : \
+ (b) >= 400 ? 7 : \
+ (b) >= 350 ? 8 : \
+ (b) >= 300 ? 9 : \
+ (b) >= 250 ? 12 : \
+ (b) >= 200 ? 15 : \
+ (b) >= 150 ? 18 : \
+ /* b >= 100 */ 27)
+
static int witness(BIGNUM *a, BIGNUM *n, BN_CTX *ctx,BN_CTX *ctx2,
BN_MONT_CTX *mont);
static int probable_prime(BIGNUM *rnd, int bits);
@@ -81,9 +99,10 @@ BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, BIGNUM *add,
{
BIGNUM *rnd=NULL;
BIGNUM t;
+ int found=0;
int i,j,c1=0;
BN_CTX *ctx;
- int checks = BN_prime_checks(bits);
+ int checks = BN_prime_checks_size(bits);
ctx=BN_CTX_new();
if (ctx == NULL) goto err;
@@ -145,12 +164,12 @@ loop:
}
}
/* we have a prime :-) */
- ret=rnd;
+ found = 1;
err:
- if ((ret == NULL) && (rnd != NULL)) BN_free(rnd);
+ if (!found && (ret == NULL) && (rnd != NULL)) BN_free(rnd);
BN_free(&t);
if (ctx != NULL) BN_CTX_free(ctx);
- return(ret);
+ return(found ? rnd : NULL);
}
int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *),
@@ -161,6 +180,12 @@ int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int,int,void *),
BN_CTX *ctx=NULL,*ctx2=NULL;
BN_MONT_CTX *mont=NULL;
+ if (checks == BN_prime_checks)
+ {
+ int bits = BN_num_bits(a);
+ checks = BN_prime_checks_size(bits);
+ }
+
if (!BN_is_odd(a))
return(0);
if (ctx_passed != NULL)
diff --git a/crypto/dh/dh.h b/crypto/dh/dh.h
index 5d17a27a2a..c96cdde968 100644
--- a/crypto/dh/dh.h
+++ b/crypto/dh/dh.h
@@ -98,7 +98,7 @@ struct dh_st
BIGNUM *p;
BIGNUM *g;
int length; /* optional */
- BIGNUM *pub_key; /* y */
+ BIGNUM *pub_key; /* g^x */
BIGNUM *priv_key; /* x */
int flags;
@@ -121,10 +121,14 @@ struct dh_st
/* DH_check error codes */
#define DH_CHECK_P_NOT_PRIME 0x01
-#define DH_CHECK_P_NOT_STRONG_PRIME 0x02
+#define DH_CHECK_P_NOT_SAFE_PRIME 0x02
#define DH_UNABLE_TO_CHECK_GENERATOR 0x04
#define DH_NOT_SUITABLE_GENERATOR 0x08
+/* primes p where (p-1)/2 is prime too are called "safe"; we define
+ this for backward compatibility: */
+#define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME
+
#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, \
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
index a2e7433b9c..7e5cfd8bfc 100644
--- a/crypto/dh/dh_check.c
+++ b/crypto/dh/dh_check.c
@@ -61,7 +61,7 @@
#include <openssl/bn.h>
#include <openssl/dh.h>
-/* Check that p is a strong prime and
+/* Check that p is a safe prime and
* if g is 2, 3 or 5, check that is is a suitable generator
* where
* for 2, p mod 24 == 11
@@ -88,11 +88,13 @@ int DH_check(DH *dh, int *ret)
l=BN_mod_word(dh->p,24);
if (l != 11) *ret|=DH_NOT_SUITABLE_GENERATOR;
}
-/* else if (BN_is_word(dh->g,DH_GENERATOR_3))
+#if 0
+ else if (BN_is_word(dh->g,DH_GENERATOR_3))
{
l=BN_mod_word(dh->p,12);
if (l != 5) *ret|=DH_NOT_SUITABLE_GENERATOR;
- }*/
+ }
+#endif
else if (BN_is_word(dh->g,DH_GENERATOR_5))
{
l=BN_mod_word(dh->p,10);
@@ -102,13 +104,13 @@ int DH_check(DH *dh, int *ret)
else
*ret|=DH_UNABLE_TO_CHECK_GENERATOR;
- if (!BN_is_prime(dh->p,BN_prime_checks(BN_num_bits(dh->p)),NULL,ctx,NULL))
+ if (!BN_is_prime(dh->p,BN_prime_checks,NULL,ctx,NULL))
*ret|=DH_CHECK_P_NOT_PRIME;
else
{
if (!BN_rshift1(q,dh->p)) goto err;
- if (!BN_is_prime(q,BN_prime_checks(BN_num_bits(q)),NULL,ctx,NULL))
- *ret|=DH_CHECK_P_NOT_STRONG_PRIME;
+ if (!BN_is_prime(q,BN_prime_checks,NULL,ctx,NULL))
+ *ret|=DH_CHECK_P_NOT_SAFE_PRIME;
}
ok=1;
err:
diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c
index b7bcd2c7a4..f0ee43ed87 100644
--- a/crypto/dh/dh_gen.c
+++ b/crypto/dh/dh_gen.c
@@ -72,14 +72,14 @@
* Having said all that,
* there is another special case method for the generators 2, 3 and 5.
* for 2, p mod 24 == 11
- * for 3, p mod 12 == 5 <<<<< does not work for strong primes.
+ * for 3, p mod 12 == 5 <<<<< does not work for safe primes.
* for 5, p mod 10 == 3 or 7
*
* Thanks to Phil Karn <karn@qualcomm.com> for the pointers about the
* special generators and for answering some of my questions.
*
* I've implemented the second simple method :-).
- * Since DH should be using a strong prime (both p and q are prime),
+ * Since DH should be using a safe prime (both p and q are prime),
* this generator function can take a very very long time to run.
*/
@@ -105,7 +105,7 @@ DH *DH_generate_parameters(int prime_len, int generator,
BN_set_word(t2,11);
g=2;
}
-#ifdef undef /* does not work for strong primes */
+#ifdef undef /* does not work for safe primes */
else if (generator == DH_GENERATOR_3)
{
BN_set_word(t1,12);
diff --git a/crypto/mem_dbg.c b/crypto/mem_dbg.c
index d084b8c6ca..f3ad5ff235 100644
--- a/crypto/mem_dbg.c
+++ b/crypto/mem_dbg.c
@@ -667,8 +667,6 @@ union void_fn_to_char_u
void (*fn_p)();
};
-static void (*mem_cb)()=NULL;
-
static void cb_leak(MEM *m, char *cb)
{
union void_fn_to_char_u mem_callback;
diff --git a/crypto/rsa/rsa_chk.c b/crypto/rsa/rsa_chk.c
index 03497f8463..91b9115798 100644
--- a/crypto/rsa/rsa_chk.c
+++ b/crypto/rsa/rsa_chk.c
@@ -75,7 +75,7 @@ int RSA_check_key(RSA *key)
}
/* p prime? */
- r = BN_is_prime(key->p, BN_prime_checks(BN_num_bits(key->p)), NULL, NULL, NULL);
+ r = BN_is_prime(key->p, BN_prime_checks, NULL, NULL, NULL);
if (r != 1)
{
ret = r;
@@ -85,7 +85,7 @@ int RSA_check_key(RSA *key)
}
/* q prime? */
- r = BN_is_prime(key->q, BN_prime_checks(BN_num_bits(key->q)), NULL, NULL, NULL);
+ r = BN_is_prime(key->q, BN_prime_checks, NULL, NULL, NULL);
if (r != 1)
{
ret = r;
diff --git a/doc/crypto/BN_generate_prime.pod b/doc/crypto/BN_generate_prime.pod
new file mode 100644
index 0000000000..6744d5d815
--- /dev/null
+++ b/doc/crypto/BN_generate_prime.pod
@@ -0,0 +1,87 @@
+=pod
+
+=head1 NAME
+
+BN_generate_prime, BN_is_prime - Generate primes and test for primality
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ BIGNUM *BN_generate_prime(BIGNUM *ret, int num, int safe, BIGNUM *add,
+ BIGNUM *rem, void (*callback)(int, int, void *), void *cb_arg);
+
+ int BN_is_prime(BIGNUM *a, int checks, void (*callback)(int, int,
+ void *), BN_CTX *ctx, void *cb_arg);
+
+=head1 DESCRIPTION
+
+BN_generate_prime() generates a pseudo-random prime number of B<num>
+bits.
+If B<ret> is not NULL, it will be used to store the number.
+
+If B<callback> is not B<NULL>, it is called as follows:
+
+=over 4
+
+=item *
+
+B<callback(0, i, cb_arg)> is called after generating the i-th
+potential prime number.
+
+=item *
+
+While the number is being tested for primality, B<callback(1, j,
+cb_arg)> is called as described below.
+
+=item *
+
+When a prime has been found, B<callback(2, i, cb_arg)> is called.
+
+=back
+
+The prime may have to fulfill additional requirements for use in
+Diffie-Hellman key exchange:
+
+If B<add> is not NULL, the prime will fulfill the condition p % B<add>
+== B<rem> (p % B<add> == 1 if B<rem> == NULL) in order to suit a given
+generator.
+
+If B<safe> is true, it will be a safe prime (i.e. a prime p so
+that (p-1)/2 is also prime).
+
+The PRNG must be seeded prior to calling BN_generate_prime().
+The prime number generation has a negligible error probability.
+
+BN_is_prime() tests if the number B<a> is prime. This is done by
+performing a Miller-Rabin probabilistic primality test with B<checks>
+iterations. If B<checks == BN_prime_check>, it uses the minimal number
+of iterations that yields a false positive rate of at most 2^-80 for
+random input.
+
+If B<callback> is not B<NULL>, B<callback(1, j, cb_arg)> is called
+after the j-th iteration. B<ctx> is a pre-allocated B<BN_CTX> (to save
+the overhead of allocating and freeing the structure in a loop), or
+NULL.
+
+=head1 RETURN VALUES
+
+BN_generate_prime() returns the prime number on success, NULL otherwise.
+
+BN_is_prime() returns 0 if the number is composite, 1 if it is
+prime with an error probability of less than 0.25^B<checks>, and
+-1 on error.
+
+The error codes can be obtained by ERR_get_error(3).
+
+=head1 SEE ALSO
+
+bn(3), err(3), rand(3)
+
+=head1 HISTORY
+
+The B<cb_arg> arguments to BN_generate_prime() and to BN_is_prime()
+were added in SSLeay 0.9.0. The B<ret> argument to BN_generate_prime()
+was added in SSLeay 0.9.1.
+
+=cut
diff --git a/doc/crypto/DH_generate_key.pod b/doc/crypto/DH_generate_key.pod
new file mode 100644
index 0000000000..edd674e4de
--- /dev/null
+++ b/doc/crypto/DH_generate_key.pod
@@ -0,0 +1,50 @@
+=pod
+
+=head1 NAME
+
+DH_generate_key, DH_compute_key - Perform Diffie-Hellman key exchange
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ int DH_generate_key(DH *dh);
+
+ int DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh);
+
+=head1 DESCRIPTION
+
+DH_generate_key() performs the first step of a Diffie-Hellman key
+exchange by generating private and public DH values. By calling
+DH_compute_key(), these are combined with the other party's public
+value to compute the shared key.
+
+DH_generate_key() expects B<dh> to contain the shared parameters
+B<dh-E<gt>p> and B<dh-E<gt>g>. It generates a random private DH value
+unless B<dh-E<gt>priv_key> is already set, and computes the
+corresponding public value B<dh-E<gt>pub_key>, which can then be
+published.
+
+DH_compute_key() computes the shared secret from the private DH value
+in B<dh> and the other party's public value in B<pub_key> and stores
+it in B<key>. B<key> must point to B<DH_size(dh)> bytes of memory.
+
+=head1 RETURN VALUES
+
+DH_generate_key() returns 1 on success, 0 otherwise.
+
+DH_compute_key() returns the size of the shared secret on success, -1
+on error.
+
+The error codes can be obtained by ERR_get_error(3).
+
+=head1 SEE ALSO
+
+dh(3), err(3), rand(3), DH_size(3)
+
+=head1 HISTORY
+
+DH_generate_key() and DH_compute_key() are available in all versions
+of SSLeay and OpenSSL.
+
+=cut
diff --git a/doc/crypto/DH_generate_parameters.pod b/doc/crypto/DH_generate_parameters.pod
new file mode 100644
index 0000000000..7523bb2fe0
--- /dev/null
+++ b/doc/crypto/DH_generate_parameters.pod
@@ -0,0 +1,67 @@
+=pod
+
+=head1 NAME
+
+DH_generate_parameters, DH_check - Generate and check Diffie-Hellman parameters
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ DH *DH_generate_parameters(int prime_len, int generator,
+ void (*callback)(int, int, void *), void *cb_arg);
+
+ int DH_check(DH *dh, int *codes);
+
+=head1 DESCRIPTION
+
+DH_generate_parameters() generates Diffie-Hellman parameters that can
+be shared among a group of users, and returns them in a newly
+allocated B<DH> structure. The pseudo-random number generator must be
+seeded prior to calling DH_generate_parameters().
+
+B<prime_len> is the length in bits of the safe prime to be generated.
+B<generator> is a small number E<gt> 1, typically 2 or 5.
+
+A callback function may be used to provide feedback about the progress
+of the key generation. If B<callback> is not B<NULL>, it will be
+called as described in L<BN_generate_prime(3)> while a random prime
+number is generated, and when a prime has been found, B<callback(3,
+0, cb_arg)> is called.
+
+DH_check() validates Diffie-Hellman parameters. It checks that B<p> is
+a safe prime, and that B<g> is a suitable generator. In the case of an
+error, the bit flags DH_CHECK_P_NOT_SAFE_PRIME or
+DH_NOT_SUITABLE_GENERATOR are set in B<*codes>.
+DH_UNABLE_TO_CHECK_GENERATOR is set if the generator cannot be
+checked, i.e. it does not equal 2 or 5.
+
+=head1 RETURN VALUES
+
+DH_generate_parameters() returns a pointer to the DH structure, or
+NULL if the parameter generation fails. The error codes can be
+obtained by ERR_get_error(3).
+
+DH_check() returns 1 if the check could be performed, 0 otherwise.
+
+=head1 NOTES
+
+DH_generate_parameters() may run for several hours before finding a
+suitable prime.
+
+The parameters generated by DH_generate_parameters() are not to be
+used in signature schemes.
+
+=head1 SEE ALSO
+
+dh(3), err(3), rand(3), DH_free(3)
+
+=head1 HISTORY
+
+DH_check() is available in all versions of SSLeay and OpenSSL.
+The B<cb_arg> argument to DH_generate_parameters() was added in SSLeay 0.9.0.
+
+In versions before OpenSSL 0.9.5, DH_CHECK_P_NOT_STRONG_PRIME is used
+instead of DH_CHECK_P_NOT_SAFE_PRIME.
+
+=cut
diff --git a/doc/crypto/DH_get_ex_new_index.pod b/doc/crypto/DH_get_ex_new_index.pod
new file mode 100644
index 0000000000..d52181e83f
--- /dev/null
+++ b/doc/crypto/DH_get_ex_new_index.pod
@@ -0,0 +1,34 @@
+=pod
+
+=head1 NAME
+
+DH_get_ex_new_index, DH_set_ex_data, DH_get_ex_data - ...
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ int DH_get_ex_new_index(long argl, char *argp, int (*new_func)(),
+ int (*dup_func)(), void (*free_func)());
+
+ int DH_set_ex_data(DH *d, int idx, char *arg);
+
+ char *DH_get_ex_data(DH *d, int idx);
+
+=head1 DESCRIPTION
+
+...
+
+=head1 RETURN VALUES
+
+...
+
+=head1 SEE ALSO
+
+...
+
+=head1 HISTORY
+
+...
+
+=cut
diff --git a/doc/crypto/DH_new.pod b/doc/crypto/DH_new.pod
new file mode 100644
index 0000000000..c54505af54
--- /dev/null
+++ b/doc/crypto/DH_new.pod
@@ -0,0 +1,38 @@
+=pod
+
+=head1 NAME
+
+DH_new, DH_free - allocate and free DH objects
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ DH* DH_new(void);
+
+ void DH_free(DH *rsa);
+
+=head1 DESCRIPTION
+
+DH_new() allocates and initializes a B<DH> structure.
+
+DH_free() frees the B<DH> structure and its components. The values are
+erased before the memory is returned to the system.
+
+=head1 RETURN VALUES
+
+If the allocation fails, DH_new() returns B<NULL> and sets an error
+code that can be obtained by ERR_get_error(3). Otherwise it returns
+a pointer to the newly allocated structure.
+
+DH_free() returns no value.
+
+=head1 SEE ALSO
+
+dh(3), err(3), DH_generate_parameters(3), DH_generate_key(3)
+
+=head1 HISTORY
+
+DH_new() and DH_free() are available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/doc/crypto/DH_set_method.pod b/doc/crypto/DH_set_method.pod
new file mode 100644
index 0000000000..b50bf42a56
--- /dev/null
+++ b/doc/crypto/DH_set_method.pod
@@ -0,0 +1,99 @@
+=pod
+
+=head1 NAME
+
+DH_set_default_method, DH_get_default_method, DH_set_method,
+DH_new_method, DH_OpenSSL - Select RSA method
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ void DH_set_default_method(DH_METHOD *meth);
+
+ DH_METHOD *DH_get_default_method(void);
+
+ DH_METHOD *DH_set_method(DH *dh, DH_METHOD *meth);
+
+ DH *DH_new_method(DH_METHOD *meth);
+
+ DH_METHOD *DH_OpenSSL(void);
+
+=head1 DESCRIPTION
+
+A B<DH_METHOD> specifies the functions that OpenSSL uses for Diffie-Hellman
+operations. By modifying the method, alternative implementations
+such as hardware accelerators may be used.
+
+Initially, the default is to use the OpenSSL internal implementation.
+DH_OpenSSL() returns a pointer to that method.
+
+DH_set_default_method() makes B<meth> the default method for all B<DH>
+structures created later.
+
+DH_get_default_method() returns a pointer to the current default
+method.
+
+DH_set_method() selects B<meth> for all operations using the structure B<dh>.
+
+DH_get_method() returns a pointer to the method currently selected
+for B<dh>.
+
+DH_new_method() allocates and initializes a B<DH> structure so that
+B<method> will be used for the DH operations. If B<method> is B<NULL>,
+the default method is used.
+
+=head1 THE DH_METHOD STRUCTURE
+
+ typedef struct dh_meth_st
+ {
+ /* name of the implementation */
+ const char *name;
+
+ /* generate private and public DH values for key agreement */
+ int (*generate_key)(DH *dh);
+
+ /* compute shared secret */
+ int (*compute_key)(unsigned char *key, BIGNUM *pub_key, DH *dh);
+
+ /* compute r = a ^ p mod m. May be NULL */
+ int (*bn_mod_exp)(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx,
+ BN_MONT_CTX *m_ctx);
+
+ /* called at DH_new */
+ int (*init)(DH *dh);
+
+ /* called at DH_free */
+ int (*finish)(DH *dh);
+
+ int flags;
+
+ char *app_data; /* ?? */
+
+ } DH_METHOD;
+
+=head1 RETURN VALUES
+
+DH_OpenSSL(), DH_get_default_method() and DH_get_method() return
+pointers to the respective B<DH_METHOD>s.
+
+DH_set_default_method() returns no value.
+
+DH_set_method() returns a pointer to the B<DH_METHOD> previously
+associated with B<dh>.
+
+DH_new_method() returns B<NULL> and sets an error code that can be
+obtained by ERR_get_error(3) if the allocation fails. Otherwise it
+returns a pointer to the newly allocated structure.
+
+=head1 SEE ALSO
+
+dh(3), DH_new(3)
+
+=head1 HISTORY
+
+DH_set_default_method(), DH_get_default_method(), DH_set_method(),
+DH_new_method() and DH_OpenSSL() were added in OpenSSL 0.9.4.
+
+=cut
diff --git a/doc/crypto/DH_size.pod b/doc/crypto/DH_size.pod
new file mode 100644
index 0000000000..67705f5d3c
--- /dev/null
+++ b/doc/crypto/DH_size.pod
@@ -0,0 +1,33 @@
+=pod
+
+=head1 NAME
+
+DH_size - Get Diffie-Hellman prime size
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ int DH_size(DH *dh);
+
+=head1 DESCRIPTION
+
+This function returns the Diffie-Hellman size in bytes. It can be used
+to determine how much memory must be allocated for the shared secret
+computed by DH_compute_key().
+
+B<dh-E<gt>p> must not be B<NULL>.
+
+=head1 RETURN VALUE
+
+The size in bytes.
+
+=head1 SEE ALSO
+
+dh(3), DH_generate_key(3)
+
+=head1 HISTORY
+
+DH_size() is available in all versions of SSLeay and OpenSSL.
+
+=cut
diff --git a/doc/crypto/DHparams_print.pod b/doc/crypto/DHparams_print.pod
new file mode 100644
index 0000000000..e34459f494
--- /dev/null
+++ b/doc/crypto/DHparams_print.pod
@@ -0,0 +1,31 @@
+=pod
+
+=head1 NAME
+
+DHparams_print, DHparams_print_fp - Print Diffie-Hellman parameters
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ int DHparams_print_fp(FILE *fp, DH *x);
+
+ int DHparams_print(BIO *bp, DH *x);
+
+=head1 DESCRIPTION
+
+...
+
+=head1 RETURN VALUES
+
+...
+
+=head1 SEE ALSO
+
+...
+
+=head1 HISTORY
+
+...
+
+=cut
diff --git a/doc/crypto/RSA_size.pod b/doc/crypto/RSA_size.pod
index 9af1c40f1a..d625925dc1 100644
--- a/doc/crypto/RSA_size.pod
+++ b/doc/crypto/RSA_size.pod
@@ -16,7 +16,7 @@ This function returns the RSA modulus size in bytes. It can be used to
determine how much memory must be allocated for an RSA encrypted
value.
-B<rsa->n> must not be B<NULL>.
+B<rsa-E<gt>n> must not be B<NULL>.
=head1 RETURN VALUE
diff --git a/doc/crypto/bn.pod b/doc/crypto/bn.pod
new file mode 100644
index 0000000000..fbd674dd5e
--- /dev/null
+++ b/doc/crypto/bn.pod
@@ -0,0 +1,138 @@
+=pod
+
+=head1 NAME
+
+bn - Multiprecision integer arithmetics
+
+=head1 SYNOPSIS
+
+ #include <openssl/bn.h>
+
+ #define BN_prime_checks(b)
+ #define BN_num_bytes(a)
+ #define BN_is_word(a,w)
+ #define BN_is_zero(a)
+ #define BN_is_one(a)
+ #define BN_is_odd(a)
+ #define BN_one(a)
+ #define BN_zero(a)
+
+ #define bn_expand(n,b)
+ #define bn_wexpand(n,b)
+
+ #define bn_fix_top(a)
+
+ BIGNUM *BN_value_one(void);
+ char * BN_options(void);
+ BN_CTX *BN_CTX_new(void);
+ void BN_CTX_init(BN_CTX *c);
+ void BN_CTX_free(BN_CTX *c);
+ int BN_rand(BIGNUM *rnd, int bits, int top,int bottom);
+ int BN_num_bits(const BIGNUM *a);
+ int BN_num_bits_word(BN_ULONG);
+ BIGNUM *BN_new(void);
+ void BN_init(BIGNUM *);
+ void BN_clear_free(BIGNUM *a);
+ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b);
+ BIGNUM *BN_bin2bn(const unsigned char *s,int len,BIGNUM *ret);
+ int BN_bn2bin(const BIGNUM *a, unsigned char *to);
+ BIGNUM *BN_mpi2bn(unsigned char *s,int len,BIGNUM *ret);
+ int BN_bn2mpi(const BIGNUM *a, unsigned char *to);
+ int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
+ int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b);
+ int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
+ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
+ BN_CTX *ctx);
+ int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b,BN_CTX *ctx);
+ int BN_sqr(BIGNUM *r, BIGNUM *a,BN_CTX *ctx);
+ BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w);
+ BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w);
+ int BN_mul_word(BIGNUM *a, BN_ULONG w);
+ int BN_add_word(BIGNUM *a, BN_ULONG w);
+ int BN_sub_word(BIGNUM *a, BN_ULONG w);
+ int BN_set_word(BIGNUM *a, BN_ULONG w);
+ BN_ULONG BN_get_word(BIGNUM *a);
+ int BN_cmp(const BIGNUM *a, const BIGNUM *b);
+ void BN_free(BIGNUM *a);
+ int BN_is_bit_set(const BIGNUM *a, int n);
+ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
+ int BN_lshift1(BIGNUM *r, BIGNUM *a);
+ int BN_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p,BN_CTX *ctx);
+ int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m,BN_CTX *ctx);
+ int BN_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+ int BN_mod_exp2_mont(BIGNUM *r, BIGNUM *a1, BIGNUM *p1,BIGNUM *a2,
+ BIGNUM *p2,BIGNUM *m,BN_CTX *ctx,BN_MONT_CTX *m_ctx);
+ int BN_mod_exp_simple(BIGNUM *r, BIGNUM *a, BIGNUM *p,
+ BIGNUM *m,BN_CTX *ctx);
+ int BN_mask_bits(BIGNUM *a,int n);
+ int BN_mod_mul(BIGNUM *ret, BIGNUM *a, BIGNUM *b, const BIGNUM *m, BN_CTX *ctx);
+ int BN_print_fp(FILE *fp, BIGNUM *a);
+ int BN_print(BIO *fp, const BIGNUM *a);
+ int BN_reciprocal(BIGNUM *r, BIGNUM *m, int len, BN_CTX *ctx);
+ int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
+ int BN_rshift1(BIGNUM *r, BIGNUM *a);
+ void BN_clear(BIGNUM *a);
+ BIGNUM *bn_expand2(BIGNUM *b, int bits);
+ BIGNUM *BN_dup(const BIGNUM *a);
+ int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
+ int BN_set_bit(BIGNUM *a, int n);
+ int BN_clear_bit(BIGNUM *a, int n);
+ char * BN_bn2hex(const BIGNUM *a);
+ char * BN_bn2dec(const BIGNUM *a);
+ int BN_hex2bn(BIGNUM **a, const char *str);
+ int BN_dec2bn(BIGNUM **a, const char *str);
+ int BN_gcd(BIGNUM *r,BIGNUM *in_a,BIGNUM *in_b,BN_CTX *ctx);
+ BIGNUM *BN_mod_inverse(BIGNUM *ret,BIGNUM *a, const BIGNUM *n,BN_CTX *ctx);
+ BIGNUM *BN_generate_prime(BIGNUM *ret,int bits,int safe,BIGNUM *add,
+ BIGNUM *rem,void (*callback)(int,int,void *),void *cb_arg);
+ int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(int,int,void *),
+ BN_CTX *ctx,void *cb_arg);
+ void ERR_load_BN_strings(void );
+
+ BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+ BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w);
+ void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num);
+ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
+ BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
+ BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num);
+
+ BN_MONT_CTX *BN_MONT_CTX_new(void );
+ void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
+ int BN_mod_mul_montgomery(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_MONT_CTX *mont,
+ BN_CTX *ctx);
+ int BN_from_montgomery(BIGNUM *r,BIGNUM *a,BN_MONT_CTX *mont,BN_CTX *ctx);
+ void BN_MONT_CTX_free(BN_MONT_CTX *mont);
+ int BN_MONT_CTX_set(BN_MONT_CTX *mont,const BIGNUM *modulus,BN_CTX *ctx);
+ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,BN_MONT_CTX *from);
+
+ BN_BLINDING *BN_BLINDING_new(BIGNUM *A,BIGNUM *Ai,BIGNUM *mod);
+ void BN_BLINDING_free(BN_BLINDING *b);
+ int BN_BLINDING_update(BN_BLINDING *b,BN_CTX *ctx);
+ int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *r, BN_CTX *ctx);
+ int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
+
+ void BN_set_params(int mul,int high,int low,int mont);
+ int BN_get_params(int which);
+
+ void BN_RECP_CTX_init(BN_RECP_CTX *recp);
+ BN_RECP_CTX *BN_RECP_CTX_new(void);
+ void BN_RECP_CTX_free(BN_RECP_CTX *recp);
+ int BN_RECP_CTX_set(BN_RECP_CTX *recp,const BIGNUM *rdiv,BN_CTX *ctx);
+ int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y,
+ BN_RECP_CTX *recp,BN_CTX *ctx);
+ int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx);
+ int BN_div_recp(BIGNUM *dv, BIGNUM *rem, BIGNUM *m,
+ BN_RECP_CTX *recp, BN_CTX *ctx);
+
+=head1 DESCRIPTION
+
+=head1 SEE ALSO
+
+err(3), rand(3)
+
+=cut
diff --git a/doc/crypto/d2i_DHparams.pod b/doc/crypto/d2i_DHparams.pod
new file mode 100644
index 0000000000..64881d374a
--- /dev/null
+++ b/doc/crypto/d2i_DHparams.pod
@@ -0,0 +1,30 @@
+=pod
+
+=head1 NAME
+
+d2i_DHparams, i2d_DHparams - ...
+
+=head1 SYNOPSIS
+
+#include <openssl/dh.h>
+
+ DH *d2i_DHparams(DH **a, unsigned char **pp, long length);
+ int i2d_DHparams(DH *a, unsigned char **pp);
+
+=head1 DESCRIPTION
+
+...
+
+=head1 RETURN VALUES
+
+...
+
+=head1 SEE ALSO
+
+...
+
+=head1 HISTORY
+
+...
+
+=cut
diff --git a/doc/crypto/dh.pod b/doc/crypto/dh.pod
new file mode 100644
index 0000000000..d364da48fd
--- /dev/null
+++ b/doc/crypto/dh.pod
@@ -0,0 +1,65 @@
+=pod
+
+=head1 NAME
+
+dh - Diffie-Hellman key agreement
+
+=head1 SYNOPSIS
+
+ #include <openssl/dh.h>
+
+ void DH_set_default_method(DH_METHOD *meth);
+ DH_METHOD *DH_get_default_method(void);
+ DH_METHOD *DH_set_method(DH *dh, DH_METHOD *meth);
+ DH *DH_new_method(DH_METHOD *meth);
+ DH_METHOD *DH_OpenSSL(void);
+
+ DH * DH_new(void);
+ void DH_free(DH *dh);
+
+ int DH_size(DH *dh);
+
+ int DH_get_ex_new_index(long argl, char *argp, int (*new_func)(),
+ int (*dup_func)(), void (*free_func)());
+ int DH_set_ex_data(DH *d, int idx, char *arg);
+ char *DH_get_ex_data(DH *d, int idx);
+
+ DH * DH_generate_parameters(int prime_len, int generator,
+ void (*callback)(int, int, void *), void *cb_arg);
+ int DH_check(DH *dh, int *codes);
+
+ int DH_generate_key(DH *dh);
+ int DH_compute_key(unsigned char *key, BIGNUM *pub_key, DH *dh);
+
+ DH * d2i_DHparams(DH **a, unsigned char **pp, long length);
+ int i2d_DHparams(DH *a, unsigned char **pp);
+
+ int DHparams_print_fp(FILE *fp, DH *x);
+ int DHparams_print(BIO *bp, DH *x);
+
+=head1 DESCRIPTION
+
+These functions implement the Diffie-Hellman key agreement protocol.
+The generation of shared DH parameters is described in
+L<DH_generate_parameters(3)>; L<DH_generate_key(3)> describes how
+to perform a key agreement.
+
+The B<DH> structure consists of several BIGNUM components.
+
+ struct
+ {
+ BIGNUM *p; // prime number (shared)
+ BIGNUM *g; // generator of Z_p (shared)
+ BIGNUM *priv_key; // private DH value x
+ BIGNUM *pub_key; // public DH value g^x
+ // ...
+ };
+ DH
+
+=head1 SEE ALSO
+
+dh(1), bn(3), dsa(3), err(3), rand(3), rsa(3), DH_set_method(3),
+DH_new(3), DH_get_ex_new_index(3), DH_generate_parameters(3),
+DH_compute_key(3), d2i_DHparams(3), DHparams_print(3)
+
+=cut