LCOV - code coverage report
Current view: top level - lib - fko_hmac.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 120 124 96.8 %
Date: 2016-06-07 Functions: 5 5 100.0 %
Branches: 91 110 82.7 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * \file lib/fko_hmac.c
       3                 :            :  *
       4                 :            :  * \brief Provide HMAC support to SPA communications
       5                 :            :  */
       6                 :            : 
       7                 :            : /*  Fwknop is developed primarily by the people listed in the file 'AUTHORS'.
       8                 :            :  *  Copyright (C) 2009-2015 fwknop developers and contributors. For a full
       9                 :            :  *  list of contributors, see the file 'CREDITS'.
      10                 :            :  *
      11                 :            :  *  License (GNU General Public License):
      12                 :            :  *
      13                 :            :  *  This program is free software; you can redistribute it and/or
      14                 :            :  *  modify it under the terms of the GNU General Public License
      15                 :            :  *  as published by the Free Software Foundation; either version 2
      16                 :            :  *  of the License, or (at your option) any later version.
      17                 :            :  *
      18                 :            :  *  This program is distributed in the hope that it will be useful,
      19                 :            :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      20                 :            :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      21                 :            :  *  GNU General Public License for more details.
      22                 :            :  *
      23                 :            :  *  You should have received a copy of the GNU General Public License
      24                 :            :  *  along with this program; if not, write to the Free Software
      25                 :            :  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
      26                 :            :  *  USA
      27                 :            :  *
      28                 :            :  *****************************************************************************
      29                 :            : */
      30                 :            : #include "fko_common.h"
      31                 :            : #include "fko.h"
      32                 :            : #include "cipher_funcs.h"
      33                 :            : #include "hmac.h"
      34                 :            : #include "base64.h"
      35                 :            : 
      36                 :            : int
      37                 :     768146 : fko_verify_hmac(fko_ctx_t ctx,
      38                 :            :     const char * const hmac_key, const int hmac_key_len)
      39                 :            : {
      40                 :     768146 :     char    *hmac_digest_from_data = NULL;
      41                 :     768146 :     char    *tbuf = NULL;
      42                 :     768146 :     int      res = FKO_SUCCESS;
      43                 :     768146 :     int      hmac_b64_digest_len = 0, zero_free_rv = FKO_SUCCESS;
      44                 :            : 
      45                 :            :     /* Must be initialized
      46                 :            :     */
      47 [ +  + ][ +  - ]:     768146 :     if(!CTX_INITIALIZED(ctx))
      48                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
      49                 :            : 
      50         [ +  - ]:     768086 :     if(hmac_key == NULL)
      51                 :            :         return(FKO_ERROR_INVALID_DATA);
      52                 :            : 
      53         [ +  - ]:     768086 :     if (! is_valid_encoded_msg_len(ctx->encrypted_msg_len))
      54                 :            :         return(FKO_ERROR_INVALID_DATA_HMAC_MSGLEN_VALIDFAIL);
      55                 :            : 
      56         [ +  + ]:     768086 :     if(hmac_key_len < 0 || hmac_key_len > MAX_DIGEST_BLOCK_LEN)
      57                 :            :         return(FKO_ERROR_INVALID_HMAC_KEY_LEN);
      58                 :            : 
      59         [ +  + ]:     768085 :     if(ctx->hmac_type == FKO_HMAC_MD5)
      60                 :            :         hmac_b64_digest_len = MD5_B64_LEN;
      61         [ +  + ]:     768079 :     else if(ctx->hmac_type == FKO_HMAC_SHA1)
      62                 :            :         hmac_b64_digest_len = SHA1_B64_LEN;
      63         [ +  + ]:     768058 :     else if(ctx->hmac_type == FKO_HMAC_SHA256)
      64                 :            :         hmac_b64_digest_len = SHA256_B64_LEN;
      65         [ +  + ]:         17 :     else if(ctx->hmac_type == FKO_HMAC_SHA384)
      66                 :            :         hmac_b64_digest_len = SHA384_B64_LEN;
      67         [ +  + ]:         11 :     else if(ctx->hmac_type == FKO_HMAC_SHA512)
      68                 :            :         hmac_b64_digest_len = SHA512_B64_LEN;
      69         [ +  + ]:          2 :     else if(ctx->hmac_type == FKO_HMAC_SHA3_256)
      70                 :            :         hmac_b64_digest_len = SHA3_256_B64_LEN;
      71         [ +  - ]:          1 :     else if(ctx->hmac_type == FKO_HMAC_SHA3_512)
      72                 :            :         hmac_b64_digest_len = SHA3_512_B64_LEN;
      73                 :            :     else
      74                 :            :         return(FKO_ERROR_UNSUPPORTED_HMAC_MODE);
      75                 :            : 
      76         [ +  + ]:     768085 :     if((ctx->encrypted_msg_len - hmac_b64_digest_len)
      77                 :            :             < MIN_SPA_ENCODED_MSG_SIZE)
      78                 :            :         return(FKO_ERROR_INVALID_DATA_HMAC_ENCMSGLEN_VALIDFAIL);
      79                 :            : 
      80                 :            :     /* Get digest value
      81                 :            :     */
      82                 :    1536150 :     hmac_digest_from_data = strndup((ctx->encrypted_msg
      83                 :     768075 :             + ctx->encrypted_msg_len - hmac_b64_digest_len),
      84                 :            :             hmac_b64_digest_len);
      85                 :            : 
      86         [ +  - ]:     768075 :     if(hmac_digest_from_data == NULL)
      87                 :            :         return(FKO_ERROR_MEMORY_ALLOCATION);
      88                 :            : 
      89                 :            :     /* Now we chop the HMAC digest off of the encrypted msg
      90                 :            :     */
      91                 :     768075 :     tbuf = strndup(ctx->encrypted_msg,
      92                 :            :             ctx->encrypted_msg_len - hmac_b64_digest_len);
      93                 :            : 
      94         [ -  + ]:     768075 :     if(tbuf == NULL)
      95                 :            :     {
      96         [ #  # ]:          0 :         if(zero_free(hmac_digest_from_data, strnlen(hmac_digest_from_data,
      97                 :            :                 MAX_SPA_ENCODED_MSG_SIZE)) == FKO_SUCCESS)
      98                 :            :             return(FKO_ERROR_MEMORY_ALLOCATION);
      99                 :            :         else
     100                 :          0 :             return(FKO_ERROR_ZERO_OUT_DATA);
     101                 :            :     }
     102                 :            : 
     103         [ +  + ]:     768075 :     if(zero_free(ctx->encrypted_msg, ctx->encrypted_msg_len) != FKO_SUCCESS)
     104                 :          2 :         zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
     105                 :            : 
     106                 :     768075 :     ctx->encrypted_msg      = tbuf;
     107                 :     768075 :     ctx->encrypted_msg_len -= hmac_b64_digest_len;
     108                 :            : 
     109         [ +  + ]:     768075 :     if(ctx->encryption_mode == FKO_ENC_MODE_ASYMMETRIC)
     110                 :            :     {
     111                 :            :         /* See if we need to add the "hQ" string to the front of the
     112                 :            :          * encrypted data.
     113                 :            :          */
     114         [ +  - ]:         24 :         if(! ctx->added_gpg_prefix)
     115                 :            :         {
     116                 :         24 :             res = add_gpg_prefix(ctx);
     117                 :            :         }
     118                 :            :     }
     119                 :            :     else
     120                 :            :     {
     121                 :            :         /* See if we need to add the "Salted__" string to the front of the
     122                 :            :          * encrypted data.
     123                 :            :          */
     124         [ +  + ]:     768051 :         if(! ctx->added_salted_str)
     125                 :            :         {
     126                 :     768043 :             res = add_salted_str(ctx);
     127                 :            :         }
     128                 :            :     }
     129                 :            : 
     130         [ +  + ]:     768075 :     if (res != FKO_SUCCESS)
     131                 :            :     {
     132         [ -  + ]:         30 :         if(zero_free(hmac_digest_from_data, strnlen(hmac_digest_from_data,
     133                 :            :                         MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS)
     134                 :          0 :             zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
     135                 :            : 
     136         [ -  + ]:         30 :         if(zero_free_rv == FKO_SUCCESS)
     137                 :            :             return(res);
     138                 :            :         else
     139                 :          0 :             return(zero_free_rv);
     140                 :            :     }
     141                 :            : 
     142                 :            :     /* Calculate the HMAC from the encrypted data and then
     143                 :            :      * compare
     144                 :            :     */
     145                 :     768045 :     res = fko_set_spa_hmac_type(ctx, ctx->hmac_type);
     146         [ +  - ]:     768045 :     if(res == FKO_SUCCESS)
     147                 :            :     {
     148                 :     768045 :         res = fko_set_spa_hmac(ctx, hmac_key, hmac_key_len);
     149                 :            : 
     150         [ +  + ]:     768045 :         if(res == FKO_SUCCESS)
     151                 :            :         {
     152         [ +  + ]:     768002 :             if(constant_runtime_cmp(hmac_digest_from_data,
     153                 :     768002 :                     ctx->msg_hmac, hmac_b64_digest_len) != 0)
     154                 :            :             {
     155                 :       2121 :                 res = FKO_ERROR_INVALID_DATA_HMAC_COMPAREFAIL;
     156                 :            :             }
     157                 :            :         }
     158                 :            :     }
     159                 :            : 
     160         [ +  + ]:     768045 :     if(zero_free(hmac_digest_from_data, strnlen(hmac_digest_from_data,
     161                 :            :                     MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS)
     162                 :          2 :         zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
     163                 :            : 
     164         [ +  + ]:     768045 :     if(res == FKO_SUCCESS)
     165                 :            :         return(zero_free_rv);
     166                 :            :     else
     167                 :       2164 :         return(res);
     168                 :            : }
     169                 :            : 
     170                 :            : /* Return the fko HMAC data
     171                 :            : */
     172                 :            : int
     173                 :       3924 : fko_get_spa_hmac(fko_ctx_t ctx, char **hmac_data)
     174                 :            : {
     175                 :            :     /* Must be initialized
     176                 :            :     */
     177 [ +  + ][ +  - ]:       3924 :     if(!CTX_INITIALIZED(ctx))
     178                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
     179                 :            : 
     180         [ +  + ]:       3772 :     if(hmac_data == NULL)
     181                 :            :         return(FKO_ERROR_INVALID_DATA);
     182                 :            : 
     183                 :       3704 :     *hmac_data = ctx->msg_hmac;
     184                 :            : 
     185                 :       3704 :     return(FKO_SUCCESS);
     186                 :            : }
     187                 :            : 
     188                 :            : /* Set the HMAC type
     189                 :            : */
     190                 :            : int
     191                 :    2405335 : fko_set_spa_hmac_type(fko_ctx_t ctx, const short hmac_type)
     192                 :            : {
     193                 :            : #if HAVE_LIBFIU
     194         [ +  + ]:    2405335 :     fiu_return_on("fko_set_spa_hmac_type_init",
     195                 :            :             FKO_ERROR_CTX_NOT_INITIALIZED);
     196                 :            : #endif
     197                 :            : 
     198                 :            :     /* Must be initialized
     199                 :            :     */
     200 [ +  + ][ +  - ]:    2405334 :     if(!CTX_INITIALIZED(ctx))
     201                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
     202                 :            : 
     203                 :            : #if HAVE_LIBFIU
     204         [ +  + ]:    2404480 :     fiu_return_on("fko_set_spa_hmac_type_val",
     205                 :            :             FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL);
     206                 :            : #endif
     207                 :            : 
     208         [ +  + ]:    2404479 :     if(hmac_type < 0 || hmac_type >= FKO_LAST_HMAC_MODE)
     209                 :            :         return(FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL);
     210                 :            : 
     211                 :    2400436 :     ctx->hmac_type = hmac_type;
     212                 :            : 
     213                 :    2400436 :     ctx->state |= FKO_HMAC_MODE_MODIFIED;
     214                 :            : 
     215                 :    2400436 :     return(FKO_SUCCESS);
     216                 :            : }
     217                 :            : 
     218                 :            : /* Return the fko HMAC type
     219                 :            : */
     220                 :            : int
     221                 :       5617 : fko_get_spa_hmac_type(fko_ctx_t ctx, short *hmac_type)
     222                 :            : {
     223                 :            :     /* Must be initialized
     224                 :            :     */
     225 [ +  + ][ +  - ]:       5617 :     if(!CTX_INITIALIZED(ctx))
     226                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
     227                 :            : 
     228         [ +  + ]:       5045 :     if(hmac_type == NULL)
     229                 :            :         return(FKO_ERROR_INVALID_DATA);
     230                 :            : 
     231                 :       4977 :     *hmac_type = ctx->hmac_type;
     232                 :            : 
     233                 :       4977 :     return(FKO_SUCCESS);
     234                 :            : }
     235                 :            : 
     236                 :    1522942 : int fko_set_spa_hmac(fko_ctx_t ctx,
     237                 :            :     const char * const hmac_key, const int hmac_key_len)
     238                 :            : {
     239                 :    1522942 :     unsigned char hmac[SHA512_DIGEST_STR_LEN] = {0};
     240                 :    1522942 :     char *hmac_base64 = NULL;
     241                 :    1522942 :     int   hmac_digest_str_len = 0;
     242                 :    1522942 :     int   hmac_digest_len = 0;
     243                 :    1522942 :     int   res = FKO_ERROR_UNKNOWN ;
     244                 :            : 
     245                 :            :     /* Must be initialized
     246                 :            :     */
     247 [ +  + ][ +  - ]:    1522942 :     if(!CTX_INITIALIZED(ctx))
     248                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
     249                 :            : 
     250         [ +  + ]:    1522934 :     if(hmac_key == NULL)
     251                 :            :         return(FKO_ERROR_INVALID_DATA);
     252                 :            : 
     253         [ +  + ]:    1522910 :     if(hmac_key_len < 0 || hmac_key_len > MAX_DIGEST_BLOCK_LEN)
     254                 :            :         return(FKO_ERROR_INVALID_HMAC_KEY_LEN);
     255                 :            : 
     256         [ +  + ]:    1522856 :     if(ctx->hmac_type == FKO_HMAC_MD5)
     257                 :            :     {
     258                 :         51 :         res = hmac_md5(ctx->encrypted_msg,
     259                 :         51 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     260                 :            : 
     261                 :         51 :         hmac_digest_len     = MD5_DIGEST_LEN;
     262                 :         51 :         hmac_digest_str_len = MD5_DIGEST_STR_LEN;
     263                 :            :     }
     264         [ +  + ]:    1522805 :     else if(ctx->hmac_type == FKO_HMAC_SHA1)
     265                 :            :     {
     266                 :         89 :         res = hmac_sha1(ctx->encrypted_msg,
     267                 :         89 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     268                 :            : 
     269                 :         89 :         hmac_digest_len     = SHA1_DIGEST_LEN;
     270                 :         89 :         hmac_digest_str_len = SHA1_DIGEST_STR_LEN;
     271                 :            :     }
     272         [ +  + ]:    1522716 :     else if(ctx->hmac_type == FKO_HMAC_SHA256)
     273                 :            :     {
     274                 :    1522596 :         res = hmac_sha256(ctx->encrypted_msg,
     275                 :    1522596 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     276                 :            : 
     277                 :    1522596 :         hmac_digest_len     = SHA256_DIGEST_LEN;
     278                 :    1522596 :         hmac_digest_str_len = SHA256_DIGEST_STR_LEN;
     279                 :            :     }
     280         [ +  + ]:        120 :     else if(ctx->hmac_type == FKO_HMAC_SHA384)
     281                 :            :     {
     282                 :         51 :         res = hmac_sha384(ctx->encrypted_msg,
     283                 :         51 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     284                 :            : 
     285                 :         51 :         hmac_digest_len     = SHA384_DIGEST_LEN;
     286                 :         51 :         hmac_digest_str_len = SHA384_DIGEST_STR_LEN;
     287                 :            :     }
     288         [ +  + ]:         69 :     else if(ctx->hmac_type == FKO_HMAC_SHA512)
     289                 :            :     {
     290                 :         57 :         res = hmac_sha512(ctx->encrypted_msg,
     291                 :         57 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     292                 :            : 
     293                 :         57 :         hmac_digest_len     = SHA512_DIGEST_LEN;
     294                 :         57 :         hmac_digest_str_len = SHA512_DIGEST_STR_LEN;
     295                 :            :     }
     296         [ +  + ]:         12 :     else if(ctx->hmac_type == FKO_HMAC_SHA3_256)
     297                 :            :     {
     298                 :          2 :         res = hmac_sha3_256(ctx->encrypted_msg,
     299                 :          2 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     300                 :          2 :         hmac_digest_len     = SHA3_256_DIGEST_LEN;
     301                 :          2 :         hmac_digest_str_len = SHA3_256_DIGEST_STR_LEN;
     302                 :            : 
     303                 :            :     }
     304         [ +  - ]:         10 :     else if(ctx->hmac_type == FKO_HMAC_SHA3_512)
     305                 :            :     {
     306                 :         10 :         res = hmac_sha3_512(ctx->encrypted_msg,
     307                 :         10 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     308                 :         10 :         hmac_digest_len     = SHA3_512_DIGEST_LEN;
     309                 :         10 :         hmac_digest_str_len = SHA3_512_DIGEST_STR_LEN;
     310                 :            : 
     311                 :            :     }
     312                 :            : 
     313         [ +  + ]:    1522856 :     if (res != FKO_SUCCESS)
     314                 :            :         return res;
     315                 :            : 
     316                 :    1522835 :     hmac_base64 = calloc(1, MD_HEX_SIZE(hmac_digest_len)+1);
     317         [ +  + ]:    1522835 :     if (hmac_base64 == NULL)
     318                 :            :         return(FKO_ERROR_MEMORY_ALLOCATION);
     319                 :            : 
     320                 :    1522813 :     b64_encode(hmac, hmac_base64, hmac_digest_len);
     321                 :    1522813 :     strip_b64_eq(hmac_base64);
     322                 :            : 
     323         [ +  + ]:    1522813 :     if(ctx->msg_hmac != NULL)
     324                 :       2623 :         free(ctx->msg_hmac);
     325                 :            : 
     326                 :    1522813 :     ctx->msg_hmac = strdup(hmac_base64);
     327                 :            : 
     328                 :    1522813 :     free(hmac_base64);
     329                 :            : 
     330         [ +  - ]:    1522813 :     if(ctx->msg_hmac == NULL)
     331                 :            :         return(FKO_ERROR_MEMORY_ALLOCATION);
     332                 :            : 
     333                 :    1522813 :     ctx->msg_hmac_len = strnlen(ctx->msg_hmac, hmac_digest_str_len);
     334                 :            : 
     335         [ +  - ]:    1522813 :     switch(ctx->msg_hmac_len)
     336                 :            :     {
     337                 :            :         case MD5_B64_LEN:
     338                 :            :             break;
     339                 :            :         case SHA1_B64_LEN:
     340                 :            :             break;
     341                 :            :         case SHA256_B64_LEN:
     342                 :            :             break;
     343                 :            :         case SHA384_B64_LEN:
     344                 :            :             break;
     345                 :            :         case SHA512_B64_LEN:
     346                 :            :             break;
     347                 :            :         default:
     348                 :            :             return(FKO_ERROR_INVALID_DATA_HMAC_LEN_VALIDFAIL);
     349                 :            :     }
     350                 :            : 
     351                 :    1522813 :     return FKO_SUCCESS;
     352                 :            : }
     353                 :            : 
     354                 :            : /***EOF***/

Generated by: LCOV version 1.10