2 * Copyright (C) 2001-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 #include <gnutls_int.h>
27 #include "gnutls_errors.h"
28 #include <auth/srp_passwd.h>
29 #include "gnutls_auth.h"
30 #include "gnutls_auth.h"
31 #include "gnutls_srp.h"
32 #include "gnutls_num.h"
34 #include <gnutls_str.h>
35 #include <gnutls_datum.h>
38 const mod_auth_st srp_auth_struct
= {
42 _gnutls_gen_srp_server_kx
,
43 _gnutls_gen_srp_client_kx
,
48 NULL
, /* certificate */
49 _gnutls_proc_srp_server_kx
,
50 _gnutls_proc_srp_client_kx
,
56 #define _b session->key->b
57 #define B session->key->B
58 #define _a session->key->a
59 #define A session->key->A
60 #define N session->key->client_p
61 #define G session->key->client_g
62 #define V session->key->x
63 #define S session->key->KEY
65 /* Checks if b%n==0 which is a fatal srp error.
66 * Returns a proper error code in that case, and 0 when
70 check_b_mod_n (bigint_t b
, bigint_t n
)
75 r
= _gnutls_mpi_mod (b
, n
);
80 return GNUTLS_E_MEMORY_ERROR
;
83 ret
= _gnutls_mpi_cmp_ui (r
, 0);
85 _gnutls_mpi_release (&r
);
90 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
96 /* Checks if a%n==0,+1,-1%n which is a fatal srp error.
97 * Returns a proper error code in that case, and 0 when
101 check_a_mod_n (bigint_t a
, bigint_t n
)
106 r
= _gnutls_mpi_mod (a
, n
);
110 return GNUTLS_E_MEMORY_ERROR
;
113 ret
= _gnutls_mpi_cmp_ui (r
, 0);
115 _gnutls_mpi_release (&r
);
120 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
127 /* Send the first key exchange message ( g, n, s) and append the verifier algorithm number
128 * Data is allocated by the caller, and should have data_size size.
131 _gnutls_gen_srp_server_kx (gnutls_session_t session
, gnutls_buffer_st
* data
)
135 SRP_PWD_ENTRY
*pwd_entry
;
136 srp_server_auth_info_t info
;
138 extension_priv_data_t epriv
;
141 ret
= _gnutls_ext_get_session_data (session
, GNUTLS_EXTENSION_SRP
, &epriv
);
142 if (ret
< 0) /* peer didn't send a username */
145 return GNUTLS_E_UNKNOWN_SRP_USERNAME
;
150 _gnutls_auth_info_set (session
, GNUTLS_CRD_SRP
,
151 sizeof (srp_server_auth_info_st
), 1)) < 0)
157 info
= _gnutls_get_auth_info (session
);
158 username
= info
->username
;
160 _gnutls_str_cpy (username
, MAX_USERNAME_SIZE
, priv
->username
);
162 ret
= _gnutls_srp_pwd_read_entry (session
, username
, &pwd_entry
);
170 /* copy from pwd_entry to local variables (actually in session) */
171 tmp_size
= pwd_entry
->g
.size
;
172 if (_gnutls_mpi_scan_nz (&G
, pwd_entry
->g
.data
, tmp_size
) < 0)
175 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
179 tmp_size
= pwd_entry
->n
.size
;
180 if (_gnutls_mpi_scan_nz (&N
, pwd_entry
->n
.data
, tmp_size
) < 0)
183 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
187 tmp_size
= pwd_entry
->v
.size
;
188 if (_gnutls_mpi_scan_nz (&V
, pwd_entry
->v
.data
, tmp_size
) < 0)
191 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
195 /* Calculate: B = (k*v + g^b) % N
197 B
= _gnutls_calc_srp_B (&_b
, G
, N
, V
);
201 ret
= GNUTLS_E_MEMORY_ERROR
;
207 ret
= _gnutls_buffer_append_data_prefix( data
, 16, pwd_entry
->n
.data
,
215 /* copy G (generator) to data
217 ret
= _gnutls_buffer_append_data_prefix( data
, 16, pwd_entry
->g
.data
,
227 ret
= _gnutls_buffer_append_data_prefix( data
, 8, pwd_entry
->salt
.data
,
228 pwd_entry
->salt
.size
);
238 ret
= _gnutls_buffer_append_mpi( data
, 16, B
, 0);
245 _gnutls_mpi_log ("SRP B: ", B
);
250 _gnutls_srp_entry_free (pwd_entry
);
254 /* return A = g^a % N */
256 _gnutls_gen_srp_client_kx (gnutls_session_t session
, gnutls_buffer_st
* data
)
259 char *username
, *password
;
260 gnutls_srp_client_credentials_t cred
;
261 extension_priv_data_t epriv
;
264 ret
= _gnutls_ext_get_session_data (session
, GNUTLS_EXTENSION_SRP
, &epriv
);
265 if (ret
< 0) /* peer didn't send a username */
268 return GNUTLS_E_UNKNOWN_SRP_USERNAME
;
272 cred
= (gnutls_srp_client_credentials_t
)
273 _gnutls_get_cred (session
->key
, GNUTLS_CRD_SRP
, NULL
);
278 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
281 if (priv
->username
== NULL
)
283 username
= cred
->username
;
284 password
= cred
->password
;
289 username
= priv
->username
;
290 password
= priv
->password
;
293 if (username
== NULL
|| password
== NULL
)
296 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
301 if (G
== NULL
|| N
== NULL
)
304 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
307 A
= _gnutls_calc_srp_A (&_a
, G
, N
);
311 return GNUTLS_E_MEMORY_ERROR
;
314 /* Rest of SRP calculations
318 session
->key
->u
= _gnutls_calc_srp_u (A
, B
, N
);
319 if (session
->key
->u
== NULL
)
322 return GNUTLS_E_MEMORY_ERROR
;
325 _gnutls_mpi_log ("SRP U: ", session
->key
->u
);
327 /* S = (B - g^x) ^ (a + u * x) % N */
328 S
= _gnutls_calc_srp_S2 (B
, G
, session
->key
->x
, _a
, session
->key
->u
, N
);
332 return GNUTLS_E_MEMORY_ERROR
;
335 _gnutls_mpi_log ("SRP B: ", B
);
337 _gnutls_mpi_release (&_b
);
338 _gnutls_mpi_release (&V
);
339 _gnutls_mpi_release (&session
->key
->u
);
340 _gnutls_mpi_release (&B
);
342 ret
= _gnutls_mpi_dprint (session
->key
->KEY
, &session
->key
->key
);
343 _gnutls_mpi_release (&S
);
351 ret
= _gnutls_buffer_append_mpi(data
, 16, A
, 0);
353 return gnutls_assert_val(ret
);
355 _gnutls_mpi_log ("SRP A: ", A
);
357 _gnutls_mpi_release (&A
);
363 /* just read A and put it to session */
365 _gnutls_proc_srp_client_kx (gnutls_session_t session
, uint8_t * data
,
369 ssize_t data_size
= _data_size
;
372 DECR_LEN (data_size
, 2);
373 _n_A
= _gnutls_read_uint16 (&data
[0]);
375 DECR_LEN (data_size
, _n_A
);
376 if (_gnutls_mpi_scan_nz (&A
, &data
[2], _n_A
) || A
== NULL
)
379 return GNUTLS_E_MPI_SCAN_FAILED
;
382 _gnutls_mpi_log ("SRP A: ", A
);
383 _gnutls_mpi_log ("SRP B: ", B
);
385 /* Checks if A % n == 0.
387 if ((ret
= check_a_mod_n (A
, N
)) < 0)
393 /* Start the SRP calculations.
396 session
->key
->u
= _gnutls_calc_srp_u (A
, B
, N
);
397 if (session
->key
->u
== NULL
)
400 return GNUTLS_E_MEMORY_ERROR
;
403 _gnutls_mpi_log ("SRP U: ", session
->key
->u
);
405 /* S = (A * v^u) ^ b % N
407 S
= _gnutls_calc_srp_S1 (A
, _b
, session
->key
->u
, V
, N
);
411 return GNUTLS_E_MEMORY_ERROR
;
414 _gnutls_mpi_log ("SRP S: ", S
);
416 _gnutls_mpi_release (&A
);
417 _gnutls_mpi_release (&_b
);
418 _gnutls_mpi_release (&V
);
419 _gnutls_mpi_release (&session
->key
->u
);
420 _gnutls_mpi_release (&B
);
422 ret
= _gnutls_mpi_dprint (session
->key
->KEY
, &session
->key
->key
);
423 _gnutls_mpi_release (&S
);
436 /* Static parameters according to draft-ietf-tls-srp-07
437 * Note that if more parameters are added check_g_n()
438 * and _gnutls_srp_entry_free() should be changed.
440 static const unsigned char srp_params_1024
[] = {
441 0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6,
442 0x9C, 0x33, 0xF8, 0x0A, 0xFA, 0x8F, 0xC5, 0xE8,
443 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF, 0x3C, 0x0B,
444 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76,
445 0xD6, 0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3,
446 0x38, 0x3B, 0x48, 0x13, 0xD6, 0x92, 0xC6, 0xE0,
447 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B, 0xE4,
448 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1,
449 0x5D, 0xC7, 0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6,
450 0xCE, 0x8E, 0xF4, 0xAD, 0x69, 0xB1, 0x5D, 0x49,
451 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
452 0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC,
453 0x68, 0xED, 0xBC, 0x3C, 0x05, 0x72, 0x6C, 0xC0,
454 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E, 0xAA, 0x9A,
455 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B,
456 0x9F, 0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
459 static const unsigned char srp_generator
= 0x02;
460 static const unsigned char srp3072_generator
= 0x05;
462 const gnutls_datum_t gnutls_srp_1024_group_prime
= {
463 (void *) srp_params_1024
, sizeof (srp_params_1024
)
466 const gnutls_datum_t gnutls_srp_1024_group_generator
= {
467 (void *) &srp_generator
, sizeof (srp_generator
)
470 static const unsigned char srp_params_1536
[] = {
471 0x9D, 0xEF, 0x3C, 0xAF, 0xB9, 0x39, 0x27, 0x7A, 0xB1,
472 0xF1, 0x2A, 0x86, 0x17, 0xA4, 0x7B, 0xBB, 0xDB, 0xA5,
473 0x1D, 0xF4, 0x99, 0xAC, 0x4C, 0x80, 0xBE, 0xEE, 0xA9,
474 0x61, 0x4B, 0x19, 0xCC, 0x4D, 0x5F, 0x4F, 0x5F, 0x55,
475 0x6E, 0x27, 0xCB, 0xDE, 0x51, 0xC6, 0xA9, 0x4B, 0xE4,
476 0x60, 0x7A, 0x29, 0x15, 0x58, 0x90, 0x3B, 0xA0, 0xD0,
477 0xF8, 0x43, 0x80, 0xB6, 0x55, 0xBB, 0x9A, 0x22, 0xE8,
478 0xDC, 0xDF, 0x02, 0x8A, 0x7C, 0xEC, 0x67, 0xF0, 0xD0,
479 0x81, 0x34, 0xB1, 0xC8, 0xB9, 0x79, 0x89, 0x14, 0x9B,
480 0x60, 0x9E, 0x0B, 0xE3, 0xBA, 0xB6, 0x3D, 0x47, 0x54,
481 0x83, 0x81, 0xDB, 0xC5, 0xB1, 0xFC, 0x76, 0x4E, 0x3F,
482 0x4B, 0x53, 0xDD, 0x9D, 0xA1, 0x15, 0x8B, 0xFD, 0x3E,
483 0x2B, 0x9C, 0x8C, 0xF5, 0x6E, 0xDF, 0x01, 0x95, 0x39,
484 0x34, 0x96, 0x27, 0xDB, 0x2F, 0xD5, 0x3D, 0x24, 0xB7,
485 0xC4, 0x86, 0x65, 0x77, 0x2E, 0x43, 0x7D, 0x6C, 0x7F,
486 0x8C, 0xE4, 0x42, 0x73, 0x4A, 0xF7, 0xCC, 0xB7, 0xAE,
487 0x83, 0x7C, 0x26, 0x4A, 0xE3, 0xA9, 0xBE, 0xB8, 0x7F,
488 0x8A, 0x2F, 0xE9, 0xB8, 0xB5, 0x29, 0x2E, 0x5A, 0x02,
489 0x1F, 0xFF, 0x5E, 0x91, 0x47, 0x9E, 0x8C, 0xE7, 0xA2,
490 0x8C, 0x24, 0x42, 0xC6, 0xF3, 0x15, 0x18, 0x0F, 0x93,
491 0x49, 0x9A, 0x23, 0x4D, 0xCF, 0x76, 0xE3, 0xFE, 0xD1,
495 const gnutls_datum_t gnutls_srp_1536_group_prime
= {
496 (void *) srp_params_1536
, sizeof (srp_params_1536
)
499 const gnutls_datum_t gnutls_srp_1536_group_generator
= {
500 (void *) &srp_generator
, sizeof (srp_generator
)
503 static const unsigned char srp_params_2048
[] = {
504 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, 0xF1,
505 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, 0xAF, 0x72,
506 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, 0xFC, 0x31, 0x92,
507 0x94, 0x3D, 0xB5, 0x60, 0x50, 0xA3, 0x73, 0x29, 0xCB,
508 0xB4, 0xA0, 0x99, 0xED, 0x81, 0x93, 0xE0, 0x75, 0x77,
509 0x67, 0xA1, 0x3D, 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03,
510 0x31, 0x0D, 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD,
511 0x50, 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
512 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, 0x66,
513 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, 0x29, 0x18,
514 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, 0x55, 0xF9, 0x79,
515 0x93, 0xEC, 0x97, 0x5E, 0xEA, 0xA8, 0x0D, 0x74, 0x0A,
516 0xDB, 0xF4, 0xFF, 0x74, 0x73, 0x59, 0xD0, 0x41, 0xD5,
517 0xC3, 0x3E, 0xA7, 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14,
518 0x77, 0x3B, 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80,
519 0x16, 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
520 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, 0x5B,
521 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, 0x54, 0x45,
522 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, 0x5E, 0xA7, 0x7A,
523 0x27, 0x75, 0xD2, 0xEC, 0xFA, 0x03, 0x2C, 0xFB, 0xDB,
524 0xF5, 0x2F, 0xB3, 0x78, 0x61, 0x60, 0x27, 0x90, 0x04,
525 0xE5, 0x7A, 0xE6, 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE,
526 0x53, 0x29, 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08,
527 0xD8, 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
528 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, 0x94,
529 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, 0x35, 0xDE,
530 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, 0x9B, 0x65, 0xE3,
531 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F,
532 0x9E, 0x4A, 0xFF, 0x73
535 const gnutls_datum_t gnutls_srp_2048_group_prime
= {
536 (void *) srp_params_2048
, sizeof (srp_params_2048
)
539 const gnutls_datum_t gnutls_srp_2048_group_generator
= {
540 (void *) &srp_generator
, sizeof (srp_generator
)
543 static const unsigned char srp_params_3072
[] = {
544 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9,
545 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6,
546 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E,
547 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
548 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E,
549 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A,
550 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14,
551 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
552 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4,
553 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF,
554 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38, 0x6B,
555 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
556 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC,
557 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63,
558 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3,
559 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
560 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C,
561 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5,
562 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35,
563 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
564 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E,
565 0x36, 0xCE, 0x3B, 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E,
566 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2,
567 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
568 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39,
569 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2,
570 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, 0x15, 0x72, 0x8E,
571 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
572 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF,
573 0x1C, 0xBA, 0x64, 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB,
574 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C,
575 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
576 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E,
577 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3,
578 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 0xF1, 0x2F, 0xFA,
579 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
580 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17,
581 0x7B, 0x20, 0x0C, 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61,
582 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46,
583 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
584 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B,
585 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF,
586 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
589 const gnutls_datum_t gnutls_srp_3072_group_generator
= {
590 (void *) &srp3072_generator
, sizeof (srp3072_generator
)
593 const gnutls_datum_t gnutls_srp_3072_group_prime
= {
594 (void *) srp_params_3072
, sizeof (srp_params_3072
)
597 static const unsigned char srp_params_4096
[] = {
598 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
599 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
600 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
601 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
602 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
603 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
604 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
605 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
606 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
607 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
608 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
609 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
610 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
611 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
612 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
613 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
614 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
615 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
616 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
617 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
618 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
619 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
620 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
621 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
622 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
623 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
624 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
625 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
626 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
627 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
628 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
629 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
630 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
631 0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
632 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
633 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
634 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
635 0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
636 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
637 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
638 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
639 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
640 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
643 const gnutls_datum_t gnutls_srp_4096_group_generator
= {
644 (void *) &srp3072_generator
, sizeof (srp3072_generator
)
647 const gnutls_datum_t gnutls_srp_4096_group_prime
= {
648 (void *) srp_params_4096
, sizeof (srp_params_4096
)
651 /* Check if G and N are parameters from the SRP draft.
654 check_g_n (const uint8_t * g
, size_t n_g
, const uint8_t * n
, size_t n_n
)
657 if ((n_n
== sizeof (srp_params_3072
) &&
658 memcmp (srp_params_3072
, n
, n_n
) == 0) ||
659 (n_n
== sizeof (srp_params_4096
) &&
660 memcmp (srp_params_4096
, n
, n_n
) == 0))
662 if (n_g
!= 1 || g
[0] != srp3072_generator
)
664 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
);
669 if (n_g
!= 1 || g
[0] != srp_generator
)
672 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
675 if (n_n
== sizeof (srp_params_1024
) &&
676 memcmp (srp_params_1024
, n
, n_n
) == 0)
681 if (n_n
== sizeof (srp_params_1536
) &&
682 memcmp (srp_params_1536
, n
, n_n
) == 0)
687 if (n_n
== sizeof (srp_params_2048
) &&
688 memcmp (srp_params_2048
, n
, n_n
) == 0)
694 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
697 /* Check if N is a prime and G a generator of the
698 * group. This is check only done if N is big enough.
699 * Otherwise only the included parameters must be used.
702 group_check_g_n (gnutls_session_t session
, bigint_t g
, bigint_t n
)
704 bigint_t q
= NULL
, two
= NULL
, w
= NULL
;
707 if (_gnutls_mpi_get_nbits (n
) < (session
->internals
.srp_prime_bits
708 ? session
->internals
.srp_prime_bits
712 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
715 /* N must be of the form N=2q+1
716 * where q is also a prime.
718 if (_gnutls_prime_check (n
) != 0)
720 _gnutls_mpi_log ("no prime N: ", n
);
722 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
725 two
= _gnutls_mpi_new (4);
729 return GNUTLS_E_MEMORY_ERROR
;
732 q
= _gnutls_mpi_alloc_like (n
);
736 ret
= GNUTLS_E_MEMORY_ERROR
;
742 _gnutls_mpi_sub_ui (q
, n
, 1);
744 /* q = q/2, remember that q is divisible by 2 (prime - 1)
746 _gnutls_mpi_set_ui (two
, 2);
747 _gnutls_mpi_div (q
, q
, two
);
749 if (_gnutls_prime_check (q
) != 0)
751 /* N was not on the form N=2q+1, where q = prime
753 _gnutls_mpi_log ("no prime Q: ", q
);
755 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
758 /* We also check whether g is a generator,
761 /* check if g < q < N
763 if (_gnutls_mpi_cmp (g
, q
) >= 0)
766 ret
= GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
770 w
= _gnutls_mpi_alloc_like (q
);
774 ret
= GNUTLS_E_MEMORY_ERROR
;
778 /* check if g^q mod N == N-1
781 _gnutls_mpi_powm (w
, g
, q
, n
);
785 _gnutls_mpi_add_ui (w
, w
, 1);
787 if (_gnutls_mpi_cmp (w
, n
) != 0)
790 ret
= GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
797 _gnutls_mpi_release (&q
);
798 _gnutls_mpi_release (&two
);
799 _gnutls_mpi_release (&w
);
805 /* receive the key exchange message ( n, g, s, B)
808 _gnutls_proc_srp_server_kx (gnutls_session_t session
, uint8_t * data
,
812 uint16_t n_g
, n_n
, n_b
;
813 size_t _n_g
, _n_n
, _n_b
;
814 const uint8_t *data_n
;
815 const uint8_t *data_g
;
816 const uint8_t *data_s
;
817 const uint8_t *data_b
;
819 uint8_t hd
[SRP_MAX_HASH_SIZE
];
820 char *username
, *password
;
821 ssize_t data_size
= _data_size
;
822 gnutls_srp_client_credentials_t cred
;
823 extension_priv_data_t epriv
;
826 ret
= _gnutls_ext_get_session_data (session
, GNUTLS_EXTENSION_SRP
, &epriv
);
830 return GNUTLS_E_UNKNOWN_SRP_USERNAME
;
834 cred
= (gnutls_srp_client_credentials_t
)
835 _gnutls_get_cred (session
->key
, GNUTLS_CRD_SRP
, NULL
);
840 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
843 if (priv
->username
== NULL
)
845 username
= cred
->username
;
846 password
= cred
->password
;
850 username
= priv
->username
;
851 password
= priv
->password
;
854 if (username
== NULL
|| password
== NULL
)
857 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
864 DECR_LEN (data_size
, 2);
865 n_n
= _gnutls_read_uint16 (&data
[i
]);
868 DECR_LEN (data_size
, n_n
);
874 DECR_LEN (data_size
, 2);
875 n_g
= _gnutls_read_uint16 (&data
[i
]);
878 DECR_LEN (data_size
, n_g
);
884 DECR_LEN (data_size
, 1);
888 DECR_LEN (data_size
, n_s
);
894 DECR_LEN (data_size
, 2);
895 n_b
= _gnutls_read_uint16 (&data
[i
]);
898 DECR_LEN (data_size
, n_b
);
906 if (_gnutls_mpi_scan_nz (&N
, data_n
, _n_n
) != 0)
909 return GNUTLS_E_MPI_SCAN_FAILED
;
912 if (_gnutls_mpi_scan_nz (&G
, data_g
, _n_g
) != 0)
915 return GNUTLS_E_MPI_SCAN_FAILED
;
918 if (_gnutls_mpi_scan_nz (&B
, data_b
, _n_b
) != 0)
921 return GNUTLS_E_MPI_SCAN_FAILED
;
925 /* Check if the g and n are from the SRP
926 * draft. Otherwise check if N is a prime and G
929 if ((ret
= check_g_n (data_g
, _n_g
, data_n
, _n_n
)) < 0)
931 _gnutls_audit_log (session
, "SRP group parameters are not in the white list. Checking validity.\n");
932 if ((ret
= group_check_g_n (session
, G
, N
)) < 0)
939 /* Checks if b % n == 0
941 if ((ret
= check_b_mod_n (B
, N
)) < 0)
948 /* generate x = SHA(s | SHA(U | ":" | p))
949 * (or the equivalent using bcrypt)
952 _gnutls_calc_srp_x (username
, password
, (uint8_t *) data_s
, n_s
,
959 if (_gnutls_mpi_scan_nz (&session
->key
->x
, hd
, _n_g
) != 0)
962 return GNUTLS_E_MPI_SCAN_FAILED
;
966 return i
; /* return the processed data
967 * needed in auth_srp_rsa.
971 #endif /* ENABLE_SRP */