Exemple #1
0
struct SRPUser * srp_user_new( SRP_HashAlgorithm alg, SRP_NGType ng_type, const char * username, 
                               const unsigned char * bytes_password, int len_password,
                               const char * n_hex, const char * g_hex )
{
    struct SRPUser  *usr  = (struct SRPUser *) malloc( sizeof(struct SRPUser) );
    int              ulen = (int)strlen(username) + 1;

    init_random(); /* Only happens once */
    
    usr->hash_alg = alg;
    usr->ng       = new_ng( ng_type, n_hex, g_hex );
    
    usr->a = BN_new();
    usr->A = BN_new();
    usr->S = BN_new();
    
    usr->username     = (const char *) malloc(ulen);
    usr->password     = (const unsigned char *) malloc(len_password);
    usr->password_len = len_password;
    usr->authenticated = 0;
    memcpy((char *)usr->username, username,       ulen);
    memcpy((char *)usr->password, bytes_password, len_password);
    
    usr->bytes_A = 0;
    
    return usr;
}
Exemple #2
0
struct SRPUser *srp_user_new(SRP_HashAlgorithm alg, SRP_NGType ng_type,
	const char *username, const char *username_for_verifier,
	const unsigned char *bytes_password, size_t len_password, const char *n_hex,
	const char *g_hex)
{
	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;

	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);

	mpz_init(usr->a);
	mpz_init(usr->A);
	mpz_init(usr->S);

	if (!usr->ng) goto err_exit;

	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 || !usr->username_verifier) goto err_exit;

	memcpy(usr->username, username, ulen);
	memcpy(usr->username_verifier, username_for_verifier, uvlen);
	memcpy(usr->password, bytes_password, len_password);

	usr->authenticated = 0;

	usr->bytes_A = 0;

	return usr;

