blob: be4065908a31d09064a8c8b2667083fa9f62b509 [file] [log] [blame]
Cullen Jennings235513a2005-09-21 22:51:36 +00001/*
2 * hmac.c
3 *
jfigus8f669722014-11-19 15:20:03 -05004 * implementation of hmac srtp_auth_type_t
Cullen Jennings235513a2005-09-21 22:51:36 +00005 *
6 * David A. McGrew
7 * Cisco Systems, Inc.
8 */
9/*
jfigusae4f3b12014-11-20 09:34:08 -050010 *
David McGrew7629bf22006-06-08 17:00:25 +000011 * Copyright(c) 2001-2006 Cisco Systems, Inc.
Cullen Jennings235513a2005-09-21 22:51:36 +000012 * All rights reserved.
jfigusae4f3b12014-11-20 09:34:08 -050013 *
Cullen Jennings235513a2005-09-21 22:51:36 +000014 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
jfigusae4f3b12014-11-20 09:34:08 -050017 *
Cullen Jennings235513a2005-09-21 22:51:36 +000018 * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
jfigusae4f3b12014-11-20 09:34:08 -050020 *
Cullen Jennings235513a2005-09-21 22:51:36 +000021 * 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.
jfigusae4f3b12014-11-20 09:34:08 -050025 *
Cullen Jennings235513a2005-09-21 22:51:36 +000026 * 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.
jfigusae4f3b12014-11-20 09:34:08 -050029 *
Cullen Jennings235513a2005-09-21 22:51:36 +000030 * 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
Teerapap Changwichukarn6cffe242014-09-24 11:24:07 +080045#ifdef HAVE_CONFIG_H
46 #include <config.h>
47#endif
48
jfigusae4f3b12014-11-20 09:34:08 -050049#include "hmac.h"
Cullen Jennings235513a2005-09-21 22:51:36 +000050#include "alloc.h"
51
52/* the debug module for authentiation */
53
jfigus02d6f032014-11-21 10:56:42 -050054srtp_debug_module_t srtp_mod_hmac = {
jfigusae4f3b12014-11-20 09:34:08 -050055 0, /* debugging is off by default */
56 "hmac sha-1" /* printable name for module */
Cullen Jennings235513a2005-09-21 22:51:36 +000057};
58
59
jfigusae4f3b12014-11-20 09:34:08 -050060static srtp_err_status_t srtp_hmac_alloc (srtp_auth_t **a, int key_len, int out_len)
61{
62 extern srtp_auth_type_t srtp_hmac;
63 uint8_t *pointer;
Cullen Jennings235513a2005-09-21 22:51:36 +000064
jfigusae4f3b12014-11-20 09:34:08 -050065 debug_print(srtp_mod_hmac, "allocating auth func with key length %d", key_len);
66 debug_print(srtp_mod_hmac, " tag length %d", out_len);
Cullen Jennings235513a2005-09-21 22:51:36 +000067
David McGrewd9431772005-10-03 14:33:59 +000068 /*
jfigusae4f3b12014-11-20 09:34:08 -050069 * check key length - note that we don't support keys larger
70 * than 20 bytes yet
71 */
72 if (key_len > 20) {
73 return srtp_err_status_bad_param;
74 }
Cullen Jennings235513a2005-09-21 22:51:36 +000075
jfigusae4f3b12014-11-20 09:34:08 -050076 /* check output length - should be less than 20 bytes */
77 if (out_len > 20) {
78 return srtp_err_status_bad_param;
79 }
Cullen Jennings235513a2005-09-21 22:51:36 +000080
jfigusae4f3b12014-11-20 09:34:08 -050081 /* allocate memory for auth and srtp_hmac_ctx_t structures */
82 pointer = (uint8_t*)srtp_crypto_alloc(sizeof(srtp_hmac_ctx_t) + sizeof(srtp_auth_t));
83 if (pointer == NULL) {
84 return srtp_err_status_alloc_fail;
85 }
Cullen Jennings235513a2005-09-21 22:51:36 +000086
jfigusae4f3b12014-11-20 09:34:08 -050087 /* set pointers */
88 *a = (srtp_auth_t*)pointer;
89 (*a)->type = &srtp_hmac;
90 (*a)->state = pointer + sizeof(srtp_auth_t);
91 (*a)->out_len = out_len;
92 (*a)->key_len = key_len;
93 (*a)->prefix_len = 0;
94
95 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +000096}
97
jfigusae4f3b12014-11-20 09:34:08 -050098static srtp_err_status_t srtp_hmac_dealloc (srtp_auth_t *a)
99{
100 /* zeroize entire state*/
101 octet_string_set_to_zero((uint8_t*)a,
102 sizeof(srtp_hmac_ctx_t) + sizeof(srtp_auth_t));
Cullen Jennings235513a2005-09-21 22:51:36 +0000103
jfigusae4f3b12014-11-20 09:34:08 -0500104 /* free memory */
105 srtp_crypto_free(a);
106
107 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000108}
109
jfigusae4f3b12014-11-20 09:34:08 -0500110static srtp_err_status_t srtp_hmac_init (srtp_hmac_ctx_t *state, const uint8_t *key, int key_len)
111{
112 int i;
113 uint8_t ipad[64];
Cullen Jennings235513a2005-09-21 22:51:36 +0000114
jfigusae4f3b12014-11-20 09:34:08 -0500115 /*
116 * check key length - note that we don't support keys larger
117 * than 20 bytes yet
118 */
119 if (key_len > 20) {
120 return srtp_err_status_bad_param;
121 }
Cullen Jennings235513a2005-09-21 22:51:36 +0000122
jfigusae4f3b12014-11-20 09:34:08 -0500123 /*
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 }
136
137 debug_print(srtp_mod_hmac, "ipad: %s", srtp_octet_string_hex_string(ipad, 64));
138
139 /* initialize sha1 context */
140 srtp_sha1_init(&state->init_ctx);
141
142 /* hash ipad ^ key */
143 srtp_sha1_update(&state->init_ctx, ipad, 64);
144 memcpy(&state->ctx, &state->init_ctx, sizeof(srtp_sha1_ctx_t));
145
146 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000147}
148
jfigusae4f3b12014-11-20 09:34:08 -0500149static srtp_err_status_t srtp_hmac_start (srtp_hmac_ctx_t *state)
150{
Cullen Jennings235513a2005-09-21 22:51:36 +0000151
jfigusae4f3b12014-11-20 09:34:08 -0500152 memcpy(&state->ctx, &state->init_ctx, sizeof(srtp_sha1_ctx_t));
Cullen Jennings235513a2005-09-21 22:51:36 +0000153
jfigusae4f3b12014-11-20 09:34:08 -0500154 return srtp_err_status_ok;
155}
Cullen Jennings235513a2005-09-21 22:51:36 +0000156
jfigusae4f3b12014-11-20 09:34:08 -0500157static srtp_err_status_t srtp_hmac_update (srtp_hmac_ctx_t *state, const uint8_t *message, int msg_octets)
158{
Cullen Jennings235513a2005-09-21 22:51:36 +0000159
jfigusae4f3b12014-11-20 09:34:08 -0500160 debug_print(srtp_mod_hmac, "input: %s",
161 srtp_octet_string_hex_string(message, msg_octets));
Cullen Jennings235513a2005-09-21 22:51:36 +0000162
jfigusae4f3b12014-11-20 09:34:08 -0500163 /* hash message into sha1 context */
164 srtp_sha1_update(&state->ctx, message, msg_octets);
Cullen Jennings235513a2005-09-21 22:51:36 +0000165
jfigusae4f3b12014-11-20 09:34:08 -0500166 return srtp_err_status_ok;
167}
Cullen Jennings235513a2005-09-21 22:51:36 +0000168
jfigusae4f3b12014-11-20 09:34:08 -0500169static srtp_err_status_t srtp_hmac_compute (srtp_hmac_ctx_t *state, const void *message,
170 int msg_octets, int tag_len, uint8_t *result)
171{
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 if (tag_len > 20) {
178 return srtp_err_status_bad_param;
179 }
180
181 /* hash message, copy output into H */
182 srtp_hmac_update(state, (const uint8_t*)message, msg_octets);
183 srtp_sha1_final(&state->ctx, H);
184
185 /*
186 * note that we don't need to debug_print() the input, since the
187 * function hmac_update() already did that for us
188 */
189 debug_print(srtp_mod_hmac, "intermediate state: %s",
190 srtp_octet_string_hex_string((uint8_t*)H, 20));
191
192 /* re-initialize hash context */
193 srtp_sha1_init(&state->ctx);
194
195 /* hash opad ^ key */
196 srtp_sha1_update(&state->ctx, (uint8_t*)state->opad, 64);
197
198 /* hash the result of the inner hash */
199 srtp_sha1_update(&state->ctx, (uint8_t*)H, 20);
200
201 /* the result is returned in the array hash_value[] */
202 srtp_sha1_final(&state->ctx, hash_value);
203
204 /* copy hash_value to *result */
205 for (i = 0; i < tag_len; i++) {
206 result[i] = ((uint8_t*)hash_value)[i];
207 }
208
209 debug_print(srtp_mod_hmac, "output: %s",
210 srtp_octet_string_hex_string((uint8_t*)hash_value, tag_len));
211
212 return srtp_err_status_ok;
Cullen Jennings235513a2005-09-21 22:51:36 +0000213}
214
215
216/* begin test case 0 */
217
jfigusae4f3b12014-11-20 09:34:08 -0500218static uint8_t srtp_hmac_test_case_0_key[20] = {
219 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
220 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
221 0x0b, 0x0b, 0x0b, 0x0b
Cullen Jennings235513a2005-09-21 22:51:36 +0000222};
223
jfigusae4f3b12014-11-20 09:34:08 -0500224static uint8_t srtp_hmac_test_case_0_data[8] = {
225 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
Cullen Jennings235513a2005-09-21 22:51:36 +0000226};
227
jfigusae4f3b12014-11-20 09:34:08 -0500228static uint8_t srtp_hmac_test_case_0_tag[20] = {
229 0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
230 0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
231 0xf1, 0x46, 0xbe, 0x00
Cullen Jennings235513a2005-09-21 22:51:36 +0000232};
233
jfigusae4f3b12014-11-20 09:34:08 -0500234static srtp_auth_test_case_t srtp_hmac_test_case_0 = {
235 20, /* octets in key */
236 srtp_hmac_test_case_0_key, /* key */
237 8, /* octets in data */
238 srtp_hmac_test_case_0_data, /* data */
239 20, /* octets in tag */
240 srtp_hmac_test_case_0_tag, /* tag */
241 NULL /* pointer to next testcase */
Cullen Jennings235513a2005-09-21 22:51:36 +0000242};
243
244/* end test case 0 */
245
jfigusae4f3b12014-11-20 09:34:08 -0500246static char srtp_hmac_description[] = "hmac sha-1 authentication function";
Cullen Jennings235513a2005-09-21 22:51:36 +0000247
248/*
jfigus8f669722014-11-19 15:20:03 -0500249 * srtp_auth_type_t hmac is the hmac metaobject
Cullen Jennings235513a2005-09-21 22:51:36 +0000250 */
251
jfigusae4f3b12014-11-20 09:34:08 -0500252srtp_auth_type_t srtp_hmac = {
253 (auth_alloc_func)srtp_hmac_alloc,
254 (auth_dealloc_func)srtp_hmac_dealloc,
255 (auth_init_func)srtp_hmac_init,
256 (auth_compute_func)srtp_hmac_compute,
257 (auth_update_func)srtp_hmac_update,
258 (auth_start_func)srtp_hmac_start,
259 (char*)srtp_hmac_description,
260 (srtp_auth_test_case_t*)&srtp_hmac_test_case_0,
jfigus02d6f032014-11-21 10:56:42 -0500261 (srtp_debug_module_t*)&srtp_mod_hmac,
jfigus67b9c732014-11-20 10:17:21 -0500262 (srtp_auth_type_id_t)SRTP_HMAC_SHA1
Cullen Jennings235513a2005-09-21 22:51:36 +0000263};
264