예제 #1
0
/*----------------------------------------------------------------------------*/
static zrtp_status_t zrtp_dh_self_test(zrtp_pk_scheme_t *self)
{
	zrtp_status_t s = zrtp_status_ok;
	zrtp_dh_crypto_context_t alice_cc;
	zrtp_dh_crypto_context_t bob_cc;
	struct BigNum alice_k;
	struct BigNum bob_k;
	zrtp_time_t start_ts = zrtp_time_now();
	
	ZRTP_LOG(3, (_ZTU_, "PKS %.4s testing... ", self->base.type));
	
	bnBegin(&alice_k);
	bnBegin(&bob_k);
	
	do {	
		/* Both sides initalise DH schemes and compute secret and public values. */
		s = self->initialize(self, &alice_cc);
		if (zrtp_status_ok != s) {
			break;
		}
		s = self->initialize(self, &bob_cc);
		if (zrtp_status_ok != s) {
			break;
		}
		
		/* Both sides validate public values. (to provide exact performance estimation) */
		s = self->validate(self, &bob_cc.pv);
		if (zrtp_status_ok != s) {
			break;
		}
		s = self->validate(self, &alice_cc.pv);
		if (zrtp_status_ok != s) {
			break;
		}
		
		/* Compute secret keys and compare them. */
		s = self->compute(self, &alice_cc, &alice_k, &bob_cc.pv);
		if (zrtp_status_ok != s) {
			break;
		}
		s= self->compute(self, &bob_cc, &bob_k, &alice_cc.pv);
		if (zrtp_status_ok != s) {
			break;
		}
				
		s = (0 == bnCmp(&alice_k, &bob_k)) ? zrtp_status_ok : zrtp_status_algo_fail;
	} while (0);

	bnEnd(&alice_k);
	bnEnd(&bob_k);
		
	ZRTP_LOGC(3, ("%s (%llu ms)\n", zrtp_log_status2str(s), (zrtp_time_now()-start_ts)/2));
	
	return s;
}
예제 #2
0
static void print_map(uint8_t *map, int width_bytes)
{
	int i;
	for(i=width_bytes-1; i >= 0; i--) {
		ZRTP_LOGC(3, ("%i%i%i%i%i%i%i%i",
					zrtp_bitmap_get_bit(map, 8*i+7),
					zrtp_bitmap_get_bit(map, 8*i+6),
					zrtp_bitmap_get_bit(map, 8*i+5),
					zrtp_bitmap_get_bit(map, 8*i+4),
					zrtp_bitmap_get_bit(map, 8*i+3),
					zrtp_bitmap_get_bit(map, 8*i+2),
					zrtp_bitmap_get_bit(map, 8*i+1),
					zrtp_bitmap_get_bit(map, 8*i+0)));			
	}
	ZRTP_LOG(3, (_ZTU_, "\n"));
}
예제 #3
0
// TODO: split test into several, more atomic tests
static void srtp_replay_test() {
	int res = 0;
	uint32_t ssrc = 1;
	int i = 0;
	uint8_t test_map[TEST_MAP_WIDTH_BYTES];
	uint8_t result_map[TEST_MAP_WIDTH_BYTES];
	uint8_t tmp_window[ZRTP_SRTP_WINDOW_WIDTH_BYTES];
	uint32_t tmp_seq;
	int delta, shift;
		
	zrtp_rp_node_t *rp_node;
	zrtp_srtp_global_t *srtp = zrtp->srtp_global;
	
	rp_node = add_rp_node(NULL, srtp->rp_ctx, RP_INCOMING_DIRECTION, ssrc);
	assert_non_null(rp_node);
		
	for (i=0; i< TEST_MAP_WIDTH_BYTES; i++) {
		test_map[i] = 0;
		result_map[i] = 0;
	}
	/*
	 * 1st test
	 * ----------------------------------------------------------------------
	 */
	init_random_map(test_map, FIRST_TEST_MAP_INIT_WIDTH, zrtp);
	inject_from_map(srtp, ssrc, test_map, result_map, TEST_MAP_WIDTH);
	
	ZRTP_LOG(3, (_ZTU_,"1st test. Wnd[%i]...\n", ZRTP_SRTP_WINDOW_WIDTH));

	tmp_seq = rp_node->rtp_rp.seq;
	for (i=0; i<ZRTP_SRTP_WINDOW_WIDTH_BYTES; i++) {
		tmp_window[i] = rp_node->rtp_rp.window[i];
	}
	
	delta = tmp_seq-ZRTP_SRTP_WINDOW_WIDTH + 1;
	if (delta > 0) {
		ZRTP_LOG(3, (_ZTU_,"after  wnd: (%i;0]\n", delta));
		ZRTP_LOG(3, (_ZTU_,"inside wnd: [%i;%i]\n", tmp_seq, delta)); 
	} else {
		ZRTP_LOG(3, (_ZTU_,"after  wnd: (0;0)\n"));
		ZRTP_LOG(3, (_ZTU_,"inside wnd: [%i;0]\n", tmp_seq)); 
	}
	
	ZRTP_LOG(3, (_ZTU_,"before wnd: [%i;%i)\n", TEST_MAP_WIDTH-1, tmp_seq));
	
	ZRTP_LOG(3, (_ZTU_,"Test map: "));
	print_map(test_map, TEST_MAP_WIDTH_BYTES);
		
	ZRTP_LOG(3, (_ZTU_,"Res  map: "));
	print_map(result_map, TEST_MAP_WIDTH_BYTES);

	shift = TEST_MAP_WIDTH;
	shift -= rp_node->rtp_rp.seq + 1;

	ZRTP_LOG(3, (_ZTU_,"Window  : "));
	for(i=shift; i > 0; i--){
		ZRTP_LOGC(3, (" "));
	}
	print_map(rp_node->rtp_rp.window, ZRTP_SRTP_WINDOW_WIDTH_BYTES);
	
	/*
	 * 2nd test
	 * ----------------------------------------------------------------------
	 */
	for(i=0; i< TEST_MAP_WIDTH_BYTES; i++){
		test_map[i] = 0;
		result_map[i] = 0;
	}

	init_random_map(test_map, TEST_MAP_WIDTH, zrtp);
	inject_from_map(srtp, ssrc, test_map, result_map, TEST_MAP_WIDTH);

	ZRTP_LOG(3, (_ZTU_,"2nd test. Wnd[%i]...\n", ZRTP_SRTP_WINDOW_WIDTH));
	ZRTP_LOG(3, (_ZTU_,"Test map: "));
	print_map(test_map, TEST_MAP_WIDTH_BYTES);
		
	ZRTP_LOG(3, (_ZTU_,"Res  map: "));
	print_map(result_map, TEST_MAP_WIDTH_BYTES);

	shift = TEST_MAP_WIDTH;
	shift -= rp_node->rtp_rp.seq + 1;

	ZRTP_LOG(3, (_ZTU_,"Window  : "));
	for (i=shift; i > 0; i--) {
		//zrtp_print_log(ZRTP_LOG_DEBUG, " ");
	}
	print_map(rp_node->rtp_rp.window, ZRTP_SRTP_WINDOW_WIDTH_BYTES);

	
	/*
	  in result map:
	  - after window we should to have all zeroes
	  - into the window we should have ones only if window have zero at appropriate position
	  - before window we should have equal values of test map and result map bits
	*/	
	for (i=0; i < TEST_MAP_WIDTH; i++) {
		if (delta > 0 && i < delta) {
			/* After window */
			if (0 != zrtp_bitmap_get_bit(result_map, i)) {
				ZRTP_LOG(3, (_ZTU_,"After window. %i bit should be 0\n", i));
				res = -1;
			}
		} else if (i <= (int)tmp_seq && i >= delta) {
			/* inside window */
			
			/* check window filtering */
			if(1 == zrtp_bitmap_get_bit(result_map, i)) {			
				if (1 == zrtp_bitmap_get_bit(tmp_window, i - (tmp_seq-ZRTP_SRTP_WINDOW_WIDTH) - 1)) {				
					ZRTP_LOG(3, (_ZTU_,"Inside window. Window filtering fail. %i bit should be 0\n", i));
					res = -1;
				}
			}
			/* check test vs result maps */
			if ( zrtp_bitmap_get_bit(result_map, i) != zrtp_bitmap_get_bit(test_map, i) &&
				 !zrtp_bitmap_get_bit(tmp_window, i - (tmp_seq-ZRTP_SRTP_WINDOW_WIDTH) - 1)) {
				ZRTP_LOG(3, (_ZTU_, "Inside window. Test map isn't equal to result at bit %i\n", i));
				res = -1;
			}
				
		} else {
			/* after window */
			if (zrtp_bitmap_get_bit(result_map, i) != zrtp_bitmap_get_bit(test_map, i)) {
				ZRTP_LOG(3, (_ZTU_,"Before window. Test map isn't equal to result at bit %i\n", i));
				res = -1;
			}
		}
	}
	
	assert_int_equal(res, 0);
}
예제 #4
0
/*----------------------------------------------------------------------------*/
zrtp_status_t zrtp_session_init( zrtp_global_t* zrtp,
								zrtp_profile_t* profile,
								zrtp_zid_t zid,
								zrtp_signaling_role_t role,
								zrtp_session_t **session)
{
    uint32_t i = 0;
	zrtp_status_t s = zrtp_status_fail;
	zrtp_session_t* new_session = NULL;
        
    if (!zrtp) {
    	return zrtp_status_bad_param;
    }
	
	new_session = zrtp_sys_alloc(sizeof(zrtp_session_t));
	if (!new_session) {
		return zrtp_status_alloc_fail;		
	}
    
    zrtp_memset(new_session, 0, sizeof(zrtp_session_t));
	new_session->id = zrtp->sessions_count++;
	
	{
		zrtp_uchar32_t buff;
		ZRTP_LOG(3, (_ZTU_,"START SESSION INITIALIZATION. sID=%u.\n", new_session->id));
		ZRTP_LOG(3, (_ZTU_,"ZID=%s.\n", hex2str((const char*)zid, sizeof(zrtp_uchar12_t), (char*)buff, sizeof(buff)) ));
	}
	
	do {	
	/*
	 * Apply profile for the stream context: set flags and prepare Hello packet.
	 * If profile structure isn't provided, generate default.
	 */	 
    if (!profile) {
		ZRTP_LOG(1, (_ZTU_,"Profile in NULL - loading default one.\n"));
		zrtp_profile_defaults(&new_session->profile, zrtp);		
    } else {
		ZRTP_LOG(1, (_ZTU_,"Loading User's profile:\n"));
		if (zrtp_status_ok != zrtp_profile_check(profile, zrtp)) {
			ZRTP_LOG(1, (_ZTU_,"ERROR! Can't apply wrong profile to the session sID=%u.\n", new_session->id));
			break;
		}
		
		/* Adjust user's settings: force SHA-384 hash for ECDH-384P */
		if (zrtp_profile_find(profile, ZRTP_CC_PKT, ZRTP_PKTYPE_EC384P) > 0) {
			ZRTP_LOG(3, (_ZTU_,"User wants ECDH384 - auto-adjust profile to use SHA-384.\n"));
			profile->hash_schemes[0] = ZRTP_HASH_SHA384;
			profile->hash_schemes[1] = ZRTP_HASH_SHA256;
			profile->hash_schemes[2] = 0;
		}		
		
		zrtp_memcpy(&new_session->profile, profile, sizeof(zrtp_profile_t));
		
		{
		int i;
		ZRTP_LOG(3, (_ZTU_,"   allowclear: %s\n", profile->allowclear?"ON":"OFF"));
		ZRTP_LOG(3, (_ZTU_,"   autosecure: %s\n", profile->autosecure?"ON":"OFF"));
		ZRTP_LOG(3, (_ZTU_," disclose_bit: %s\n", profile->disclose_bit?"ON":"OFF"));
		ZRTP_LOG(3, (_ZTU_," signal. role: %s\n", zrtp_log_sign_role2str(role)));	
		ZRTP_LOG(3, (_ZTU_,"          TTL: %u\n", profile->cache_ttl));
				
		ZRTP_LOG(3, (_ZTU_,"  SAS schemes: "));
		i=0;
		while (profile->sas_schemes[i]) {
			ZRTP_LOGC(3, ("%.4s ", zrtp_comp_id2type(ZRTP_CC_SAS, profile->sas_schemes[i++])));
		}
		ZRTP_LOGC(3, ("\n")); ZRTP_LOG(1, (_ZTU_,"     Ciphers: "));
		i=0;
		while (profile->cipher_types[i]) {
			ZRTP_LOGC(3, ("%.4s ", zrtp_comp_id2type(ZRTP_CC_CIPHER, profile->cipher_types[i++])));
		}
		ZRTP_LOGC(3, ("\n")); ZRTP_LOG(1, (_ZTU_,"   PK schemes: "));
		i=0;
		while (profile->pk_schemes[i]) {
			ZRTP_LOGC(3, ("%.4s ", zrtp_comp_id2type(ZRTP_CC_PKT, profile->pk_schemes[i++])));
		}
		ZRTP_LOGC(3, ("\n")); ZRTP_LOG(1, (_ZTU_,"          ATL: "));
		i=0;
		while (profile->auth_tag_lens[i]) {
			ZRTP_LOGC(3, ("%.4s ", zrtp_comp_id2type(ZRTP_CC_ATL, profile->auth_tag_lens[i++])));
		}
		ZRTP_LOGC(3, ("\n")); ZRTP_LOG(1, (_ZTU_,"      Hashes: "));
		i=0;
		while (profile->hash_schemes[i]) {
			ZRTP_LOGC(3, ("%.4s ", zrtp_comp_id2type(ZRTP_CC_HASH, profile->hash_schemes[i++])));
		}
		ZRTP_LOGC(3, ("\n"));
		}
	}

	/* Set ZIDs */
	ZSTR_SET_EMPTY(new_session->zid);
    ZSTR_SET_EMPTY(new_session->peer_zid);
	zrtp_zstrncpyc(ZSTR_GV(new_session->zid), (const char*)zid, sizeof(zrtp_zid_t));	

	new_session->zrtp = zrtp;
	new_session->signaling_role = role;
	new_session->mitm_alert_detected = 0;

	/*
	 * Allocate memory for holding secrets and initialize with random values.
	 * Actual values will be written from the cache at the beginning of the protocol.
	 */
	new_session->secrets.rs1 = _zrtp_alloc_shared_secret(new_session);
	new_session->secrets.rs2 = _zrtp_alloc_shared_secret(new_session);	
	new_session->secrets.auxs = _zrtp_alloc_shared_secret(new_session);
	new_session->secrets.pbxs = _zrtp_alloc_shared_secret(new_session);

	if ( !new_session->secrets.rs1 || !new_session->secrets.rs2 ||
		 !new_session->secrets.auxs || !new_session->secrets.pbxs) {
		ZRTP_LOG(1, (_ZTU_,"ERROR! Can't allocate shared secrets sID=%u\n.", new_session->id));
		s = zrtp_status_alloc_fail;
		break;
	}

	/* Initialize SAS values */	
	ZSTR_SET_EMPTY(new_session->sas1);
	ZSTR_SET_EMPTY(new_session->sas2);
	ZSTR_SET_EMPTY(new_session->sasbin);
	ZSTR_SET_EMPTY(new_session->zrtpsess);
    
    /* Clear all stream structures */
    for (i=0; i<ZRTP_MAX_STREAMS_PER_SESSION ; i++) {
		new_session->streams[i].state		= ZRTP_STATE_NONE;
		new_session->streams[i].prev_state	= ZRTP_STATE_NONE;
		new_session->streams[i].mode		= ZRTP_STREAM_MODE_UNKN;
    }
        
    /* Initialize synchronization objects */
	s = zrtp_mutex_init(&new_session->streams_protector);
    if (zrtp_status_ok != s) {
		ZRTP_LOG(1, (_ZTU_,"ERROR! can't initialize Stream protector. sID=%u.\n", new_session->id));
		break;
	}	
	s = zrtp_mutex_init(&new_session->init_protector);
    if (zrtp_status_ok != s) {
		ZRTP_LOG(1, (_ZTU_,"ERROR! can't initialize Init protector. sID=%u.\n", new_session->id));
		break;
	}		
	
	s = zrtp_status_ok;
	} while (0);
	
	if (zrtp_status_ok != s) {
		zrtp_sys_free(new_session);
		return s;
	}

    /* Add new session to the global list */    
    zrtp_mutex_lock(zrtp->sessions_protector);
    mlist_add(&zrtp->sessions_head, &new_session->_mlist);
    zrtp_mutex_unlock(zrtp->sessions_protector);
    
	*session = new_session;
	
    ZRTP_LOG(3, (_ZTU_,"Session initialization - DONE. sID=%u.\n\n", new_session->id));

    return zrtp_status_ok;
}