LCOV - code coverage report
Current view: top level - libavutil - hmac.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 97 105 92.4 %
Date: 2017-12-15 02:19:58 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 <stddef.h>
      22             : #include <stdint.h>
      23             : #include <string.h>
      24             : 
      25             : #include "attributes.h"
      26             : #include "hmac.h"
      27             : #include "md5.h"
      28             : #include "sha.h"
      29             : #include "sha512.h"
      30             : #include "mem.h"
      31             : #include "version.h"
      32             : 
      33             : #define MAX_HASHLEN 64
      34             : #define MAX_BLOCKLEN 128
      35             : 
      36             : typedef void (*hmac_final)(void *ctx, uint8_t *dst);
      37             : #if FF_API_CRYPTO_SIZE_T
      38             : typedef void (*hmac_update)(void *ctx, const uint8_t *src, int len);
      39             : #else
      40             : typedef void (*hmac_update)(void *ctx, const uint8_t *src, size_t len);
      41             : #endif
      42             : typedef void (*hmac_init)(void *ctx);
      43             : 
      44             : struct AVHMAC {
      45             :     void *hash;
      46             :     int blocklen, hashlen;
      47             :     hmac_final  final;
      48             :     hmac_update update;
      49             :     hmac_init   init;
      50             :     uint8_t key[MAX_BLOCKLEN];
      51             :     int keylen;
      52             : };
      53             : 
      54             : #define DEFINE_SHA(bits)                           \
      55             : static av_cold void sha ## bits ##_init(void *ctx) \
      56             : {                                                  \
      57             :     av_sha_init(ctx, bits);                        \
      58             : }
      59             : 
      60             : #define DEFINE_SHA512(bits)                        \
      61             : static av_cold void sha ## bits ##_init(void *ctx) \
      62             : {                                                  \
      63             :     av_sha512_init(ctx, bits);                     \
      64             : }
      65             : 
      66          48 : DEFINE_SHA(160)
      67          12 : DEFINE_SHA(224)
      68          12 : DEFINE_SHA(256)
      69          12 : DEFINE_SHA512(384)
      70          12 : DEFINE_SHA512(512)
      71             : 
      72          21 : AVHMAC *av_hmac_alloc(enum AVHMACType type)
      73             : {
      74          21 :     AVHMAC *c = av_mallocz(sizeof(*c));
      75          21 :     if (!c)
      76           0 :         return NULL;
      77          21 :     switch (type) {
      78           1 :     case AV_HMAC_MD5:
      79           1 :         c->blocklen = 64;
      80           1 :         c->hashlen  = 16;
      81           1 :         c->init     = (hmac_init) av_md5_init;
      82           1 :         c->update   = (hmac_update) av_md5_update;
      83           1 :         c->final    = (hmac_final) av_md5_final;
      84           1 :         c->hash     = av_md5_alloc();
      85           1 :         break;
      86          16 :     case AV_HMAC_SHA1:
      87          16 :         c->blocklen = 64;
      88          16 :         c->hashlen  = 20;
      89          16 :         c->init     = sha160_init;
      90          16 :         c->update   = (hmac_update) av_sha_update;
      91          16 :         c->final    = (hmac_final) av_sha_final;
      92          16 :         c->hash     = av_sha_alloc();
      93          16 :         break;
      94           1 :     case AV_HMAC_SHA224:
      95           1 :         c->blocklen = 64;
      96           1 :         c->hashlen  = 28;
      97           1 :         c->init     = sha224_init;
      98           1 :         c->update   = (hmac_update) av_sha_update;
      99           1 :         c->final    = (hmac_final) av_sha_final;
     100           1 :         c->hash     = av_sha_alloc();
     101           1 :         break;
     102           1 :     case AV_HMAC_SHA256:
     103           1 :         c->blocklen = 64;
     104           1 :         c->hashlen  = 32;
     105           1 :         c->init     = sha256_init;
     106           1 :         c->update   = (hmac_update) av_sha_update;
     107           1 :         c->final    = (hmac_final) av_sha_final;
     108           1 :         c->hash     = av_sha_alloc();
     109           1 :         break;
     110           1 :     case AV_HMAC_SHA384:
     111           1 :         c->blocklen = 128;
     112           1 :         c->hashlen  = 48;
     113           1 :         c->init     = sha384_init;
     114           1 :         c->update   = (hmac_update) av_sha512_update;
     115           1 :         c->final    = (hmac_final) av_sha512_final;
     116           1 :         c->hash     = av_sha512_alloc();
     117           1 :         break;
     118           1 :     case AV_HMAC_SHA512:
     119           1 :         c->blocklen = 128;
     120           1 :         c->hashlen  = 64;
     121           1 :         c->init     = sha512_init;
     122           1 :         c->update   = (hmac_update) av_sha512_update;
     123           1 :         c->final    = (hmac_final) av_sha512_final;
     124           1 :         c->hash     = av_sha512_alloc();
     125           1 :         break;
     126           0 :     default:
     127           0 :         av_free(c);
     128           0 :         return NULL;
     129             :     }
     130          21 :     if (!c->hash) {
     131           0 :         av_free(c);
     132           0 :         return NULL;
     133             :     }
     134          21 :     return c;
     135             : }
     136             : 
     137          21 : void av_hmac_free(AVHMAC *c)
     138             : {
     139          21 :     if (!c)
     140           0 :         return;
     141          21 :     av_freep(&c->hash);
     142          21 :     av_free(c);
     143             : }
     144             : 
     145          48 : void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
     146             : {
     147             :     int i;
     148             :     uint8_t block[MAX_BLOCKLEN];
     149          48 :     if (keylen > c->blocklen) {
     150          12 :         c->init(c->hash);
     151          12 :         c->update(c->hash, key, keylen);
     152          12 :         c->final(c->hash, c->key);
     153          12 :         c->keylen = c->hashlen;
     154             :     } else {
     155          36 :         memcpy(c->key, key, keylen);
     156          36 :         c->keylen = keylen;
     157             :     }
     158          48 :     c->init(c->hash);
     159        1080 :     for (i = 0; i < c->keylen; i++)
     160        1032 :         block[i] = c->key[i] ^ 0x36;
     161        2728 :     for (i = c->keylen; i < c->blocklen; i++)
     162        2680 :         block[i] = 0x36;
     163          48 :     c->update(c->hash, block, c->blocklen);
     164          48 : }
     165             : 
     166          57 : void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
     167             : {
     168          57 :     c->update(c->hash, data, len);
     169          57 : }
     170             : 
     171          48 : int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
     172             : {
     173             :     uint8_t block[MAX_BLOCKLEN];
     174             :     int i;
     175          48 :     if (outlen < c->hashlen)
     176           0 :         return AVERROR(EINVAL);
     177          48 :     c->final(c->hash, out);
     178          48 :     c->init(c->hash);
     179        1080 :     for (i = 0; i < c->keylen; i++)
     180        1032 :         block[i] = c->key[i] ^ 0x5C;
     181        2728 :     for (i = c->keylen; i < c->blocklen; i++)
     182        2680 :         block[i] = 0x5C;
     183          48 :     c->update(c->hash, block, c->blocklen);
     184          48 :     c->update(c->hash, out, c->hashlen);
     185          48 :     c->final(c->hash, out);
     186          48 :     return c->hashlen;
     187             : }
     188             : 
     189          30 : int av_hmac_calc(AVHMAC *c, const uint8_t *data, unsigned int len,
     190             :                  const uint8_t *key, unsigned int keylen,
     191             :                  uint8_t *out, unsigned int outlen)
     192             : {
     193          30 :     av_hmac_init(c, key, keylen);
     194          30 :     av_hmac_update(c, data, len);
     195          30 :     return av_hmac_final(c, out, outlen);
     196             : }

Generated by: LCOV version 1.13