annotate ffmpeg/libavformat/srtp.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * SRTP encryption/decryption
yading@11 3 * Copyright (c) 2012 Martin Storsjo
yading@11 4 *
yading@11 5 * This file is part of FFmpeg.
yading@11 6 *
yading@11 7 * FFmpeg is free software; you can redistribute it and/or
yading@11 8 * modify it under the terms of the GNU Lesser General Public
yading@11 9 * License as published by the Free Software Foundation; either
yading@11 10 * version 2.1 of the License, or (at your option) any later version.
yading@11 11 *
yading@11 12 * FFmpeg is distributed in the hope that it will be useful,
yading@11 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 15 * Lesser General Public License for more details.
yading@11 16 *
yading@11 17 * You should have received a copy of the GNU Lesser General Public
yading@11 18 * License along with FFmpeg; if not, write to the Free Software
yading@11 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 20 */
yading@11 21
yading@11 22 #include "libavutil/base64.h"
yading@11 23 #include "libavutil/aes.h"
yading@11 24 #include "libavutil/hmac.h"
yading@11 25 #include "libavutil/intreadwrite.h"
yading@11 26 #include "libavutil/log.h"
yading@11 27 #include "rtp.h"
yading@11 28 #include "rtpdec.h"
yading@11 29 #include "srtp.h"
yading@11 30
yading@11 31 void ff_srtp_free(struct SRTPContext *s)
yading@11 32 {
yading@11 33 if (!s)
yading@11 34 return;
yading@11 35 av_freep(&s->aes);
yading@11 36 if (s->hmac)
yading@11 37 av_hmac_free(s->hmac);
yading@11 38 s->hmac = NULL;
yading@11 39 }
yading@11 40
yading@11 41 static void encrypt_counter(struct AVAES *aes, uint8_t *iv, uint8_t *outbuf,
yading@11 42 int outlen)
yading@11 43 {
yading@11 44 int i, j, outpos;
yading@11 45 for (i = 0, outpos = 0; outpos < outlen; i++) {
yading@11 46 uint8_t keystream[16];
yading@11 47 AV_WB16(&iv[14], i);
yading@11 48 av_aes_crypt(aes, keystream, iv, 1, NULL, 0);
yading@11 49 for (j = 0; j < 16 && outpos < outlen; j++, outpos++)
yading@11 50 outbuf[outpos] ^= keystream[j];
yading@11 51 }
yading@11 52 }
yading@11 53
yading@11 54 static void derive_key(struct AVAES *aes, const uint8_t *salt, int label,
yading@11 55 uint8_t *out, int outlen)
yading@11 56 {
yading@11 57 uint8_t input[16] = { 0 };
yading@11 58 memcpy(input, salt, 14);
yading@11 59 // Key derivation rate assumed to be zero
yading@11 60 input[14 - 7] ^= label;
yading@11 61 memset(out, 0, outlen);
yading@11 62 encrypt_counter(aes, input, out, outlen);
yading@11 63 }
yading@11 64
yading@11 65 int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite,
yading@11 66 const char *params)
yading@11 67 {
yading@11 68 uint8_t buf[30];
yading@11 69
yading@11 70 ff_srtp_free(s);
yading@11 71
yading@11 72 // RFC 4568
yading@11 73 if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80") ||
yading@11 74 !strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_80")) {
yading@11 75 s->rtp_hmac_size = s->rtcp_hmac_size = 10;
yading@11 76 } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
yading@11 77 s->rtp_hmac_size = s->rtcp_hmac_size = 4;
yading@11 78 } else if (!strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_32")) {
yading@11 79 // RFC 5764 section 4.1.2
yading@11 80 s->rtp_hmac_size = 4;
yading@11 81 s->rtcp_hmac_size = 10;
yading@11 82 } else {
yading@11 83 av_log(NULL, AV_LOG_WARNING, "SRTP Crypto suite %s not supported\n",
yading@11 84 suite);
yading@11 85 return AVERROR(EINVAL);
yading@11 86 }
yading@11 87 if (av_base64_decode(buf, params, sizeof(buf)) != sizeof(buf)) {
yading@11 88 av_log(NULL, AV_LOG_WARNING, "Incorrect amount of SRTP params\n");
yading@11 89 return AVERROR(EINVAL);
yading@11 90 }
yading@11 91 // MKI and lifetime not handled yet
yading@11 92 s->aes = av_aes_alloc();
yading@11 93 s->hmac = av_hmac_alloc(AV_HMAC_SHA1);
yading@11 94 if (!s->aes || !s->hmac)
yading@11 95 return AVERROR(ENOMEM);
yading@11 96 memcpy(s->master_key, buf, 16);
yading@11 97 memcpy(s->master_salt, buf + 16, 14);
yading@11 98
yading@11 99 // RFC 3711
yading@11 100 av_aes_init(s->aes, s->master_key, 128, 0);
yading@11 101
yading@11 102 derive_key(s->aes, s->master_salt, 0x00, s->rtp_key, sizeof(s->rtp_key));
yading@11 103 derive_key(s->aes, s->master_salt, 0x02, s->rtp_salt, sizeof(s->rtp_salt));
yading@11 104 derive_key(s->aes, s->master_salt, 0x01, s->rtp_auth, sizeof(s->rtp_auth));
yading@11 105
yading@11 106 derive_key(s->aes, s->master_salt, 0x03, s->rtcp_key, sizeof(s->rtcp_key));
yading@11 107 derive_key(s->aes, s->master_salt, 0x05, s->rtcp_salt, sizeof(s->rtcp_salt));
yading@11 108 derive_key(s->aes, s->master_salt, 0x04, s->rtcp_auth, sizeof(s->rtcp_auth));
yading@11 109 return 0;
yading@11 110 }
yading@11 111
yading@11 112 static void create_iv(uint8_t *iv, const uint8_t *salt, uint64_t index,
yading@11 113 uint32_t ssrc)
yading@11 114 {
yading@11 115 uint8_t indexbuf[8];
yading@11 116 int i;
yading@11 117 memset(iv, 0, 16);
yading@11 118 AV_WB32(&iv[4], ssrc);
yading@11 119 AV_WB64(indexbuf, index);
yading@11 120 for (i = 0; i < 8; i++) // index << 16
yading@11 121 iv[6 + i] ^= indexbuf[i];
yading@11 122 for (i = 0; i < 14; i++)
yading@11 123 iv[i] ^= salt[i];
yading@11 124 }
yading@11 125
yading@11 126 int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr)
yading@11 127 {
yading@11 128 uint8_t iv[16] = { 0 }, hmac[20];
yading@11 129 int len = *lenptr;
yading@11 130 int av_uninit(seq_largest);
yading@11 131 uint32_t ssrc, av_uninit(roc);
yading@11 132 uint64_t index;
yading@11 133 int rtcp, hmac_size;
yading@11 134
yading@11 135 // TODO: Missing replay protection
yading@11 136
yading@11 137 if (len < 2)
yading@11 138 return AVERROR_INVALIDDATA;
yading@11 139
yading@11 140 rtcp = RTP_PT_IS_RTCP(buf[1]);
yading@11 141 hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
yading@11 142
yading@11 143 if (len < hmac_size)
yading@11 144 return AVERROR_INVALIDDATA;
yading@11 145
yading@11 146 // Authentication HMAC
yading@11 147 av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
yading@11 148 // If MKI is used, this should exclude the MKI as well
yading@11 149 av_hmac_update(s->hmac, buf, len - hmac_size);
yading@11 150
yading@11 151 if (!rtcp) {
yading@11 152 int seq = AV_RB16(buf + 2);
yading@11 153 uint32_t v;
yading@11 154 uint8_t rocbuf[4];
yading@11 155
yading@11 156 // RFC 3711 section 3.3.1, appendix A
yading@11 157 seq_largest = s->seq_initialized ? s->seq_largest : seq;
yading@11 158 v = roc = s->roc;
yading@11 159 if (seq_largest < 32768) {
yading@11 160 if (seq - seq_largest > 32768)
yading@11 161 v = roc - 1;
yading@11 162 } else {
yading@11 163 if (seq_largest - 32768 > seq)
yading@11 164 v = roc + 1;
yading@11 165 }
yading@11 166 if (v == roc) {
yading@11 167 seq_largest = FFMAX(seq_largest, seq);
yading@11 168 } else if (v == roc + 1) {
yading@11 169 seq_largest = seq;
yading@11 170 roc = v;
yading@11 171 }
yading@11 172 index = seq + (((uint64_t)v) << 16);
yading@11 173
yading@11 174 AV_WB32(rocbuf, roc);
yading@11 175 av_hmac_update(s->hmac, rocbuf, 4);
yading@11 176 }
yading@11 177
yading@11 178 av_hmac_final(s->hmac, hmac, sizeof(hmac));
yading@11 179 if (memcmp(hmac, buf + len - hmac_size, hmac_size)) {
yading@11 180 av_log(NULL, AV_LOG_WARNING, "HMAC mismatch\n");
yading@11 181 return AVERROR_INVALIDDATA;
yading@11 182 }
yading@11 183
yading@11 184 len -= hmac_size;
yading@11 185 *lenptr = len;
yading@11 186
yading@11 187 if (len < 12)
yading@11 188 return AVERROR_INVALIDDATA;
yading@11 189
yading@11 190 if (rtcp) {
yading@11 191 uint32_t srtcp_index = AV_RB32(buf + len - 4);
yading@11 192 len -= 4;
yading@11 193 *lenptr = len;
yading@11 194
yading@11 195 ssrc = AV_RB32(buf + 4);
yading@11 196 index = srtcp_index & 0x7fffffff;
yading@11 197
yading@11 198 buf += 8;
yading@11 199 len -= 8;
yading@11 200 if (!(srtcp_index & 0x80000000))
yading@11 201 return 0;
yading@11 202 } else {
yading@11 203 int ext, csrc;
yading@11 204 s->seq_initialized = 1;
yading@11 205 s->seq_largest = seq_largest;
yading@11 206 s->roc = roc;
yading@11 207
yading@11 208 csrc = buf[0] & 0x0f;
yading@11 209 ext = buf[0] & 0x10;
yading@11 210 ssrc = AV_RB32(buf + 8);
yading@11 211
yading@11 212 buf += 12;
yading@11 213 len -= 12;
yading@11 214
yading@11 215 buf += 4 * csrc;
yading@11 216 len -= 4 * csrc;
yading@11 217 if (len < 0)
yading@11 218 return AVERROR_INVALIDDATA;
yading@11 219
yading@11 220 if (ext) {
yading@11 221 if (len < 4)
yading@11 222 return AVERROR_INVALIDDATA;
yading@11 223 ext = (AV_RB16(buf + 2) + 1) * 4;
yading@11 224 if (len < ext)
yading@11 225 return AVERROR_INVALIDDATA;
yading@11 226 len -= ext;
yading@11 227 buf += ext;
yading@11 228 }
yading@11 229 }
yading@11 230
yading@11 231 create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
yading@11 232 av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
yading@11 233 encrypt_counter(s->aes, iv, buf, len);
yading@11 234
yading@11 235 return 0;
yading@11 236 }
yading@11 237
yading@11 238 int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len,
yading@11 239 uint8_t *out, int outlen)
yading@11 240 {
yading@11 241 uint8_t iv[16] = { 0 }, hmac[20];
yading@11 242 uint64_t index;
yading@11 243 uint32_t ssrc;
yading@11 244 int rtcp, hmac_size, padding;
yading@11 245 uint8_t *buf;
yading@11 246
yading@11 247 if (len < 8)
yading@11 248 return AVERROR_INVALIDDATA;
yading@11 249
yading@11 250 rtcp = RTP_PT_IS_RTCP(in[1]);
yading@11 251 hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
yading@11 252 padding = hmac_size;
yading@11 253 if (rtcp)
yading@11 254 padding += 4; // For the RTCP index
yading@11 255
yading@11 256 if (len + padding > outlen)
yading@11 257 return 0;
yading@11 258
yading@11 259 memcpy(out, in, len);
yading@11 260 buf = out;
yading@11 261
yading@11 262 if (rtcp) {
yading@11 263 ssrc = AV_RB32(buf + 4);
yading@11 264 index = s->rtcp_index++;
yading@11 265
yading@11 266 buf += 8;
yading@11 267 len -= 8;
yading@11 268 } else {
yading@11 269 int ext, csrc;
yading@11 270 int seq = AV_RB16(buf + 2);
yading@11 271
yading@11 272 if (len < 12)
yading@11 273 return AVERROR_INVALIDDATA;
yading@11 274
yading@11 275 ssrc = AV_RB32(buf + 8);
yading@11 276
yading@11 277 if (seq < s->seq_largest)
yading@11 278 s->roc++;
yading@11 279 s->seq_largest = seq;
yading@11 280 index = seq + (((uint64_t)s->roc) << 16);
yading@11 281
yading@11 282 csrc = buf[0] & 0x0f;
yading@11 283 ext = buf[0] & 0x10;
yading@11 284
yading@11 285 buf += 12;
yading@11 286 len -= 12;
yading@11 287
yading@11 288 buf += 4 * csrc;
yading@11 289 len -= 4 * csrc;
yading@11 290 if (len < 0)
yading@11 291 return AVERROR_INVALIDDATA;
yading@11 292
yading@11 293 if (ext) {
yading@11 294 if (len < 4)
yading@11 295 return AVERROR_INVALIDDATA;
yading@11 296 ext = (AV_RB16(buf + 2) + 1) * 4;
yading@11 297 if (len < ext)
yading@11 298 return AVERROR_INVALIDDATA;
yading@11 299 len -= ext;
yading@11 300 buf += ext;
yading@11 301 }
yading@11 302 }
yading@11 303
yading@11 304 create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
yading@11 305 av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
yading@11 306 encrypt_counter(s->aes, iv, buf, len);
yading@11 307
yading@11 308 if (rtcp) {
yading@11 309 AV_WB32(buf + len, 0x80000000 | index);
yading@11 310 len += 4;
yading@11 311 }
yading@11 312
yading@11 313 av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
yading@11 314 av_hmac_update(s->hmac, out, buf + len - out);
yading@11 315 if (!rtcp) {
yading@11 316 uint8_t rocbuf[4];
yading@11 317 AV_WB32(rocbuf, s->roc);
yading@11 318 av_hmac_update(s->hmac, rocbuf, 4);
yading@11 319 }
yading@11 320 av_hmac_final(s->hmac, hmac, sizeof(hmac));
yading@11 321
yading@11 322 memcpy(buf + len, hmac, hmac_size);
yading@11 323 len += hmac_size;
yading@11 324 return buf + len - out;
yading@11 325 }
yading@11 326
yading@11 327 #ifdef TEST
yading@11 328 #include <stdio.h>
yading@11 329
yading@11 330 static const char *aes128_80_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
yading@11 331
yading@11 332 static const uint8_t rtp_aes128_80[] = {
yading@11 333 // RTP header
yading@11 334 0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
yading@11 335 // encrypted payload
yading@11 336 0x62, 0x69, 0x76, 0xca, 0xc5,
yading@11 337 // HMAC
yading@11 338 0xa1, 0xac, 0x1b, 0xb4, 0xa0, 0x1c, 0xd5, 0x49, 0x28, 0x99,
yading@11 339 };
yading@11 340
yading@11 341 static const uint8_t rtcp_aes128_80[] = {
yading@11 342 // RTCP header
yading@11 343 0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
yading@11 344 // encrypted payload
yading@11 345 0x8a, 0xac, 0xdc, 0xa5, 0x4c, 0xf6, 0x78, 0xa6, 0x62, 0x8f, 0x24, 0xda,
yading@11 346 0x6c, 0x09, 0x3f, 0xa9, 0x28, 0x7a, 0xb5, 0x7f, 0x1f, 0x0f, 0xc9, 0x35,
yading@11 347 // RTCP index
yading@11 348 0x80, 0x00, 0x00, 0x03,
yading@11 349 // HMAC
yading@11 350 0xe9, 0x3b, 0xc0, 0x5c, 0x0c, 0x06, 0x9f, 0xab, 0xc0, 0xde,
yading@11 351 };
yading@11 352
yading@11 353 static const char *aes128_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
yading@11 354
yading@11 355 static const uint8_t rtp_aes128_32[] = {
yading@11 356 // RTP header
yading@11 357 0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
yading@11 358 // encrypted payload
yading@11 359 0x62, 0x69, 0x76, 0xca, 0xc5,
yading@11 360 // HMAC
yading@11 361 0xa1, 0xac, 0x1b, 0xb4,
yading@11 362 };
yading@11 363
yading@11 364 static const uint8_t rtcp_aes128_32[] = {
yading@11 365 // RTCP header
yading@11 366 0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
yading@11 367 // encrypted payload
yading@11 368 0x35, 0xe9, 0xb5, 0xff, 0x0d, 0xd1, 0xde, 0x70, 0x74, 0x10, 0xaa, 0x1b,
yading@11 369 0xb2, 0x8d, 0xf0, 0x20, 0x02, 0x99, 0x6b, 0x1b, 0x0b, 0xd0, 0x47, 0x34,
yading@11 370 // RTCP index
yading@11 371 0x80, 0x00, 0x00, 0x04,
yading@11 372 // HMAC
yading@11 373 0x5b, 0xd2, 0xa9, 0x9d,
yading@11 374 };
yading@11 375
yading@11 376 static const char *aes128_80_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
yading@11 377
yading@11 378 static const uint8_t rtp_aes128_80_32[] = {
yading@11 379 // RTP header
yading@11 380 0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
yading@11 381 // encrypted payload
yading@11 382 0x62, 0x69, 0x76, 0xca, 0xc5,
yading@11 383 // HMAC
yading@11 384 0xa1, 0xac, 0x1b, 0xb4,
yading@11 385 };
yading@11 386
yading@11 387 static const uint8_t rtcp_aes128_80_32[] = {
yading@11 388 // RTCP header
yading@11 389 0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
yading@11 390 // encrypted payload
yading@11 391 0xd6, 0xae, 0xc1, 0x58, 0x63, 0x70, 0xc9, 0x88, 0x66, 0x26, 0x1c, 0x53,
yading@11 392 0xff, 0x5d, 0x5d, 0x2b, 0x0f, 0x8c, 0x72, 0x3e, 0xc9, 0x1d, 0x43, 0xf9,
yading@11 393 // RTCP index
yading@11 394 0x80, 0x00, 0x00, 0x05,
yading@11 395 // HMAC
yading@11 396 0x09, 0x16, 0xb4, 0x27, 0x9a, 0xe9, 0x92, 0x26, 0x4e, 0x10,
yading@11 397 };
yading@11 398
yading@11 399 static void print_data(const uint8_t *buf, int len)
yading@11 400 {
yading@11 401 int i;
yading@11 402 for (i = 0; i < len; i++)
yading@11 403 printf("%02x", buf[i]);
yading@11 404 printf("\n");
yading@11 405 }
yading@11 406
yading@11 407 static int test_decrypt(struct SRTPContext *srtp, const uint8_t *in, int len,
yading@11 408 uint8_t *out)
yading@11 409 {
yading@11 410 memcpy(out, in, len);
yading@11 411 if (!ff_srtp_decrypt(srtp, out, &len)) {
yading@11 412 print_data(out, len);
yading@11 413 return len;
yading@11 414 } else
yading@11 415 return -1;
yading@11 416 }
yading@11 417
yading@11 418 static void test_encrypt(const uint8_t *data, int in_len, const char *suite,
yading@11 419 const char *key)
yading@11 420 {
yading@11 421 struct SRTPContext enc = { 0 }, dec = { 0 };
yading@11 422 int len;
yading@11 423 char buf[RTP_MAX_PACKET_LENGTH];
yading@11 424 ff_srtp_set_crypto(&enc, suite, key);
yading@11 425 ff_srtp_set_crypto(&dec, suite, key);
yading@11 426 len = ff_srtp_encrypt(&enc, data, in_len, buf, sizeof(buf));
yading@11 427 if (!ff_srtp_decrypt(&dec, buf, &len)) {
yading@11 428 if (len == in_len && !memcmp(buf, data, len))
yading@11 429 printf("Decrypted content matches input\n");
yading@11 430 else
yading@11 431 printf("Decrypted content doesn't match input\n");
yading@11 432 } else {
yading@11 433 printf("Decryption failed\n");
yading@11 434 }
yading@11 435 ff_srtp_free(&enc);
yading@11 436 ff_srtp_free(&dec);
yading@11 437 }
yading@11 438
yading@11 439 int main(void)
yading@11 440 {
yading@11 441 static const char *aes128_80_suite = "AES_CM_128_HMAC_SHA1_80";
yading@11 442 static const char *aes128_32_suite = "AES_CM_128_HMAC_SHA1_32";
yading@11 443 static const char *aes128_80_32_suite = "SRTP_AES128_CM_HMAC_SHA1_32";
yading@11 444 static const char *test_key = "abcdefghijklmnopqrstuvwxyz1234567890ABCD";
yading@11 445 uint8_t buf[RTP_MAX_PACKET_LENGTH];
yading@11 446 struct SRTPContext srtp = { 0 };
yading@11 447 int len;
yading@11 448 ff_srtp_set_crypto(&srtp, aes128_80_suite, aes128_80_key);
yading@11 449 len = test_decrypt(&srtp, rtp_aes128_80, sizeof(rtp_aes128_80), buf);
yading@11 450 test_encrypt(buf, len, aes128_80_suite, test_key);
yading@11 451 test_encrypt(buf, len, aes128_32_suite, test_key);
yading@11 452 test_encrypt(buf, len, aes128_80_32_suite, test_key);
yading@11 453 test_decrypt(&srtp, rtcp_aes128_80, sizeof(rtcp_aes128_80), buf);
yading@11 454 test_encrypt(buf, len, aes128_80_suite, test_key);
yading@11 455 test_encrypt(buf, len, aes128_32_suite, test_key);
yading@11 456 test_encrypt(buf, len, aes128_80_32_suite, test_key);
yading@11 457 ff_srtp_free(&srtp);
yading@11 458
yading@11 459 memset(&srtp, 0, sizeof(srtp)); // Clear the context
yading@11 460 ff_srtp_set_crypto(&srtp, aes128_32_suite, aes128_32_key);
yading@11 461 test_decrypt(&srtp, rtp_aes128_32, sizeof(rtp_aes128_32), buf);
yading@11 462 test_decrypt(&srtp, rtcp_aes128_32, sizeof(rtcp_aes128_32), buf);
yading@11 463 ff_srtp_free(&srtp);
yading@11 464
yading@11 465 memset(&srtp, 0, sizeof(srtp)); // Clear the context
yading@11 466 ff_srtp_set_crypto(&srtp, aes128_80_32_suite, aes128_80_32_key);
yading@11 467 test_decrypt(&srtp, rtp_aes128_80_32, sizeof(rtp_aes128_80_32), buf);
yading@11 468 test_decrypt(&srtp, rtcp_aes128_80_32, sizeof(rtcp_aes128_80_32), buf);
yading@11 469 ff_srtp_free(&srtp);
yading@11 470 return 0;
yading@11 471 }
yading@11 472 #endif /* TEST */