"Fossies" - the Fresh Open Source Software Archive

Member "libmcrypt-2.5.8/modules/algorithms/safer128.c" (19 Jan 2003, 9679 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 "safer128.c" see the Fossies "Dox" file reference documentation.

    1 /*******************************************************************************
    2 *
    3 * FILE:           safer.c
    4 *
    5 * DESCRIPTION:    block-cipher algorithm SAFER (Secure And Fast Encryption
    6 *                 Routine) in its four versions: SAFER K-64, SAFER K-128,
    7 *                 SAFER SK-64 and SAFER SK-128.
    8 *
    9 * AUTHOR:         Richard De Moliner (demoliner@isi.ee.ethz.ch)
   10 *                 Signal and Information Processing Laboratory
   11 *                 Swiss Federal Institute of Technology
   12 *                 CH-8092 Zuerich, Switzerland
   13 *
   14 * DATE:           September 9, 1995
   15 *
   16 * CHANGE HISTORY:
   17 *
   18 *******************************************************************************/
   19 
   20 /* modified in order to use the libmcrypt API by Nikos Mavroyanopoulos 
   21  * All modifications are placed under the license of libmcrypt.
   22  */
   23 
   24 
   25 /* $Id: safer128.c,v 1.12 2003/01/19 17:48:27 nmav Exp $ */
   26 
   27 /******************* External Headers *****************************************/
   28 
   29 /******************* Local Headers ********************************************/
   30 #include <libdefs.h>
   31 
   32 #include <mcrypt_modules.h>
   33 #include "safer.h"
   34 
   35 #define _mcrypt_set_key safer_sk128_LTX__mcrypt_set_key
   36 #define _mcrypt_encrypt safer_sk128_LTX__mcrypt_encrypt
   37 #define _mcrypt_decrypt safer_sk128_LTX__mcrypt_decrypt
   38 #define _mcrypt_get_size safer_sk128_LTX__mcrypt_get_size
   39 #define _mcrypt_get_block_size safer_sk128_LTX__mcrypt_get_block_size
   40 #define _is_block_algorithm safer_sk128_LTX__is_block_algorithm
   41 #define _mcrypt_get_key_size safer_sk128_LTX__mcrypt_get_key_size
   42 #define _mcrypt_get_supported_key_sizes safer_sk128_LTX__mcrypt_get_supported_key_sizes
   43 #define _mcrypt_get_algorithms_name safer_sk128_LTX__mcrypt_get_algorithms_name
   44 #define _mcrypt_self_test safer_sk128_LTX__mcrypt_self_test
   45 #define _mcrypt_algorithm_version safer_sk128_LTX__mcrypt_algorithm_version
   46 
   47 /******************* Constants ************************************************/
   48 #define TAB_LEN      256
   49 static int _safer128_init = 0;
   50 /******************* Assertions ***********************************************/
   51 
   52 /******************* Macros ***************************************************/
   53 #define ROL(x, n)    ((unsigned char)((unsigned int)(x) << (n)\
   54                                      |(unsigned int)((x) & 0xFF) >> (8 - (n))))
   55 #define EXP(x)       exp_tab128[(x) & 0xFF]
   56 #define LOG(x)       log_tab128[(x) & 0xFF]
   57 #define PHT(x, y)    { y += x; x += y; }
   58 #define IPHT(x, y)   { x -= y; y -= x; }
   59 
   60 /******************* Types ****************************************************/
   61 static unsigned char exp_tab128[TAB_LEN];
   62 static unsigned char log_tab128[TAB_LEN];
   63 
   64 /******************* Module Data **********************************************/
   65 
   66 /******************* Functions ************************************************/
   67 
   68 /******************************************************************************/
   69 
   70 static void _mcrypt_Safer_Init_Module(void)
   71 {
   72     unsigned int i, exp;
   73 
   74     exp = 1;
   75     for (i = 0; i < TAB_LEN; i++) {
   76         exp_tab128[i] = (unsigned char) (exp & 0xFF);
   77         log_tab128[exp_tab128[i]] = (unsigned char) i;
   78         exp = exp * 45 % 257;
   79     }
   80 }               /* Safer_Init_Module */
   81 
   82 /******************************************************************************/
   83 
   84 WIN32DLL_DEFINE
   85     int _mcrypt_set_key(safer_key_t * key, safer_block_t * userkey,
   86             int len)
   87 {
   88     unsigned int i, j;
   89     unsigned char ka[SAFER_BLOCK_LEN + 1];
   90     unsigned char kb[SAFER_BLOCK_LEN + 1];
   91     int nof_rounds = SAFER_SK64_DEFAULT_NOF_ROUNDS;
   92     int strengthened = 1;
   93     unsigned char *userkey_1 = &userkey[0];
   94     unsigned char *userkey_2 = &userkey[8];
   95 
   96     if (_safer128_init == 0) {
   97         _mcrypt_Safer_Init_Module();
   98         _safer128_init = 1;
   99     }
  100     if (SAFER_MAX_NOF_ROUNDS < nof_rounds)
  101         nof_rounds = SAFER_MAX_NOF_ROUNDS;
  102     *key++ = (unsigned char) nof_rounds;
  103     ka[SAFER_BLOCK_LEN] = 0;
  104     kb[SAFER_BLOCK_LEN] = 0;
  105     for (j = 0; j < SAFER_BLOCK_LEN; j++) {
  106         ka[SAFER_BLOCK_LEN] ^= ka[j] = ROL(userkey_1[j], 5);
  107         kb[SAFER_BLOCK_LEN] ^= kb[j] = *key++ = userkey_2[j];
  108     }
  109     for (i = 1; i <= nof_rounds; i++) {
  110         for (j = 0; j < SAFER_BLOCK_LEN + 1; j++) {
  111             ka[j] = ROL(ka[j], 6);
  112             kb[j] = ROL(kb[j], 6);
  113         }
  114         for (j = 0; j < SAFER_BLOCK_LEN; j++)
  115             if (strengthened)
  116                 *key++ =
  117                     (ka
  118                      [(j + 2 * i - 1) %
  119                       (SAFER_BLOCK_LEN + 1)] +
  120                      exp_tab128[exp_tab128[18 * i + j + 1]]) &
  121                     0xFF;
  122             else
  123                 *key++ =
  124                     (ka[j] +
  125                      exp_tab128[exp_tab128[18 * i + j + 1]]) &
  126                     0xFF;
  127         for (j = 0; j < SAFER_BLOCK_LEN; j++)
  128             if (strengthened)
  129                 *key++ =
  130                     (kb
  131                      [(j + 2 * i) %
  132                       (SAFER_BLOCK_LEN + 1)] +
  133                      exp_tab128[exp_tab128[18 * i + j + 10]]) &
  134                     0xFF;
  135             else
  136                 *key++ =
  137                     (kb[j] +
  138                      exp_tab128[exp_tab128[18 * i + j + 10]]) &
  139                     0xFF;
  140     }
  141     for (j = 0; j < SAFER_BLOCK_LEN + 1; j++)
  142         ka[j] = kb[j] = 0;
  143 
  144     return 0;
  145 }               /* Safer_Expand_Userkey */
  146 
  147 /******************************************************************************/
  148 
  149 
  150 WIN32DLL_DEFINE
  151     void _mcrypt_encrypt(const safer_key_t * key, safer_block_t * block_in)
  152 {
  153     unsigned char a, b, c, d, e, f, g, h, t;
  154     unsigned int round;
  155 
  156     a = block_in[0];
  157     b = block_in[1];
  158     c = block_in[2];
  159     d = block_in[3];
  160     e = block_in[4];
  161     f = block_in[5];
  162     g = block_in[6];
  163     h = block_in[7];
  164     if (SAFER_MAX_NOF_ROUNDS < (round = *key))
  165         round = SAFER_MAX_NOF_ROUNDS;
  166     while (round--) {
  167         a ^= *++key;
  168         b += *++key;
  169         c += *++key;
  170         d ^= *++key;
  171         e ^= *++key;
  172         f += *++key;
  173         g += *++key;
  174         h ^= *++key;
  175         a = EXP(a) + *++key;
  176         b = LOG(b) ^ *++key;
  177         c = LOG(c) ^ *++key;
  178         d = EXP(d) + *++key;
  179         e = EXP(e) + *++key;
  180         f = LOG(f) ^ *++key;
  181         g = LOG(g) ^ *++key;
  182         h = EXP(h) + *++key;
  183         PHT(a, b);
  184         PHT(c, d);
  185         PHT(e, f);
  186         PHT(g, h);
  187         PHT(a, c);
  188         PHT(e, g);
  189         PHT(b, d);
  190         PHT(f, h);
  191         PHT(a, e);
  192         PHT(b, f);
  193         PHT(c, g);
  194         PHT(d, h);
  195         t = b;
  196         b = e;
  197         e = c;
  198         c = t;
  199         t = d;
  200         d = f;
  201         f = g;
  202         g = t;
  203     }
  204     a ^= *++key;
  205     b += *++key;
  206     c += *++key;
  207     d ^= *++key;
  208     e ^= *++key;
  209     f += *++key;
  210     g += *++key;
  211     h ^= *++key;
  212     block_in[0] = a & 0xFF;
  213     block_in[1] = b & 0xFF;
  214     block_in[2] = c & 0xFF;
  215     block_in[3] = d & 0xFF;
  216     block_in[4] = e & 0xFF;
  217     block_in[5] = f & 0xFF;
  218     block_in[6] = g & 0xFF;
  219     block_in[7] = h & 0xFF;
  220 }               /* Safer_Encrypt_Block */
  221 
  222 /******************************************************************************/
  223 
  224 WIN32DLL_DEFINE
  225     void _mcrypt_decrypt(const safer_key_t * key, safer_block_t * block_in)
  226 {
  227     safer_block_t a, b, c, d, e, f, g, h, t;
  228     unsigned int round;
  229     a = block_in[0];
  230     b = block_in[1];
  231     c = block_in[2];
  232     d = block_in[3];
  233     e = block_in[4];
  234     f = block_in[5];
  235     g = block_in[6];
  236     h = block_in[7];
  237     if (SAFER_MAX_NOF_ROUNDS < (round = *key))
  238         round = SAFER_MAX_NOF_ROUNDS;
  239     key += SAFER_BLOCK_LEN * (1 + 2 * round);
  240     h ^= *key;
  241     g -= *--key;
  242     f -= *--key;
  243     e ^= *--key;
  244     d ^= *--key;
  245     c -= *--key;
  246     b -= *--key;
  247     a ^= *--key;
  248     while (round--) {
  249         t = e;
  250         e = b;
  251         b = c;
  252         c = t;
  253         t = f;
  254         f = d;
  255         d = g;
  256         g = t;
  257         IPHT(a, e);
  258         IPHT(b, f);
  259         IPHT(c, g);
  260         IPHT(d, h);
  261         IPHT(a, c);
  262         IPHT(e, g);
  263         IPHT(b, d);
  264         IPHT(f, h);
  265         IPHT(a, b);
  266         IPHT(c, d);
  267         IPHT(e, f);
  268         IPHT(g, h);
  269         h -= *--key;
  270         g ^= *--key;
  271         f ^= *--key;
  272         e -= *--key;
  273         d -= *--key;
  274         c ^= *--key;
  275         b ^= *--key;
  276         a -= *--key;
  277         h = LOG(h) ^ *--key;
  278         g = EXP(g) - *--key;
  279         f = EXP(f) - *--key;
  280         e = LOG(e) ^ *--key;
  281         d = LOG(d) ^ *--key;
  282         c = EXP(c) - *--key;
  283         b = EXP(b) - *--key;
  284         a = LOG(a) ^ *--key;
  285     }
  286     block_in[0] = a & 0xFF;
  287     block_in[1] = b & 0xFF;
  288     block_in[2] = c & 0xFF;
  289     block_in[3] = d & 0xFF;
  290     block_in[4] = e & 0xFF;
  291     block_in[5] = f & 0xFF;
  292     block_in[6] = g & 0xFF;
  293     block_in[7] = h & 0xFF;
  294 }               /* Safer_Decrypt_Block */
  295 
  296 /******************************************************************************/
  297 
  298 WIN32DLL_DEFINE int _mcrypt_get_size()
  299 {
  300     return (1 + SAFER_BLOCK_LEN * (1 + 2 * SAFER_MAX_NOF_ROUNDS));
  301 }
  302 WIN32DLL_DEFINE int _mcrypt_get_block_size()
  303 {
  304     return 8;
  305 }
  306 WIN32DLL_DEFINE int _is_block_algorithm()
  307 {
  308     return 1;
  309 }
  310 WIN32DLL_DEFINE int _mcrypt_get_key_size()
  311 {
  312     return 16;
  313 }
  314 
  315 static const int key_sizes[] = { 16 };
  316 WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
  317 {
  318     *len = sizeof(key_sizes)/sizeof(int);
  319     return key_sizes;
  320 
  321 }
  322 
  323 WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
  324 {
  325     return "SAFER-SK128";
  326 }
  327 
  328 #define CIPHER "35ed856e2cf90947"
  329 
  330 WIN32DLL_DEFINE int _mcrypt_self_test()
  331 {
  332     char *keyword;
  333     unsigned char plaintext[16];
  334     unsigned char ciphertext[16];
  335     int blocksize = _mcrypt_get_block_size(), j;
  336     void *key;
  337     unsigned char cipher_tmp[200];
  338 
  339     keyword = calloc(1, _mcrypt_get_key_size());
  340     if (keyword == NULL)
  341         return -1;
  342 
  343     for (j = 0; j < _mcrypt_get_key_size(); j++) {
  344         keyword[j] = ((j * 2 + 10) % 256);
  345     }
  346 
  347     for (j = 0; j < blocksize; j++) {
  348         plaintext[j] = j % 256;
  349     }
  350     key = malloc(_mcrypt_get_size());
  351     if (key == NULL) {
  352         free(keyword);
  353         return -1;
  354     }
  355     memcpy(ciphertext, plaintext, blocksize);
  356 
  357     _mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
  358     free(keyword);
  359 
  360     _mcrypt_encrypt(key, (void *) ciphertext);
  361 
  362     for (j = 0; j < blocksize; j++) {
  363         sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
  364             ciphertext[j]);
  365     }
  366 
  367     if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
  368         printf("failed compatibility\n");
  369         printf("Expected: %s\nGot: %s\n", CIPHER,
  370                (char *) cipher_tmp);
  371         free(key);
  372         return -1;
  373     }
  374     _mcrypt_decrypt(key, (void *) ciphertext);
  375     free(key);
  376 
  377     if (strcmp(ciphertext, plaintext) != 0) {
  378         printf("failed internally\n");
  379         return -1;
  380     }
  381 
  382     return 0;
  383 }
  384 
  385 WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
  386 {
  387     return 20010801;
  388 }
  389 
  390 #ifdef WIN32
  391 # ifdef USE_LTDL
  392 WIN32DLL_DEFINE int main (void)
  393 {
  394        /* empty main function to avoid linker error (see cygwin FAQ) */
  395 }
  396 # endif
  397 #endif