/*----------------------------------------------------------------------------*/ 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; }
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")); }
// 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); }
/*----------------------------------------------------------------------------*/ 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; }