Ejemplo n.º 1
0
static bool_t ortp_init_srtp_policy(srtp_t srtp, srtp_policy_t* policy, enum ortp_srtp_crypto_suite_t suite, ssrc_t ssrc, const char* b64_key)
{
	uint8_t* key;
	int key_size;
	err_status_t err;
	unsigned b64_key_length = strlen(b64_key);
		
	switch (suite) {
		case AES_128_SHA1_32:
			crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy->rtp);
			// srtp doc says: not adapted to rtcp...
			crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy->rtcp);
			break;
		case AES_128_NO_AUTH:
			crypto_policy_set_aes_cm_128_null_auth(&policy->rtp);
			// srtp doc says: not adapted to rtcp...
			crypto_policy_set_aes_cm_128_null_auth(&policy->rtcp);
			break;
		case NO_CIPHER_SHA1_80:
			crypto_policy_set_null_cipher_hmac_sha1_80(&policy->rtp);
			crypto_policy_set_null_cipher_hmac_sha1_80(&policy->rtcp);
			break;
		case AES_128_SHA1_80: /*default mode*/
		default:
			crypto_policy_set_rtp_default(&policy->rtp);
			crypto_policy_set_rtcp_default(&policy->rtcp);
	}
	//b64_decode(char const *src, size_t srcLen, void *dest, size_t destSize)
	key_size = b64_decode(b64_key, b64_key_length, 0, 0);
	if (key_size != policy->rtp.cipher_key_len) {
		ortp_error("Key size (%d) doesn't match the selected srtp profile (required %d)",
			key_size,
			policy->rtp.cipher_key_len);
			return FALSE;
	}
	key = (uint8_t*) ortp_malloc0(key_size+2); /*srtp uses padding*/
	if (b64_decode(b64_key, b64_key_length, key, key_size) != key_size) {
		ortp_error("Error decoding key");
		ortp_free(key);
		return FALSE;
	}
		
	policy->ssrc = ssrc;
	policy->key = key;
	policy->next = NULL;
		
	err = ortp_srtp_add_stream(srtp, policy);
	if (err != err_status_ok) {
		ortp_error("Failed to add incoming stream to srtp session (%d)", err);
		ortp_free(key);
		return FALSE;
	}
		
	ortp_free(key);
	return TRUE;
}
Ejemplo n.º 2
0
RefPtr<SrtpFlow> SrtpFlow::Create(int cipher_suite,
                                           bool inbound,
                                           const void *key,
                                           size_t key_len) {
  nsresult res = Init();
  if (!NS_SUCCEEDED(res))
    return NULL;

  RefPtr<SrtpFlow> flow = new SrtpFlow();

  if (!key) {
    MOZ_MTLOG(PR_LOG_ERROR, "Null SRTP key specified");
    return NULL;
  }

  if (key_len != SRTP_TOTAL_KEY_LENGTH) {
    MOZ_MTLOG(PR_LOG_ERROR, "Invalid SRTP key length");
    return NULL;
  }

  srtp_policy_t policy;
  memset(&policy, 0, sizeof(srtp_policy_t));

  // Note that we set the same cipher suite for RTP and RTCP
  // since any flow can only have one cipher suite with DTLS-SRTP
  switch (cipher_suite) {
    case SRTP_AES128_CM_HMAC_SHA1_80:
      MOZ_MTLOG(PR_LOG_DEBUG, "Setting SRTP cipher suite SRTP_AES128_CM_HMAC_SHA1_80");
      crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
      crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
      break;
    case SRTP_AES128_CM_HMAC_SHA1_32:
      MOZ_MTLOG(PR_LOG_DEBUG, "Setting SRTP cipher suite SRTP_AES128_CM_HMAC_SHA1_32");
      crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
      crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); // 80-bit per RFC 5764
      break;                                                   // S 4.1.2.
    default:
      MOZ_MTLOG(PR_LOG_ERROR, "Request to set unknown SRTP cipher suite");
      return NULL;
  }
  // This key is copied into the srtp_t object, so we don't
  // need to keep it.
  policy.key = const_cast<unsigned char *>(
      static_cast<const unsigned char *>(key));
  policy.ssrc.type = inbound ? ssrc_any_inbound : ssrc_any_outbound;
  policy.ssrc.value = 0;
  policy.ekt = NULL;
  policy.window_size = 0;      // Use the default value.
  policy.allow_repeat_tx = 0;  // TODO([email protected]): revisit?
  policy.next = NULL;

  // Now make the session
  err_status_t r = srtp_create(&flow->session_, &policy);
  if (r != err_status_ok) {
    MOZ_MTLOG(PR_LOG_ERROR, "Error creating srtp session");
    return NULL;
  }

  return flow;
}
Ejemplo n.º 3
0
JNIEXPORT jint JNICALL Java_org_theonionphone_protocol_SrtpProtocol_initReceiver
	(JNIEnv *env, jobject obj, jint ssrc, jbyteArray keyByteArray, jbyteArray saltByteArray) {

	srtp_policy_t policy;
	char key[SRTP_KEY_SIZE];

	// copy key and salt to an array needed by srtp
	(*env)->GetByteArrayRegion(env, keyByteArray, 0, KEY_SIZE, key);
	(*env)->GetByteArrayRegion(env, saltByteArray, 0, SALT_SIZE, key + KEY_SIZE);

	//set up crypto policies
	crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
	crypto_policy_set_rtcp_default(&policy.rtcp);

	policy.ssrc.type  = ssrc_specific;
	policy.ssrc.value = ssrc;
	policy.key  = (uint8_t *) key;
	policy.next = NULL;
	policy.rtp.sec_serv = sec_serv_conf_and_auth;
	policy.rtcp.sec_serv = sec_serv_none;  /* we don't do RTCP anyway */

	//create an srtp stream
	srtpContextRecv = malloc(sizeof(srtp_t*));
		if(srtpContextRecv == NULL) {
			return 69;
		}
	err_status_t status = srtp_create(srtpContextRecv, &policy);

	return status;
}
Ejemplo n.º 4
0
trtp_srtp_set_crypto(struct trtp_manager_s* rtp_mgr, const char* crypto_line, int32_t idx)
{
	//e.g. 2 F8_128_HMAC_SHA1_80 inline:MTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5QUJjZGVm|2^20|1:4;inline:QUJjZGVmMTIzNDU2Nzg5QUJDREUwMTIzNDU2Nzg5|2^20|2:4"
	trtp_srtp_ctx_xt* srtp_ctx;
	int ret;
	uint8_t *key_bin;
	err_status_t srtp_err;
	int32_t tag, crypto_type;
	char key_str[SRTP_MAX_KEY_LEN + 1];
	
	memset(key_str, 0, sizeof(key_str));

	if((ret = trtp_srtp_match_line(crypto_line, &tag, &crypto_type, key_str, sizeof(key_str) - 1))){
		return ret;
	}

	srtp_ctx = &rtp_mgr->srtp_contexts[idx][crypto_type];
	ret = trtp_srtp_ctx_deinit(srtp_ctx);

	srtp_ctx->tag = tag;
	srtp_ctx->crypto_type = (trtp_srtp_crypto_type_t)crypto_type;
	memcpy(srtp_ctx->key_str, key_str, sizeof(srtp_ctx->key_str));
	
	switch(srtp_ctx->crypto_type){
		case HMAC_SHA1_80:
			{
				crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtp);
				crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtcp);
				if(idx == TRTP_SRTP_LINE_IDX_REMOTE){
					trtp_srtp_ctx_deinit(&rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32]);
					rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80].tag = srtp_ctx->tag;
				}
				break;
			}
		case HMAC_SHA1_32:
			{
				crypto_policy_set_aes_cm_128_hmac_sha1_32(&srtp_ctx->policy.rtp);
				crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtcp); // RTCP always 80
				if(idx == TRTP_SRTP_LINE_IDX_REMOTE){
					trtp_srtp_ctx_deinit(&rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_80]);
					rtp_mgr->srtp_contexts[TRTP_SRTP_LINE_IDX_LOCAL][HMAC_SHA1_32].tag = srtp_ctx->tag;
				}
				break;
			}
	}

	key_bin = (unsigned char*)srtp_ctx->key_bin;
	tsk_base64_decode((const uint8_t*)srtp_ctx->key_str, tsk_strlen(srtp_ctx->key_str), (char**)&key_bin);
	srtp_ctx->policy.key = key_bin;
	srtp_ctx->policy.ssrc.type = idx == TRTP_SRTP_LINE_IDX_REMOTE ? ssrc_any_inbound : ssrc_any_outbound;
	if((srtp_err = srtp_create(&srtp_ctx->session, &srtp_ctx->policy)) != err_status_ok){
		TSK_DEBUG_ERROR("srtp_create() failed: %d", srtp_err);
		return -3;
	}
	srtp_ctx->initialized = tsk_true;
	return 0;
}
Ejemplo n.º 5
0
int trtp_srtp_set_key_and_salt(trtp_manager_t* rtp_mgr, trtp_srtp_crypto_type_t crypto_type, const void* key, tsk_size_t key_size, const void* salt, tsk_size_t salt_size, int32_t idx)
{
	int ret;
	trtp_srtp_ctx_xt* srtp_ctx;
	err_status_t srtp_err;
	if(!rtp_mgr || !key || !key_size || !salt || !salt_size){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	if((key_size + salt_size) > sizeof(srtp_ctx->key_bin)){
		TSK_DEBUG_ERROR("Invalid [key||salt].len [%u||%u]", key_size, salt_size);
	}

	srtp_ctx = &rtp_mgr->srtp_contexts[idx][0];
	if((ret = trtp_srtp_ctx_deinit(srtp_ctx))){
		return ret;
	}
		
	switch((srtp_ctx->crypto_type = crypto_type)){
		case HMAC_SHA1_80:
		default:
			{
				crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtp);
				crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtcp);
				break;
			}
		case HMAC_SHA1_32:
			{
				crypto_policy_set_aes_cm_128_hmac_sha1_32(&srtp_ctx->policy.rtp);
				crypto_policy_set_aes_cm_128_hmac_sha1_80(&srtp_ctx->policy.rtcp); // always 80
				break;
			}
	}

	memcpy(srtp_ctx->key_bin, key, key_size);
