1*4882a593Smuzhiyun /* Copyright (C) 2016 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
2*4882a593Smuzhiyun *
3*4882a593Smuzhiyun * This file is provided under a dual BSD/GPLv2 license.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SipHash: a fast short-input PRF
6*4882a593Smuzhiyun * https://131002.net/siphash/
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * This implementation is specifically for SipHash2-4 for a secure PRF
9*4882a593Smuzhiyun * and HalfSipHash1-3/SipHash1-3 for an insecure PRF only suitable for
10*4882a593Smuzhiyun * hashtables.
11*4882a593Smuzhiyun */
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <linux/siphash.h>
14*4882a593Smuzhiyun #include <asm/unaligned.h>
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
17*4882a593Smuzhiyun #include <linux/dcache.h>
18*4882a593Smuzhiyun #include <asm/word-at-a-time.h>
19*4882a593Smuzhiyun #endif
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #define SIPROUND SIPHASH_PERMUTATION(v0, v1, v2, v3)
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #define PREAMBLE(len) \
24*4882a593Smuzhiyun u64 v0 = SIPHASH_CONST_0; \
25*4882a593Smuzhiyun u64 v1 = SIPHASH_CONST_1; \
26*4882a593Smuzhiyun u64 v2 = SIPHASH_CONST_2; \
27*4882a593Smuzhiyun u64 v3 = SIPHASH_CONST_3; \
28*4882a593Smuzhiyun u64 b = ((u64)(len)) << 56; \
29*4882a593Smuzhiyun v3 ^= key->key[1]; \
30*4882a593Smuzhiyun v2 ^= key->key[0]; \
31*4882a593Smuzhiyun v1 ^= key->key[1]; \
32*4882a593Smuzhiyun v0 ^= key->key[0];
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #define POSTAMBLE \
35*4882a593Smuzhiyun v3 ^= b; \
36*4882a593Smuzhiyun SIPROUND; \
37*4882a593Smuzhiyun SIPROUND; \
38*4882a593Smuzhiyun v0 ^= b; \
39*4882a593Smuzhiyun v2 ^= 0xff; \
40*4882a593Smuzhiyun SIPROUND; \
41*4882a593Smuzhiyun SIPROUND; \
42*4882a593Smuzhiyun SIPROUND; \
43*4882a593Smuzhiyun SIPROUND; \
44*4882a593Smuzhiyun return (v0 ^ v1) ^ (v2 ^ v3);
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
__siphash_aligned(const void * data,size_t len,const siphash_key_t * key)47*4882a593Smuzhiyun u64 __siphash_aligned(const void *data, size_t len, const siphash_key_t *key)
48*4882a593Smuzhiyun {
49*4882a593Smuzhiyun const u8 *end = data + len - (len % sizeof(u64));
50*4882a593Smuzhiyun const u8 left = len & (sizeof(u64) - 1);
51*4882a593Smuzhiyun u64 m;
52*4882a593Smuzhiyun PREAMBLE(len)
53*4882a593Smuzhiyun for (; data != end; data += sizeof(u64)) {
54*4882a593Smuzhiyun m = le64_to_cpup(data);
55*4882a593Smuzhiyun v3 ^= m;
56*4882a593Smuzhiyun SIPROUND;
57*4882a593Smuzhiyun SIPROUND;
58*4882a593Smuzhiyun v0 ^= m;
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
61*4882a593Smuzhiyun if (left)
62*4882a593Smuzhiyun b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) &
63*4882a593Smuzhiyun bytemask_from_count(left)));
64*4882a593Smuzhiyun #else
65*4882a593Smuzhiyun switch (left) {
66*4882a593Smuzhiyun case 7: b |= ((u64)end[6]) << 48; /* fall through */
67*4882a593Smuzhiyun case 6: b |= ((u64)end[5]) << 40; /* fall through */
68*4882a593Smuzhiyun case 5: b |= ((u64)end[4]) << 32; /* fall through */
69*4882a593Smuzhiyun case 4: b |= le32_to_cpup(data); break;
70*4882a593Smuzhiyun case 3: b |= ((u64)end[2]) << 16; /* fall through */
71*4882a593Smuzhiyun case 2: b |= le16_to_cpup(data); break;
72*4882a593Smuzhiyun case 1: b |= end[0];
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun #endif
75*4882a593Smuzhiyun POSTAMBLE
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun EXPORT_SYMBOL(__siphash_aligned);
78*4882a593Smuzhiyun #endif
79*4882a593Smuzhiyun
__siphash_unaligned(const void * data,size_t len,const siphash_key_t * key)80*4882a593Smuzhiyun u64 __siphash_unaligned(const void *data, size_t len, const siphash_key_t *key)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun const u8 *end = data + len - (len % sizeof(u64));
83*4882a593Smuzhiyun const u8 left = len & (sizeof(u64) - 1);
84*4882a593Smuzhiyun u64 m;
85*4882a593Smuzhiyun PREAMBLE(len)
86*4882a593Smuzhiyun for (; data != end; data += sizeof(u64)) {
87*4882a593Smuzhiyun m = get_unaligned_le64(data);
88*4882a593Smuzhiyun v3 ^= m;
89*4882a593Smuzhiyun SIPROUND;
90*4882a593Smuzhiyun SIPROUND;
91*4882a593Smuzhiyun v0 ^= m;
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
94*4882a593Smuzhiyun if (left)
95*4882a593Smuzhiyun b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) &
96*4882a593Smuzhiyun bytemask_from_count(left)));
97*4882a593Smuzhiyun #else
98*4882a593Smuzhiyun switch (left) {
99*4882a593Smuzhiyun case 7: b |= ((u64)end[6]) << 48; /* fall through */
100*4882a593Smuzhiyun case 6: b |= ((u64)end[5]) << 40; /* fall through */
101*4882a593Smuzhiyun case 5: b |= ((u64)end[4]) << 32; /* fall through */
102*4882a593Smuzhiyun case 4: b |= get_unaligned_le32(end); break;
103*4882a593Smuzhiyun case 3: b |= ((u64)end[2]) << 16; /* fall through */
104*4882a593Smuzhiyun case 2: b |= get_unaligned_le16(end); break;
105*4882a593Smuzhiyun case 1: b |= end[0];
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun #endif
108*4882a593Smuzhiyun POSTAMBLE
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun EXPORT_SYMBOL(__siphash_unaligned);
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun /**
113*4882a593Smuzhiyun * siphash_1u64 - compute 64-bit siphash PRF value of a u64
114*4882a593Smuzhiyun * @first: first u64
115*4882a593Smuzhiyun * @key: the siphash key
116*4882a593Smuzhiyun */
siphash_1u64(const u64 first,const siphash_key_t * key)117*4882a593Smuzhiyun u64 siphash_1u64(const u64 first, const siphash_key_t *key)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun PREAMBLE(8)
120*4882a593Smuzhiyun v3 ^= first;
121*4882a593Smuzhiyun SIPROUND;
122*4882a593Smuzhiyun SIPROUND;
123*4882a593Smuzhiyun v0 ^= first;
124*4882a593Smuzhiyun POSTAMBLE
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun EXPORT_SYMBOL(siphash_1u64);
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun /**
129*4882a593Smuzhiyun * siphash_2u64 - compute 64-bit siphash PRF value of 2 u64
130*4882a593Smuzhiyun * @first: first u64
131*4882a593Smuzhiyun * @second: second u64
132*4882a593Smuzhiyun * @key: the siphash key
133*4882a593Smuzhiyun */
siphash_2u64(const u64 first,const u64 second,const siphash_key_t * key)134*4882a593Smuzhiyun u64 siphash_2u64(const u64 first, const u64 second, const siphash_key_t *key)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun PREAMBLE(16)
137*4882a593Smuzhiyun v3 ^= first;
138*4882a593Smuzhiyun SIPROUND;
139*4882a593Smuzhiyun SIPROUND;
140*4882a593Smuzhiyun v0 ^= first;
141*4882a593Smuzhiyun v3 ^= second;
142*4882a593Smuzhiyun SIPROUND;
143*4882a593Smuzhiyun SIPROUND;
144*4882a593Smuzhiyun v0 ^= second;
145*4882a593Smuzhiyun POSTAMBLE
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun EXPORT_SYMBOL(siphash_2u64);
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /**
150*4882a593Smuzhiyun * siphash_3u64 - compute 64-bit siphash PRF value of 3 u64
151*4882a593Smuzhiyun * @first: first u64
152*4882a593Smuzhiyun * @second: second u64
153*4882a593Smuzhiyun * @third: third u64
154*4882a593Smuzhiyun * @key: the siphash key
155*4882a593Smuzhiyun */
siphash_3u64(const u64 first,const u64 second,const u64 third,const siphash_key_t * key)156*4882a593Smuzhiyun u64 siphash_3u64(const u64 first, const u64 second, const u64 third,
157*4882a593Smuzhiyun const siphash_key_t *key)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun PREAMBLE(24)
160*4882a593Smuzhiyun v3 ^= first;
161*4882a593Smuzhiyun SIPROUND;
162*4882a593Smuzhiyun SIPROUND;
163*4882a593Smuzhiyun v0 ^= first;
164*4882a593Smuzhiyun v3 ^= second;
165*4882a593Smuzhiyun SIPROUND;
166*4882a593Smuzhiyun SIPROUND;
167*4882a593Smuzhiyun v0 ^= second;
168*4882a593Smuzhiyun v3 ^= third;
169*4882a593Smuzhiyun SIPROUND;
170*4882a593Smuzhiyun SIPROUND;
171*4882a593Smuzhiyun v0 ^= third;
172*4882a593Smuzhiyun POSTAMBLE
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun EXPORT_SYMBOL(siphash_3u64);
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun /**
177*4882a593Smuzhiyun * siphash_4u64 - compute 64-bit siphash PRF value of 4 u64
178*4882a593Smuzhiyun * @first: first u64
179*4882a593Smuzhiyun * @second: second u64
180*4882a593Smuzhiyun * @third: third u64
181*4882a593Smuzhiyun * @forth: forth u64
182*4882a593Smuzhiyun * @key: the siphash key
183*4882a593Smuzhiyun */
siphash_4u64(const u64 first,const u64 second,const u64 third,const u64 forth,const siphash_key_t * key)184*4882a593Smuzhiyun u64 siphash_4u64(const u64 first, const u64 second, const u64 third,
185*4882a593Smuzhiyun const u64 forth, const siphash_key_t *key)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun PREAMBLE(32)
188*4882a593Smuzhiyun v3 ^= first;
189*4882a593Smuzhiyun SIPROUND;
190*4882a593Smuzhiyun SIPROUND;
191*4882a593Smuzhiyun v0 ^= first;
192*4882a593Smuzhiyun v3 ^= second;
193*4882a593Smuzhiyun SIPROUND;
194*4882a593Smuzhiyun SIPROUND;
195*4882a593Smuzhiyun v0 ^= second;
196*4882a593Smuzhiyun v3 ^= third;
197*4882a593Smuzhiyun SIPROUND;
198*4882a593Smuzhiyun SIPROUND;
199*4882a593Smuzhiyun v0 ^= third;
200*4882a593Smuzhiyun v3 ^= forth;
201*4882a593Smuzhiyun SIPROUND;
202*4882a593Smuzhiyun SIPROUND;
203*4882a593Smuzhiyun v0 ^= forth;
204*4882a593Smuzhiyun POSTAMBLE
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun EXPORT_SYMBOL(siphash_4u64);
207*4882a593Smuzhiyun
siphash_1u32(const u32 first,const siphash_key_t * key)208*4882a593Smuzhiyun u64 siphash_1u32(const u32 first, const siphash_key_t *key)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun PREAMBLE(4)
211*4882a593Smuzhiyun b |= first;
212*4882a593Smuzhiyun POSTAMBLE
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun EXPORT_SYMBOL(siphash_1u32);
215*4882a593Smuzhiyun
siphash_3u32(const u32 first,const u32 second,const u32 third,const siphash_key_t * key)216*4882a593Smuzhiyun u64 siphash_3u32(const u32 first, const u32 second, const u32 third,
217*4882a593Smuzhiyun const siphash_key_t *key)
218*4882a593Smuzhiyun {
219*4882a593Smuzhiyun u64 combined = (u64)second << 32 | first;
220*4882a593Smuzhiyun PREAMBLE(12)
221*4882a593Smuzhiyun v3 ^= combined;
222*4882a593Smuzhiyun SIPROUND;
223*4882a593Smuzhiyun SIPROUND;
224*4882a593Smuzhiyun v0 ^= combined;
225*4882a593Smuzhiyun b |= third;
226*4882a593Smuzhiyun POSTAMBLE
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun EXPORT_SYMBOL(siphash_3u32);
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun #if BITS_PER_LONG == 64
231*4882a593Smuzhiyun /* Note that on 64-bit, we make HalfSipHash1-3 actually be SipHash1-3, for
232*4882a593Smuzhiyun * performance reasons. On 32-bit, below, we actually implement HalfSipHash1-3.
233*4882a593Smuzhiyun */
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun #define HSIPROUND SIPROUND
236*4882a593Smuzhiyun #define HPREAMBLE(len) PREAMBLE(len)
237*4882a593Smuzhiyun #define HPOSTAMBLE \
238*4882a593Smuzhiyun v3 ^= b; \
239*4882a593Smuzhiyun HSIPROUND; \
240*4882a593Smuzhiyun v0 ^= b; \
241*4882a593Smuzhiyun v2 ^= 0xff; \
242*4882a593Smuzhiyun HSIPROUND; \
243*4882a593Smuzhiyun HSIPROUND; \
244*4882a593Smuzhiyun HSIPROUND; \
245*4882a593Smuzhiyun return (v0 ^ v1) ^ (v2 ^ v3);
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
__hsiphash_aligned(const void * data,size_t len,const hsiphash_key_t * key)248*4882a593Smuzhiyun u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun const u8 *end = data + len - (len % sizeof(u64));
251*4882a593Smuzhiyun const u8 left = len & (sizeof(u64) - 1);
252*4882a593Smuzhiyun u64 m;
253*4882a593Smuzhiyun HPREAMBLE(len)
254*4882a593Smuzhiyun for (; data != end; data += sizeof(u64)) {
255*4882a593Smuzhiyun m = le64_to_cpup(data);
256*4882a593Smuzhiyun v3 ^= m;
257*4882a593Smuzhiyun HSIPROUND;
258*4882a593Smuzhiyun v0 ^= m;
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
261*4882a593Smuzhiyun if (left)
262*4882a593Smuzhiyun b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) &
263*4882a593Smuzhiyun bytemask_from_count(left)));
264*4882a593Smuzhiyun #else
265*4882a593Smuzhiyun switch (left) {
266*4882a593Smuzhiyun case 7: b |= ((u64)end[6]) << 48; /* fall through */
267*4882a593Smuzhiyun case 6: b |= ((u64)end[5]) << 40; /* fall through */
268*4882a593Smuzhiyun case 5: b |= ((u64)end[4]) << 32; /* fall through */
269*4882a593Smuzhiyun case 4: b |= le32_to_cpup(data); break;
270*4882a593Smuzhiyun case 3: b |= ((u64)end[2]) << 16; /* fall through */
271*4882a593Smuzhiyun case 2: b |= le16_to_cpup(data); break;
272*4882a593Smuzhiyun case 1: b |= end[0];
273*4882a593Smuzhiyun }
274*4882a593Smuzhiyun #endif
275*4882a593Smuzhiyun HPOSTAMBLE
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun EXPORT_SYMBOL(__hsiphash_aligned);
278*4882a593Smuzhiyun #endif
279*4882a593Smuzhiyun
__hsiphash_unaligned(const void * data,size_t len,const hsiphash_key_t * key)280*4882a593Smuzhiyun u32 __hsiphash_unaligned(const void *data, size_t len,
281*4882a593Smuzhiyun const hsiphash_key_t *key)
282*4882a593Smuzhiyun {
283*4882a593Smuzhiyun const u8 *end = data + len - (len % sizeof(u64));
284*4882a593Smuzhiyun const u8 left = len & (sizeof(u64) - 1);
285*4882a593Smuzhiyun u64 m;
286*4882a593Smuzhiyun HPREAMBLE(len)
287*4882a593Smuzhiyun for (; data != end; data += sizeof(u64)) {
288*4882a593Smuzhiyun m = get_unaligned_le64(data);
289*4882a593Smuzhiyun v3 ^= m;
290*4882a593Smuzhiyun HSIPROUND;
291*4882a593Smuzhiyun v0 ^= m;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
294*4882a593Smuzhiyun if (left)
295*4882a593Smuzhiyun b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) &
296*4882a593Smuzhiyun bytemask_from_count(left)));
297*4882a593Smuzhiyun #else
298*4882a593Smuzhiyun switch (left) {
299*4882a593Smuzhiyun case 7: b |= ((u64)end[6]) << 48; /* fall through */
300*4882a593Smuzhiyun case 6: b |= ((u64)end[5]) << 40; /* fall through */
301*4882a593Smuzhiyun case 5: b |= ((u64)end[4]) << 32; /* fall through */
302*4882a593Smuzhiyun case 4: b |= get_unaligned_le32(end); break;
303*4882a593Smuzhiyun case 3: b |= ((u64)end[2]) << 16; /* fall through */
304*4882a593Smuzhiyun case 2: b |= get_unaligned_le16(end); break;
305*4882a593Smuzhiyun case 1: b |= end[0];
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun #endif
308*4882a593Smuzhiyun HPOSTAMBLE
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun EXPORT_SYMBOL(__hsiphash_unaligned);
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun /**
313*4882a593Smuzhiyun * hsiphash_1u32 - compute 64-bit hsiphash PRF value of a u32
314*4882a593Smuzhiyun * @first: first u32
315*4882a593Smuzhiyun * @key: the hsiphash key
316*4882a593Smuzhiyun */
hsiphash_1u32(const u32 first,const hsiphash_key_t * key)317*4882a593Smuzhiyun u32 hsiphash_1u32(const u32 first, const hsiphash_key_t *key)
318*4882a593Smuzhiyun {
319*4882a593Smuzhiyun HPREAMBLE(4)
320*4882a593Smuzhiyun b |= first;
321*4882a593Smuzhiyun HPOSTAMBLE
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun EXPORT_SYMBOL(hsiphash_1u32);
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun /**
326*4882a593Smuzhiyun * hsiphash_2u32 - compute 32-bit hsiphash PRF value of 2 u32
327*4882a593Smuzhiyun * @first: first u32
328*4882a593Smuzhiyun * @second: second u32
329*4882a593Smuzhiyun * @key: the hsiphash key
330*4882a593Smuzhiyun */
hsiphash_2u32(const u32 first,const u32 second,const hsiphash_key_t * key)331*4882a593Smuzhiyun u32 hsiphash_2u32(const u32 first, const u32 second, const hsiphash_key_t *key)
332*4882a593Smuzhiyun {
333*4882a593Smuzhiyun u64 combined = (u64)second << 32 | first;
334*4882a593Smuzhiyun HPREAMBLE(8)
335*4882a593Smuzhiyun v3 ^= combined;
336*4882a593Smuzhiyun HSIPROUND;
337*4882a593Smuzhiyun v0 ^= combined;
338*4882a593Smuzhiyun HPOSTAMBLE
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun EXPORT_SYMBOL(hsiphash_2u32);
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun /**
343*4882a593Smuzhiyun * hsiphash_3u32 - compute 32-bit hsiphash PRF value of 3 u32
344*4882a593Smuzhiyun * @first: first u32
345*4882a593Smuzhiyun * @second: second u32
346*4882a593Smuzhiyun * @third: third u32
347*4882a593Smuzhiyun * @key: the hsiphash key
348*4882a593Smuzhiyun */
hsiphash_3u32(const u32 first,const u32 second,const u32 third,const hsiphash_key_t * key)349*4882a593Smuzhiyun u32 hsiphash_3u32(const u32 first, const u32 second, const u32 third,
350*4882a593Smuzhiyun const hsiphash_key_t *key)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun u64 combined = (u64)second << 32 | first;
353*4882a593Smuzhiyun HPREAMBLE(12)
354*4882a593Smuzhiyun v3 ^= combined;
355*4882a593Smuzhiyun HSIPROUND;
356*4882a593Smuzhiyun v0 ^= combined;
357*4882a593Smuzhiyun b |= third;
358*4882a593Smuzhiyun HPOSTAMBLE
359*4882a593Smuzhiyun }
360*4882a593Smuzhiyun EXPORT_SYMBOL(hsiphash_3u32);
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun /**
363*4882a593Smuzhiyun * hsiphash_4u32 - compute 32-bit hsiphash PRF value of 4 u32
364*4882a593Smuzhiyun * @first: first u32
365*4882a593Smuzhiyun * @second: second u32
366*4882a593Smuzhiyun * @third: third u32
367*4882a593Smuzhiyun * @forth: forth u32
368*4882a593Smuzhiyun * @key: the hsiphash key
369*4882a593Smuzhiyun */
hsiphash_4u32(const u32 first,const u32 second,const u32 third,const u32 forth,const hsiphash_key_t * key)370*4882a593Smuzhiyun u32 hsiphash_4u32(const u32 first, const u32 second, const u32 third,
371*4882a593Smuzhiyun const u32 forth, const hsiphash_key_t *key)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun u64 combined = (u64)second << 32 | first;
374*4882a593Smuzhiyun HPREAMBLE(16)
375*4882a593Smuzhiyun v3 ^= combined;
376*4882a593Smuzhiyun HSIPROUND;
377*4882a593Smuzhiyun v0 ^= combined;
378*4882a593Smuzhiyun combined = (u64)forth << 32 | third;
379*4882a593Smuzhiyun v3 ^= combined;
380*4882a593Smuzhiyun HSIPROUND;
381*4882a593Smuzhiyun v0 ^= combined;
382*4882a593Smuzhiyun HPOSTAMBLE
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun EXPORT_SYMBOL(hsiphash_4u32);
385*4882a593Smuzhiyun #else
386*4882a593Smuzhiyun #define HSIPROUND HSIPHASH_PERMUTATION(v0, v1, v2, v3)
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun #define HPREAMBLE(len) \
389*4882a593Smuzhiyun u32 v0 = HSIPHASH_CONST_0; \
390*4882a593Smuzhiyun u32 v1 = HSIPHASH_CONST_1; \
391*4882a593Smuzhiyun u32 v2 = HSIPHASH_CONST_2; \
392*4882a593Smuzhiyun u32 v3 = HSIPHASH_CONST_3; \
393*4882a593Smuzhiyun u32 b = ((u32)(len)) << 24; \
394*4882a593Smuzhiyun v3 ^= key->key[1]; \
395*4882a593Smuzhiyun v2 ^= key->key[0]; \
396*4882a593Smuzhiyun v1 ^= key->key[1]; \
397*4882a593Smuzhiyun v0 ^= key->key[0];
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun #define HPOSTAMBLE \
400*4882a593Smuzhiyun v3 ^= b; \
401*4882a593Smuzhiyun HSIPROUND; \
402*4882a593Smuzhiyun v0 ^= b; \
403*4882a593Smuzhiyun v2 ^= 0xff; \
404*4882a593Smuzhiyun HSIPROUND; \
405*4882a593Smuzhiyun HSIPROUND; \
406*4882a593Smuzhiyun HSIPROUND; \
407*4882a593Smuzhiyun return v1 ^ v3;
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
__hsiphash_aligned(const void * data,size_t len,const hsiphash_key_t * key)410*4882a593Smuzhiyun u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key)
411*4882a593Smuzhiyun {
412*4882a593Smuzhiyun const u8 *end = data + len - (len % sizeof(u32));
413*4882a593Smuzhiyun const u8 left = len & (sizeof(u32) - 1);
414*4882a593Smuzhiyun u32 m;
415*4882a593Smuzhiyun HPREAMBLE(len)
416*4882a593Smuzhiyun for (; data != end; data += sizeof(u32)) {
417*4882a593Smuzhiyun m = le32_to_cpup(data);
418*4882a593Smuzhiyun v3 ^= m;
419*4882a593Smuzhiyun HSIPROUND;
420*4882a593Smuzhiyun v0 ^= m;
421*4882a593Smuzhiyun }
422*4882a593Smuzhiyun switch (left) {
423*4882a593Smuzhiyun case 3: b |= ((u32)end[2]) << 16; /* fall through */
424*4882a593Smuzhiyun case 2: b |= le16_to_cpup(data); break;
425*4882a593Smuzhiyun case 1: b |= end[0];
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun HPOSTAMBLE
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun EXPORT_SYMBOL(__hsiphash_aligned);
430*4882a593Smuzhiyun #endif
431*4882a593Smuzhiyun
__hsiphash_unaligned(const void * data,size_t len,const hsiphash_key_t * key)432*4882a593Smuzhiyun u32 __hsiphash_unaligned(const void *data, size_t len,
433*4882a593Smuzhiyun const hsiphash_key_t *key)
434*4882a593Smuzhiyun {
435*4882a593Smuzhiyun const u8 *end = data + len - (len % sizeof(u32));
436*4882a593Smuzhiyun const u8 left = len & (sizeof(u32) - 1);
437*4882a593Smuzhiyun u32 m;
438*4882a593Smuzhiyun HPREAMBLE(len)
439*4882a593Smuzhiyun for (; data != end; data += sizeof(u32)) {
440*4882a593Smuzhiyun m = get_unaligned_le32(data);
441*4882a593Smuzhiyun v3 ^= m;
442*4882a593Smuzhiyun HSIPROUND;
443*4882a593Smuzhiyun v0 ^= m;
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun switch (left) {
446*4882a593Smuzhiyun case 3: b |= ((u32)end[2]) << 16; /* fall through */
447*4882a593Smuzhiyun case 2: b |= get_unaligned_le16(end); break;
448*4882a593Smuzhiyun case 1: b |= end[0];
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun HPOSTAMBLE
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun EXPORT_SYMBOL(__hsiphash_unaligned);
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun /**
455*4882a593Smuzhiyun * hsiphash_1u32 - compute 32-bit hsiphash PRF value of a u32
456*4882a593Smuzhiyun * @first: first u32
457*4882a593Smuzhiyun * @key: the hsiphash key
458*4882a593Smuzhiyun */
hsiphash_1u32(const u32 first,const hsiphash_key_t * key)459*4882a593Smuzhiyun u32 hsiphash_1u32(const u32 first, const hsiphash_key_t *key)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun HPREAMBLE(4)
462*4882a593Smuzhiyun v3 ^= first;
463*4882a593Smuzhiyun HSIPROUND;
464*4882a593Smuzhiyun v0 ^= first;
465*4882a593Smuzhiyun HPOSTAMBLE
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun EXPORT_SYMBOL(hsiphash_1u32);
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun /**
470*4882a593Smuzhiyun * hsiphash_2u32 - compute 32-bit hsiphash PRF value of 2 u32
471*4882a593Smuzhiyun * @first: first u32
472*4882a593Smuzhiyun * @second: second u32
473*4882a593Smuzhiyun * @key: the hsiphash key
474*4882a593Smuzhiyun */
hsiphash_2u32(const u32 first,const u32 second,const hsiphash_key_t * key)475*4882a593Smuzhiyun u32 hsiphash_2u32(const u32 first, const u32 second, const hsiphash_key_t *key)
476*4882a593Smuzhiyun {
477*4882a593Smuzhiyun HPREAMBLE(8)
478*4882a593Smuzhiyun v3 ^= first;
479*4882a593Smuzhiyun HSIPROUND;
480*4882a593Smuzhiyun v0 ^= first;
481*4882a593Smuzhiyun v3 ^= second;
482*4882a593Smuzhiyun HSIPROUND;
483*4882a593Smuzhiyun v0 ^= second;
484*4882a593Smuzhiyun HPOSTAMBLE
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun EXPORT_SYMBOL(hsiphash_2u32);
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun /**
489*4882a593Smuzhiyun * hsiphash_3u32 - compute 32-bit hsiphash PRF value of 3 u32
490*4882a593Smuzhiyun * @first: first u32
491*4882a593Smuzhiyun * @second: second u32
492*4882a593Smuzhiyun * @third: third u32
493*4882a593Smuzhiyun * @key: the hsiphash key
494*4882a593Smuzhiyun */
hsiphash_3u32(const u32 first,const u32 second,const u32 third,const hsiphash_key_t * key)495*4882a593Smuzhiyun u32 hsiphash_3u32(const u32 first, const u32 second, const u32 third,
496*4882a593Smuzhiyun const hsiphash_key_t *key)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun HPREAMBLE(12)
499*4882a593Smuzhiyun v3 ^= first;
500*4882a593Smuzhiyun HSIPROUND;
501*4882a593Smuzhiyun v0 ^= first;
502*4882a593Smuzhiyun v3 ^= second;
503*4882a593Smuzhiyun HSIPROUND;
504*4882a593Smuzhiyun v0 ^= second;
505*4882a593Smuzhiyun v3 ^= third;
506*4882a593Smuzhiyun HSIPROUND;
507*4882a593Smuzhiyun v0 ^= third;
508*4882a593Smuzhiyun HPOSTAMBLE
509*4882a593Smuzhiyun }
510*4882a593Smuzhiyun EXPORT_SYMBOL(hsiphash_3u32);
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun /**
513*4882a593Smuzhiyun * hsiphash_4u32 - compute 32-bit hsiphash PRF value of 4 u32
514*4882a593Smuzhiyun * @first: first u32
515*4882a593Smuzhiyun * @second: second u32
516*4882a593Smuzhiyun * @third: third u32
517*4882a593Smuzhiyun * @forth: forth u32
518*4882a593Smuzhiyun * @key: the hsiphash key
519*4882a593Smuzhiyun */
hsiphash_4u32(const u32 first,const u32 second,const u32 third,const u32 forth,const hsiphash_key_t * key)520*4882a593Smuzhiyun u32 hsiphash_4u32(const u32 first, const u32 second, const u32 third,
521*4882a593Smuzhiyun const u32 forth, const hsiphash_key_t *key)
522*4882a593Smuzhiyun {
523*4882a593Smuzhiyun HPREAMBLE(16)
524*4882a593Smuzhiyun v3 ^= first;
525*4882a593Smuzhiyun HSIPROUND;
526*4882a593Smuzhiyun v0 ^= first;
527*4882a593Smuzhiyun v3 ^= second;
528*4882a593Smuzhiyun HSIPROUND;
529*4882a593Smuzhiyun v0 ^= second;
530*4882a593Smuzhiyun v3 ^= third;
531*4882a593Smuzhiyun HSIPROUND;
532*4882a593Smuzhiyun v0 ^= third;
533*4882a593Smuzhiyun v3 ^= forth;
534*4882a593Smuzhiyun HSIPROUND;
535*4882a593Smuzhiyun v0 ^= forth;
536*4882a593Smuzhiyun HPOSTAMBLE
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun EXPORT_SYMBOL(hsiphash_4u32);
539*4882a593Smuzhiyun #endif
540