safer.c revision f7fc46c63fdc8f39234fea409b8dbe116d73ebf8
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, tomstdenis@gmail.com, 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 (demoliner@isi.ee.ethz.ch) 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 35const 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 ****************************************************/ 98extern const unsigned char safer_ebox[], safer_lbox[]; 99 100#ifdef LTC_CLEAN_STACK 101static 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 107static 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 169static 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 180int 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 197int 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 214int 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 231int 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 249static int _safer_ecb_encrypt(const unsigned char *block_in, 250 unsigned char *block_out, 251 symmetric_key *skey) 252#else 253int 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 292int 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 303static int _safer_ecb_decrypt(const unsigned char *block_in, 304 unsigned char *block_out, 305 symmetric_key *skey) 306#else 307int 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 347int 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 357int 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 368int 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 379int 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 408int 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*/ 446void safer_done(symmetric_key *skey) 447{ 448} 449 450int 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 $ */ 492