This supports HMAC-MD5 and HMAC-SHA1 for now, other hashes are simple to add. Signed-off-by: Martin Storsjö <martin@martin.st>tags/n1.2
| @@ -13,6 +13,9 @@ libavutil: 2012-10-22 | |||
| API changes, most recent first: | |||
| 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. | |||
| @@ -19,6 +19,7 @@ HEADERS = adler32.h \ | |||
| eval.h \ | |||
| fifo.h \ | |||
| file.h \ | |||
| hmac.h \ | |||
| imgutils.h \ | |||
| intfloat.h \ | |||
| intfloat_readwrite.h \ | |||
| @@ -66,6 +67,7 @@ OBJS = adler32.o \ | |||
| fifo.o \ | |||
| file.o \ | |||
| float_dsp.o \ | |||
| hmac.o \ | |||
| imgutils.o \ | |||
| intfloat_readwrite.o \ | |||
| intmath.o \ | |||
| @@ -0,0 +1,138 @@ | |||
| /* | |||
| * Copyright (C) 2012 Martin Storsjo | |||
| * | |||
| * This file is part of Libav. | |||
| * | |||
| * Libav 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. | |||
| * | |||
| * Libav 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 Libav; 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); | |||
| } | |||
| @@ -0,0 +1,95 @@ | |||
| /* | |||
| * Copyright (C) 2012 Martin Storsjo | |||
| * | |||
| * This file is part of Libav. | |||
| * | |||
| * Libav 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. | |||
| * | |||
| * Libav 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 Libav; 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 */ | |||
| @@ -37,7 +37,7 @@ | |||
| */ | |||
| #define LIBAVUTIL_VERSION_MAJOR 52 | |||
| #define LIBAVUTIL_VERSION_MINOR 4 | |||
| #define LIBAVUTIL_VERSION_MINOR 5 | |||
| #define LIBAVUTIL_VERSION_MICRO 0 | |||
| #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | |||