Document the DH library, and make some minor changes along the way.
authorUlf Möller <ulf@openssl.org>
Sat, 22 Jan 2000 20:05:23 +0000 (20:05 +0000)
committerUlf Möller <ulf@openssl.org>
Sat, 22 Jan 2000 20:05:23 +0000 (20:05 +0000)
20 files changed:
CHANGES
crypto/bn/bn.h
crypto/bn/bn_prime.c
crypto/dh/dh.h
crypto/dh/dh_check.c
crypto/dh/dh_gen.c
crypto/mem_dbg.c
crypto/rsa/rsa_chk.c
doc/crypto/BN_generate_prime.pod [new file with mode: 0644]
doc/crypto/DH_generate_key.pod [new file with mode: 0644]
doc/crypto/DH_generate_parameters.pod [new file with mode: 0644]
doc/crypto/DH_get_ex_new_index.pod [new file with mode: 0644]
doc/crypto/DH_new.pod [new file with mode: 0644]
doc/crypto/DH_set_method.pod [new file with mode: 0644]
doc/crypto/DH_size.pod [new file with mode: 0644]
doc/crypto/DHparams_print.pod [new file with mode: 0644]
doc/crypto/RSA_size.pod
doc/crypto/bn.pod [new file with mode: 0644]
doc/crypto/d2i_DHparams.pod [new file with mode: 0644]
doc/crypto/dh.pod [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index b1bb986..d9be214 100644 (file)
--- 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]
index dd1d263..f803f0f 100644 (file)
@@ -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)))
index f4f596a..f82cc1f 100644 (file)
 #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)
index 5d17a27..c96cdde 100644 (file)
@@ -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, \
index a2e7433..7e5cfd8 100644 (file)
@@ -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:
index b7bcd2c..f0ee43e 100644 (file)
  * 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);
index d084b8c..f3ad5ff 100644 (file)
@@ -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;
index 03497f8..91b9115 100644 (file)
@@ -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 (file)
index 0000000..6744d5d
--- /dev/null
@@ -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 (file)
index 0000000..edd674e
--- /dev/null
@@ -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 (file)
index 0000000..7523bb2
--- /dev/null
@@ -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 (file)
index 0000000..d52181e
--- /dev/null
@@ -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 (file)
index 0000000..c54505a
--- /dev/null
@@ -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 (file)
index 0000000..b50bf42
--- /dev/null
@@ -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 (file)
index 0000000..67705f5
--- /dev/null
@@ -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 (file)
index 0000000..e34459f
--- /dev/null
@@ -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
index 9af1c40..d625925 100644 (file)
@@ -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 (file)
index 0000000..fbd674d
--- /dev/null
@@ -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 (file)
index 0000000..64881d3
--- /dev/null
@@ -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 (file)
index 0000000..d364da4
--- /dev/null
@@ -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