"Fossies" - the Fresh Open Source Software Archive

Member "libmcrypt-2.5.8/modules/algorithms/safer64.c" (19 Jan 2003, 9558 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 "safer64.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 /* $Id: safer64.c,v 1.12 2003/01/19 17:48:27 nmav Exp $ */
   25 
   26 /******************* External Headers *****************************************/
   27 
   28 /******************* Local Headers ********************************************/
   29 #include <libdefs.h>
   30 
   31 #include <mcrypt_modules.h>
   32 #include "safer.h"
   33 
   34 
   35 #define _mcrypt_set_key safer_sk64_LTX__mcrypt_set_key
   36 #define _mcrypt_encrypt safer_sk64_LTX__mcrypt_encrypt
   37 #define _mcrypt_decrypt safer_sk64_LTX__mcrypt_decrypt
   38 #define _mcrypt_get_size safer_sk64_LTX__mcrypt_get_size
   39 #define _mcrypt_get_block_size safer_sk64_LTX__mcrypt_get_block_size
   40 #define _is_block_algorithm safer_sk64_LTX__is_block_algorithm
   41 #define _mcrypt_get_key_size safer_sk64_LTX__mcrypt_get_key_size
   42 #define _mcrypt_get_supported_key_sizes safer_sk64_LTX__mcrypt_get_supported_key_sizes
   43 #define _mcrypt_get_algorithms_name safer_sk64_LTX__mcrypt_get_algorithms_name
   44 #define _mcrypt_self_test safer_sk64_LTX__mcrypt_self_test
   45 #define _mcrypt_algorithm_version safer_sk64_LTX__mcrypt_algorithm_version
   46 
   47 /******************* Constants ************************************************/
   48 #define TAB_LEN      256
   49 static int _safer64_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_tab64[(x) & 0xFF]
   56 #define LOG(x)       log_tab64[(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_tab64[TAB_LEN];
   62 static unsigned char log_tab64[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_tab64[i] = (unsigned char) (exp & 0xFF);
   77         log_tab64[exp_tab64[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 
   94     if (_safer64_init == 0) {
   95         _mcrypt_Safer_Init_Module();
   96         _safer64_init = 1;
   97     }
   98     if (SAFER_MAX_NOF_ROUNDS < nof_rounds)
   99         nof_rounds = SAFER_MAX_NOF_ROUNDS;
  100     *key++ = (unsigned char) nof_rounds;
  101     ka[SAFER_BLOCK_LEN] = 0;
  102     kb[SAFER_BLOCK_LEN] = 0;
  103     for (j = 0; j < SAFER_BLOCK_LEN; j++) {
  104         ka[SAFER_BLOCK_LEN] ^= ka[j] = ROL(userkey[j], 5);
  105         kb[SAFER_BLOCK_LEN] ^= kb[j] = *key++ = userkey[j];
  106     }
  107     for (i = 1; i <= nof_rounds; i++) {
  108         for (j = 0; j < SAFER_BLOCK_LEN + 1; j++) {
  109             ka[j] = ROL(ka[j], 6);
  110             kb[j] = ROL(kb[j], 6);
  111         }
  112         for (j = 0; j < SAFER_BLOCK_LEN; j++)
  113             if (strengthened)
  114                 *key++ =
  115                     (ka
  116                      [(j + 2 * i - 1) %
  117                       (SAFER_BLOCK_LEN + 1)] +
  118                      exp_tab64[exp_tab64[18 * i + j + 1]]) &
  119                     0xFF;
  120             else
  121                 *key++ =
  122                     (ka[j] +
  123                      exp_tab64[exp_tab64[18 * i + j + 1]]) &
  124                     0xFF;
  125         for (j = 0; j < SAFER_BLOCK_LEN; j++)
  126             if (strengthened)
  127                 *key++ =
  128                     (kb
  129                      [(j + 2 * i) %
  130                       (SAFER_BLOCK_LEN + 1)] +
  131                      exp_tab64[exp_tab64[18 * i + j + 10]]) &
  132                     0xFF;
  133             else
  134                 *key++ =
  135                     (kb[j] +
  136                      exp_tab64[exp_tab64[18 * i + j + 10]]) &
  137                     0xFF;
  138     }
  139     for (j = 0; j < SAFER_BLOCK_LEN + 1; j++)
  140         ka[j] = kb[j] = 0;
  141     return 0;
  142 }               /* Safer_Expand_Userkey */
  143 
  144 /******************************************************************************/
  145 
  146 
  147 WIN32DLL_DEFINE
  148     void _mcrypt_encrypt(const safer_key_t * key, safer_block_t * block_in)
  149 {
  150     unsigned char a, b, c, d, e, f, g, h, t;
  151     unsigned int round;
  152 
  153     a = block_in[0];
  154     b = block_in[1];
  155     c = block_in[2];
  156     d = block_in[3];
  157     e = block_in[4];
  158     f = block_in[5];
  159     g = block_in[6];
  160     h = block_in[7];
  161     if (SAFER_MAX_NOF_ROUNDS < (round = *key))
  162         round = SAFER_MAX_NOF_ROUNDS;
  163     while (round--) {
  164         a ^= *++key;
  165         b += *++key;
  166         c += *++key;
  167         d ^= *++key;
  168         e ^= *++key;
  169         f += *++key;
  170         g += *++key;
  171         h ^= *++key;
  172         a = EXP(a) + *++key;
  173         b = LOG(b) ^ *++key;
  174         c = LOG(c) ^ *++key;
  175         d = EXP(d) + *++key;
  176         e = EXP(e) + *++key;
  177         f = LOG(f) ^ *++key;
  178         g = LOG(g) ^ *++key;
  179         h = EXP(h) + *++key;
  180         PHT(a, b);
  181         PHT(c, d);
  182         PHT(e, f);
  183         PHT(g, h);
  184         PHT(a, c);
  185         PHT(e, g);
  186         PHT(b, d);
  187         PHT(f, h);
  188         PHT(a, e);
  189         PHT(b, f);
  190         PHT(c, g);
  191         PHT(d, h);
  192         t = b;
  193         b = e;
  194         e = c;
  195         c = t;
  196         t = d;
  197         d = f;
  198         f = g;
  199         g = t;
  200     }
  201     a ^= *++key;
  202     b += *++key;
  203     c += *++key;
  204     d ^= *++key;
  205     e ^= *++key;
  206     f += *++key;
  207     g += *++key;
  208     h ^= *++key;
  209     block_in[0] = a & 0xFF;
  210     block_in[1] = b & 0xFF;
  211     block_in[2] = c & 0xFF;
  212     block_in[3] = d & 0xFF;
  213     block_in[4] = e & 0xFF;
  214     block_in[5] = f & 0xFF;
  215     block_in[6] = g & 0xFF;
  216     block_in[7] = h & 0xFF;
  217 }               /* Safer_Encrypt_Block */
  218 
  219 /******************************************************************************/
  220 
  221 WIN32DLL_DEFINE
  222     void _mcrypt_decrypt(const safer_key_t * key, safer_block_t * block_in)
  223 {
  224     safer_block_t a, b, c, d, e, f, g, h, t;
  225     unsigned int round;
  226     a = block_in[0];
  227     b = block_in[1];
  228     c = block_in[2];
  229     d = block_in[3];
  230     e = block_in[4];
  231     f = block_in[5];
  232     g = block_in[6];
  233     h = block_in[7];
  234     if (SAFER_MAX_NOF_ROUNDS < (round = *key))
  235         round = SAFER_MAX_NOF_ROUNDS;
  236     key += SAFER_BLOCK_LEN * (1 + 2 * round);
  237     h ^= *key;
  238     g -= *--key;
  239     f -= *--key;
  240     e ^= *--key;
  241     d ^= *--key;
  242     c -= *--key;
  243     b -= *--key;
  244     a ^= *--key;
  245     while (round--) {
  246         t = e;
  247         e = b;
  248         b = c;
  249         c = t;
  250         t = f;
  251         f = d;
  252         d = g;
  253         g = t;
  254         IPHT(a, e);
  255         IPHT(b, f);
  256         IPHT(c, g);
  257         IPHT(d, h);
  258         IPHT(a, c);
  259         IPHT(e, g);
  260         IPHT(b, d);
  261         IPHT(f, h);
  262         IPHT(a, b);
  263         IPHT(c, d);
  264         IPHT(e, f);
  265         IPHT(g, h);
  266         h -= *--key;
  267         g ^= *--key;
  268         f ^= *--key;
  269         e -= *--key;
  270         d -= *--key;
  271         c ^= *--key;
  272         b ^= *--key;
  273         a -= *--key;
  274         h = LOG(h) ^ *--key;
  275         g = EXP(g) - *--key;
  276         f = EXP(f) - *--key;
  277         e = LOG(e) ^ *--key;
  278         d = LOG(d) ^ *--key;
  279         c = EXP(c) - *--key;
  280         b = EXP(b) - *--key;
  281         a = LOG(a) ^ *--key;
  282     }
  283     block_in[0] = a & 0xFF;
  284     block_in[1] = b & 0xFF;
  285     block_in[2] = c & 0xFF;
  286     block_in[3] = d & 0xFF;
  287     block_in[4] = e & 0xFF;
  288     block_in[5] = f & 0xFF;
  289     block_in[6] = g & 0xFF;
  290     block_in[7] = h & 0xFF;
  291 }               /* Safer_Decrypt_Block */
  292 
  293 /******************************************************************************/
  294 
  295 
  296 WIN32DLL_DEFINE int _mcrypt_get_size()
  297 {
  298     return (1 + SAFER_BLOCK_LEN * (1 + 2 * SAFER_MAX_NOF_ROUNDS));
  299 }
  300 WIN32DLL_DEFINE int _mcrypt_get_block_size()
  301 {
  302     return 8;
  303 }
  304 WIN32DLL_DEFINE int _is_block_algorithm()
  305 {
  306     return 1;
  307 }
  308 WIN32DLL_DEFINE int _mcrypt_get_key_size()
  309 {
  310     return 8;
  311 }
  312 
  313 static const int key_sizes[] = { 8 };
  314 WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
  315 {
  316     *len = sizeof(key_sizes)/sizeof(int);
  317     return key_sizes;
  318 
  319 }
  320 WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
  321 {
  322 return "SAFER-SK64";
  323 }
  324 
  325 #define CIPHER "e490eebffd908f34"
  326 
  327 WIN32DLL_DEFINE int _mcrypt_self_test()
  328 {
  329     char *keyword;
  330     unsigned char plaintext[16];
  331     unsigned char ciphertext[16];
  332     int blocksize = _mcrypt_get_block_size(), j;
  333     void *key;
  334     unsigned char cipher_tmp[200];
  335 
  336     keyword = calloc(1, _mcrypt_get_key_size());
  337     if (keyword == NULL)
  338         return -1;
  339 
  340     for (j = 0; j < _mcrypt_get_key_size(); j++) {
  341         keyword[j] = ((j * 2 + 10) % 256);
  342     }
  343 
  344     for (j = 0; j < blocksize; j++) {
  345         plaintext[j] = j % 256;
  346     }
  347     key = malloc(_mcrypt_get_size());
  348     if (key == NULL) {
  349         free(keyword);
  350         return -1;
  351     }
  352     memcpy(ciphertext, plaintext, blocksize);
  353 
  354     _mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
  355     free(keyword);
  356 
  357     _mcrypt_encrypt(key, (void *) ciphertext);
  358 
  359     for (j = 0; j < blocksize; j++) {
  360         sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
  361             ciphertext[j]);
  362     }
  363 
  364     if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
  365         printf("failed compatibility\n");
  366         printf("Expected: %s\nGot: %s\n", CIPHER,
  367                (char *) cipher_tmp);
  368         free(key);
  369         return -1;
  370     }
  371     _mcrypt_decrypt(key, (void *) ciphertext);
  372     free(key);
  373 
  374     if (strcmp(ciphertext, plaintext) != 0) {
  375         printf("failed internally\n");
  376         return -1;
  377     }
  378 
  379     return 0;
  380 }
  381 
  382 WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
  383 {
  384     return 20010801;
  385 }
  386 
  387 #ifdef WIN32
  388 # ifdef USE_LTDL
  389 WIN32DLL_DEFINE int main (void)
  390 {
  391        /* empty main function to avoid linker error (see cygwin FAQ) */
  392 }
  393 # endif
  394 #endif