#if HAVE_APPEND_SALT_TO_KEY
	append_salt_to_key(srtp_ctx->key_bin, key_size, (void*)salt, salt_size);
#else
	memcpy(&srtp_ctx->key_bin[key_size], salt, salt_size);
#endif
	
	srtp_ctx->policy.key = srtp_ctx->key_bin;
	srtp_ctx->policy.ssrc.type = idx == TRTP_SRTP_LINE_IDX_REMOTE ? ssrc_any_inbound : ssrc_any_outbound;
	if((srtp_err = srtp_create(&srtp_ctx->session, &srtp_ctx->policy)) != err_status_ok){
		TSK_DEBUG_ERROR("srtp_create() failed: %d", srtp_err);
		return -3;
	}
	srtp_ctx->initialized = tsk_true;
	return 0;
}
Ejemplo n.º 6
0
int trtp_srtp_ctx_init(trtp_srtp_ctx_xt* ctx, int32_t tag, trtp_srtp_crypto_type_t type, uint32_t ssrc){

	char* key_str = ctx->key_str;
	err_status_t srtp_err;
	tsk_size_t size;
	
	if(!ctx){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	if(ctx->initialized){
		trtp_srtp_ctx_deinit(ctx);
	}

	ctx->tag = tag;
	ctx->crypto_type = type;
	if((srtp_err = crypto_get_random((unsigned char*)ctx->key_bin, sizeof(ctx->key_bin))) != err_status_ok){
		TSK_DEBUG_ERROR("crypto_get_random() failed");
		return -2;
	}
	size = tsk_base64_encode((const uint8_t*)ctx->key_bin, sizeof(ctx->key_bin), &key_str);
	key_str[size] = '\0';

	switch(ctx->crypto_type){
		case HMAC_SHA1_80:
			{
				crypto_policy_set_aes_cm_128_hmac_sha1_80(&ctx->policy.rtp);
				crypto_policy_set_aes_cm_128_hmac_sha1_80(&ctx->policy.rtcp);
				break;
			}
		case HMAC_SHA1_32:
		default:
			{
				crypto_policy_set_aes_cm_128_hmac_sha1_32(&ctx->policy.rtp);
				crypto_policy_set_aes_cm_128_hmac_sha1_80(&ctx->policy.rtcp); // RTCP always 80
				break;
			}
	}
	
	ctx->policy.key = (unsigned char*)ctx->key_bin;
	ctx->policy.ssrc.type = ssrc_any_outbound;
	ctx->policy.ssrc.value = ssrc;
	if((srtp_err = srtp_create(&ctx->session, &ctx->policy)) != err_status_ok){
		TSK_DEBUG_ERROR("srtp_create() failed");
		return -3;
	}
	ctx->initialized = tsk_true;
	return 0;
}
Ejemplo n.º 7
0
static int start_srtp(struct menc_st *st, const char *suite)
{
	crypto_policy_t policy;
	err_status_t e;

	if (0 == str_casecmp(suite, aes_cm_128_hmac_sha1_32)) {
		crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy);
	}
	else if (0 == str_casecmp(suite, aes_cm_128_hmac_sha1_80)) {
		crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy);
	}
	else {
		DEBUG_WARNING("unknown SRTP crypto suite (%s)\n", suite);
		return ENOENT;
	}

	/* transmit policy */
	st->policy_tx.rtp = policy;
	st->policy_tx.rtcp = policy;
	st->policy_tx.ssrc.type = ssrc_any_outbound;
	st->policy_tx.key = st->key_tx;
	st->policy_tx.next = NULL;

	/* receive policy */
	st->policy_rx.rtp = policy;
	st->policy_rx.rtcp = policy;
	st->policy_rx.ssrc.type = ssrc_any_inbound;
	st->policy_rx.key = st->key_rx;
	st->policy_rx.next = NULL;

	/* allocate and initialize the SRTP session */
	e = srtp_create(&st->srtp_tx, &st->policy_tx);
	if (e != err_status_ok) {
		DEBUG_WARNING("srtp_create TX failed (%H)\n",
			      errstatus_print, e);
		return EPROTO;
	}

	e = srtp_create(&st->srtp_rx, &st->policy_rx);
	if (err_status_ok != e) {
		DEBUG_WARNING("srtp_create RX failed (%H)\n",
			      errstatus_print, e);
		return EPROTO;
	}

	/* use SRTP for this stream/session */
	st->use_srtp = true;

	return 0;
}
Ejemplo n.º 8
0
JNIEXPORT jint JNICALL Java_org_theonionphone_protocol_SrtpProtocol_initSender
	(JNIEnv *env, jobject obj, jbyteArray keyByteArray, jbyteArray saltByteArray, jint codecType, jint sampleCount,
			jint payloadSizeInBytes, jint rtpPacketSizeInBytes, jint srtpPacketSizeInBytes) {

	srtp_policy_t policy;
	char key[SRTP_KEY_SIZE];
	payloadSize = payloadSizeInBytes;
	rtpPacketSize = rtpPacketSizeInBytes;
	srtpPacketSize = srtpPacketSizeInBytes;

	// copy key and salt to an array needed by srtp
	(*env)->GetByteArrayRegion(env, keyByteArray, 0, KEY_SIZE, key);
	(*env)->GetByteArrayRegion(env, saltByteArray, 0, SALT_SIZE, key + KEY_SIZE);

	//initialize rtp
	err_status_t status = initRtp(&rtpContext, codecType, sampleCount);
	if(status) {
		return status;
	}

	//initialize srtp
	status = srtp_init();
	if(status) {
		return status;
	}

	//set up crypto policies
	crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
	crypto_policy_set_rtcp_default(&policy.rtcp);

	policy.ssrc.type  = ssrc_specific;
	policy.ssrc.value = rtpContext->mSsrc;
	policy.key  = (uint8_t *) key;
	policy.next = NULL;
	policy.rtp.sec_serv = sec_serv_conf_and_auth;
	policy.rtcp.sec_serv = sec_serv_none;  /* we don't do RTCP anyway */

	//create an srtp stream
	srtpContextSend = malloc(sizeof(srtp_t*));
	if(srtpContextSend == NULL) {
		return 69;
	}
	status = srtp_create(srtpContextSend, &policy);

	return status;
}
Ejemplo n.º 9
0
/**
 * SRTP crypto data ready for the sender or receiver.
 *
 * The ZRTP implementation calls this method right after all SRTP
 * secrets are computed and ready to be used. The parameter points
 * to a structure that contains pointers to the SRTP secrets and a
 * <code>enum Role</code>. The called method (the implementation
 * of this abstract method) must either copy the pointers to the SRTP
 * data or the SRTP data itself to a save place. The SrtpSecret_t
 * structure is destroyed after the callback method returns to the
 * ZRTP implementation.
 *
 * The SRTP data themselves are obtained in the ZRtp object and are
 * valid as long as the ZRtp object is active. TheZRtp's
 * destructor clears the secrets. Thus the called method needs to
 * save the pointers only, ZRtp takes care of the data.
 *
 * The implementing class may enable SRTP processing in this
 * method or delay it to srtpSecertsOn().
 *
 * @param ctx
 *    Pointer to the opaque ZrtpContext structure.
 * @param secrets A pointer to a SrtpSecret_t structure that
 *     contains all necessary data.
 *
 * @param part for which part (Sender or Receiver) this data is
 *     valid.
 *
 * @return Returns false if something went wrong during
 *    initialization of SRTP context, for example memory shortage.
 */
