summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2017-01-08 07:54:01 -0500
committerDavid S. Miller <davem@davemloft.net>2017-01-09 13:58:57 -0500
commit1ae2324f732c9c4e2fa4ebd885fa1001b70d52e1 (patch)
tree9d63a575a90f854e8a338cf46e35ecc96d7f6794
parent2c956a60778cbb6a27e0c7a8a52a91378c90e1d1 (diff)
siphash: implement HalfSipHash1-3 for hash tables
HalfSipHash, or hsiphash, is a shortened version of SipHash, which generates 32-bit outputs using a weaker 64-bit key. It has *much* lower security margins, and shouldn't be used for anything too sensitive, but it could be used as a hashtable key function replacement, if the output is never exposed, and if the security requirement is not too high. The goal is to make this something that performance-critical jhash users would be willing to use. On 64-bit machines, HalfSipHash1-3 is slower than SipHash1-3, so we alias SipHash1-3 to HalfSipHash1-3 on those systems. 64-bit x86_64: [ 0.509409] test_siphash: SipHash2-4 cycles: 4049181 [ 0.510650] test_siphash: SipHash1-3 cycles: 2512884 [ 0.512205] test_siphash: HalfSipHash1-3 cycles: 3429920 [ 0.512904] test_siphash: JenkinsHash cycles: 978267 So, we map hsiphash() -> SipHash1-3 32-bit x86: [ 0.509868] test_siphash: SipHash2-4 cycles: 14812892 [ 0.513601] test_siphash: SipHash1-3 cycles: 9510710 [ 0.515263] test_siphash: HalfSipHash1-3 cycles: 3856157 [ 0.515952] test_siphash: JenkinsHash cycles: 1148567 So, we map hsiphash() -> HalfSipHash1-3 hsiphash() is roughly 3 times slower than jhash(), but comes with a considerable security improvement. Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Reviewed-by: Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--Documentation/siphash.txt75
-rw-r--r--include/linux/siphash.h57
-rw-r--r--lib/siphash.c321
-rw-r--r--lib/test_siphash.c98
4 files changed, 546 insertions, 5 deletions
diff --git a/Documentation/siphash.txt b/Documentation/siphash.txt
index e8e6ddbbaab4..908d348ff777 100644
--- a/Documentation/siphash.txt
+++ b/Documentation/siphash.txt
@@ -98,3 +98,78 @@ u64 h = siphash(&combined, offsetofend(typeof(combined), dport), &secret);
98 98
99Read the SipHash paper if you're interested in learning more: 99Read the SipHash paper if you're interested in learning more:
100https://131002.net/siphash/siphash.pdf 100https://131002.net/siphash/siphash.pdf
101
102
103~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
104
105HalfSipHash - SipHash's insecure younger cousin
106-----------------------------------------------
107Written by Jason A. Donenfeld <jason@zx2c4.com>
108
109On the off-chance that SipHash is not fast enough for your needs, you might be
110able to justify using HalfSipHash, a terrifying but potentially useful
111possibility. HalfSipHash cuts SipHash's rounds down from "2-4" to "1-3" and,
112even scarier, uses an easily brute-forcable 64-bit key (with a 32-bit output)
113instead of SipHash's 128-bit key. However, this may appeal to some
114high-performance `jhash` users.
115
116Danger!
117
118Do not ever use HalfSipHash except for as a hashtable key function, and only
119then when you can be absolutely certain that the outputs will never be
120transmitted out of the kernel. This is only remotely useful over `jhash` as a
121means of mitigating hashtable flooding denial of service attacks.
122
1231. Generating a key
124
125Keys should always be generated from a cryptographically secure source of
126random numbers, either using get_random_bytes or get_random_once:
127
128hsiphash_key_t key;
129get_random_bytes(&key, sizeof(key));
130
131If you're not deriving your key from here, you're doing it wrong.
132
1332. Using the functions
134
135There are two variants of the function, one that takes a list of integers, and
136one that takes a buffer:
137
138u32 hsiphash(const void *data, size_t len, const hsiphash_key_t *key);
139
140And:
141
142u32 hsiphash_1u32(u32, const hsiphash_key_t *key);
143u32 hsiphash_2u32(u32, u32, const hsiphash_key_t *key);
144u32 hsiphash_3u32(u32, u32, u32, const hsiphash_key_t *key);
145u32 hsiphash_4u32(u32, u32, u32, u32, const hsiphash_key_t *key);
146
147If you pass the generic hsiphash function something of a constant length, it
148will constant fold at compile-time and automatically choose one of the
149optimized functions.
150
1513. Hashtable key function usage:
152
153struct some_hashtable {
154 DECLARE_HASHTABLE(hashtable, 8);
155 hsiphash_key_t key;
156};
157
158void init_hashtable(struct some_hashtable *table)
159{
160 get_random_bytes(&table->key, sizeof(table->key));
161}
162
163static inline hlist_head *some_hashtable_bucket(struct some_hashtable *table, struct interesting_input *input)
164{
165 return &table->hashtable[hsiphash(input, sizeof(*input), &table->key) & (HASH_SIZE(table->hashtable) - 1)];
166}
167
168You may then iterate like usual over the returned hash bucket.
169
1704. Performance
171
172HalfSipHash is roughly 3 times slower than JenkinsHash. For many replacements,
173this will not be a problem, as the hashtable lookup isn't the bottleneck. And
174in general, this is probably a good sacrifice to make for the security and DoS
175resistance of HalfSipHash.
diff --git a/include/linux/siphash.h b/include/linux/siphash.h
index feeb29cd113e..fa7a6b9cedbf 100644
--- a/include/linux/siphash.h
+++ b/include/linux/siphash.h
@@ -5,7 +5,9 @@
5 * SipHash: a fast short-input PRF 5 * SipHash: a fast short-input PRF
6 * https://131002.net/siphash/ 6 * https://131002.net/siphash/
7 * 7 *
8 * This implementation is specifically for SipHash2-4. 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
10 * hashtables.
9 */ 11 */
10 12
11#ifndef _LINUX_SIPHASH_H 13#ifndef _LINUX_SIPHASH_H
@@ -82,4 +84,57 @@ static inline u64 siphash(const void *data, size_t len,
82 return ___siphash_aligned(data, len, key); 84 return ___siphash_aligned(data, len, key);
83} 85}
84 86
87#define HSIPHASH_ALIGNMENT __alignof__(unsigned long)
88typedef struct {
89 unsigned long key[2];
90} hsiphash_key_t;
91
92u32 __hsiphash_aligned(const void *data, size_t len,
93 const hsiphash_key_t *key);
94#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
95u32 __hsiphash_unaligned(const void *data, size_t len,
96 const hsiphash_key_t *key);
97#endif
98
99u32 hsiphash_1u32(const u32 a, const hsiphash_key_t *key);
100u32 hsiphash_2u32(const u32 a, const u32 b, const hsiphash_key_t *key);
101u32 hsiphash_3u32(const u32 a, const u32 b, const u32 c,
102 const hsiphash_key_t *key);
103u32 hsiphash_4u32(const u32 a, const u32 b, const u32 c, const u32 d,
104 const hsiphash_key_t *key);
105
106static inline u32 ___hsiphash_aligned(const __le32 *data, size_t len,
107 const hsiphash_key_t *key)
108{
109 if (__builtin_constant_p(len) && len == 4)
110 return hsiphash_1u32(le32_to_cpu(data[0]), key);
111 if (__builtin_constant_p(len) && len == 8)
112 return hsiphash_2u32(le32_to_cpu(data[0]), le32_to_cpu(data[1]),
113 key);
114 if (__builtin_constant_p(len) && len == 12)
115 return hsiphash_3u32(le32_to_cpu(data[0]), le32_to_cpu(data[1]),
116 le32_to_cpu(data[2]), key);
117 if (__builtin_constant_p(len) && len == 16)
118 return hsiphash_4u32(le32_to_cpu(data[0]), le32_to_cpu(data[1]),
119 le32_to_cpu(data[2]), le32_to_cpu(data[3]),
120 key);
121 return __hsiphash_aligned(data, len, key);
122}
123
124/**
125 * hsiphash - compute 32-bit hsiphash PRF value
126 * @data: buffer to hash
127 * @size: size of @data
128 * @key: the hsiphash key
129 */
130static inline u32 hsiphash(const void *data, size_t len,
131 const hsiphash_key_t *key)
132{
133#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
134 if (!IS_ALIGNED((unsigned long)data, HSIPHASH_ALIGNMENT))
135 return __hsiphash_unaligned(data, len, key);
136#endif
137 return ___hsiphash_aligned(data, len, key);
138}
139
85#endif /* _LINUX_SIPHASH_H */ 140#endif /* _LINUX_SIPHASH_H */
diff --git a/lib/siphash.c b/lib/siphash.c
index c43cf406e71b..3ae58b4edad6 100644
--- a/lib/siphash.c
+++ b/lib/siphash.c
@@ -5,7 +5,9 @@
5 * SipHash: a fast short-input PRF 5 * SipHash: a fast short-input PRF
6 * https://131002.net/siphash/ 6 * https://131002.net/siphash/
7 * 7 *
8 * This implementation is specifically for SipHash2-4. 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
10 * hashtables.
9 */ 11 */
10 12
11#include <linux/siphash.h> 13#include <linux/siphash.h>
@@ -230,3 +232,320 @@ u64 siphash_3u32(const u32 first, const u32 second, const u32 third,
230 POSTAMBLE 232 POSTAMBLE
231} 233}
232EXPORT_SYMBOL(siphash_3u32); 234EXPORT_SYMBOL(siphash_3u32);
235
236#if BITS_PER_LONG == 64
237/* Note that on 64-bit, we make HalfSipHash1-3 actually be SipHash1-3, for
238 * performance reasons. On 32-bit, below, we actually implement HalfSipHash1-3.
239 */
240
241#define HSIPROUND SIPROUND
242#define HPREAMBLE(len) PREAMBLE(len)
243#define HPOSTAMBLE \
244 v3 ^= b; \
245 HSIPROUND; \
246 v0 ^= b; \
247 v2 ^= 0xff; \
248 HSIPROUND; \
249 HSIPROUND; \
250 HSIPROUND; \
251 return (v0 ^ v1) ^ (v2 ^ v3);
252
253u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key)
254{
255 const u8 *end = data + len - (len % sizeof(u64));
256 const u8 left = len & (sizeof(u64) - 1);
257 u64 m;
258 HPREAMBLE(len)
259 for (; data != end; data += sizeof(u64)) {
260 m = le64_to_cpup(data);
261 v3 ^= m;
262 HSIPROUND;
263 v0 ^= m;
264 }
265#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
266 if (left)
267 b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) &
268 bytemask_from_count(left)));
269#else
270 switch (left) {
271 case 7: b |= ((u64)end[6]) << 48;
272 case 6: b |= ((u64)end[5]) << 40;
273 case 5: b |= ((u64)end[4]) << 32;
274 case 4: b |= le32_to_cpup(data); break;
275 case 3: b |= ((u64)end[2]) << 16;
276 case 2: b |= le16_to_cpup(data); break;
277 case 1: b |= end[0];
278 }
279#endif
280 HPOSTAMBLE
281}
282EXPORT_SYMBOL(__hsiphash_aligned);
283
284#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
285u32 __hsiphash_unaligned(const void *data, size_t len,
286 const hsiphash_key_t *key)
287{
288 const u8 *end = data + len - (len % sizeof(u64));
289 const u8 left = len & (sizeof(u64) - 1);
290 u64 m;
291 HPREAMBLE(len)
292 for (; data != end; data += sizeof(u64)) {
293 m = get_unaligned_le64(data);
294 v3 ^= m;
295 HSIPROUND;
296 v0 ^= m;
297 }
298#if defined(CONFIG_DCACHE_WORD_ACCESS) && BITS_PER_LONG == 64
299 if (left)
300 b |= le64_to_cpu((__force __le64)(load_unaligned_zeropad(data) &
301 bytemask_from_count(left)));
302#else
303 switch (left) {
304 case 7: b |= ((u64)end[6]) << 48;
305 case 6: b |= ((u64)end[5]) << 40;
306 case 5: b |= ((u64)end[4]) << 32;
307 case 4: b |= get_unaligned_le32(end); break;
308 case 3: b |= ((u64)end[2]) << 16;
309 case 2: b |= get_unaligned_le16(end); break;
310 case 1: b |= end[0];
311 }
312#endif
313 HPOSTAMBLE
314}
315EXPORT_SYMBOL(__hsiphash_unaligned);
316#endif
317
318/**
319 * hsiphash_1u32 - compute 64-bit hsiphash PRF value of a u32
320 * @first: first u32
321 * @key: the hsiphash key
322 */
323u32 hsiphash_1u32(const u32 first, const hsiphash_key_t *key)
324{
325 HPREAMBLE(4)
326 b |= first;
327 HPOSTAMBLE
328}
329EXPORT_SYMBOL(hsiphash_1u32);
330
331/**
332 * hsiphash_2u32 - compute 32-bit hsiphash PRF value of 2 u32
333 * @first: first u32
334 * @second: second u32
335 * @key: the hsiphash key
336 */
337u32 hsiphash_2u32(const u32 first, const u32 second, const hsiphash_key_t *key)
338{
339 u64 combined = (u64)second << 32 | first;
340 HPREAMBLE(8)
341 v3 ^= combined;
342 HSIPROUND;
343 v0 ^= combined;
344 HPOSTAMBLE
345}
346EXPORT_SYMBOL(hsiphash_2u32);
347
348/**
349 * hsiphash_3u32 - compute 32-bit hsiphash PRF value of 3 u32
350 * @first: first u32
351 * @second: second u32
352 * @third: third u32
353 * @key: the hsiphash key
354 */
355u32 hsiphash_3u32(const u32 first, const u32 second, const u32 third,
356 const hsiphash_key_t *key)
357{
358 u64 combined = (u64)second << 32 | first;
359 HPREAMBLE(12)
360 v3 ^= combined;
361 HSIPROUND;
362 v0 ^= combined;
363 b |= third;
364 HPOSTAMBLE
365}
366EXPORT_SYMBOL(hsiphash_3u32);
367
368/**
369 * hsiphash_4u32 - compute 32-bit hsiphash PRF value of 4 u32
370 * @first: first u32
371 * @second: second u32
372 * @third: third u32
373 * @forth: forth u32
374 * @key: the hsiphash key
375 */
376u32 hsiphash_4u32(const u32 first, const u32 second, const u32 third,
377 const u32 forth, const hsiphash_key_t *key)
378{
379 u64 combined = (u64)second << 32 | first;
380 HPREAMBLE(16)
381 v3 ^= combined;
382 HSIPROUND;
383 v0 ^= combined;
384 combined = (u64)forth << 32 | third;
385 v3 ^= combined;
386 HSIPROUND;
387 v0 ^= combined;
388 HPOSTAMBLE
389}
390EXPORT_SYMBOL(hsiphash_4u32);
391#else
392#define HSIPROUND \
393 do { \
394 v0 += v1; v1 = rol32(v1, 5); v1 ^= v0; v0 = rol32(v0, 16); \
395 v2 += v3; v3 = rol32(v3, 8); v3 ^= v2; \
396 v0 += v3; v3 = rol32(v3, 7); v3 ^= v0; \
397 v2 += v1; v1 = rol32(v1, 13); v1 ^= v2; v2 = rol32(v2, 16); \
398 } while (0)
399
400#define HPREAMBLE(len) \
401 u32 v0 = 0; \
402 u32 v1 = 0; \
403 u32 v2 = 0x6c796765U; \
404 u32 v3 = 0x74656462U; \
405 u32 b = ((u32)(len)) << 24; \
406 v3 ^= key->key[1]; \
407 v2 ^= key->key[0]; \
408 v1 ^= key->key[1]; \
409 v0 ^= key->key[0];
410
411#define HPOSTAMBLE \
412 v3 ^= b; \
413 HSIPROUND; \
414 v0 ^= b; \
415 v2 ^= 0xff; \
416 HSIPROUND; \
417 HSIPROUND; \
418 HSIPROUND; \
419 return v1 ^ v3;
420
421u32 __hsiphash_aligned(const void *data, size_t len, const hsiphash_key_t *key)
422{
423 const u8 *end = data + len - (len % sizeof(u32));
424 const u8 left = len & (sizeof(u32) - 1);
425 u32 m;
426 HPREAMBLE(len)
427 for (; data != end; data += sizeof(u32)) {
428 m = le32_to_cpup(data);
429 v3 ^= m;
430 HSIPROUND;
431 v0 ^= m;
432 }
433 switch (left) {
434 case 3: b |= ((u32)end[2]) << 16;
435 case 2: b |= le16_to_cpup(data); break;
436 case 1: b |= end[0];
437 }
438 HPOSTAMBLE
439}
440EXPORT_SYMBOL(__hsiphash_aligned);
441
442#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
443u32 __hsiphash_unaligned(const void *data, size_t len,
444 const hsiphash_key_t *key)
445{
446 const u8 *end = data + len - (len % sizeof(u32));
447 const u8 left = len & (sizeof(u32) - 1);
448 u32 m;
449 HPREAMBLE(len)
450 for (; data != end; data += sizeof(u32)) {
451 m = get_unaligned_le32(data);
452 v3 ^= m;
453 HSIPROUND;
454 v0 ^= m;
455 }
456 switch (left) {
457 case 3: b |= ((u32)end[2]) << 16;
458 case 2: b |= get_unaligned_le16(end); break;
459 case 1: b |= end[0];
460 }
461 HPOSTAMBLE
462}
463EXPORT_SYMBOL(__hsiphash_unaligned);
464#endif
465
466/**
467 * hsiphash_1u32 - compute 32-bit hsiphash PRF value of a u32
468 * @first: first u32
469 * @key: the hsiphash key
470 */
471u32 hsiphash_1u32(const u32 first, const hsiphash_key_t *key)
472{
473 HPREAMBLE(4)
474 v3 ^= first;
475 HSIPROUND;
476 v0 ^= first;
477 HPOSTAMBLE
478}
479EXPORT_SYMBOL(hsiphash_1u32);
480
481/**
482 * hsiphash_2u32 - compute 32-bit hsiphash PRF value of 2 u32
483 * @first: first u32
484 * @second: second u32
485 * @key: the hsiphash key
486 */
487u32 hsiphash_2u32(const u32 first, const u32 second, const hsiphash_key_t *key)
488{
489 HPREAMBLE(8)
490 v3 ^= first;
491 HSIPROUND;
492 v0 ^= first;
493 v3 ^= second;
494 HSIPROUND;
495 v0 ^= second;
496 HPOSTAMBLE
497}
498EXPORT_SYMBOL(hsiphash_2u32);
499
500/**
501 * hsiphash_3u32 - compute 32-bit hsiphash PRF value of 3 u32
502 * @first: first u32
503 * @second: second u32
504 * @third: third u32
505 * @key: the hsiphash key
506 */
507u32 hsiphash_3u32(const u32 first, const u32 second, const u32 third,
508 const hsiphash_key_t *key)
509{
510 HPREAMBLE(12)
511 v3 ^= first;
512 HSIPROUND;
513 v0 ^= first;
514 v3 ^= second;
515 HSIPROUND;
516 v0 ^= second;
517 v3 ^= third;
518 HSIPROUND;
519 v0 ^= third;
520 HPOSTAMBLE
521}
522EXPORT_SYMBOL(hsiphash_3u32);
523
524/**
525 * hsiphash_4u32 - compute 32-bit hsiphash PRF value of 4 u32
526 * @first: first u32
527 * @second: second u32
528 * @third: third u32
529 * @forth: forth u32
530 * @key: the hsiphash key
531 */
532u32 hsiphash_4u32(const u32 first, const u32 second, const u32 third,
533 const u32 forth, const hsiphash_key_t *key)
534{
535 HPREAMBLE(16)
536 v3 ^= first;
537 HSIPROUND;
538 v0 ^= first;
539 v3 ^= second;
540 HSIPROUND;
541 v0 ^= second;
542 v3 ^= third;
543 HSIPROUND;
544 v0 ^= third;
545 v3 ^= forth;
546 HSIPROUND;
547 v0 ^= forth;
548 HPOSTAMBLE
549}
550EXPORT_SYMBOL(hsiphash_4u32);
551#endif
diff --git a/lib/test_siphash.c b/lib/test_siphash.c
index d972acfc15e4..a6d854d933bf 100644
--- a/lib/test_siphash.c
+++ b/lib/test_siphash.c
@@ -7,7 +7,9 @@
7 * SipHash: a fast short-input PRF 7 * SipHash: a fast short-input PRF
8 * https://131002.net/siphash/ 8 * https://131002.net/siphash/
9 * 9 *
10 * This implementation is specifically for SipHash2-4. 10 * This implementation is specifically for SipHash2-4 for a secure PRF
11 * and HalfSipHash1-3/SipHash1-3 for an insecure PRF only suitable for
12 * hashtables.
11 */ 13 */
12 14
13#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -18,8 +20,8 @@
18#include <linux/errno.h> 20#include <linux/errno.h>
19#include <linux/module.h> 21#include <linux/module.h>
20 22
21/* Test vectors taken from official reference source available at: 23/* Test vectors taken from reference source available at:
22 * https://131002.net/siphash/siphash24.c 24 * https://github.com/veorq/SipHash
23 */ 25 */
24 26
25static const siphash_key_t test_key_siphash = 27static const siphash_key_t test_key_siphash =
@@ -50,6 +52,64 @@ static const u64 test_vectors_siphash[64] = {
50 0x958a324ceb064572ULL 52 0x958a324ceb064572ULL
51}; 53};
52 54
55#if BITS_PER_LONG == 64
56static const hsiphash_key_t test_key_hsiphash =
57 {{ 0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL }};
58
59static const u32 test_vectors_hsiphash[64] = {
60 0x050fc4dcU, 0x7d57ca93U, 0x4dc7d44dU,
61 0xe7ddf7fbU, 0x88d38328U, 0x49533b67U,
62 0xc59f22a7U, 0x9bb11140U, 0x8d299a8eU,
63 0x6c063de4U, 0x92ff097fU, 0xf94dc352U,
64 0x57b4d9a2U, 0x1229ffa7U, 0xc0f95d34U,
65 0x2a519956U, 0x7d908b66U, 0x63dbd80cU,
66 0xb473e63eU, 0x8d297d1cU, 0xa6cce040U,
67 0x2b45f844U, 0xa320872eU, 0xdae6c123U,
68 0x67349c8cU, 0x705b0979U, 0xca9913a5U,
69 0x4ade3b35U, 0xef6cd00dU, 0x4ab1e1f4U,
70 0x43c5e663U, 0x8c21d1bcU, 0x16a7b60dU,
71 0x7a8ff9bfU, 0x1f2a753eU, 0xbf186b91U,
72 0xada26206U, 0xa3c33057U, 0xae3a36a1U,
73 0x7b108392U, 0x99e41531U, 0x3f1ad944U,
74 0xc8138825U, 0xc28949a6U, 0xfaf8876bU,
75 0x9f042196U, 0x68b1d623U, 0x8b5114fdU,
76 0xdf074c46U, 0x12cc86b3U, 0x0a52098fU,
77 0x9d292f9aU, 0xa2f41f12U, 0x43a71ed0U,
78 0x73f0bce6U, 0x70a7e980U, 0x243c6d75U,
79 0xfdb71513U, 0xa67d8a08U, 0xb7e8f148U,
80 0xf7a644eeU, 0x0f1837f2U, 0x4b6694e0U,
81 0xb7bbb3a8U
82};
83#else
84static const hsiphash_key_t test_key_hsiphash =
85 {{ 0x03020100U, 0x07060504U }};
86
87static const u32 test_vectors_hsiphash[64] = {
88 0x5814c896U, 0xe7e864caU, 0xbc4b0e30U,
89 0x01539939U, 0x7e059ea6U, 0x88e3d89bU,
90 0xa0080b65U, 0x9d38d9d6U, 0x577999b1U,
91 0xc839caedU, 0xe4fa32cfU, 0x959246eeU,
92 0x6b28096cU, 0x66dd9cd6U, 0x16658a7cU,
93 0xd0257b04U, 0x8b31d501U, 0x2b1cd04bU,
94 0x06712339U, 0x522aca67U, 0x911bb605U,
95 0x90a65f0eU, 0xf826ef7bU, 0x62512debU,
96 0x57150ad7U, 0x5d473507U, 0x1ec47442U,
97 0xab64afd3U, 0x0a4100d0U, 0x6d2ce652U,
98 0x2331b6a3U, 0x08d8791aU, 0xbc6dda8dU,
99 0xe0f6c934U, 0xb0652033U, 0x9b9851ccU,
100 0x7c46fb7fU, 0x732ba8cbU, 0xf142997aU,
101 0xfcc9aa1bU, 0x05327eb2U, 0xe110131cU,
102 0xf9e5e7c0U, 0xa7d708a6U, 0x11795ab1U,
103 0x65671619U, 0x9f5fff91U, 0xd89c5267U,
104 0x007783ebU, 0x95766243U, 0xab639262U,
105 0x9c7e1390U, 0xc368dda6U, 0x38ddc455U,
106 0xfa13d379U, 0x979ea4e8U, 0x53ecd77eU,
107 0x2ee80657U, 0x33dbb66aU, 0xae3f0577U,
108 0x88b4c4ccU, 0x3e7f480bU, 0x74c1ebf8U,
109 0x87178304U
110};
111#endif
112
53static int __init siphash_test_init(void) 113static int __init siphash_test_init(void)
54{ 114{
55 u8 in[64] __aligned(SIPHASH_ALIGNMENT); 115 u8 in[64] __aligned(SIPHASH_ALIGNMENT);
@@ -70,6 +130,16 @@ static int __init siphash_test_init(void)
70 pr_info("siphash self-test unaligned %u: FAIL\n", i + 1); 130 pr_info("siphash self-test unaligned %u: FAIL\n", i + 1);
71 ret = -EINVAL; 131 ret = -EINVAL;
72 } 132 }
133 if (hsiphash(in, i, &test_key_hsiphash) !=
134 test_vectors_hsiphash[i]) {
135 pr_info("hsiphash self-test aligned %u: FAIL\n", i + 1);
136 ret = -EINVAL;
137 }
138 if (hsiphash(in_unaligned + 1, i, &test_key_hsiphash) !=
139 test_vectors_hsiphash[i]) {
140 pr_info("hsiphash self-test unaligned %u: FAIL\n", i + 1);
141 ret = -EINVAL;
142 }
73 } 143 }
74 if (siphash_1u64(0x0706050403020100ULL, &test_key_siphash) != 144 if (siphash_1u64(0x0706050403020100ULL, &test_key_siphash) !=
75 test_vectors_siphash[8]) { 145 test_vectors_siphash[8]) {
@@ -115,6 +185,28 @@ static int __init siphash_test_init(void)
115 pr_info("siphash self-test 4u32: FAIL\n"); 185 pr_info("siphash self-test 4u32: FAIL\n");
116 ret = -EINVAL; 186 ret = -EINVAL;
117 } 187 }
188 if (hsiphash_1u32(0x03020100U, &test_key_hsiphash) !=
189 test_vectors_hsiphash[4]) {
190 pr_info("hsiphash self-test 1u32: FAIL\n");
191 ret = -EINVAL;
192 }
193 if (hsiphash_2u32(0x03020100U, 0x07060504U, &test_key_hsiphash) !=
194 test_vectors_hsiphash[8]) {
195 pr_info("hsiphash self-test 2u32: FAIL\n");
196 ret = -EINVAL;
197 }
198 if (hsiphash_3u32(0x03020100U, 0x07060504U,
199 0x0b0a0908U, &test_key_hsiphash) !=
200 test_vectors_hsiphash[12]) {
201 pr_info("hsiphash self-test 3u32: FAIL\n");
202 ret = -EINVAL;
203 }
204 if (hsiphash_4u32(0x03020100U, 0x07060504U,
205 0x0b0a0908U, 0x0f0e0d0cU, &test_key_hsiphash) !=
206 test_vectors_hsiphash[16]) {
207 pr_info("hsiphash self-test 4u32: FAIL\n");
208 ret = -EINVAL;
209 }
118 if (!ret) 210 if (!ret)
119 pr_info("self-tests: pass\n"); 211 pr_info("self-tests: pass\n");
120 return ret; 212 return ret;