2 * SRTP encryption/decryption
3 * Copyright (c) 2012 Martin Storsjo
5 * This file is part of FFmpeg.
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.
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.
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
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"
30 void ff_srtp_free(struct SRTPContext *s)
36 av_hmac_free(s->hmac);
40 static void encrypt_counter(struct AVAES *aes, uint8_t *iv, uint8_t *outbuf,
44 for (i = 0, outpos = 0; outpos < outlen; i++) {
45 uint8_t keystream[16];
47 av_aes_crypt(aes, keystream, iv, 1, NULL, 0);
48 for (j = 0; j < 16 && outpos < outlen; j++, outpos++)
49 outbuf[outpos] ^= keystream[j];
53 static void derive_key(struct AVAES *aes, const uint8_t *salt, int label,
54 uint8_t *out, int outlen)
56 uint8_t input[16] = { 0 };
57 memcpy(input, salt, 14);
58 // Key derivation rate assumed to be zero
59 input[14 - 7] ^= label;
60 memset(out, 0, outlen);
61 encrypt_counter(aes, input, out, outlen);
64 int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite,
72 if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
74 } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
77 av_log(NULL, AV_LOG_WARNING, "SRTP Crypto suite %s not supported\n",
79 return AVERROR(EINVAL);
81 if (av_base64_decode(buf, params, sizeof(buf)) != sizeof(buf)) {
82 av_log(NULL, AV_LOG_WARNING, "Incorrect amount of SRTP params\n");
83 return AVERROR(EINVAL);
85 // MKI and lifetime not handled yet
86 s->aes = av_aes_alloc();
87 s->hmac = av_hmac_alloc(AV_HMAC_SHA1);
88 if (!s->aes || !s->hmac)
89 return AVERROR(ENOMEM);
90 memcpy(s->master_key, buf, 16);
91 memcpy(s->master_salt, buf + 16, 14);
94 av_aes_init(s->aes, s->master_key, 128, 0);
96 derive_key(s->aes, s->master_salt, 0x00, s->rtp_key, sizeof(s->rtp_key));
97 derive_key(s->aes, s->master_salt, 0x02, s->rtp_salt, sizeof(s->rtp_salt));
98 derive_key(s->aes, s->master_salt, 0x01, s->rtp_auth, sizeof(s->rtp_auth));
100 derive_key(s->aes, s->master_salt, 0x03, s->rtcp_key, sizeof(s->rtcp_key));
101 derive_key(s->aes, s->master_salt, 0x05, s->rtcp_salt, sizeof(s->rtcp_salt));
102 derive_key(s->aes, s->master_salt, 0x04, s->rtcp_auth, sizeof(s->rtcp_auth));
106 static void create_iv(uint8_t *iv, const uint8_t *salt, uint64_t index,
112 AV_WB32(&iv[4], ssrc);
113 AV_WB64(indexbuf, index);
114 for (i = 0; i < 8; i++) // index << 16
115 iv[6 + i] ^= indexbuf[i];
116 for (i = 0; i < 14; i++)
120 int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr)
122 uint8_t iv[16] = { 0 }, hmac[20];
124 int ext, av_uninit(seq_largest);
125 uint32_t ssrc, av_uninit(roc);
129 // TODO: Missing replay protection
131 if (len < s->hmac_size)
132 return AVERROR_INVALIDDATA;
134 rtcp = RTP_PT_IS_RTCP(buf[1]);
136 // Authentication HMAC
137 av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
138 // If MKI is used, this should exclude the MKI as well
139 av_hmac_update(s->hmac, buf, len - s->hmac_size);
142 int seq = AV_RB16(buf + 2);
146 // RFC 3711 section 3.3.1, appendix A
147 seq_largest = s->seq_initialized ? s->seq_largest : seq;
149 if (seq_largest < 32768) {
150 if (seq - seq_largest > 32768)
153 if (seq_largest - 32768 > seq)
157 seq_largest = FFMAX(seq_largest, seq);
158 } else if (v == roc + 1) {
162 index = seq + (((uint64_t)v) << 16);
164 AV_WB32(rocbuf, roc);
165 av_hmac_update(s->hmac, rocbuf, 4);
168 av_hmac_final(s->hmac, hmac, sizeof(hmac));
169 if (memcmp(hmac, buf + len - s->hmac_size, s->hmac_size)) {
170 av_log(NULL, AV_LOG_WARNING, "HMAC mismatch\n");
171 return AVERROR_INVALIDDATA;
178 return AVERROR_INVALIDDATA;
181 uint32_t srtcp_index = AV_RB32(buf + len - 4);
185 ssrc = AV_RB32(buf + 4);
186 index = srtcp_index & 0x7fffffff;
190 if (!(srtcp_index & 0x80000000))
193 s->seq_initialized = 1;
194 s->seq_largest = seq_largest;
198 ssrc = AV_RB32(buf + 8);
205 return AVERROR_INVALIDDATA;
206 ext = (AV_RB16(buf + 2) + 1) * 4;
208 return AVERROR_INVALIDDATA;
214 create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
215 av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
216 encrypt_counter(s->aes, iv, buf, len);
221 int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len,
222 uint8_t *out, int outlen)
224 uint8_t iv[16] = { 0 }, hmac[20];
230 if (len + 14 > outlen)
235 memcpy(out, in, len);
238 rtcp = RTP_PT_IS_RTCP(buf[1]);
241 ssrc = AV_RB32(buf + 4);
242 index = s->rtcp_index++;
248 int seq = AV_RB16(buf + 2);
249 ssrc = AV_RB32(buf + 8);
251 if (seq < s->seq_largest)
253 s->seq_largest = seq;
254 index = seq + (((uint64_t)s->roc) << 16);
263 return AVERROR_INVALIDDATA;
264 ext = (AV_RB16(buf + 2) + 1) * 4;
266 return AVERROR_INVALIDDATA;
272 create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
273 av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
274 encrypt_counter(s->aes, iv, buf, len);
277 AV_WB32(buf + len, 0x80000000 | index);
281 av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
282 av_hmac_update(s->hmac, out, buf + len - out);
285 AV_WB32(rocbuf, s->roc);
286 av_hmac_update(s->hmac, rocbuf, 4);
288 av_hmac_final(s->hmac, hmac, sizeof(hmac));
290 memcpy(buf + len, hmac, s->hmac_size);
292 return buf + len - out;
298 static const char *aes128_80_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
300 static const uint8_t rtp_aes128_80[] = {
302 0x80, 0xe0, 0x12, 0x34,
303 0x12, 0x34, 0x56, 0x78,
304 0x12, 0x34, 0x56, 0x78,
306 0x62, 0x69, 0x76, 0xca, 0xc5,
308 0xa1, 0xac, 0x1b, 0xb4, 0xa0, 0x1c, 0xd5, 0x49, 0x28, 0x99,
311 static const uint8_t rtcp_aes128_80[] = {
313 0x81, 0xc9, 0x00, 0x07,
314 0x12, 0x34, 0x56, 0x78,
316 0x8a, 0xac, 0xdc, 0xa5,
317 0x4c, 0xf6, 0x78, 0xa6,
318 0x62, 0x8f, 0x24, 0xda,
319 0x6c, 0x09, 0x3f, 0xa9,
320 0x28, 0x7a, 0xb5, 0x7f,
321 0x1f, 0x0f, 0xc9, 0x35,
323 0x80, 0x00, 0x00, 0x03,
325 0xe9, 0x3b, 0xc0, 0x5c, 0x0c, 0x06, 0x9f, 0xab, 0xc0, 0xde,
328 static const char *aes128_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
330 static const uint8_t rtp_aes128_32[] = {
332 0x80, 0xe0, 0x12, 0x34,
333 0x12, 0x34, 0x56, 0x78,
334 0x12, 0x34, 0x56, 0x78,
336 0x62, 0x69, 0x76, 0xca, 0xc5,
338 0xa1, 0xac, 0x1b, 0xb4,
341 static const uint8_t rtcp_aes128_32[] = {
343 0x81, 0xc9, 0x00, 0x07,
344 0x12, 0x34, 0x56, 0x78,
346 0x35, 0xe9, 0xb5, 0xff,
347 0x0d, 0xd1, 0xde, 0x70,
348 0x74, 0x10, 0xaa, 0x1b,
349 0xb2, 0x8d, 0xf0, 0x20,
350 0x02, 0x99, 0x6b, 0x1b,
351 0x0b, 0xd0, 0x47, 0x34,
353 0x80, 0x00, 0x00, 0x04,
355 0x5b, 0xd2, 0xa9, 0x9d,
358 static void print_data(const uint8_t *buf, int len)
361 for (i = 0; i < len; i++)
362 printf("%02x", buf[i]);
366 static int test_decrypt(struct SRTPContext *srtp, const uint8_t *in, int len,
369 memcpy(out, in, len);
370 if (!ff_srtp_decrypt(srtp, out, &len)) {
371 print_data(out, len);
377 static void test_encrypt(const uint8_t *data, int in_len, const char *suite,
380 struct SRTPContext enc = { 0 }, dec = { 0 };
383 ff_srtp_set_crypto(&enc, suite, key);
384 ff_srtp_set_crypto(&dec, suite, key);
385 len = ff_srtp_encrypt(&enc, data, in_len, buf, sizeof(buf));
386 if (!ff_srtp_decrypt(&dec, buf, &len)) {
387 if (len == in_len && !memcmp(buf, data, len))
388 printf("Decrypted content matches input\n");
390 printf("Decrypted content doesn't match input\n");
392 printf("Decryption failed\n");
400 static const char *aes128_80_suite = "AES_CM_128_HMAC_SHA1_80";
401 static const char *aes128_32_suite = "AES_CM_128_HMAC_SHA1_32";
402 static const char *test_key = "abcdefghijklmnopqrstuvwxyz1234567890ABCD";
404 struct SRTPContext srtp = { 0 };
406 ff_srtp_set_crypto(&srtp, aes128_80_suite, aes128_80_key);
407 len = test_decrypt(&srtp, rtp_aes128_80, sizeof(rtp_aes128_80), buf);
408 test_encrypt(buf, len, aes128_80_suite, test_key);
409 test_encrypt(buf, len, aes128_32_suite, test_key);
410 test_decrypt(&srtp, rtcp_aes128_80, sizeof(rtcp_aes128_80), buf);
411 test_encrypt(buf, len, aes128_80_suite, test_key);
412 test_encrypt(buf, len, aes128_32_suite, test_key);
415 memset(&srtp, 0, sizeof(srtp)); // Clear the context
416 ff_srtp_set_crypto(&srtp, aes128_32_suite, aes128_32_key);
417 test_decrypt(&srtp, rtp_aes128_32, sizeof(rtp_aes128_32), buf);
418 test_decrypt(&srtp, rtcp_aes128_32, sizeof(rtcp_aes128_32), buf);