netwerk/srtp/src/crypto/hash/hmac.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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  */
    45 #include "hmac.h" 
    46 #include "alloc.h"
    48 /* the debug module for authentiation */
    50 debug_module_t mod_hmac = {
    51   0,                  /* debugging is off by default */
    52   "hmac sha-1"        /* printable name for module   */
    53 };
    56 err_status_t
    57 hmac_alloc(auth_t **a, int key_len, int out_len) {
    58   extern auth_type_t hmac;
    59   uint8_t *pointer;
    61   debug_print(mod_hmac, "allocating auth func with key length %d", key_len);
    62   debug_print(mod_hmac, "                          tag length %d", out_len);
    64   /*
    65    * check key length - note that we don't support keys larger
    66    * than 20 bytes yet
    67    */
    68   if (key_len > 20)
    69     return err_status_bad_param;
    71   /* check output length - should be less than 20 bytes */
    72   if (out_len > 20)
    73     return err_status_bad_param;
    75   /* allocate memory for auth and hmac_ctx_t structures */
    76   pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t));
    77   if (pointer == NULL)
    78     return err_status_alloc_fail;
    80   /* set pointers */
    81   *a = (auth_t *)pointer;
    82   (*a)->type = &hmac;
    83   (*a)->state = pointer + sizeof(auth_t);  
    84   (*a)->out_len = out_len;
    85   (*a)->key_len = key_len;
    86   (*a)->prefix_len = 0;
    88   /* increment global count of all hmac uses */
    89   hmac.ref_count++;
    91   return err_status_ok;
    92 }
    94 err_status_t
    95 hmac_dealloc(auth_t *a) {
    96   extern auth_type_t hmac;
    98   /* zeroize entire state*/
    99   octet_string_set_to_zero((uint8_t *)a, 
   100 			   sizeof(hmac_ctx_t) + sizeof(auth_t));
   102   /* free memory */
   103   crypto_free(a);
   105   /* decrement global count of all hmac uses */
   106   hmac.ref_count--;
   108   return err_status_ok;
   109 }
   111 err_status_t
   112 hmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len) {
   113   int i;
   114   uint8_t ipad[64]; 
   116     /*
   117    * check key length - note that we don't support keys larger
   118    * than 20 bytes yet
   119    */
   120   if (key_len > 20)              
   121     return err_status_bad_param;
   123   /*
   124    * set values of ipad and opad by exoring the key into the
   125    * appropriate constant values
   126    */
   127   for (i=0; i < key_len; i++) {    
   128     ipad[i] = key[i] ^ 0x36;
   129     state->opad[i] = key[i] ^ 0x5c;
   130   }  
   131   /* set the rest of ipad, opad to constant values */
   132   for (   ; i < 64; i++) {    
   133     ipad[i] = 0x36;
   134     ((uint8_t *)state->opad)[i] = 0x5c;
   135   }  
   137   debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, 64));
   139   /* initialize sha1 context */
   140   sha1_init(&state->init_ctx);
   142   /* hash ipad ^ key */
   143   sha1_update(&state->init_ctx, ipad, 64);
   144   memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t)); 
   146   return err_status_ok;
   147 }
   149 err_status_t
   150 hmac_start(hmac_ctx_t *state) {
   152   memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t));
   154   return err_status_ok;
   155 }
   157 err_status_t
   158 hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets) {
   160   debug_print(mod_hmac, "input: %s", 
   161 	      octet_string_hex_string(message, msg_octets));
   163   /* hash message into sha1 context */
   164   sha1_update(&state->ctx, message, msg_octets);
   166   return err_status_ok;
   167 }
   169 err_status_t
   170 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;
   176   /* check tag length, return error if we can't provide the value expected */
   177   if (tag_len > 20)
   178     return err_status_bad_param;
   180   /* hash message, copy output into H */
   181   hmac_update(state, (const uint8_t*)message, msg_octets);
   182   sha1_final(&state->ctx, H);
   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));
   191   /* re-initialize hash context */
   192   sha1_init(&state->ctx);
   194   /* hash opad ^ key  */
   195   sha1_update(&state->ctx, (uint8_t *)state->opad, 64);
   197   /* hash the result of the inner hash */
   198   sha1_update(&state->ctx, (uint8_t *)H, 20);
   200   /* the result is returned in the array hash_value[] */
   201   sha1_final(&state->ctx, hash_value);
   203   /* copy hash_value to *result */
   204   for (i=0; i < tag_len; i++)    
   205     result[i] = ((uint8_t *)hash_value)[i];
   207   debug_print(mod_hmac, "output: %s", 
   208 	      octet_string_hex_string((uint8_t *)hash_value, tag_len));
   210   return err_status_ok;
   211 }
   214 /* begin test case 0 */
   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 };
   223 uint8_t 
   224 hmac_test_case_0_data[8] = {
   225   0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65   /* "Hi There" */
   226 };
   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 };
   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 };
   246 /* end test case 0 */
   248 char hmac_description[] = "hmac sha-1 authentication function";
   250 /*
   251  * auth_type_t hmac is the hmac metaobject
   252  */
   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 };

mercurial