Home | History | Annotate | Download | only in hash
      1 /*
      2  * auth.c
      3  *
      4  * some bookkeeping functions for authentication functions
      5  *
      6  * David A. McGrew
      7  * Cisco Systems, Inc.
      8  */
      9 
     10 /*
     11  *
     12  * Copyright (c) 2001-2006, Cisco Systems, Inc.
     13  * All rights reserved.
     14  *
     15  * Redistribution and use in source and binary forms, with or without
     16  * modification, are permitted provided that the following conditions
     17  * are met:
     18  *
     19  *   Redistributions of source code must retain the above copyright
     20  *   notice, this list of conditions and the following disclaimer.
     21  *
     22  *   Redistributions in binary form must reproduce the above
     23  *   copyright notice, this list of conditions and the following
     24  *   disclaimer in the documentation and/or other materials provided
     25  *   with the distribution.
     26  *
     27  *   Neither the name of the Cisco Systems, Inc. nor the names of its
     28  *   contributors may be used to endorse or promote products derived
     29  *   from this software without specific prior written permission.
     30  *
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     34  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     35  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     36  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     37  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     38  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     41  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     42  * OF THE POSSIBILITY OF SUCH DAMAGE.
     43  *
     44  */
     45 
     46 #include "auth.h"
     47 
     48 /* the debug module for authentiation */
     49 
     50 debug_module_t mod_auth = {
     51   0,                  /* debugging is off by default */
     52   "auth func"         /* printable name for module   */
     53 };
     54 
     55 
     56 int
     57 auth_get_key_length(const auth_t *a) {
     58   return a->key_len;
     59 }
     60 
     61 int
     62 auth_get_tag_length(const auth_t *a) {
     63   return a->out_len;
     64 }
     65 
     66 int
     67 auth_get_prefix_length(const auth_t *a) {
     68   return a->prefix_len;
     69 }
     70 
     71 int
     72 auth_type_get_ref_count(const auth_type_t *at) {
     73   return at->ref_count;
     74 }
     75 
     76 /*
     77  * auth_type_self_test() tests an auth function of type ct against
     78  * test cases provided in an array of values of key, data, and tag
     79  * that is known to be good
     80  */
     81 
     82 /* should be big enough for most occasions */
     83 #define SELF_TEST_TAG_BUF_OCTETS 32
     84 
     85 err_status_t
     86 auth_type_self_test(const auth_type_t *at) {
     87   auth_test_case_t *test_case = at->test_data;
     88   auth_t *a;
     89   err_status_t status;
     90   uint8_t tag[SELF_TEST_TAG_BUF_OCTETS];
     91   int i, case_num = 0;
     92 
     93   debug_print(mod_auth, "running self-test for auth function %s",
     94 	      at->description);
     95 
     96   /*
     97    * check to make sure that we have at least one test case, and
     98    * return an error if we don't - we need to be paranoid here
     99    */
    100   if (test_case == NULL)
    101     return err_status_cant_check;
    102 
    103   /* loop over all test cases */
    104   while (test_case != NULL) {
    105 
    106     /* check test case parameters */
    107     if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS)
    108       return err_status_bad_param;
    109 
    110     /* allocate auth */
    111     status = auth_type_alloc(at, &a, test_case->key_length_octets,
    112 			     test_case->tag_length_octets);
    113     if (status)
    114       return status;
    115 
    116     /* initialize auth */
    117     status = auth_init(a, test_case->key);
    118     if (status) {
    119       auth_dealloc(a);
    120       return status;
    121     }
    122 
    123     /* zeroize tag then compute */
    124     octet_string_set_to_zero(tag, test_case->tag_length_octets);
    125     status = auth_compute(a, test_case->data,
    126 			  test_case->data_length_octets, tag);
    127     if (status) {
    128       auth_dealloc(a);
    129       return status;
    130     }
    131 
    132     debug_print(mod_auth, "key: %s",
    133 		octet_string_hex_string(test_case->key,
    134 					test_case->key_length_octets));
    135     debug_print(mod_auth, "data: %s",
    136 		octet_string_hex_string(test_case->data,
    137 				   test_case->data_length_octets));
    138     debug_print(mod_auth, "tag computed: %s",
    139 	   octet_string_hex_string(tag, test_case->tag_length_octets));
    140     debug_print(mod_auth, "tag expected: %s",
    141 	   octet_string_hex_string(test_case->tag,
    142 				   test_case->tag_length_octets));
    143 
    144     /* check the result */
    145     status = err_status_ok;
    146     for (i=0; i < test_case->tag_length_octets; i++)
    147       if (tag[i] != test_case->tag[i]) {
    148 	status = err_status_algo_fail;
    149 	debug_print(mod_auth, "test case %d failed", case_num);
    150 	debug_print(mod_auth, "  (mismatch at octet %d)", i);
    151       }
    152     if (status) {
    153       auth_dealloc(a);
    154       return err_status_algo_fail;
    155     }
    156 
    157     /* deallocate the auth function */
    158     status = auth_dealloc(a);
    159     if (status)
    160       return status;
    161 
    162     /*
    163      * the auth function passed the test case, so move on to the next test
    164      * case in the list; if NULL, we'll quit and return an OK
    165      */
    166     test_case = test_case->next_test_case;
    167     ++case_num;
    168   }
    169 
    170   return err_status_ok;
    171 }
    172 
    173 
    174