1*8411e6adSJerome Forissier /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2*8411e6adSJerome Forissier /* SPDX-License-Identifier: Unlicense */
35a913ee7SJerome Forissier /**********************************************************************\
45a913ee7SJerome Forissier * To commemorate the 1996 RSA Data Security Conference, the following *
55a913ee7SJerome Forissier * code is released into the public domain by its author. Prost! *
65a913ee7SJerome Forissier * *
75a913ee7SJerome Forissier * This cipher uses 16-bit words and little-endian byte ordering. *
85a913ee7SJerome Forissier * I wonder which processor it was optimized for? *
95a913ee7SJerome Forissier * *
105a913ee7SJerome Forissier * Thanks to CodeView, SoftIce, and D86 for helping bring this code to *
115a913ee7SJerome Forissier * the public. *
125a913ee7SJerome Forissier \**********************************************************************/
135a913ee7SJerome Forissier #include "tomcrypt_private.h"
145a913ee7SJerome Forissier
155a913ee7SJerome Forissier /**
165a913ee7SJerome Forissier @file rc2.c
175a913ee7SJerome Forissier Implementation of RC2 with fixed effective key length of 64bits
185a913ee7SJerome Forissier */
195a913ee7SJerome Forissier
205a913ee7SJerome Forissier #ifdef LTC_RC2
215a913ee7SJerome Forissier
225a913ee7SJerome Forissier const struct ltc_cipher_descriptor rc2_desc = {
235a913ee7SJerome Forissier "rc2",
245a913ee7SJerome Forissier 12, 8, 128, 8, 16,
255a913ee7SJerome Forissier &rc2_setup,
265a913ee7SJerome Forissier &rc2_ecb_encrypt,
275a913ee7SJerome Forissier &rc2_ecb_decrypt,
285a913ee7SJerome Forissier &rc2_test,
295a913ee7SJerome Forissier &rc2_done,
305a913ee7SJerome Forissier &rc2_keysize,
315a913ee7SJerome Forissier NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
325a913ee7SJerome Forissier };
335a913ee7SJerome Forissier
345a913ee7SJerome Forissier /* 256-entry permutation table, probably derived somehow from pi */
355a913ee7SJerome Forissier static const unsigned char permute[256] = {
365a913ee7SJerome Forissier 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
375a913ee7SJerome Forissier 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
385a913ee7SJerome Forissier 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50,
395a913ee7SJerome Forissier 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
405a913ee7SJerome Forissier 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
415a913ee7SJerome Forissier 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
425a913ee7SJerome Forissier 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3,
435a913ee7SJerome Forissier 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215,
445a913ee7SJerome Forissier 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
455a913ee7SJerome Forissier 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236,
465a913ee7SJerome Forissier 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
475a913ee7SJerome Forissier 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49,
485a913ee7SJerome Forissier 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201,
495a913ee7SJerome Forissier 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169,
505a913ee7SJerome Forissier 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
515a913ee7SJerome Forissier 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173
525a913ee7SJerome Forissier };
535a913ee7SJerome Forissier
545a913ee7SJerome Forissier /**
555a913ee7SJerome Forissier Initialize the RC2 block cipher
565a913ee7SJerome Forissier @param key The symmetric key you wish to pass
575a913ee7SJerome Forissier @param keylen The key length in bytes
585a913ee7SJerome Forissier @param bits The effective key length in bits
595a913ee7SJerome Forissier @param num_rounds The number of rounds desired (0 for default)
605a913ee7SJerome Forissier @param skey The key in as scheduled by this function.
615a913ee7SJerome Forissier @return CRYPT_OK if successful
625a913ee7SJerome Forissier */
rc2_setup_ex(const unsigned char * key,int keylen,int bits,int num_rounds,symmetric_key * skey)635a913ee7SJerome Forissier int rc2_setup_ex(const unsigned char *key, int keylen, int bits, int num_rounds, symmetric_key *skey)
645a913ee7SJerome Forissier {
655a913ee7SJerome Forissier unsigned *xkey = skey->rc2.xkey;
665a913ee7SJerome Forissier unsigned char tmp[128];
675a913ee7SJerome Forissier unsigned T8, TM;
685a913ee7SJerome Forissier int i;
695a913ee7SJerome Forissier
705a913ee7SJerome Forissier LTC_ARGCHK(key != NULL);
715a913ee7SJerome Forissier LTC_ARGCHK(skey != NULL);
725a913ee7SJerome Forissier
735a913ee7SJerome Forissier if (keylen == 0 || keylen > 128 || bits > 1024) {
745a913ee7SJerome Forissier return CRYPT_INVALID_KEYSIZE;
755a913ee7SJerome Forissier }
765a913ee7SJerome Forissier if (bits == 0) {
775a913ee7SJerome Forissier bits = 1024;
785a913ee7SJerome Forissier }
795a913ee7SJerome Forissier
805a913ee7SJerome Forissier if (num_rounds != 0 && num_rounds != 16) {
815a913ee7SJerome Forissier return CRYPT_INVALID_ROUNDS;
825a913ee7SJerome Forissier }
835a913ee7SJerome Forissier
845a913ee7SJerome Forissier for (i = 0; i < keylen; i++) {
855a913ee7SJerome Forissier tmp[i] = key[i] & 255;
865a913ee7SJerome Forissier }
875a913ee7SJerome Forissier
885a913ee7SJerome Forissier /* Phase 1: Expand input key to 128 bytes */
895a913ee7SJerome Forissier if (keylen < 128) {
905a913ee7SJerome Forissier for (i = keylen; i < 128; i++) {
915a913ee7SJerome Forissier tmp[i] = permute[(tmp[i - 1] + tmp[i - keylen]) & 255];
925a913ee7SJerome Forissier }
935a913ee7SJerome Forissier }
945a913ee7SJerome Forissier
955a913ee7SJerome Forissier /* Phase 2 - reduce effective key size to "bits" */
965a913ee7SJerome Forissier T8 = (unsigned)(bits+7)>>3;
975a913ee7SJerome Forissier TM = (255 >> (unsigned)(7 & -bits));
985a913ee7SJerome Forissier tmp[128 - T8] = permute[tmp[128 - T8] & TM];
995a913ee7SJerome Forissier for (i = 127 - T8; i >= 0; i--) {
1005a913ee7SJerome Forissier tmp[i] = permute[tmp[i + 1] ^ tmp[i + T8]];
1015a913ee7SJerome Forissier }
1025a913ee7SJerome Forissier
1035a913ee7SJerome Forissier /* Phase 3 - copy to xkey in little-endian order */
1045a913ee7SJerome Forissier for (i = 0; i < 64; i++) {
1055a913ee7SJerome Forissier xkey[i] = (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8);
1065a913ee7SJerome Forissier }
1075a913ee7SJerome Forissier
1085a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
1095a913ee7SJerome Forissier zeromem(tmp, sizeof(tmp));
1105a913ee7SJerome Forissier #endif
1115a913ee7SJerome Forissier
1125a913ee7SJerome Forissier return CRYPT_OK;
1135a913ee7SJerome Forissier }
1145a913ee7SJerome Forissier
1155a913ee7SJerome Forissier /**
1165a913ee7SJerome Forissier Initialize the RC2 block cipher
1175a913ee7SJerome Forissier
1185a913ee7SJerome Forissier The effective key length is here always keylen * 8
1195a913ee7SJerome Forissier
1205a913ee7SJerome Forissier @param key The symmetric key you wish to pass
1215a913ee7SJerome Forissier @param keylen The key length in bytes
1225a913ee7SJerome Forissier @param num_rounds The number of rounds desired (0 for default)
1235a913ee7SJerome Forissier @param skey The key in as scheduled by this function.
1245a913ee7SJerome Forissier @return CRYPT_OK if successful
1255a913ee7SJerome Forissier */
rc2_setup(const unsigned char * key,int keylen,int num_rounds,symmetric_key * skey)1265a913ee7SJerome Forissier int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
1275a913ee7SJerome Forissier {
1285a913ee7SJerome Forissier return rc2_setup_ex(key, keylen, keylen * 8, num_rounds, skey);
1295a913ee7SJerome Forissier }
1305a913ee7SJerome Forissier
1315a913ee7SJerome Forissier /**********************************************************************\
1325a913ee7SJerome Forissier * Encrypt an 8-byte block of plaintext using the given key. *
1335a913ee7SJerome Forissier \**********************************************************************/
1345a913ee7SJerome Forissier /**
1355a913ee7SJerome Forissier Encrypts a block of text with RC2
1365a913ee7SJerome Forissier @param pt The input plaintext (8 bytes)
1375a913ee7SJerome Forissier @param ct The output ciphertext (8 bytes)
1385a913ee7SJerome Forissier @param skey The key as scheduled
1395a913ee7SJerome Forissier @return CRYPT_OK if successful
1405a913ee7SJerome Forissier */
1415a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
s_rc2_ecb_encrypt(const unsigned char * pt,unsigned char * ct,const symmetric_key * skey)142*8411e6adSJerome Forissier static int s_rc2_ecb_encrypt( const unsigned char *pt,
1435a913ee7SJerome Forissier unsigned char *ct,
1445a913ee7SJerome Forissier const symmetric_key *skey)
1455a913ee7SJerome Forissier #else
1465a913ee7SJerome Forissier int rc2_ecb_encrypt( const unsigned char *pt,
1475a913ee7SJerome Forissier unsigned char *ct,
1485a913ee7SJerome Forissier const symmetric_key *skey)
1495a913ee7SJerome Forissier #endif
1505a913ee7SJerome Forissier {
1515a913ee7SJerome Forissier const unsigned *xkey;
1525a913ee7SJerome Forissier unsigned x76, x54, x32, x10, i;
1535a913ee7SJerome Forissier
1545a913ee7SJerome Forissier LTC_ARGCHK(pt != NULL);
1555a913ee7SJerome Forissier LTC_ARGCHK(ct != NULL);
1565a913ee7SJerome Forissier LTC_ARGCHK(skey != NULL);
1575a913ee7SJerome Forissier
1585a913ee7SJerome Forissier xkey = skey->rc2.xkey;
1595a913ee7SJerome Forissier
1605a913ee7SJerome Forissier x76 = ((unsigned)pt[7] << 8) + (unsigned)pt[6];
1615a913ee7SJerome Forissier x54 = ((unsigned)pt[5] << 8) + (unsigned)pt[4];
1625a913ee7SJerome Forissier x32 = ((unsigned)pt[3] << 8) + (unsigned)pt[2];
1635a913ee7SJerome Forissier x10 = ((unsigned)pt[1] << 8) + (unsigned)pt[0];
1645a913ee7SJerome Forissier
1655a913ee7SJerome Forissier for (i = 0; i < 16; i++) {
1665a913ee7SJerome Forissier x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF;
1675a913ee7SJerome Forissier x10 = ((x10 << 1) | (x10 >> 15));
1685a913ee7SJerome Forissier
1695a913ee7SJerome Forissier x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF;
1705a913ee7SJerome Forissier x32 = ((x32 << 2) | (x32 >> 14));
1715a913ee7SJerome Forissier
1725a913ee7SJerome Forissier x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF;
1735a913ee7SJerome Forissier x54 = ((x54 << 3) | (x54 >> 13));
1745a913ee7SJerome Forissier
1755a913ee7SJerome Forissier x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF;
1765a913ee7SJerome Forissier x76 = ((x76 << 5) | (x76 >> 11));
1775a913ee7SJerome Forissier
1785a913ee7SJerome Forissier if (i == 4 || i == 10) {
1795a913ee7SJerome Forissier x10 = (x10 + xkey[x76 & 63]) & 0xFFFF;
1805a913ee7SJerome Forissier x32 = (x32 + xkey[x10 & 63]) & 0xFFFF;
1815a913ee7SJerome Forissier x54 = (x54 + xkey[x32 & 63]) & 0xFFFF;
1825a913ee7SJerome Forissier x76 = (x76 + xkey[x54 & 63]) & 0xFFFF;
1835a913ee7SJerome Forissier }
1845a913ee7SJerome Forissier }
1855a913ee7SJerome Forissier
1865a913ee7SJerome Forissier ct[0] = (unsigned char)x10;
1875a913ee7SJerome Forissier ct[1] = (unsigned char)(x10 >> 8);
1885a913ee7SJerome Forissier ct[2] = (unsigned char)x32;
1895a913ee7SJerome Forissier ct[3] = (unsigned char)(x32 >> 8);
1905a913ee7SJerome Forissier ct[4] = (unsigned char)x54;
1915a913ee7SJerome Forissier ct[5] = (unsigned char)(x54 >> 8);
1925a913ee7SJerome Forissier ct[6] = (unsigned char)x76;
1935a913ee7SJerome Forissier ct[7] = (unsigned char)(x76 >> 8);
1945a913ee7SJerome Forissier
1955a913ee7SJerome Forissier return CRYPT_OK;
1965a913ee7SJerome Forissier }
1975a913ee7SJerome Forissier
1985a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
rc2_ecb_encrypt(const unsigned char * pt,unsigned char * ct,const symmetric_key * skey)1995a913ee7SJerome Forissier int rc2_ecb_encrypt( const unsigned char *pt,
2005a913ee7SJerome Forissier unsigned char *ct,
2015a913ee7SJerome Forissier const symmetric_key *skey)
2025a913ee7SJerome Forissier {
203*8411e6adSJerome Forissier int err = s_rc2_ecb_encrypt(pt, ct, skey);
2045a913ee7SJerome Forissier burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5);
2055a913ee7SJerome Forissier return err;
2065a913ee7SJerome Forissier }
2075a913ee7SJerome Forissier #endif
2085a913ee7SJerome Forissier
2095a913ee7SJerome Forissier /**********************************************************************\
2105a913ee7SJerome Forissier * Decrypt an 8-byte block of ciphertext using the given key. *
2115a913ee7SJerome Forissier \**********************************************************************/
2125a913ee7SJerome Forissier /**
2135a913ee7SJerome Forissier Decrypts a block of text with RC2
2145a913ee7SJerome Forissier @param ct The input ciphertext (8 bytes)
2155a913ee7SJerome Forissier @param pt The output plaintext (8 bytes)
2165a913ee7SJerome Forissier @param skey The key as scheduled
2175a913ee7SJerome Forissier @return CRYPT_OK if successful
2185a913ee7SJerome Forissier */
2195a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
s_rc2_ecb_decrypt(const unsigned char * ct,unsigned char * pt,const symmetric_key * skey)220*8411e6adSJerome Forissier static int s_rc2_ecb_decrypt( const unsigned char *ct,
2215a913ee7SJerome Forissier unsigned char *pt,
2225a913ee7SJerome Forissier const symmetric_key *skey)
2235a913ee7SJerome Forissier #else
2245a913ee7SJerome Forissier int rc2_ecb_decrypt( const unsigned char *ct,
2255a913ee7SJerome Forissier unsigned char *pt,
2265a913ee7SJerome Forissier const symmetric_key *skey)
2275a913ee7SJerome Forissier #endif
2285a913ee7SJerome Forissier {
2295a913ee7SJerome Forissier unsigned x76, x54, x32, x10;
2305a913ee7SJerome Forissier const unsigned *xkey;
2315a913ee7SJerome Forissier int i;
2325a913ee7SJerome Forissier
2335a913ee7SJerome Forissier LTC_ARGCHK(pt != NULL);
2345a913ee7SJerome Forissier LTC_ARGCHK(ct != NULL);
2355a913ee7SJerome Forissier LTC_ARGCHK(skey != NULL);
2365a913ee7SJerome Forissier
2375a913ee7SJerome Forissier xkey = skey->rc2.xkey;
2385a913ee7SJerome Forissier
2395a913ee7SJerome Forissier x76 = ((unsigned)ct[7] << 8) + (unsigned)ct[6];
2405a913ee7SJerome Forissier x54 = ((unsigned)ct[5] << 8) + (unsigned)ct[4];
2415a913ee7SJerome Forissier x32 = ((unsigned)ct[3] << 8) + (unsigned)ct[2];
2425a913ee7SJerome Forissier x10 = ((unsigned)ct[1] << 8) + (unsigned)ct[0];
2435a913ee7SJerome Forissier
2445a913ee7SJerome Forissier for (i = 15; i >= 0; i--) {
2455a913ee7SJerome Forissier if (i == 4 || i == 10) {
2465a913ee7SJerome Forissier x76 = (x76 - xkey[x54 & 63]) & 0xFFFF;
2475a913ee7SJerome Forissier x54 = (x54 - xkey[x32 & 63]) & 0xFFFF;
2485a913ee7SJerome Forissier x32 = (x32 - xkey[x10 & 63]) & 0xFFFF;
2495a913ee7SJerome Forissier x10 = (x10 - xkey[x76 & 63]) & 0xFFFF;
2505a913ee7SJerome Forissier }
2515a913ee7SJerome Forissier
2525a913ee7SJerome Forissier x76 = ((x76 << 11) | (x76 >> 5));
2535a913ee7SJerome Forissier x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF;
2545a913ee7SJerome Forissier
2555a913ee7SJerome Forissier x54 = ((x54 << 13) | (x54 >> 3));
2565a913ee7SJerome Forissier x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF;
2575a913ee7SJerome Forissier
2585a913ee7SJerome Forissier x32 = ((x32 << 14) | (x32 >> 2));
2595a913ee7SJerome Forissier x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF;
2605a913ee7SJerome Forissier
2615a913ee7SJerome Forissier x10 = ((x10 << 15) | (x10 >> 1));
2625a913ee7SJerome Forissier x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF;
2635a913ee7SJerome Forissier }
2645a913ee7SJerome Forissier
2655a913ee7SJerome Forissier pt[0] = (unsigned char)x10;
2665a913ee7SJerome Forissier pt[1] = (unsigned char)(x10 >> 8);
2675a913ee7SJerome Forissier pt[2] = (unsigned char)x32;
2685a913ee7SJerome Forissier pt[3] = (unsigned char)(x32 >> 8);
2695a913ee7SJerome Forissier pt[4] = (unsigned char)x54;
2705a913ee7SJerome Forissier pt[5] = (unsigned char)(x54 >> 8);
2715a913ee7SJerome Forissier pt[6] = (unsigned char)x76;
2725a913ee7SJerome Forissier pt[7] = (unsigned char)(x76 >> 8);
2735a913ee7SJerome Forissier
2745a913ee7SJerome Forissier return CRYPT_OK;
2755a913ee7SJerome Forissier }
2765a913ee7SJerome Forissier
2775a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
rc2_ecb_decrypt(const unsigned char * ct,unsigned char * pt,const symmetric_key * skey)2785a913ee7SJerome Forissier int rc2_ecb_decrypt( const unsigned char *ct,
2795a913ee7SJerome Forissier unsigned char *pt,
2805a913ee7SJerome Forissier const symmetric_key *skey)
2815a913ee7SJerome Forissier {
282*8411e6adSJerome Forissier int err = s_rc2_ecb_decrypt(ct, pt, skey);
2835a913ee7SJerome Forissier burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int));
2845a913ee7SJerome Forissier return err;
2855a913ee7SJerome Forissier }
2865a913ee7SJerome Forissier #endif
2875a913ee7SJerome Forissier
2885a913ee7SJerome Forissier /**
2895a913ee7SJerome Forissier Performs a self-test of the RC2 block cipher
2905a913ee7SJerome Forissier @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
2915a913ee7SJerome Forissier */
rc2_test(void)2925a913ee7SJerome Forissier int rc2_test(void)
2935a913ee7SJerome Forissier {
2945a913ee7SJerome Forissier #ifndef LTC_TEST
2955a913ee7SJerome Forissier return CRYPT_NOP;
2965a913ee7SJerome Forissier #else
2975a913ee7SJerome Forissier static const struct {
2985a913ee7SJerome Forissier int keylen, bits;
2995a913ee7SJerome Forissier unsigned char key[16], pt[8], ct[8];
3005a913ee7SJerome Forissier } tests[] = {
3015a913ee7SJerome Forissier
3025a913ee7SJerome Forissier { 8, 63,
3035a913ee7SJerome Forissier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3045a913ee7SJerome Forissier 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3055a913ee7SJerome Forissier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3065a913ee7SJerome Forissier { 0xeb, 0xb7, 0x73, 0xf9, 0x93, 0x27, 0x8e, 0xff }
3075a913ee7SJerome Forissier },
3085a913ee7SJerome Forissier { 8, 64,
3095a913ee7SJerome Forissier { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
3105a913ee7SJerome Forissier 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3115a913ee7SJerome Forissier { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
3125a913ee7SJerome Forissier { 0x27, 0x8b, 0x27, 0xe4, 0x2e, 0x2f, 0x0d, 0x49 }
3135a913ee7SJerome Forissier },
3145a913ee7SJerome Forissier { 8, 64,
3155a913ee7SJerome Forissier { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3165a913ee7SJerome Forissier 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3175a913ee7SJerome Forissier { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
3185a913ee7SJerome Forissier { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 }
3195a913ee7SJerome Forissier },
3205a913ee7SJerome Forissier { 1, 64,
3215a913ee7SJerome Forissier { 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3225a913ee7SJerome Forissier 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3235a913ee7SJerome Forissier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3245a913ee7SJerome Forissier { 0x61, 0xa8, 0xa2, 0x44, 0xad, 0xac, 0xcc, 0xf0 }
3255a913ee7SJerome Forissier },
3265a913ee7SJerome Forissier { 7, 64,
3275a913ee7SJerome Forissier { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x00,
3285a913ee7SJerome Forissier 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3295a913ee7SJerome Forissier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3305a913ee7SJerome Forissier { 0x6c, 0xcf, 0x43, 0x08, 0x97, 0x4c, 0x26, 0x7f }
3315a913ee7SJerome Forissier },
3325a913ee7SJerome Forissier { 16, 64,
3335a913ee7SJerome Forissier { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f,
3345a913ee7SJerome Forissier 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 },
3355a913ee7SJerome Forissier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3365a913ee7SJerome Forissier { 0x1a, 0x80, 0x7d, 0x27, 0x2b, 0xbe, 0x5d, 0xb1 }
3375a913ee7SJerome Forissier },
3385a913ee7SJerome Forissier { 16, 128,
3395a913ee7SJerome Forissier { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f,
3405a913ee7SJerome Forissier 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 },
3415a913ee7SJerome Forissier { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
3425a913ee7SJerome Forissier { 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 }
3435a913ee7SJerome Forissier }
3445a913ee7SJerome Forissier };
3455a913ee7SJerome Forissier int x, y, err;
3465a913ee7SJerome Forissier symmetric_key skey;
3475a913ee7SJerome Forissier unsigned char tmp[2][8];
3485a913ee7SJerome Forissier
3495a913ee7SJerome Forissier for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
3505a913ee7SJerome Forissier zeromem(tmp, sizeof(tmp));
3515a913ee7SJerome Forissier if (tests[x].bits == (tests[x].keylen * 8)) {
3525a913ee7SJerome Forissier if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) {
3535a913ee7SJerome Forissier return err;
3545a913ee7SJerome Forissier }
3555a913ee7SJerome Forissier }
3565a913ee7SJerome Forissier else {
3575a913ee7SJerome Forissier if ((err = rc2_setup_ex(tests[x].key, tests[x].keylen, tests[x].bits, 0, &skey)) != CRYPT_OK) {
3585a913ee7SJerome Forissier return err;
3595a913ee7SJerome Forissier }
3605a913ee7SJerome Forissier }
3615a913ee7SJerome Forissier
3625a913ee7SJerome Forissier rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey);
3635a913ee7SJerome Forissier rc2_ecb_decrypt(tmp[0], tmp[1], &skey);
3645a913ee7SJerome Forissier
3655a913ee7SJerome Forissier if (compare_testvector(tmp[0], 8, tests[x].ct, 8, "RC2 CT", x) ||
3665a913ee7SJerome Forissier compare_testvector(tmp[1], 8, tests[x].pt, 8, "RC2 PT", x)) {
3675a913ee7SJerome Forissier return CRYPT_FAIL_TESTVECTOR;
3685a913ee7SJerome Forissier }
3695a913ee7SJerome Forissier
3705a913ee7SJerome Forissier /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
3715a913ee7SJerome Forissier for (y = 0; y < 8; y++) tmp[0][y] = 0;
3725a913ee7SJerome Forissier for (y = 0; y < 1000; y++) rc2_ecb_encrypt(tmp[0], tmp[0], &skey);
3735a913ee7SJerome Forissier for (y = 0; y < 1000; y++) rc2_ecb_decrypt(tmp[0], tmp[0], &skey);
3745a913ee7SJerome Forissier for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
3755a913ee7SJerome Forissier }
3765a913ee7SJerome Forissier return CRYPT_OK;
3775a913ee7SJerome Forissier #endif
3785a913ee7SJerome Forissier }
3795a913ee7SJerome Forissier
3805a913ee7SJerome Forissier /** Terminate the context
3815a913ee7SJerome Forissier @param skey The scheduled key
3825a913ee7SJerome Forissier */
rc2_done(symmetric_key * skey)3835a913ee7SJerome Forissier void rc2_done(symmetric_key *skey)
3845a913ee7SJerome Forissier {
3855a913ee7SJerome Forissier LTC_UNUSED_PARAM(skey);
3865a913ee7SJerome Forissier }
3875a913ee7SJerome Forissier
3885a913ee7SJerome Forissier /**
3895a913ee7SJerome Forissier Gets suitable key size
3905a913ee7SJerome Forissier @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
3915a913ee7SJerome Forissier @return CRYPT_OK if the input key size is acceptable.
3925a913ee7SJerome Forissier */
rc2_keysize(int * keysize)3935a913ee7SJerome Forissier int rc2_keysize(int *keysize)
3945a913ee7SJerome Forissier {
3955a913ee7SJerome Forissier LTC_ARGCHK(keysize != NULL);
3965a913ee7SJerome Forissier if (*keysize < 1) {
3975a913ee7SJerome Forissier return CRYPT_INVALID_KEYSIZE;
3985a913ee7SJerome Forissier }
3995a913ee7SJerome Forissier if (*keysize > 128) {
4005a913ee7SJerome Forissier *keysize = 128;
4015a913ee7SJerome Forissier }
4025a913ee7SJerome Forissier return CRYPT_OK;
4035a913ee7SJerome Forissier }
4045a913ee7SJerome Forissier
4055a913ee7SJerome Forissier #endif
4065a913ee7SJerome Forissier
4075a913ee7SJerome Forissier
4085a913ee7SJerome Forissier
409