"Fossies" - the Fresh Open Source Software Archive

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

    1 /**********************************************************************\
    2 * To commemorate the 1996 RSA Data Security Conference, the following  *
    3 * code is released into the public domain by its author.  Prost!       *
    4 *                                                                      *
    5 * This cipher uses 16-bit words and little-endian byte ordering.       *
    6 * I wonder which processor it was optimized for?                       *
    7 *                                                                      *
    8 * Thanks to CodeView, SoftIce, and D86 for helping bring this code to  *
    9 * the public.                                                          *
   10 \**********************************************************************/
   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: rc2.c,v 1.14 2003/01/19 17:48:27 nmav Exp $ */
   17 
   18 #include <libdefs.h>
   19 
   20 #include <mcrypt_modules.h>
   21 /* #include <assert.h> */
   22 #include "rc2.h"
   23 
   24 #define _mcrypt_set_key rc2_LTX__mcrypt_set_key
   25 #define _mcrypt_encrypt rc2_LTX__mcrypt_encrypt
   26 #define _mcrypt_decrypt rc2_LTX__mcrypt_decrypt
   27 #define _mcrypt_get_size rc2_LTX__mcrypt_get_size
   28 #define _mcrypt_get_block_size rc2_LTX__mcrypt_get_block_size
   29 #define _is_block_algorithm rc2_LTX__is_block_algorithm
   30 #define _mcrypt_get_key_size rc2_LTX__mcrypt_get_key_size
   31 #define _mcrypt_get_supported_key_sizes rc2_LTX__mcrypt_get_supported_key_sizes
   32 #define _mcrypt_get_algorithms_name rc2_LTX__mcrypt_get_algorithms_name
   33 #define _mcrypt_self_test rc2_LTX__mcrypt_self_test
   34 #define _mcrypt_algorithm_version rc2_LTX__mcrypt_algorithm_version
   35 
   36 /**********************************************************************\
   37 * Expand a variable-length user key (between 1 and 128 bytes) to a     *
   38 * 64-short working rc2 key, of at most "bits" effective key bits.      *
   39 * The effective key bits parameter looks like an export control hack.  *
   40 * For normal use, it should always be set to 1024.  For convenience,   *
   41 * zero is accepted as an alias for 1024.                               *
   42 \**********************************************************************/
   43 
   44 WIN32DLL_DEFINE
   45     int _mcrypt_set_key(word16 * xkey, const byte * key, unsigned int len)
   46 {
   47     unsigned int j;
   48     byte *xkey_p = (void *) xkey;
   49     int i;
   50 
   51     /* 256-entry permutation table, probably derived somehow from pi */
   52     static const byte permute[256] = {
   53         217, 120, 249, 196, 25, 221, 181, 237, 40, 233, 253, 121,
   54         74, 160, 216, 157,
   55         198, 126, 55, 131, 43, 118, 83, 142, 98, 76, 100, 136,
   56         68, 139, 251, 162,
   57         23, 154, 89, 245, 135, 179, 79, 19, 97, 69, 109, 141, 9,
   58         129, 125, 50,
   59         189, 143, 64, 235, 134, 183, 123, 11, 240, 149, 33, 34,
   60         92, 107, 78, 130,
   61         84, 214, 101, 147, 206, 96, 178, 28, 115, 86, 192, 20,
   62         167, 140, 241, 220,
   63         18, 117, 202, 31, 59, 190, 228, 209, 66, 61, 212, 48,
   64         163, 60, 182, 38,
   65         111, 191, 14, 218, 70, 105, 7, 87, 39, 242, 29, 155, 188,
   66         148, 67, 3,
   67         248, 17, 199, 246, 144, 239, 62, 231, 6, 195, 213, 47,
   68         200, 102, 30, 215,
   69         8, 232, 234, 222, 128, 82, 238, 247, 132, 170, 114, 172,
   70         53, 77, 106, 42,
   71         150, 26, 210, 113, 90, 21, 73, 116, 75, 159, 208, 94, 4,
   72         24, 164, 236,
   73         194, 224, 65, 110, 15, 81, 203, 204, 36, 145, 175, 80,
   74         161, 244, 112, 57,
   75         153, 124, 58, 133, 35, 184, 180, 122, 252, 2, 54, 91, 37,
   76         85, 151, 49,
   77         45, 93, 250, 152, 227, 138, 146, 174, 5, 223, 41, 16,
   78         103, 108, 186, 201,
   79         211, 0, 230, 207, 225, 158, 168, 44, 99, 22, 1, 63, 88,
   80         226, 137, 169,
   81         13, 56, 52, 27, 171, 51, 255, 176, 187, 72, 12, 95, 185,
   82         177, 205, 46,
   83         197, 243, 219, 71, 229, 165, 156, 119, 10, 166, 32, 104,
   84         254, 127, 193, 173
   85     };
   86 
   87 /*  assert(len > 0 && len <= 128); */
   88 
   89     memmove(xkey, key, len);
   90 
   91     /* Phase 1: Expand input key to 128 bytes */
   92 
   93     for (j = len; j < 128; j++) {
   94         xkey_p[j] =
   95             permute[(xkey_p[j - len] + xkey_p[j - 1]) % 256];
   96     }
   97 
   98     xkey_p[0] = permute[xkey_p[0]];
   99 
  100     /* Phase 2 - reduce effective key size to "bits" */
  101     /* stripped */
  102 
  103     /* Phase 3 - copy to xkey in little-endian order */
  104     i = 63;
  105     do {
  106         xkey[i] = xkey_p[2 * i] + (xkey_p[2 * i + 1] << 8);
  107     } while (i--);
  108 
  109     return 0;
  110 }
  111 
  112 
  113 /**********************************************************************\
  114 * Encrypt an 8-byte block of plaintext using the given key.            *
  115 \**********************************************************************/
  116 
  117 WIN32DLL_DEFINE void _mcrypt_encrypt(const word16 * xkey, word16 * plain)
  118 {
  119     word16 x3, x2, x1, x0, i;
  120 
  121 #ifdef WORDS_BIGENDIAN
  122     x3 = byteswap16(plain[3]);
  123     x2 = byteswap16(plain[2]);
  124     x1 = byteswap16(plain[1]);
  125     x0 = byteswap16(plain[0]);
  126 #else
  127     x3 = plain[3];
  128     x2 = plain[2];
  129     x1 = plain[1];
  130     x0 = plain[0];
  131 #endif
  132 
  133     for (i = 0; i < 16; i++) {
  134         x0 += (x1 & ~x3) + (x2 & x3) + xkey[4 * i + 0];
  135         x0 = rotl16(x0, 1);
  136 
  137         x1 += (x2 & ~x0) + (x3 & x0) + xkey[4 * i + 1];
  138         x1 = rotl16(x1, 2);
  139 
  140         x2 += (x3 & ~x1) + (x0 & x1) + xkey[4 * i + 2];
  141         x2 = rotl16(x2, 3);
  142 
  143         x3 += (x0 & ~x2) + (x1 & x2) + xkey[4 * i + 3];
  144         x3 = rotl16(x3, 5);
  145 
  146         if (i == 4 || i == 10) {
  147             x0 += xkey[x3 & 63];
  148             x1 += xkey[x0 & 63];
  149             x2 += xkey[x1 & 63];
  150             x3 += xkey[x2 & 63];
  151         }
  152     }
  153 
  154 #ifdef WORDS_BIGENDIAN
  155     plain[0] = byteswap16(x0);
  156     plain[1] = byteswap16(x1);
  157     plain[2] = byteswap16(x2);
  158     plain[3] = byteswap16(x3);
  159 #else
  160     plain[0] = (x0);
  161     plain[1] = (x1);
  162     plain[2] = (x2);
  163     plain[3] = (x3);
  164 
  165 #endif
  166 
  167 }
  168 
  169 /**********************************************************************\
  170 * Decrypt an 8-byte block of ciphertext using the given key.           *
  171 \**********************************************************************/
  172 
  173 WIN32DLL_DEFINE void _mcrypt_decrypt(const word16 * xkey, word16 * plain)
  174 {
  175     word16 x3, x2, x1, x0, i;
  176 
  177 #ifndef WORDS_BIGENDIAN
  178     x3 = plain[3];
  179     x2 = plain[2];
  180     x1 = plain[1];
  181     x0 = plain[0];
  182 #else
  183     x3 = byteswap16(plain[3]);
  184     x2 = byteswap16(plain[2]);
  185     x1 = byteswap16(plain[1]);
  186     x0 = byteswap16(plain[0]);
  187 #endif
  188 
  189 
  190     i = 15;
  191     do {
  192         x3 = rotr16(x3, 5);
  193         x3 -= (x0 & ~x2) + (x1 & x2) + xkey[4 * i + 3];
  194 
  195         x2 = rotr16(x2, 3);
  196         x2 -= (x3 & ~x1) + (x0 & x1) + xkey[4 * i + 2];
  197 
  198         x1 = rotr16(x1, 2);
  199         x1 -= (x2 & ~x0) + (x3 & x0) + xkey[4 * i + 1];
  200 
  201         x0 = rotr16(x0, 1);
  202         x0 -= (x1 & ~x3) + (x2 & x3) + xkey[4 * i + 0];
  203 
  204         if (i == 5 || i == 11) {
  205             x3 -= xkey[x2 & 63];
  206             x2 -= xkey[x1 & 63];
  207             x1 -= xkey[x0 & 63];
  208             x0 -= xkey[x3 & 63];
  209         }
  210     } while (i--);
  211 
  212 #ifdef WORDS_BIGENDIAN
  213     plain[0] = byteswap16(x0);
  214     plain[1] = byteswap16(x1);
  215     plain[2] = byteswap16(x2);
  216     plain[3] = byteswap16(x3);
  217 #else
  218     plain[0] = x0;
  219     plain[1] = x1;
  220     plain[2] = x2;
  221     plain[3] = x3;
  222 #endif
  223 }
  224 
  225 WIN32DLL_DEFINE int _mcrypt_get_size()
  226 {
  227     return 64 * sizeof(word16);
  228 }
  229 WIN32DLL_DEFINE int _mcrypt_get_block_size()
  230 {
  231     return 8;
  232 }
  233 WIN32DLL_DEFINE int _is_block_algorithm()
  234 {
  235     return 1;
  236 }
  237 WIN32DLL_DEFINE int _mcrypt_get_key_size()
  238 {
  239     return 128;
  240 }
  241 
  242 WIN32DLL_DEFINE const int *_mcrypt_get_supported_key_sizes(int *len)
  243 {
  244     *len = 0;
  245     return NULL;
  246 }
  247 WIN32DLL_DEFINE char *_mcrypt_get_algorithms_name()
  248 {
  249 return "RC2";
  250 }
  251 
  252 #define CIPHER "becbe4c8e6237a14"
  253 
  254 WIN32DLL_DEFINE int _mcrypt_self_test()
  255 {
  256     char *keyword;
  257     unsigned char plaintext[16];
  258     unsigned char ciphertext[16];
  259     int blocksize = _mcrypt_get_block_size(), j;
  260     void *key;
  261     unsigned char cipher_tmp[200];
  262 
  263     keyword = calloc(1, _mcrypt_get_key_size());
  264     if (keyword == NULL)
  265         return -1;
  266 
  267     for (j = 0; j < _mcrypt_get_key_size(); j++) {
  268         keyword[j] = ((j * 2 + 10) % 256);
  269     }
  270 
  271     for (j = 0; j < blocksize; j++) {
  272         plaintext[j] = j % 256;
  273     }
  274 
  275     key = malloc(_mcrypt_get_size());
  276     if (key == NULL) {
  277         free(keyword);
  278         return -1;
  279     }
  280 
  281     memcpy(ciphertext, plaintext, blocksize);
  282 
  283     _mcrypt_set_key(key, (void *) keyword, _mcrypt_get_key_size());
  284     free(keyword);
  285 
  286     _mcrypt_encrypt(key, (void *) ciphertext);
  287 
  288     for (j = 0; j < blocksize; j++) {
  289         sprintf(&((char *) cipher_tmp)[2 * j], "%.2x",
  290             ciphertext[j]);
  291     }
  292 
  293     if (strcmp((char *) cipher_tmp, CIPHER) != 0) {
  294         printf("failed compatibility\n");
  295         printf("Expected: %s\nGot: %s\n", CIPHER,
  296                (char *) cipher_tmp);
  297         free(key);
  298         return -1;
  299     }
  300     _mcrypt_decrypt(key, (void *) ciphertext);
  301     free(key);
  302 
  303     if (strcmp(ciphertext, plaintext) != 0) {
  304         printf("failed internally\n");
  305         return -1;
  306     }
  307 
  308     return 0;
  309 }
  310 
  311 WIN32DLL_DEFINE word32 _mcrypt_algorithm_version()
  312 {
  313     return 20010801;
  314 }
  315 
  316 #ifdef WIN32
  317 # ifdef USE_LTDL
  318 WIN32DLL_DEFINE int main (void)
  319 {
  320        /* empty main function to avoid linker error (see cygwin FAQ) */
  321 }
  322 # endif
  323 #endif