Mercurial > dropbear
comparison libtomcrypt/src/ciphers/safer/safer.c @ 399:a707e6148060
merge of '5fdf69ca60d1683cdd9f4c2595134bed26394834'
and '6b61c50f4cf888bea302ac8fcf5dbb573b443251'
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 03 Feb 2007 08:20:34 +0000 |
parents | 0cbe8f6dbf9e |
children | f849a5ca2efc |
comparison
equal
deleted
inserted
replaced
394:17d097fc111c | 399:a707e6148060 |
---|---|
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
2 * | |
3 * LibTomCrypt is a library that provides various cryptographic | |
4 * algorithms in a highly modular and flexible manner. | |
5 * | |
6 * The library is free for all purposes without any express | |
7 * guarantee it works. | |
8 * | |
9 * Tom St Denis, [email protected], http://libtomcrypt.com | |
10 */ | |
11 | |
12 /******************************************************************************* | |
13 * | |
14 * FILE: safer.c | |
15 * | |
16 * DESCRIPTION: block-cipher algorithm SAFER (Secure And Fast Encryption | |
17 * Routine) in its four versions: SAFER K-64, SAFER K-128, | |
18 * SAFER SK-64 and SAFER SK-128. | |
19 * | |
20 * AUTHOR: Richard De Moliner ([email protected]) | |
21 * Signal and Information Processing Laboratory | |
22 * Swiss Federal Institute of Technology | |
23 * CH-8092 Zuerich, Switzerland | |
24 * | |
25 * DATE: September 9, 1995 | |
26 * | |
27 * CHANGE HISTORY: | |
28 * | |
29 *******************************************************************************/ | |
30 | |
31 #include <tomcrypt.h> | |
32 | |
33 #ifdef SAFER | |
34 | |
35 const struct ltc_cipher_descriptor | |
36 safer_k64_desc = { | |
37 "safer-k64", | |
38 8, 8, 8, 8, SAFER_K64_DEFAULT_NOF_ROUNDS, | |
39 &safer_k64_setup, | |
40 &safer_ecb_encrypt, | |
41 &safer_ecb_decrypt, | |
42 &safer_k64_test, | |
43 &safer_done, | |
44 &safer_64_keysize, | |
45 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL | |
46 }, | |
47 | |
48 safer_sk64_desc = { | |
49 "safer-sk64", | |
50 9, 8, 8, 8, SAFER_SK64_DEFAULT_NOF_ROUNDS, | |
51 &safer_sk64_setup, | |
52 &safer_ecb_encrypt, | |
53 &safer_ecb_decrypt, | |
54 &safer_sk64_test, | |
55 &safer_done, | |
56 &safer_64_keysize, | |
57 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL | |
58 }, | |
59 | |
60 safer_k128_desc = { | |
61 "safer-k128", | |
62 10, 16, 16, 8, SAFER_K128_DEFAULT_NOF_ROUNDS, | |
63 &safer_k128_setup, | |
64 &safer_ecb_encrypt, | |
65 &safer_ecb_decrypt, | |
66 &safer_sk128_test, | |
67 &safer_done, | |
68 &safer_128_keysize, | |
69 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL | |
70 }, | |
71 | |
72 safer_sk128_desc = { | |
73 "safer-sk128", | |
74 11, 16, 16, 8, SAFER_SK128_DEFAULT_NOF_ROUNDS, | |
75 &safer_sk128_setup, | |
76 &safer_ecb_encrypt, | |
77 &safer_ecb_decrypt, | |
78 &safer_sk128_test, | |
79 &safer_done, | |
80 &safer_128_keysize, | |
81 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL | |
82 }; | |
83 | |
84 /******************* Constants ************************************************/ | |
85 /* #define TAB_LEN 256 */ | |
86 | |
87 /******************* Assertions ***********************************************/ | |
88 | |
89 /******************* Macros ***************************************************/ | |
90 #define ROL8(x, n) ((unsigned char)((unsigned int)(x) << (n)\ | |
91 |(unsigned int)((x) & 0xFF) >> (8 - (n)))) | |
92 #define EXP(x) safer_ebox[(x) & 0xFF] | |
93 #define LOG(x) safer_lbox[(x) & 0xFF] | |
94 #define PHT(x, y) { y += x; x += y; } | |
95 #define IPHT(x, y) { x -= y; y -= x; } | |
96 | |
97 /******************* Types ****************************************************/ | |
98 extern const unsigned char safer_ebox[], safer_lbox[]; | |
99 | |
100 #ifdef LTC_CLEAN_STACK | |
101 static void _Safer_Expand_Userkey(const unsigned char *userkey_1, | |
102 const unsigned char *userkey_2, | |
103 unsigned int nof_rounds, | |
104 int strengthened, | |
105 safer_key_t key) | |
106 #else | |
107 static void Safer_Expand_Userkey(const unsigned char *userkey_1, | |
108 const unsigned char *userkey_2, | |
109 unsigned int nof_rounds, | |
110 int strengthened, | |
111 safer_key_t key) | |
112 #endif | |
113 { unsigned int i, j, k; | |
114 unsigned char ka[SAFER_BLOCK_LEN + 1]; | |
115 unsigned char kb[SAFER_BLOCK_LEN + 1]; | |
116 | |
117 if (SAFER_MAX_NOF_ROUNDS < nof_rounds) | |
118 nof_rounds = SAFER_MAX_NOF_ROUNDS; | |
119 *key++ = (unsigned char)nof_rounds; | |
120 ka[SAFER_BLOCK_LEN] = (unsigned char)0; | |
121 kb[SAFER_BLOCK_LEN] = (unsigned char)0; | |
122 k = 0; | |
123 for (j = 0; j < SAFER_BLOCK_LEN; j++) { | |
124 ka[j] = ROL8(userkey_1[j], 5); | |
125 ka[SAFER_BLOCK_LEN] ^= ka[j]; | |
126 kb[j] = *key++ = userkey_2[j]; | |
127 kb[SAFER_BLOCK_LEN] ^= kb[j]; | |
128 } | |
129 for (i = 1; i <= nof_rounds; i++) { | |
130 for (j = 0; j < SAFER_BLOCK_LEN + 1; j++) { | |
131 ka[j] = ROL8(ka[j], 6); | |
132 kb[j] = ROL8(kb[j], 6); | |
133 } | |
134 if (strengthened) { | |
135 k = 2 * i - 1; | |
136 while (k >= (SAFER_BLOCK_LEN + 1)) { k -= SAFER_BLOCK_LEN + 1; } | |
137 } | |
138 for (j = 0; j < SAFER_BLOCK_LEN; j++) { | |
139 if (strengthened) { | |
140 *key++ = (ka[k] | |
141 + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; | |
142 if (++k == (SAFER_BLOCK_LEN + 1)) { k = 0; } | |
143 } else { | |
144 *key++ = (ka[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; | |
145 } | |
146 } | |
147 if (strengthened) { | |
148 k = 2 * i; | |
149 while (k >= (SAFER_BLOCK_LEN + 1)) { k -= SAFER_BLOCK_LEN + 1; } | |
150 } | |
151 for (j = 0; j < SAFER_BLOCK_LEN; j++) { | |
152 if (strengthened) { | |
153 *key++ = (kb[k] | |
154 + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; | |
155 if (++k == (SAFER_BLOCK_LEN + 1)) { k = 0; } | |
156 } else { | |
157 *key++ = (kb[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; | |
158 } | |
159 } | |
160 } | |
161 | |
162 #ifdef LTC_CLEAN_STACK | |
163 zeromem(ka, sizeof(ka)); | |
164 zeromem(kb, sizeof(kb)); | |
165 #endif | |
166 } | |
167 | |
168 #ifdef LTC_CLEAN_STACK | |
169 static void Safer_Expand_Userkey(const unsigned char *userkey_1, | |
170 const unsigned char *userkey_2, | |
171 unsigned int nof_rounds, | |
172 int strengthened, | |
173 safer_key_t key) | |
174 { | |
175 _Safer_Expand_Userkey(userkey_1, userkey_2, nof_rounds, strengthened, key); | |
176 burn_stack(sizeof(unsigned char) * (2 * (SAFER_BLOCK_LEN + 1)) + sizeof(unsigned int)*2); | |
177 } | |
178 #endif | |
179 | |
180 int safer_k64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) | |
181 { | |
182 LTC_ARGCHK(key != NULL); | |
183 LTC_ARGCHK(skey != NULL); | |
184 | |
185 if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { | |
186 return CRYPT_INVALID_ROUNDS; | |
187 } | |
188 | |
189 if (keylen != 8) { | |
190 return CRYPT_INVALID_KEYSIZE; | |
191 } | |
192 | |
193 Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); | |
194 return CRYPT_OK; | |
195 } | |
196 | |
197 int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) | |
198 { | |
199 LTC_ARGCHK(key != NULL); | |
200 LTC_ARGCHK(skey != NULL); | |
201 | |
202 if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { | |
203 return CRYPT_INVALID_ROUNDS; | |
204 } | |
205 | |
206 if (keylen != 8) { | |
207 return CRYPT_INVALID_KEYSIZE; | |
208 } | |
209 | |
210 Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:SAFER_SK64_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); | |
211 return CRYPT_OK; | |
212 } | |
213 | |
214 int safer_k128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) | |
215 { | |
216 LTC_ARGCHK(key != NULL); | |
217 LTC_ARGCHK(skey != NULL); | |
218 | |
219 if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { | |
220 return CRYPT_INVALID_ROUNDS; | |
221 } | |
222 | |
223 if (keylen != 16) { | |
224 return CRYPT_INVALID_KEYSIZE; | |
225 } | |
226 | |
227 Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0 ?numrounds:SAFER_K128_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); | |
228 return CRYPT_OK; | |
229 } | |
230 | |
231 int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) | |
232 { | |
233 LTC_ARGCHK(key != NULL); | |
234 LTC_ARGCHK(skey != NULL); | |
235 | |
236 if (numrounds != 0 && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) { | |
237 return CRYPT_INVALID_ROUNDS; | |
238 } | |
239 | |
240 if (keylen != 16) { | |
241 return CRYPT_INVALID_KEYSIZE; | |
242 } | |
243 | |
244 Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0?numrounds:SAFER_SK128_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); | |
245 return CRYPT_OK; | |
246 } | |
247 | |
248 #ifdef LTC_CLEAN_STACK | |
249 static int _safer_ecb_encrypt(const unsigned char *block_in, | |
250 unsigned char *block_out, | |
251 symmetric_key *skey) | |
252 #else | |
253 int safer_ecb_encrypt(const unsigned char *block_in, | |
254 unsigned char *block_out, | |
255 symmetric_key *skey) | |
256 #endif | |
257 { unsigned char a, b, c, d, e, f, g, h, t; | |
258 unsigned int round; | |
259 unsigned char *key; | |
260 | |
261 LTC_ARGCHK(block_in != NULL); | |
262 LTC_ARGCHK(block_out != NULL); | |
263 LTC_ARGCHK(skey != NULL); | |
264 | |
265 key = skey->safer.key; | |
266 a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; | |
267 e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; | |
268 if (SAFER_MAX_NOF_ROUNDS < (round = *key)) round = SAFER_MAX_NOF_ROUNDS; | |
269 while(round-- > 0) | |
270 { | |
271 a ^= *++key; b += *++key; c += *++key; d ^= *++key; | |
272 e ^= *++key; f += *++key; g += *++key; h ^= *++key; | |
273 a = EXP(a) + *++key; b = LOG(b) ^ *++key; | |
274 c = LOG(c) ^ *++key; d = EXP(d) + *++key; | |
275 e = EXP(e) + *++key; f = LOG(f) ^ *++key; | |
276 g = LOG(g) ^ *++key; h = EXP(h) + *++key; | |
277 PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h); | |
278 PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h); | |
279 PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h); | |
280 t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t; | |
281 } | |
282 a ^= *++key; b += *++key; c += *++key; d ^= *++key; | |
283 e ^= *++key; f += *++key; g += *++key; h ^= *++key; | |
284 block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; | |
285 block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; | |
286 block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; | |
287 block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; | |
288 return CRYPT_OK; | |
289 } | |
290 | |
291 #ifdef LTC_CLEAN_STACK | |
292 int safer_ecb_encrypt(const unsigned char *block_in, | |
293 unsigned char *block_out, | |
294 symmetric_key *skey) | |
295 { | |
296 int err = _safer_ecb_encrypt(block_in, block_out, skey); | |
297 burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); | |
298 return err; | |
299 } | |
300 #endif | |
301 | |
302 #ifdef LTC_CLEAN_STACK | |
303 static int _safer_ecb_decrypt(const unsigned char *block_in, | |
304 unsigned char *block_out, | |
305 symmetric_key *skey) | |
306 #else | |
307 int safer_ecb_decrypt(const unsigned char *block_in, | |
308 unsigned char *block_out, | |
309 symmetric_key *skey) | |
310 #endif | |
311 { unsigned char a, b, c, d, e, f, g, h, t; | |
312 unsigned int round; | |
313 unsigned char *key; | |
314 | |
315 LTC_ARGCHK(block_in != NULL); | |
316 LTC_ARGCHK(block_out != NULL); | |
317 LTC_ARGCHK(skey != NULL); | |
318 | |
319 key = skey->safer.key; | |
320 a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; | |
321 e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; | |
322 if (SAFER_MAX_NOF_ROUNDS < (round = *key)) round = SAFER_MAX_NOF_ROUNDS; | |
323 key += SAFER_BLOCK_LEN * (1 + 2 * round); | |
324 h ^= *key; g -= *--key; f -= *--key; e ^= *--key; | |
325 d ^= *--key; c -= *--key; b -= *--key; a ^= *--key; | |
326 while (round--) | |
327 { | |
328 t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t; | |
329 IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h); | |
330 IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h); | |
331 IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h); | |
332 h -= *--key; g ^= *--key; f ^= *--key; e -= *--key; | |
333 d -= *--key; c ^= *--key; b ^= *--key; a -= *--key; | |
334 h = LOG(h) ^ *--key; g = EXP(g) - *--key; | |
335 f = EXP(f) - *--key; e = LOG(e) ^ *--key; | |
336 d = LOG(d) ^ *--key; c = EXP(c) - *--key; | |
337 b = EXP(b) - *--key; a = LOG(a) ^ *--key; | |
338 } | |
339 block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; | |
340 block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; | |
341 block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; | |
342 block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; | |
343 return CRYPT_OK; | |
344 } | |
345 | |
346 #ifdef LTC_CLEAN_STACK | |
347 int safer_ecb_decrypt(const unsigned char *block_in, | |
348 unsigned char *block_out, | |
349 symmetric_key *skey) | |
350 { | |
351 int err = _safer_ecb_decrypt(block_in, block_out, skey); | |
352 burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); | |
353 return err; | |
354 } | |
355 #endif | |
356 | |
357 int safer_64_keysize(int *keysize) | |
358 { | |
359 LTC_ARGCHK(keysize != NULL); | |
360 if (*keysize < 8) { | |
361 return CRYPT_INVALID_KEYSIZE; | |
362 } else { | |
363 *keysize = 8; | |
364 return CRYPT_OK; | |
365 } | |
366 } | |
367 | |
368 int safer_128_keysize(int *keysize) | |
369 { | |
370 LTC_ARGCHK(keysize != NULL); | |
371 if (*keysize < 16) { | |
372 return CRYPT_INVALID_KEYSIZE; | |
373 } else { | |
374 *keysize = 16; | |
375 return CRYPT_OK; | |
376 } | |
377 } | |
378 | |
379 int safer_k64_test(void) | |
380 { | |
381 #ifndef LTC_TEST | |
382 return CRYPT_NOP; | |
383 #else | |
384 static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, | |
385 k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 }, | |
386 k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 }; | |
387 | |
388 symmetric_key skey; | |
389 unsigned char buf[2][8]; | |
390 int err; | |
391 | |
392 /* test K64 */ | |
393 if ((err = safer_k64_setup(k64_key, 8, 6, &skey)) != CRYPT_OK) { | |
394 return err; | |
395 } | |
396 safer_ecb_encrypt(k64_pt, buf[0], &skey); | |
397 safer_ecb_decrypt(buf[0], buf[1], &skey); | |
398 | |
399 if (XMEMCMP(buf[0], k64_ct, 8) != 0 || XMEMCMP(buf[1], k64_pt, 8) != 0) { | |
400 return CRYPT_FAIL_TESTVECTOR; | |
401 } | |
402 | |
403 return CRYPT_OK; | |
404 #endif | |
405 } | |
406 | |
407 | |
408 int safer_sk64_test(void) | |
409 { | |
410 #ifndef LTC_TEST | |
411 return CRYPT_NOP; | |
412 #else | |
413 static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, | |
414 sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, | |
415 sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 }; | |
416 | |
417 symmetric_key skey; | |
418 unsigned char buf[2][8]; | |
419 int err, y; | |
420 | |
421 /* test SK64 */ | |
422 if ((err = safer_sk64_setup(sk64_key, 8, 6, &skey)) != CRYPT_OK) { | |
423 return err; | |
424 } | |
425 | |
426 safer_ecb_encrypt(sk64_pt, buf[0], &skey); | |
427 safer_ecb_decrypt(buf[0], buf[1], &skey); | |
428 | |
429 if (XMEMCMP(buf[0], sk64_ct, 8) != 0 || XMEMCMP(buf[1], sk64_pt, 8) != 0) { | |
430 return CRYPT_FAIL_TESTVECTOR; | |
431 } | |
432 | |
433 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ | |
434 for (y = 0; y < 8; y++) buf[0][y] = 0; | |
435 for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); | |
436 for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); | |
437 for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; | |
438 | |
439 return CRYPT_OK; | |
440 #endif | |
441 } | |
442 | |
443 /** Terminate the context | |
444 @param skey The scheduled key | |
445 */ | |
446 void safer_done(symmetric_key *skey) | |
447 { | |
448 } | |
449 | |
450 int safer_sk128_test(void) | |
451 { | |
452 #ifndef LTC_TEST | |
453 return CRYPT_NOP; | |
454 #else | |
455 static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, | |
456 sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8, | |
457 0, 0, 0, 0, 0, 0, 0, 0 }, | |
458 sk128_ct[] = { 255, 120, 17, 228, 179, 167, 46, 113 }; | |
459 | |
460 symmetric_key skey; | |
461 unsigned char buf[2][8]; | |
462 int err, y; | |
463 | |
464 /* test SK128 */ | |
465 if ((err = safer_sk128_setup(sk128_key, 16, 0, &skey)) != CRYPT_OK) { | |
466 return err; | |
467 } | |
468 safer_ecb_encrypt(sk128_pt, buf[0], &skey); | |
469 safer_ecb_decrypt(buf[0], buf[1], &skey); | |
470 | |
471 if (XMEMCMP(buf[0], sk128_ct, 8) != 0 || XMEMCMP(buf[1], sk128_pt, 8) != 0) { | |
472 return CRYPT_FAIL_TESTVECTOR; | |
473 } | |
474 | |
475 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ | |
476 for (y = 0; y < 8; y++) buf[0][y] = 0; | |
477 for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); | |
478 for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); | |
479 for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; | |
480 return CRYPT_OK; | |
481 #endif | |
482 } | |
483 | |
484 #endif | |
485 | |
486 | |
487 | |
488 | |
489 /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/safer/safer.c,v $ */ | |
490 /* $Revision: 1.13 $ */ | |
491 /* $Date: 2006/11/08 23:01:06 $ */ |