]>
git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blob - lib/siphash.c
1 /* Copyright (C) 2016 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
3 * This file is provided under a dual BSD/GPLv2 license.
5 * SipHash: a fast short-input PRF
6 * https://131002.net/siphash/
8 * This implementation is specifically for SipHash2-4 for a secure PRF
9 * and HalfSipHash1-3/SipHash1-3 for an insecure PRF only suitable for
13 #include <linux/siphash.h>
14 #include <asm/unaligned.h>
16 #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
17 #include <linux/dcache.h>
18 #include <asm/word-at-a-time.h>
21 #define SIPROUND SIPHASH_PERMUTATION(v0, v1, v2, v3)
23 #define PREAMBLE(len) \
24 u64 v0 = SIPHASH_CONST_0; \
25 u64 v1 = SIPHASH_CONST_1; \
26 u64 v2 = SIPHASH_CONST_2; \
27 u64 v3 = SIPHASH_CONST_3; \
28 u64 b = ((u64)(len)) << 56; \
44 return (v0 ^ v1) ^ (v2 ^ v3);
46 #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
47 u64
__siphash_aligned(const void *data
, size_t len
, const siphash_key_t
*key
)
49 const u8
*end
= data
+ len
- (len
% sizeof(u64
));
50 const u8 left
= len
& (sizeof(u64
) - 1);
53 for (; data
!= end
; data
+= sizeof(u64
)) {
54 m
= le64_to_cpup(data
);
60 #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
62 b
|= le64_to_cpu((__force __le64
)(load_unaligned_zeropad(data
) &
63 bytemask_from_count(left
)));
66 case 7: b
|= ((u64
)end
[6]) << 48; fallthrough
;
67 case 6: b
|= ((u64
)end
[5]) << 40; fallthrough
;
68 case 5: b
|= ((u64
)end
[4]) << 32; fallthrough
;
69 case 4: b
|= le32_to_cpup(data
); break;
70 case 3: b
|= ((u64
)end
[2]) << 16; fallthrough
;
71 case 2: b
|= le16_to_cpup(data
); break;
77 EXPORT_SYMBOL(__siphash_aligned
);
80 u64
__siphash_unaligned(const void *data
, size_t len
, const siphash_key_t
*key
)
82 const u8
*end
= data
+ len
- (len
% sizeof(u64
));
83 const u8 left
= len
& (sizeof(u64
) - 1);
86 for (; data
!= end
; data
+= sizeof(u64
)) {
87 m
= get_unaligned_le64(data
);
93 #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
95 b
|= le64_to_cpu((__force __le64
)(load_unaligned_zeropad(data
) &
96 bytemask_from_count(left
)));
99 case 7: b
|= ((u64
)end
[6]) << 48; fallthrough
;
100 case 6: b
|= ((u64
)end
[5]) << 40; fallthrough
;
101 case 5: b
|= ((u64
)end
[4]) << 32; fallthrough
;
102 case 4: b
|= get_unaligned_le32(end
); break;
103 case 3: b
|= ((u64
)end
[2]) << 16; fallthrough
;
104 case 2: b
|= get_unaligned_le16(end
); break;
110 EXPORT_SYMBOL(__siphash_unaligned
);
113 * siphash_1u64 - compute 64-bit siphash PRF value of a u64
115 * @key: the siphash key
117 u64
siphash_1u64(const u64 first
, const siphash_key_t
*key
)
126 EXPORT_SYMBOL(siphash_1u64
);
129 * siphash_2u64 - compute 64-bit siphash PRF value of 2 u64
131 * @second: second u64
132 * @key: the siphash key
134 u64
siphash_2u64(const u64 first
, const u64 second
, const siphash_key_t
*key
)
147 EXPORT_SYMBOL(siphash_2u64
);
150 * siphash_3u64 - compute 64-bit siphash PRF value of 3 u64
152 * @second: second u64
154 * @key: the siphash key
156 u64
siphash_3u64(const u64 first
, const u64 second
, const u64 third
,
157 const siphash_key_t
*key
)
174 EXPORT_SYMBOL(siphash_3u64
);
177 * siphash_4u64 - compute 64-bit siphash PRF value of 4 u64
179 * @second: second u64
182 * @key: the siphash key
184 u64
siphash_4u64(const u64 first
, const u64 second
, const u64 third
,
185 const u64 forth
, const siphash_key_t
*key
)
206 EXPORT_SYMBOL(siphash_4u64
);
208 u64
siphash_1u32(const u32 first
, const siphash_key_t
*key
)
214 EXPORT_SYMBOL(siphash_1u32
);
216 u64
siphash_3u32(const u32 first
, const u32 second
, const u32 third
,
217 const siphash_key_t
*key
)
219 u64 combined
= (u64
)second
<< 32 | first
;
228 EXPORT_SYMBOL(siphash_3u32
);
230 #if BITS_PER_LONG == 64
231 /* Note that on 64-bit, we make HalfSipHash1-3 actually be SipHash1-3, for
232 * performance reasons. On 32-bit, below, we actually implement HalfSipHash1-3.
235 #define HSIPROUND SIPROUND
236 #define HPREAMBLE(len) PREAMBLE(len)
245 return (v0 ^ v1) ^ (v2 ^ v3);
247 #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
248 u32
__hsiphash_aligned(const void *data
, size_t len
, const hsiphash_key_t
*key
)
250 const u8
*end
= data
+ len
- (len
% sizeof(u64
));
251 const u8 left
= len
& (sizeof(u64
) - 1);
254 for (; data
!= end
; data
+= sizeof(u64
)) {
255 m
= le64_to_cpup(data
);
260 #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
262 b
|= le64_to_cpu((__force __le64
)(load_unaligned_zeropad(data
) &
263 bytemask_from_count(left
)));
266 case 7: b
|= ((u64
)end
[6]) << 48; fallthrough
;
267 case 6: b
|= ((u64
)end
[5]) << 40; fallthrough
;
268 case 5: b
|= ((u64
)end
[4]) << 32; fallthrough
;
269 case 4: b
|= le32_to_cpup(data
); break;
270 case 3: b
|= ((u64
)end
[2]) << 16; fallthrough
;
271 case 2: b
|= le16_to_cpup(data
); break;
277 EXPORT_SYMBOL(__hsiphash_aligned
);
280 u32
__hsiphash_unaligned(const void *data
, size_t len
,
281 const hsiphash_key_t
*key
)
283 const u8
*end
= data
+ len
- (len
% sizeof(u64
));
284 const u8 left
= len
& (sizeof(u64
) - 1);
287 for (; data
!= end
; data
+= sizeof(u64
)) {
288 m
= get_unaligned_le64(data
);
293 #if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
295 b
|= le64_to_cpu((__force __le64
)(load_unaligned_zeropad(data
) &
296 bytemask_from_count(left
)));
299 case 7: b
|= ((u64
)end
[6]) << 48; fallthrough
;
300 case 6: b
|= ((u64
)end
[5]) << 40; fallthrough
;
301 case 5: b
|= ((u64
)end
[4]) << 32; fallthrough
;
302 case 4: b
|= get_unaligned_le32(end
); break;
303 case 3: b
|= ((u64
)end
[2]) << 16; fallthrough
;
304 case 2: b
|= get_unaligned_le16(end
); break;
310 EXPORT_SYMBOL(__hsiphash_unaligned
);
313 * hsiphash_1u32 - compute 64-bit hsiphash PRF value of a u32
315 * @key: the hsiphash key
317 u32
hsiphash_1u32(const u32 first
, const hsiphash_key_t
*key
)
323 EXPORT_SYMBOL(hsiphash_1u32
);
326 * hsiphash_2u32 - compute 32-bit hsiphash PRF value of 2 u32
328 * @second: second u32
329 * @key: the hsiphash key
331 u32
hsiphash_2u32(const u32 first
, const u32 second
, const hsiphash_key_t
*key
)
333 u64 combined
= (u64
)second
<< 32 | first
;
340 EXPORT_SYMBOL(hsiphash_2u32
);
343 * hsiphash_3u32 - compute 32-bit hsiphash PRF value of 3 u32
345 * @second: second u32
347 * @key: the hsiphash key
349 u32
hsiphash_3u32(const u32 first
, const u32 second
, const u32 third
,
350 const hsiphash_key_t
*key
)
352 u64 combined
= (u64
)second
<< 32 | first
;
360 EXPORT_SYMBOL(hsiphash_3u32
);
363 * hsiphash_4u32 - compute 32-bit hsiphash PRF value of 4 u32
365 * @second: second u32
368 * @key: the hsiphash key
370 u32
hsiphash_4u32(const u32 first
, const u32 second
, const u32 third
,
371 const u32 forth
, const hsiphash_key_t
*key
)
373 u64 combined
= (u64
)second
<< 32 | first
;
378 combined
= (u64
)forth
<< 32 | third
;
384 EXPORT_SYMBOL(hsiphash_4u32
);
386 #define HSIPROUND HSIPHASH_PERMUTATION(v0, v1, v2, v3)
388 #define HPREAMBLE(len) \
389 u32 v0 = HSIPHASH_CONST_0; \
390 u32 v1 = HSIPHASH_CONST_1; \
391 u32 v2 = HSIPHASH_CONST_2; \
392 u32 v3 = HSIPHASH_CONST_3; \
393 u32 b = ((u32)(len)) << 24; \
409 #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
410 u32
__hsiphash_aligned(const void *data
, size_t len
, const hsiphash_key_t
*key
)
412 const u8
*end
= data
+ len
- (len
% sizeof(u32
));
413 const u8 left
= len
& (sizeof(u32
) - 1);
416 for (; data
!= end
; data
+= sizeof(u32
)) {
417 m
= le32_to_cpup(data
);
423 case 3: b
|= ((u32
)end
[2]) << 16; fallthrough
;
424 case 2: b
|= le16_to_cpup(data
); break;
429 EXPORT_SYMBOL(__hsiphash_aligned
);
432 u32
__hsiphash_unaligned(const void *data
, size_t len
,
433 const hsiphash_key_t
*key
)
435 const u8
*end
= data
+ len
- (len
% sizeof(u32
));
436 const u8 left
= len
& (sizeof(u32
) - 1);
439 for (; data
!= end
; data
+= sizeof(u32
)) {
440 m
= get_unaligned_le32(data
);
446 case 3: b
|= ((u32
)end
[2]) << 16; fallthrough
;
447 case 2: b
|= get_unaligned_le16(end
); break;
452 EXPORT_SYMBOL(__hsiphash_unaligned
);
455 * hsiphash_1u32 - compute 32-bit hsiphash PRF value of a u32
457 * @key: the hsiphash key
459 u32
hsiphash_1u32(const u32 first
, const hsiphash_key_t
*key
)
467 EXPORT_SYMBOL(hsiphash_1u32
);
470 * hsiphash_2u32 - compute 32-bit hsiphash PRF value of 2 u32
472 * @second: second u32
473 * @key: the hsiphash key
475 u32
hsiphash_2u32(const u32 first
, const u32 second
, const hsiphash_key_t
*key
)
486 EXPORT_SYMBOL(hsiphash_2u32
);
489 * hsiphash_3u32 - compute 32-bit hsiphash PRF value of 3 u32
491 * @second: second u32
493 * @key: the hsiphash key
495 u32
hsiphash_3u32(const u32 first
, const u32 second
, const u32 third
,
496 const hsiphash_key_t
*key
)
510 EXPORT_SYMBOL(hsiphash_3u32
);
513 * hsiphash_4u32 - compute 32-bit hsiphash PRF value of 4 u32
515 * @second: second u32
518 * @key: the hsiphash key
520 u32
hsiphash_4u32(const u32 first
, const u32 second
, const u32 third
,
521 const u32 forth
, const hsiphash_key_t
*key
)
538 EXPORT_SYMBOL(hsiphash_4u32
);