Expand Up
@@ -69,6 +69,19 @@ static int g_initialized = 0;
static unsigned int g_rand_idx;
static unsigned char g_rand_buff[RAND_BUFF_MAX];
void *(*srp_alloc) (size_t ) = &malloc;
void *(*srp_realloc) (void *, size_t ) = &realloc;
void (*srp_free) (void *) = &free;
void srp_set_memory_functions (
void *(*new_srp_alloc) (size_t ),
void *(*new_srp_realloc) (void *, size_t ),
void (*new_srp_free) (void *)) {
srp_alloc = new_srp_alloc;
srp_realloc = new_srp_realloc;
srp_free = new_srp_free;
}
typedef struct
{
mpz_t N;
Expand Down
Expand Up
@@ -171,13 +184,13 @@ static void delete_ng(NGConstant *ng)
if (ng) {
mpz_clear (ng->N );
mpz_clear (ng->g );
free (ng);
srp_free (ng);
}
}
static NGConstant *new_ng ( SRP_NGType ng_type, const char *n_hex, const char *g_hex )
{
NGConstant *ng = (NGConstant *) malloc (sizeof (NGConstant));
NGConstant *ng = (NGConstant *) srp_alloc (sizeof (NGConstant));
mpz_init (ng->N );
mpz_init (ng->g );
Expand Down
Expand Up
@@ -367,18 +380,18 @@ static int H_nn(mpz_t result, SRP_HashAlgorithm alg, const mpz_t N, const mpz_t
size_t len_n1 = mpz_num_bytes (n1);
size_t len_n2 = mpz_num_bytes (n2);
size_t nbytes = len_N + len_N;
unsigned char *bin = (unsigned char *) malloc (nbytes);
unsigned char *bin = (unsigned char *) srp_alloc (nbytes);
if (!bin)
return 0 ;
if (len_n1 > len_N || len_n2 > len_N) {
free (bin);
srp_free (bin);
return 0 ;
}
memset (bin, 0 , nbytes);
mpz_to_bin (n1, bin + (len_N - len_n1));
mpz_to_bin (n2, bin + (len_N + len_N - len_n2));
hash ( alg, bin, nbytes, buff );
free (bin);
srp_free (bin);
mpz_from_bin (buff, hash_length (alg), result);
return 1 ;
}
Expand All
@@ -387,13 +400,13 @@ static int H_ns(mpz_t result, SRP_HashAlgorithm alg, const unsigned char *n, siz
{
unsigned char buff[SHA512_DIGEST_LENGTH];
size_t nbytes = len_n + len_bytes;
unsigned char *bin = (unsigned char *) malloc (nbytes);
unsigned char *bin = (unsigned char *) srp_alloc (nbytes);
if (!bin)
return 0 ;
memcpy (bin, n, len_n);
memcpy (bin + len_n, bytes, len_bytes);
hash (alg, bin, nbytes, buff);
free (bin);
srp_free (bin);
mpz_from_bin (buff, hash_length (alg), result);
return 1 ;
}
Expand All
@@ -418,23 +431,23 @@ static int calculate_x(mpz_t result, SRP_HashAlgorithm alg, const unsigned char
static void update_hash_n (SRP_HashAlgorithm alg, HashCTX *ctx, const mpz_t n)
{
size_t len = mpz_num_bytes (n);
unsigned char * n_bytes = (unsigned char *) malloc (len);
unsigned char * n_bytes = (unsigned char *) srp_alloc (len);
if (!n_bytes)
return ;
mpz_to_bin (n, n_bytes);
hash_update (alg, ctx, n_bytes, len);
free (n_bytes);
srp_free (n_bytes);
}
static void hash_num ( SRP_HashAlgorithm alg, const mpz_t n, unsigned char *dest )
{
int nbytes = mpz_num_bytes (n);
unsigned char *bin = (unsigned char *) malloc (nbytes);
unsigned char *bin = (unsigned char *) srp_alloc (nbytes);
if (!bin)
return ;
mpz_to_bin (n, bin);
hash (alg, bin, nbytes, dest);
free (bin);
srp_free (bin);
}
static void calculate_M (SRP_HashAlgorithm alg, NGConstant *ng, unsigned char *dest,
Expand Down
Expand Up
@@ -510,7 +523,7 @@ static void srp_pcgrandom_seed(srp_pcgrandom *r, unsigned long long int state,
}
static int fill_buff ()
static SRP_Result fill_buff ()
{
g_rand_idx = 0 ;
Expand All
@@ -526,7 +539,7 @@ static int fill_buff()
CryptGenRandom (wctx, sizeof (g_rand_buff), (BYTE*) g_rand_buff);
CryptReleaseContext (wctx, 0 );
return 1 ;
return SRP_OK ;
#else
fp = fopen (" /dev/urandom" , " r" );
Expand All
@@ -535,41 +548,48 @@ static int fill_buff()
fread (g_rand_buff, sizeof (g_rand_buff), 1 , fp);
fclose (fp);
} else {
srp_pcgrandom *r = (srp_pcgrandom *) malloc (sizeof (srp_pcgrandom));
srp_pcgrandom *r = (srp_pcgrandom *) srp_alloc (sizeof (srp_pcgrandom));
if (!r)
return SRP_ERR;
srp_pcgrandom_seed (r, time (NULL ) ^ clock (), 0xda3e39cb94b95bdbULL );
size_t i = 0 ;
for (i = 0 ; i < RAND_BUFF_MAX; i++) {
g_rand_buff[i] = srp_pcgrandom_next (r);
}
srp_free (r);
}
#endif
return 1 ;
return SRP_OK ;
}
static void mpz_fill_random (mpz_t num)
static SRP_Result mpz_fill_random (mpz_t num)
{
// was call: BN_rand(num, 256, -1, 0);
if (RAND_BUFF_MAX - g_rand_idx < 32 )
fill_buff ();
if (fill_buff () != SRP_OK)
return SRP_ERR;
mpz_from_bin ((const unsigned char *) (&g_rand_buff[g_rand_idx]), 32 , num);
g_rand_idx += 32 ;
return SRP_OK;
}
static void init_random ()
static SRP_Result init_random ()
{
if (g_initialized)
return ;
g_initialized = fill_buff ();
return SRP_OK;
SRP_Result ret = fill_buff ();
g_initialized = (ret == SRP_OK);
return ret;
}
#define srp_dbg_num (num, text ) ;
/* void srp_dbg_num(mpz_t num, char * prevtext)
{
int len_num = mpz_num_bytes(num);
char *bytes_num = (char*) malloc (len_num);
char *bytes_num = (char*) srp_alloc (len_num);
mpz_to_bin(num, (unsigned char *) bytes_num);
srp_dbg_data(bytes_num, len_num, prevtext);
free (bytes_num);
srp_free (bytes_num);
}*/
Expand All
@@ -579,53 +599,64 @@ static void init_random()
*
***********************************************************************************************************/
void srp_create_salted_verification_key ( SRP_HashAlgorithm alg,
SRP_Result srp_create_salted_verification_key ( SRP_HashAlgorithm alg,
SRP_NGType ng_type, const char *username_for_verifier,
const unsigned char *password, size_t len_password,
unsigned char **bytes_s, size_t *len_s,
unsigned char **bytes_v, size_t *len_v,
const char *n_hex, const char *g_hex )
{
SRP_Result ret = SRP_OK;
mpz_t v; mpz_init (v);
mpz_t x; mpz_init (x);
NGConstant *ng = new_ng (ng_type, n_hex, g_hex);
if (!ng)
goto cleanup_and_exit ;
if (!ng)
goto error_and_exit ;
init_random (); /* Only happens once */
if (init_random () != SRP_OK) /* Only happens once */
goto error_and_exit;
if (*bytes_s == NULL ) {
*len_s = 16 ;
if (RAND_BUFF_MAX - g_rand_idx < 16 )
fill_buff ();
*bytes_s = (unsigned char *)malloc (sizeof (char ) * 16 );
memcpy (*bytes_s, &g_rand_buff + g_rand_idx, sizeof (char ) * 16 );
g_rand_idx += 16 ;
size_t size_to_fill = 16 ;
*len_s = size_to_fill;
if (RAND_BUFF_MAX - g_rand_idx < size_to_fill)
if (fill_buff () != SRP_OK)
goto error_and_exit;
*bytes_s = (unsigned char *)srp_alloc (size_to_fill);
if (!*bytes_s)
goto error_and_exit;
memcpy (*bytes_s, &g_rand_buff + g_rand_idx, size_to_fill);
g_rand_idx += size_to_fill;
}
if (!calculate_x (x, alg, *bytes_s, *len_s, username_for_verifier,
password, len_password))
goto cleanup_and_exit ;
goto error_and_exit ;
srp_dbg_num (x, " Server calculated x: " );
mpz_powm (v, ng->g , x, ng->N );
*len_v = mpz_num_bytes (v);
*bytes_v = (unsigned char *)malloc (*len_v);
*bytes_v = (unsigned char *)srp_alloc (*len_v);
if (!bytes_v)
goto cleanup_and_exit ;
goto error_and_exit ;
mpz_to_bin (v, *bytes_v);
cleanup_and_exit:
delete_ng ( ng );
mpz_clear (v);
mpz_clear (x);
return ret;
error_and_exit:
ret = SRP_ERR;
goto cleanup_and_exit;
}
Expand Down
Expand Up
@@ -663,19 +694,23 @@ struct SRPVerifier *srp_verifier_new(SRP_HashAlgorithm alg,
if (!ng)
goto cleanup_and_exit;
ver = (struct SRPVerifier *) malloc ( sizeof (struct SRPVerifier ) );
ver = (struct SRPVerifier *) srp_alloc ( sizeof (struct SRPVerifier ) );
if (!ver)
goto cleanup_and_exit;
init_random (); /* Only happens once */
if (init_random () != SRP_OK) { /* Only happens once */
srp_free (ver);
ver = 0 ;
goto cleanup_and_exit;
}
ver->username = (char *) malloc (ulen);
ver->username = (char *) srp_alloc (ulen);
ver->hash_alg = alg;
ver->ng = ng;
if (!ver->username ) {
free (ver);
srp_free (ver);
ver = 0 ;
goto cleanup_and_exit;
}
Expand All
@@ -690,11 +725,15 @@ struct SRPVerifier *srp_verifier_new(SRP_HashAlgorithm alg,
if (bytes_b) {
mpz_from_bin (bytes_b, len_b, b);
} else {
mpz_fill_random (b);
if (mpz_fill_random (b) != SRP_OK) {
srp_free (ver);
ver = 0 ;
goto cleanup_and_exit;
}
}
if (!H_nn (k, alg, ng->N , ng->N , ng->g )) {
free (ver);
srp_free (ver);
ver = 0 ;
goto cleanup_and_exit;
}
Expand All
@@ -705,7 +744,7 @@ struct SRPVerifier *srp_verifier_new(SRP_HashAlgorithm alg,
mpz_addm (B, tmp1, tmp2, ng->N , tmp3);
if (!H_nn (u, alg, ng->N , A, B)) {
free (ver);
srp_free (ver);
ver = 0 ;
goto cleanup_and_exit;
}
Expand All
@@ -723,11 +762,11 @@ struct SRPVerifier *srp_verifier_new(SRP_HashAlgorithm alg,
calculate_H_AMK (alg, ver->H_AMK , A, ver->M , ver->session_key );
*len_B = mpz_num_bytes (B);
*bytes_B = (unsigned char *)malloc (*len_B);
*bytes_B = (unsigned char *)srp_alloc (*len_B);
if (!*bytes_B) {
free (ver->username );
free (ver);
srp_free (ver->username );
srp_free (ver);
ver = 0 ;
*len_B = 0 ;
goto cleanup_and_exit;
Expand All
@@ -737,7 +776,7 @@ struct SRPVerifier *srp_verifier_new(SRP_HashAlgorithm alg,
ver->bytes_B = *bytes_B;
} else {
free (ver);
srp_free (ver);
ver = 0 ;
}
Expand All
@@ -762,10 +801,10 @@ void srp_verifier_delete(struct SRPVerifier *ver)
{
if (ver) {
delete_ng (ver->ng );
free (ver->username );
free (ver->bytes_B );
srp_free (ver->username );
srp_free (ver->bytes_B );
memset (ver, 0 , sizeof (*ver));
free (ver);
srp_free (ver);
}
}
Expand Down
Expand Up
@@ -814,14 +853,15 @@ struct SRPUser *srp_user_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
const unsigned char *bytes_password, size_t len_password,
const char *n_hex, const char *g_hex)
{
struct SRPUser *usr = (struct SRPUser *) malloc (sizeof (struct SRPUser ));
struct SRPUser *usr = (struct SRPUser *) srp_alloc (sizeof (struct SRPUser ));
size_t ulen = strlen (username) + 1 ;
size_t uvlen = strlen (username_for_verifier) + 1 ;
if (!usr)
goto err_exit;
init_random (); /* Only happens once */
if (init_random () != SRP_OK) /* Only happens once */
goto err_exit;
usr->hash_alg = alg;
usr->ng = new_ng (ng_type, n_hex, g_hex);
Expand All
@@ -833,12 +873,12 @@ struct SRPUser *srp_user_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
if (!usr->ng )
goto err_exit;
usr->username = (char *)malloc (ulen);
usr->username_verifier = (char *)malloc (uvlen);
usr->password = (unsigned char *)malloc (len_password);
usr->username = (char *)srp_alloc (ulen);
usr->username_verifier = (char *)srp_alloc (uvlen);
usr->password = (unsigned char *)srp_alloc (len_password);
usr->password_len = len_password;
if (!usr->username || !usr->password )
if (!usr->username || !usr->password || !usr-> username_verifier )
goto err_exit;
memcpy (usr->username , username, ulen);
Expand All
@@ -858,15 +898,13 @@ struct SRPUser *srp_user_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
mpz_clear (usr->S );
if (usr->ng )
delete_ng (usr->ng );
if (usr->username )
free (usr->username );
if (usr->username_verifier )
free (usr->username_verifier );
srp_free (usr->username );
srp_free (usr->username_verifier );
if (usr->password ) {
memset (usr->password , 0 , usr->password_len );
free (usr->password );
srp_free (usr->password );
}
free (usr);
srp_free (usr);
}
return 0 ;
Expand All
@@ -885,15 +923,15 @@ void srp_user_delete(struct SRPUser *usr)
memset (usr->password , 0 , usr->password_len );
free (usr->username );
free (usr->username_verifier );
free (usr->password );
srp_free (usr->username );
srp_free (usr->username_verifier );
srp_free (usr->password );
if (usr->bytes_A )
free (usr->bytes_A );
srp_free (usr->bytes_A );
memset (usr, 0 , sizeof (*usr));
free (usr);
srp_free (usr);
}
}
Expand Down
Expand Up
@@ -926,33 +964,38 @@ size_t srp_user_get_session_key_length(struct SRPUser *usr)
/* Output: username, bytes_A, len_A */
void srp_user_start_authentication (struct SRPUser *usr, char **username,
SRP_Result srp_user_start_authentication (struct SRPUser *usr, char **username,
const unsigned char *bytes_a, size_t len_a,
unsigned char **bytes_A, size_t *len_A)
{
if (bytes_a) {
mpz_from_bin (bytes_a, len_a, usr->a );
} else {
mpz_fill_random (usr->a );
if (mpz_fill_random (usr->a ) != SRP_OK)
goto error_and_exit;
}
mpz_powm (usr->A , usr->ng ->g , usr->a , usr->ng ->N );
*len_A = mpz_num_bytes (usr->A );
*bytes_A = (unsigned char *)malloc (*len_A);
*bytes_A = (unsigned char *)srp_alloc (*len_A);
if (!*bytes_A) {
*len_A = 0 ;
*bytes_A = 0 ;
*username = 0 ;
return ;
}
if (!*bytes_A)
goto error_and_exit;
mpz_to_bin (usr->A , *bytes_A);
usr->bytes_A = *bytes_A;
if (username)
*username = usr->username ;
return SRP_OK;
error_and_exit:
*len_A = 0 ;
*bytes_A = 0 ;
*username = 0 ;
return SRP_ERR;
}
Expand Down