LCOV - code coverage report
Current view: top level - netwerk/srtp/src/crypto/hash - hmac.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 52 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * hmac.c
       3             :  *
       4             :  * implementation of hmac auth_type_t
       5             :  *
       6             :  * David A. McGrew
       7             :  * Cisco Systems, Inc.
       8             :  */
       9             : /*
      10             :  *      
      11             :  * Copyright(c) 2001-2006 Cisco Systems, Inc.
      12             :  * All rights reserved.
      13             :  * 
      14             :  * Redistribution and use in source and binary forms, with or without
      15             :  * modification, are permitted provided that the following conditions
      16             :  * are met:
      17             :  * 
      18             :  *   Redistributions of source code must retain the above copyright
      19             :  *   notice, this list of conditions and the following disclaimer.
      20             :  * 
      21             :  *   Redistributions in binary form must reproduce the above
      22             :  *   copyright notice, this list of conditions and the following
      23             :  *   disclaimer in the documentation and/or other materials provided
      24             :  *   with the distribution.
      25             :  * 
      26             :  *   Neither the name of the Cisco Systems, Inc. nor the names of its
      27             :  *   contributors may be used to endorse or promote products derived
      28             :  *   from this software without specific prior written permission.
      29             :  * 
      30             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
      31             :  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
      32             :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
      33             :  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
      34             :  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
      35             :  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
      36             :  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      37             :  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      38             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      39             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      40             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      41             :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      42             :  *
      43             :  */
      44             : 
      45             : #include "hmac.h" 
      46             : #include "alloc.h"
      47             : 
      48             : /* the debug module for authentiation */
      49             : 
      50             : debug_module_t mod_hmac = {
      51             :   0,                  /* debugging is off by default */
      52             :   "hmac sha-1"        /* printable name for module   */
      53             : };
      54             : 
      55             : 
      56             : err_status_t
      57           0 : hmac_alloc(auth_t **a, int key_len, int out_len) {
      58             :   extern auth_type_t hmac;
      59             :   uint8_t *pointer;
      60             : 
      61             :   debug_print(mod_hmac, "allocating auth func with key length %d", key_len);
      62             :   debug_print(mod_hmac, "                          tag length %d", out_len);
      63             : 
      64             :   /*
      65             :    * check key length - note that we don't support keys larger
      66             :    * than 20 bytes yet
      67             :    */
      68           0 :   if (key_len > 20)
      69           0 :     return err_status_bad_param;
      70             : 
      71             :   /* check output length - should be less than 20 bytes */
      72           0 :   if (out_len > 20)
      73           0 :     return err_status_bad_param;
      74             : 
      75             :   /* allocate memory for auth and hmac_ctx_t structures */
      76           0 :   pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t));
      77           0 :   if (pointer == NULL)
      78           0 :     return err_status_alloc_fail;
      79             : 
      80             :   /* set pointers */
      81           0 :   *a = (auth_t *)pointer;
      82           0 :   (*a)->type = &hmac;
      83           0 :   (*a)->state = pointer + sizeof(auth_t);  
      84           0 :   (*a)->out_len = out_len;
      85           0 :   (*a)->key_len = key_len;
      86           0 :   (*a)->prefix_len = 0;
      87             : 
      88             :   /* increment global count of all hmac uses */
      89           0 :   hmac.ref_count++;
      90             : 
      91           0 :   return err_status_ok;
      92             : }
      93             : 
      94             : err_status_t
      95           0 : hmac_dealloc(auth_t *a) {
      96             :   extern auth_type_t hmac;
      97             :   
      98             :   /* zeroize entire state*/
      99           0 :   octet_string_set_to_zero((uint8_t *)a, 
     100             :                            sizeof(hmac_ctx_t) + sizeof(auth_t));
     101             : 
     102             :   /* free memory */
     103           0 :   crypto_free(a);
     104             :   
     105             :   /* decrement global count of all hmac uses */
     106           0 :   hmac.ref_count--;
     107             : 
     108           0 :   return err_status_ok;
     109             : }
     110             : 
     111             : err_status_t
     112           0 : hmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len) {
     113             :   int i;
     114             :   uint8_t ipad[64]; 
     115             :   
     116             :     /*
     117             :    * check key length - note that we don't support keys larger
     118             :    * than 20 bytes yet
     119             :    */
     120           0 :   if (key_len > 20)              
     121           0 :     return err_status_bad_param;
     122             :   
     123             :   /*
     124             :    * set values of ipad and opad by exoring the key into the
     125             :    * appropriate constant values
     126             :    */
     127           0 :   for (i=0; i < key_len; i++) {    
     128           0 :     ipad[i] = key[i] ^ 0x36;
     129           0 :     state->opad[i] = key[i] ^ 0x5c;
     130             :   }  
     131             :   /* set the rest of ipad, opad to constant values */
     132           0 :   for (   ; i < 64; i++) {    
     133           0 :     ipad[i] = 0x36;
     134           0 :     ((uint8_t *)state->opad)[i] = 0x5c;
     135             :   }  
     136             : 
     137             :   debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, 64));
     138             :   
     139             :   /* initialize sha1 context */
     140           0 :   sha1_init(&state->init_ctx);
     141             : 
     142             :   /* hash ipad ^ key */
     143           0 :   sha1_update(&state->init_ctx, ipad, 64);
     144           0 :   memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t)); 
     145             : 
     146           0 :   return err_status_ok;
     147             : }
     148             : 
     149             : err_status_t
     150           0 : hmac_start(hmac_ctx_t *state) {
     151             :     
     152           0 :   memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t));
     153             : 
     154           0 :   return err_status_ok;
     155             : }
     156             : 
     157             : err_status_t
     158           0 : hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets) {
     159             : 
     160             :   debug_print(mod_hmac, "input: %s", 
     161             :               octet_string_hex_string(message, msg_octets));
     162             :   
     163             :   /* hash message into sha1 context */
     164           0 :   sha1_update(&state->ctx, message, msg_octets);
     165             : 
     166           0 :   return err_status_ok;
     167             : }
     168             : 
     169             : err_status_t
     170           0 : hmac_compute(hmac_ctx_t *state, const void *message,
     171             :              int msg_octets, int tag_len, uint8_t *result) {
     172             :   uint32_t hash_value[5];
     173             :   uint32_t H[5];
     174             :   int i;
     175             : 
     176             :   /* check tag length, return error if we can't provide the value expected */
     177           0 :   if (tag_len > 20)
     178           0 :     return err_status_bad_param;
     179             :   
     180             :   /* hash message, copy output into H */
     181           0 :   hmac_update(state, (const uint8_t*)message, msg_octets);
     182           0 :   sha1_final(&state->ctx, H);
     183             : 
     184             :   /*
     185             :    * note that we don't need to debug_print() the input, since the
     186             :    * function hmac_update() already did that for us
     187             :    */
     188             :   debug_print(mod_hmac, "intermediate state: %s", 
     189             :               octet_string_hex_string((uint8_t *)H, 20));
     190             : 
     191             :   /* re-initialize hash context */
     192           0 :   sha1_init(&state->ctx);
     193             :   
     194             :   /* hash opad ^ key  */
     195           0 :   sha1_update(&state->ctx, (uint8_t *)state->opad, 64);
     196             : 
     197             :   /* hash the result of the inner hash */
     198           0 :   sha1_update(&state->ctx, (uint8_t *)H, 20);
     199             :   
     200             :   /* the result is returned in the array hash_value[] */
     201           0 :   sha1_final(&state->ctx, hash_value);
     202             : 
     203             :   /* copy hash_value to *result */
     204           0 :   for (i=0; i < tag_len; i++)    
     205           0 :     result[i] = ((uint8_t *)hash_value)[i];
     206             : 
     207             :   debug_print(mod_hmac, "output: %s", 
     208             :               octet_string_hex_string((uint8_t *)hash_value, tag_len));
     209             : 
     210           0 :   return err_status_ok;
     211             : }
     212             : 
     213             : 
     214             : /* begin test case 0 */
     215             : 
     216             : uint8_t
     217             : hmac_test_case_0_key[20] = {
     218             :   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 
     219             :   0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 
     220             :   0x0b, 0x0b, 0x0b, 0x0b
     221             : };
     222             : 
     223             : uint8_t 
     224             : hmac_test_case_0_data[8] = {
     225             :   0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65   /* "Hi There" */
     226             : };
     227             : 
     228             : uint8_t
     229             : hmac_test_case_0_tag[20] = {
     230             :   0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 
     231             :   0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e, 
     232             :   0xf1, 0x46, 0xbe, 0x00
     233             : };
     234             : 
     235             : auth_test_case_t
     236             : hmac_test_case_0 = {
     237             :   20,                        /* octets in key            */
     238             :   hmac_test_case_0_key,      /* key                      */
     239             :   8,                         /* octets in data           */ 
     240             :   hmac_test_case_0_data,     /* data                     */
     241             :   20,                        /* octets in tag            */
     242             :   hmac_test_case_0_tag,      /* tag                      */
     243             :   NULL                       /* pointer to next testcase */
     244             : };
     245             : 
     246             : /* end test case 0 */
     247             : 
     248             : char hmac_description[] = "hmac sha-1 authentication function";
     249             : 
     250             : /*
     251             :  * auth_type_t hmac is the hmac metaobject
     252             :  */
     253             : 
     254             : auth_type_t
     255             : hmac  = {
     256             :   (auth_alloc_func)      hmac_alloc,
     257             :   (auth_dealloc_func)    hmac_dealloc,
     258             :   (auth_init_func)       hmac_init,
     259             :   (auth_compute_func)    hmac_compute,
     260             :   (auth_update_func)     hmac_update,
     261             :   (auth_start_func)      hmac_start,
     262             :   (char *)               hmac_description,
     263             :   (int)                  0,  /* instance count */
     264             :   (auth_test_case_t *)  &hmac_test_case_0,
     265             :   (debug_module_t *)    &mod_hmac,
     266             :   (auth_type_id_t)       HMAC_SHA1
     267             : };
     268             : 

Generated by: LCOV version 1.13