static int32_t ozrtp_srtpSecretsReady (ZrtpContext* ctx, C_SrtpSecret_t* secrets, int32_t part ) {
	srtp_policy_t policy;
	err_status_t srtpCreateStatus;
	err_status_t addStreamStatus;
	OrtpZrtpContext *userData = user_data(ctx);

	ortp_message("ZRTP secrets for %s are ready; auth tag len is %i",
	             (part == ForSender) ? "sender" : "receiver",secrets->srtpAuthTagLen);

	// Get authentication and cipher algorithms in srtp format
	if (secrets->authAlgorithm != zrtp_Sha1) {
		ortp_fatal("unsupported authentication algorithm by srtp");
	}

	if (secrets->symEncAlgorithm != zrtp_Aes) {
		ortp_fatal("unsupported cipher algorithm by srtp");
	}

	/*
	 * Don't use crypto_policy_set_from_profile_for_rtp(), it is totally buggy.
	 */
	memset(&policy,0,sizeof(policy));

	if (secrets->srtpAuthTagLen == 32){
		crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
		crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtcp);
	}else if (secrets->srtpAuthTagLen == 80){
		crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
		crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
	}else{
		ortp_fatal("unsupported auth tag len");
	}

	if (part == ForSender) {
		srtpCreateStatus=srtp_create(&userData->srtpSend, NULL);
		policy.ssrc.type=ssrc_specific;
		policy.ssrc.value=userData->session->snd.ssrc; // us
		policy.key=key_with_salt(secrets, secrets->role);
		addStreamStatus=srtp_add_stream(userData->srtpSend, &policy);
	} else { //if (part == ForReceiver)
		srtpCreateStatus=srtp_create(&userData->srtpRecv, NULL);
		policy.ssrc.type = ssrc_any_inbound; /*we don't know the incoming ssrc will be */
		int32_t peerRole=secrets->role == Initiator ? Responder : Initiator;
		policy.key=key_with_salt(secrets,peerRole);
		addStreamStatus=srtp_add_stream(userData->srtpRecv, &policy);
	}

	ortp_free(policy.key);

	if (srtpCreateStatus != err_status_ok) {
		ortp_error("ZRTP Error %u during creation of SRTP context for %s",
			srtpCreateStatus, (part == ForSender) ? "sender" : "receiver");
		return 0;
	}
	if (addStreamStatus != err_status_ok) {
		ortp_error("ZRTP Error %u during addition of SRTP stream for %s",
			addStreamStatus, (part == ForSender) ? "sender" : "receiver");
		return 0;
	}
	return 1;
}
Ejemplo n.º 10
0
static int add_srtp_stream(srtp_t srtp, MSCryptoSuite suite, uint32_t ssrc, const char* b64_key, bool_t inbound)
{
	srtp_policy_t policy;
	uint8_t* key;
	int key_size;
	err_status_t err;
	unsigned b64_key_length = strlen(b64_key);
	ssrc_t ssrc_conf;

	memset(&policy,0,sizeof(policy));

	switch(suite){
		case MS_AES_128_SHA1_32:
			crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp);
			// srtp doc says: not adapted to rtcp...
			crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtcp);
			break;
		case MS_AES_128_NO_AUTH:
			crypto_policy_set_aes_cm_128_null_auth(&policy.rtp);
			// srtp doc says: not adapted to rtcp...
			crypto_policy_set_aes_cm_128_null_auth(&policy.rtcp);
			break;
		case MS_NO_CIPHER_SHA1_80:
			crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtp);
			crypto_policy_set_null_cipher_hmac_sha1_80(&policy.rtcp);
			break;
		case MS_AES_128_SHA1_80: /*default mode*/
			crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
			crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
			break;
		case MS_AES_256_SHA1_80:
			crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
			crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
			break;
		case MS_AES_256_SHA1_32:
			crypto_policy_set_aes_cm_256_hmac_sha1_32(&policy.rtp);
			crypto_policy_set_aes_cm_256_hmac_sha1_32(&policy.rtcp);
			break;
		case MS_CRYPTO_SUITE_INVALID:
			return -1;
			break;
	}
	key_size = b64_decode(b64_key, b64_key_length, 0, 0);
	if (key_size != policy.rtp.cipher_key_len) {
		ortp_error("Key size (%d) doesn't match the selected srtp profile (required %d)",
			key_size,
			policy.rtp.cipher_key_len);
			return -1;
	}
	key = (uint8_t*) ortp_malloc0(key_size+2); /*srtp uses padding*/
	if (b64_decode(b64_key, b64_key_length, key, key_size) != key_size) {
		ortp_error("Error decoding key");
		ortp_free(key);
		return -1;
	}
	if (!inbound)
		policy.allow_repeat_tx=1; /*necessary for telephone-events*/

	/*ssrc_conf.type=inbound ? ssrc_any_inbound : ssrc_specific;*/
	ssrc_conf.type=ssrc_specific;
	ssrc_conf.value=ssrc;

	policy.ssrc = ssrc_conf;
	policy.key = key;
	policy.next = NULL;

	err = srtp_add_stream(srtp, &policy);
	if (err != err_status_ok) {
		ortp_error("Failed to add stream to srtp session (%d)", err);
		ortp_free(key);
		return -1;
	}

	ortp_free(key);
	return 0;
}