"Fossies" - the Fresh Open Source Software Archive

Member "libmcrypt-2.5.8/modules/algorithms/cast-128.c" (19 Jan 2003, 10235 Bytes) of package /linux/privat/old/libmcrypt-2.5.8.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "cast-128.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * $Id: cast-128.c,v 1.12 2003/01/19 17:48:27 nmav Exp $
    3  *
    4  *  CAST-128 in C
    5  *  Written by Steve Reid <sreid@sea-to-sky.net>
    6  *  100% Public Domain - no warranty
    7  *  Released 1997.10.11
    8  */
    9 
   10 /* Adapted to the pike cryptographic toolkit by Niels Möller */
   11 
   12 /* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos 
   13  * All modifications are placed under the license of libmcrypt.
   14  */
   15 
   16 /* $Id: cast-128.c,v 1.12 2003/01/19 17:48:27 nmav Exp $ */
   17 
   18 #include <libdefs.h>
   19 
   20 #include <mcrypt_modules.h>
   21 #include "cast-128.h"
   22 
   23 #define _mcrypt_set_key cast_128_LTX__mcrypt_set_key
   24 #define _mcrypt_encrypt cast_128_LTX__mcrypt_encrypt
   25 #define _mcrypt_decrypt cast_128_LTX__mcrypt_decrypt
   26 #define _mcrypt_get_size cast_128_LTX__mcrypt_get_size
   27 #define _mcrypt_get_block_size cast_128_LTX__mcrypt_get_block_size
   28 #define _is_block_algorithm cast_128_LTX__is_block_algorithm
   29 #define _mcrypt_get_key_size cast_128_LTX__mcrypt_get_key_size
   30 #define _mcrypt_get_supported_key_sizes cast_128_LTX__mcrypt_get_supported_key_sizes
   31 #define _mcrypt_get_algorithms_name cast_128_LTX__mcrypt_get_algorithms_name
   32 #define _mcrypt_self_test cast_128_LTX__mcrypt_self_test
   33 #define _mcrypt_algorithm_version cast_128_LTX__mcrypt_algorithm_version
   34 
   35 #define u8 byte
   36 #define u32 word32
   37 
   38 #include "cast-128_sboxes.h"
   39 
   40 /* Macros to access 8-bit bytes out of a 32-bit word */
   41 #define U8a(x) ( (u8) (x>>24) )
   42 #define U8b(x) ( (u8) ((x>>16)&255) )
   43 #define U8c(x) ( (u8) ((x>>8)&255) )
   44 #define U8d(x) ( (u8) ((x)&255) )
   45 
   46 /* Circular left shift */
   47 #define ROL(x, n) ( ((x)<<(n)) | ((x)>>(32-(n))) )
   48 
   49 /* CAST-128 uses three different round functions */
   50 #define F1(l, r, i) \
   51     t = ROL(key->xkey[i] + r, key->xkey[i+16]); \
   52     l ^= ((cast_sbox1[U8a(t)] ^ cast_sbox2[U8b(t)]) \
   53      - cast_sbox3[U8c(t)]) + cast_sbox4[U8d(t)];
   54 #define F2(l, r, i) \
   55     t = ROL(key->xkey[i] ^ r, key->xkey[i+16]); \
   56     l ^= ((cast_sbox1[U8a(t)] - cast_sbox2[U8b(t)]) \
   57      + cast_sbox3[U8c(t)]) ^ cast_sbox4[U8d(t)];
   58 #define F3(l, r, i) \
   59     t = ROL(key->xkey[i] - r, key->xkey[i+16]); \
   60     l ^= ((cast_sbox1[U8a(t)] + cast_sbox2[U8b(t)]) \
   61      ^ cast_sbox3[U8c(t)]) - cast_sbox4[U8d(t)];
   62 
   63 
   64 /***** Encryption Function *****/
   65 
   66 WIN32DLL_DEFINE void _mcrypt_encrypt(CAST_KEY * key, u8 * block)
   67 {
   68     u32 t, l, r;
   69 
   70     /* Get inblock into l,r */
   71     l = ((u32) block[0] << 24) | ((u32) block[1] << 16)
   72         | ((u32) block[2] << 8) | (u32) block[3];
   73     r = ((u32) block[4] << 24) | ((u32) block[5] << 16)
   74         | ((u32) block[6] << 8) | (u32) block[7];
   75     /* Do the work */
   76     F1(l, r, 0);
   77     F2(r, l, 1);
   78     F3(l, r, 2);
   79     F1(r, l, 3);
   80     F2(l, r, 4);
   81     F3(r, l, 5);
   82     F1(l, r, 6);
   83     F2(r, l, 7);
   84     F3(l, r, 8);
   85     F1(r, l, 9);
   86     F2(l, r, 10);
   87     F3(r, l, 11);
   88     /* Only do full 16 rounds if key length > 80 bits */
   89     if (key->rounds > 12) {
   90         F1(l, r, 12);
   91         F2(r, l, 13);
   92         F3(l, r, 14);
   93         F1(r, l, 15);
   94     }
   95     /* Put l,r into outblock */
   96     block[0] = U8a(r);
   97     block[1] = U8b(r);
   98     block[2] = U8c(r);
   99     block[3] = U8d(r);
  100     block[4] = U8a(l);
  101     block[5] = U8b(l);
  102     block[6] = U8c(l);
  103     block[7] = U8d(l);
  104     /* Wipe clean */
  105     t = l = r = 0;
  106 }
  107 
  108 
  109 /***** Decryption Function *****/
  110 
  111 WIN32DLL_DEFINE void _mcrypt_decrypt(CAST_KEY * key, u8 * block)
  112 {
  113     u32 t, l, r;
  114 
  115     /* Get inblock into l,r */
  116     r = ((u32) block[0] << 24) | ((u32) block[1] << 16)
  117         | ((u32) block[2] << 8) | (u32) block[3];
  118     l = ((u32) block[4] << 24) | ((u32) block[5] << 16)
  119         | ((u32) block[6] << 8) | (u32) block[7];
  120     /* Do the work */
  121     /* Only do full 16 rounds if key length > 80 bits */
  122     if (key->rounds > 12) {
  123         F1(r, l, 15);
  124         F3(l, r, 14);
  125         F2(r, l, 13);
  126         F1(l, r, 12);
  127     }
  128     F3(r, l, 11);
  129     F2(l, r, 10);
  130     F1(r, l, 9);
  131     F3(l, r, 8);
  132     F2(r, l, 7);
  133     F1(l, r, 6);
  134     F3(r, l, 5);
  135     F2(l, r, 4);
  136     F1(r, l, 3);
  137     F3(l, r, 2);
  138     F2(r, l, 1);
  139     F1(l, r, 0);
  140     /* Put l,r into outblock */
  141     block[0] = U8a(l);
  142     block[1] = U8b(l);
  143     block[2] = U8c(l);
  144     block[3] = U8d(l);
  145     block[4] = U8a(r);
  146     block[5] = U8b(r);
  147     block[6] = U8c(r);
  148     block[7] = U8d(r);
  149     /* Wipe clean */
  150     t = l = r = 0;
  151 }
  152 
  153 
  154 /***** Key Schedual *****/
  155 
  156 WIN32DLL_DEFINE
  157     int _mcrypt_set_key(CAST_KEY * key, u8 * rawkey, unsigned keybytes)
  158 {
  159     u32 t[4], z[4], x[4];
  160     unsigned i;
  161 
  162     /* Set number of rounds to 12 or 16, depending on key length */
  163     key->rounds = (keybytes <= CAST_SMALL_KEY)
  164         ? CAST_SMALL_ROUNDS : CAST_FULL_ROUNDS;
  165 
  166 
  167     /* Copy key to workspace x */
  168     for (i = 0; i < 4; i++) {
  169         x[i] = 0;
  170         if ((i * 4 + 0) < keybytes)
  171             x[i] = (u32) rawkey[i * 4 + 0] << 24;
  172         if ((i * 4 + 1) < keybytes)
  173             x[i] |= (u32) rawkey[i * 4 + 1] << 16;
  174         if ((i * 4 + 2) < keybytes)
  175             x[i] |= (u32) rawkey[i * 4 + 2] << 8;
  176         if ((i * 4 + 3) < keybytes)
  177             x[i] |= (u32) rawkey[i * 4 + 3];
  178     }
  179     /* Generate 32 subkeys, four at a time */
  180     for (i = 0; i < 32; i += 4) {
  181         switch (i & 4) {
  182         case 0:
  183             t[0] = z[0] = x[0] ^ cast_sbox5[U8b(x[3])]
  184                 ^ cast_sbox6[U8d(x[3])] ^ cast_sbox7[U8a(x[3])]
  185                 ^ cast_sbox8[U8c(x[3])] ^
  186                 cast_sbox7[U8a(x[2])];
  187             t[1] = z[1] = x[2] ^ cast_sbox5[U8a(z[0])]
  188                 ^ cast_sbox6[U8c(z[0])] ^ cast_sbox7[U8b(z[0])]
  189                 ^ cast_sbox8[U8d(z[0])] ^
  190                 cast_sbox8[U8c(x[2])];
  191             t[2] = z[2] = x[3] ^ cast_sbox5[U8d(z[1])]
  192                 ^ cast_sbox6[U8c(z[1])] ^ cast_sbox7[U8b(z[1])]
  193                 ^ cast_sbox8[U8a(z[1])] ^
  194                 cast_sbox5[U8b(x[2])];
  195             t[3] = z[3] =
  196                 x[1] ^ cast_sbox5[U8c(z[2])] ^
  197                 cast_sbox6[U8b(z[2])] ^ cast_sbox7[U8d(z[2])]
  198                 ^ cast_sbox8[U8a(z[2])] ^
  199                 cast_sbox6[U8d(x[2])];
  200             break;
  201         case 4:
  202             t[0] = x[0] = z[2] ^ cast_sbox5[U8b(z[1])]
  203                 ^ cast_sbox6[U8d(z[1])] ^ cast_sbox7[U8a(z[1])]
  204                 ^ cast_sbox8[U8c(z[1])] ^
  205                 cast_sbox7[U8a(z[0])];
  206             t[1] = x[1] = z[0] ^ cast_sbox5[U8a(x[0])]
  207                 ^ cast_sbox6[U8c(x[0])] ^ cast_sbox7[U8b(x[0])]
  208                 ^ cast_sbox8[U8d(x[0])] ^
  209                 cast_sbox8[U8c(z[0])];
  210             t[2] = x[2] = z[1] ^ cast_sbox5[U8d(x[1])]
  211                 ^ cast_sbox6[U8c(x[1])] ^ cast_sbox7[U8b(x[1])]
  212                 ^ cast_sbox8[U8a(x[1])] ^
  213                 cast_sbox5[U8b(z[0])];
  214             t[3] = x[3] = z[3] ^ cast_sbox5[U8c(x[2])]
  215                 ^ cast_sbox6[U8b(x[2])] ^ cast_sbox7[U8d(x[2])]
  216                 ^ cast_sbox8[U8a(x[2])] ^
  217                 cast_sbox6[U8d(z[0])];
  218             break;
  219         }
  220         switch (i & 12) {
  221         case 0:
  222         case 12:
  223             key->xkey[i + 0] =
  224                 cast_sbox5[U8a(t[2])] ^ cast_sbox6[U8b(t[2])]
  225                 ^ cast_sbox7[U8d(t[1])] ^
  226                 cast_sbox8[U8c(t[1])];
  227             key->xkey[i + 1] =
  228                 cast_sbox5[U8c(t[2])] ^ cast_sbox6[U8d(t[2])]
  229                 ^ cast_sbox7[U8b(t[1])] ^
  230                 cast_sbox8[U8a(t[1])];
  231             key->xkey[i + 2] =
  232                 cast_sbox5[U8a(t[3])] ^ cast_sbox6[U8b(t[3])]
  233                 ^ cast_sbox7[U8d(t[0])] ^
  234                 cast_sbox8[U8c(t[0])];
  235             key->xkey[i + 3] =
  236                 cast_sbox5[U8c(t[3])] ^ cast_sbox6[U8d(t[3])]
  237                 ^ cast_sbox7[U8b(t[0])] ^
  238                 cast_sbox8[U8a(t[0])];
  239             break;
  240         case 4:
  241         case 8:
  242             key->xkey[i + 0] =
  243                 cast_sbox5[U8d(t[0])] ^ cast_sbox6[U8c(t[0])]
  244                 ^ cast_sbox7[U8a(t[3])] ^
  245                 cast_sbox8[U8b(t[3])];
  246             key->xkey[i + 1] =
  247                 cast_sbox5[U8b(t[0])] ^ cast_sbox6[U8a(t[0])]
  248                 ^ cast_sbox7[U8c(t[3])] ^
  249                 cast_sbox8[U8d(t[3])];
  250             key->xkey[i + 2] =
  251                 cast_sbox5[U8d(t[1])] ^ cast_sbox6[U8c(t[1])]
  252                 ^ cast_sbox7[U8a(t[2])] ^
  253                 cast_sbox8[U8b(t[2])];
  254             key->xkey[i + 3] =
  255                 cast_sbox5[U8b(t[1])] ^ cast_sbox6[U8a(t[1])]
  256                 ^ cast_sbox7[U8c(t[2])] ^
  257                 cast_sbox8[U8d(t[2])];
  258             break;
  259         }
  260         switch (i & 12) {
  261         case 0:
  262             key->xkey[i + 0] ^= cast_sbox5[U8c(z[0])];
  263             key->xkey[i + 1] ^= cast_sbox6[U8c(z[1])];
  264             key->xkey[i + 2] ^= cast_sbox7[U8b(z[2])];
  265             key->xkey[i + 3] ^= cast_sbox8[U8a(z[3])];
  266             break;
  267         case 4:
  268             key->xkey[i + 0] ^= cast_sbox5[U8a(x[2])];
  269             key->xkey[i + 1] ^= cast_sbox6[U8b(x[3])];
  270             key->xkey[i + 2] ^= cast_sbox7[U8d(x[0])];
  271             key->xkey[i + 3] ^= cast_sbox8[U8d(x[1])];
  272             break;
  273         case 8:
  274             key->xkey[i + 0] ^= cast_sbox5[U8b(z[2])];
  275             key->xkey[i + 1] ^= cast_sbox6[U8a(z[3])];
  276             key->xkey[i + 2] ^= cast_sbox7[U8c(z[0])];
  277             key->xkey[i + 3] ^= cast_sbox8[U8c(z[1])];
  278             break;
  279         case 12:
  280             key->xkey[i + 0] ^= cast_sbox5[U8d(x[0])];
  281             key->xkey[i + 1] ^= cast_sbox6[U8d(x[1])];
  282             key->xkey[i + 2] ^= cast_sbox7[U8a(x[2])];
  283             key->xkey[i + 3] ^= cast_sbox8[U8b(x[3])];
  284             break;
  285         }
  286         if (i >= 16) {
  287             key->xkey[i + 0] &= 31;
  288             key->xkey[i + 1] &= 31;
  289             key->xkey[i + 2] &= 31;
  290             key->xkey[i + 3] &= 31;
  291         }
  292     }
  293     /* Wipe clean */
  294     for (i = 0; i < 4; i++) {
  295         t[i] = x[i] = z[i] = 0;
  296     }
  297     return 0;
  298 }
  299 
  300 /* Made in Canada */
  301 
  302 
  303 WIN32DLL_DEFINE int _mcrypt_get_size()
  304 {
  305     return sizeof(CAST_KEY);
  306 }
  307 WIN32DLL_DEFINE int _mcrypt_get_block_size()
  308 {
  309     return 8;
  310 }
  311 WIN32DLL_DEFINE int _is_block_algorithm()
  312 {
  313     return 1;
  314 }
  315 WIN32DLL_DEFINE int _mcrypt_get_key_size()
  316 {
  317     return 16;
  318 }
  319 
  320 static const int key_sizes[] = { 16 };
  321 WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
  322 {
  323     *len = sizeof(key_sizes)/sizeof(int);
  324     return key_sizes;
  325 
  326 }
  327 
  328 WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
  329 {
  330 return "CAST-128";
  331 }
  332 
  333 #define CIPHER "434e25460c8c9525"
  334 
  335 WIN32DLL_DEFINE int _mcrypt_self_test()
  336 {
  337     char *keyword;
  338     unsigned char plaintext[16];
  339     unsigned char ciphertext[16];
  340     int blocksize = _mcrypt_get_block_size(), j;
  341     void *key;
  342     unsigned char cipher_tmp[200];
  343 
  344     keyword = calloc(1, _mcrypt_get_key_size());
  345     if (keyword == NULL)
  346         return -1;
  347 
  348     for (j = 0; j < _mcrypt_get_key_size(); j++) {
  349         keyword[j] = ((j * 2 + 10) % 256);
  350     }
  351 
  352     for (j = 0; j < blocksize; j++) {
  353         plaintext[j] = j % 256;
  354     }
  355     key = malloc(_mcrypt_get_size());
  356     if (key == NULL)
  357         return -1;
  358 
  359     memcpy(ciphertext, plaintext, blocksize);
  360 
  361     _mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
  362     free(keyword);
  363     _mcrypt_encrypt(key, (void *) ciphertext);
  364 
  365     for (j = 0; j < blocksize; j++) {
  366         sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
  367             ciphertext[j]);
  368     }
  369 
  370     if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
  371         printf("failed compatibility\n");
  372         printf("Expected: %s\nGot: %s\n", CIPHER,
  373                (char *) cipher_tmp);
  374         free(key);
  375         return -1;
  376     }
  377     _mcrypt_decrypt(key, (void *) ciphertext);
  378     free(key);
  379 
  380     if (strcmp(ciphertext, plaintext) != 0) {
  381         printf("failed internally\n");
  382         return -1;
  383     }
  384 
  385     return 0;
  386 }
  387 
  388 WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
  389 {
  390     return 20010801;
  391 }
  392 
  393 #ifdef WIN32
  394 # ifdef USE_LTDL
  395 WIN32DLL_DEFINE int main (void)
  396 {
  397        /* empty main function to avoid linker error (see cygwin FAQ) */
  398 }
  399 # endif
  400 #endif