1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */ 2 /* SPDX-License-Identifier: Unlicense */ 3 /**********************************************************************\ 4 * To commemorate the 1996 RSA Data Security Conference, the following * 5 * code is released into the public domain by its author. Prost! * 6 * * 7 * This cipher uses 16-bit words and little-endian byte ordering. * 8 * I wonder which processor it was optimized for? * 9 * * 10 * Thanks to CodeView, SoftIce, and D86 for helping bring this code to * 11 * the public. * 12 \**********************************************************************/ 13 #include "tomcrypt_private.h" 14 15 /** 16 @file rc2.c 17 Implementation of RC2 with fixed effective key length of 64bits 18 */ 19 20 #ifdef LTC_RC2 21 22 const struct ltc_cipher_descriptor rc2_desc = { 23 "rc2", 24 12, 8, 128, 8, 16, 25 &rc2_setup, 26 &rc2_ecb_encrypt, 27 &rc2_ecb_decrypt, 28 &rc2_test, 29 &rc2_done, 30 &rc2_keysize, 31 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 32 }; 33 34 /* 256-entry permutation table, probably derived somehow from pi */ 35 static const unsigned char permute[256] = { 36 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157, 37 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162, 38 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50, 39 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130, 40 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220, 41 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38, 42 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3, 43 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215, 44 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42, 45 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236, 46 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57, 47 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49, 48 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201, 49 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169, 50 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46, 51 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173 52 }; 53 54 /** 55 Initialize the RC2 block cipher 56 @param key The symmetric key you wish to pass 57 @param keylen The key length in bytes 58 @param bits The effective key length in bits 59 @param num_rounds The number of rounds desired (0 for default) 60 @param skey The key in as scheduled by this function. 61 @return CRYPT_OK if successful 62 */ 63 int rc2_setup_ex(const unsigned char *key, int keylen, int bits, int num_rounds, symmetric_key *skey) 64 { 65 unsigned *xkey = skey->rc2.xkey; 66 unsigned char tmp[128]; 67 unsigned T8, TM; 68 int i; 69 70 LTC_ARGCHK(key != NULL); 71 LTC_ARGCHK(skey != NULL); 72 73 if (keylen == 0 || keylen > 128 || bits > 1024) { 74 return CRYPT_INVALID_KEYSIZE; 75 } 76 if (bits == 0) { 77 bits = 1024; 78 } 79 80 if (num_rounds != 0 && num_rounds != 16) { 81 return CRYPT_INVALID_ROUNDS; 82 } 83 84 for (i = 0; i < keylen; i++) { 85 tmp[i] = key[i] & 255; 86 } 87 88 /* Phase 1: Expand input key to 128 bytes */ 89 if (keylen < 128) { 90 for (i = keylen; i < 128; i++) { 91 tmp[i] = permute[(tmp[i - 1] + tmp[i - keylen]) & 255]; 92 } 93 } 94 95 /* Phase 2 - reduce effective key size to "bits" */ 96 T8 = (unsigned)(bits+7)>>3; 97 TM = (255 >> (unsigned)(7 & -bits)); 98 tmp[128 - T8] = permute[tmp[128 - T8] & TM]; 99 for (i = 127 - T8; i >= 0; i--) { 100 tmp[i] = permute[tmp[i + 1] ^ tmp[i + T8]]; 101 } 102 103 /* Phase 3 - copy to xkey in little-endian order */ 104 for (i = 0; i < 64; i++) { 105 xkey[i] = (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8); 106 } 107 108 #ifdef LTC_CLEAN_STACK 109 zeromem(tmp, sizeof(tmp)); 110 #endif 111 112 return CRYPT_OK; 113 } 114 115 /** 116 Initialize the RC2 block cipher 117 118 The effective key length is here always keylen * 8 119 120 @param key The symmetric key you wish to pass 121 @param keylen The key length in bytes 122 @param num_rounds The number of rounds desired (0 for default) 123 @param skey The key in as scheduled by this function. 124 @return CRYPT_OK if successful 125 */ 126 int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) 127 { 128 return rc2_setup_ex(key, keylen, keylen * 8, num_rounds, skey); 129 } 130 131 /**********************************************************************\ 132 * Encrypt an 8-byte block of plaintext using the given key. * 133 \**********************************************************************/ 134 /** 135 Encrypts a block of text with RC2 136 @param pt The input plaintext (8 bytes) 137 @param ct The output ciphertext (8 bytes) 138 @param skey The key as scheduled 139 @return CRYPT_OK if successful 140 */ 141 #ifdef LTC_CLEAN_STACK 142 static int s_rc2_ecb_encrypt( const unsigned char *pt, 143 unsigned char *ct, 144 const symmetric_key *skey) 145 #else 146 int rc2_ecb_encrypt( const unsigned char *pt, 147 unsigned char *ct, 148 const symmetric_key *skey) 149 #endif 150 { 151 const unsigned *xkey; 152 unsigned x76, x54, x32, x10, i; 153 154 LTC_ARGCHK(pt != NULL); 155 LTC_ARGCHK(ct != NULL); 156 LTC_ARGCHK(skey != NULL); 157 158 xkey = skey->rc2.xkey; 159 160 x76 = ((unsigned)pt[7] << 8) + (unsigned)pt[6]; 161 x54 = ((unsigned)pt[5] << 8) + (unsigned)pt[4]; 162 x32 = ((unsigned)pt[3] << 8) + (unsigned)pt[2]; 163 x10 = ((unsigned)pt[1] << 8) + (unsigned)pt[0]; 164 165 for (i = 0; i < 16; i++) { 166 x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF; 167 x10 = ((x10 << 1) | (x10 >> 15)); 168 169 x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF; 170 x32 = ((x32 << 2) | (x32 >> 14)); 171 172 x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF; 173 x54 = ((x54 << 3) | (x54 >> 13)); 174 175 x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF; 176 x76 = ((x76 << 5) | (x76 >> 11)); 177 178 if (i == 4 || i == 10) { 179 x10 = (x10 + xkey[x76 & 63]) & 0xFFFF; 180 x32 = (x32 + xkey[x10 & 63]) & 0xFFFF; 181 x54 = (x54 + xkey[x32 & 63]) & 0xFFFF; 182 x76 = (x76 + xkey[x54 & 63]) & 0xFFFF; 183 } 184 } 185 186 ct[0] = (unsigned char)x10; 187 ct[1] = (unsigned char)(x10 >> 8); 188 ct[2] = (unsigned char)x32; 189 ct[3] = (unsigned char)(x32 >> 8); 190 ct[4] = (unsigned char)x54; 191 ct[5] = (unsigned char)(x54 >> 8); 192 ct[6] = (unsigned char)x76; 193 ct[7] = (unsigned char)(x76 >> 8); 194 195 return CRYPT_OK; 196 } 197 198 #ifdef LTC_CLEAN_STACK 199 int rc2_ecb_encrypt( const unsigned char *pt, 200 unsigned char *ct, 201 const symmetric_key *skey) 202 { 203 int err = s_rc2_ecb_encrypt(pt, ct, skey); 204 burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5); 205 return err; 206 } 207 #endif 208 209 /**********************************************************************\ 210 * Decrypt an 8-byte block of ciphertext using the given key. * 211 \**********************************************************************/ 212 /** 213 Decrypts a block of text with RC2 214 @param ct The input ciphertext (8 bytes) 215 @param pt The output plaintext (8 bytes) 216 @param skey The key as scheduled 217 @return CRYPT_OK if successful 218 */ 219 #ifdef LTC_CLEAN_STACK 220 static int s_rc2_ecb_decrypt( const unsigned char *ct, 221 unsigned char *pt, 222 const symmetric_key *skey) 223 #else 224 int rc2_ecb_decrypt( const unsigned char *ct, 225 unsigned char *pt, 226 const symmetric_key *skey) 227 #endif 228 { 229 unsigned x76, x54, x32, x10; 230 const unsigned *xkey; 231 int i; 232 233 LTC_ARGCHK(pt != NULL); 234 LTC_ARGCHK(ct != NULL); 235 LTC_ARGCHK(skey != NULL); 236 237 xkey = skey->rc2.xkey; 238 239 x76 = ((unsigned)ct[7] << 8) + (unsigned)ct[6]; 240 x54 = ((unsigned)ct[5] << 8) + (unsigned)ct[4]; 241 x32 = ((unsigned)ct[3] << 8) + (unsigned)ct[2]; 242 x10 = ((unsigned)ct[1] << 8) + (unsigned)ct[0]; 243 244 for (i = 15; i >= 0; i--) { 245 if (i == 4 || i == 10) { 246 x76 = (x76 - xkey[x54 & 63]) & 0xFFFF; 247 x54 = (x54 - xkey[x32 & 63]) & 0xFFFF; 248 x32 = (x32 - xkey[x10 & 63]) & 0xFFFF; 249 x10 = (x10 - xkey[x76 & 63]) & 0xFFFF; 250 } 251 252 x76 = ((x76 << 11) | (x76 >> 5)); 253 x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF; 254 255 x54 = ((x54 << 13) | (x54 >> 3)); 256 x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF; 257 258 x32 = ((x32 << 14) | (x32 >> 2)); 259 x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF; 260 261 x10 = ((x10 << 15) | (x10 >> 1)); 262 x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF; 263 } 264 265 pt[0] = (unsigned char)x10; 266 pt[1] = (unsigned char)(x10 >> 8); 267 pt[2] = (unsigned char)x32; 268 pt[3] = (unsigned char)(x32 >> 8); 269 pt[4] = (unsigned char)x54; 270 pt[5] = (unsigned char)(x54 >> 8); 271 pt[6] = (unsigned char)x76; 272 pt[7] = (unsigned char)(x76 >> 8); 273 274 return CRYPT_OK; 275 } 276 277 #ifdef LTC_CLEAN_STACK 278 int rc2_ecb_decrypt( const unsigned char *ct, 279 unsigned char *pt, 280 const symmetric_key *skey) 281 { 282 int err = s_rc2_ecb_decrypt(ct, pt, skey); 283 burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int)); 284 return err; 285 } 286 #endif 287 288 /** 289 Performs a self-test of the RC2 block cipher 290 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled 291 */ 292 int rc2_test(void) 293 { 294 #ifndef LTC_TEST 295 return CRYPT_NOP; 296 #else 297 static const struct { 298 int keylen, bits; 299 unsigned char key[16], pt[8], ct[8]; 300 } tests[] = { 301 302 { 8, 63, 303 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 305 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 306 { 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff } 307 }, 308 { 8, 64, 309 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 311 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, 312 { 0x27, 0x8b, 0x27, 0xe4, 0x2e, 0x2f, 0x0d, 0x49 } 313 }, 314 { 8, 64, 315 { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 317 { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, 318 { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 } 319 }, 320 { 1, 64, 321 { 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 323 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 324 { 0x61, 0xa8, 0xa2, 0x44, 0xad, 0xac, 0xcc, 0xf0 } 325 }, 326 { 7, 64, 327 { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x00, 328 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 329 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 330 { 0x6c, 0xcf, 0x43, 0x08, 0x97, 0x4c, 0x26, 0x7f } 331 }, 332 { 16, 64, 333 { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, 334 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 }, 335 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 336 { 0x1a, 0x80, 0x7d, 0x27, 0x2b, 0xbe, 0x5d, 0xb1 } 337 }, 338 { 16, 128, 339 { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, 340 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 }, 341 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 342 { 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 } 343 } 344 }; 345 int x, y, err; 346 symmetric_key skey; 347 unsigned char tmp[2][8]; 348 349 for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { 350 zeromem(tmp, sizeof(tmp)); 351 if (tests[x].bits == (tests[x].keylen * 8)) { 352 if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { 353 return err; 354 } 355 } 356 else { 357 if ((err = rc2_setup_ex(tests[x].key, tests[x].keylen, tests[x].bits, 0, &skey)) != CRYPT_OK) { 358 return err; 359 } 360 } 361 362 rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey); 363 rc2_ecb_decrypt(tmp[0], tmp[1], &skey); 364 365 if (compare_testvector(tmp[0], 8, tests[x].ct, 8, "RC2 CT", x) || 366 compare_testvector(tmp[1], 8, tests[x].pt, 8, "RC2 PT", x)) { 367 return CRYPT_FAIL_TESTVECTOR; 368 } 369 370 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ 371 for (y = 0; y < 8; y++) tmp[0][y] = 0; 372 for (y = 0; y < 1000; y++) rc2_ecb_encrypt(tmp[0], tmp[0], &skey); 373 for (y = 0; y < 1000; y++) rc2_ecb_decrypt(tmp[0], tmp[0], &skey); 374 for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; 375 } 376 return CRYPT_OK; 377 #endif 378 } 379 380 /** Terminate the context 381 @param skey The scheduled key 382 */ 383 void rc2_done(symmetric_key *skey) 384 { 385 LTC_UNUSED_PARAM(skey); 386 } 387 388 /** 389 Gets suitable key size 390 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. 391 @return CRYPT_OK if the input key size is acceptable. 392 */ 393 int rc2_keysize(int *keysize) 394 { 395 LTC_ARGCHK(keysize != NULL); 396 if (*keysize < 1) { 397 return CRYPT_INVALID_KEYSIZE; 398 } 399 if (*keysize > 128) { 400 *keysize = 128; 401 } 402 return CRYPT_OK; 403 } 404 405 #endif 406 407 408 409