err_exit:
	if (usr) {
		mpz_clear(usr->a);
		mpz_clear(usr->A);
		mpz_clear(usr->S);
		if (usr->ng) delete_ng(usr->ng);
		srp_free(usr->username);
		srp_free(usr->username_verifier);
		if (usr->password) {
			memset(usr->password, 0, usr->password_len);
			srp_free(usr->password);
		}
		srp_free(usr);
	}

	return 0;
}
Exemple #3
0
struct SRPUser * srp_user_new( SRP_HashAlgorithm alg, SRP_NGType ng_type, const char * username, 
                              const char * bytes_password, int len_password,
                               const char * n_hex, const char * g_hex )
{
    struct SRPUser  *usr  = (struct SRPUser *) malloc( sizeof(struct SRPUser) );
    int              ulen = strlen(username) + 1;

    if (!usr)
       goto err_exit;

    init_random(); /* Only happens once */
    
    usr->hash_alg = alg;
    usr->ng       = new_ng( ng_type, n_hex, g_hex );
    
    usr->a = BN_new();
    usr->A = BN_new();
    usr->S = BN_new();

    if (!usr->ng || !usr->a || !usr->A || !usr->S)
       goto err_exit;
    
    usr->username     = (const char *) malloc(ulen);
    usr->password     = (const unsigned char *) malloc(len_password);
    usr->password_len = len_password;

    if (!usr->username || !usr->password)
       goto err_exit;
    
    memcpy((char *)usr->username, username,       ulen);
    memcpy((char *)usr->password, bytes_password, len_password);

    usr->authenticated = 0;
    
    usr->bytes_A = 0;
    
    return usr;

 err_exit:
    if (usr)
    {
       BN_free(usr->a);
       BN_free(usr->A);
       BN_free(usr->S);
       if (usr->username)
          free((void*)usr->username);
       if (usr->password)
       {
          memset((void*)usr->password, 0, usr->password_len);
          free((void*)usr->password);
       }
       free(usr);
    }
    
    return 0;
}
Exemple #4
0
// clang-format off
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);
	// clang-format on

	NGConstant *ng = new_ng(ng_type, n_hex, g_hex);

	if (!ng) goto error_and_exit;

	if (init_random() != SRP_OK) /* Only happens once */
		goto error_and_exit;

	if (*bytes_s == NULL) {
		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 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 *)srp_alloc(*len_v);

	if (!*bytes_v) 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;
}
Exemple #5
0
SRPUser * srp_user_new_with_a(SRP_HashAlgorithm alg,
                              SRP_NGType ng_type,
                              const char *username,
                              const char *password,
                              const char *n_hex,
                              const char *g_hex,
                              BIGNUM *a) {
    SRPUser *usr = (SRPUser *)malloc(sizeof(SRPUser));
    int username_length = strlen(username) + 1;
    int password_length = strlen(password) + 1;
    
    if (!usr) goto err_exit;

    init_random();
    
    usr->hash_alg = alg;
    usr->ng = new_ng(ng_type, n_hex, g_hex);
    usr->a = a;
    usr->A = BN_new();
    usr->S = BN_new();
    usr->Astr = 0;
    usr->HAMK = 0;
    
    if (!usr->ng || !usr->a || !usr->A || !usr->S) goto err_exit;
    
    usr->username = (const char *) malloc(username_length);
    usr->password = (const char *) malloc(password_length);
    usr->password_len = password_length;
    
    if (!usr->username || !usr->password) goto err_exit;
    
    memcpy((char *)usr->username, username, username_length);
    memcpy((char *)usr->password, password, password_length);
    
    usr->authenticated = 0;
    usr->bytes_A = 0;
    
    return usr;
    
err_exit:
    if (usr) {
        BN_free(usr->a);
        BN_free(usr->A);
        BN_free(usr->S);
        if (usr->username) free((void*)usr->username);
        if (usr->password) {
            memset((void*)usr->password, 0, usr->password_len);
            free((void*)usr->password);
        }
        free(usr);
    }
    return 0;
}
Exemple #6
0
void srp_create_salted_verification_key( SRP_HashAlgorithm alg, 
                                         SRP_NGType ng_type, const char * username,
                                         const unsigned char * password, int len_password,
                                         const unsigned char ** bytes_s, int * len_s, 
                                         const unsigned char ** bytes_v, int * len_v,
                                         const char * n_hex, const char * g_hex )
{
    BIGNUM     * s   = BN_new();
    BIGNUM     * v   = BN_new();
    BIGNUM     * x   = 0;
    BN_CTX     * ctx = BN_CTX_new();
    NGConstant * ng  = new_ng( ng_type, n_hex, g_hex );

    if( !s || !v || !ctx || !ng )
       goto cleanup_and_exit;

    init_random(); /* Only happens once */
    
    BN_rand(s, 32, -1, 0);
    
    x = calculate_x( alg, s, username, password, len_password );

    if( !x )
       goto cleanup_and_exit;

    BN_mod_exp(v, ng->g, x, ng->N, ctx);
        
    *len_s   = BN_num_bytes(s);
    *len_v   = BN_num_bytes(v);
    
    *bytes_s = (const unsigned char *) malloc( *len_s );
    *bytes_v = (const unsigned char *) malloc( *len_v );

    if (!bytes_s || !bytes_v)
       goto cleanup_and_exit;
    
    BN_bn2bin(s, (unsigned char *) *bytes_s);
    BN_bn2bin(v, (unsigned char *) *bytes_v);
    
 cleanup_and_exit:
    delete_ng( ng );
    BN_free(s);
    BN_free(v);
    BN_free(x);
    BN_CTX_free(ctx);
}
Exemple #7
0
/* Out: bytes_B, len_B.
 * 
 * On failure, bytes_B will be set to NULL and len_B will be set to 0
 */
