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