xref: /optee_os/core/lib/libtomcrypt/src/ciphers/rc6.c (revision 8411e6ad673d20c4742ed30c785e3f5cdea54dfa)
1*8411e6adSJerome Forissier /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2*8411e6adSJerome Forissier /* SPDX-License-Identifier: Unlicense */
35a913ee7SJerome Forissier 
45a913ee7SJerome Forissier /**
55a913ee7SJerome Forissier    @file rc6.c
65a913ee7SJerome Forissier    LTC_RC6 code by Tom St Denis
75a913ee7SJerome Forissier */
85a913ee7SJerome Forissier #include "tomcrypt_private.h"
95a913ee7SJerome Forissier 
105a913ee7SJerome Forissier #ifdef LTC_RC6
115a913ee7SJerome Forissier 
125a913ee7SJerome Forissier const struct ltc_cipher_descriptor rc6_desc =
135a913ee7SJerome Forissier {
145a913ee7SJerome Forissier     "rc6",
155a913ee7SJerome Forissier     3,
165a913ee7SJerome Forissier     8, 128, 16, 20,
175a913ee7SJerome Forissier     &rc6_setup,
185a913ee7SJerome Forissier     &rc6_ecb_encrypt,
195a913ee7SJerome Forissier     &rc6_ecb_decrypt,
205a913ee7SJerome Forissier     &rc6_test,
215a913ee7SJerome Forissier     &rc6_done,
225a913ee7SJerome Forissier     &rc6_keysize,
235a913ee7SJerome Forissier     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
245a913ee7SJerome Forissier };
255a913ee7SJerome Forissier 
265a913ee7SJerome Forissier static const ulong32 stab[44] = {
275a913ee7SJerome Forissier 0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL,
285a913ee7SJerome Forissier 0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL,
295a913ee7SJerome Forissier 0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL,
305a913ee7SJerome Forissier 0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL,
315a913ee7SJerome Forissier 0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL,
325a913ee7SJerome Forissier 0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL };
335a913ee7SJerome Forissier 
345a913ee7SJerome Forissier  /**
355a913ee7SJerome Forissier     Initialize the LTC_RC6 block cipher
365a913ee7SJerome Forissier     @param key The symmetric key you wish to pass
375a913ee7SJerome Forissier     @param keylen The key length in bytes
385a913ee7SJerome Forissier     @param num_rounds The number of rounds desired (0 for default)
395a913ee7SJerome Forissier     @param skey The key in as scheduled by this function.
405a913ee7SJerome Forissier     @return CRYPT_OK if successful
415a913ee7SJerome Forissier  */
425a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
s_rc6_setup(const unsigned char * key,int keylen,int num_rounds,symmetric_key * skey)43*8411e6adSJerome Forissier static int s_rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
445a913ee7SJerome Forissier #else
455a913ee7SJerome Forissier int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
465a913ee7SJerome Forissier #endif
475a913ee7SJerome Forissier {
485a913ee7SJerome Forissier     ulong32 L[64], S[50], A, B, i, j, v, s, l;
495a913ee7SJerome Forissier 
505a913ee7SJerome Forissier     LTC_ARGCHK(key != NULL);
515a913ee7SJerome Forissier     LTC_ARGCHK(skey != NULL);
525a913ee7SJerome Forissier 
535a913ee7SJerome Forissier     /* test parameters */
545a913ee7SJerome Forissier     if (num_rounds != 0 && num_rounds != 20) {
555a913ee7SJerome Forissier        return CRYPT_INVALID_ROUNDS;
565a913ee7SJerome Forissier     }
575a913ee7SJerome Forissier 
585a913ee7SJerome Forissier     /* key must be between 64 and 1024 bits */
595a913ee7SJerome Forissier     if (keylen < 8 || keylen > 128) {
605a913ee7SJerome Forissier        return CRYPT_INVALID_KEYSIZE;
615a913ee7SJerome Forissier     }
625a913ee7SJerome Forissier 
635a913ee7SJerome Forissier     /* copy the key into the L array */
645a913ee7SJerome Forissier     for (A = i = j = 0; i < (ulong32)keylen; ) {
655a913ee7SJerome Forissier         A = (A << 8) | ((ulong32)(key[i++] & 255));
665a913ee7SJerome Forissier         if (!(i & 3)) {
675a913ee7SJerome Forissier            L[j++] = BSWAP(A);
685a913ee7SJerome Forissier            A = 0;
695a913ee7SJerome Forissier         }
705a913ee7SJerome Forissier     }
715a913ee7SJerome Forissier 
725a913ee7SJerome Forissier     /* handle odd sized keys */
735a913ee7SJerome Forissier     if (keylen & 3) {
745a913ee7SJerome Forissier        A <<= (8 * (4 - (keylen&3)));
755a913ee7SJerome Forissier        L[j++] = BSWAP(A);
765a913ee7SJerome Forissier     }
775a913ee7SJerome Forissier 
785a913ee7SJerome Forissier     /* setup the S array */
795a913ee7SJerome Forissier     XMEMCPY(S, stab, 44 * sizeof(stab[0]));
805a913ee7SJerome Forissier 
815a913ee7SJerome Forissier     /* mix buffer */
825a913ee7SJerome Forissier     s = 3 * MAX(44, j);
835a913ee7SJerome Forissier     l = j;
845a913ee7SJerome Forissier     for (A = B = i = j = v = 0; v < s; v++) {
855a913ee7SJerome Forissier         A = S[i] = ROLc(S[i] + A + B, 3);
865a913ee7SJerome Forissier         B = L[j] = ROL(L[j] + A + B, (A+B));
875a913ee7SJerome Forissier         if (++i == 44) { i = 0; }
885a913ee7SJerome Forissier         if (++j == l)  { j = 0; }
895a913ee7SJerome Forissier     }
905a913ee7SJerome Forissier 
915a913ee7SJerome Forissier     /* copy to key */
925a913ee7SJerome Forissier     for (i = 0; i < 44; i++) {
935a913ee7SJerome Forissier         skey->rc6.K[i] = S[i];
945a913ee7SJerome Forissier     }
955a913ee7SJerome Forissier     return CRYPT_OK;
965a913ee7SJerome Forissier }
975a913ee7SJerome Forissier 
985a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
rc6_setup(const unsigned char * key,int keylen,int num_rounds,symmetric_key * skey)995a913ee7SJerome Forissier int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
1005a913ee7SJerome Forissier {
1015a913ee7SJerome Forissier    int x;
102*8411e6adSJerome Forissier    x = s_rc6_setup(key, keylen, num_rounds, skey);
1035a913ee7SJerome Forissier    burn_stack(sizeof(ulong32) * 122);
1045a913ee7SJerome Forissier    return x;
1055a913ee7SJerome Forissier }
1065a913ee7SJerome Forissier #endif
1075a913ee7SJerome Forissier 
1085a913ee7SJerome Forissier /**
1095a913ee7SJerome Forissier   Encrypts a block of text with LTC_RC6
1105a913ee7SJerome Forissier   @param pt The input plaintext (16 bytes)
1115a913ee7SJerome Forissier   @param ct The output ciphertext (16 bytes)
1125a913ee7SJerome Forissier   @param skey The key as scheduled
1135a913ee7SJerome Forissier */
1145a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
s_rc6_ecb_encrypt(const unsigned char * pt,unsigned char * ct,const symmetric_key * skey)115*8411e6adSJerome Forissier static int s_rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
1165a913ee7SJerome Forissier #else
1175a913ee7SJerome Forissier int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
1185a913ee7SJerome Forissier #endif
1195a913ee7SJerome Forissier {
1205a913ee7SJerome Forissier    ulong32 a,b,c,d,t,u;
1215a913ee7SJerome Forissier    const ulong32 *K;
1225a913ee7SJerome Forissier    int r;
1235a913ee7SJerome Forissier 
1245a913ee7SJerome Forissier    LTC_ARGCHK(skey != NULL);
1255a913ee7SJerome Forissier    LTC_ARGCHK(pt   != NULL);
1265a913ee7SJerome Forissier    LTC_ARGCHK(ct   != NULL);
1275a913ee7SJerome Forissier    LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]);
1285a913ee7SJerome Forissier 
1295a913ee7SJerome Forissier    b += skey->rc6.K[0];
1305a913ee7SJerome Forissier    d += skey->rc6.K[1];
1315a913ee7SJerome Forissier 
1325a913ee7SJerome Forissier #define RND(a,b,c,d) \
1335a913ee7SJerome Forissier        t = (b * (b + b + 1)); t = ROLc(t, 5); \
1345a913ee7SJerome Forissier        u = (d * (d + d + 1)); u = ROLc(u, 5); \
1355a913ee7SJerome Forissier        a = ROL(a^t,u) + K[0];                \
1365a913ee7SJerome Forissier        c = ROL(c^u,t) + K[1]; K += 2;
1375a913ee7SJerome Forissier 
1385a913ee7SJerome Forissier    K = skey->rc6.K + 2;
1395a913ee7SJerome Forissier    for (r = 0; r < 20; r += 4) {
1405a913ee7SJerome Forissier        RND(a,b,c,d);
1415a913ee7SJerome Forissier        RND(b,c,d,a);
1425a913ee7SJerome Forissier        RND(c,d,a,b);
1435a913ee7SJerome Forissier        RND(d,a,b,c);
1445a913ee7SJerome Forissier    }
1455a913ee7SJerome Forissier 
1465a913ee7SJerome Forissier #undef RND
1475a913ee7SJerome Forissier 
1485a913ee7SJerome Forissier    a += skey->rc6.K[42];
1495a913ee7SJerome Forissier    c += skey->rc6.K[43];
1505a913ee7SJerome Forissier    STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]);
1515a913ee7SJerome Forissier    return CRYPT_OK;
1525a913ee7SJerome Forissier }
1535a913ee7SJerome Forissier 
1545a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
rc6_ecb_encrypt(const unsigned char * pt,unsigned char * ct,const symmetric_key * skey)1555a913ee7SJerome Forissier int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
1565a913ee7SJerome Forissier {
157*8411e6adSJerome Forissier    int err = s_rc6_ecb_encrypt(pt, ct, skey);
1585a913ee7SJerome Forissier    burn_stack(sizeof(ulong32) * 6 + sizeof(int));
1595a913ee7SJerome Forissier    return err;
1605a913ee7SJerome Forissier }
1615a913ee7SJerome Forissier #endif
1625a913ee7SJerome Forissier 
1635a913ee7SJerome Forissier /**
1645a913ee7SJerome Forissier   Decrypts a block of text with LTC_RC6
1655a913ee7SJerome Forissier   @param ct The input ciphertext (16 bytes)
1665a913ee7SJerome Forissier   @param pt The output plaintext (16 bytes)
1675a913ee7SJerome Forissier   @param skey The key as scheduled
1685a913ee7SJerome Forissier */
1695a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
s_rc6_ecb_decrypt(const unsigned char * ct,unsigned char * pt,const symmetric_key * skey)170*8411e6adSJerome Forissier static int s_rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
1715a913ee7SJerome Forissier #else
1725a913ee7SJerome Forissier int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
1735a913ee7SJerome Forissier #endif
1745a913ee7SJerome Forissier {
1755a913ee7SJerome Forissier    ulong32 a,b,c,d,t,u;
1765a913ee7SJerome Forissier    const ulong32 *K;
1775a913ee7SJerome Forissier    int r;
1785a913ee7SJerome Forissier 
1795a913ee7SJerome Forissier    LTC_ARGCHK(skey != NULL);
1805a913ee7SJerome Forissier    LTC_ARGCHK(pt   != NULL);
1815a913ee7SJerome Forissier    LTC_ARGCHK(ct   != NULL);
1825a913ee7SJerome Forissier 
1835a913ee7SJerome Forissier    LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]);
1845a913ee7SJerome Forissier    a -= skey->rc6.K[42];
1855a913ee7SJerome Forissier    c -= skey->rc6.K[43];
1865a913ee7SJerome Forissier 
1875a913ee7SJerome Forissier #define RND(a,b,c,d) \
1885a913ee7SJerome Forissier        t = (b * (b + b + 1)); t = ROLc(t, 5); \
1895a913ee7SJerome Forissier        u = (d * (d + d + 1)); u = ROLc(u, 5); \
1905a913ee7SJerome Forissier        c = ROR(c - K[1], t) ^ u; \
1915a913ee7SJerome Forissier        a = ROR(a - K[0], u) ^ t; K -= 2;
1925a913ee7SJerome Forissier 
1935a913ee7SJerome Forissier    K = skey->rc6.K + 40;
1945a913ee7SJerome Forissier 
1955a913ee7SJerome Forissier    for (r = 0; r < 20; r += 4) {
1965a913ee7SJerome Forissier        RND(d,a,b,c);
1975a913ee7SJerome Forissier        RND(c,d,a,b);
1985a913ee7SJerome Forissier        RND(b,c,d,a);
1995a913ee7SJerome Forissier        RND(a,b,c,d);
2005a913ee7SJerome Forissier    }
2015a913ee7SJerome Forissier 
2025a913ee7SJerome Forissier #undef RND
2035a913ee7SJerome Forissier 
2045a913ee7SJerome Forissier    b -= skey->rc6.K[0];
2055a913ee7SJerome Forissier    d -= skey->rc6.K[1];
2065a913ee7SJerome Forissier    STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]);
2075a913ee7SJerome Forissier 
2085a913ee7SJerome Forissier    return CRYPT_OK;
2095a913ee7SJerome Forissier }
2105a913ee7SJerome Forissier 
2115a913ee7SJerome Forissier #ifdef LTC_CLEAN_STACK
rc6_ecb_decrypt(const unsigned char * ct,unsigned char * pt,const symmetric_key * skey)2125a913ee7SJerome Forissier int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
2135a913ee7SJerome Forissier {
214*8411e6adSJerome Forissier    int err = s_rc6_ecb_decrypt(ct, pt, skey);
2155a913ee7SJerome Forissier    burn_stack(sizeof(ulong32) * 6 + sizeof(int));
2165a913ee7SJerome Forissier    return err;
2175a913ee7SJerome Forissier }
2185a913ee7SJerome Forissier #endif
2195a913ee7SJerome Forissier 
2205a913ee7SJerome Forissier /**
2215a913ee7SJerome Forissier   Performs a self-test of the LTC_RC6 block cipher
2225a913ee7SJerome Forissier   @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
2235a913ee7SJerome Forissier */
rc6_test(void)2245a913ee7SJerome Forissier int rc6_test(void)
2255a913ee7SJerome Forissier {
2265a913ee7SJerome Forissier  #ifndef LTC_TEST
2275a913ee7SJerome Forissier     return CRYPT_NOP;
2285a913ee7SJerome Forissier  #else
2295a913ee7SJerome Forissier    static const struct {
2305a913ee7SJerome Forissier        int keylen;
2315a913ee7SJerome Forissier        unsigned char key[32], pt[16], ct[16];
2325a913ee7SJerome Forissier    } tests[] = {
2335a913ee7SJerome Forissier    {
2345a913ee7SJerome Forissier        16,
2355a913ee7SJerome Forissier        { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
2365a913ee7SJerome Forissier          0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
2375a913ee7SJerome Forissier          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2385a913ee7SJerome Forissier          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2395a913ee7SJerome Forissier        { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
2405a913ee7SJerome Forissier          0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
2415a913ee7SJerome Forissier        { 0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23,
2425a913ee7SJerome Forissier          0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4, 0x3f, 0x18 }
2435a913ee7SJerome Forissier    },
2445a913ee7SJerome Forissier    {
2455a913ee7SJerome Forissier        24,
2465a913ee7SJerome Forissier        { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
2475a913ee7SJerome Forissier          0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
2485a913ee7SJerome Forissier          0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
2495a913ee7SJerome Forissier          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
2505a913ee7SJerome Forissier        { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
2515a913ee7SJerome Forissier          0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
2525a913ee7SJerome Forissier        { 0x68, 0x83, 0x29, 0xd0, 0x19, 0xe5, 0x05, 0x04,
2535a913ee7SJerome Forissier          0x1e, 0x52, 0xe9, 0x2a, 0xf9, 0x52, 0x91, 0xd4 }
2545a913ee7SJerome Forissier    },
2555a913ee7SJerome Forissier    {
2565a913ee7SJerome Forissier        32,
2575a913ee7SJerome Forissier        { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
2585a913ee7SJerome Forissier          0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
2595a913ee7SJerome Forissier          0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
2605a913ee7SJerome Forissier          0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe },
2615a913ee7SJerome Forissier        { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
2625a913ee7SJerome Forissier          0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
2635a913ee7SJerome Forissier        { 0xc8, 0x24, 0x18, 0x16, 0xf0, 0xd7, 0xe4, 0x89,
2645a913ee7SJerome Forissier          0x20, 0xad, 0x16, 0xa1, 0x67, 0x4e, 0x5d, 0x48 }
2655a913ee7SJerome Forissier    }
2665a913ee7SJerome Forissier    };
2675a913ee7SJerome Forissier    unsigned char tmp[2][16];
2685a913ee7SJerome Forissier    int x, y, err;
2695a913ee7SJerome Forissier    symmetric_key key;
2705a913ee7SJerome Forissier 
2715a913ee7SJerome Forissier    for (x  = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
2725a913ee7SJerome Forissier       /* setup key */
2735a913ee7SJerome Forissier       if ((err = rc6_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) {
2745a913ee7SJerome Forissier          return err;
2755a913ee7SJerome Forissier       }
2765a913ee7SJerome Forissier 
2775a913ee7SJerome Forissier       /* encrypt and decrypt */
2785a913ee7SJerome Forissier       rc6_ecb_encrypt(tests[x].pt, tmp[0], &key);
2795a913ee7SJerome Forissier       rc6_ecb_decrypt(tmp[0], tmp[1], &key);
2805a913ee7SJerome Forissier 
2815a913ee7SJerome Forissier       /* compare */
2825a913ee7SJerome Forissier       if (compare_testvector(tmp[0], 16, tests[x].ct, 16, "RC6 Encrypt", x) ||
2835a913ee7SJerome Forissier             compare_testvector(tmp[1], 16, tests[x].pt, 16, "RC6 Decrypt", x)) {
2845a913ee7SJerome Forissier          return CRYPT_FAIL_TESTVECTOR;
2855a913ee7SJerome Forissier       }
2865a913ee7SJerome Forissier 
2875a913ee7SJerome Forissier       /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
2885a913ee7SJerome Forissier       for (y = 0; y < 16; y++) tmp[0][y] = 0;
2895a913ee7SJerome Forissier       for (y = 0; y < 1000; y++) rc6_ecb_encrypt(tmp[0], tmp[0], &key);
2905a913ee7SJerome Forissier       for (y = 0; y < 1000; y++) rc6_ecb_decrypt(tmp[0], tmp[0], &key);
2915a913ee7SJerome Forissier       for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
2925a913ee7SJerome Forissier    }
2935a913ee7SJerome Forissier    return CRYPT_OK;
2945a913ee7SJerome Forissier   #endif
2955a913ee7SJerome Forissier }
2965a913ee7SJerome Forissier 
2975a913ee7SJerome Forissier /** Terminate the context
2985a913ee7SJerome Forissier    @param skey    The scheduled key
2995a913ee7SJerome Forissier */
rc6_done(symmetric_key * skey)3005a913ee7SJerome Forissier void rc6_done(symmetric_key *skey)
3015a913ee7SJerome Forissier {
3025a913ee7SJerome Forissier   LTC_UNUSED_PARAM(skey);
3035a913ee7SJerome Forissier }
3045a913ee7SJerome Forissier 
3055a913ee7SJerome Forissier /**
3065a913ee7SJerome Forissier   Gets suitable key size
3075a913ee7SJerome Forissier   @param keysize [in/out] The length of the recommended key (in bytes).  This function will store the suitable size back in this variable.
3085a913ee7SJerome Forissier   @return CRYPT_OK if the input key size is acceptable.
3095a913ee7SJerome Forissier */
rc6_keysize(int * keysize)3105a913ee7SJerome Forissier int rc6_keysize(int *keysize)
3115a913ee7SJerome Forissier {
3125a913ee7SJerome Forissier    LTC_ARGCHK(keysize != NULL);
3135a913ee7SJerome Forissier    if (*keysize < 8) {
3145a913ee7SJerome Forissier       return CRYPT_INVALID_KEYSIZE;
3155a913ee7SJerome Forissier    }
3165a913ee7SJerome Forissier    if (*keysize > 128) {
3175a913ee7SJerome Forissier       *keysize = 128;
3185a913ee7SJerome Forissier    }
3195a913ee7SJerome Forissier    return CRYPT_OK;
3205a913ee7SJerome Forissier }
3215a913ee7SJerome Forissier 
3225a913ee7SJerome Forissier #endif /*LTC_RC6*/
3235a913ee7SJerome Forissier 
3245a913ee7SJerome Forissier 
325