struct SRPVerifier *  srp_verifier_new( SRP_HashAlgorithm alg, SRP_NGType ng_type, const char * username,
                                        const unsigned char * bytes_s, int len_s, 
                                        const unsigned char * bytes_v, int len_v,
                                        const unsigned char * bytes_A, int len_A,
                                        const unsigned char ** bytes_B, int * len_B,
                                        const char * n_hex, const char * g_hex )
{
    BIGNUM             *s    = BN_bin2bn(bytes_s, len_s, NULL);
    BIGNUM             *v    = BN_bin2bn(bytes_v, len_v, NULL);
    BIGNUM             *A    = BN_bin2bn(bytes_A, len_A, NULL);
    BIGNUM             *u    = 0;
    BIGNUM             *B    = BN_new();
    BIGNUM             *S    = BN_new();
    BIGNUM             *b    = BN_new();
    BIGNUM             *k    = 0;
    BIGNUM             *tmp1 = BN_new();
    BIGNUM             *tmp2 = BN_new();
    BN_CTX             *ctx  = BN_CTX_new();
    int                 ulen = strlen(username) + 1;
    NGConstant         *ng   = new_ng( ng_type, n_hex, g_hex );
    struct SRPVerifier *ver  = 0;

    *len_B   = 0;
    *bytes_B = 0;
    
    if( !s || !v || !A || !B || !S || !b || !tmp1 || !tmp2 || !ctx || !ng )
       goto cleanup_and_exit;
    
    ver = (struct SRPVerifier *) malloc( sizeof(struct SRPVerifier) );

    if (!ver)
       goto cleanup_and_exit;

    init_random(); /* Only happens once */
    
    ver->username = (char *) malloc( ulen );
    ver->hash_alg = alg;
    ver->ng       = ng;

    if (!ver->username)
    {
       free(ver);
       ver = 0;
       goto cleanup_and_exit;
    }
    
    memcpy( (char*)ver->username, username, ulen );
    
    ver->authenticated = 0;
        
    /* SRP-6a safety check */
    BN_mod(tmp1, A, ng->N, ctx);
    if ( !BN_is_zero(tmp1) )
    {
       BN_rand(b, 256, -1, 0);
       
       k = H_nn(alg, ng->N, ng->g);
       
       /* B = kv + g^b */
       BN_mul(tmp1, k, v, ctx);
       BN_mod_exp(tmp2, ng->g, b, ng->N, ctx);
       BN_add(B, tmp1, tmp2);
       
       u = H_nn(alg, A, B);
       
       /* S = (A *(v^u)) ^ b */
       BN_mod_exp(tmp1, v, u, ng->N, ctx);
       BN_mul(tmp2, A, tmp1, ctx);
       BN_mod_exp(S, tmp2, b, ng->N, ctx);
       
       hash_num(alg, S, ver->session_key);
       
       calculate_M( alg, ng, ver->M, username, s, A, B, ver->session_key );
       calculate_H_AMK( alg, ver->H_AMK, A, ver->M, ver->session_key );
       
       *len_B   = BN_num_bytes(B);
       *bytes_B = malloc( *len_B );
       
       if( !*bytes_B )
       {
          free( (void*) ver->username );
          free( ver );
          ver = 0;
          *len_B = 0;
          goto cleanup_and_exit;
       }
       
       BN_bn2bin( B, (unsigned char *) *bytes_B );
          
       ver->bytes_B = *bytes_B;
    }
    
 cleanup_and_exit:
    BN_free(s);
    BN_free(v);
    BN_free(A);
    if (u) BN_free(u);
    if (k) BN_free(k);
    BN_free(B);
    BN_free(S);
    BN_free(b);
    BN_free(tmp1);
    BN_free(tmp2);
    BN_CTX_free(ctx);
    
    return ver;
}
Exemple #8
0
/* Out: bytes_B, len_B.
 *
 * On failure, bytes_B will be set to NULL and len_B will be set to 0
 */
