err_status_t srtp_stream_init_from_ekt(srtp_stream_t stream, const void *srtcp_hdr, unsigned pkt_octet_len) { err_status_t err; const uint8_t *master_key; srtp_policy_t srtp_policy; unsigned master_key_len; uint32_t roc; /* * NOTE: at present, we only support a single ekt_policy at a time. */ if (stream->ekt->data->spi != srtcp_packet_get_ekt_spi(srtcp_hdr, pkt_octet_len)) return err_status_no_ctx; if (stream->ekt->data->ekt_cipher_type != EKT_CIPHER_AES_128_ECB) return err_status_bad_param; master_key_len = 16; /* decrypt the Encrypted Master Key field */ master_key = srtcp_packet_get_emk_location(srtcp_hdr, pkt_octet_len); /* FIX!? This decrypts the master key in-place, and never uses it */ /* FIX!? It's also passing to ekt_dec_key (which is an AES_KEY) * to a function which expects a raw (unexpanded) key */ aes_decrypt_with_raw_key((void*)master_key, &stream->ekt->data->ekt_dec_key, 16); /* set the SRTP ROC */ roc = srtcp_packet_get_ekt_roc(srtcp_hdr, pkt_octet_len); err = rdbx_set_roc(&stream->rtp_rdbx, roc); if (err) return err; err = srtp_stream_init(stream, &srtp_policy); if (err) return err; return err_status_ok; }
/* Create a stream in the session */ static err_status_t init_session_stream (GstSrtpDec * filter, guint32 ssrc, GstSrtpDecSsrcStream * stream) { err_status_t ret; srtp_policy_t policy; GstMapInfo map; guchar tmp[1]; memset (&policy, 0, sizeof (srtp_policy_t)); if (!stream) return err_status_bad_param; GST_INFO_OBJECT (filter, "Setting RTP policy..."); set_crypto_policy_cipher_auth (stream->rtp_cipher, stream->rtp_auth, &policy.rtp); GST_INFO_OBJECT (filter, "Setting RTCP policy..."); set_crypto_policy_cipher_auth (stream->rtcp_cipher, stream->rtcp_auth, &policy.rtcp); if (stream->key) { gst_buffer_map (stream->key, &map, GST_MAP_READ); policy.key = (guchar *) map.data; } else { policy.key = tmp; } policy.ssrc.value = ssrc; policy.ssrc.type = ssrc_specific; policy.window_size = filter->replay_window_size; policy.next = NULL; /* If it is the first stream, create the session * If not, add the stream policy to the session */ if (filter->first_session) ret = srtp_create (&filter->session, &policy); else ret = srtp_add_stream (filter->session, &policy); if (stream->key) gst_buffer_unmap (stream->key, &map); if (ret == err_status_ok) { srtp_stream_t srtp_stream; srtp_stream = srtp_get_stream (filter->session, htonl (ssrc)); if (srtp_stream) { /* Here, we just set the ROC, but we also need to set the initial * RTP sequence number later, otherwise libsrtp will not be able * to get the right packet index. */ rdbx_set_roc (&srtp_stream->rtp_rdbx, stream->roc); filter->roc_changed = TRUE; } filter->first_session = FALSE; g_hash_table_insert (filter->streams, GUINT_TO_POINTER (stream->ssrc), stream); } return ret; }