gnutls_dh.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
00003  *
00004  * Author: Nikos Mavrogiannopoulos
00005  *
00006  * This file is part of GNUTLS.
00007  *
00008  * The GNUTLS library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public License
00010  * as published by the Free Software Foundation; either version 2.1 of
00011  * the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00021  * USA
00022  *
00023  */
00024 
00025 #include <gnutls_int.h>
00026 #include <gnutls_errors.h>
00027 
00028 
00029 /*
00030         --Example--
00031         you: X = g ^ x mod p;
00032         peer:Y = g ^ y mod p;
00033 
00034         your_key = Y ^ x mod p;
00035         his_key  = X ^ y mod p;
00036 
00037 //      generate our secret and the public value (X) for it
00038         X = MHD_gtls_calc_dh_secret(&x, g, p);
00039 //      now we can calculate the shared secret
00040         key = MHD_gtls_calc_dh_key(Y, x, g, p);
00041         MHD_gtls_mpi_release(x);
00042         MHD_gtls_mpi_release(g);
00043 */
00044 
00045 #define MAX_BITS 18000
00046 
00047 /* returns the public value (X), and the secret (ret_x).
00048  */
00049 mpi_t
00050 MHD_gtls_calc_dh_secret (mpi_t * ret_x, mpi_t g, mpi_t prime)
00051 {
00052   mpi_t e, x;
00053   int x_size = MHD__gnutls_mpi_get_nbits (prime) - 1;
00054   /* The size of the secret key is less than
00055    * prime/2
00056    */
00057 
00058   if (x_size > MAX_BITS || x_size <= 0)
00059     {
00060       MHD_gnutls_assert ();
00061       return NULL;
00062     }
00063 
00064   x = MHD__gnutls_mpi_new (x_size);
00065   if (x == NULL)
00066     {
00067       MHD_gnutls_assert ();
00068       if (ret_x)
00069         *ret_x = NULL;
00070 
00071       return NULL;
00072     }
00073 
00074   /* FIXME: (x_size/8)*8 is there to overcome a bug in libgcrypt
00075    * which does not really check the bits given but the bytes.
00076    */
00077   do
00078     {
00079       MHD__gnutls_mpi_randomize (x, (x_size / 8) * 8, GCRY_STRONG_RANDOM);
00080       /* Check whether x is zero.
00081        */
00082     }
00083   while (MHD__gnutls_mpi_cmp_ui (x, 0) == 0);
00084 
00085   e = MHD__gnutls_mpi_alloc_like (prime);
00086   if (e == NULL)
00087     {
00088       MHD_gnutls_assert ();
00089       if (ret_x)
00090         *ret_x = NULL;
00091 
00092       MHD_gtls_mpi_release (&x);
00093       return NULL;
00094     }
00095 
00096   MHD__gnutls_mpi_powm (e, g, x, prime);
00097 
00098   if (ret_x)
00099     *ret_x = x;
00100   else
00101     MHD_gtls_mpi_release (&x);
00102   return e;
00103 }
00104 
00105 
00106 mpi_t
00107 MHD_gtls_calc_dh_key (mpi_t f, mpi_t x, mpi_t prime)
00108 {
00109   mpi_t k;
00110   int bits;
00111 
00112   bits = MHD__gnutls_mpi_get_nbits (prime);
00113   if (bits <= 0 || bits > MAX_BITS)
00114     {
00115       MHD_gnutls_assert ();
00116       return NULL;
00117     }
00118 
00119   k = MHD__gnutls_mpi_alloc_like (prime);
00120   if (k == NULL)
00121     return NULL;
00122   MHD__gnutls_mpi_powm (k, f, x, prime);
00123   return k;
00124 }
00125 
00126 /*-
00127   * MHD_gtls_get_dh_params - Returns the DH parameters pointer
00128   * @dh_params: is an DH parameters structure, or NULL.
00129   * @func: is a callback function to receive the parameters or NULL.
00130   * @session: a gnutls session.
00131   *
00132   * This function will return the dh parameters pointer.
00133   *
00134   -*/
00135 MHD_gtls_dh_params_t
00136 MHD_gtls_get_dh_params (MHD_gtls_dh_params_t dh_params,
00137                         MHD_gnutls_params_function * func,
00138                         MHD_gtls_session_t session)
00139 {
00140   MHD_gnutls_params_st params;
00141   int ret;
00142 
00143   /* if cached return the cached */
00144   if (session->internals.params.dh_params)
00145     return session->internals.params.dh_params;
00146 
00147   if (dh_params)
00148     {
00149       session->internals.params.dh_params = dh_params;
00150     }
00151   else if (func)
00152     {
00153       ret = func (session, GNUTLS_PARAMS_DH, &params);
00154       if (ret == 0 && params.type == GNUTLS_PARAMS_DH)
00155         {
00156           session->internals.params.dh_params = params.params.dh;
00157           session->internals.params.free_dh_params = params.deinit;
00158         }
00159     }
00160 
00161   return session->internals.params.dh_params;
00162 }

Generated on Fri Feb 27 18:31:58 2009 for GNU libmicrohttpd by  doxygen 1.5.7.1