18c2ecf20Sopenharmony_ci/* Copyright (C) 2016 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved. 28c2ecf20Sopenharmony_ci * 38c2ecf20Sopenharmony_ci * This file is provided under a dual BSD/GPLv2 license. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * SipHash: a fast short-input PRF 68c2ecf20Sopenharmony_ci * https://131002.net/siphash/ 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * This implementation is specifically for SipHash2-4 for a secure PRF 98c2ecf20Sopenharmony_ci * and HalfSipHash1-3/SipHash1-3 for an insecure PRF only suitable for 108c2ecf20Sopenharmony_ci * hashtables. 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/siphash.h> 148c2ecf20Sopenharmony_ci#include <asm/unaligned.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64 178c2ecf20Sopenharmony_ci#include <linux/dcache.h> 188c2ecf20Sopenharmony_ci#include <asm/word-at-a-time.h> 198c2ecf20Sopenharmony_ci#endif 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define SIPROUND SIPHASH_PERMUTATION(v0, v1, v2, v3) 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define PREAMBLE(len) \ 248c2ecf20Sopenharmony_ci u64 v0 = SIPHASH_CONST_0; \ 258c2ecf20Sopenharmony_ci u64 v1 = SIPHASH_CONST_1; \ 268c2ecf20Sopenharmony_ci u64 v2 = SIPHASH_CONST_2; \ 278c2ecf20Sopenharmony_ci u64 v3 = SIPHASH_CONST_3; \ 288c2ecf20Sopenharmony_ci u64 b = ((u64)(len)) << 56; \ 298c2ecf20Sopenharmony_ci v3 ^= key->key[1]; \ 308c2ecf20Sopenharmony_ci v2 ^= key->key[0]; \ 318c2ecf20Sopenharmony_ci v1 ^= key->key[1]; \ 328c2ecf20Sopenharmony_ci v0 ^= key->key[0]; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#define POSTAMBLE \ 358c2ecf20Sopenharmony_ci v3 ^= b; \ 368c2ecf20Sopenharmony_ci SIPROUND; \ 378c2ecf20Sopenharmony_ci SIPROUND; \ 388c2ecf20Sopenharmony_ci v0 ^= b; \ 398c2ecf20Sopenharmony_ci v2 ^= 0xff; \ 408c2ecf20Sopenharmony_ci SIPROUND; \ 418c2ecf20Sopenharmony_ci SIPROUND; \ 428c2ecf20Sopenharmony_ci SIPROUND; \ 438c2ecf20Sopenharmony_ci SIPROUND; \ 448c2ecf20Sopenharmony_ci return (v0 ^ v1) ^ (v2 ^ v3); 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 478c2ecf20Sopenharmony_ciu64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key) 488c2ecf20Sopenharmony_ci{ 498c2ecf20Sopenharmony_ci const u8 *end = data + len - (len % sizeof(u64)); 508c2ecf20Sopenharmony_ci const u8 left = len & (sizeof(u64) - 1); 518c2ecf20Sopenharmony_ci u64 m; 528c2ecf20Sopenharmony_ci PREAMBLE(len) 538c2ecf20Sopenharmony_ci for (; data != end; data += sizeof(u64)) { 548c2ecf20Sopenharmony_ci m = le64_to_cpup(data); 558c2ecf20Sopenharmony_ci v3 ^= m; 568c2ecf20Sopenharmony_ci SIPROUND; 578c2ecf20Sopenharmony_ci SIPROUND; 588c2ecf20Sopenharmony_ci v0 ^= m; 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64 618c2ecf20Sopenharmony_ci if (left) 628c2ecf20Sopenharmony_ci b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) & 638c2ecf20Sopenharmony_ci bytemask_from_count(left))); 648c2ecf20Sopenharmony_ci#else 658c2ecf20Sopenharmony_ci switch (left) { 668c2ecf20Sopenharmony_ci case 7: b |= ((u64)end[6]) << 48; /* fall through */ 678c2ecf20Sopenharmony_ci case 6: b |= ((u64)end[5]) << 40; /* fall through */ 688c2ecf20Sopenharmony_ci case 5: b |= ((u64)end[4]) << 32; /* fall through */ 698c2ecf20Sopenharmony_ci case 4: b |= le32_to_cpup(data); break; 708c2ecf20Sopenharmony_ci case 3: b |= ((u64)end[2]) << 16; /* fall through */ 718c2ecf20Sopenharmony_ci case 2: b |= le16_to_cpup(data); break; 728c2ecf20Sopenharmony_ci case 1: b |= end[0]; 738c2ecf20Sopenharmony_ci } 748c2ecf20Sopenharmony_ci#endif 758c2ecf20Sopenharmony_ci POSTAMBLE 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__siphash_aligned); 788c2ecf20Sopenharmony_ci#endif 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ciu64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key) 818c2ecf20Sopenharmony_ci{ 828c2ecf20Sopenharmony_ci const u8 *end = data + len - (len % sizeof(u64)); 838c2ecf20Sopenharmony_ci const u8 left = len & (sizeof(u64) - 1); 848c2ecf20Sopenharmony_ci u64 m; 858c2ecf20Sopenharmony_ci PREAMBLE(len) 868c2ecf20Sopenharmony_ci for (; data != end; data += sizeof(u64)) { 878c2ecf20Sopenharmony_ci m = get_unaligned_le64(data); 888c2ecf20Sopenharmony_ci v3 ^= m; 898c2ecf20Sopenharmony_ci SIPROUND; 908c2ecf20Sopenharmony_ci SIPROUND; 918c2ecf20Sopenharmony_ci v0 ^= m; 928c2ecf20Sopenharmony_ci } 938c2ecf20Sopenharmony_ci#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64 948c2ecf20Sopenharmony_ci if (left) 958c2ecf20Sopenharmony_ci b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) & 968c2ecf20Sopenharmony_ci bytemask_from_count(left))); 978c2ecf20Sopenharmony_ci#else 988c2ecf20Sopenharmony_ci switch (left) { 998c2ecf20Sopenharmony_ci case 7: b |= ((u64)end[6]) << 48; /* fall through */ 1008c2ecf20Sopenharmony_ci case 6: b |= ((u64)end[5]) << 40; /* fall through */ 1018c2ecf20Sopenharmony_ci case 5: b |= ((u64)end[4]) << 32; /* fall through */ 1028c2ecf20Sopenharmony_ci case 4: b |= get_unaligned_le32(end); break; 1038c2ecf20Sopenharmony_ci case 3: b |= ((u64)end[2]) << 16; /* fall through */ 1048c2ecf20Sopenharmony_ci case 2: b |= get_unaligned_le16(end); break; 1058c2ecf20Sopenharmony_ci case 1: b |= end[0]; 1068c2ecf20Sopenharmony_ci } 1078c2ecf20Sopenharmony_ci#endif 1088c2ecf20Sopenharmony_ci POSTAMBLE 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__siphash_unaligned); 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_ci/** 1138c2ecf20Sopenharmony_ci * siphash_1u64 - compute 64-bit siphash PRF value of a u64 1148c2ecf20Sopenharmony_ci * @first: first u64 1158c2ecf20Sopenharmony_ci * @key: the siphash key 1168c2ecf20Sopenharmony_ci */ 1178c2ecf20Sopenharmony_ciu64 siphash_1u64(const u64 first, const siphash_key_t *key) 1188c2ecf20Sopenharmony_ci{ 1198c2ecf20Sopenharmony_ci PREAMBLE(8) 1208c2ecf20Sopenharmony_ci v3 ^= first; 1218c2ecf20Sopenharmony_ci SIPROUND; 1228c2ecf20Sopenharmony_ci SIPROUND; 1238c2ecf20Sopenharmony_ci v0 ^= first; 1248c2ecf20Sopenharmony_ci POSTAMBLE 1258c2ecf20Sopenharmony_ci} 1268c2ecf20Sopenharmony_ciEXPORT_SYMBOL(siphash_1u64); 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_ci/** 1298c2ecf20Sopenharmony_ci * siphash_2u64 - compute 64-bit siphash PRF value of 2 u64 1308c2ecf20Sopenharmony_ci * @first: first u64 1318c2ecf20Sopenharmony_ci * @second: second u64 1328c2ecf20Sopenharmony_ci * @key: the siphash key 1338c2ecf20Sopenharmony_ci */ 1348c2ecf20Sopenharmony_ciu64 siphash_2u64(const u64 first, const u64 second, const siphash_key_t *key) 1358c2ecf20Sopenharmony_ci{ 1368c2ecf20Sopenharmony_ci PREAMBLE(16) 1378c2ecf20Sopenharmony_ci v3 ^= first; 1388c2ecf20Sopenharmony_ci SIPROUND; 1398c2ecf20Sopenharmony_ci SIPROUND; 1408c2ecf20Sopenharmony_ci v0 ^= first; 1418c2ecf20Sopenharmony_ci v3 ^= second; 1428c2ecf20Sopenharmony_ci SIPROUND; 1438c2ecf20Sopenharmony_ci SIPROUND; 1448c2ecf20Sopenharmony_ci v0 ^= second; 1458c2ecf20Sopenharmony_ci POSTAMBLE 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ciEXPORT_SYMBOL(siphash_2u64); 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_ci/** 1508c2ecf20Sopenharmony_ci * siphash_3u64 - compute 64-bit siphash PRF value of 3 u64 1518c2ecf20Sopenharmony_ci * @first: first u64 1528c2ecf20Sopenharmony_ci * @second: second u64 1538c2ecf20Sopenharmony_ci * @third: third u64 1548c2ecf20Sopenharmony_ci * @key: the siphash key 1558c2ecf20Sopenharmony_ci */ 1568c2ecf20Sopenharmony_ciu64 siphash_3u64(const u64 first, const u64 second, const u64 third, 1578c2ecf20Sopenharmony_ci const siphash_key_t *key) 1588c2ecf20Sopenharmony_ci{ 1598c2ecf20Sopenharmony_ci PREAMBLE(24) 1608c2ecf20Sopenharmony_ci v3 ^= first; 1618c2ecf20Sopenharmony_ci SIPROUND; 1628c2ecf20Sopenharmony_ci SIPROUND; 1638c2ecf20Sopenharmony_ci v0 ^= first; 1648c2ecf20Sopenharmony_ci v3 ^= second; 1658c2ecf20Sopenharmony_ci SIPROUND; 1668c2ecf20Sopenharmony_ci SIPROUND; 1678c2ecf20Sopenharmony_ci v0 ^= second; 1688c2ecf20Sopenharmony_ci v3 ^= third; 1698c2ecf20Sopenharmony_ci SIPROUND; 1708c2ecf20Sopenharmony_ci SIPROUND; 1718c2ecf20Sopenharmony_ci v0 ^= third; 1728c2ecf20Sopenharmony_ci POSTAMBLE 1738c2ecf20Sopenharmony_ci} 1748c2ecf20Sopenharmony_ciEXPORT_SYMBOL(siphash_3u64); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci/** 1778c2ecf20Sopenharmony_ci * siphash_4u64 - compute 64-bit siphash PRF value of 4 u64 1788c2ecf20Sopenharmony_ci * @first: first u64 1798c2ecf20Sopenharmony_ci * @second: second u64 1808c2ecf20Sopenharmony_ci * @third: third u64 1818c2ecf20Sopenharmony_ci * @forth: forth u64 1828c2ecf20Sopenharmony_ci * @key: the siphash key 1838c2ecf20Sopenharmony_ci */ 1848c2ecf20Sopenharmony_ciu64 siphash_4u64(const u64 first, const u64 second, const u64 third, 1858c2ecf20Sopenharmony_ci const u64 forth, const siphash_key_t *key) 1868c2ecf20Sopenharmony_ci{ 1878c2ecf20Sopenharmony_ci PREAMBLE(32) 1888c2ecf20Sopenharmony_ci v3 ^= first; 1898c2ecf20Sopenharmony_ci SIPROUND; 1908c2ecf20Sopenharmony_ci SIPROUND; 1918c2ecf20Sopenharmony_ci v0 ^= first; 1928c2ecf20Sopenharmony_ci v3 ^= second; 1938c2ecf20Sopenharmony_ci SIPROUND; 1948c2ecf20Sopenharmony_ci SIPROUND; 1958c2ecf20Sopenharmony_ci v0 ^= second; 1968c2ecf20Sopenharmony_ci v3 ^= third; 1978c2ecf20Sopenharmony_ci SIPROUND; 1988c2ecf20Sopenharmony_ci SIPROUND; 1998c2ecf20Sopenharmony_ci v0 ^= third; 2008c2ecf20Sopenharmony_ci v3 ^= forth; 2018c2ecf20Sopenharmony_ci SIPROUND; 2028c2ecf20Sopenharmony_ci SIPROUND; 2038c2ecf20Sopenharmony_ci v0 ^= forth; 2048c2ecf20Sopenharmony_ci POSTAMBLE 2058c2ecf20Sopenharmony_ci} 2068c2ecf20Sopenharmony_ciEXPORT_SYMBOL(siphash_4u64); 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ciu64 siphash_1u32(const u32 first, const siphash_key_t *key) 2098c2ecf20Sopenharmony_ci{ 2108c2ecf20Sopenharmony_ci PREAMBLE(4) 2118c2ecf20Sopenharmony_ci b |= first; 2128c2ecf20Sopenharmony_ci POSTAMBLE 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ciEXPORT_SYMBOL(siphash_1u32); 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ciu64 siphash_3u32(const u32 first, const u32 second, const u32 third, 2178c2ecf20Sopenharmony_ci const siphash_key_t *key) 2188c2ecf20Sopenharmony_ci{ 2198c2ecf20Sopenharmony_ci u64 combined = (u64)second << 32 | first; 2208c2ecf20Sopenharmony_ci PREAMBLE(12) 2218c2ecf20Sopenharmony_ci v3 ^= combined; 2228c2ecf20Sopenharmony_ci SIPROUND; 2238c2ecf20Sopenharmony_ci SIPROUND; 2248c2ecf20Sopenharmony_ci v0 ^= combined; 2258c2ecf20Sopenharmony_ci b |= third; 2268c2ecf20Sopenharmony_ci POSTAMBLE 2278c2ecf20Sopenharmony_ci} 2288c2ecf20Sopenharmony_ciEXPORT_SYMBOL(siphash_3u32); 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci#if BITS_PER_LONG == 64 2318c2ecf20Sopenharmony_ci/* Note that on 64-bit, we make HalfSipHash1-3 actually be SipHash1-3, for 2328c2ecf20Sopenharmony_ci * performance reasons. On 32-bit, below, we actually implement HalfSipHash1-3. 2338c2ecf20Sopenharmony_ci */ 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci#define HSIPROUND SIPROUND 2368c2ecf20Sopenharmony_ci#define HPREAMBLE(len) PREAMBLE(len) 2378c2ecf20Sopenharmony_ci#define HPOSTAMBLE \ 2388c2ecf20Sopenharmony_ci v3 ^= b; \ 2398c2ecf20Sopenharmony_ci HSIPROUND; \ 2408c2ecf20Sopenharmony_ci v0 ^= b; \ 2418c2ecf20Sopenharmony_ci v2 ^= 0xff; \ 2428c2ecf20Sopenharmony_ci HSIPROUND; \ 2438c2ecf20Sopenharmony_ci HSIPROUND; \ 2448c2ecf20Sopenharmony_ci HSIPROUND; \ 2458c2ecf20Sopenharmony_ci return (v0 ^ v1) ^ (v2 ^ v3); 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 2488c2ecf20Sopenharmony_ciu32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key) 2498c2ecf20Sopenharmony_ci{ 2508c2ecf20Sopenharmony_ci const u8 *end = data + len - (len % sizeof(u64)); 2518c2ecf20Sopenharmony_ci const u8 left = len & (sizeof(u64) - 1); 2528c2ecf20Sopenharmony_ci u64 m; 2538c2ecf20Sopenharmony_ci HPREAMBLE(len) 2548c2ecf20Sopenharmony_ci for (; data != end; data += sizeof(u64)) { 2558c2ecf20Sopenharmony_ci m = le64_to_cpup(data); 2568c2ecf20Sopenharmony_ci v3 ^= m; 2578c2ecf20Sopenharmony_ci HSIPROUND; 2588c2ecf20Sopenharmony_ci v0 ^= m; 2598c2ecf20Sopenharmony_ci } 2608c2ecf20Sopenharmony_ci#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64 2618c2ecf20Sopenharmony_ci if (left) 2628c2ecf20Sopenharmony_ci b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) & 2638c2ecf20Sopenharmony_ci bytemask_from_count(left))); 2648c2ecf20Sopenharmony_ci#else 2658c2ecf20Sopenharmony_ci switch (left) { 2668c2ecf20Sopenharmony_ci case 7: b |= ((u64)end[6]) << 48; /* fall through */ 2678c2ecf20Sopenharmony_ci case 6: b |= ((u64)end[5]) << 40; /* fall through */ 2688c2ecf20Sopenharmony_ci case 5: b |= ((u64)end[4]) << 32; /* fall through */ 2698c2ecf20Sopenharmony_ci case 4: b |= le32_to_cpup(data); break; 2708c2ecf20Sopenharmony_ci case 3: b |= ((u64)end[2]) << 16; /* fall through */ 2718c2ecf20Sopenharmony_ci case 2: b |= le16_to_cpup(data); break; 2728c2ecf20Sopenharmony_ci case 1: b |= end[0]; 2738c2ecf20Sopenharmony_ci } 2748c2ecf20Sopenharmony_ci#endif 2758c2ecf20Sopenharmony_ci HPOSTAMBLE 2768c2ecf20Sopenharmony_ci} 2778c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__hsiphash_aligned); 2788c2ecf20Sopenharmony_ci#endif 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ciu32 __hsiphash_unaligned(const void *data, size_t len, 2818c2ecf20Sopenharmony_ci const hsiphash_key_t *key) 2828c2ecf20Sopenharmony_ci{ 2838c2ecf20Sopenharmony_ci const u8 *end = data + len - (len % sizeof(u64)); 2848c2ecf20Sopenharmony_ci const u8 left = len & (sizeof(u64) - 1); 2858c2ecf20Sopenharmony_ci u64 m; 2868c2ecf20Sopenharmony_ci HPREAMBLE(len) 2878c2ecf20Sopenharmony_ci for (; data != end; data += sizeof(u64)) { 2888c2ecf20Sopenharmony_ci m = get_unaligned_le64(data); 2898c2ecf20Sopenharmony_ci v3 ^= m; 2908c2ecf20Sopenharmony_ci HSIPROUND; 2918c2ecf20Sopenharmony_ci v0 ^= m; 2928c2ecf20Sopenharmony_ci } 2938c2ecf20Sopenharmony_ci#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64 2948c2ecf20Sopenharmony_ci if (left) 2958c2ecf20Sopenharmony_ci b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) & 2968c2ecf20Sopenharmony_ci bytemask_from_count(left))); 2978c2ecf20Sopenharmony_ci#else 2988c2ecf20Sopenharmony_ci switch (left) { 2998c2ecf20Sopenharmony_ci case 7: b |= ((u64)end[6]) << 48; /* fall through */ 3008c2ecf20Sopenharmony_ci case 6: b |= ((u64)end[5]) << 40; /* fall through */ 3018c2ecf20Sopenharmony_ci case 5: b |= ((u64)end[4]) << 32; /* fall through */ 3028c2ecf20Sopenharmony_ci case 4: b |= get_unaligned_le32(end); break; 3038c2ecf20Sopenharmony_ci case 3: b |= ((u64)end[2]) << 16; /* fall through */ 3048c2ecf20Sopenharmony_ci case 2: b |= get_unaligned_le16(end); break; 3058c2ecf20Sopenharmony_ci case 1: b |= end[0]; 3068c2ecf20Sopenharmony_ci } 3078c2ecf20Sopenharmony_ci#endif 3088c2ecf20Sopenharmony_ci HPOSTAMBLE 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__hsiphash_unaligned); 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci/** 3138c2ecf20Sopenharmony_ci * hsiphash_1u32 - compute 64-bit hsiphash PRF value of a u32 3148c2ecf20Sopenharmony_ci * @first: first u32 3158c2ecf20Sopenharmony_ci * @key: the hsiphash key 3168c2ecf20Sopenharmony_ci */ 3178c2ecf20Sopenharmony_ciu32 hsiphash_1u32(const u32 first, const hsiphash_key_t *key) 3188c2ecf20Sopenharmony_ci{ 3198c2ecf20Sopenharmony_ci HPREAMBLE(4) 3208c2ecf20Sopenharmony_ci b |= first; 3218c2ecf20Sopenharmony_ci HPOSTAMBLE 3228c2ecf20Sopenharmony_ci} 3238c2ecf20Sopenharmony_ciEXPORT_SYMBOL(hsiphash_1u32); 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci/** 3268c2ecf20Sopenharmony_ci * hsiphash_2u32 - compute 32-bit hsiphash PRF value of 2 u32 3278c2ecf20Sopenharmony_ci * @first: first u32 3288c2ecf20Sopenharmony_ci * @second: second u32 3298c2ecf20Sopenharmony_ci * @key: the hsiphash key 3308c2ecf20Sopenharmony_ci */ 3318c2ecf20Sopenharmony_ciu32 hsiphash_2u32(const u32 first, const u32 second, const hsiphash_key_t *key) 3328c2ecf20Sopenharmony_ci{ 3338c2ecf20Sopenharmony_ci u64 combined = (u64)second << 32 | first; 3348c2ecf20Sopenharmony_ci HPREAMBLE(8) 3358c2ecf20Sopenharmony_ci v3 ^= combined; 3368c2ecf20Sopenharmony_ci HSIPROUND; 3378c2ecf20Sopenharmony_ci v0 ^= combined; 3388c2ecf20Sopenharmony_ci HPOSTAMBLE 3398c2ecf20Sopenharmony_ci} 3408c2ecf20Sopenharmony_ciEXPORT_SYMBOL(hsiphash_2u32); 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci/** 3438c2ecf20Sopenharmony_ci * hsiphash_3u32 - compute 32-bit hsiphash PRF value of 3 u32 3448c2ecf20Sopenharmony_ci * @first: first u32 3458c2ecf20Sopenharmony_ci * @second: second u32 3468c2ecf20Sopenharmony_ci * @third: third u32 3478c2ecf20Sopenharmony_ci * @key: the hsiphash key 3488c2ecf20Sopenharmony_ci */ 3498c2ecf20Sopenharmony_ciu32 hsiphash_3u32(const u32 first, const u32 second, const u32 third, 3508c2ecf20Sopenharmony_ci const hsiphash_key_t *key) 3518c2ecf20Sopenharmony_ci{ 3528c2ecf20Sopenharmony_ci u64 combined = (u64)second << 32 | first; 3538c2ecf20Sopenharmony_ci HPREAMBLE(12) 3548c2ecf20Sopenharmony_ci v3 ^= combined; 3558c2ecf20Sopenharmony_ci HSIPROUND; 3568c2ecf20Sopenharmony_ci v0 ^= combined; 3578c2ecf20Sopenharmony_ci b |= third; 3588c2ecf20Sopenharmony_ci HPOSTAMBLE 3598c2ecf20Sopenharmony_ci} 3608c2ecf20Sopenharmony_ciEXPORT_SYMBOL(hsiphash_3u32); 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci/** 3638c2ecf20Sopenharmony_ci * hsiphash_4u32 - compute 32-bit hsiphash PRF value of 4 u32 3648c2ecf20Sopenharmony_ci * @first: first u32 3658c2ecf20Sopenharmony_ci * @second: second u32 3668c2ecf20Sopenharmony_ci * @third: third u32 3678c2ecf20Sopenharmony_ci * @forth: forth u32 3688c2ecf20Sopenharmony_ci * @key: the hsiphash key 3698c2ecf20Sopenharmony_ci */ 3708c2ecf20Sopenharmony_ciu32 hsiphash_4u32(const u32 first, const u32 second, const u32 third, 3718c2ecf20Sopenharmony_ci const u32 forth, const hsiphash_key_t *key) 3728c2ecf20Sopenharmony_ci{ 3738c2ecf20Sopenharmony_ci u64 combined = (u64)second << 32 | first; 3748c2ecf20Sopenharmony_ci HPREAMBLE(16) 3758c2ecf20Sopenharmony_ci v3 ^= combined; 3768c2ecf20Sopenharmony_ci HSIPROUND; 3778c2ecf20Sopenharmony_ci v0 ^= combined; 3788c2ecf20Sopenharmony_ci combined = (u64)forth << 32 | third; 3798c2ecf20Sopenharmony_ci v3 ^= combined; 3808c2ecf20Sopenharmony_ci HSIPROUND; 3818c2ecf20Sopenharmony_ci v0 ^= combined; 3828c2ecf20Sopenharmony_ci HPOSTAMBLE 3838c2ecf20Sopenharmony_ci} 3848c2ecf20Sopenharmony_ciEXPORT_SYMBOL(hsiphash_4u32); 3858c2ecf20Sopenharmony_ci#else 3868c2ecf20Sopenharmony_ci#define HSIPROUND HSIPHASH_PERMUTATION(v0, v1, v2, v3) 3878c2ecf20Sopenharmony_ci 3888c2ecf20Sopenharmony_ci#define HPREAMBLE(len) \ 3898c2ecf20Sopenharmony_ci u32 v0 = HSIPHASH_CONST_0; \ 3908c2ecf20Sopenharmony_ci u32 v1 = HSIPHASH_CONST_1; \ 3918c2ecf20Sopenharmony_ci u32 v2 = HSIPHASH_CONST_2; \ 3928c2ecf20Sopenharmony_ci u32 v3 = HSIPHASH_CONST_3; \ 3938c2ecf20Sopenharmony_ci u32 b = ((u32)(len)) << 24; \ 3948c2ecf20Sopenharmony_ci v3 ^= key->key[1]; \ 3958c2ecf20Sopenharmony_ci v2 ^= key->key[0]; \ 3968c2ecf20Sopenharmony_ci v1 ^= key->key[1]; \ 3978c2ecf20Sopenharmony_ci v0 ^= key->key[0]; 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_ci#define HPOSTAMBLE \ 4008c2ecf20Sopenharmony_ci v3 ^= b; \ 4018c2ecf20Sopenharmony_ci HSIPROUND; \ 4028c2ecf20Sopenharmony_ci v0 ^= b; \ 4038c2ecf20Sopenharmony_ci v2 ^= 0xff; \ 4048c2ecf20Sopenharmony_ci HSIPROUND; \ 4058c2ecf20Sopenharmony_ci HSIPROUND; \ 4068c2ecf20Sopenharmony_ci HSIPROUND; \ 4078c2ecf20Sopenharmony_ci return v1 ^ v3; 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 4108c2ecf20Sopenharmony_ciu32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key) 4118c2ecf20Sopenharmony_ci{ 4128c2ecf20Sopenharmony_ci const u8 *end = data + len - (len % sizeof(u32)); 4138c2ecf20Sopenharmony_ci const u8 left = len & (sizeof(u32) - 1); 4148c2ecf20Sopenharmony_ci u32 m; 4158c2ecf20Sopenharmony_ci HPREAMBLE(len) 4168c2ecf20Sopenharmony_ci for (; data != end; data += sizeof(u32)) { 4178c2ecf20Sopenharmony_ci m = le32_to_cpup(data); 4188c2ecf20Sopenharmony_ci v3 ^= m; 4198c2ecf20Sopenharmony_ci HSIPROUND; 4208c2ecf20Sopenharmony_ci v0 ^= m; 4218c2ecf20Sopenharmony_ci } 4228c2ecf20Sopenharmony_ci switch (left) { 4238c2ecf20Sopenharmony_ci case 3: b |= ((u32)end[2]) << 16; /* fall through */ 4248c2ecf20Sopenharmony_ci case 2: b |= le16_to_cpup(data); break; 4258c2ecf20Sopenharmony_ci case 1: b |= end[0]; 4268c2ecf20Sopenharmony_ci } 4278c2ecf20Sopenharmony_ci HPOSTAMBLE 4288c2ecf20Sopenharmony_ci} 4298c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__hsiphash_aligned); 4308c2ecf20Sopenharmony_ci#endif 4318c2ecf20Sopenharmony_ci 4328c2ecf20Sopenharmony_ciu32 __hsiphash_unaligned(const void *data, size_t len, 4338c2ecf20Sopenharmony_ci const hsiphash_key_t *key) 4348c2ecf20Sopenharmony_ci{ 4358c2ecf20Sopenharmony_ci const u8 *end = data + len - (len % sizeof(u32)); 4368c2ecf20Sopenharmony_ci const u8 left = len & (sizeof(u32) - 1); 4378c2ecf20Sopenharmony_ci u32 m; 4388c2ecf20Sopenharmony_ci HPREAMBLE(len) 4398c2ecf20Sopenharmony_ci for (; data != end; data += sizeof(u32)) { 4408c2ecf20Sopenharmony_ci m = get_unaligned_le32(data); 4418c2ecf20Sopenharmony_ci v3 ^= m; 4428c2ecf20Sopenharmony_ci HSIPROUND; 4438c2ecf20Sopenharmony_ci v0 ^= m; 4448c2ecf20Sopenharmony_ci } 4458c2ecf20Sopenharmony_ci switch (left) { 4468c2ecf20Sopenharmony_ci case 3: b |= ((u32)end[2]) << 16; /* fall through */ 4478c2ecf20Sopenharmony_ci case 2: b |= get_unaligned_le16(end); break; 4488c2ecf20Sopenharmony_ci case 1: b |= end[0]; 4498c2ecf20Sopenharmony_ci } 4508c2ecf20Sopenharmony_ci HPOSTAMBLE 4518c2ecf20Sopenharmony_ci} 4528c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__hsiphash_unaligned); 4538c2ecf20Sopenharmony_ci 4548c2ecf20Sopenharmony_ci/** 4558c2ecf20Sopenharmony_ci * hsiphash_1u32 - compute 32-bit hsiphash PRF value of a u32 4568c2ecf20Sopenharmony_ci * @first: first u32 4578c2ecf20Sopenharmony_ci * @key: the hsiphash key 4588c2ecf20Sopenharmony_ci */ 4598c2ecf20Sopenharmony_ciu32 hsiphash_1u32(const u32 first, const hsiphash_key_t *key) 4608c2ecf20Sopenharmony_ci{ 4618c2ecf20Sopenharmony_ci HPREAMBLE(4) 4628c2ecf20Sopenharmony_ci v3 ^= first; 4638c2ecf20Sopenharmony_ci HSIPROUND; 4648c2ecf20Sopenharmony_ci v0 ^= first; 4658c2ecf20Sopenharmony_ci HPOSTAMBLE 4668c2ecf20Sopenharmony_ci} 4678c2ecf20Sopenharmony_ciEXPORT_SYMBOL(hsiphash_1u32); 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci/** 4708c2ecf20Sopenharmony_ci * hsiphash_2u32 - compute 32-bit hsiphash PRF value of 2 u32 4718c2ecf20Sopenharmony_ci * @first: first u32 4728c2ecf20Sopenharmony_ci * @second: second u32 4738c2ecf20Sopenharmony_ci * @key: the hsiphash key 4748c2ecf20Sopenharmony_ci */ 4758c2ecf20Sopenharmony_ciu32 hsiphash_2u32(const u32 first, const u32 second, const hsiphash_key_t *key) 4768c2ecf20Sopenharmony_ci{ 4778c2ecf20Sopenharmony_ci HPREAMBLE(8) 4788c2ecf20Sopenharmony_ci v3 ^= first; 4798c2ecf20Sopenharmony_ci HSIPROUND; 4808c2ecf20Sopenharmony_ci v0 ^= first; 4818c2ecf20Sopenharmony_ci v3 ^= second; 4828c2ecf20Sopenharmony_ci HSIPROUND; 4838c2ecf20Sopenharmony_ci v0 ^= second; 4848c2ecf20Sopenharmony_ci HPOSTAMBLE 4858c2ecf20Sopenharmony_ci} 4868c2ecf20Sopenharmony_ciEXPORT_SYMBOL(hsiphash_2u32); 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci/** 4898c2ecf20Sopenharmony_ci * hsiphash_3u32 - compute 32-bit hsiphash PRF value of 3 u32 4908c2ecf20Sopenharmony_ci * @first: first u32 4918c2ecf20Sopenharmony_ci * @second: second u32 4928c2ecf20Sopenharmony_ci * @third: third u32 4938c2ecf20Sopenharmony_ci * @key: the hsiphash key 4948c2ecf20Sopenharmony_ci */ 4958c2ecf20Sopenharmony_ciu32 hsiphash_3u32(const u32 first, const u32 second, const u32 third, 4968c2ecf20Sopenharmony_ci const hsiphash_key_t *key) 4978c2ecf20Sopenharmony_ci{ 4988c2ecf20Sopenharmony_ci HPREAMBLE(12) 4998c2ecf20Sopenharmony_ci v3 ^= first; 5008c2ecf20Sopenharmony_ci HSIPROUND; 5018c2ecf20Sopenharmony_ci v0 ^= first; 5028c2ecf20Sopenharmony_ci v3 ^= second; 5038c2ecf20Sopenharmony_ci HSIPROUND; 5048c2ecf20Sopenharmony_ci v0 ^= second; 5058c2ecf20Sopenharmony_ci v3 ^= third; 5068c2ecf20Sopenharmony_ci HSIPROUND; 5078c2ecf20Sopenharmony_ci v0 ^= third; 5088c2ecf20Sopenharmony_ci HPOSTAMBLE 5098c2ecf20Sopenharmony_ci} 5108c2ecf20Sopenharmony_ciEXPORT_SYMBOL(hsiphash_3u32); 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ci/** 5138c2ecf20Sopenharmony_ci * hsiphash_4u32 - compute 32-bit hsiphash PRF value of 4 u32 5148c2ecf20Sopenharmony_ci * @first: first u32 5158c2ecf20Sopenharmony_ci * @second: second u32 5168c2ecf20Sopenharmony_ci * @third: third u32 5178c2ecf20Sopenharmony_ci * @forth: forth u32 5188c2ecf20Sopenharmony_ci * @key: the hsiphash key 5198c2ecf20Sopenharmony_ci */ 5208c2ecf20Sopenharmony_ciu32 hsiphash_4u32(const u32 first, const u32 second, const u32 third, 5218c2ecf20Sopenharmony_ci const u32 forth, const hsiphash_key_t *key) 5228c2ecf20Sopenharmony_ci{ 5238c2ecf20Sopenharmony_ci HPREAMBLE(16) 5248c2ecf20Sopenharmony_ci v3 ^= first; 5258c2ecf20Sopenharmony_ci HSIPROUND; 5268c2ecf20Sopenharmony_ci v0 ^= first; 5278c2ecf20Sopenharmony_ci v3 ^= second; 5288c2ecf20Sopenharmony_ci HSIPROUND; 5298c2ecf20Sopenharmony_ci v0 ^= second; 5308c2ecf20Sopenharmony_ci v3 ^= third; 5318c2ecf20Sopenharmony_ci HSIPROUND; 5328c2ecf20Sopenharmony_ci v0 ^= third; 5338c2ecf20Sopenharmony_ci v3 ^= forth; 5348c2ecf20Sopenharmony_ci HSIPROUND; 5358c2ecf20Sopenharmony_ci v0 ^= forth; 5368c2ecf20Sopenharmony_ci HPOSTAMBLE 5378c2ecf20Sopenharmony_ci} 5388c2ecf20Sopenharmony_ciEXPORT_SYMBOL(hsiphash_4u32); 5398c2ecf20Sopenharmony_ci#endif 540