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