LCOV - code coverage report
Current view: top level - src/libavutil - hmac.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 91 98 92.9 %
Date: 2017-01-21 09:32:20 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2012 Martin Storsjo
       3             :  *
       4             :  * This file is part of FFmpeg.
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public
       8             :  * License as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14             :  * Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with FFmpeg; if not, write to the Free Software
      18             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <string.h>
      22             : 
      23             : #include "attributes.h"
      24             : #include "hmac.h"
      25             : #include "md5.h"
      26             : #include "sha.h"
      27             : #include "sha512.h"
      28             : #include "mem.h"
      29             : 
      30             : #define MAX_HASHLEN 64
      31             : #define MAX_BLOCKLEN 128
      32             : 
      33             : struct AVHMAC {
      34             :     void *hash;
      35             :     int blocklen, hashlen;
      36             :     void (*final)(void*, uint8_t*);
      37             :     void (*update)(void*, const uint8_t*, int len);
      38             :     void (*init)(void*);
      39             :     uint8_t key[MAX_BLOCKLEN];
      40             :     int keylen;
      41             : };
      42             : 
      43             : #define DEFINE_SHA(bits)                           \
      44             : static av_cold void sha ## bits ##_init(void *ctx) \
      45             : {                                                  \
      46             :     av_sha_init(ctx, bits);                        \
      47             : }
      48             : 
      49             : #define DEFINE_SHA512(bits)                        \
      50             : static av_cold void sha ## bits ##_init(void *ctx) \
      51             : {                                                  \
      52             :     av_sha512_init(ctx, bits);                     \
      53             : }
      54             : 
      55          48 : DEFINE_SHA(160)
      56          12 : DEFINE_SHA(224)
      57          12 : DEFINE_SHA(256)
      58          12 : DEFINE_SHA512(384)
      59          12 : DEFINE_SHA512(512)
      60             : 
      61          21 : AVHMAC *av_hmac_alloc(enum AVHMACType type)
      62             : {
      63          21 :     AVHMAC *c = av_mallocz(sizeof(*c));
      64          21 :     if (!c)
      65           0 :         return NULL;
      66          21 :     switch (type) {
      67             :     case AV_HMAC_MD5:
      68           1 :         c->blocklen = 64;
      69           1 :         c->hashlen  = 16;
      70           1 :         c->init     = (void*)av_md5_init;
      71           1 :         c->update   = (void*)av_md5_update;
      72           1 :         c->final    = (void*)av_md5_final;
      73           1 :         c->hash     = av_md5_alloc();
      74           1 :         break;
      75             :     case AV_HMAC_SHA1:
      76          16 :         c->blocklen = 64;
      77          16 :         c->hashlen  = 20;
      78          16 :         c->init     = sha160_init;
      79          16 :         c->update   = (void*)av_sha_update;
      80          16 :         c->final    = (void*)av_sha_final;
      81          16 :         c->hash     = av_sha_alloc();
      82          16 :         break;
      83             :     case AV_HMAC_SHA224:
      84           1 :         c->blocklen = 64;
      85           1 :         c->hashlen  = 28;
      86           1 :         c->init     = sha224_init;
      87           1 :         c->update   = (void*)av_sha_update;
      88           1 :         c->final    = (void*)av_sha_final;
      89           1 :         c->hash     = av_sha_alloc();
      90           1 :         break;
      91             :     case AV_HMAC_SHA256:
      92           1 :         c->blocklen = 64;
      93           1 :         c->hashlen  = 32;
      94           1 :         c->init     = sha256_init;
      95           1 :         c->update   = (void*)av_sha_update;
      96           1 :         c->final    = (void*)av_sha_final;
      97           1 :         c->hash     = av_sha_alloc();
      98           1 :         break;
      99             :     case AV_HMAC_SHA384:
     100           1 :         c->blocklen = 128;
     101           1 :         c->hashlen  = 48;
     102           1 :         c->init     = sha384_init;
     103           1 :         c->update   = (void*)av_sha512_update;
     104           1 :         c->final    = (void*)av_sha512_final;
     105           1 :         c->hash     = av_sha512_alloc();
     106           1 :         break;
     107             :     case AV_HMAC_SHA512:
     108           1 :         c->blocklen = 128;
     109           1 :         c->hashlen  = 64;
     110           1 :         c->init     = sha512_init;
     111           1 :         c->update   = (void*)av_sha512_update;
     112           1 :         c->final    = (void*)av_sha512_final;
     113           1 :         c->hash     = av_sha512_alloc();
     114           1 :         break;
     115             :     default:
     116           0 :         av_free(c);
     117           0 :         return NULL;
     118             :     }
     119          21 :     if (!c->hash) {
     120           0 :         av_free(c);
     121           0 :         return NULL;
     122             :     }
     123          21 :     return c;
     124             : }
     125             : 
     126          21 : void av_hmac_free(AVHMAC *c)
     127             : {
     128          21 :     if (!c)
     129           0 :         return;
     130          21 :     av_freep(&c->hash);
     131          21 :     av_free(c);
     132             : }
     133             : 
     134          48 : void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
     135             : {
     136             :     int i;
     137             :     uint8_t block[MAX_BLOCKLEN];
     138          48 :     if (keylen > c->blocklen) {
     139          12 :         c->init(c->hash);
     140          12 :         c->update(c->hash, key, keylen);
     141          12 :         c->final(c->hash, c->key);
     142          12 :         c->keylen = c->hashlen;
     143             :     } else {
     144          36 :         memcpy(c->key, key, keylen);
     145          36 :         c->keylen = keylen;
     146             :     }
     147          48 :     c->init(c->hash);
     148        1080 :     for (i = 0; i < c->keylen; i++)
     149        1032 :         block[i] = c->key[i] ^ 0x36;
     150        2728 :     for (i = c->keylen; i < c->blocklen; i++)
     151        2680 :         block[i] = 0x36;
     152          48 :     c->update(c->hash, block, c->blocklen);
     153          48 : }
     154             : 
     155          57 : void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
     156             : {
     157          57 :     c->update(c->hash, data, len);
     158          57 : }
     159             : 
     160          48 : int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
     161             : {
     162             :     uint8_t block[MAX_BLOCKLEN];
     163             :     int i;
     164          48 :     if (outlen < c->hashlen)
     165           0 :         return AVERROR(EINVAL);
     166          48 :     c->final(c->hash, out);
     167          48 :     c->init(c->hash);
     168        1080 :     for (i = 0; i < c->keylen; i++)
     169        1032 :         block[i] = c->key[i] ^ 0x5C;
     170        2728 :     for (i = c->keylen; i < c->blocklen; i++)
     171        2680 :         block[i] = 0x5C;
     172          48 :     c->update(c->hash, block, c->blocklen);
     173          48 :     c->update(c->hash, out, c->hashlen);
     174          48 :     c->final(c->hash, out);
     175          48 :     return c->hashlen;
     176             : }
     177             : 
     178          30 : int av_hmac_calc(AVHMAC *c, const uint8_t *data, unsigned int len,
     179             :                  const uint8_t *key, unsigned int keylen,
     180             :                  uint8_t *out, unsigned int outlen)
     181             : {
     182          30 :     av_hmac_init(c, key, keylen);
     183          30 :     av_hmac_update(c, data, len);
     184          30 :     return av_hmac_final(c, out, outlen);
     185             : }

Generated by: LCOV version 1.12