updated licenses
[gnutls.git] / lib / auth / dh_common.c
blob172c7d45c01f3c3fdf84c2605f7bc4e3519d4b7e
1 /*
2 * Copyright (C) 2002-2012 Free Software Foundation, Inc.
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GnuTLS.
8 * The GnuTLS is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 3 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>
23 /* This file contains common stuff in Ephemeral Diffie-Hellman (DHE)
24 * and Anonymous DH key exchange(DHA). These are used in the handshake
25 * procedure of the certificate and anoymous authentication.
28 #include "gnutls_int.h"
29 #include "gnutls_auth.h"
30 #include "gnutls_errors.h"
31 #include "gnutls_dh.h"
32 #include "gnutls_num.h"
33 #include "gnutls_sig.h"
34 #include <gnutls_datum.h>
35 #include <gnutls_x509.h>
36 #include <gnutls_state.h>
37 #include <auth/dh_common.h>
38 #include <algorithms.h>
39 #include <auth/psk.h>
41 /* Frees the dh_info_st structure.
43 void
44 _gnutls_free_dh_info (dh_info_st * dh)
46 dh->secret_bits = 0;
47 _gnutls_free_datum (&dh->prime);
48 _gnutls_free_datum (&dh->generator);
49 _gnutls_free_datum (&dh->public_key);
52 int
53 _gnutls_proc_dh_common_client_kx (gnutls_session_t session,
54 uint8_t * data, size_t _data_size,
55 bigint_t g, bigint_t p,
56 gnutls_datum_t* psk_key)
58 uint16_t n_Y;
59 size_t _n_Y;
60 int ret;
61 ssize_t data_size = _data_size;
64 DECR_LEN (data_size, 2);
65 n_Y = _gnutls_read_uint16 (&data[0]);
66 _n_Y = n_Y;
68 DECR_LEN (data_size, n_Y);
69 if (_gnutls_mpi_scan_nz (&session->key->client_Y, &data[2], _n_Y))
71 gnutls_assert ();
72 return GNUTLS_E_MPI_SCAN_FAILED;
75 _gnutls_dh_set_peer_public (session, session->key->client_Y);
77 session->key->KEY =
78 gnutls_calc_dh_key (session->key->client_Y, session->key->dh_secret, p);
80 if (session->key->KEY == NULL)
82 gnutls_assert ();
83 return GNUTLS_E_MEMORY_ERROR;
86 _gnutls_mpi_release (&session->key->client_Y);
87 _gnutls_mpi_release (&session->key->dh_secret);
90 if (psk_key == NULL)
92 ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key);
94 else /* In DHE_PSK the key is set differently */
96 gnutls_datum_t tmp_dh_key;
97 ret = _gnutls_mpi_dprint (session->key->KEY, &tmp_dh_key);
98 if (ret < 0)
100 gnutls_assert ();
101 return ret;
104 ret = _gnutls_set_psk_session_key (session, psk_key, &tmp_dh_key);
105 _gnutls_free_datum (&tmp_dh_key);
109 _gnutls_mpi_release (&session->key->KEY);
111 if (ret < 0)
113 return ret;
116 return 0;
119 int _gnutls_gen_dh_common_client_kx (gnutls_session_t session, gnutls_buffer_st* data)
121 return _gnutls_gen_dh_common_client_kx_int(session, data, NULL);
125 _gnutls_gen_dh_common_client_kx_int (gnutls_session_t session, gnutls_buffer_st* data, gnutls_datum_t* pskkey)
127 bigint_t x = NULL, X = NULL;
128 int ret;
130 X = gnutls_calc_dh_secret (&x, session->key->client_g,
131 session->key->client_p, 0);
132 if (X == NULL || x == NULL)
134 gnutls_assert ();
135 ret = GNUTLS_E_MEMORY_ERROR;
136 goto error;
139 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
141 ret = _gnutls_buffer_append_mpi( data, 16, X, 0);
142 if (ret < 0)
144 gnutls_assert();
145 goto error;
148 /* calculate the key after calculating the message */
149 session->key->KEY =
150 gnutls_calc_dh_key (session->key->client_Y, x, session->key->client_p);
152 if (session->key->KEY == NULL)
154 gnutls_assert ();
155 ret = GNUTLS_E_MEMORY_ERROR;
156 goto error;
159 /* THESE SHOULD BE DISCARDED */
160 _gnutls_mpi_release (&session->key->client_Y);
161 _gnutls_mpi_release (&session->key->client_p);
162 _gnutls_mpi_release (&session->key->client_g);
164 if (_gnutls_cipher_suite_get_kx_algo
165 (session->security_parameters.cipher_suite)
166 != GNUTLS_KX_DHE_PSK)
168 ret = _gnutls_mpi_dprint (session->key->KEY, &session->key->key);
170 else /* In DHE_PSK the key is set differently */
172 gnutls_datum_t tmp_dh_key;
174 ret = _gnutls_mpi_dprint (session->key->KEY, &tmp_dh_key);
175 if (ret < 0)
177 gnutls_assert ();
178 goto error;
181 ret = _gnutls_set_psk_session_key (session, pskkey, &tmp_dh_key);
182 _gnutls_free_datum (&tmp_dh_key);
185 _gnutls_mpi_release (&session->key->KEY);
187 if (ret < 0)
189 gnutls_assert ();
190 goto error;
193 ret = data->length;
195 error:
196 _gnutls_mpi_release (&x);
197 _gnutls_mpi_release (&X);
198 return ret;
201 /* Returns the bytes parsed */
203 _gnutls_proc_dh_common_server_kx (gnutls_session_t session,
204 uint8_t * data, size_t _data_size)
206 uint16_t n_Y, n_g, n_p;
207 size_t _n_Y, _n_g, _n_p;
208 uint8_t *data_p;
209 uint8_t *data_g;
210 uint8_t *data_Y;
211 int i, bits, ret;
212 ssize_t data_size = _data_size;
214 i = 0;
216 DECR_LEN (data_size, 2);
217 n_p = _gnutls_read_uint16 (&data[i]);
218 i += 2;
220 DECR_LEN (data_size, n_p);
221 data_p = &data[i];
222 i += n_p;
224 DECR_LEN (data_size, 2);
225 n_g = _gnutls_read_uint16 (&data[i]);
226 i += 2;
228 DECR_LEN (data_size, n_g);
229 data_g = &data[i];
230 i += n_g;
232 DECR_LEN (data_size, 2);
233 n_Y = _gnutls_read_uint16 (&data[i]);
234 i += 2;
236 DECR_LEN (data_size, n_Y);
237 data_Y = &data[i];
238 i += n_Y;
240 _n_Y = n_Y;
241 _n_g = n_g;
242 _n_p = n_p;
244 if (_gnutls_mpi_scan_nz (&session->key->client_Y, data_Y, _n_Y) != 0)
246 gnutls_assert ();
247 return GNUTLS_E_MPI_SCAN_FAILED;
250 if (_gnutls_mpi_scan_nz (&session->key->client_g, data_g, _n_g) != 0)
252 gnutls_assert ();
253 return GNUTLS_E_MPI_SCAN_FAILED;
255 if (_gnutls_mpi_scan_nz (&session->key->client_p, data_p, _n_p) != 0)
257 gnutls_assert ();
258 return GNUTLS_E_MPI_SCAN_FAILED;
261 bits = _gnutls_dh_get_allowed_prime_bits (session);
262 if (bits < 0)
264 gnutls_assert ();
265 return bits;
268 if (_gnutls_mpi_get_nbits (session->key->client_p) < (size_t) bits)
270 /* the prime used by the peer is not acceptable
272 gnutls_assert ();
273 return GNUTLS_E_DH_PRIME_UNACCEPTABLE;
276 _gnutls_dh_set_group (session, session->key->client_g,
277 session->key->client_p);
278 _gnutls_dh_set_peer_public (session, session->key->client_Y);
280 ret = n_Y + n_p + n_g + 6;
282 return ret;
286 _gnutls_dh_common_print_server_kx (gnutls_session_t session,
287 bigint_t g, bigint_t p, unsigned int q_bits,
288 gnutls_buffer_st* data)
290 bigint_t x, Y;
291 int ret;
293 /* Y=g^x mod p */
294 Y = gnutls_calc_dh_secret (&x, g, p, q_bits);
295 if (Y == NULL || x == NULL)
297 gnutls_assert ();
298 return GNUTLS_E_MEMORY_ERROR;
301 session->key->dh_secret = x;
302 _gnutls_dh_set_secret_bits (session, _gnutls_mpi_get_nbits (x));
304 ret = _gnutls_buffer_append_mpi(data, 16, p, 0);
305 if (ret < 0)
307 ret = gnutls_assert_val(ret);
308 goto cleanup;
311 ret = _gnutls_buffer_append_mpi(data, 16, g, 0);
312 if (ret < 0)
314 ret = gnutls_assert_val(ret);
315 goto cleanup;
318 ret = _gnutls_buffer_append_mpi(data, 16, Y, 0);
319 if (ret < 0)
321 ret = gnutls_assert_val(ret);
322 goto cleanup;
325 cleanup:
326 _gnutls_mpi_release (&Y);
328 return data->length;