1 /* This file is derived from sober128 implementation in corosync
2 cluster engine. corosync cluster engine borrows the implementation
3 from LibTomCrypt.
4
5 The latest version of the original code can be found at
6 http://www.libtom.net/LibTomCrypt/ according to which this code is in the
7 Public Domain
8 */
9
10 /* About LibTomCrypt:
11 * ---------------------------------------------------------------------
12 * LibTomCrypt, modular cryptographic library -- Tom St Denis
13 *
14 * LibTomCrypt is a library that provides various cryptographic
15 * algorithms in a highly modular and flexible manner.
16 *
17 * The library is free for all purposes without any express
18 * guarantee it works.
19 *
20 * Tom St Denis, tomstdenis@iahu.ca, http://www.libtom.net/LibTomCrypt/
21 */
22
23 #include "sober128.h"
24
25 typedef unsigned long ulong32;
26 typedef unsigned long long ulong64;
27
28 /* ---- HELPER MACROS ---- */
29 #define STORE32L(x, y) \
30 { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
31 (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
32
33 #define LOAD32L(x, y) \
34 { x = ((unsigned long)((y)[3] & 255)<<24) | \
35 ((unsigned long)((y)[2] & 255)<<16) | \
36 ((unsigned long)((y)[1] & 255)<<8) | \
37 ((unsigned long)((y)[0] & 255)); }
38
39 /* rotates the hard way */
40 #define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
41
42
43 /* Id: s128multab.h 213 2003-12-16 04:27:12Z ggr $ */
44 /* @(#)TuringMultab.h 1.3 (QUALCOMM) 02/09/03 */
45 /* Multiplication table for Turing using 0xD02B4367 */
46
47 static const ulong32 Multab[256] = {
48 0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9,
49 0x97AC41D1, 0x478702B6, 0x7AFAC71F, 0xAAD18478,
50 0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746,
51 0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697,
52 0xC62A4993, 0x16010AF4, 0x2B7CCF5D, 0xFB578C3A,
53 0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB,
54 0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5,
55 0x32938AAD, 0xE2B8C9CA, 0xDFC50C63, 0x0FEE4F04,
56 0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2,
57 0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613,
58 0xA2411084, 0x726A53E3, 0x4F17964A, 0x9F3CD52D,
59 0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC,
60 0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51,
61 0x90D29A29, 0x40F9D94E, 0x7D841CE7, 0xADAF5F80,
62 0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE,
63 0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F,
64 0xCFA869D6, 0x1F832AB1, 0x22FEEF18, 0xF2D5AC7F,
65 0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE,
66 0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90,
67 0x3B11AAE8, 0xEB3AE98F, 0xD6472C26, 0x066C6F41,
68 0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC,
69 0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D,
70 0x6A97A2AA, 0xBABCE1CD, 0x87C12464, 0x57EA6703,
71 0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2,
72 0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14,
73 0x9950BA6C, 0x497BF90B, 0x74063CA2, 0xA42D7FC5,
74 0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB,
75 0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A,
76 0xC8D6B22E, 0x18FDF149, 0x258034E0, 0xF5AB7787,
77 0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656,
78 0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568,
79 0x3C6F7110, 0xEC443277, 0xD139F7DE, 0x0112B4B9,
80 0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748,
81 0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699,
82 0xB008500E, 0x60231369, 0x5D5ED6C0, 0x8D7595A7,
83 0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476,
84 0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB,
85 0x829BDAA3, 0x52B099C4, 0x6FCD5C6D, 0xBFE61F0A,
86 0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34,
87 0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5,
88 0x1249408A, 0xC26203ED, 0xFF1FC644, 0x2F348523,
89 0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2,
90 0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC,
91 0xE6F083B4, 0x36DBC0D3, 0x0BA6057A, 0xDB8D461D,
92 0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0,
93 0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61,
94 0xB7768BF6, 0x675DC891, 0x5A200D38, 0x8A0B4E5F,
95 0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E,
96 0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E,
97 0x8B19FAE6, 0x5B32B981, 0x664F7C28, 0xB6643F4F,
98 0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71,
99 0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0,
100 0xDA9FF2A4, 0x0AB4B1C3, 0x37C9746A, 0xE7E2370D,
101 0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC,
102 0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2,
103 0x2E26319A, 0xFE0D72FD, 0xC370B754, 0x135BF433,
104 0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5,
105 0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24,
106 0xBEF4ABB3, 0x6EDFE8D4, 0x53A22D7D, 0x83896E1A,
107 0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB,
108 0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566,
109 0x8C67211E, 0x5C4C6279, 0x6131A7D0, 0xB11AE4B7,
110 0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789,
111 0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658,
112 };
113
114 /* Id: s128sbox.h 213 2003-12-16 04:27:12Z ggr $ */
115 /* Sbox for SOBER-128 */
116 /*
117 * This is really the combination of two SBoxes; the least significant
118 * 24 bits comes from:
119 * 8->32 Sbox generated by Millan et. al. at Queensland University of
120 * Technology. See: E. Dawson, W. Millan, L. Burnett, G. Carter,
121 * "On the Design of 8*32 S-boxes". Unpublished report, by the
122 * Information Systems Research Centre,
123 * Queensland University of Technology, 1999.
124 *
125 * The most significant 8 bits are the Skipjack "F table", which can be
126 * found at http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf .
127 * In this optimised table, though, the intent is to XOR the word from
128 * the table selected by the high byte with the input word. Thus, the
129 * high byte is actually the Skipjack F-table entry XORED with its
130 * table index.
131 */
132 static const ulong32 Sbox[256] = {
133 0xa3aa1887, 0xd65e435c, 0x0b65c042, 0x800e6ef4,
134 0xfc57ee20, 0x4d84fed3, 0xf066c502, 0xf354e8ae,
135 0xbb2ee9d9, 0x281f38d4, 0x1f829b5d, 0x735cdf3c,
136 0x95864249, 0xbc2e3963, 0xa1f4429f, 0xf6432c35,
137 0xf7f40325, 0x3cc0dd70, 0x5f973ded, 0x9902dc5e,
138 0xda175b42, 0x590012bf, 0xdc94d78c, 0x39aab26b,
139 0x4ac11b9a, 0x8c168146, 0xc3ea8ec5, 0x058ac28f,
140 0x52ed5c0f, 0x25b4101c, 0x5a2db082, 0x370929e1,
141 0x2a1843de, 0xfe8299fc, 0x202fbc4b, 0x833915dd,
142 0x33a803fa, 0xd446b2de, 0x46233342, 0x4fcee7c3,
143 0x3ad607ef, 0x9e97ebab, 0x507f859b, 0xe81f2e2f,
144 0xc55b71da, 0xd7e2269a, 0x1339c3d1, 0x7ca56b36,
145 0xa6c9def2, 0xb5c9fc5f, 0x5927b3a3, 0x89a56ddf,
146 0xc625b510, 0x560f85a7, 0xace82e71, 0x2ecb8816,
147 0x44951e2a, 0x97f5f6af, 0xdfcbc2b3, 0xce4ff55d,
148 0xcb6b6214, 0x2b0b83e3, 0x549ea6f5, 0x9de041af,
149 0x792f1f17, 0xf73b99ee, 0x39a65ec0, 0x4c7016c6,
150 0x857709a4, 0xd6326e01, 0xc7b280d9, 0x5cfb1418,
151 0xa6aff227, 0xfd548203, 0x506b9d96, 0xa117a8c0,
152 0x9cd5bf6e, 0xdcee7888, 0x61fcfe64, 0xf7a193cd,
153 0x050d0184, 0xe8ae4930, 0x88014f36, 0xd6a87088,
154 0x6bad6c2a, 0x1422c678, 0xe9204de7, 0xb7c2e759,
155 0x0200248e, 0x013b446b, 0xda0d9fc2, 0x0414a895,
156 0x3a6cc3a1, 0x56fef170, 0x86c19155, 0xcf7b8a66,
157 0x551b5e69, 0xb4a8623e, 0xa2bdfa35, 0xc4f068cc,
158 0x573a6acd, 0x6355e936, 0x03602db9, 0x0edf13c1,
159 0x2d0bb16d, 0x6980b83c, 0xfeb23763, 0x3dd8a911,
160 0x01b6bc13, 0xf55579d7, 0xf55c2fa8, 0x19f4196e,
161 0xe7db5476, 0x8d64a866, 0xc06e16ad, 0xb17fc515,
162 0xc46feb3c, 0x8bc8a306, 0xad6799d9, 0x571a9133,
163 0x992466dd, 0x92eb5dcd, 0xac118f50, 0x9fafb226,
164 0xa1b9cef3, 0x3ab36189, 0x347a19b1, 0x62c73084,
165 0xc27ded5c, 0x6c8bc58f, 0x1cdde421, 0xed1e47fb,
166 0xcdcc715e, 0xb9c0ff99, 0x4b122f0f, 0xc4d25184,
167 0xaf7a5e6c, 0x5bbf18bc, 0x8dd7c6e0, 0x5fb7e420,
168 0x521f523f, 0x4ad9b8a2, 0xe9da1a6b, 0x97888c02,
169 0x19d1e354, 0x5aba7d79, 0xa2cc7753, 0x8c2d9655,
170 0x19829da1, 0x531590a7, 0x19c1c149, 0x3d537f1c,
171 0x50779b69, 0xed71f2b7, 0x463c58fa, 0x52dc4418,
172 0xc18c8c76, 0xc120d9f0, 0xafa80d4d, 0x3b74c473,
173 0xd09410e9, 0x290e4211, 0xc3c8082b, 0x8f6b334a,
174 0x3bf68ed2, 0xa843cc1b, 0x8d3c0ff3, 0x20e564a0,
175 0xf8f55a4f, 0x2b40f8e7, 0xfea7f15f, 0xcf00fe21,
176 0x8a6d37d6, 0xd0d506f1, 0xade00973, 0xefbbde36,
177 0x84670fa8, 0xfa31ab9e, 0xaedab618, 0xc01f52f5,
178 0x6558eb4f, 0x71b9e343, 0x4b8d77dd, 0x8cb93da6,
179 0x740fd52d, 0x425412f8, 0xc5a63360, 0x10e53ad0,
180 0x5a700f1c, 0x8324ed0b, 0xe53dc1ec, 0x1a366795,
181 0x6d549d15, 0xc5ce46d7, 0xe17abe76, 0x5f48e0a0,
182 0xd0f07c02, 0x941249b7, 0xe49ed6ba, 0x37a47f78,
183 0xe1cfffbd, 0xb007ca84, 0xbb65f4da, 0xb59f35da,
184 0x33d2aa44, 0x417452ac, 0xc0d674a7, 0x2d61a46a,
185 0xdc63152a, 0x3e12b7aa, 0x6e615927, 0xa14fb118,
186 0xa151758d, 0xba81687b, 0xe152f0b3, 0x764254ed,
187 0x34c77271, 0x0a31acab, 0x54f94aec, 0xb9e994cd,
188 0x574d9e81, 0x5b623730, 0xce8a21e8, 0x37917f0b,
189 0xe8a9b5d6, 0x9697adf8, 0xf3d30431, 0x5dcac921,
190 0x76b35d46, 0xaa430a36, 0xc2194022, 0x22bca65e,
191 0xdaec70ba, 0xdfaea8cc, 0x777bae8b, 0x242924d5,
192 0x1f098a5a, 0x4b396b81, 0x55de2522, 0x435c1cb8,
193 0xaeb8fe1d, 0x9db3c697, 0x5b164f83, 0xe0c16376,
194 0xa319224c, 0xd0203b35, 0x433ac0fe, 0x1466a19a,
195 0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8,
196 0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40,
197 };
198
199
200 /* Implementation of SOBER-128 by Tom St Denis.
201 * Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM.
202 */
203
204 /* don't change these... */
205 #define N 17
206 #define FOLD N /* how many iterations of folding to do */
207 #define INITKONST 0x6996c53a /* value of KONST to use during key loading */
208 #define KEYP 15 /* where to insert key words */
209 #define FOLDP 4 /* where to insert non-linear feedback */
210
BYTE2WORD(const unsigned char * b)211 static ulong32 BYTE2WORD(const unsigned char *b)
212 {
213 ulong32 t;
214 LOAD32L(t, b);
215 return t;
216 }
217
XORWORD(ulong32 w,unsigned char * b)218 static void XORWORD(ulong32 w, unsigned char *b)
219 {
220 ulong32 t;
221 LOAD32L(t, b);
222 t ^= w;
223 STORE32L(t, b);
224 }
225
226 /* give correct offset for the current position of the register,
227 * where logically R[0] is at position "zero".
228 */
229 #define OFF(zero, i) (((zero)+(i)) % N)
230
231 /* step the LFSR */
232 /* After stepping, "zero" moves right one place */
233 #define STEP(R,z) \
234 R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF];
235
cycle(ulong32 * R)236 static void cycle(ulong32 *R)
237 {
238 ulong32 t;
239 int i;
240
241 STEP(R,0);
242 t = R[0];
243 for (i = 1; i < N; ++i) {
244 R[i-1] = R[i];
245 }
246 R[N-1] = t;
247 }
248
249 /* Return a non-linear function of some parts of the register.
250 */
251 #define NLFUNC(c,z) \
252 { \
253 t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \
254 t ^= Sbox[(t >> 24) & 0xFF]; \
255 t = ROR(t, 8); \
256 t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \
257 t ^= Sbox[(t >> 24) & 0xFF]; \
258 t = t + c->R[OFF(z,13)]; \
259 }
260
nltap(sober128_prng * c)261 static ulong32 nltap(sober128_prng *c)
262 {
263 ulong32 t;
264 NLFUNC(c, 0);
265 return t;
266 }
267
268 /* initialise to known state
269 */
sober128_start(sober128_prng * c)270 int sober128_start(sober128_prng *c)
271 {
272 int i;
273
274 /* Register initialised to Fibonacci numbers */
275 c->R[0] = 1;
276 c->R[1] = 1;
277 for (i = 2; i < N; ++i) {
278 c->R[i] = c->R[i-1] + c->R[i-2];
279 }
280 c->konst = INITKONST;
281
282 /* next add_entropy will be the key */
283 c->flag = 1;
284 c->set = 0;
285
286 return 0;
287 }
288
289 /* Save the current register state
290 */
s128_savestate(sober128_prng * c)291 static void s128_savestate(sober128_prng *c)
292 {
293 int i;
294 for (i = 0; i < N; ++i) {
295 c->initR[i] = c->R[i];
296 }
297 }
298
299 /* initialise to previously saved register state
300 */
s128_reloadstate(sober128_prng * c)301 static void s128_reloadstate(sober128_prng *c)
302 {
303 int i;
304
305 for (i = 0; i < N; ++i) {
306 c->R[i] = c->initR[i];
307 }
308 }
309
310 /* Initialise "konst"
311 */
s128_genkonst(sober128_prng * c)312 static void s128_genkonst(sober128_prng *c)
313 {
314 ulong32 newkonst;
315
316 do {
317 cycle(c->R);
318 newkonst = nltap(c);
319 } while ((newkonst & 0xFF000000) == 0);
320 c->konst = newkonst;
321 }
322
323 /* Load key material into the register
324 */
325 #define ADDKEY(k) \
326 c->R[KEYP] += (k);
327
328 #define XORNL(nl) \
329 c->R[FOLDP] ^= (nl);
330
331 /* nonlinear diffusion of register for key */
332 #define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t;
s128_diffuse(sober128_prng * c)333 static void s128_diffuse(sober128_prng *c)
334 {
335 ulong32 t;
336 /* relies on FOLD == N == 17! */
337 DROUND(0);
338 DROUND(1);
339 DROUND(2);
340 DROUND(3);
341 DROUND(4);
342 DROUND(5);
343 DROUND(6);
344 DROUND(7);
345 DROUND(8);
346 DROUND(9);
347 DROUND(10);
348 DROUND(11);
349 DROUND(12);
350 DROUND(13);
351 DROUND(14);
352 DROUND(15);
353 DROUND(16);
354 }
355
sober128_add_entropy(const unsigned char * buf,unsigned long len,sober128_prng * c)356 int sober128_add_entropy(const unsigned char *buf, unsigned long len, sober128_prng *c)
357 {
358 ulong32 i, k;
359
360
361 if (c->flag == 1) {
362 /* this is the first call to the add_entropy so this input is the key */
363 /* len must be multiple of 4 bytes */
364 /* assert ((len & 3) == 0); */
365
366 for (i = 0; i < len/4; i++) {
367 k = BYTE2WORD(&buf[i*4]);
368 ADDKEY(k);
369 cycle(c->R);
370 XORNL(nltap(c));
371 }
372
373 /* also fold in the length of the key */
374 ADDKEY(len);
375
376 /* now diffuse */
377 s128_diffuse(c);
378
379 s128_genkonst(c);
380 s128_savestate(c);
381 c->nbuf = 0;
382 c->flag = 0;
383 c->set = 1;
384 } else {
385 /* ok we are adding an IV then... */
386 s128_reloadstate(c);
387
388 /* len must be multiple of 4 bytes */
389 /* assert ((len & 3) == 0); */
390
391 for (i = 0; i < len/4; i++) {
392 k = BYTE2WORD(&buf[i*4]);
393 ADDKEY(k);
394 cycle(c->R);
395 XORNL(nltap(c));
396 }
397
398 /* also fold in the length of the key */
399 ADDKEY(len);
400
401 /* now diffuse */
402 s128_diffuse(c);
403 c->nbuf = 0;
404 }
405
406 return 0;
407 }
408
409 /* XOR pseudo-random bytes into buffer
410 */
411 #define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, buf+(z*4));
412
sober128_read(unsigned char * buf,unsigned long nbytes,sober128_prng * c)413 unsigned long sober128_read(unsigned char *buf, unsigned long nbytes, sober128_prng *c)
414 {
415 ulong32 t, tlen;
416
417 tlen = nbytes;
418
419 /* handle any previously buffered bytes */
420 while (c->nbuf != 0 && nbytes != 0) {
421 *buf++ ^= c->sbuf & 0xFF;
422 c->sbuf >>= 8;
423 c->nbuf -= 8;
424 --nbytes;
425 }
426
427 #ifndef SMALL_CODE
428 /* do lots at a time, if there's enough to do */
429 while (nbytes >= N*4) {
430 SROUND(0);
431 SROUND(1);
432 SROUND(2);
433 SROUND(3);
434 SROUND(4);
435 SROUND(5);
436 SROUND(6);
437 SROUND(7);
438 SROUND(8);
439 SROUND(9);
440 SROUND(10);
441 SROUND(11);
442 SROUND(12);
443 SROUND(13);
444 SROUND(14);
445 SROUND(15);
446 SROUND(16);
447 buf += 4*N;
448 nbytes -= 4*N;
449 }
450 #endif
451
452 /* do small or odd size buffers the slow way */
453 while (4 <= nbytes) {
454 cycle(c->R);
455 t = nltap(c);
456 XORWORD(t, buf);
457 buf += 4;
458 nbytes -= 4;
459 }
460
461 /* handle any trailing bytes */
462 if (nbytes != 0) {
463 cycle(c->R);
464 c->sbuf = nltap(c);
465 c->nbuf = 32;
466 while (c->nbuf != 0 && nbytes != 0) {
467 *buf++ ^= c->sbuf & 0xFF;
468 c->sbuf >>= 8;
469 c->nbuf -= 8;
470 --nbytes;
471 }
472 }
473
474 return tlen;
475 }
476
477 /*
478 * Editor modelines - https://www.wireshark.org/tools/modelines.html
479 *
480 * Local variables:
481 * c-basic-offset: 4
482 * tab-width: 8
483 * indent-tabs-mode: nil
484 * End:
485 *
486 * vi: set shiftwidth=4 tabstop=8 expandtab:
487 * :indentSize=4:tabSize=8:noTabs=true:
488 */
489