FFmpeg  4.0
srtp.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include <stdint.h>
20 #include <stdio.h>
21 #include <string.h>
22 
23 #include "libavformat/rtpdec.h"
24 #include "libavformat/srtp.h"
25 
26 static const char *aes128_80_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
27 
28 static const uint8_t rtp_aes128_80[] = {
29  // RTP header
30  0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
31  // encrypted payload
32  0x62, 0x69, 0x76, 0xca, 0xc5,
33  // HMAC
34  0xa1, 0xac, 0x1b, 0xb4, 0xa0, 0x1c, 0xd5, 0x49, 0x28, 0x99,
35 };
36 
37 static const uint8_t rtcp_aes128_80[] = {
38  // RTCP header
39  0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
40  // encrypted payload
41  0x8a, 0xac, 0xdc, 0xa5, 0x4c, 0xf6, 0x78, 0xa6, 0x62, 0x8f, 0x24, 0xda,
42  0x6c, 0x09, 0x3f, 0xa9, 0x28, 0x7a, 0xb5, 0x7f, 0x1f, 0x0f, 0xc9, 0x35,
43  // RTCP index
44  0x80, 0x00, 0x00, 0x03,
45  // HMAC
46  0xe9, 0x3b, 0xc0, 0x5c, 0x0c, 0x06, 0x9f, 0xab, 0xc0, 0xde,
47 };
48 
49 static const char *aes128_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
50 
51 static const uint8_t rtp_aes128_32[] = {
52  // RTP header
53  0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
54  // encrypted payload
55  0x62, 0x69, 0x76, 0xca, 0xc5,
56  // HMAC
57  0xa1, 0xac, 0x1b, 0xb4,
58 };
59 
60 static const uint8_t rtcp_aes128_32[] = {
61  // RTCP header
62  0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
63  // encrypted payload
64  0x35, 0xe9, 0xb5, 0xff, 0x0d, 0xd1, 0xde, 0x70, 0x74, 0x10, 0xaa, 0x1b,
65  0xb2, 0x8d, 0xf0, 0x20, 0x02, 0x99, 0x6b, 0x1b, 0x0b, 0xd0, 0x47, 0x34,
66  // RTCP index
67  0x80, 0x00, 0x00, 0x04,
68  // HMAC
69  0x5b, 0xd2, 0xa9, 0x9d,
70 };
71 
72 static const char *aes128_80_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
73 
74 static const uint8_t rtp_aes128_80_32[] = {
75  // RTP header
76  0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
77  // encrypted payload
78  0x62, 0x69, 0x76, 0xca, 0xc5,
79  // HMAC
80  0xa1, 0xac, 0x1b, 0xb4,
81 };
82 
83 static const uint8_t rtcp_aes128_80_32[] = {
84  // RTCP header
85  0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
86  // encrypted payload
87  0xd6, 0xae, 0xc1, 0x58, 0x63, 0x70, 0xc9, 0x88, 0x66, 0x26, 0x1c, 0x53,
88  0xff, 0x5d, 0x5d, 0x2b, 0x0f, 0x8c, 0x72, 0x3e, 0xc9, 0x1d, 0x43, 0xf9,
89  // RTCP index
90  0x80, 0x00, 0x00, 0x05,
91  // HMAC
92  0x09, 0x16, 0xb4, 0x27, 0x9a, 0xe9, 0x92, 0x26, 0x4e, 0x10,
93 };
94 
95 static void print_data(const uint8_t *buf, int len)
96 {
97  int i;
98  for (i = 0; i < len; i++)
99  printf("%02x", buf[i]);
100  printf("\n");
101 }
102 
103 static int test_decrypt(struct SRTPContext *srtp, const uint8_t *in, int len,
104  uint8_t *out)
105 {
106  memcpy(out, in, len);
107  if (!ff_srtp_decrypt(srtp, out, &len)) {
108  print_data(out, len);
109  return len;
110  } else
111  return -1;
112 }
113 
114 static void test_encrypt(const uint8_t *data, int in_len, const char *suite,
115  const char *key)
116 {
117  struct SRTPContext enc = { 0 }, dec = { 0 };
118  int len;
120  ff_srtp_set_crypto(&enc, suite, key);
121  ff_srtp_set_crypto(&dec, suite, key);
122  len = ff_srtp_encrypt(&enc, data, in_len, buf, sizeof(buf));
123  if (!ff_srtp_decrypt(&dec, buf, &len)) {
124  if (len == in_len && !memcmp(buf, data, len))
125  printf("Decrypted content matches input\n");
126  else
127  printf("Decrypted content doesn't match input\n");
128  } else {
129  printf("Decryption failed\n");
130  }
131  ff_srtp_free(&enc);
132  ff_srtp_free(&dec);
133 }
134 
135 int main(void)
136 {
137  static const char *aes128_80_suite = "AES_CM_128_HMAC_SHA1_80";
138  static const char *aes128_32_suite = "AES_CM_128_HMAC_SHA1_32";
139  static const char *aes128_80_32_suite = "SRTP_AES128_CM_HMAC_SHA1_32";
140  static const char *test_key = "abcdefghijklmnopqrstuvwxyz1234567890ABCD";
142  struct SRTPContext srtp = { 0 };
143  int len;
144  ff_srtp_set_crypto(&srtp, aes128_80_suite, aes128_80_key);
145  len = test_decrypt(&srtp, rtp_aes128_80, sizeof(rtp_aes128_80), buf);
146  test_encrypt(buf, len, aes128_80_suite, test_key);
147  test_encrypt(buf, len, aes128_32_suite, test_key);
148  test_encrypt(buf, len, aes128_80_32_suite, test_key);
149  test_decrypt(&srtp, rtcp_aes128_80, sizeof(rtcp_aes128_80), buf);
150  test_encrypt(buf, len, aes128_80_suite, test_key);
151  test_encrypt(buf, len, aes128_32_suite, test_key);
152  test_encrypt(buf, len, aes128_80_32_suite, test_key);
153  ff_srtp_free(&srtp);
154 
155  memset(&srtp, 0, sizeof(srtp)); // Clear the context
156  ff_srtp_set_crypto(&srtp, aes128_32_suite, aes128_32_key);
157  test_decrypt(&srtp, rtp_aes128_32, sizeof(rtp_aes128_32), buf);
158  test_decrypt(&srtp, rtcp_aes128_32, sizeof(rtcp_aes128_32), buf);
159  ff_srtp_free(&srtp);
160 
161  memset(&srtp, 0, sizeof(srtp)); // Clear the context
162  ff_srtp_set_crypto(&srtp, aes128_80_32_suite, aes128_80_32_key);
163  test_decrypt(&srtp, rtp_aes128_80_32, sizeof(rtp_aes128_80_32), buf);
164  test_decrypt(&srtp, rtcp_aes128_80_32, sizeof(rtcp_aes128_80_32), buf);
165  ff_srtp_free(&srtp);
166  return 0;
167 }
static const uint8_t rtp_aes128_80_32[]
Definition: srtp.c:74
int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len, uint8_t *out, int outlen)
Definition: srtp.c:238
#define RTP_MAX_PACKET_LENGTH
Definition: rtpdec.h:36
static const uint8_t rtcp_aes128_32[]
Definition: srtp.c:60
static const char * aes128_80_32_key
Definition: srtp.c:72
const char * key
static const char * aes128_80_key
Definition: srtp.c:26
void ff_srtp_free(struct SRTPContext *s)
Definition: srtp.c:31
uint8_t
const char data[16]
Definition: mxf.c:90
static const uint8_t rtcp_aes128_80_32[]
Definition: srtp.c:83
int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr)
Definition: srtp.c:126
int main(void)
Definition: srtp.c:135
static int test_decrypt(struct SRTPContext *srtp, const uint8_t *in, int len, uint8_t *out)
Definition: srtp.c:103
void * buf
Definition: avisynth_c.h:690
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
static void print_data(const uint8_t *buf, int len)
Definition: srtp.c:95
static const uint8_t rtp_aes128_80[]
Definition: srtp.c:28
static const uint8_t rtcp_aes128_80[]
Definition: srtp.c:37
static void test_encrypt(const uint8_t *data, int in_len, const char *suite, const char *key)
Definition: srtp.c:114
static const char * aes128_32_key
Definition: srtp.c:49
static const uint8_t rtp_aes128_32[]
Definition: srtp.c:51
static const uint8_t test_key[]
Definition: des.c:37
int len
int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite, const char *params)
Definition: srtp.c:65
FILE * out
Definition: movenc.c:54