|
|
|
|
@ -49,6 +49,10 @@ static u_int64_t packet_index(struct ssrc_ctx *ssrc_ctx, struct rtp_header *rtp)
|
|
|
|
|
u_int16_t seq;
|
|
|
|
|
|
|
|
|
|
seq = ntohs(rtp->seq_num);
|
|
|
|
|
|
|
|
|
|
crypto_debug_init((seq & 0x1ff) == (ssrc_ctx->parent->h.ssrc & 0x1ff));
|
|
|
|
|
crypto_debug_printf("SSRC %" PRIx32 ", seq %" PRIu16, ssrc_ctx->parent->h.ssrc, seq);
|
|
|
|
|
|
|
|
|
|
/* rfc 3711 section 3.3.1 */
|
|
|
|
|
if (G_UNLIKELY(!ssrc_ctx->srtp_index))
|
|
|
|
|
ssrc_ctx->srtp_index = seq;
|
|
|
|
|
@ -58,6 +62,9 @@ static u_int64_t packet_index(struct ssrc_ctx *ssrc_ctx, struct rtp_header *rtp)
|
|
|
|
|
u_int32_t roc = (ssrc_ctx->srtp_index & 0xffffffff0000ULL) >> 16;
|
|
|
|
|
u_int32_t v = 0;
|
|
|
|
|
|
|
|
|
|
crypto_debug_printf(", prev seq %" PRIu64 ", s_l %" PRIu16 ", ROC %" PRIu32,
|
|
|
|
|
ssrc_ctx->srtp_index, s_l, roc);
|
|
|
|
|
|
|
|
|
|
if (s_l < 0x8000) {
|
|
|
|
|
if (((seq - s_l) > 0x8000) && roc > 0)
|
|
|
|
|
v = (roc - 1) % 0x10000;
|
|
|
|
|
@ -71,6 +78,9 @@ static u_int64_t packet_index(struct ssrc_ctx *ssrc_ctx, struct rtp_header *rtp)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ssrc_ctx->srtp_index = (u_int64_t)(((v << 16) | seq) & 0xffffffffffffULL);
|
|
|
|
|
|
|
|
|
|
crypto_debug_printf(", v %" PRIu32 ", ext seq %" PRIu64, v, ssrc_ctx->srtp_index);
|
|
|
|
|
|
|
|
|
|
return ssrc_ctx->srtp_index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -84,6 +94,9 @@ void rtp_append_mki(str *s, struct crypto_context *c) {
|
|
|
|
|
p = s->s + s->len;
|
|
|
|
|
memcpy(p, c->params.mki, c->params.mki_len);
|
|
|
|
|
s->len += c->params.mki_len;
|
|
|
|
|
|
|
|
|
|
crypto_debug_printf(", MKI: ");
|
|
|
|
|
crypto_debug_dump_raw(p, c->params.mki_len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* rfc 3711, section 3.3 */
|
|
|
|
|
@ -101,19 +114,29 @@ int rtp_avp2savp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
|
|
|
|
|
|
|
|
|
|
index = packet_index(ssrc_ctx, rtp);
|
|
|
|
|
|
|
|
|
|
crypto_debug_printf(", plain pl: ");
|
|
|
|
|
crypto_debug_dump(&payload);
|
|
|
|
|
|
|
|
|
|
/* rfc 3711 section 3.1 */
|
|
|
|
|
if (!c->params.session_params.unencrypted_srtp && crypto_encrypt_rtp(c, rtp, &payload, index))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
crypto_debug_printf(", enc pl: ");
|
|
|
|
|
crypto_debug_dump(&payload);
|
|
|
|
|
|
|
|
|
|
to_auth = *s;
|
|
|
|
|
|
|
|
|
|
rtp_append_mki(s, c);
|
|
|
|
|
|
|
|
|
|
if (!c->params.session_params.unauthenticated_srtp && c->params.crypto_suite->srtp_auth_tag) {
|
|
|
|
|
c->params.crypto_suite->hash_rtp(c, s->s + s->len, &to_auth, index);
|
|
|
|
|
crypto_debug_printf(", auth: ");
|
|
|
|
|
crypto_debug_dump_raw(s->s + s->len, c->params.crypto_suite->srtp_auth_tag);
|
|
|
|
|
s->len += c->params.crypto_suite->srtp_auth_tag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
crypto_debug_finish();
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -138,30 +161,51 @@ int rtp_savp2avp(str *s, struct crypto_context *c, struct ssrc_ctx *ssrc_ctx) {
|
|
|
|
|
s, &payload))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
crypto_debug_printf(", enc pl: ");
|
|
|
|
|
crypto_debug_dump(&to_decrypt);
|
|
|
|
|
|
|
|
|
|
if (!auth_tag.len)
|
|
|
|
|
goto decrypt;
|
|
|
|
|
|
|
|
|
|
/* authenticate */
|
|
|
|
|
assert(sizeof(hmac) >= auth_tag.len);
|
|
|
|
|
c->params.crypto_suite->hash_rtp(c, hmac, &to_auth, index);
|
|
|
|
|
|
|
|
|
|
crypto_debug_printf(", rcv hmac: ");
|
|
|
|
|
crypto_debug_dump(&auth_tag);
|
|
|
|
|
crypto_debug_printf(", calc hmac: ");
|
|
|
|
|
crypto_debug_dump_raw(hmac, auth_tag.len);
|
|
|
|
|
|
|
|
|
|
if (!str_memcmp(&auth_tag, hmac))
|
|
|
|
|
goto decrypt;
|
|
|
|
|
/* possible ROC mismatch, attempt to guess */
|
|
|
|
|
/* first, let's see if we missed a rollover */
|
|
|
|
|
index += 0x10000;
|
|
|
|
|
c->params.crypto_suite->hash_rtp(c, hmac, &to_auth, index);
|
|
|
|
|
|
|
|
|
|
crypto_debug_printf(", calc hmac 2: ");
|
|
|
|
|
crypto_debug_dump_raw(hmac, auth_tag.len);
|
|
|
|
|
|
|
|
|
|
if (!str_memcmp(&auth_tag, hmac))
|
|
|
|
|
goto decrypt_idx;
|
|
|
|
|
/* or maybe we did a rollover too many */
|
|
|
|
|
if (index >= 0x20000) {
|
|
|
|
|
index -= 0x20000;
|
|
|
|
|
c->params.crypto_suite->hash_rtp(c, hmac, &to_auth, index);
|
|
|
|
|
|
|
|
|
|
crypto_debug_printf(", calc hmac 3: ");
|
|
|
|
|
crypto_debug_dump_raw(hmac, auth_tag.len);
|
|
|
|
|
|
|
|
|
|
if (!str_memcmp(&auth_tag, hmac))
|
|
|
|
|
goto decrypt_idx;
|
|
|
|
|
}
|
|
|
|
|
/* last guess: reset ROC to zero */
|
|
|
|
|
index &= 0xffff;
|
|
|
|
|
c->params.crypto_suite->hash_rtp(c, hmac, &to_auth, index);
|
|
|
|
|
|
|
|
|
|
crypto_debug_printf(", calc hmac 4: ");
|
|
|
|
|
crypto_debug_dump_raw(hmac, auth_tag.len);
|
|
|
|
|
|
|
|
|
|
if (!str_memcmp(&auth_tag, hmac))
|
|
|
|
|
goto decrypt_idx;
|
|
|
|
|
goto error;
|
|
|
|
|
@ -172,8 +216,13 @@ decrypt:
|
|
|
|
|
if (!c->params.session_params.unencrypted_srtp && crypto_decrypt_rtp(c, rtp, &to_decrypt, index))
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
crypto_debug_printf(", dec pl: ");
|
|
|
|
|
crypto_debug_dump(&to_decrypt);
|
|
|
|
|
|
|
|
|
|
*s = to_auth;
|
|
|
|
|
|
|
|
|
|
crypto_debug_finish();
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
|
|