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: | 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 | 2013-01-13 - xxxxxxx - lavc 54.36.0 - vdpau.h | ||||
| Add AVVDPAUContext struct for VDPAU hardware-accelerated decoding. | Add AVVDPAUContext struct for VDPAU hardware-accelerated decoding. | ||||
| @@ -19,6 +19,7 @@ HEADERS = adler32.h \ | |||||
| eval.h \ | eval.h \ | ||||
| fifo.h \ | fifo.h \ | ||||
| file.h \ | file.h \ | ||||
| hmac.h \ | |||||
| imgutils.h \ | imgutils.h \ | ||||
| intfloat.h \ | intfloat.h \ | ||||
| intfloat_readwrite.h \ | intfloat_readwrite.h \ | ||||
| @@ -66,6 +67,7 @@ OBJS = adler32.o \ | |||||
| fifo.o \ | fifo.o \ | ||||
| file.o \ | file.o \ | ||||
| float_dsp.o \ | float_dsp.o \ | ||||
| hmac.o \ | |||||
| imgutils.o \ | imgutils.o \ | ||||
| intfloat_readwrite.o \ | intfloat_readwrite.o \ | ||||
| intmath.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_MAJOR 52 | ||||
| #define LIBAVUTIL_VERSION_MINOR 4 | |||||
| #define LIBAVUTIL_VERSION_MINOR 5 | |||||
| #define LIBAVUTIL_VERSION_MICRO 0 | #define LIBAVUTIL_VERSION_MICRO 0 | ||||
| #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | ||||