hmac_mbedtls.c (7082B)
1 /* 2 * hmac_mbedtls.c 3 * 4 * Implementation of hmac srtp_auth_type_t that leverages Mbedtls 5 * 6 * YongCheng Yang 7 */ 8 /* 9 * 10 * Copyright(c) 2013-2017, Cisco Systems, Inc. 11 * All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 17 * Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials provided 23 * with the distribution. 24 * 25 * Neither the name of the Cisco Systems, Inc. nor the names of its 26 * contributors may be used to endorse or promote products derived 27 * from this software without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 32 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 33 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 34 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 35 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 36 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 38 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 40 * OF THE POSSIBILITY OF SUCH DAMAGE. 41 * 42 */ 43 44 #ifdef HAVE_CONFIG_H 45 #include <config.h> 46 #endif 47 48 #include "auth.h" 49 #include "alloc.h" 50 #include "err.h" /* for srtp_debug */ 51 #include "auth_test_cases.h" 52 #include <mbedtls/md.h> 53 54 #define SHA1_DIGEST_SIZE 20 55 56 /* the debug module for authentiation */ 57 58 srtp_debug_module_t srtp_mod_hmac = { 59 0, /* debugging is off by default */ 60 "hmac sha-1 mbedtls" /* printable name for module */ 61 }; 62 63 static srtp_err_status_t srtp_hmac_mbedtls_alloc(srtp_auth_t **a, 64 int key_len, 65 int out_len) 66 { 67 extern const srtp_auth_type_t srtp_hmac; 68 69 debug_print(srtp_mod_hmac, "allocating auth func with key length %d", 70 key_len); 71 debug_print(srtp_mod_hmac, " tag length %d", 72 out_len); 73 74 /* check output length - should be less than 20 bytes */ 75 if (out_len > SHA1_DIGEST_SIZE) { 76 return srtp_err_status_bad_param; 77 } 78 79 *a = (srtp_auth_t *)srtp_crypto_alloc(sizeof(srtp_auth_t)); 80 if (*a == NULL) { 81 return srtp_err_status_alloc_fail; 82 } 83 // allocate the buffer of mbedtls context. 84 (*a)->state = srtp_crypto_alloc(sizeof(mbedtls_md_context_t)); 85 if ((*a)->state == NULL) { 86 srtp_crypto_free(*a); 87 *a = NULL; 88 return srtp_err_status_alloc_fail; 89 } 90 mbedtls_md_init((mbedtls_md_context_t *)(*a)->state); 91 92 /* set pointers */ 93 (*a)->type = &srtp_hmac; 94 (*a)->out_len = out_len; 95 (*a)->key_len = key_len; 96 (*a)->prefix_len = 0; 97 98 return srtp_err_status_ok; 99 } 100 101 static srtp_err_status_t srtp_hmac_mbedtls_dealloc(srtp_auth_t *a) 102 { 103 mbedtls_md_context_t *hmac_ctx; 104 hmac_ctx = (mbedtls_md_context_t *)a->state; 105 mbedtls_md_free(hmac_ctx); 106 srtp_crypto_free(hmac_ctx); 107 /* zeroize entire state*/ 108 octet_string_set_to_zero(a, sizeof(srtp_auth_t)); 109 110 /* free memory */ 111 srtp_crypto_free(a); 112 113 return srtp_err_status_ok; 114 } 115 116 static srtp_err_status_t srtp_hmac_mbedtls_start(void *statev) 117 { 118 mbedtls_md_context_t *state = (mbedtls_md_context_t *)statev; 119 if (mbedtls_md_hmac_reset(state) != 0) 120 return srtp_err_status_auth_fail; 121 122 return srtp_err_status_ok; 123 } 124 125 static srtp_err_status_t srtp_hmac_mbedtls_init(void *statev, 126 const uint8_t *key, 127 int key_len) 128 { 129 mbedtls_md_context_t *state = (mbedtls_md_context_t *)statev; 130 const mbedtls_md_info_t *info = NULL; 131 132 info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); 133 if (info == NULL) 134 return srtp_err_status_auth_fail; 135 136 if (mbedtls_md_setup(state, info, 1) != 0) 137 return srtp_err_status_auth_fail; 138 139 debug_print(srtp_mod_hmac, "mbedtls setup, name: %s", 140 mbedtls_md_get_name(info)); 141 debug_print(srtp_mod_hmac, "mbedtls setup, size: %d", 142 mbedtls_md_get_size(info)); 143 144 if (mbedtls_md_hmac_starts(state, key, key_len) != 0) 145 return srtp_err_status_auth_fail; 146 147 return srtp_err_status_ok; 148 } 149 150 static srtp_err_status_t srtp_hmac_mbedtls_update(void *statev, 151 const uint8_t *message, 152 int msg_octets) 153 { 154 mbedtls_md_context_t *state = (mbedtls_md_context_t *)statev; 155 156 debug_print(srtp_mod_hmac, "input: %s", 157 srtp_octet_string_hex_string(message, msg_octets)); 158 159 if (mbedtls_md_hmac_update(state, message, msg_octets) != 0) 160 return srtp_err_status_auth_fail; 161 162 return srtp_err_status_ok; 163 } 164 165 static srtp_err_status_t srtp_hmac_mbedtls_compute(void *statev, 166 const uint8_t *message, 167 int msg_octets, 168 int tag_len, 169 uint8_t *result) 170 { 171 mbedtls_md_context_t *state = (mbedtls_md_context_t *)statev; 172 uint8_t hash_value[SHA1_DIGEST_SIZE]; 173 int i; 174 175 /* check tag length, return error if we can't provide the value expected */ 176 if (tag_len > SHA1_DIGEST_SIZE) { 177 return srtp_err_status_bad_param; 178 } 179 180 /* hash message, copy output into H */ 181 if (mbedtls_md_hmac_update(statev, message, msg_octets) != 0) 182 return srtp_err_status_auth_fail; 183 184 if (mbedtls_md_hmac_finish(state, hash_value) != 0) 185 return srtp_err_status_auth_fail; 186 187 /* copy hash_value to *result */ 188 for (i = 0; i < tag_len; i++) { 189 result[i] = hash_value[i]; 190 } 191 192 debug_print(srtp_mod_hmac, "output: %s", 193 srtp_octet_string_hex_string(hash_value, tag_len)); 194 195 return srtp_err_status_ok; 196 } 197 198 /* end test case 0 */ 199 200 static const char srtp_hmac_mbedtls_description[] = 201 "hmac sha-1 authentication function using mbedtls"; 202 203 /* 204 * srtp_auth_type_t hmac is the hmac metaobject 205 */ 206 207 const srtp_auth_type_t srtp_hmac = { 208 srtp_hmac_mbedtls_alloc, /* */ 209 srtp_hmac_mbedtls_dealloc, /* */ 210 srtp_hmac_mbedtls_init, /* */ 211 srtp_hmac_mbedtls_compute, /* */ 212 srtp_hmac_mbedtls_update, /* */ 213 srtp_hmac_mbedtls_start, /* */ 214 srtp_hmac_mbedtls_description, /* */ 215 &srtp_hmac_test_case_0, /* */ 216 SRTP_HMAC_SHA1 /* */ 217 };