#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "rtp.h"
+#include "rtpdec.h"
#include "srtp.h"
void ff_srtp_free(struct SRTPContext *s)
ff_srtp_free(s);
// RFC 4568
- if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
- s->hmac_size = 10;
+ if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80") ||
+ !strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_80")) {
+ s->rtp_hmac_size = s->rtcp_hmac_size = 10;
} else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
- s->hmac_size = 4;
+ s->rtp_hmac_size = s->rtcp_hmac_size = 4;
+ } else if (!strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_32")) {
+ // RFC 5764 section 4.1.2
+ s->rtp_hmac_size = 4;
+ s->rtcp_hmac_size = 10;
} else {
av_log(NULL, AV_LOG_WARNING, "SRTP Crypto suite %s not supported\n",
suite);
{
uint8_t iv[16] = { 0 }, hmac[20];
int len = *lenptr;
- int ext, seq_largest;
- uint32_t ssrc, roc;
+ int av_uninit(seq_largest);
+ uint32_t ssrc, av_uninit(roc);
uint64_t index;
- int rtcp;
+ int rtcp, hmac_size;
// TODO: Missing replay protection
- if (len < s->hmac_size)
+ if (len < 2)
return AVERROR_INVALIDDATA;
rtcp = RTP_PT_IS_RTCP(buf[1]);
+ hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
+
+ if (len < hmac_size)
+ return AVERROR_INVALIDDATA;
// Authentication HMAC
av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
// If MKI is used, this should exclude the MKI as well
- av_hmac_update(s->hmac, buf, len - s->hmac_size);
+ av_hmac_update(s->hmac, buf, len - hmac_size);
if (!rtcp) {
int seq = AV_RB16(buf + 2);
}
av_hmac_final(s->hmac, hmac, sizeof(hmac));
- if (memcmp(hmac, buf + len - s->hmac_size, s->hmac_size)) {
+ if (memcmp(hmac, buf + len - hmac_size, hmac_size)) {
av_log(NULL, AV_LOG_WARNING, "HMAC mismatch\n");
return AVERROR_INVALIDDATA;
}
- len -= s->hmac_size;
+ len -= hmac_size;
*lenptr = len;
if (len < 12)
if (!(srtcp_index & 0x80000000))
return 0;
} else {
+ int ext, csrc;
s->seq_initialized = 1;
s->seq_largest = seq_largest;
s->roc = roc;
+ csrc = buf[0] & 0x0f;
ext = buf[0] & 0x10;
ssrc = AV_RB32(buf + 8);
buf += 12;
len -= 12;
+ buf += 4 * csrc;
+ len -= 4 * csrc;
+ if (len < 0)
+ return AVERROR_INVALIDDATA;
+
if (ext) {
if (len < 4)
return AVERROR_INVALIDDATA;
uint8_t iv[16] = { 0 }, hmac[20];
uint64_t index;
uint32_t ssrc;
- int rtcp;
+ int rtcp, hmac_size, padding;
uint8_t *buf;
- if (len + 14 > outlen)
- return 0;
- if (len < 12)
+ if (len < 8)
+ return AVERROR_INVALIDDATA;
+
+ rtcp = RTP_PT_IS_RTCP(in[1]);
+ hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
+ padding = hmac_size;
+ if (rtcp)
+ padding += 4; // For the RTCP index
+
+ if (len + padding > outlen)
return 0;
memcpy(out, in, len);
buf = out;
- rtcp = RTP_PT_IS_RTCP(buf[1]);
-
if (rtcp) {
ssrc = AV_RB32(buf + 4);
index = s->rtcp_index++;
buf += 8;
len -= 8;
} else {
- int ext;
+ int ext, csrc;
int seq = AV_RB16(buf + 2);
+
+ if (len < 12)
+ return AVERROR_INVALIDDATA;
+
ssrc = AV_RB32(buf + 8);
if (seq < s->seq_largest)
s->seq_largest = seq;
index = seq + (((uint64_t)s->roc) << 16);
+ csrc = buf[0] & 0x0f;
ext = buf[0] & 0x10;
buf += 12;
len -= 12;
+ buf += 4 * csrc;
+ len -= 4 * csrc;
+ if (len < 0)
+ return AVERROR_INVALIDDATA;
+
if (ext) {
if (len < 4)
return AVERROR_INVALIDDATA;
}
av_hmac_final(s->hmac, hmac, sizeof(hmac));
- memcpy(buf + len, hmac, s->hmac_size);
- len += s->hmac_size;
+ memcpy(buf + len, hmac, hmac_size);
+ len += hmac_size;
return buf + len - out;
}