1 /* 2 * libjingle 3 * Copyright 2014 Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #if defined(HAVE_SRTP) && defined(ENABLE_EXTERNAL_AUTH) 29 30 #include "talk/session/media/externalhmac.h" 31 32 #include <stdlib.h> // For malloc/free. 33 34 #ifdef SRTP_RELATIVE_PATH 35 #include "srtp.h" // NOLINT 36 #else 37 #include "third_party/libsrtp/include/srtp.h" 38 #endif // SRTP_RELATIVE_PATH 39 40 #include "talk/base/logging.h" 41 42 // Begin test case 0 */ 43 static const uint8_t kExternalHmacTestCase0Key[20] = { 44 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 45 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 46 0x0b, 0x0b, 0x0b, 0x0b 47 }; 48 49 static const uint8_t kExternalHmacTestCase0Data[8] = { 50 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 // "Hi There" 51 }; 52 53 static const uint8_t kExternalHmacFakeTag[10] = { 54 0xba, 0xdd, 0xba, 0xdd, 0xba, 0xdd, 0xba, 0xdd, 0xba, 0xdd 55 }; 56 57 static const auth_test_case_t kExternalHmacTestCase0 = { 58 20, // Octets in key 59 const_cast<uint8_t*>(kExternalHmacTestCase0Key), // Key 60 8, // Octets in data 61 const_cast<uint8_t*>(kExternalHmacTestCase0Data), // Data 62 10, // Octets in tag 63 const_cast<uint8_t*>(kExternalHmacFakeTag), // Tag 64 NULL // Pointer to next 65 // testcase 66 }; 67 68 static const char kExternalHmacDescription[] = 69 "external hmac sha-1 authentication"; 70 71 // auth_type_t external_hmac is the hmac metaobject 72 73 static const auth_type_t external_hmac = { 74 external_hmac_alloc, 75 external_hmac_dealloc, 76 (auth_init_func) external_hmac_init, 77 (auth_compute_func) external_hmac_compute, 78 (auth_update_func) external_hmac_update, 79 (auth_start_func) external_hmac_start, 80 const_cast<char*>(kExternalHmacDescription), 81 0, // Instance count. 82 const_cast<auth_test_case_t*>(&kExternalHmacTestCase0), 83 NULL, // No debugging module. 84 EXTERNAL_HMAC_SHA1 85 }; 86 87 88 err_status_t external_hmac_alloc(auth_t** a, int key_len, int out_len) { 89 uint8_t* pointer; 90 91 // Check key length - note that we don't support keys larger 92 // than 20 bytes yet 93 if (key_len > 20) 94 return err_status_bad_param; 95 96 // Check output length - should be less than 20 bytes/ 97 if (out_len > 20) 98 return err_status_bad_param; 99 100 // Allocate memory for auth and hmac_ctx_t structures. 101 pointer = new uint8_t[(sizeof(external_hmac_ctx_t) + sizeof(auth_t))]; 102 if (pointer == NULL) 103 return err_status_alloc_fail; 104 105 // Set pointers 106 *a = (auth_t *)pointer; 107 // |external_hmac| is const and libsrtp expects |type| to be non-const. 108 // const conversion is required. |external_hmac| is constant because we don't 109 // want to increase global count in Chrome. 110 (*a)->type = const_cast<auth_type_t*>(&external_hmac); 111 (*a)->state = pointer + sizeof(auth_t); 112 (*a)->out_len = out_len; 113 (*a)->key_len = key_len; 114 (*a)->prefix_len = 0; 115 116 return err_status_ok; 117 } 118 119 err_status_t external_hmac_dealloc(auth_t* a) { 120 // Zeroize entire state 121 memset((uint8_t *)a, 0, sizeof(external_hmac_ctx_t) + sizeof(auth_t)); 122 123 // Free memory 124 delete[] a; 125 126 return err_status_ok; 127 } 128 129 err_status_t external_hmac_init(external_hmac_ctx_t* state, 130 const uint8_t* key, 131 int key_len) { 132 if (key_len > HMAC_KEY_LENGTH) 133 return err_status_bad_param; 134 135 memset(state->key, 0, key_len); 136 memcpy(state->key, key, key_len); 137 state->key_length = key_len; 138 return err_status_ok; 139 } 140 141 err_status_t external_hmac_start(external_hmac_ctx_t* state) { 142 return err_status_ok; 143 } 144 145 err_status_t external_hmac_update(external_hmac_ctx_t* state, 146 const uint8_t* message, 147 int msg_octets) { 148 return err_status_ok; 149 } 150 151 err_status_t external_hmac_compute(external_hmac_ctx_t* state, 152 const void* message, 153 int msg_octets, 154 int tag_len, 155 uint8_t* result) { 156 memcpy(result, kExternalHmacFakeTag, tag_len); 157 return err_status_ok; 158 } 159 160 err_status_t external_crypto_init() { 161 // |external_hmac| is const. const_cast is required as libsrtp expects 162 // non-const. 163 err_status_t status = crypto_kernel_replace_auth_type( 164 const_cast<auth_type_t*>(&external_hmac), EXTERNAL_HMAC_SHA1); 165 if (status) { 166 LOG(LS_ERROR) << "Error in replacing default auth module, error: " 167 << status; 168 return err_status_fail; 169 } 170 return err_status_ok; 171 } 172 173 #endif // defined(HAVE_SRTP) && defined(ENABLE_EXTERNAL_AUTH) 174