1 /*- 2 * Copyright 2006 Bob Jenkins 3 * 4 * Derived from public domain source, see 5 * <http://burtleburtle.net/bob/c/lookup3.c>: 6 * 7 * "lookup3.c, by Bob Jenkins, May 2006, Public Domain. 8 * 9 * These are functions for producing 32-bit hashes for hash table lookup... 10 * ...You can use this free for any purpose. It's in the public domain. 11 * It has no warranty." 12 * 13 * Copyright (c) 2014-2016 Solarflare Communications Inc. 14 * All rights reserved. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions are met: 18 * 19 * 1. Redistributions of source code must retain the above copyright notice, 20 * this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright notice, 22 * this list of conditions and the following disclaimer in the documentation 23 * and/or other materials provided with the distribution. 24 * 25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 27 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 30 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 32 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 35 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * The views and conclusions contained in the software and documentation are 38 * those of the authors and should not be interpreted as representing official 39 * policies, either expressed or implied, of the FreeBSD Project. 40 */ 41 42 #include <sys/cdefs.h> 43 #include "efx.h" 44 #include "efx_impl.h" 45 46 /* Hash initial value */ 47 #define EFX_HASH_INITIAL_VALUE 0xdeadbeef 48 49 /* 50 * Rotate a 32-bit value left 51 * 52 * Allow platform to provide an intrinsic or optimised routine and 53 * fall-back to a simple shift based implementation. 54 */ 55 #if EFSYS_HAS_ROTL_DWORD 56 57 #define EFX_HASH_ROTATE(_value, _shift) \ 58 EFSYS_ROTL_DWORD(_value, _shift) 59 60 #else 61 62 #define EFX_HASH_ROTATE(_value, _shift) \ 63 (((_value) << (_shift)) | ((_value) >> (32 - (_shift)))) 64 65 #endif 66 67 /* Mix three 32-bit values reversibly */ 68 #define EFX_HASH_MIX(_a, _b, _c) \ 69 do { \ 70 _a -= _c; \ 71 _a ^= EFX_HASH_ROTATE(_c, 4); \ 72 _c += _b; \ 73 _b -= _a; \ 74 _b ^= EFX_HASH_ROTATE(_a, 6); \ 75 _a += _c; \ 76 _c -= _b; \ 77 _c ^= EFX_HASH_ROTATE(_b, 8); \ 78 _b += _a; \ 79 _a -= _c; \ 80 _a ^= EFX_HASH_ROTATE(_c, 16); \ 81 _c += _b; \ 82 _b -= _a; \ 83 _b ^= EFX_HASH_ROTATE(_a, 19); \ 84 _a += _c; \ 85 _c -= _b; \ 86 _c ^= EFX_HASH_ROTATE(_b, 4); \ 87 _b += _a; \ 88 _NOTE(CONSTANTCONDITION) \ 89 } while (B_FALSE) 90 91 /* Final mixing of three 32-bit values into one (_c) */ 92 #define EFX_HASH_FINALISE(_a, _b, _c) \ 93 do { \ 94 _c ^= _b; \ 95 _c -= EFX_HASH_ROTATE(_b, 14); \ 96 _a ^= _c; \ 97 _a -= EFX_HASH_ROTATE(_c, 11); \ 98 _b ^= _a; \ 99 _b -= EFX_HASH_ROTATE(_a, 25); \ 100 _c ^= _b; \ 101 _c -= EFX_HASH_ROTATE(_b, 16); \ 102 _a ^= _c; \ 103 _a -= EFX_HASH_ROTATE(_c, 4); \ 104 _b ^= _a; \ 105 _b -= EFX_HASH_ROTATE(_a, 14); \ 106 _c ^= _b; \ 107 _c -= EFX_HASH_ROTATE(_b, 24); \ 108 _NOTE(CONSTANTCONDITION) \ 109 } while (B_FALSE) 110 111 /* Produce a 32-bit hash from 32-bit aligned input */ 112 __checkReturn uint32_t 113 efx_hash_dwords( 114 __in_ecount(count) uint32_t const *input, 115 __in size_t count, 116 __in uint32_t init) 117 { 118 uint32_t a; 119 uint32_t b; 120 uint32_t c; 121 122 /* Set up the initial internal state */ 123 a = b = c = EFX_HASH_INITIAL_VALUE + 124 (((uint32_t)count) * sizeof (uint32_t)) + init; 125 126 /* Handle all but the last three dwords of the input */ 127 while (count > 3) { 128 a += input[0]; 129 b += input[1]; 130 c += input[2]; 131 EFX_HASH_MIX(a, b, c); 132 133 count -= 3; 134 input += 3; 135 } 136 137 /* Handle the left-overs */ 138 switch (count) { 139 case 3: 140 c += input[2]; 141 /* Fall-through */ 142 case 2: 143 b += input[1]; 144 /* Fall-through */ 145 case 1: 146 a += input[0]; 147 EFX_HASH_FINALISE(a, b, c); 148 break; 149 150 case 0: 151 /* Should only get here if count parameter was zero */ 152 break; 153 } 154 155 return (c); 156 } 157 158 #if EFSYS_IS_BIG_ENDIAN 159 160 /* Produce a 32-bit hash from arbitrarily aligned input */ 161 __checkReturn uint32_t 162 efx_hash_bytes( 163 __in_ecount(length) uint8_t const *input, 164 __in size_t length, 165 __in uint32_t init) 166 { 167 uint32_t a; 168 uint32_t b; 169 uint32_t c; 170 171 /* Set up the initial internal state */ 172 a = b = c = EFX_HASH_INITIAL_VALUE + (uint32_t)length + init; 173 174 /* Handle all but the last twelve bytes of the input */ 175 while (length > 12) { 176 a += ((uint32_t)input[0]) << 24; 177 a += ((uint32_t)input[1]) << 16; 178 a += ((uint32_t)input[2]) << 8; 179 a += ((uint32_t)input[3]); 180 b += ((uint32_t)input[4]) << 24; 181 b += ((uint32_t)input[5]) << 16; 182 b += ((uint32_t)input[6]) << 8; 183 b += ((uint32_t)input[7]); 184 c += ((uint32_t)input[8]) << 24; 185 c += ((uint32_t)input[9]) << 16; 186 c += ((uint32_t)input[10]) << 8; 187 c += ((uint32_t)input[11]); 188 EFX_HASH_MIX(a, b, c); 189 length -= 12; 190 input += 12; 191 } 192 193 /* Handle the left-overs */ 194 switch (length) { 195 case 12: 196 c += ((uint32_t)input[11]); 197 /* Fall-through */ 198 case 11: 199 c += ((uint32_t)input[10]) << 8; 200 /* Fall-through */ 201 case 10: 202 c += ((uint32_t)input[9]) << 16; 203 /* Fall-through */ 204 case 9: 205 c += ((uint32_t)input[8]) << 24; 206 /* Fall-through */ 207 case 8: 208 b += ((uint32_t)input[7]); 209 /* Fall-through */ 210 case 7: 211 b += ((uint32_t)input[6]) << 8; 212 /* Fall-through */ 213 case 6: 214 b += ((uint32_t)input[5]) << 16; 215 /* Fall-through */ 216 case 5: 217 b += ((uint32_t)input[4]) << 24; 218 /* Fall-through */ 219 case 4: 220 a += ((uint32_t)input[3]); 221 /* Fall-through */ 222 case 3: 223 a += ((uint32_t)input[2]) << 8; 224 /* Fall-through */ 225 case 2: 226 a += ((uint32_t)input[1]) << 16; 227 /* Fall-through */ 228 case 1: 229 a += ((uint32_t)input[0]) << 24; 230 EFX_HASH_FINALISE(a, b, c); 231 break; 232 233 case 0: 234 /* Should only get here if length parameter was zero */ 235 break; 236 } 237 238 return (c); 239 } 240 241 #elif EFSYS_IS_LITTLE_ENDIAN 242 243 /* Produce a 32-bit hash from arbitrarily aligned input */ 244 __checkReturn uint32_t 245 efx_hash_bytes( 246 __in_ecount(length) uint8_t const *input, 247 __in size_t length, 248 __in uint32_t init) 249 { 250 uint32_t a; 251 uint32_t b; 252 uint32_t c; 253 254 /* Set up the initial internal state */ 255 a = b = c = EFX_HASH_INITIAL_VALUE + (uint32_t)length + init; 256 257 /* Handle all but the last twelve bytes of the input */ 258 while (length > 12) { 259 a += ((uint32_t)input[0]); 260 a += ((uint32_t)input[1]) << 8; 261 a += ((uint32_t)input[2]) << 16; 262 a += ((uint32_t)input[3]) << 24; 263 b += ((uint32_t)input[4]); 264 b += ((uint32_t)input[5]) << 8; 265 b += ((uint32_t)input[6]) << 16; 266 b += ((uint32_t)input[7]) << 24; 267 c += ((uint32_t)input[8]); 268 c += ((uint32_t)input[9]) << 8; 269 c += ((uint32_t)input[10]) << 16; 270 c += ((uint32_t)input[11]) << 24; 271 EFX_HASH_MIX(a, b, c); 272 length -= 12; 273 input += 12; 274 } 275 276 /* Handle the left-overs */ 277 switch (length) { 278 case 12: 279 c += ((uint32_t)input[11]) << 24; 280 /* Fall-through */ 281 case 11: 282 c += ((uint32_t)input[10]) << 16; 283 /* Fall-through */ 284 case 10: 285 c += ((uint32_t)input[9]) << 8; 286 /* Fall-through */ 287 case 9: 288 c += ((uint32_t)input[8]); 289 /* Fall-through */ 290 case 8: 291 b += ((uint32_t)input[7]) << 24; 292 /* Fall-through */ 293 case 7: 294 b += ((uint32_t)input[6]) << 16; 295 /* Fall-through */ 296 case 6: 297 b += ((uint32_t)input[5]) << 8; 298 /* Fall-through */ 299 case 5: 300 b += ((uint32_t)input[4]); 301 /* Fall-through */ 302 case 4: 303 a += ((uint32_t)input[3]) << 24; 304 /* Fall-through */ 305 case 3: 306 a += ((uint32_t)input[2]) << 16; 307 /* Fall-through */ 308 case 2: 309 a += ((uint32_t)input[1]) << 8; 310 /* Fall-through */ 311 case 1: 312 a += ((uint32_t)input[0]); 313 EFX_HASH_FINALISE(a, b, c); 314 break; 315 316 case 0: 317 /* Should only get here if length parameter was zero */ 318 break; 319 } 320 321 return (c); 322 } 323 324 #else 325 326 #error "Neither of EFSYS_IS_{BIG,LITTLE}_ENDIAN is set" 327 328 #endif 329