From e1d0b3d875a2ec713239eda2c3bd79249b9631c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 18 Jan 2013 12:01:33 +0200 Subject: [PATCH 1/2] srtp: Add support for a few DTLS-SRTP related crypto suites MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The main difference to the existing suites from RFC 4568 is that the version with a 32 bit HMAC still uses 80 bit HMAC for RTCP packets. Signed-off-by: Martin Storsjö --- libavformat/srtp.c | 32 +++++++++++++++++++++----------- libavformat/srtp.h | 2 +- libavformat/version.h | 2 +- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/libavformat/srtp.c b/libavformat/srtp.c index 21dafc2c4c..d90f8bc618 100644 --- a/libavformat/srtp.c +++ b/libavformat/srtp.c @@ -69,10 +69,15 @@ int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite, 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); @@ -124,19 +129,23 @@ int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr) int ext, 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); @@ -166,12 +175,12 @@ int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr) } 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) @@ -231,7 +240,7 @@ int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len, uint8_t iv[16] = { 0 }, hmac[20]; uint64_t index; uint32_t ssrc; - int rtcp; + int rtcp, hmac_size; uint8_t *buf; if (len + 14 > outlen) @@ -243,6 +252,7 @@ int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len, buf = out; rtcp = RTP_PT_IS_RTCP(buf[1]); + hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size; if (rtcp) { ssrc = AV_RB32(buf + 4); @@ -300,8 +310,8 @@ int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len, } 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; } diff --git a/libavformat/srtp.h b/libavformat/srtp.h index a1cb92d2ba..18ed177af5 100644 --- a/libavformat/srtp.h +++ b/libavformat/srtp.h @@ -30,7 +30,7 @@ struct AVHMAC; struct SRTPContext { struct AVAES *aes; struct AVHMAC *hmac; - int hmac_size; + int rtp_hmac_size, rtcp_hmac_size; uint8_t master_key[16]; uint8_t master_salt[14]; uint8_t rtp_key[16], rtcp_key[16]; diff --git a/libavformat/version.h b/libavformat/version.h index 89f1f6c603..c0d791138a 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 54 #define LIBAVFORMAT_VERSION_MINOR 21 -#define LIBAVFORMAT_VERSION_MICRO 0 +#define LIBAVFORMAT_VERSION_MICRO 1 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From a2a991b2ddf951454ffceb7bcedc9db93e26c610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 18 Jan 2013 12:33:02 +0200 Subject: [PATCH 2/2] srtp: Improve the minimum encryption buffer size check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This clarifies where the limit number comes from, and only requires exactly as much padding space as will be needed. Signed-off-by: Martin Storsjö --- libavformat/srtp.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/libavformat/srtp.c b/libavformat/srtp.c index d90f8bc618..192285fc98 100644 --- a/libavformat/srtp.c +++ b/libavformat/srtp.c @@ -240,20 +240,24 @@ int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len, uint8_t iv[16] = { 0 }, hmac[20]; uint64_t index; uint32_t ssrc; - int rtcp, hmac_size; + int rtcp, hmac_size, padding; uint8_t *buf; - if (len + 14 > outlen) - return 0; if (len < 12) return 0; + 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]); - hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size; - if (rtcp) { ssrc = AV_RB32(buf + 4); index = s->rtcp_index++;