Line data Source code
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 0 : auth_get_key_length(const auth_t *a) {
58 0 : return a->key_len;
59 : }
60 :
61 : int
62 0 : auth_get_tag_length(const auth_t *a) {
63 0 : return a->out_len;
64 : }
65 :
66 : int
67 0 : auth_get_prefix_length(const auth_t *a) {
68 0 : return a->prefix_len;
69 : }
70 :
71 : int
72 0 : auth_type_get_ref_count(const auth_type_t *at) {
73 0 : return at->ref_count;
74 : }
75 :
76 : /*
77 : * auth_type_test() tests an auth function of type ct against
78 : * test cases provided in a list test_data 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 0 : auth_type_test(const auth_type_t *at, const auth_test_case_t *test_data) {
87 0 : const auth_test_case_t *test_case = test_data;
88 : auth_t *a;
89 : err_status_t status;
90 : uint8_t tag[SELF_TEST_TAG_BUF_OCTETS];
91 0 : 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 0 : if (test_case == NULL)
101 0 : return err_status_cant_check;
102 :
103 : /* loop over all test cases */
104 0 : while (test_case != NULL) {
105 :
106 : /* check test case parameters */
107 0 : if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS)
108 0 : return err_status_bad_param;
109 :
110 : /* allocate auth */
111 0 : status = auth_type_alloc(at, &a, test_case->key_length_octets,
112 : test_case->tag_length_octets);
113 0 : if (status)
114 0 : return status;
115 :
116 : /* initialize auth */
117 0 : status = auth_init(a, test_case->key);
118 0 : if (status) {
119 0 : auth_dealloc(a);
120 0 : return status;
121 : }
122 :
123 : /* zeroize tag then compute */
124 0 : octet_string_set_to_zero(tag, test_case->tag_length_octets);
125 0 : status = auth_compute(a, test_case->data,
126 : test_case->data_length_octets, tag);
127 0 : if (status) {
128 0 : auth_dealloc(a);
129 0 : 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 0 : status = err_status_ok;
146 0 : for (i=0; i < test_case->tag_length_octets; i++)
147 0 : if (tag[i] != test_case->tag[i]) {
148 0 : 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 0 : if (status) {
153 0 : auth_dealloc(a);
154 0 : return err_status_algo_fail;
155 : }
156 :
157 : /* deallocate the auth function */
158 0 : status = auth_dealloc(a);
159 0 : if (status)
160 0 : 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 0 : test_case = test_case->next_test_case;
167 0 : ++case_num;
168 : }
169 :
170 0 : return err_status_ok;
171 : }
172 :
173 :
174 : /*
175 : * auth_type_self_test(at) performs auth_type_test on at's internal
176 : * list of test data.
177 : */
178 :
179 : err_status_t
180 0 : auth_type_self_test(const auth_type_t *at) {
181 0 : return auth_type_test(at, at->test_data);
182 : }
183 :
|