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 
27 static const siphash_key_t test_key_siphash =
28 	{{ 0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL }};
29 
30 static 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
56 static const hsiphash_key_t test_key_hsiphash =
57 	{{ 0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL }};
58 
59 static 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
84 static const hsiphash_key_t test_key_hsiphash =
85 	{{ 0x03020100U, 0x07060504U }};
86 
87 static 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 
siphash_test_init(void)113 static 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 
siphash_test_exit(void)215 static void __exit siphash_test_exit(void)
216 {
217 }
218 
219 module_init(siphash_test_init);
220 module_exit(siphash_test_exit);
221 
222 MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
223 MODULE_LICENSE("Dual BSD/GPL");
224