"Fossies" - the Fresh Open Source Software Archive

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

    1 /* 
    2  * Copyright (C) 1998,1999,2000,2001 Nikos Mavroyanopoulos
    3  *
    4  * This library is free software; you can redistribute it and/or modify it 
    5  * under the terms of the GNU Library General Public License as published 
    6  * by the Free Software Foundation; either version 2 of the License, or 
    7  * (at your option) any later version.
    8  *
    9  * This library is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   12  * Library General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU Library General Public
   15  * License along with this library; if not, write to the
   16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   17  * Boston, MA 02111-1307, USA.
   18  */
   19 
   20 #include <libdefs.h>
   21 
   22 #include <mcrypt_modules.h>
   23 #include "wake.h"
   24 
   25 #define _mcrypt_set_key wake_LTX__mcrypt_set_key
   26 #define _mcrypt_encrypt wake_LTX__mcrypt_encrypt
   27 #define _mcrypt_decrypt wake_LTX__mcrypt_decrypt
   28 #define _mcrypt_get_size wake_LTX__mcrypt_get_size
   29 #define _mcrypt_get_block_size wake_LTX__mcrypt_get_block_size
   30 #define _is_block_algorithm wake_LTX__is_block_algorithm
   31 #define _mcrypt_get_key_size wake_LTX__mcrypt_get_key_size
   32 #define _mcrypt_get_algo_iv_size wake_LTX__mcrypt_get_algo_iv_size
   33 #define _mcrypt_get_supported_key_sizes wake_LTX__mcrypt_get_supported_key_sizes
   34 #define _mcrypt_get_algorithms_name wake_LTX__mcrypt_get_algorithms_name
   35 #define _mcrypt_self_test wake_LTX__mcrypt_self_test
   36 #define _mcrypt_algorithm_version wake_LTX__mcrypt_algorithm_version
   37 
   38 /* WAKE reference C-code, based on the description in David J. Wheeler's
   39  * paper "A bulk Data Encryption Algorithm"
   40  */
   41 
   42 /* #define USE_IV */
   43 /* IV is an mcrypt extension */
   44 
   45 static const word32 tt[10] = {
   46     0x726a8f3bUL,
   47     0xe69a3b5cUL,
   48     0xd3c71fe5UL,
   49     0xab3c73d2UL,
   50     0x4d3a8eb3UL,
   51     0x0396d6e8UL,
   52     0x3d4c2f7aUL,
   53     0x9ee27cf3UL
   54 };
   55 
   56 WIN32DLL_DEFINE
   57     int _mcrypt_set_key(WAKE_KEY * wake_key, word32 * key, int len,
   58             word32 * IV, int ivlen)
   59 {
   60     word32 x, z, p;
   61     word32 k[4];
   62 /* the key must be exactly 256 bits */
   63     if (len != 32)
   64         return -1;
   65 
   66 #ifdef WORDS_BIGENDIAN
   67     k[0] = byteswap32(key[0]);
   68     k[1] = byteswap32(key[1]);
   69     k[2] = byteswap32(key[2]);
   70     k[3] = byteswap32(key[3]);
   71 #else
   72     k[0] = key[0];
   73     k[1] = key[1];
   74     k[2] = key[2];
   75     k[3] = key[3];
   76 #endif
   77 
   78     for (p = 0; p < 4; p++) {
   79         wake_key->t[p] = k[p];
   80     }
   81 
   82     for (p = 4; p < 256; p++) {
   83         x = wake_key->t[p - 4] + wake_key->t[p - 1];
   84         wake_key->t[p] = x >> 3 ^ tt[x & 7];
   85     }
   86 
   87     for (p = 0; p < 23; p++)
   88         wake_key->t[p] += wake_key->t[p + 89];
   89 
   90     x = wake_key->t[33];
   91     z = wake_key->t[59] | 0x01000001;
   92     z &= 0xff7fffff;
   93 
   94     for (p = 0; p < 256; p++) {
   95         x = (x & 0xff7fffff) + z;
   96         wake_key->t[p] = (wake_key->t[p] & 0x00ffffff) ^ x;
   97     }
   98 
   99     wake_key->t[256] = wake_key->t[0];
  100     x &= 0xff;
  101 
  102     for (p = 0; p < 256; p++) {
  103         wake_key->t[p] = wake_key->t[x =
  104                          (wake_key->t[p ^ x] ^ x) &
  105                          0xff];
  106         wake_key->t[x] = wake_key->t[p + 1];
  107     }
  108 
  109     wake_key->counter = 0;
  110     wake_key->r[0] = k[0];
  111     wake_key->r[1] = k[1];
  112     wake_key->r[2] = k[2];
  113 #ifdef WORDS_BIGENDIAN
  114     wake_key->r[3] = byteswap32(k[3]);
  115 #else
  116     wake_key->r[3] = k[3];
  117 #endif
  118 #ifdef USE_IV
  119     wake_key->started = 0;
  120     if (ivlen > 32)
  121         wake_key->ivsize = 32;
  122     else
  123         wake_key->ivsize = ivlen / 4 * 4;
  124 
  125     if (IV == NULL)
  126         wake_key->ivsize = 0;
  127     if (wake_key->ivsize > 0 && IV != NULL)
  128         memcpy(&wake_key->iv, IV, wake_key->ivsize);
  129 #endif
  130 
  131     return 0;
  132 }
  133 
  134 /* in order to read the code easier */
  135 #define r2 wake_key->tmp
  136 #define r1 wake_key->tmp
  137 #define counter wake_key->counter
  138 
  139 /* M(X,Y) = (X+Y)>>8 XOR t[(X+Y) & 0xff] */
  140 #define M(X,Y) _int_M(X,Y, wake_key)
  141 inline static word32 _int_M(word32 X, word32 Y, WAKE_KEY * wake_key)
  142 {
  143     register word32 TMP;
  144 
  145     TMP = X + Y;
  146     return ((((TMP) >> 8) & 0x00ffffff) ^ wake_key->t[(TMP) & 0xff]);
  147 }
  148 
  149 WIN32DLL_DEFINE
  150     void _mcrypt_encrypt(WAKE_KEY * wake_key, byte * input, int len)
  151 {
  152     register word32 r3, r4, r5;
  153     word32 r6;
  154     int i;
  155 
  156     if (len == 0)
  157         return;
  158 
  159     r3 = wake_key->r[0];
  160     r4 = wake_key->r[1];
  161     r5 = wake_key->r[2];
  162     r6 = wake_key->r[3];
  163 
  164 #ifdef USE_IV
  165     if (wake_key->started == 0) {
  166         wake_key->started = 1;
  167         _mcrypt_encrypt(wake_key, (byte *) & wake_key->iv,
  168                 wake_key->ivsize);
  169     }
  170 #endif
  171 
  172     for (i = 0; i < len; i++) {
  173         /* R1 = V[n] = V[n] XOR R6 - here we do it per byte --sloooow */
  174         /* R1 is ignored */
  175         input[i] ^= ((byte *) & r6)[counter];
  176 
  177         /* R2 = V[n] = R1 - per byte also */
  178         ((byte *) & r2)[counter] = input[i];
  179         counter++;
  180 
  181         if (counter == 4) { /* r6 was used - update it! */
  182             counter = 0;
  183 
  184 #ifdef WORDS_BIGENDIAN
  185             /* these swaps are because we do operations per byte */
  186             r2 = byteswap32(r2);
  187             r6 = byteswap32(r6);
  188 #endif
  189             r3 = M(r3, r2);
  190             r4 = M(r4, r3);
  191             r5 = M(r5, r4);
  192             r6 = M(r6, r5);
  193 
  194 #ifdef WORDS_BIGENDIAN
  195             r6 = byteswap32(r6);
  196 #endif
  197         }
  198     }
  199 
  200     wake_key->r[0] = r3;
  201     wake_key->r[1] = r4;
  202     wake_key->r[2] = r5;
  203     wake_key->r[3] = r6;
  204 
  205 }
  206 
  207 
  208 WIN32DLL_DEFINE
  209     void _mcrypt_decrypt(WAKE_KEY * wake_key, byte * input, int len)
  210 {
  211     register word32 r3, r4, r5;
  212     word32 r6;
  213     int i;
  214 
  215     if (len == 0)
  216         return;
  217 
  218     r3 = wake_key->r[0];
  219     r4 = wake_key->r[1];
  220     r5 = wake_key->r[2];
  221     r6 = wake_key->r[3];
  222 
  223 #ifdef USE_IV
  224     if (wake_key->started == 0) {
  225         wake_key->started = 1;
  226         _mcrypt_encrypt(wake_key, (byte *) & wake_key->iv,
  227                 wake_key->ivsize);
  228         wake_key->r[0] = r3;
  229         wake_key->r[1] = r4;
  230         wake_key->r[2] = r5;
  231         wake_key->r[3] = r6;
  232         _mcrypt_decrypt(wake_key, (byte *) & wake_key->iv,
  233                 wake_key->ivsize);
  234     }
  235 #endif
  236 
  237     for (i = 0; i < len; i++) {
  238         /* R1 = V[n] */
  239         ((byte *) & r1)[counter] = input[i];
  240         /* R2 = V[n] = V[n] ^ R6 */
  241         /* R2 is ignored */
  242         input[i] ^= ((byte *) & r6)[counter];
  243         counter++;
  244 
  245         if (counter == 4) {
  246             counter = 0;
  247 
  248 #ifdef WORDS_BIGENDIAN
  249             r1 = byteswap32(r1);
  250             r6 = byteswap32(r6);
  251 #endif
  252             r3 = M(r3, r1);
  253             r4 = M(r4, r3);
  254             r5 = M(r5, r4);
  255             r6 = M(r6, r5);
  256 
  257 #ifdef WORDS_BIGENDIAN
  258             r6 = byteswap32(r6);
  259 #endif
  260         }
  261     }
  262 
  263     wake_key->r[0] = r3;
  264     wake_key->r[1] = r4;
  265     wake_key->r[2] = r5;
  266     wake_key->r[3] = r6;
  267 
  268 }
  269 
  270 
  271 WIN32DLL_DEFINE int _mcrypt_get_size()
  272 {
  273     return sizeof(WAKE_KEY);
  274 }
  275 WIN32DLL_DEFINE int _mcrypt_get_block_size()
  276 {
  277     return 1;
  278 }
  279 WIN32DLL_DEFINE int _mcrypt_get_algo_iv_size()
  280 {
  281 #ifdef USE_IV
  282     return 32;
  283 #else
  284     return 0;
  285 #endif
  286 }
  287 WIN32DLL_DEFINE int _is_block_algorithm()
  288 {
  289     return 0;
  290 }
  291 WIN32DLL_DEFINE int _mcrypt_get_key_size()
  292 {
  293     return 32;
  294 }
  295 
  296 static const int key_sizes[] = { 32 };
  297 WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
  298 {
  299     *len = sizeof(key_sizes)/sizeof(int);
  300     return key_sizes;
  301 }
  302 
  303 WIN32DLL_DEFINE const char *_mcrypt_get_algorithms_name()
  304 {
  305 return "WAKE";
  306 }
  307 
  308 #define CIPHER "434d575db053acfe6e4076f05298bedbd5f4f000be555d029b1367cffc7cd51bba61c76aa17da3530fb7d9"
  309 
  310 WIN32DLL_DEFINE int _mcrypt_self_test()
  311 {
  312     unsigned char *keyword;
  313     unsigned char plaintext[43];
  314     unsigned char ciphertext[43];
  315     int blocksize = 43, j;
  316     void *key, *key2;
  317     unsigned char cipher_tmp[200];
  318 
  319     keyword = calloc(1, _mcrypt_get_key_size());
  320     for (j = 0; j < _mcrypt_get_key_size(); j++) {
  321         keyword[j] = (j * 5 + 10) & 0xff;
  322     }
  323 
  324     for (j = 0; j < blocksize; j++) {
  325         plaintext[j] = (j + 5) % 0xff;
  326     }
  327     key = malloc(_mcrypt_get_size());
  328     key2 = malloc(_mcrypt_get_size());
  329 
  330     memcpy(ciphertext, plaintext, blocksize);
  331 
  332     _mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size(),
  333             NULL, 0);
  334     _mcrypt_encrypt(key, (void *) ciphertext, blocksize);
  335     free(key);
  336 
  337     for (j = 0; j < blocksize; j++) {
  338         sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
  339             ciphertext[j]);
  340     }
  341 
  342     if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
  343         printf("failed compatibility\n");
  344         printf("Expected: %s\nGot: %s\n", CIPHER,
  345                (char *) cipher_tmp);
  346         free(key);
  347         free(key2);
  348         return -1;
  349     }
  350     _mcrypt_set_key(key2, (void *) keyword, _mcrypt_get_key_size(),
  351             NULL, 0);
  352     free(keyword);
  353 
  354     _mcrypt_decrypt(key2, (void *) ciphertext, blocksize);
  355     free(key2);
  356 
  357     if (memcmp(ciphertext, plaintext, blocksize) != 0) {
  358         printf("failed internally\n");
  359         return -1;
  360     }
  361 
  362     return 0;
  363 }
  364 
  365 WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
  366 {
  367     return 20010801;
  368 }
  369 
  370 #ifdef WIN32
  371 # ifdef USE_LTDL
  372 WIN32DLL_DEFINE int main (void)
  373 {
  374        /* empty main function to avoid linker error (see cygwin FAQ) */
  375 }
  376 # endif
  377 #endif