LCOV - code coverage report
Current view: top level - lib - hmac.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 143 148 96.6 %
Date: 2015-08-23 Functions: 21 21 100.0 %
Branches: 17 22 77.3 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *****************************************************************************
       3                 :            :  *
       4                 :            :  * File:    fko_hmac.c
       5                 :            :  *
       6                 :            :  * Purpose: Provide HMAC support to SPA communications
       7                 :            :  *
       8                 :            :  *  Fwknop is developed primarily by the people listed in the file 'AUTHORS'.
       9                 :            :  *  Copyright (C) 2009-2014 fwknop developers and contributors. For a full
      10                 :            :  *  list of contributors, see the file 'CREDITS'.
      11                 :            :  *
      12                 :            :  *  License (GNU General Public License):
      13                 :            :  *
      14                 :            :  *  This program is free software; you can redistribute it and/or
      15                 :            :  *  modify it under the terms of the GNU General Public License
      16                 :            :  *  as published by the Free Software Foundation; either version 2
      17                 :            :  *  of the License, or (at your option) any later version.
      18                 :            :  *
      19                 :            :  *  This program is distributed in the hope that it will be useful,
      20                 :            :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      21                 :            :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      22                 :            :  *  GNU General Public License for more details.
      23                 :            :  *
      24                 :            :  *  You should have received a copy of the GNU General Public License
      25                 :            :  *  along with this program; if not, write to the Free Software
      26                 :            :  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
      27                 :            :  *  USA
      28                 :            :  *
      29                 :            :  *****************************************************************************
      30                 :            : */
      31                 :            : 
      32                 :            : #include "hmac.h"
      33                 :            : 
      34                 :            : typedef struct {
      35                 :            :     MD5Context ctx_inside;
      36                 :            :     MD5Context ctx_outside;
      37                 :            : 
      38                 :            :     unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN];
      39                 :            :     unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN];
      40                 :            : } hmac_md5_ctx;
      41                 :            : 
      42                 :            : typedef struct {
      43                 :            :     SHA1_INFO ctx_inside;
      44                 :            :     SHA1_INFO ctx_outside;
      45                 :            : 
      46                 :            :     unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN];
      47                 :            :     unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN];
      48                 :            : } hmac_sha1_ctx;
      49                 :            : 
      50                 :            : typedef struct {
      51                 :            :     SHA256_CTX ctx_inside;
      52                 :            :     SHA256_CTX ctx_outside;
      53                 :            : 
      54                 :            :     unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN];
      55                 :            :     unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN];
      56                 :            : } hmac_sha256_ctx;
      57                 :            : 
      58                 :            : typedef struct {
      59                 :            :     SHA384_CTX ctx_inside;
      60                 :            :     SHA384_CTX ctx_outside;
      61                 :            : 
      62                 :            :     unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN];
      63                 :            :     unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN];
      64                 :            : } hmac_sha384_ctx;
      65                 :            : 
      66                 :            : typedef struct {
      67                 :            :     SHA512_CTX ctx_inside;
      68                 :            :     SHA512_CTX ctx_outside;
      69                 :            : 
      70                 :            :     unsigned char block_inner_pad[MAX_DIGEST_BLOCK_LEN];
      71                 :            :     unsigned char block_outer_pad[MAX_DIGEST_BLOCK_LEN];
      72                 :            : } hmac_sha512_ctx;
      73                 :            : 
      74                 :            : static void
      75                 :    1524278 : pad_init(unsigned char *inner_pad, unsigned char *outer_pad,
      76                 :            :         const unsigned char * const key, const int key_len)
      77                 :            : {
      78                 :    1524278 :     int i = 0;
      79                 :            : 
      80         [ +  + ]:  194572639 :     for (i=0; i < MAX_DIGEST_BLOCK_LEN && i < key_len; i++) {
      81                 :  193048361 :         inner_pad[i] = key[i] ^ 0x36;
      82                 :  193048361 :         outer_pad[i] = key[i] ^ 0x5c;
      83                 :            :     }
      84                 :            : 
      85         [ +  + ]:    1524278 :     if(i < MAX_DIGEST_BLOCK_LEN)
      86                 :            :     {
      87         [ +  + ]:    2080520 :         while(i < MAX_DIGEST_BLOCK_LEN)
      88                 :            :         {
      89                 :    2059223 :             inner_pad[i] = 0x36;
      90                 :    2059223 :             outer_pad[i] = 0x5c;
      91                 :    2059223 :             i++;
      92                 :            :         }
      93                 :            :     }
      94                 :    1524278 :     return;
      95                 :            : }
      96                 :            : 
      97                 :            : /* Begin MD5 HMAC functions
      98                 :            : */
      99                 :            : static void
     100                 :         51 : hmac_md5_init(hmac_md5_ctx *ctx, const char *key, const int key_len)
     101                 :            : {
     102                 :         51 :     unsigned char  final_key[MAX_DIGEST_BLOCK_LEN] = {0};
     103                 :         51 :     unsigned char  init_key[MAX_DIGEST_BLOCK_LEN]  = {0};
     104                 :         51 :     int            final_len = key_len;
     105                 :            : 
     106         [ -  + ]:         51 :     if(key_len > MAX_DIGEST_BLOCK_LEN)
     107                 :          0 :         final_len = MAX_DIGEST_BLOCK_LEN;
     108                 :            : 
     109                 :         51 :     memcpy(init_key, key, final_len);
     110                 :            : 
     111         [ +  + ]:         51 :     if(MD5_BLOCK_LEN < key_len)
     112                 :            :     {
     113                 :            :         /* Calculate the digest of the key
     114                 :            :         */
     115                 :          3 :         md5(final_key, init_key, final_len);
     116                 :            :     }
     117                 :            :     else
     118                 :            :     {
     119                 :         48 :         memcpy(final_key, init_key, key_len);
     120                 :            :     }
     121                 :            : 
     122                 :         51 :     pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len);
     123                 :            : 
     124                 :         51 :     MD5Init(&ctx->ctx_inside);
     125                 :         51 :     MD5Update(&ctx->ctx_inside, ctx->block_inner_pad, MD5_BLOCK_LEN);
     126                 :            : 
     127                 :         51 :     MD5Init(&ctx->ctx_outside);
     128                 :         51 :     MD5Update(&ctx->ctx_outside, ctx->block_outer_pad, MD5_BLOCK_LEN);
     129                 :            : 
     130                 :         51 :     return;
     131                 :            : }
     132                 :            : 
     133                 :            : static void
     134                 :         51 : hmac_md5_update(hmac_md5_ctx *ctx, const char *msg,
     135                 :            :     unsigned int msg_len)
     136                 :            : {
     137                 :         51 :     MD5Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len);
     138                 :         51 :     return;
     139                 :            : }
     140                 :            : 
     141                 :            : static void
     142                 :         51 : hmac_md5_final(hmac_md5_ctx *ctx, unsigned char *hmac)
     143                 :            : {
     144                 :            :     unsigned char digest_inside[MD5_DIGEST_LEN];
     145                 :            : 
     146                 :         51 :     MD5Final(digest_inside, &ctx->ctx_inside);
     147                 :         51 :     MD5Update(&ctx->ctx_outside, digest_inside, MD5_DIGEST_LEN);
     148                 :         51 :     MD5Final(hmac, &ctx->ctx_outside);
     149                 :            : 
     150                 :         51 :     return;
     151                 :            : }
     152                 :            : 
     153                 :            : void
     154                 :         51 : hmac_md5(const char *msg, const unsigned int msg_len,
     155                 :            :     unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
     156                 :            : {
     157                 :            :     hmac_md5_ctx ctx;
     158                 :            : 
     159                 :            :     memset(&ctx, 0, sizeof(ctx));
     160                 :            : 
     161                 :         51 :     hmac_md5_init(&ctx, hmac_key, hmac_key_len);
     162                 :         51 :     hmac_md5_update(&ctx, msg, msg_len);
     163                 :         51 :     hmac_md5_final(&ctx, hmac);
     164                 :            : 
     165                 :         51 :     return;
     166                 :            : }
     167                 :            : 
     168                 :            : /* Begin SHA1 HMAC functions
     169                 :            : */
     170                 :            : static void
     171                 :         85 : hmac_sha1_init(hmac_sha1_ctx *ctx, const char *key, const int key_len)
     172                 :            : {
     173                 :         85 :     unsigned char  final_key[MAX_DIGEST_BLOCK_LEN] = {0};
     174                 :         85 :     unsigned char  init_key[MAX_DIGEST_BLOCK_LEN]  = {0};
     175                 :         85 :     int            final_len = key_len;
     176                 :            : 
     177         [ -  + ]:         85 :     if(key_len > MAX_DIGEST_BLOCK_LEN)
     178                 :          0 :         final_len = MAX_DIGEST_BLOCK_LEN;
     179                 :            : 
     180                 :         85 :     memcpy(init_key, key, final_len);
     181                 :            : 
     182         [ +  + ]:         85 :     if(SHA1_BLOCK_LEN < key_len)
     183                 :            :     {
     184                 :            :         /* Calculate the digest of the key
     185                 :            :         */
     186                 :          3 :         sha1(final_key, init_key, final_len);
     187                 :            :     }
     188                 :            :     else
     189                 :            :     {
     190                 :         82 :         memcpy(final_key, init_key, key_len);
     191                 :            :     }
     192                 :            : 
     193                 :         85 :     pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len);
     194                 :            : 
     195                 :         85 :     sha1_init(&ctx->ctx_inside);
     196                 :         85 :     sha1_update(&ctx->ctx_inside, ctx->block_inner_pad, SHA1_BLOCK_LEN);
     197                 :            : 
     198                 :         85 :     sha1_init(&ctx->ctx_outside);
     199                 :         85 :     sha1_update(&ctx->ctx_outside, ctx->block_outer_pad, SHA1_BLOCK_LEN);
     200                 :            : 
     201                 :         85 :     return;
     202                 :            : }
     203                 :            : 
     204                 :            : static void
     205                 :         85 : hmac_sha1_update(hmac_sha1_ctx *ctx, const char *msg,
     206                 :            :     unsigned int msg_len)
     207                 :            : {
     208                 :         85 :     sha1_update(&ctx->ctx_inside, (unsigned char *)msg, msg_len);
     209                 :         85 :     return;
     210                 :            : }
     211                 :            : 
     212                 :            : static void
     213                 :         85 : hmac_sha1_final(hmac_sha1_ctx *ctx, unsigned char *hmac)
     214                 :            : {
     215                 :            :     unsigned char digest_inside[SHA1_DIGEST_LEN];
     216                 :            : 
     217                 :         85 :     sha1_final(digest_inside, &ctx->ctx_inside);
     218                 :         85 :     sha1_update(&ctx->ctx_outside, digest_inside, SHA1_DIGEST_LEN);
     219                 :         85 :     sha1_final(hmac, &ctx->ctx_outside);
     220                 :            : 
     221                 :         85 :     return;
     222                 :            : }
     223                 :            : 
     224                 :            : void
     225                 :         85 : hmac_sha1(const char *msg, const unsigned int msg_len,
     226                 :            :     unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
     227                 :            : {
     228                 :            :     hmac_sha1_ctx ctx;
     229                 :            : 
     230                 :            :     memset(&ctx, 0, sizeof(ctx));
     231                 :            : 
     232                 :         85 :     hmac_sha1_init(&ctx, hmac_key, hmac_key_len);
     233                 :         85 :     hmac_sha1_update(&ctx, msg, msg_len);
     234                 :         85 :     hmac_sha1_final(&ctx, hmac);
     235                 :            : 
     236                 :         85 :     return;
     237                 :            : }
     238                 :            : 
     239                 :            : /* Begin SHA256 HMAC functions
     240                 :            : */
     241                 :            : static void
     242                 :    1524026 : hmac_sha256_init(hmac_sha256_ctx *ctx, const char *key, const int key_len)
     243                 :            : {
     244                 :    1524026 :     unsigned char  final_key[MAX_DIGEST_BLOCK_LEN] = {0};
     245                 :    1524026 :     unsigned char  init_key[MAX_DIGEST_BLOCK_LEN]  = {0};
     246                 :    1524026 :     int            final_len = key_len;
     247                 :            : 
     248         [ -  + ]:    1524026 :     if(key_len > MAX_DIGEST_BLOCK_LEN)
     249                 :          0 :         final_len = MAX_DIGEST_BLOCK_LEN;
     250                 :            : 
     251                 :    1524026 :     memcpy(init_key, key, final_len);
     252                 :            : 
     253         [ +  + ]:    1524026 :     if(SHA256_BLOCK_LEN < key_len)
     254                 :            :     {
     255                 :            :         /* Calculate the digest of the key
     256                 :            :         */
     257                 :    1503017 :         sha256(final_key, init_key, final_len);
     258                 :            :     }
     259                 :            :     else
     260                 :            :     {
     261                 :      21009 :         memcpy(final_key, init_key, key_len);
     262                 :            :     }
     263                 :            : 
     264                 :    1524026 :     pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len);
     265                 :            : 
     266                 :    1524026 :     SHA256_Init(&ctx->ctx_inside);
     267                 :    1524026 :     SHA256_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA256_BLOCK_LEN);
     268                 :            : 
     269                 :    1524026 :     SHA256_Init(&ctx->ctx_outside);
     270                 :    1524026 :     SHA256_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA256_BLOCK_LEN);
     271                 :            : 
     272                 :    1524026 :     return;
     273                 :            : }
     274                 :            : 
     275                 :            : static void
     276                 :    1524026 : hmac_sha256_update(hmac_sha256_ctx *ctx, const char *msg,
     277                 :            :     unsigned int msg_len)
     278                 :            : {
     279                 :    1524026 :     SHA256_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len);
     280                 :    1524026 :     return;
     281                 :            : }
     282                 :            : 
     283                 :            : static void
     284                 :    1524026 : hmac_sha256_final(hmac_sha256_ctx *ctx, unsigned char *hmac)
     285                 :            : {
     286                 :            :     unsigned char digest_inside[SHA256_DIGEST_LEN];
     287                 :            : 
     288                 :    1524026 :     SHA256_Final(digest_inside, &ctx->ctx_inside);
     289                 :    1524026 :     SHA256_Update(&ctx->ctx_outside, digest_inside, SHA256_DIGEST_LEN);
     290                 :    1524026 :     SHA256_Final(hmac, &ctx->ctx_outside);
     291                 :            : 
     292                 :    1524026 :     return;
     293                 :            : }
     294                 :            : 
     295                 :            : void
     296                 :    1524026 : hmac_sha256(const char *msg, const unsigned int msg_len,
     297                 :            :     unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
     298                 :            : {
     299                 :            :     hmac_sha256_ctx ctx;
     300                 :            : 
     301                 :            :     memset(&ctx, 0, sizeof(ctx));
     302                 :            : 
     303                 :    1524026 :     hmac_sha256_init(&ctx, hmac_key, hmac_key_len);
     304                 :    1524026 :     hmac_sha256_update(&ctx, msg, msg_len);
     305                 :    1524026 :     hmac_sha256_final(&ctx, hmac);
     306                 :            : 
     307                 :    1524026 :     return;
     308                 :            : }
     309                 :            : 
     310                 :            : /* Begin SHA384 HMAC functions
     311                 :            : */
     312                 :            : static void
     313                 :         51 : hmac_sha384_init(hmac_sha384_ctx *ctx, const char *key, const int key_len)
     314                 :            : {
     315                 :         51 :     unsigned char  final_key[MAX_DIGEST_BLOCK_LEN] = {0};
     316                 :         51 :     int            final_len = key_len;
     317                 :            : 
     318         [ -  + ]:         51 :     if(key_len > MAX_DIGEST_BLOCK_LEN)
     319                 :          0 :         final_len = MAX_DIGEST_BLOCK_LEN;
     320                 :            : 
     321                 :            :     /* When we eventually support arbitrary key sizes, take the digest
     322                 :            :      * of the key with: sha384(final_key, init_key, final_len);
     323                 :            :     */
     324                 :         51 :     memcpy(final_key, key, final_len);
     325                 :            : 
     326                 :         51 :     pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len);
     327                 :            : 
     328                 :         51 :     SHA384_Init(&ctx->ctx_inside);
     329                 :         51 :     SHA384_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA384_BLOCK_LEN);
     330                 :            : 
     331                 :         51 :     SHA384_Init(&ctx->ctx_outside);
     332                 :         51 :     SHA384_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA384_BLOCK_LEN);
     333                 :            : 
     334                 :         51 :     return;
     335                 :            : }
     336                 :            : 
     337                 :            : static void
     338                 :         51 : hmac_sha384_update(hmac_sha384_ctx *ctx, const char *msg,
     339                 :            :     unsigned int msg_len)
     340                 :            : {
     341                 :         51 :     SHA384_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len);
     342                 :         51 :     return;
     343                 :            : }
     344                 :            : 
     345                 :            : static void
     346                 :         51 : hmac_sha384_final(hmac_sha384_ctx *ctx, unsigned char *hmac)
     347                 :            : {
     348                 :            :     unsigned char digest_inside[SHA384_DIGEST_LEN];
     349                 :            : 
     350                 :         51 :     SHA384_Final(digest_inside, &ctx->ctx_inside);
     351                 :         51 :     SHA384_Update(&ctx->ctx_outside, digest_inside, SHA384_DIGEST_LEN);
     352                 :         51 :     SHA384_Final(hmac, &ctx->ctx_outside);
     353                 :            : 
     354                 :         51 :     return;
     355                 :            : }
     356                 :            : 
     357                 :            : void
     358                 :         51 : hmac_sha384(const char *msg, const unsigned int msg_len,
     359                 :            :     unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
     360                 :            : {
     361                 :            :     hmac_sha384_ctx ctx;
     362                 :            : 
     363                 :            :     memset(&ctx, 0, sizeof(ctx));
     364                 :            : 
     365                 :         51 :     hmac_sha384_init(&ctx, hmac_key, hmac_key_len);
     366                 :         51 :     hmac_sha384_update(&ctx, msg, msg_len);
     367                 :         51 :     hmac_sha384_final(&ctx, hmac);
     368                 :            : 
     369                 :         51 :     return;
     370                 :            : }
     371                 :            : 
     372                 :            : /* Begin SHA512 HMAC functions
     373                 :            : */
     374                 :            : static void
     375                 :         65 : hmac_sha512_init(hmac_sha512_ctx *ctx, const char *key, const int key_len)
     376                 :            : {
     377                 :         65 :     unsigned char  final_key[MAX_DIGEST_BLOCK_LEN] = {0};
     378                 :         65 :     int            final_len = key_len;
     379                 :            : 
     380         [ -  + ]:         65 :     if(key_len > MAX_DIGEST_BLOCK_LEN)
     381                 :          0 :         final_len = MAX_DIGEST_BLOCK_LEN;
     382                 :            : 
     383                 :            :     /* When we eventually support arbitrary key sizes, take the digest
     384                 :            :      * of the key with: sha512(final_key, init_key, final_len);
     385                 :            :     */
     386                 :         65 :     memcpy(final_key, key, final_len);
     387                 :            : 
     388                 :         65 :     pad_init(ctx->block_inner_pad, ctx->block_outer_pad, final_key, final_len);
     389                 :            : 
     390                 :         65 :     SHA512_Init(&ctx->ctx_inside);
     391                 :         65 :     SHA512_Update(&ctx->ctx_inside, ctx->block_inner_pad, SHA512_BLOCK_LEN);
     392                 :            : 
     393                 :         65 :     SHA512_Init(&ctx->ctx_outside);
     394                 :         65 :     SHA512_Update(&ctx->ctx_outside, ctx->block_outer_pad, SHA512_BLOCK_LEN);
     395                 :            : 
     396                 :         65 :     return;
     397                 :            : }
     398                 :            : 
     399                 :            : static void
     400                 :         65 : hmac_sha512_update(hmac_sha512_ctx *ctx, const char *msg,
     401                 :            :     unsigned int msg_len)
     402                 :            : {
     403                 :         65 :     SHA512_Update(&ctx->ctx_inside, (unsigned char *)msg, msg_len);
     404                 :         65 :     return;
     405                 :            : }
     406                 :            : 
     407                 :            : static void
     408                 :         65 : hmac_sha512_final(hmac_sha512_ctx *ctx, unsigned char *hmac)
     409                 :            : {
     410                 :            :     unsigned char digest_inside[SHA512_DIGEST_LEN];
     411                 :            : 
     412                 :         65 :     SHA512_Final(digest_inside, &ctx->ctx_inside);
     413                 :         65 :     SHA512_Update(&ctx->ctx_outside, digest_inside, SHA512_DIGEST_LEN);
     414                 :         65 :     SHA512_Final(hmac, &ctx->ctx_outside);
     415                 :            : 
     416                 :         65 :     return;
     417                 :            : }
     418                 :            : 
     419                 :            : void
     420                 :         65 : hmac_sha512(const char *msg, const unsigned int msg_len,
     421                 :            :     unsigned char *hmac, const char *hmac_key, const int hmac_key_len)
     422                 :            : {
     423                 :            :     hmac_sha512_ctx ctx;
     424                 :            : 
     425                 :            :     memset(&ctx, 0, sizeof(ctx));
     426                 :            : 
     427                 :         65 :     hmac_sha512_init(&ctx, hmac_key, hmac_key_len);
     428                 :         65 :     hmac_sha512_update(&ctx, msg, msg_len);
     429                 :         65 :     hmac_sha512_final(&ctx, hmac);
     430                 :            : 
     431                 :         65 :     return;
     432                 :            : }

Generated by: LCOV version 1.10