documented fix
[gnutls.git] / lib / gnutls_dh.c
blob2c6a6c32a290b242ab7e883e5318622be01a671f
1 /*
2 * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2010 Free
3 * Software Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GnuTLS.
9 * The GnuTLS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 #include <gnutls_int.h>
27 #include <gnutls_errors.h>
28 #include <gnutls_dh.h>
31 /*
32 --Example--
33 you: X = g ^ x mod p;
34 peer:Y = g ^ y mod p;
36 your_key = Y ^ x mod p;
37 his_key = X ^ y mod p;
39 // generate our secret and the public value (X) for it
40 X = gnutls_calc_dh_secret(&x, g, p);
41 // now we can calculate the shared secret
42 key = gnutls_calc_dh_key(Y, x, g, p);
43 _gnutls_mpi_release(x);
44 _gnutls_mpi_release(g);
47 #define MAX_BITS 18000
49 /* returns the public value (X), and the secret (ret_x).
51 bigint_t
52 gnutls_calc_dh_secret (bigint_t * ret_x, bigint_t g, bigint_t prime)
54 bigint_t e, x = NULL;
55 int x_size = _gnutls_mpi_get_nbits (prime) - 1;
56 /* The size of the secret key is less than
57 * prime/2
60 if (x_size > MAX_BITS || x_size <= 0)
62 gnutls_assert ();
63 return NULL;
66 x = _gnutls_mpi_randomize (NULL, x_size, GNUTLS_RND_RANDOM);
67 if (x == NULL)
69 gnutls_assert ();
70 return NULL;
73 e = _gnutls_mpi_alloc_like (prime);
74 if (e == NULL)
76 gnutls_assert ();
77 if (ret_x)
78 *ret_x = NULL;
80 _gnutls_mpi_release (&x);
81 return NULL;
84 _gnutls_mpi_powm (e, g, x, prime);
86 if (ret_x)
87 *ret_x = x;
88 else
89 _gnutls_mpi_release (&x);
90 return e;
94 bigint_t
95 gnutls_calc_dh_key (bigint_t f, bigint_t x, bigint_t prime)
97 bigint_t k;
98 int bits;
100 bits = _gnutls_mpi_get_nbits (prime);
101 if (bits <= 0 || bits > MAX_BITS)
103 gnutls_assert ();
104 return NULL;
107 k = _gnutls_mpi_alloc_like (prime);
108 if (k == NULL)
109 return NULL;
110 _gnutls_mpi_powm (k, f, x, prime);
111 return k;
115 * _gnutls_get_dh_params - Returns the DH parameters pointer
116 * @dh_params: is an DH parameters structure, or NULL.
117 * @func: is a callback function to receive the parameters or NULL.
118 * @session: a gnutls session.
120 * This function will return the dh parameters pointer.
122 gnutls_dh_params_t
123 _gnutls_get_dh_params (gnutls_dh_params_t dh_params,
124 gnutls_params_function * func,
125 gnutls_session_t session)
127 gnutls_params_st params;
128 int ret;
130 /* if cached return the cached */
131 if (session->internals.params.dh_params)
132 return session->internals.params.dh_params;
134 if (dh_params)
136 session->internals.params.dh_params = dh_params;
138 else if (func)
140 ret = func (session, GNUTLS_PARAMS_DH, &params);
141 if (ret == 0 && params.type == GNUTLS_PARAMS_DH)
143 session->internals.params.dh_params = params.params.dh;
144 session->internals.params.free_dh_params = params.deinit;
148 return session->internals.params.dh_params;