LCOV - code coverage report
Current view: top level - lib - fko_hmac.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 106 110 96.4 %
Date: 2015-08-23 Functions: 5 5 100.0 %
Branches: 79 100 79.0 %

           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                 :            : #include "fko_common.h"
      32                 :            : #include "fko.h"
      33                 :            : #include "cipher_funcs.h"
      34                 :            : #include "hmac.h"
      35                 :            : #include "base64.h"
      36                 :            : 
      37                 :            : int
      38                 :     770074 : fko_verify_hmac(fko_ctx_t ctx,
      39                 :            :     const char * const hmac_key, const int hmac_key_len)
      40                 :            : {
      41                 :     770074 :     char    *hmac_digest_from_data = NULL;
      42                 :     770074 :     char    *tbuf = NULL;
      43                 :     770074 :     int      res = FKO_SUCCESS;
      44                 :     770074 :     int      hmac_b64_digest_len = 0, zero_free_rv = FKO_SUCCESS;
      45                 :            : 
      46                 :            :     /* Must be initialized
      47                 :            :     */
      48 [ +  + ][ +  - ]:     770074 :     if(!CTX_INITIALIZED(ctx))
      49                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
      50                 :            : 
      51         [ +  - ]:     770014 :     if(hmac_key == NULL)
      52                 :            :         return(FKO_ERROR_INVALID_DATA);
      53                 :            : 
      54         [ +  - ]:     770014 :     if (! is_valid_encoded_msg_len(ctx->encrypted_msg_len))
      55                 :            :         return(FKO_ERROR_INVALID_DATA_HMAC_MSGLEN_VALIDFAIL);
      56                 :            : 
      57         [ +  + ]:     770014 :     if(hmac_key_len < 0 || hmac_key_len > MAX_DIGEST_BLOCK_LEN)
      58                 :            :         return(FKO_ERROR_INVALID_HMAC_KEY_LEN);
      59                 :            : 
      60         [ +  + ]:     770013 :     if(ctx->hmac_type == FKO_HMAC_MD5)
      61                 :            :         hmac_b64_digest_len = MD5_B64_LEN;
      62         [ +  + ]:     770007 :     else if(ctx->hmac_type == FKO_HMAC_SHA1)
      63                 :            :         hmac_b64_digest_len = SHA1_B64_LEN;
      64         [ +  + ]:     769988 :     else if(ctx->hmac_type == FKO_HMAC_SHA256)
      65                 :            :         hmac_b64_digest_len = SHA256_B64_LEN;
      66         [ +  + ]:         15 :     else if(ctx->hmac_type == FKO_HMAC_SHA384)
      67                 :            :         hmac_b64_digest_len = SHA384_B64_LEN;
      68         [ +  - ]:          9 :     else if(ctx->hmac_type == FKO_HMAC_SHA512)
      69                 :            :         hmac_b64_digest_len = SHA512_B64_LEN;
      70                 :            :     else
      71                 :            :         return(FKO_ERROR_UNSUPPORTED_HMAC_MODE);
      72                 :            : 
      73         [ +  + ]:     770013 :     if((ctx->encrypted_msg_len - hmac_b64_digest_len)
      74                 :            :             < MIN_SPA_ENCODED_MSG_SIZE)
      75                 :            :         return(FKO_ERROR_INVALID_DATA_HMAC_ENCMSGLEN_VALIDFAIL);
      76                 :            : 
      77                 :            :     /* Get digest value
      78                 :            :     */
      79                 :    1540006 :     hmac_digest_from_data = strndup((ctx->encrypted_msg
      80                 :     770003 :             + ctx->encrypted_msg_len - hmac_b64_digest_len),
      81                 :            :             hmac_b64_digest_len);
      82                 :            : 
      83         [ +  - ]:     770003 :     if(hmac_digest_from_data == NULL)
      84                 :            :         return(FKO_ERROR_MEMORY_ALLOCATION);
      85                 :            : 
      86                 :            :     /* Now we chop the HMAC digest off of the encrypted msg
      87                 :            :     */
      88                 :     770003 :     tbuf = strndup(ctx->encrypted_msg,
      89                 :            :             ctx->encrypted_msg_len - hmac_b64_digest_len);
      90                 :            : 
      91         [ -  + ]:     770003 :     if(tbuf == NULL)
      92                 :            :     {
      93         [ #  # ]:          0 :         if(zero_free(hmac_digest_from_data, strnlen(hmac_digest_from_data,
      94                 :            :                 MAX_SPA_ENCODED_MSG_SIZE)) == FKO_SUCCESS)
      95                 :            :             return(FKO_ERROR_MEMORY_ALLOCATION);
      96                 :            :         else
      97                 :          0 :             return(FKO_ERROR_ZERO_OUT_DATA);
      98                 :            :     }
      99                 :            : 
     100         [ +  + ]:     770003 :     if(zero_free(ctx->encrypted_msg, ctx->encrypted_msg_len) != FKO_SUCCESS)
     101                 :          2 :         zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
     102                 :            : 
     103                 :     770003 :     ctx->encrypted_msg      = tbuf;
     104                 :     770003 :     ctx->encrypted_msg_len -= hmac_b64_digest_len;
     105                 :            : 
     106         [ +  + ]:     770003 :     if(ctx->encryption_mode == FKO_ENC_MODE_ASYMMETRIC)
     107                 :            :     {
     108                 :            :         /* See if we need to add the "hQ" string to the front of the
     109                 :            :          * encrypted data.
     110                 :            :          */
     111         [ +  - ]:         24 :         if(! ctx->added_gpg_prefix)
     112                 :            :         {
     113                 :         24 :             res = add_gpg_prefix(ctx);
     114                 :            :         }
     115                 :            :     }
     116                 :            :     else
     117                 :            :     {
     118                 :            :         /* See if we need to add the "Salted__" string to the front of the
     119                 :            :          * encrypted data.
     120                 :            :          */
     121         [ +  + ]:     769979 :         if(! ctx->added_salted_str)
     122                 :            :         {
     123                 :     769971 :             res = add_salted_str(ctx);
     124                 :            :         }
     125                 :            :     }
     126                 :            : 
     127         [ +  + ]:     770003 :     if (res != FKO_SUCCESS)
     128                 :            :     {
     129         [ -  + ]:         51 :         if(zero_free(hmac_digest_from_data, strnlen(hmac_digest_from_data,
     130                 :            :                         MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS)
     131                 :          0 :             zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
     132                 :            : 
     133         [ -  + ]:         51 :         if(zero_free_rv == FKO_SUCCESS)
     134                 :            :             return(res);
     135                 :            :         else
     136                 :          0 :             return(zero_free_rv);
     137                 :            :     }
     138                 :            : 
     139                 :            :     /* Calculate the HMAC from the encrypted data and then
     140                 :            :      * compare
     141                 :            :     */
     142                 :     769952 :     res = fko_set_spa_hmac_type(ctx, ctx->hmac_type);
     143         [ +  - ]:     769952 :     if(res == FKO_SUCCESS)
     144                 :            :     {
     145                 :     769952 :         res = fko_set_spa_hmac(ctx, hmac_key, hmac_key_len);
     146                 :            : 
     147         [ +  + ]:     769952 :         if(res == FKO_SUCCESS)
     148                 :            :         {
     149         [ +  + ]:     769899 :             if(constant_runtime_cmp(hmac_digest_from_data,
     150                 :     769899 :                     ctx->msg_hmac, hmac_b64_digest_len) != 0)
     151                 :            :             {
     152                 :       2241 :                 res = FKO_ERROR_INVALID_DATA_HMAC_COMPAREFAIL;
     153                 :            :             }
     154                 :            :         }
     155                 :            :     }
     156                 :            : 
     157         [ +  + ]:     769952 :     if(zero_free(hmac_digest_from_data, strnlen(hmac_digest_from_data,
     158                 :            :                     MAX_SPA_ENCODED_MSG_SIZE)) != FKO_SUCCESS)
     159                 :          2 :         zero_free_rv = FKO_ERROR_ZERO_OUT_DATA;
     160                 :            : 
     161         [ +  + ]:     769952 :     if(res == FKO_SUCCESS)
     162                 :            :         return(zero_free_rv);
     163                 :            :     else
     164                 :       2294 :         return(res);
     165                 :            : }
     166                 :            : 
     167                 :            : /* Return the fko HMAC data
     168                 :            : */
     169                 :            : int
     170                 :       3418 : fko_get_spa_hmac(fko_ctx_t ctx, char **hmac_data)
     171                 :            : {
     172                 :            :     /* Must be initialized
     173                 :            :     */
     174 [ +  + ][ +  - ]:       3418 :     if(!CTX_INITIALIZED(ctx))
     175                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
     176                 :            : 
     177         [ +  + ]:       3266 :     if(hmac_data == NULL)
     178                 :            :         return(FKO_ERROR_INVALID_DATA);
     179                 :            : 
     180                 :       3198 :     *hmac_data = ctx->msg_hmac;
     181                 :            : 
     182                 :       3198 :     return(FKO_SUCCESS);
     183                 :            : }
     184                 :            : 
     185                 :            : /* Set the HMAC type
     186                 :            : */
     187                 :            : int
     188                 :    2409570 : fko_set_spa_hmac_type(fko_ctx_t ctx, const short hmac_type)
     189                 :            : {
     190                 :            : #if HAVE_LIBFIU
     191         [ +  + ]:    2409570 :     fiu_return_on("fko_set_spa_hmac_type_init",
     192                 :            :             FKO_ERROR_CTX_NOT_INITIALIZED);
     193                 :            : #endif
     194                 :            : 
     195                 :            :     /* Must be initialized
     196                 :            :     */
     197 [ +  + ][ +  - ]:    2409569 :     if(!CTX_INITIALIZED(ctx))
     198                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
     199                 :            : 
     200                 :            : #if HAVE_LIBFIU
     201         [ +  + ]:    2408735 :     fiu_return_on("fko_set_spa_hmac_type_val",
     202                 :            :             FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL);
     203                 :            : #endif
     204                 :            : 
     205         [ +  + ]:    2408734 :     if(hmac_type < 0 || hmac_type >= FKO_LAST_HMAC_MODE)
     206                 :            :         return(FKO_ERROR_INVALID_DATA_HMAC_TYPE_VALIDFAIL);
     207                 :            : 
     208                 :    2404691 :     ctx->hmac_type = hmac_type;
     209                 :            : 
     210                 :    2404691 :     ctx->state |= FKO_HMAC_MODE_MODIFIED;
     211                 :            : 
     212                 :    2404691 :     return(FKO_SUCCESS);
     213                 :            : }
     214                 :            : 
     215                 :            : /* Return the fko HMAC type
     216                 :            : */
     217                 :            : int
     218                 :       5095 : fko_get_spa_hmac_type(fko_ctx_t ctx, short *hmac_type)
     219                 :            : {
     220                 :            :     /* Must be initialized
     221                 :            :     */
     222 [ +  + ][ +  - ]:       5095 :     if(!CTX_INITIALIZED(ctx))
     223                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
     224                 :            : 
     225         [ +  + ]:       4527 :     if(hmac_type == NULL)
     226                 :            :         return(FKO_ERROR_INVALID_DATA);
     227                 :            : 
     228                 :       4459 :     *hmac_type = ctx->hmac_type;
     229                 :            : 
     230                 :       4459 :     return(FKO_SUCCESS);
     231                 :            : }
     232                 :            : 
     233                 :    1524340 : int fko_set_spa_hmac(fko_ctx_t ctx,
     234                 :            :     const char * const hmac_key, const int hmac_key_len)
     235                 :            : {
     236                 :    1524340 :     unsigned char hmac[SHA512_DIGEST_STR_LEN] = {0};
     237                 :    1524340 :     char *hmac_base64 = NULL;
     238                 :    1524340 :     int   hmac_digest_str_len = 0;
     239                 :    1524340 :     int   hmac_digest_len = 0;
     240                 :            : 
     241                 :            :     /* Must be initialized
     242                 :            :     */
     243 [ +  - ][ +  - ]:    1524340 :     if(!CTX_INITIALIZED(ctx))
     244                 :            :         return(FKO_ERROR_CTX_NOT_INITIALIZED);
     245                 :            : 
     246         [ +  - ]:    1524340 :     if(hmac_key == NULL)
     247                 :            :         return(FKO_ERROR_INVALID_DATA);
     248                 :            : 
     249         [ +  + ]:    1524340 :     if(hmac_key_len < 0 || hmac_key_len > MAX_DIGEST_BLOCK_LEN)
     250                 :            :         return(FKO_ERROR_INVALID_HMAC_KEY_LEN);
     251                 :            : 
     252         [ +  + ]:    1524278 :     if(ctx->hmac_type == FKO_HMAC_MD5)
     253                 :            :     {
     254                 :         51 :         hmac_md5(ctx->encrypted_msg,
     255                 :         51 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     256                 :            : 
     257                 :         51 :         hmac_digest_len     = MD5_DIGEST_LEN;
     258                 :         51 :         hmac_digest_str_len = MD5_DIGEST_STR_LEN;
     259                 :            :     }
     260         [ +  + ]:    1524227 :     else if(ctx->hmac_type == FKO_HMAC_SHA1)
     261                 :            :     {
     262                 :         85 :         hmac_sha1(ctx->encrypted_msg,
     263                 :         85 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     264                 :            : 
     265                 :         85 :         hmac_digest_len     = SHA1_DIGEST_LEN;
     266                 :         85 :         hmac_digest_str_len = SHA1_DIGEST_STR_LEN;
     267                 :            :     }
     268         [ +  + ]:    1524142 :     else if(ctx->hmac_type == FKO_HMAC_SHA256)
     269                 :            :     {
     270                 :    1524026 :         hmac_sha256(ctx->encrypted_msg,
     271                 :    1524026 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     272                 :            : 
     273                 :    1524026 :         hmac_digest_len     = SHA256_DIGEST_LEN;
     274                 :    1524026 :         hmac_digest_str_len = SHA256_DIGEST_STR_LEN;
     275                 :            :     }
     276         [ +  + ]:        116 :     else if(ctx->hmac_type == FKO_HMAC_SHA384)
     277                 :            :     {
     278                 :         51 :         hmac_sha384(ctx->encrypted_msg,
     279                 :         51 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     280                 :            : 
     281                 :         51 :         hmac_digest_len     = SHA384_DIGEST_LEN;
     282                 :         51 :         hmac_digest_str_len = SHA384_DIGEST_STR_LEN;
     283                 :            :     }
     284         [ +  - ]:         65 :     else if(ctx->hmac_type == FKO_HMAC_SHA512)
     285                 :            :     {
     286                 :         65 :         hmac_sha512(ctx->encrypted_msg,
     287                 :         65 :             ctx->encrypted_msg_len, hmac, hmac_key, hmac_key_len);
     288                 :            : 
     289                 :         65 :         hmac_digest_len     = SHA512_DIGEST_LEN;
     290                 :         65 :         hmac_digest_str_len = SHA512_DIGEST_STR_LEN;
     291                 :            :     }
     292                 :            : 
     293                 :    1524278 :     hmac_base64 = calloc(1, MD_HEX_SIZE(hmac_digest_len)+1);
     294         [ +  + ]:    1524278 :     if (hmac_base64 == NULL)
     295                 :            :         return(FKO_ERROR_MEMORY_ALLOCATION);
     296                 :            : 
     297                 :    1524225 :     b64_encode(hmac, hmac_base64, hmac_digest_len);
     298                 :    1524225 :     strip_b64_eq(hmac_base64);
     299                 :            : 
     300         [ +  + ]:    1524225 :     if(ctx->msg_hmac != NULL)
     301                 :       2615 :         free(ctx->msg_hmac);
     302                 :            : 
     303                 :    1524225 :     ctx->msg_hmac = strdup(hmac_base64);
     304                 :            : 
     305                 :    1524225 :     free(hmac_base64);
     306                 :            : 
     307         [ +  - ]:    1524225 :     if(ctx->msg_hmac == NULL)
     308                 :            :         return(FKO_ERROR_MEMORY_ALLOCATION);
     309                 :            : 
     310                 :    1524225 :     ctx->msg_hmac_len = strnlen(ctx->msg_hmac, hmac_digest_str_len);
     311                 :            : 
     312         [ +  - ]:    1524225 :     switch(ctx->msg_hmac_len)
     313                 :            :     {
     314                 :            :         case MD5_B64_LEN:
     315                 :            :             break;
     316                 :            :         case SHA1_B64_LEN:
     317                 :            :             break;
     318                 :            :         case SHA256_B64_LEN:
     319                 :            :             break;
     320                 :            :         case SHA384_B64_LEN:
     321                 :            :             break;
     322                 :            :         case SHA512_B64_LEN:
     323                 :            :             break;
     324                 :            :         default:
     325                 :            :             return(FKO_ERROR_INVALID_DATA_HMAC_LEN_VALIDFAIL);
     326                 :            :     }
     327                 :            : 
     328                 :    1524225 :     return FKO_SUCCESS;
     329                 :            : }
     330                 :            : 
     331                 :            : /***EOF***/

Generated by: LCOV version 1.10