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 a%n==0,+1,-1%n which is a fatal srp error.
66 * Returns a proper error code in that case, and 0 when
70 check_param_mod_n (bigint_t a
, bigint_t n
, int is_a
)
75 r
= _gnutls_mpi_mod (a
, n
);
79 return GNUTLS_E_MEMORY_ERROR
;
82 ret
= _gnutls_mpi_cmp_ui (r
, 0);
83 if (ret
== 0) err
= 1;
87 ret
= _gnutls_mpi_cmp_ui (r
, 1);
88 if (ret
== 0) err
= 1;
90 _gnutls_mpi_add_ui(r
, r
, 1);
91 ret
= _gnutls_mpi_cmp (r
, n
);
92 if (ret
== 0) err
= 1;
95 _gnutls_mpi_release (&r
);
100 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
107 /* Send the first key exchange message ( g, n, s) and append the verifier algorithm number
108 * Data is allocated by the caller, and should have data_size size.
111 _gnutls_gen_srp_server_kx (gnutls_session_t session
, gnutls_buffer_st
* data
)
115 SRP_PWD_ENTRY
*pwd_entry
;
116 srp_server_auth_info_t info
;
118 extension_priv_data_t epriv
;
121 ret
= _gnutls_ext_get_session_data (session
, GNUTLS_EXTENSION_SRP
, &epriv
);
122 if (ret
< 0) /* peer didn't send a username */
125 return GNUTLS_E_UNKNOWN_SRP_USERNAME
;
130 _gnutls_auth_info_set (session
, GNUTLS_CRD_SRP
,
131 sizeof (srp_server_auth_info_st
), 1)) < 0)
137 info
= _gnutls_get_auth_info (session
);
138 username
= info
->username
;
140 _gnutls_str_cpy (username
, MAX_USERNAME_SIZE
, priv
->username
);
142 ret
= _gnutls_srp_pwd_read_entry (session
, username
, &pwd_entry
);
150 /* copy from pwd_entry to local variables (actually in session) */
151 tmp_size
= pwd_entry
->g
.size
;
152 if (_gnutls_mpi_scan_nz (&G
, pwd_entry
->g
.data
, tmp_size
) < 0)
155 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
159 tmp_size
= pwd_entry
->n
.size
;
160 if (_gnutls_mpi_scan_nz (&N
, pwd_entry
->n
.data
, tmp_size
) < 0)
163 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
167 tmp_size
= pwd_entry
->v
.size
;
168 if (_gnutls_mpi_scan_nz (&V
, pwd_entry
->v
.data
, tmp_size
) < 0)
171 ret
= GNUTLS_E_MPI_SCAN_FAILED
;
175 /* Calculate: B = (k*v + g^b) % N
177 B
= _gnutls_calc_srp_B (&_b
, G
, N
, V
);
181 ret
= GNUTLS_E_MEMORY_ERROR
;
187 ret
= _gnutls_buffer_append_data_prefix( data
, 16, pwd_entry
->n
.data
,
195 /* copy G (generator) to data
197 ret
= _gnutls_buffer_append_data_prefix( data
, 16, pwd_entry
->g
.data
,
207 ret
= _gnutls_buffer_append_data_prefix( data
, 8, pwd_entry
->salt
.data
,
208 pwd_entry
->salt
.size
);
218 ret
= _gnutls_buffer_append_mpi( data
, 16, B
, 0);
225 _gnutls_mpi_log ("SRP B: ", B
);
230 _gnutls_srp_entry_free (pwd_entry
);
234 /* return A = g^a % N */
236 _gnutls_gen_srp_client_kx (gnutls_session_t session
, gnutls_buffer_st
* data
)
239 char *username
, *password
;
240 gnutls_srp_client_credentials_t cred
;
241 extension_priv_data_t epriv
;
244 ret
= _gnutls_ext_get_session_data (session
, GNUTLS_EXTENSION_SRP
, &epriv
);
245 if (ret
< 0) /* peer didn't send a username */
248 return GNUTLS_E_UNKNOWN_SRP_USERNAME
;
252 cred
= (gnutls_srp_client_credentials_t
)
253 _gnutls_get_cred (session
->key
, GNUTLS_CRD_SRP
, NULL
);
258 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
261 if (priv
->username
== NULL
)
263 username
= cred
->username
;
264 password
= cred
->password
;
269 username
= priv
->username
;
270 password
= priv
->password
;
273 if (username
== NULL
|| password
== NULL
)
276 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
281 if (G
== NULL
|| N
== NULL
)
284 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
287 A
= _gnutls_calc_srp_A (&_a
, G
, N
);
291 return GNUTLS_E_MEMORY_ERROR
;
294 /* Rest of SRP calculations
298 session
->key
->u
= _gnutls_calc_srp_u (A
, B
, N
);
299 if (session
->key
->u
== NULL
)
302 return GNUTLS_E_MEMORY_ERROR
;
305 _gnutls_mpi_log ("SRP U: ", session
->key
->u
);
307 /* S = (B - g^x) ^ (a + u * x) % N */
308 S
= _gnutls_calc_srp_S2 (B
, G
, session
->key
->x
, _a
, session
->key
->u
, N
);
312 return GNUTLS_E_MEMORY_ERROR
;
315 _gnutls_mpi_log ("SRP B: ", B
);
317 _gnutls_mpi_release (&_b
);
318 _gnutls_mpi_release (&V
);
319 _gnutls_mpi_release (&session
->key
->u
);
320 _gnutls_mpi_release (&B
);
322 ret
= _gnutls_mpi_dprint (session
->key
->KEY
, &session
->key
->key
);
323 _gnutls_mpi_release (&S
);
331 ret
= _gnutls_buffer_append_mpi(data
, 16, A
, 0);
333 return gnutls_assert_val(ret
);
335 _gnutls_mpi_log ("SRP A: ", A
);
337 _gnutls_mpi_release (&A
);
343 /* just read A and put it to session */
345 _gnutls_proc_srp_client_kx (gnutls_session_t session
, uint8_t * data
,
349 ssize_t data_size
= _data_size
;
352 DECR_LEN (data_size
, 2);
353 _n_A
= _gnutls_read_uint16 (&data
[0]);
355 DECR_LEN (data_size
, _n_A
);
356 if (_gnutls_mpi_scan_nz (&A
, &data
[2], _n_A
) || A
== NULL
)
359 return GNUTLS_E_MPI_SCAN_FAILED
;
362 _gnutls_mpi_log ("SRP A: ", A
);
363 _gnutls_mpi_log ("SRP B: ", B
);
365 /* Checks if A % n == 0.
367 if ((ret
= check_param_mod_n (A
, N
, 1)) < 0)
373 /* Start the SRP calculations.
376 session
->key
->u
= _gnutls_calc_srp_u (A
, B
, N
);
377 if (session
->key
->u
== NULL
)
380 return GNUTLS_E_MEMORY_ERROR
;
383 _gnutls_mpi_log ("SRP U: ", session
->key
->u
);
385 /* S = (A * v^u) ^ b % N
387 S
= _gnutls_calc_srp_S1 (A
, _b
, session
->key
->u
, V
, N
);
391 return GNUTLS_E_MEMORY_ERROR
;
394 _gnutls_mpi_log ("SRP S: ", S
);
396 _gnutls_mpi_release (&A
);
397 _gnutls_mpi_release (&_b
);
398 _gnutls_mpi_release (&V
);
399 _gnutls_mpi_release (&session
->key
->u
);
400 _gnutls_mpi_release (&B
);
402 ret
= _gnutls_mpi_dprint (session
->key
->KEY
, &session
->key
->key
);
403 _gnutls_mpi_release (&S
);
416 /* Static parameters according to draft-ietf-tls-srp-07
417 * Note that if more parameters are added check_g_n()
418 * and _gnutls_srp_entry_free() should be changed.
420 static const unsigned char srp_params_1024
[] = {
421 0xEE, 0xAF, 0x0A, 0xB9, 0xAD, 0xB3, 0x8D, 0xD6,
422 0x9C, 0x33, 0xF8, 0x0A, 0xFA, 0x8F, 0xC5, 0xE8,
423 0x60, 0x72, 0x61, 0x87, 0x75, 0xFF, 0x3C, 0x0B,
424 0x9E, 0xA2, 0x31, 0x4C, 0x9C, 0x25, 0x65, 0x76,
425 0xD6, 0x74, 0xDF, 0x74, 0x96, 0xEA, 0x81, 0xD3,
426 0x38, 0x3B, 0x48, 0x13, 0xD6, 0x92, 0xC6, 0xE0,
427 0xE0, 0xD5, 0xD8, 0xE2, 0x50, 0xB9, 0x8B, 0xE4,
428 0x8E, 0x49, 0x5C, 0x1D, 0x60, 0x89, 0xDA, 0xD1,
429 0x5D, 0xC7, 0xD7, 0xB4, 0x61, 0x54, 0xD6, 0xB6,
430 0xCE, 0x8E, 0xF4, 0xAD, 0x69, 0xB1, 0x5D, 0x49,
431 0x82, 0x55, 0x9B, 0x29, 0x7B, 0xCF, 0x18, 0x85,
432 0xC5, 0x29, 0xF5, 0x66, 0x66, 0x0E, 0x57, 0xEC,
433 0x68, 0xED, 0xBC, 0x3C, 0x05, 0x72, 0x6C, 0xC0,
434 0x2F, 0xD4, 0xCB, 0xF4, 0x97, 0x6E, 0xAA, 0x9A,
435 0xFD, 0x51, 0x38, 0xFE, 0x83, 0x76, 0x43, 0x5B,
436 0x9F, 0xC6, 0x1D, 0x2F, 0xC0, 0xEB, 0x06, 0xE3
439 static const unsigned char srp_generator
= 0x02;
440 static const unsigned char srp3072_generator
= 0x05;
442 const gnutls_datum_t gnutls_srp_1024_group_prime
= {
443 (void *) srp_params_1024
, sizeof (srp_params_1024
)
446 const gnutls_datum_t gnutls_srp_1024_group_generator
= {
447 (void *) &srp_generator
, sizeof (srp_generator
)
450 static const unsigned char srp_params_1536
[] = {
451 0x9D, 0xEF, 0x3C, 0xAF, 0xB9, 0x39, 0x27, 0x7A, 0xB1,
452 0xF1, 0x2A, 0x86, 0x17, 0xA4, 0x7B, 0xBB, 0xDB, 0xA5,
453 0x1D, 0xF4, 0x99, 0xAC, 0x4C, 0x80, 0xBE, 0xEE, 0xA9,
454 0x61, 0x4B, 0x19, 0xCC, 0x4D, 0x5F, 0x4F, 0x5F, 0x55,
455 0x6E, 0x27, 0xCB, 0xDE, 0x51, 0xC6, 0xA9, 0x4B, 0xE4,
456 0x60, 0x7A, 0x29, 0x15, 0x58, 0x90, 0x3B, 0xA0, 0xD0,
457 0xF8, 0x43, 0x80, 0xB6, 0x55, 0xBB, 0x9A, 0x22, 0xE8,
458 0xDC, 0xDF, 0x02, 0x8A, 0x7C, 0xEC, 0x67, 0xF0, 0xD0,
459 0x81, 0x34, 0xB1, 0xC8, 0xB9, 0x79, 0x89, 0x14, 0x9B,
460 0x60, 0x9E, 0x0B, 0xE3, 0xBA, 0xB6, 0x3D, 0x47, 0x54,
461 0x83, 0x81, 0xDB, 0xC5, 0xB1, 0xFC, 0x76, 0x4E, 0x3F,
462 0x4B, 0x53, 0xDD, 0x9D, 0xA1, 0x15, 0x8B, 0xFD, 0x3E,
463 0x2B, 0x9C, 0x8C, 0xF5, 0x6E, 0xDF, 0x01, 0x95, 0x39,
464 0x34, 0x96, 0x27, 0xDB, 0x2F, 0xD5, 0x3D, 0x24, 0xB7,
465 0xC4, 0x86, 0x65, 0x77, 0x2E, 0x43, 0x7D, 0x6C, 0x7F,
466 0x8C, 0xE4, 0x42, 0x73, 0x4A, 0xF7, 0xCC, 0xB7, 0xAE,
467 0x83, 0x7C, 0x26, 0x4A, 0xE3, 0xA9, 0xBE, 0xB8, 0x7F,
468 0x8A, 0x2F, 0xE9, 0xB8, 0xB5, 0x29, 0x2E, 0x5A, 0x02,
469 0x1F, 0xFF, 0x5E, 0x91, 0x47, 0x9E, 0x8C, 0xE7, 0xA2,
470 0x8C, 0x24, 0x42, 0xC6, 0xF3, 0x15, 0x18, 0x0F, 0x93,
471 0x49, 0x9A, 0x23, 0x4D, 0xCF, 0x76, 0xE3, 0xFE, 0xD1,
475 const gnutls_datum_t gnutls_srp_1536_group_prime
= {
476 (void *) srp_params_1536
, sizeof (srp_params_1536
)
479 const gnutls_datum_t gnutls_srp_1536_group_generator
= {
480 (void *) &srp_generator
, sizeof (srp_generator
)
483 static const unsigned char srp_params_2048
[] = {
484 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, 0xF1,
485 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, 0xAF, 0x72,
486 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, 0xFC, 0x31, 0x92,
487 0x94, 0x3D, 0xB5, 0x60, 0x50, 0xA3, 0x73, 0x29, 0xCB,
488 0xB4, 0xA0, 0x99, 0xED, 0x81, 0x93, 0xE0, 0x75, 0x77,
489 0x67, 0xA1, 0x3D, 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03,
490 0x31, 0x0D, 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD,
491 0x50, 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
492 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, 0x66,
493 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, 0x29, 0x18,
494 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, 0x55, 0xF9, 0x79,
495 0x93, 0xEC, 0x97, 0x5E, 0xEA, 0xA8, 0x0D, 0x74, 0x0A,
496 0xDB, 0xF4, 0xFF, 0x74, 0x73, 0x59, 0xD0, 0x41, 0xD5,
497 0xC3, 0x3E, 0xA7, 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14,
498 0x77, 0x3B, 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80,
499 0x16, 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
500 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, 0x5B,
501 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, 0x54, 0x45,
502 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, 0x5E, 0xA7, 0x7A,
503 0x27, 0x75, 0xD2, 0xEC, 0xFA, 0x03, 0x2C, 0xFB, 0xDB,
504 0xF5, 0x2F, 0xB3, 0x78, 0x61, 0x60, 0x27, 0x90, 0x04,
505 0xE5, 0x7A, 0xE6, 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE,
506 0x53, 0x29, 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08,
507 0xD8, 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
508 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, 0x94,
509 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, 0x35, 0xDE,
510 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, 0x9B, 0x65, 0xE3,
511 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F,
512 0x9E, 0x4A, 0xFF, 0x73
515 const gnutls_datum_t gnutls_srp_2048_group_prime
= {
516 (void *) srp_params_2048
, sizeof (srp_params_2048
)
519 const gnutls_datum_t gnutls_srp_2048_group_generator
= {
520 (void *) &srp_generator
, sizeof (srp_generator
)
523 static const unsigned char srp_params_3072
[] = {
524 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9,
525 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6,
526 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E,
527 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
528 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E,
529 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A,
530 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14,
531 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
532 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4,
533 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF,
534 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38, 0x6B,
535 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
536 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC,
537 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63,
538 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3,
539 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
540 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C,
541 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5,
542 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35,
543 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
544 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E,
545 0x36, 0xCE, 0x3B, 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E,
546 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2,
547 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
548 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39,
549 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2,
550 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, 0x15, 0x72, 0x8E,
551 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
552 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF,
553 0x1C, 0xBA, 0x64, 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB,
554 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C,
555 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
556 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E,
557 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3,
558 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, 0xF1, 0x2F, 0xFA,
559 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
560 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17,
561 0x7B, 0x20, 0x0C, 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61,
562 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46,
563 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
564 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B,
565 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF,
566 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
569 const gnutls_datum_t gnutls_srp_3072_group_generator
= {
570 (void *) &srp3072_generator
, sizeof (srp3072_generator
)
573 const gnutls_datum_t gnutls_srp_3072_group_prime
= {
574 (void *) srp_params_3072
, sizeof (srp_params_3072
)
577 static const unsigned char srp_params_4096
[] = {
578 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
579 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
580 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
581 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
582 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
583 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
584 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
585 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
586 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
587 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
588 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
589 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
590 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
591 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
592 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
593 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
594 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
595 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
596 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
597 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
598 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
599 0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
600 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
601 0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
602 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
603 0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
604 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
605 0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
606 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
607 0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
608 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
609 0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
610 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
611 0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
612 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
613 0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
614 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
615 0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
616 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
617 0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
618 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
619 0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
620 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
623 const gnutls_datum_t gnutls_srp_4096_group_generator
= {
624 (void *) &srp3072_generator
, sizeof (srp3072_generator
)
627 const gnutls_datum_t gnutls_srp_4096_group_prime
= {
628 (void *) srp_params_4096
, sizeof (srp_params_4096
)
631 /* Check if G and N are parameters from the SRP draft.
634 check_g_n (const uint8_t * g
, size_t n_g
, const uint8_t * n
, size_t n_n
)
637 if ((n_n
== sizeof (srp_params_3072
) &&
638 memcmp (srp_params_3072
, n
, n_n
) == 0) ||
639 (n_n
== sizeof (srp_params_4096
) &&
640 memcmp (srp_params_4096
, n
, n_n
) == 0))
642 if (n_g
!= 1 || g
[0] != srp3072_generator
)
644 return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
);
649 if (n_g
!= 1 || g
[0] != srp_generator
)
652 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
655 if (n_n
== sizeof (srp_params_1024
) &&
656 memcmp (srp_params_1024
, n
, n_n
) == 0)
661 if (n_n
== sizeof (srp_params_1536
) &&
662 memcmp (srp_params_1536
, n
, n_n
) == 0)
667 if (n_n
== sizeof (srp_params_2048
) &&
668 memcmp (srp_params_2048
, n
, n_n
) == 0)
674 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
677 /* Check if N is a prime and G a generator of the
678 * group. This check is only done if N is big enough.
679 * Otherwise only the included parameters must be used.
682 group_check_g_n (gnutls_session_t session
, bigint_t g
, bigint_t n
)
684 bigint_t q
= NULL
, two
= NULL
, w
= NULL
;
687 if (_gnutls_mpi_get_nbits (n
) < (session
->internals
.srp_prime_bits
688 ? session
->internals
.srp_prime_bits
692 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
695 /* N must be of the form N=2q+1
696 * where q is also a prime.
698 if (_gnutls_prime_check (n
) != 0)
700 _gnutls_mpi_log ("no prime N: ", n
);
702 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
705 two
= _gnutls_mpi_new (4);
709 return GNUTLS_E_MEMORY_ERROR
;
712 q
= _gnutls_mpi_alloc_like (n
);
716 ret
= GNUTLS_E_MEMORY_ERROR
;
722 _gnutls_mpi_sub_ui (q
, n
, 1);
724 /* q = q/2, remember that q is divisible by 2 (prime - 1)
726 _gnutls_mpi_set_ui (two
, 2);
727 _gnutls_mpi_div (q
, q
, two
);
729 if (_gnutls_prime_check (q
) != 0)
731 /* N was not on the form N=2q+1, where q = prime
733 _gnutls_mpi_log ("no prime Q: ", q
);
735 return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
738 /* We also check whether g is a generator,
741 /* check if g < q < N
743 if (_gnutls_mpi_cmp (g
, q
) >= 0)
746 ret
= GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
750 w
= _gnutls_mpi_alloc_like (q
);
754 ret
= GNUTLS_E_MEMORY_ERROR
;
758 /* check if g^q mod N == N-1
761 _gnutls_mpi_powm (w
, g
, q
, n
);
765 _gnutls_mpi_add_ui (w
, w
, 1);
767 if (_gnutls_mpi_cmp (w
, n
) != 0)
770 ret
= GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER
;
777 _gnutls_mpi_release (&q
);
778 _gnutls_mpi_release (&two
);
779 _gnutls_mpi_release (&w
);
785 /* receive the key exchange message ( n, g, s, B)
788 _gnutls_proc_srp_server_kx (gnutls_session_t session
, uint8_t * data
,
792 uint16_t n_g
, n_n
, n_b
;
793 size_t _n_g
, _n_n
, _n_b
;
794 const uint8_t *data_n
;
795 const uint8_t *data_g
;
796 const uint8_t *data_s
;
797 const uint8_t *data_b
;
799 uint8_t hd
[SRP_MAX_HASH_SIZE
];
800 char *username
, *password
;
801 ssize_t data_size
= _data_size
;
802 gnutls_srp_client_credentials_t cred
;
803 extension_priv_data_t epriv
;
806 ret
= _gnutls_ext_get_session_data (session
, GNUTLS_EXTENSION_SRP
, &epriv
);
810 return GNUTLS_E_UNKNOWN_SRP_USERNAME
;
814 cred
= (gnutls_srp_client_credentials_t
)
815 _gnutls_get_cred (session
->key
, GNUTLS_CRD_SRP
, NULL
);
820 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
823 if (priv
->username
== NULL
)
825 username
= cred
->username
;
826 password
= cred
->password
;
830 username
= priv
->username
;
831 password
= priv
->password
;
834 if (username
== NULL
|| password
== NULL
)
837 return GNUTLS_E_INSUFFICIENT_CREDENTIALS
;
844 DECR_LEN (data_size
, 2);
845 n_n
= _gnutls_read_uint16 (&data
[i
]);
848 DECR_LEN (data_size
, n_n
);
854 DECR_LEN (data_size
, 2);
855 n_g
= _gnutls_read_uint16 (&data
[i
]);
858 DECR_LEN (data_size
, n_g
);
864 DECR_LEN (data_size
, 1);
868 DECR_LEN (data_size
, n_s
);
874 DECR_LEN (data_size
, 2);
875 n_b
= _gnutls_read_uint16 (&data
[i
]);
878 DECR_LEN (data_size
, n_b
);
886 if (_gnutls_mpi_scan_nz (&N
, data_n
, _n_n
) != 0)
889 return GNUTLS_E_MPI_SCAN_FAILED
;
892 if (_gnutls_mpi_scan_nz (&G
, data_g
, _n_g
) != 0)
895 return GNUTLS_E_MPI_SCAN_FAILED
;
898 if (_gnutls_mpi_scan_nz (&B
, data_b
, _n_b
) != 0)
901 return GNUTLS_E_MPI_SCAN_FAILED
;
905 /* Check if the g and n are from the SRP
906 * draft. Otherwise check if N is a prime and G
909 if ((ret
= check_g_n (data_g
, _n_g
, data_n
, _n_n
)) < 0)
911 _gnutls_audit_log (session
, "SRP group parameters are not in the white list. Checking validity.\n");
912 if ((ret
= group_check_g_n (session
, G
, N
)) < 0)
919 /* Checks if b % n == 0
921 if ((ret
= check_param_mod_n (B
, N
, 0)) < 0)
928 /* generate x = SHA(s | SHA(U | ":" | p))
929 * (or the equivalent using bcrypt)
932 _gnutls_calc_srp_x (username
, password
, (uint8_t *) data_s
, n_s
,
939 if (_gnutls_mpi_scan_nz (&session
->key
->x
, hd
, _n_g
) != 0)
942 return GNUTLS_E_MPI_SCAN_FAILED
;
946 return i
; /* return the processed data
947 * needed in auth_srp_rsa.
951 #endif /* ENABLE_SRP */