ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

rc2.c
Go to the documentation of this file.
00001 /*
00002  * dlls/rsaen/rc2.c
00003  * RC2 functions  
00004  *
00005  * Copyright 2004 Michael Jung
00006  * Based on public domain code by Tom St Denis (tomstdenis@iahu.ca)
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00021  */
00022 
00023 /*
00024  * This file contains code from the LibTomCrypt cryptographic 
00025  * library written by Tom St Denis (tomstdenis@iahu.ca). LibTomCrypt
00026  * is in the public domain. The code in this file is tailored to
00027  * special requirements. Take a look at http://libtomcrypt.org for the
00028  * original version. 
00029  */
00030 
00031 #include "tomcrypt.h"
00032 
00033 /* 256-entry permutation table, probably derived somehow from pi */
00034 static const unsigned char permute[256] = {
00035         217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
00036         198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
00037          23,154, 89,245,135,179, 79, 19, 97, 69,109,141,  9,129,125, 50,
00038         189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
00039          84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
00040          18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
00041         111,191, 14,218, 70,105,  7, 87, 39,242, 29,155,188,148, 67,  3,
00042         248, 17,199,246,144,239, 62,231,  6,195,213, 47,200,102, 30,215,
00043           8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
00044         150, 26,210,113, 90, 21, 73,116, 75,159,208, 94,  4, 24,164,236,
00045         194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
00046         153,124, 58,133, 35,184,180,122,252,  2, 54, 91, 37, 85,151, 49,
00047          45, 93,250,152,227,138,146,174,  5,223, 41, 16,103,108,186,201,
00048         211,  0,230,207,225,158,168, 44, 99, 22,  1, 63, 88,226,137,169,
00049          13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
00050         197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173
00051 };
00052 
00053 int rc2_setup(const unsigned char *key, int keylen, int bits, int rounds, rc2_key *rc2)
00054 {
00055    unsigned *xkey = rc2->xkey;
00056    unsigned char tmp[128];
00057    unsigned T8, TM;
00058    int i;
00059 
00060    if (keylen < 5 || keylen > 128) {
00061       return CRYPT_INVALID_KEYSIZE;
00062    }
00063 
00064    if (rounds != 0 && rounds != 16) {
00065       return CRYPT_INVALID_ROUNDS;
00066    }
00067 
00068     /* Following comment is from Eric Young's rc2 code: */
00069     /* It has come to my attention that there are 2 versions of the RC2
00070      * key schedule.  One which is normal, and anther which has a hook to
00071      * use a reduced key length.
00072      * BSAFE uses the 'retarded' version.  What I previously shipped is
00073      * the same as specifying 1024 for the 'bits' parameter.  BSAFE uses
00074      * a version where the bits parameter is the same as len*8 */
00075     /* Seems like MS uses the 'retarded' version, too.
00076      * Adjust effective keylen bits */
00077    if (bits <= 0) bits = keylen << 3;
00078    if (bits > 1024) bits = 1024;
00079    
00080    for (i = 0; i < keylen; i++) {
00081        tmp[i] = key[i] & 255;
00082    }
00083 
00084     /* Phase 1: Expand input key to 128 bytes */
00085     if (keylen < 128) {
00086         for (i = keylen; i < 128; i++) {
00087             tmp[i] = permute[(tmp[i - 1] + tmp[i - keylen]) & 255];
00088         }
00089     }
00090     
00091     /* Phase 2 - reduce effective key size to "bits" */
00092     /*bits = keylen<<3; */
00093     T8   = (unsigned)(bits+7)>>3;
00094     TM   = (255 >> (unsigned)(7 & -bits));
00095     tmp[128 - T8] = permute[tmp[128 - T8] & TM];
00096     for (i = 127 - T8; i >= 0; i--) {
00097         tmp[i] = permute[tmp[i + 1] ^ tmp[i + T8]];
00098     }
00099 
00100     /* Phase 3 - copy to xkey in little-endian order */
00101     for (i = 0; i < 64; i++) {
00102         xkey[i] =  (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8);
00103     }        
00104 
00105     return CRYPT_OK;
00106 }
00107 
00108 /**********************************************************************\
00109 * Encrypt an 8-byte block of plaintext using the given key.            *
00110 \**********************************************************************/
00111 void rc2_ecb_encrypt( const unsigned char *plain,
00112                             unsigned char *cipher,
00113                             rc2_key *rc2)
00114 {
00115     unsigned *xkey;
00116     unsigned x76, x54, x32, x10, i;
00117 
00118     xkey = rc2->xkey;
00119 
00120     x76 = ((unsigned)plain[7] << 8) + (unsigned)plain[6];
00121     x54 = ((unsigned)plain[5] << 8) + (unsigned)plain[4];
00122     x32 = ((unsigned)plain[3] << 8) + (unsigned)plain[2];
00123     x10 = ((unsigned)plain[1] << 8) + (unsigned)plain[0];
00124 
00125     for (i = 0; i < 16; i++) {
00126         x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF;
00127         x10 = ((x10 << 1) | (x10 >> 15));
00128 
00129         x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF;
00130         x32 = ((x32 << 2) | (x32 >> 14));
00131 
00132         x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF;
00133         x54 = ((x54 << 3) | (x54 >> 13));
00134 
00135         x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF;
00136         x76 = ((x76 << 5) | (x76 >> 11));
00137 
00138         if (i == 4 || i == 10) {
00139             x10 = (x10 + xkey[x76 & 63]) & 0xFFFF;
00140             x32 = (x32 + xkey[x10 & 63]) & 0xFFFF;
00141             x54 = (x54 + xkey[x32 & 63]) & 0xFFFF;
00142             x76 = (x76 + xkey[x54 & 63]) & 0xFFFF;
00143         }
00144     }
00145 
00146     cipher[0] = (unsigned char)x10;
00147     cipher[1] = (unsigned char)(x10 >> 8);
00148     cipher[2] = (unsigned char)x32;
00149     cipher[3] = (unsigned char)(x32 >> 8);
00150     cipher[4] = (unsigned char)x54;
00151     cipher[5] = (unsigned char)(x54 >> 8);
00152     cipher[6] = (unsigned char)x76;
00153     cipher[7] = (unsigned char)(x76 >> 8);
00154 }
00155 
00156 /**********************************************************************\
00157 * Decrypt an 8-byte block of ciphertext using the given key.           *
00158 \**********************************************************************/
00159 void rc2_ecb_decrypt( const unsigned char *cipher,
00160                             unsigned char *plain,
00161                             rc2_key *rc2)
00162 {
00163     unsigned x76, x54, x32, x10;
00164     unsigned *xkey;
00165     int i;
00166 
00167     xkey = rc2->xkey;
00168 
00169     x76 = ((unsigned)cipher[7] << 8) + (unsigned)cipher[6];
00170     x54 = ((unsigned)cipher[5] << 8) + (unsigned)cipher[4];
00171     x32 = ((unsigned)cipher[3] << 8) + (unsigned)cipher[2];
00172     x10 = ((unsigned)cipher[1] << 8) + (unsigned)cipher[0];
00173 
00174     for (i = 15; i >= 0; i--) {
00175         if (i == 4 || i == 10) {
00176             x76 = (x76 - xkey[x54 & 63]) & 0xFFFF;
00177             x54 = (x54 - xkey[x32 & 63]) & 0xFFFF;
00178             x32 = (x32 - xkey[x10 & 63]) & 0xFFFF;
00179             x10 = (x10 - xkey[x76 & 63]) & 0xFFFF;
00180         }
00181 
00182         x76 = ((x76 << 11) | (x76 >> 5));
00183         x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF;
00184 
00185         x54 = ((x54 << 13) | (x54 >> 3));
00186         x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF;
00187 
00188         x32 = ((x32 << 14) | (x32 >> 2));
00189         x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF;
00190 
00191         x10 = ((x10 << 15) | (x10 >> 1));
00192         x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF;
00193     }
00194 
00195     plain[0] = (unsigned char)x10;
00196     plain[1] = (unsigned char)(x10 >> 8);
00197     plain[2] = (unsigned char)x32;
00198     plain[3] = (unsigned char)(x32 >> 8);
00199     plain[4] = (unsigned char)x54;
00200     plain[5] = (unsigned char)(x54 >> 8);
00201     plain[6] = (unsigned char)x76;
00202     plain[7] = (unsigned char)(x76 >> 8);
00203 }

Generated on Sat May 26 2012 04:24:44 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.