|
|
|
|
@ -137,8 +137,6 @@ error:
|
|
|
|
|
|
|
|
|
|
static u_int64_t packet_index(struct crypto_context *c, struct rtp_header *rtp) {
|
|
|
|
|
u_int16_t seq;
|
|
|
|
|
u_int64_t index;
|
|
|
|
|
long long int diff;
|
|
|
|
|
|
|
|
|
|
seq = ntohs(rtp->seq_num);
|
|
|
|
|
/* rfc 3711 section 3.3.1 */
|
|
|
|
|
@ -146,24 +144,24 @@ static u_int64_t packet_index(struct crypto_context *c, struct rtp_header *rtp)
|
|
|
|
|
c->last_index = seq;
|
|
|
|
|
|
|
|
|
|
/* rfc 3711 appendix A, modified, and sections 3.3 and 3.3.1 */
|
|
|
|
|
index = (c->last_index & 0xffffffff0000ULL) | seq;
|
|
|
|
|
diff = index - c->last_index;
|
|
|
|
|
if (diff >= 0) {
|
|
|
|
|
if (diff < 0x8000)
|
|
|
|
|
c->last_index = index;
|
|
|
|
|
else if (index >= 0x10000)
|
|
|
|
|
index -= 0x10000;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (diff >= -0x8000)
|
|
|
|
|
;
|
|
|
|
|
else {
|
|
|
|
|
index += 0x10000;
|
|
|
|
|
c->last_index = index;
|
|
|
|
|
}
|
|
|
|
|
u_int16_t s_l = (c->last_index & 0x00000000ffffULL);
|
|
|
|
|
u_int32_t roc = (c->last_index & 0xffffffff0000ULL) >> 16;
|
|
|
|
|
u_int32_t v = 0;
|
|
|
|
|
|
|
|
|
|
if (s_l < 0x8000) {
|
|
|
|
|
if (((seq - s_l) > 0x8000) && roc > 0)
|
|
|
|
|
v = (roc - 1) % 0x10000;
|
|
|
|
|
else
|
|
|
|
|
v = roc;
|
|
|
|
|
} else {
|
|
|
|
|
if ((s_l - 0x8000) > seq)
|
|
|
|
|
v = (roc + 1) % 0x10000;
|
|
|
|
|
else
|
|
|
|
|
v = roc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return index;
|
|
|
|
|
c->last_index = (u_int64_t)(((v << 16) | seq) & 0xffffffffffffULL);
|
|
|
|
|
return c->last_index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void rtp_append_mki(str *s, struct crypto_context *c) {
|
|
|
|
|
@ -178,29 +176,59 @@ void rtp_append_mki(str *s, struct crypto_context *c) {
|
|
|
|
|
s->len += c->params.mki_len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int rtp_ssrc_check(const struct rtp_header *rtp, struct crypto_context *c) {
|
|
|
|
|
struct rtp_ssrc_entry *cur_ssrc;
|
|
|
|
|
|
|
|
|
|
/* check last known SSRC */
|
|
|
|
|
if (G_LIKELY(rtp->ssrc == c->ssrc))
|
|
|
|
|
return 0;
|
|
|
|
|
if (!c->ssrc) {
|
|
|
|
|
c->ssrc = rtp->ssrc;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* SSRC mismatch. stash away last know info */
|
|
|
|
|
ilog(LOG_DEBUG, "SSRC changed, updating SRTP crypto contexts");
|
|
|
|
|
if (G_UNLIKELY(!c->ssrc_hash))
|
|
|
|
|
c->ssrc_hash = create_ssrc_table();
|
|
|
|
|
|
|
|
|
|
// Find the entry for the last SSRC.
|
|
|
|
|
cur_ssrc = find_ssrc(c->ssrc, c->ssrc_hash);
|
|
|
|
|
// If it doesn't exist, create a new entry.
|
|
|
|
|
if (G_UNLIKELY(!cur_ssrc)) {
|
|
|
|
|
cur_ssrc = create_ssrc_entry(c->ssrc, c->last_index);
|
|
|
|
|
add_ssrc_entry(cur_ssrc, c->ssrc_hash);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
cur_ssrc->index = c->last_index;
|
|
|
|
|
|
|
|
|
|
// New SSRC, set the crypto context.
|
|
|
|
|
c->ssrc = rtp->ssrc;
|
|
|
|
|
cur_ssrc = find_ssrc(rtp->ssrc, c->ssrc_hash);
|
|
|
|
|
if (G_UNLIKELY(!cur_ssrc))
|
|
|
|
|
c->last_index = 0;
|
|
|
|
|
else
|
|
|
|
|
c->last_index = cur_ssrc->index;
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* rfc 3711, section 3.3 */
|
|
|
|
|
int rtp_avp2savp(str *s, struct crypto_context *c) {
|
|
|
|
|
struct rtp_header *rtp;
|
|
|
|
|
str payload, to_auth;
|
|
|
|
|
u_int64_t index;
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (rtp_payload(&rtp, &payload, s))
|
|
|
|
|
return -1;
|
|
|
|
|
if (check_session_keys(c))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
/* SSRC is part of the crypto context and ROC must be reset when it changes */
|
|
|
|
|
if (G_UNLIKELY(!c->ssrc))
|
|
|
|
|
c->ssrc = rtp->ssrc;
|
|
|
|
|
else if (G_UNLIKELY(c->ssrc != rtp->ssrc)) {
|
|
|
|
|
c->last_index = 0;
|
|
|
|
|
c->ssrc = rtp->ssrc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = rtp_ssrc_check(rtp, c);
|
|
|
|
|
index = packet_index(c, rtp);
|
|
|
|
|
|
|
|
|
|
/* rfc 3711 section 3.1 */
|
|
|
|
|
|
|
|
|
|
if (!c->params.session_params.unencrypted_srtp && crypto_encrypt_rtp(c, rtp, &payload, index))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
@ -213,7 +241,7 @@ int rtp_avp2savp(str *s, struct crypto_context *c) {
|
|
|
|
|
s->len += c->params.crypto_suite->srtp_auth_tag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* rfc 3711, section 3.3 */
|
|
|
|
|
@ -222,12 +250,14 @@ int rtp_savp2avp(str *s, struct crypto_context *c) {
|
|
|
|
|
u_int64_t index;
|
|
|
|
|
str payload, to_auth, to_decrypt, auth_tag;
|
|
|
|
|
char hmac[20];
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
if (rtp_payload(&rtp, &payload, s))
|
|
|
|
|
return -1;
|
|
|
|
|
if (check_session_keys(c))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
ret = rtp_ssrc_check(rtp, c);
|
|
|
|
|
index = packet_index(c, rtp);
|
|
|
|
|
if (srtp_payloads(&to_auth, &to_decrypt, &auth_tag, NULL,
|
|
|
|
|
c->params.session_params.unauthenticated_srtp ? 0 : c->params.crypto_suite->srtp_auth_tag,
|
|
|
|
|
@ -271,7 +301,7 @@ decrypt:
|
|
|
|
|
|
|
|
|
|
*s = to_auth;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
ilog(LOG_WARNING | LOG_FLAG_LIMIT, "Discarded invalid SRTP packet: authentication failed");
|
|
|
|
|
|