1/* Test cases for siphash.c
2 *
3 * Copyright (C) 2016 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
4 *
5 * This file is provided under a dual BSD/GPLv2 license.
6 *
7 * SipHash: a fast short-input PRF
8 * https://131002.net/siphash/
9 *
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.
13 */
14
15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
17#include <linux/siphash.h>
18#include <linux/kernel.h>
19#include <linux/string.h>
20#include <linux/errno.h>
21#include <linux/module.h>
22
23/* Test vectors taken from reference source available at:
24 * https://github.com/veorq/SipHash
25 */
26
27static const siphash_key_t test_key_siphash =
28 {{ 0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL }};
29
30static const u64 test_vectors_siphash[64] = {
31 0x726fdb47dd0e0e31ULL, 0x74f839c593dc67fdULL, 0x0d6c8009d9a94f5aULL,
32 0x85676696d7fb7e2dULL, 0xcf2794e0277187b7ULL, 0x18765564cd99a68dULL,
33 0xcbc9466e58fee3ceULL, 0xab0200f58b01d137ULL, 0x93f5f5799a932462ULL,
34 0x9e0082df0ba9e4b0ULL, 0x7a5dbbc594ddb9f3ULL, 0xf4b32f46226bada7ULL,
35 0x751e8fbc860ee5fbULL, 0x14ea5627c0843d90ULL, 0xf723ca908e7af2eeULL,
36 0xa129ca6149be45e5ULL, 0x3f2acc7f57c29bdbULL, 0x699ae9f52cbe4794ULL,
37 0x4bc1b3f0968dd39cULL, 0xbb6dc91da77961bdULL, 0xbed65cf21aa2ee98ULL,
38 0xd0f2cbb02e3b67c7ULL, 0x93536795e3a33e88ULL, 0xa80c038ccd5ccec8ULL,
39 0xb8ad50c6f649af94ULL, 0xbce192de8a85b8eaULL, 0x17d835b85bbb15f3ULL,
40 0x2f2e6163076bcfadULL, 0xde4daaaca71dc9a5ULL, 0xa6a2506687956571ULL,
41 0xad87a3535c49ef28ULL, 0x32d892fad841c342ULL, 0x7127512f72f27cceULL,
42 0xa7f32346f95978e3ULL, 0x12e0b01abb051238ULL, 0x15e034d40fa197aeULL,
43 0x314dffbe0815a3b4ULL, 0x027990f029623981ULL, 0xcadcd4e59ef40c4dULL,
44 0x9abfd8766a33735cULL, 0x0e3ea96b5304a7d0ULL, 0xad0c42d6fc585992ULL,
45 0x187306c89bc215a9ULL, 0xd4a60abcf3792b95ULL, 0xf935451de4f21df2ULL,
46 0xa9538f0419755787ULL, 0xdb9acddff56ca510ULL, 0xd06c98cd5c0975ebULL,
47 0xe612a3cb9ecba951ULL, 0xc766e62cfcadaf96ULL, 0xee64435a9752fe72ULL,
48 0xa192d576b245165aULL, 0x0a8787bf8ecb74b2ULL, 0x81b3e73d20b49b6fULL,
49 0x7fa8220ba3b2eceaULL, 0x245731c13ca42499ULL, 0xb78dbfaf3a8d83bdULL,
50 0xea1ad565322a1a0bULL, 0x60e61c23a3795013ULL, 0x6606d7e446282b93ULL,
51 0x6ca4ecb15c5f91e1ULL, 0x9f626da15c9625f3ULL, 0xe51b38608ef25f57ULL,
52 0x958a324ceb064572ULL
53};
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
113static int __init siphash_test_init(void)
114{
115 u8 in[64] __aligned(SIPHASH_ALIGNMENT);
116 u8 in_unaligned[65] __aligned(SIPHASH_ALIGNMENT);
117 u8 i;
118 int ret = 0;
119
120 for (i = 0; i < 64; ++i) {
121 in[i] = i;
122 in_unaligned[i + 1] = i;
123 if (siphash(in, i, &test_key_siphash) !=
124 test_vectors_siphash[i]) {
125 pr_info("siphash self-test aligned %u: FAIL\n", i + 1);
126 ret = -EINVAL;
127 }
128 if (siphash(in_unaligned + 1, i, &test_key_siphash) !=
129 test_vectors_siphash[i]) {
130 pr_info("siphash self-test unaligned %u: FAIL\n", i + 1);
131 ret = -EINVAL;
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 }
143 }
144 if (siphash_1u64(0x0706050403020100ULL, &test_key_siphash) !=
145 test_vectors_siphash[8]) {
146 pr_info("siphash self-test 1u64: FAIL\n");
147 ret = -EINVAL;
148 }
149 if (siphash_2u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
150 &test_key_siphash) != test_vectors_siphash[16]) {
151 pr_info("siphash self-test 2u64: FAIL\n");
152 ret = -EINVAL;
153 }
154 if (siphash_3u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
155 0x1716151413121110ULL, &test_key_siphash) !=
156 test_vectors_siphash[24]) {
157 pr_info("siphash self-test 3u64: FAIL\n");
158 ret = -EINVAL;
159 }
160 if (siphash_4u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
161 0x1716151413121110ULL, 0x1f1e1d1c1b1a1918ULL,
162 &test_key_siphash) != test_vectors_siphash[32]) {
163 pr_info("siphash self-test 4u64: FAIL\n");
164 ret = -EINVAL;
165 }
166 if (siphash_1u32(0x03020100U, &test_key_siphash) !=
167 test_vectors_siphash[4]) {
168 pr_info("siphash self-test 1u32: FAIL\n");
169 ret = -EINVAL;
170 }
171 if (siphash_2u32(0x03020100U, 0x07060504U, &test_key_siphash) !=
172 test_vectors_siphash[8]) {
173 pr_info("siphash self-test 2u32: FAIL\n");
174 ret = -EINVAL;
175 }
176 if (siphash_3u32(0x03020100U, 0x07060504U,
177 0x0b0a0908U, &test_key_siphash) !=
178 test_vectors_siphash[12]) {
179 pr_info("siphash self-test 3u32: FAIL\n");
180 ret = -EINVAL;
181 }
182 if (siphash_4u32(0x03020100U, 0x07060504U,
183 0x0b0a0908U, 0x0f0e0d0cU, &test_key_siphash) !=
184 test_vectors_siphash[16]) {
185 pr_info("siphash self-test 4u32: FAIL\n");
186 ret = -EINVAL;
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 }
210 if (!ret)
211 pr_info("self-tests: pass\n");
212 return ret;
213}
214
215static void __exit siphash_test_exit(void)
216{
217}
218
219module_init(siphash_test_init);
220module_exit(siphash_test_exit);
221
222MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
223MODULE_LICENSE("Dual BSD/GPL");
224