struct SRPVerifier *srp_verifier_new(SRP_HashAlgorithm alg,
	SRP_NGType ng_type, const char *username,
	const unsigned char *bytes_s, size_t len_s,
	const unsigned char *bytes_v, size_t len_v,
	const unsigned char *bytes_A, size_t len_A,
	const unsigned char *bytes_b, size_t len_b,
	unsigned char **bytes_B, size_t *len_B,
	const char *n_hex, const char *g_hex )
{
	mpz_t v; mpz_init(v); mpz_from_bin(bytes_v, len_v, v);
	mpz_t A; mpz_init(A); mpz_from_bin(bytes_A, len_A, A);
	mpz_t u; mpz_init(u);
	mpz_t B; mpz_init(B);
	mpz_t S; mpz_init(S);
	mpz_t b; mpz_init(b);
	mpz_t k; mpz_init(k);
	mpz_t tmp1; mpz_init(tmp1);
	mpz_t tmp2; mpz_init(tmp2);
	mpz_t tmp3; mpz_init(tmp3);
	// clang-format on
	size_t ulen = strlen(username) + 1;
	NGConstant *ng = new_ng(ng_type, n_hex, g_hex);
	struct SRPVerifier *ver = 0;

	*len_B = 0;
	*bytes_B = 0;

	if (!ng) goto cleanup_and_exit;

	ver = (struct SRPVerifier *)srp_alloc(sizeof(struct SRPVerifier));

	if (!ver) goto cleanup_and_exit;

	if (init_random() != SRP_OK) { /* Only happens once */
		srp_free(ver);
		ver = 0;
		goto cleanup_and_exit;
	}

	ver->username = (char *)srp_alloc(ulen);
	ver->hash_alg = alg;
	ver->ng = ng;

	if (!ver->username) {
		srp_free(ver);
		ver = 0;
		goto cleanup_and_exit;
	}

	memcpy((char *)ver->username, username, ulen);

	ver->authenticated = 0;

	/* SRP-6a safety check */
	mpz_mod(tmp1, A, ng->N);
	if (mpz_sgn(tmp1) != 0) {
		if (bytes_b) {
			mpz_from_bin(bytes_b, len_b, b);
		} else {
			if (!mpz_fill_random(b)) goto ver_cleanup_and_exit;
		}

		if (!H_nn(k, alg, ng->N, ng->N, ng->g)) goto ver_cleanup_and_exit;

		/* B = kv + g^b */
		mpz_mulm(tmp1, k, v, ng->N, tmp3);
		mpz_powm(tmp2, ng->g, b, ng->N);
		mpz_addm(B, tmp1, tmp2, ng->N, tmp3);

		if (!H_nn(u, alg, ng->N, A, B)) goto ver_cleanup_and_exit;

		srp_dbg_num(u, "Server calculated u: ");

		/* S = (A *(v^u)) ^ b */
		mpz_powm(tmp1, v, u, ng->N);
		mpz_mulm(tmp2, A, tmp1, ng->N, tmp3);
		mpz_powm(S, tmp2, b, ng->N);

		if (!hash_num(alg, S, ver->session_key)) goto ver_cleanup_and_exit;

		if (!calculate_M(
				alg, ng, ver->M, username, bytes_s, len_s, A, B, ver->session_key)) {
			goto ver_cleanup_and_exit;
		}
		if (!calculate_H_AMK(alg, ver->H_AMK, A, ver->M, ver->session_key)) {
			goto ver_cleanup_and_exit;
		}

		*len_B = mpz_num_bytes(B);
		*bytes_B = (unsigned char *)srp_alloc(*len_B);

		if (!*bytes_B) {
			*len_B = 0;
			goto ver_cleanup_and_exit;
		}

		mpz_to_bin(B, *bytes_B);

		ver->bytes_B = *bytes_B;
	} else {
		srp_free(ver);
		ver = 0;
	}

cleanup_and_exit:
	mpz_clear(v);
	mpz_clear(A);
	mpz_clear(u);
	mpz_clear(k);
	mpz_clear(B);
	mpz_clear(S);
	mpz_clear(b);
	mpz_clear(tmp1);
	mpz_clear(tmp2);
	mpz_clear(tmp3);
	return ver;
ver_cleanup_and_exit:
	srp_free(ver->username);
	srp_free(ver);
	ver = 0;
	goto cleanup_and_exit;
}