FFmpeg
srtp.c
Go to the documentation of this file.
1 /*
2  * SRTP encryption/decryption
3  * Copyright (c) 2012 Martin Storsjo
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/base64.h"
23 #include "libavutil/aes.h"
24 #include "libavutil/hmac.h"
25 #include "libavutil/intreadwrite.h"
26 #include "libavutil/log.h"
27 #include "libavutil/mem.h"
28 #include "rtp.h"
29 #include "rtpdec.h"
30 #include "srtp.h"
31 
32 void ff_srtp_free(struct SRTPContext *s)
33 {
34  if (!s)
35  return;
36  av_freep(&s->aes);
37  if (s->hmac)
38  av_hmac_free(s->hmac);
39  s->hmac = NULL;
40 }
41 
42 static void encrypt_counter(struct AVAES *aes, uint8_t *iv, uint8_t *outbuf,
43  int outlen)
44 {
45  int i, j, outpos;
46  for (i = 0, outpos = 0; outpos < outlen; i++) {
47  uint8_t keystream[16];
48  AV_WB16(&iv[14], i);
49  av_aes_crypt(aes, keystream, iv, 1, NULL, 0);
50  for (j = 0; j < 16 && outpos < outlen; j++, outpos++)
51  outbuf[outpos] ^= keystream[j];
52  }
53 }
54 
55 static void derive_key(struct AVAES *aes, const uint8_t *salt, int label,
56  uint8_t *out, int outlen)
57 {
58  uint8_t input[16] = { 0 };
59  memcpy(input, salt, 14);
60  // Key derivation rate assumed to be zero
61  input[14 - 7] ^= label;
62  memset(out, 0, outlen);
63  encrypt_counter(aes, input, out, outlen);
64 }
65 
66 int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite,
67  const char *params)
68 {
69  uint8_t buf[30];
70 
71  ff_srtp_free(s);
72 
73  // RFC 4568
74  if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80") ||
75  !strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_80")) {
76  s->rtp_hmac_size = s->rtcp_hmac_size = 10;
77  } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
78  s->rtp_hmac_size = s->rtcp_hmac_size = 4;
79  } else if (!strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_32")) {
80  // RFC 5764 section 4.1.2
81  s->rtp_hmac_size = 4;
82  s->rtcp_hmac_size = 10;
83  } else {
84  av_log(NULL, AV_LOG_WARNING, "SRTP Crypto suite %s not supported\n",
85  suite);
86  return AVERROR(EINVAL);
87  }
88  if (av_base64_decode(buf, params, sizeof(buf)) != sizeof(buf)) {
89  av_log(NULL, AV_LOG_WARNING, "Incorrect amount of SRTP params\n");
90  return AVERROR(EINVAL);
91  }
92  // MKI and lifetime not handled yet
93  s->aes = av_aes_alloc();
94  s->hmac = av_hmac_alloc(AV_HMAC_SHA1);
95  if (!s->aes || !s->hmac)
96  return AVERROR(ENOMEM);
97  memcpy(s->master_key, buf, 16);
98  memcpy(s->master_salt, buf + 16, 14);
99 
100  // RFC 3711
101  av_aes_init(s->aes, s->master_key, 128, 0);
102 
103  derive_key(s->aes, s->master_salt, 0x00, s->rtp_key, sizeof(s->rtp_key));
104  derive_key(s->aes, s->master_salt, 0x02, s->rtp_salt, sizeof(s->rtp_salt));
105  derive_key(s->aes, s->master_salt, 0x01, s->rtp_auth, sizeof(s->rtp_auth));
106 
107  derive_key(s->aes, s->master_salt, 0x03, s->rtcp_key, sizeof(s->rtcp_key));
108  derive_key(s->aes, s->master_salt, 0x05, s->rtcp_salt, sizeof(s->rtcp_salt));
109  derive_key(s->aes, s->master_salt, 0x04, s->rtcp_auth, sizeof(s->rtcp_auth));
110  return 0;
111 }
112 
113 static void create_iv(uint8_t *iv, const uint8_t *salt, uint64_t index,
114  uint32_t ssrc)
115 {
116  uint8_t indexbuf[8];
117  int i;
118  memset(iv, 0, 16);
119  AV_WB32(&iv[4], ssrc);
120  AV_WB64(indexbuf, index);
121  for (i = 0; i < 8; i++) // index << 16
122  iv[6 + i] ^= indexbuf[i];
123  for (i = 0; i < 14; i++)
124  iv[i] ^= salt[i];
125 }
126 
127 int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr)
128 {
129  uint8_t iv[16] = { 0 }, hmac[20];
130  int len = *lenptr;
131  int av_uninit(seq_largest);
132  uint32_t ssrc, av_uninit(roc);
133  uint64_t index;
134  int rtcp, hmac_size;
135 
136  // TODO: Missing replay protection
137 
138  if (len < 2)
139  return AVERROR_INVALIDDATA;
140 
141  rtcp = RTP_PT_IS_RTCP(buf[1]);
142  hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
143 
144  if (len < hmac_size)
145  return AVERROR_INVALIDDATA;
146 
147  // Authentication HMAC
148  av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
149  // If MKI is used, this should exclude the MKI as well
150  av_hmac_update(s->hmac, buf, len - hmac_size);
151 
152  if (!rtcp) {
153  int seq = AV_RB16(buf + 2);
154  uint32_t v;
155  uint8_t rocbuf[4];
156 
157  // RFC 3711 section 3.3.1, appendix A
158  seq_largest = s->seq_initialized ? s->seq_largest : seq;
159  v = roc = s->roc;
160  if (seq_largest < 32768) {
161  if (seq - seq_largest > 32768)
162  v = roc - 1;
163  } else {
164  if (seq_largest - 32768 > seq)
165  v = roc + 1;
166  }
167  if (v == roc) {
168  seq_largest = FFMAX(seq_largest, seq);
169  } else if (v == roc + 1) {
170  seq_largest = seq;
171  roc = v;
172  }
173  index = seq + (((uint64_t)v) << 16);
174 
175  AV_WB32(rocbuf, roc);
176  av_hmac_update(s->hmac, rocbuf, 4);
177  }
178 
179  av_hmac_final(s->hmac, hmac, sizeof(hmac));
180  if (memcmp(hmac, buf + len - hmac_size, hmac_size)) {
181  av_log(NULL, AV_LOG_WARNING, "HMAC mismatch\n");
182  return AVERROR_INVALIDDATA;
183  }
184 
185  len -= hmac_size;
186  *lenptr = len;
187 
188  if (len < 12)
189  return AVERROR_INVALIDDATA;
190 
191  if (rtcp) {
192  uint32_t srtcp_index = AV_RB32(buf + len - 4);
193  len -= 4;
194  *lenptr = len;
195 
196  ssrc = AV_RB32(buf + 4);
197  index = srtcp_index & 0x7fffffff;
198 
199  buf += 8;
200  len -= 8;
201  if (!(srtcp_index & 0x80000000))
202  return 0;
203  } else {
204  int ext, csrc;
205  s->seq_initialized = 1;
206  s->seq_largest = seq_largest;
207  s->roc = roc;
208 
209  csrc = buf[0] & 0x0f;
210  ext = buf[0] & 0x10;
211  ssrc = AV_RB32(buf + 8);
212 
213  buf += 12;
214  len -= 12;
215 
216  buf += 4 * csrc;
217  len -= 4 * csrc;
218  if (len < 0)
219  return AVERROR_INVALIDDATA;
220 
221  if (ext) {
222  if (len < 4)
223  return AVERROR_INVALIDDATA;
224  ext = (AV_RB16(buf + 2) + 1) * 4;
225  if (len < ext)
226  return AVERROR_INVALIDDATA;
227  len -= ext;
228  buf += ext;
229  }
230  }
231 
232  create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
233  av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
234  encrypt_counter(s->aes, iv, buf, len);
235 
236  return 0;
237 }
238 
239 int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len,
240  uint8_t *out, int outlen)
241 {
242  uint8_t iv[16] = { 0 }, hmac[20];
243  uint64_t index;
244  uint32_t ssrc;
245  int rtcp, hmac_size, padding;
246  uint8_t *buf;
247 
248  if (len < 8)
249  return AVERROR_INVALIDDATA;
250 
251  rtcp = RTP_PT_IS_RTCP(in[1]);
252  hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
253  padding = hmac_size;
254  if (rtcp)
255  padding += 4; // For the RTCP index
256 
257  if (len + padding > outlen)
258  return 0;
259 
260  memcpy(out, in, len);
261  buf = out;
262 
263  if (rtcp) {
264  ssrc = AV_RB32(buf + 4);
265  index = s->rtcp_index++;
266 
267  buf += 8;
268  len -= 8;
269  } else {
270  int ext, csrc;
271  int seq = AV_RB16(buf + 2);
272 
273  if (len < 12)
274  return AVERROR_INVALIDDATA;
275 
276  ssrc = AV_RB32(buf + 8);
277 
278  if (seq < s->seq_largest)
279  s->roc++;
280  s->seq_largest = seq;
281  index = seq + (((uint64_t)s->roc) << 16);
282 
283  csrc = buf[0] & 0x0f;
284  ext = buf[0] & 0x10;
285 
286  buf += 12;
287  len -= 12;
288 
289  buf += 4 * csrc;
290  len -= 4 * csrc;
291  if (len < 0)
292  return AVERROR_INVALIDDATA;
293 
294  if (ext) {
295  if (len < 4)
296  return AVERROR_INVALIDDATA;
297  ext = (AV_RB16(buf + 2) + 1) * 4;
298  if (len < ext)
299  return AVERROR_INVALIDDATA;
300  len -= ext;
301  buf += ext;
302  }
303  }
304 
305  create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
306  av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
307  encrypt_counter(s->aes, iv, buf, len);
308 
309  if (rtcp) {
310  AV_WB32(buf + len, 0x80000000 | index);
311  len += 4;
312  }
313 
314  av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
315  av_hmac_update(s->hmac, out, buf + len - out);
316  if (!rtcp) {
317  uint8_t rocbuf[4];
318  AV_WB32(rocbuf, s->roc);
319  av_hmac_update(s->hmac, rocbuf, 4);
320  }
321  av_hmac_final(s->hmac, hmac, sizeof(hmac));
322 
323  memcpy(buf + len, hmac, hmac_size);
324  len += hmac_size;
325  return buf + len - out;
326 }
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
av_aes_init
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:201
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
out
FILE * out
Definition: movenc.c:55
srtp.h
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
SRTPContext
Definition: srtp.h:30
av_hmac_final
int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
Finish hashing and output the HMAC digest.
Definition: hmac.c:167
AV_WB64
#define AV_WB64(p, v)
Definition: intreadwrite.h:431
ff_srtp_decrypt
int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr)
Definition: srtp.c:127
ff_srtp_encrypt
int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len, uint8_t *out, int outlen)
Definition: srtp.c:239
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
aes.h
NULL
#define NULL
Definition: coverity.c:32
AV_WB16
#define AV_WB16(p, v)
Definition: intreadwrite.h:403
av_aes_crypt
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:169
av_aes_alloc
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:35
av_hmac_update
void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
Hash data with the HMAC.
Definition: hmac.c:162
av_base64_decode
int av_base64_decode(uint8_t *out, const char *in_str, int out_size)
Decode a base64-encoded string.
Definition: base64.c:81
base64.h
index
int index
Definition: gxfenc.c:90
rtpdec.h
AV_HMAC_SHA1
@ AV_HMAC_SHA1
Definition: hmac.h:34
AV_WB32
#define AV_WB32(p, v)
Definition: intreadwrite.h:417
suite
FFmpeg currently uses a custom build this text attempts to document some of its obscure features and options Makefile the full command issued by make and its output will be shown on the screen DBG Preprocess x86 external assembler files to a dbg asm file in the object which then gets compiled Helps in developing those assembler files DESTDIR Destination directory for the install useful to prepare packages or install FFmpeg in cross environments GEN Set to ‘1’ to generate the missing or mismatched references Makefile builds all the libraries and the executables fate Run the fate test suite
Definition: build_system.txt:28
RTP_PT_IS_RTCP
#define RTP_PT_IS_RTCP(x)
Definition: rtp.h:112
AV_RB32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_RB32
Definition: bytestream.h:96
ff_srtp_free
void ff_srtp_free(struct SRTPContext *s)
Definition: srtp.c:32
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
rtp.h
av_hmac_alloc
AVHMAC * av_hmac_alloc(enum AVHMACType type)
Allocate an AVHMAC context.
Definition: hmac.c:68
av_hmac_free
void av_hmac_free(AVHMAC *c)
Free an AVHMAC context.
Definition: hmac.c:133
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
av_hmac_init
void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
Initialize an AVHMAC context with an authentication key.
Definition: hmac.c:141
len
int len
Definition: vorbis_enc_data.h:426
ff_srtp_set_crypto
int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite, const char *params)
Definition: srtp.c:66
av_uninit
#define av_uninit(x)
Definition: attributes.h:154
AVAES
Definition: aes_internal.h:34
mem.h
create_iv
static void create_iv(uint8_t *iv, const uint8_t *salt, uint64_t index, uint32_t ssrc)
Definition: srtp.c:113
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
encrypt_counter
static void encrypt_counter(struct AVAES *aes, uint8_t *iv, uint8_t *outbuf, int outlen)
Definition: srtp.c:42
derive_key
static void derive_key(struct AVAES *aes, const uint8_t *salt, int label, uint8_t *out, int outlen)
Definition: srtp.c:55
hmac.h
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98