Merge commit 'ab2ad8bd56882c0ea160b154e8b836eb71abc49d'
authorMichael Niedermayer <michaelni@gmx.at>
Tue, 15 Jan 2013 14:56:12 +0000 (15:56 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Tue, 15 Jan 2013 14:57:33 +0000 (15:57 +0100)
* commit 'ab2ad8bd56882c0ea160b154e8b836eb71abc49d':
  lavf: Add functions for SRTP decryption/encryption
  lavu: Add an API for calculating HMAC (RFC 2104)

Conflicts:
doc/APIchanges
libavutil/version.h

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
doc/APIchanges
libavformat/srtp.c
libavformat/srtp.h
libavutil/Makefile
libavutil/hmac.c
libavutil/hmac.h
libavutil/version.h

diff --cc doc/APIchanges
@@@ -15,123 -13,9 +15,126 @@@ libavutil:     2012-10-2
  
  API changes, most recent first:
  
 +2012-12-20 - xxxxxxx - lavfi 3.28.100 - avfilter.h
 +  Add AVFilterLink.channels, avfilter_link_get_channels()
 +  and avfilter_ref_get_channels().
 +
 +2012-12-15 - 2ada584d - lavc 54.80.100 - avcodec.h
 +  Add pkt_size field to AVFrame.
 +
 +2012-11-25 - c70ec631 - lavu 52.9.100 - opt.h
 +  Add the following convenience functions to opt.h:
 +   av_opt_get_image_size
 +   av_opt_get_pixel_fmt
 +   av_opt_get_sample_fmt
 +   av_opt_set_image_size
 +   av_opt_set_pixel_fmt
 +   av_opt_set_sample_fmt
 +
 +2012-11-17 - 4cd74c81 - lavu 52.8.100 - bprint.h
 +  Add av_bprint_strftime().
 +
 +2012-11-15 - 92648107 - lavu 52.7.100 - opt.h
 +  Add av_opt_get_key_value().
 +
 +2012-11-13 - 79456652 - lavfi 3.23.100 - avfilter.h
 +  Add channels field to AVFilterBufferRefAudioProps.
 +
 +2012-11-03 - 481fdeee - lavu 52.3.100 - opt.h
 +  Add AV_OPT_TYPE_SAMPLE_FMT value to AVOptionType enum.
 +
 +2012-10-21 - 6fb2fd8 - lavc  54.68.100 - avcodec.h
 +                       lavfi  3.20.100 - avfilter.h
 +  Add AV_PKT_DATA_STRINGS_METADATA side data type, used to transmit key/value
 +  strings between AVPacket and AVFrame, and add metadata field to
 +  AVCodecContext (which shall not be accessed by users; see AVFrame metadata
 +  instead).
 +
 +2012-09-27 - a70b493 - lavd 54.3.100 - version.h
 +  Add LIBAVDEVICE_IDENT symbol.
 +
 +2012-09-27 - a70b493 - lavfi 3.18.100 - version.h
 +  Add LIBAVFILTER_IDENT symbol.
 +
 +2012-09-27 - a70b493 - libswr 0.16.100 - version.h
 +  Add LIBSWRESAMPLE_VERSION, LIBSWRESAMPLE_BUILD
 +  and LIBSWRESAMPLE_IDENT symbols.
 +
 +2012-09-06 - 29e972f - lavu 51.72.100 - parseutils.h
 +  Add av_small_strptime() time parsing function.
 +
 +  Can be used as a stripped-down replacement for strptime(), on
 +  systems which do not support it.
 +
 +2012-08-25 - 2626cc4 - lavf 54.28.100
 +  Matroska demuxer now identifies SRT subtitles as AV_CODEC_ID_SUBRIP instead
 +  of AV_CODEC_ID_TEXT.
 +
 +2012-08-13 - 5c0d8bc - lavfi 3.8.100 - avfilter.h
 +  Add avfilter_get_class() function, and priv_class field to AVFilter
 +  struct.
 +
 +2012-08-12 - a25346e - lavu 51.69.100 - opt.h
 +  Add AV_OPT_FLAG_FILTERING_PARAM symbol in opt.h.
 +
 +2012-07-31 - 23fc4dd - lavc 54.46.100
 +  Add channels field to AVFrame.
 +
 +2012-07-30 - f893904 - lavu 51.66.100
 +  Add av_get_channel_description()
 +  and av_get_standard_channel_layout() functions.
 +
 +2012-07-21 - 016a472 - lavc 54.43.100
 +  Add decode_error_flags field to AVFrame.
 +
 +2012-07-20 - b062936 - lavf 54.18.100
 +  Add avformat_match_stream_specifier() function.
 +
 +2012-07-14 - f49ec1b - lavc 54.38.100 - avcodec.h
 +  Add metadata to AVFrame, and the accessor functions
 +  av_frame_get_metadata() and av_frame_set_metadata().
 +
 +2012-07-10 - 0e003d8 - lavc 54.33.100
 +  Add av_fast_padded_mallocz().
 +
 +2012-07-10 - 21d5609 - lavfi 3.2.0 - avfilter.h
 +  Add init_opaque() callback to AVFilter struct.
 +
 +2012-06-26 - e6674e4 - lavu 51.63.100 - imgutils.h
 +  Add functions to libavutil/imgutils.h:
 +  av_image_get_buffer_size()
 +  av_image_fill_arrays()
 +  av_image_copy_to_buffer()
 +
 +2012-06-24 - c41899a - lavu 51.62.100 - version.h
 +  version moved from avutil.h to version.h
 +
 +2012-04-11 - 359abb1 - lavu 51.58.100 - error.h
 +  Add av_make_error_string() and av_err2str() utilities to
 +  libavutil/error.h.
 +
 +2012-06-05 - 62b39d4 - lavc 54.24.100
 +  Add pkt_duration field to AVFrame.
 +
 +2012-05-24 - f2ee065 - lavu 51.54.100
 +  Move AVPALETTE_SIZE and AVPALETTE_COUNT macros from
 +  libavcodec/avcodec.h to libavutil/pixfmt.h.
 +
 +2012-05-14 - 94a9ac1 - lavf 54.5.100
 +  Add av_guess_sample_aspect_ratio() function.
 +
 +2012-04-20 - 65fa7bc - lavfi 2.70.100
 +  Add avfilter_unref_bufferp() to avfilter.h.
 +
 +2012-04-13 - 162e400 - lavfi 2.68.100
 +  Install libavfilter/asrc_abuffer.h public header.
 +
 +2012-03-26 - a67d9cf - lavfi 2.66.100
 +  Add avfilter_fill_frame_from_{audio_,}buffer_ref() functions.
 +
+ 2013-01-xx - xxxxxxx - lavu 52.5.0 - hmac.h
+   Add AVHMAC.
  2013-01-13 - xxxxxxx - lavc 54.36.0 - vdpau.h
    Add AVVDPAUContext struct for VDPAU hardware-accelerated decoding.
  
index 0000000,6c589b0..55b3b5b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,293 +1,293 @@@
 - * This file is part of Libav.
+ /*
+  * SRTP encryption/decryption
+  * Copyright (c) 2012 Martin Storsjo
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include "libavutil/base64.h"
+ #include "libavutil/aes.h"
+ #include "libavutil/hmac.h"
+ #include "libavutil/intreadwrite.h"
+ #include "libavutil/log.h"
+ #include "rtp.h"
+ #include "srtp.h"
+ void ff_srtp_free(struct SRTPContext *s)
+ {
+     if (!s)
+         return;
+     av_freep(&s->aes);
+     if (s->hmac)
+         av_hmac_free(s->hmac);
+     s->hmac = NULL;
+ }
+ static void encrypt_counter(struct AVAES *aes, uint8_t *iv, uint8_t *outbuf,
+                             int outlen)
+ {
+     int i, j, outpos;
+     for (i = 0, outpos = 0; outpos < outlen; i++) {
+         uint8_t keystream[16];
+         AV_WB16(&iv[14], i);
+         av_aes_crypt(aes, keystream, iv, 1, NULL, 0);
+         for (j = 0; j < 16 && outpos < outlen; j++, outpos++)
+             outbuf[outpos] ^= keystream[j];
+     }
+ }
+ static void derive_key(struct AVAES *aes, const uint8_t *salt, int label,
+                        uint8_t *out, int outlen)
+ {
+     uint8_t input[16] = { 0 };
+     memcpy(input, salt, 14);
+     // Key derivation rate assumed to be zero
+     input[14 - 7] ^= label;
+     memset(out, 0, outlen);
+     encrypt_counter(aes, input, out, outlen);
+ }
+ int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite,
+                        const char *params)
+ {
+     uint8_t buf[30];
+     ff_srtp_free(s);
+     // RFC 4568
+     if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80")) {
+         s->hmac_size = 10;
+     } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
+         s->hmac_size = 4;
+     } else {
+         av_log(NULL, AV_LOG_WARNING, "SRTP Crypto suite %s not supported\n",
+                                      suite);
+         return AVERROR(EINVAL);
+     }
+     if (av_base64_decode(buf, params, sizeof(buf)) != sizeof(buf)) {
+         av_log(NULL, AV_LOG_WARNING, "Incorrect amount of SRTP params\n");
+         return AVERROR(EINVAL);
+     }
+     // MKI and lifetime not handled yet
+     s->aes  = av_aes_alloc();
+     s->hmac = av_hmac_alloc(AV_HMAC_SHA1);
+     if (!s->aes || !s->hmac)
+         return AVERROR(ENOMEM);
+     memcpy(s->master_key, buf, 16);
+     memcpy(s->master_salt, buf + 16, 14);
+     // RFC 3711
+     av_aes_init(s->aes, s->master_key, 128, 0);
+     derive_key(s->aes, s->master_salt, 0x00, s->rtp_key, sizeof(s->rtp_key));
+     derive_key(s->aes, s->master_salt, 0x02, s->rtp_salt, sizeof(s->rtp_salt));
+     derive_key(s->aes, s->master_salt, 0x01, s->rtp_auth, sizeof(s->rtp_auth));
+     derive_key(s->aes, s->master_salt, 0x03, s->rtcp_key, sizeof(s->rtcp_key));
+     derive_key(s->aes, s->master_salt, 0x05, s->rtcp_salt, sizeof(s->rtcp_salt));
+     derive_key(s->aes, s->master_salt, 0x04, s->rtcp_auth, sizeof(s->rtcp_auth));
+     return 0;
+ }
+ static void create_iv(uint8_t *iv, const uint8_t *salt, uint64_t index,
+                       uint32_t ssrc)
+ {
+     uint8_t indexbuf[8];
+     int i;
+     memset(iv, 0, 16);
+     AV_WB32(&iv[4], ssrc);
+     AV_WB64(indexbuf, index);
+     for (i = 0; i < 8; i++) // index << 16
+         iv[6 + i] ^= indexbuf[i];
+     for (i = 0; i < 14; i++)
+         iv[i] ^= salt[i];
+ }
+ int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr)
+ {
+     uint8_t iv[16] = { 0 }, hmac[20];
+     int len = *lenptr;
+     int ext, seq_largest;
+     uint32_t ssrc, roc;
+     uint64_t index;
+     int rtcp;
+     // TODO: Missing replay protection
+     if (len < s->hmac_size)
+         return AVERROR_INVALIDDATA;
+     rtcp = RTP_PT_IS_RTCP(buf[1]);
+     // 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);
+     if (!rtcp) {
+         int seq = AV_RB16(buf + 2);
+         uint32_t v;
+         uint8_t rocbuf[4];
+         // RFC 3711 section 3.3.1, appendix A
+         seq_largest = s->seq_initialized ? s->seq_largest : seq;
+         v = roc = s->roc;
+         if (seq_largest < 32768) {
+             if (seq - seq_largest > 32768)
+                 v = roc - 1;
+         } else {
+             if (seq_largest - 32768 > seq)
+                 v = roc + 1;
+         }
+         if (v == roc) {
+             seq_largest = FFMAX(seq_largest, seq);
+         } else if (v == roc + 1) {
+             seq_largest = seq;
+             roc = v;
+         }
+         index = seq + (((uint64_t)v) << 16);
+         AV_WB32(rocbuf, roc);
+         av_hmac_update(s->hmac, rocbuf, 4);
+     }
+     av_hmac_final(s->hmac, hmac, sizeof(hmac));
+     if (memcmp(hmac, buf + len - s->hmac_size, s->hmac_size)) {
+         av_log(NULL, AV_LOG_WARNING, "HMAC mismatch\n");
+         return AVERROR_INVALIDDATA;
+     }
+     len -= s->hmac_size;
+     *lenptr = len;
+     if (len < 12)
+         return AVERROR_INVALIDDATA;
+     if (rtcp) {
+         uint32_t srtcp_index = AV_RB32(buf + len - 4);
+         len -= 4;
+         *lenptr = len;
+         ssrc = AV_RB32(buf + 4);
+         index = srtcp_index & 0x7fffffff;
+         buf += 8;
+         len -= 8;
+         if (!(srtcp_index & 0x80000000))
+             return 0;
+     } else {
+         s->seq_initialized = 1;
+         s->seq_largest     = seq_largest;
+         s->roc             = roc;
+         ext  = buf[0] & 0x10;
+         ssrc = AV_RB32(buf + 8);
+         buf += 12;
+         len -= 12;
+         if (ext) {
+             if (len < 4)
+                 return AVERROR_INVALIDDATA;
+             ext = (AV_RB16(buf + 2) + 1) * 4;
+             if (len < ext)
+                 return AVERROR_INVALIDDATA;
+             len -= ext;
+             buf += ext;
+         }
+     }
+     create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
+     av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
+     encrypt_counter(s->aes, iv, buf, len);
+     return 0;
+ }
+ int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len,
+                     uint8_t *out, int outlen)
+ {
+     uint8_t iv[16] = { 0 }, hmac[20];
+     uint64_t index;
+     uint32_t ssrc;
+     int rtcp;
+     uint8_t *buf;
+     if (len + 14 > outlen)
+         return 0;
+     if (len < 12)
+         return 0;
+     memcpy(out, in, len);
+     buf = out;
+     rtcp = RTP_PT_IS_RTCP(buf[1]);
+     if (rtcp) {
+         ssrc = AV_RB32(buf + 4);
+         index = s->rtcp_index++;
+         buf += 8;
+         len -= 8;
+     } else {
+         int ext;
+         int seq = AV_RB16(buf + 2);
+         ssrc = AV_RB32(buf + 8);
+         if (seq < s->seq_largest)
+             s->roc++;
+         s->seq_largest = seq;
+         index = seq + (((uint64_t)s->roc) << 16);
+         ext = buf[0] & 0x10;
+         buf += 12;
+         len -= 12;
+         if (ext) {
+             if (len < 4)
+                 return AVERROR_INVALIDDATA;
+             ext = (AV_RB16(buf + 2) + 1) * 4;
+             if (len < ext)
+                 return AVERROR_INVALIDDATA;
+             len -= ext;
+             buf += ext;
+         }
+     }
+     create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
+     av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
+     encrypt_counter(s->aes, iv, buf, len);
+     if (rtcp) {
+         AV_WB32(buf + len, 0x80000000 | index);
+         len += 4;
+     }
+     av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
+     av_hmac_update(s->hmac, out, buf + len - out);
+     if (!rtcp) {
+         uint8_t rocbuf[4];
+         AV_WB32(rocbuf, s->roc);
+         av_hmac_update(s->hmac, rocbuf, 4);
+     }
+     av_hmac_final(s->hmac, hmac, sizeof(hmac));
+     memcpy(buf + len, hmac, s->hmac_size);
+     len += s->hmac_size;
+     return buf + len - out;
+ }
index 0000000,a1cb92d..97bbf2b
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,52 +1,52 @@@
 - * This file is part of Libav.
+ /*
+  * SRTP encryption/decryption
+  * Copyright (c) 2012 Martin Storsjo
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #ifndef AVFORMAT_SRTP_H
+ #define AVFORMAT_SRTP_H
+ #include <stdint.h>
+ struct AVAES;
+ struct AVHMAC;
+ struct SRTPContext {
+     struct AVAES *aes;
+     struct AVHMAC *hmac;
+     int hmac_size;
+     uint8_t master_key[16];
+     uint8_t master_salt[14];
+     uint8_t rtp_key[16],  rtcp_key[16];
+     uint8_t rtp_salt[14], rtcp_salt[14];
+     uint8_t rtp_auth[20], rtcp_auth[20];
+     int seq_largest, seq_initialized;
+     uint32_t roc;
+     uint32_t rtcp_index;
+ };
+ int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite,
+                        const char *params);
+ void ff_srtp_free(struct SRTPContext *s);
+ int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr);
+ int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len,
+                     uint8_t *out, int outlen);
+ #endif /* AVFORMAT_SRTP_H */
Simple merge
index 0000000,3308f1b..1520148
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,138 +1,138 @@@
 - * This file is part of Libav.
+ /*
+  * Copyright (C) 2012 Martin Storsjo
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #include <string.h>
+ #include "hmac.h"
+ #include "md5.h"
+ #include "sha.h"
+ #include "mem.h"
+ #define MAX_HASHLEN 20
+ #define MAX_BLOCKLEN 64
+ struct AVHMAC {
+     void *hash;
+     int blocklen, hashlen;
+     void (*final)(void*, uint8_t*);
+     void (*update)(void*, const uint8_t*, int len);
+     void (*init)(void*);
+     uint8_t key[MAX_BLOCKLEN];
+     int keylen;
+ };
+ static void sha1_init(void *ctx)
+ {
+     av_sha_init(ctx, 160);
+ }
+ AVHMAC *av_hmac_alloc(enum AVHMACType type)
+ {
+     AVHMAC *c = av_mallocz(sizeof(*c));
+     if (!c)
+         return NULL;
+     switch (type) {
+     case AV_HMAC_MD5:
+         c->blocklen = 64;
+         c->hashlen  = 16;
+         c->init     = av_md5_init;
+         c->update   = av_md5_update;
+         c->final    = av_md5_final;
+         c->hash     = av_md5_alloc();
+         break;
+     case AV_HMAC_SHA1:
+         c->blocklen = 64;
+         c->hashlen  = 20;
+         c->init     = sha1_init;
+         c->update   = av_sha_update;
+         c->final    = av_sha_final;
+         c->hash     = av_sha_alloc();
+         break;
+     default:
+         av_free(c);
+         return NULL;
+     }
+     if (!c->hash) {
+         av_free(c);
+         return NULL;
+     }
+     return c;
+ }
+ void av_hmac_free(AVHMAC *c)
+ {
+     if (!c)
+         return;
+     av_free(c->hash);
+     av_free(c);
+ }
+ void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
+ {
+     int i;
+     uint8_t block[MAX_BLOCKLEN];
+     if (keylen > c->blocklen) {
+         c->init(c->hash);
+         c->update(c->hash, key, keylen);
+         c->final(c->hash, c->key);
+         c->keylen = c->hashlen;
+     } else {
+         memcpy(c->key, key, keylen);
+         c->keylen = keylen;
+     }
+     c->init(c->hash);
+     for (i = 0; i < c->keylen; i++)
+         block[i] = c->key[i] ^ 0x36;
+     for (i = c->keylen; i < c->blocklen; i++)
+         block[i] = 0x36;
+     c->update(c->hash, block, c->blocklen);
+ }
+ void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
+ {
+     c->update(c->hash, data, len);
+ }
+ int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
+ {
+     uint8_t block[MAX_BLOCKLEN];
+     int i;
+     if (outlen < c->hashlen)
+         return AVERROR(EINVAL);
+     c->final(c->hash, out);
+     c->init(c->hash);
+     for (i = 0; i < c->keylen; i++)
+         block[i] = c->key[i] ^ 0x5C;
+     for (i = c->keylen; i < c->blocklen; i++)
+         block[i] = 0x5C;
+     c->update(c->hash, block, c->blocklen);
+     c->update(c->hash, out, c->hashlen);
+     c->final(c->hash, out);
+     return c->hashlen;
+ }
+ int av_hmac_calc(AVHMAC *c, const uint8_t *data, unsigned int len,
+                  const uint8_t *key, unsigned int keylen,
+                  uint8_t *out, unsigned int outlen)
+ {
+     av_hmac_init(c, key, keylen);
+     av_hmac_update(c, data, len);
+     return av_hmac_final(c, out, outlen);
+ }
index 0000000,28c2062..aef84c6
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,95 +1,95 @@@
 - * This file is part of Libav.
+ /*
+  * Copyright (C) 2012 Martin Storsjo
+  *
 - * Libav is free software; you can redistribute it and/or
++ * This file is part of FFmpeg.
+  *
 - * Libav is distributed in the hope that it will be useful,
++ * FFmpeg is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Lesser General Public
+  * License as published by the Free Software Foundation; either
+  * version 2.1 of the License, or (at your option) any later version.
+  *
 - * License along with Libav; if not, write to the Free Software
++ * FFmpeg is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
+  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+  */
+ #ifndef AVUTIL_HMAC_H
+ #define AVUTIL_HMAC_H
+ #include <stdint.h>
+ /**
+  * @defgroup lavu_hmac HMAC
+  * @ingroup lavu_crypto
+  * @{
+  */
+ enum AVHMACType {
+     AV_HMAC_MD5,
+     AV_HMAC_SHA1,
+ };
+ typedef struct AVHMAC AVHMAC;
+ /**
+  * Allocate an AVHMAC context.
+  * @param type The hash function used for the HMAC.
+  */
+ AVHMAC *av_hmac_alloc(enum AVHMACType type);
+ /**
+  * Free an AVHMAC context.
+  * @param ctx The context to free, may be NULL
+  */
+ void av_hmac_free(AVHMAC *ctx);
+ /**
+  * Initialize an AVHMAC context with an authentication key.
+  * @param ctx    The HMAC context
+  * @param key    The authentication key
+  * @param keylen The length of the key, in bytes
+  */
+ void av_hmac_init(AVHMAC *ctx, const uint8_t *key, unsigned int keylen);
+ /**
+  * Hash data with the HMAC.
+  * @param ctx  The HMAC context
+  * @param data The data to hash
+  * @param len  The length of the data, in bytes
+  */
+ void av_hmac_update(AVHMAC *ctx, const uint8_t *data, unsigned int len);
+ /**
+  * Finish hashing and output the HMAC digest.
+  * @param ctx    The HMAC context
+  * @param out    The output buffer to write the digest into
+  * @param outlen The length of the out buffer, in bytes
+  * @return       The number of bytes written to out, or a negative error code.
+  */
+ int av_hmac_final(AVHMAC *ctx, uint8_t *out, unsigned int outlen);
+ /**
+  * Hash an array of data with a key.
+  * @param ctx    The HMAC context
+  * @param data   The data to hash
+  * @param len    The length of the data, in bytes
+  * @param key    The authentication key
+  * @param keylen The length of the key, in bytes
+  * @param out    The output buffer to write the digest into
+  * @param outlen The length of the out buffer, in bytes
+  * @return       The number of bytes written to out, or a negative error code.
+  */
+ int av_hmac_calc(AVHMAC *ctx, const uint8_t *data, unsigned int len,
+                  const uint8_t *key, unsigned int keylen,
+                  uint8_t *out, unsigned int outlen);
+ /**
+  * @}
+  */
+ #endif /* AVUTIL_HMAC_H */
@@@ -74,9 -36,9 +74,9 @@@
   * @{
   */
  
 -#define LIBAVUTIL_VERSION_MAJOR 52
 -#define LIBAVUTIL_VERSION_MINOR  5
 -#define LIBAVUTIL_VERSION_MICRO  0
 +#define LIBAVUTIL_VERSION_MAJOR  52
- #define LIBAVUTIL_VERSION_MINOR  14
++#define LIBAVUTIL_VERSION_MINOR  15
 +#define LIBAVUTIL_VERSION_MICRO 100
  
  #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
                                                 LIBAVUTIL_VERSION_MINOR, \