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 extern "C" { 35 #ifdef SRTP_RELATIVE_PATH 36 #include "srtp.h" // NOLINT 37 #include "crypto_kernel.h" // NOLINT 38 #else 39 #include "third_party/libsrtp/srtp/include/srtp.h" 40 #include "third_party/libsrtp/srtp/crypto/include/crypto_kernel.h" 41 #endif // SRTP_RELATIVE_PATH 42 } 43 44 #include "webrtc/base/logging.h" 45 46 // Begin test case 0 */ 47 static const uint8_t kExternalHmacTestCase0Key[20] = { 48 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 49 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 50 0x0b, 0x0b, 0x0b, 0x0b 51 }; 52 53 static const uint8_t kExternalHmacTestCase0Data[8] = { 54 0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 // "Hi There" 55 }; 56 57 static const uint8_t kExternalHmacFakeTag[10] = { 58 0xba, 0xdd, 0xba, 0xdd, 0xba, 0xdd, 0xba, 0xdd, 0xba, 0xdd 59 }; 60 61 static const auth_test_case_t kExternalHmacTestCase0 = { 62 20, // Octets in key 63 const_cast<uint8_t*>(kExternalHmacTestCase0Key), // Key 64 8, // Octets in data 65 const_cast<uint8_t*>(kExternalHmacTestCase0Data), // Data 66 10, // Octets in tag 67 const_cast<uint8_t*>(kExternalHmacFakeTag), // Tag 68 NULL // Pointer to next 69 // testcase 70 }; 71 72 static const char kExternalHmacDescription[] = 73 "external hmac sha-1 authentication"; 74 75 // auth_type_t external_hmac is the hmac metaobject 76 77 static const auth_type_t external_hmac = { 78 external_hmac_alloc, 79 external_hmac_dealloc, 80 (auth_init_func) external_hmac_init, 81 (auth_compute_func) external_hmac_compute, 82 (auth_update_func) external_hmac_update, 83 (auth_start_func) external_hmac_start, 84 const_cast<char*>(kExternalHmacDescription), 85 0, // Instance count. 86 const_cast<auth_test_case_t*>(&kExternalHmacTestCase0), 87 NULL, // No debugging module. 88 EXTERNAL_HMAC_SHA1 89 }; 90 91 92 err_status_t external_hmac_alloc(auth_t** a, int key_len, int out_len) { 93 uint8_t* pointer; 94 95 // Check key length - note that we don't support keys larger 96 // than 20 bytes yet 97 if (key_len > 20) 98 return err_status_bad_param; 99 100 // Check output length - should be less than 20 bytes/ 101 if (out_len > 20) 102 return err_status_bad_param; 103 104 // Allocate memory for auth and hmac_ctx_t structures. 105 pointer = new uint8_t[(sizeof(ExternalHmacContext) + sizeof(auth_t))]; 106 if (pointer == NULL) 107 return err_status_alloc_fail; 108 109 // Set pointers 110 *a = (auth_t *)pointer; 111 // |external_hmac| is const and libsrtp expects |type| to be non-const. 112 // const conversion is required. |external_hmac| is constant because we don't 113 // want to increase global count in Chrome. 114 (*a)->type = const_cast<auth_type_t*>(&external_hmac); 115 (*a)->state = pointer + sizeof(auth_t); 116 (*a)->out_len = out_len; 117 (*a)->key_len = key_len; 118 (*a)->prefix_len = 0; 119 120 return err_status_ok; 121 } 122 123 err_status_t external_hmac_dealloc(auth_t* a) { 124 // Zeroize entire state 125 memset((uint8_t *)a, 0, sizeof(ExternalHmacContext) + sizeof(auth_t)); 126 127 // Free memory 128 delete[] a; 129 130 return err_status_ok; 131 } 132 133 err_status_t external_hmac_init(ExternalHmacContext* state, 134 const uint8_t* key, 135 int key_len) { 136 if (key_len > HMAC_KEY_LENGTH) 137 return err_status_bad_param; 138 139 memset(state->key, 0, key_len); 140 memcpy(state->key, key, key_len); 141 state->key_length = key_len; 142 return err_status_ok; 143 } 144 145 err_status_t external_hmac_start(ExternalHmacContext* state) { 146 return err_status_ok; 147 } 148 149 err_status_t external_hmac_update(ExternalHmacContext* state, 150 const uint8_t* message, 151 int msg_octets) { 152 return err_status_ok; 153 } 154 155 err_status_t external_hmac_compute(ExternalHmacContext* state, 156 const void* message, 157 int msg_octets, 158 int tag_len, 159 uint8_t* result) { 160 memcpy(result, kExternalHmacFakeTag, tag_len); 161 return err_status_ok; 162 } 163 164 err_status_t external_crypto_init() { 165 // |external_hmac| is const. const_cast is required as libsrtp expects 166 // non-const. 167 err_status_t status = crypto_kernel_replace_auth_type( 168 const_cast<auth_type_t*>(&external_hmac), EXTERNAL_HMAC_SHA1); 169 if (status) { 170 LOG(LS_ERROR) << "Error in replacing default auth module, error: " 171 << status; 172 return err_status_fail; 173 } 174 return err_status_ok; 175 } 176 177 #endif // defined(HAVE_SRTP) && defined(ENABLE_EXTERNAL_AUTH) 178