SASC
DVBSoftCAM

crypto.c

Go to the documentation of this file.
00001 /*
00002  * Softcam plugin to VDR (C++)
00003  *
00004  * This code is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This code is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
00018  */
00019 
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <stdio.h>
00023 
00024 #include "crypto.h"
00025 #include "helper.h"
00026 #include "log.h"
00027 
00028 // -----------------------------------------------------------------------------
00029 
00030 void RotateBytes(unsigned char *out, const unsigned char *in, int n)
00031 {
00032   if(n>0) {
00033     out+=n;
00034     do { *(--out)=*(in++); } while(--n);
00035     }
00036 }
00037 
00038 void RotateBytes(unsigned char *in, int n)
00039 {
00040   if(n>1) {
00041     unsigned char *e=in+n-1;
00042     do {
00043       unsigned char temp=*in;
00044       *in++=*e;
00045       *e-- =temp;
00046       } while(in<e);
00047     }
00048 }
00049 
00050 // -- cBN ----------------------------------------------------------------------
00051 
00052 bool cBN::Get(const unsigned char *in, int n)
00053 {
00054   return BN_bin2bn(in,n,&big)!=0;
00055 }
00056 
00057 int cBN::Put(unsigned char *out, int n) const
00058 {
00059   int s=BN_num_bytes(&big);
00060   if(s>n) {
00061     unsigned char *buff=AUTOMEM(s);
00062     BN_bn2bin(&big,buff);
00063     memcpy(out,buff+s-n,n);
00064     }
00065   else if(s<n) {
00066     int l=n-s;
00067     memset(out,0,l);
00068     BN_bn2bin(&big,out+l);
00069     }
00070   else BN_bn2bin(&big,out);
00071   return s;
00072 }
00073 
00074 bool cBN::GetLE(const unsigned char *in, int n)
00075 {
00076   unsigned char *tmp=AUTOMEM(n);
00077   RotateBytes(tmp,in,n);
00078   return BN_bin2bn(tmp,n,&big)!=0;
00079 }
00080 
00081 int cBN::PutLE(unsigned char *out, int n) const
00082 {
00083   int s=Put(out,n);
00084   RotateBytes(out,n);
00085   return s;
00086 }
00087 
00088 // -- cIDEA --------------------------------------------------------------------
00089 
00090 #ifndef OPENSSL_HAS_IDEA
00091 #warning ** openssl lacks IDEA support. Using deprecated static support code. Update your openssl package.
00092 #include "support/i_cbc.c"
00093 #include "support/i_ecb.c"
00094 #include "support/i_skey.c"
00095 #endif
00096 
00097 void cIDEA::Decrypt(unsigned char *data, int len, const unsigned char *key, unsigned char *iv) const
00098 {
00099   unsigned char v[8];
00100   if(!iv) { memset(v,0,sizeof(v)); iv=v; }
00101   IDEA_KEY_SCHEDULE ks;
00102   idea_set_encrypt_key(key,&ks);
00103   idea_cbc_encrypt(data,data,len&~7,&ks,iv,IDEA_DECRYPT);
00104 }
00105 
00106 void cIDEA::Decrypt(const unsigned char *data, int len, unsigned char *decrypt, const unsigned char *key, unsigned char *iv) const
00107 {
00108   unsigned char v[8];
00109   if(!iv) { memset(v,0,sizeof(v)); iv=v; }
00110   IDEA_KEY_SCHEDULE ks;
00111   idea_set_encrypt_key(key,&ks);
00112   idea_cbc_encrypt(data,decrypt,len&~7,&ks,iv,IDEA_DECRYPT);
00113 }
00114 
00115 int cIDEA::Encrypt(const unsigned char *data, int len, unsigned char *crypt, const unsigned char *key, unsigned char *iv) const
00116 {
00117   unsigned char v[8];
00118   if(!iv) { memset(v,0,sizeof(v)); iv=v; }
00119   len&=~7;
00120   IDEA_KEY_SCHEDULE ks;
00121   idea_set_encrypt_key(key,&ks);
00122   idea_cbc_encrypt(data,crypt,len,&ks,iv,IDEA_ENCRYPT);
00123   return len;
00124 }
00125 
00126 void cIDEA::SetEncKey(const unsigned char *key, IdeaKS *ks) const
00127 {
00128   idea_set_encrypt_key(key,ks);
00129 }
00130 
00131 void cIDEA::SetDecKey(const unsigned char *key, IdeaKS *ks) const
00132 {
00133   IDEA_KEY_SCHEDULE tmp;
00134   idea_set_encrypt_key(key,&tmp);
00135   idea_set_decrypt_key(&tmp,ks);
00136 }
00137 
00138 void cIDEA::Decrypt(unsigned char *data, int len, IdeaKS *ks, unsigned char *iv) const
00139 {
00140   unsigned char v[8];
00141   if(!iv) { memset(v,0,sizeof(v)); iv=v; }
00142   idea_cbc_encrypt(data,data,len&~7,ks,iv,IDEA_DECRYPT);
00143 }
00144 
00145 int cIDEA::Encrypt(const unsigned char *data, int len, unsigned char *crypt, IdeaKS *ks, unsigned char *iv) const
00146 {
00147   unsigned char v[8];
00148   if(!iv) { memset(v,0,sizeof(v)); iv=v; }
00149   idea_cbc_encrypt(data,crypt,len&~7,ks,iv,IDEA_ENCRYPT);
00150   return len;
00151 }
00152 
00153 void cIDEA::EcbEncrypt(const unsigned char *data, int len, unsigned char *crypt, IdeaKS *ks) const
00154 {
00155   len/=8;
00156   while(len>0) {
00157     idea_ecb_encrypt(data,crypt,ks);
00158     data+=8;
00159     crypt+=8;
00160     }
00161 }
00162 
00163 // -- cRSA ---------------------------------------------------------------------
00164 
00165 bool cRSA::Input(cBN *d, const unsigned char *in, int n, bool LE) const
00166 {
00167   if(LE) return d->GetLE(in,n); 
00168   else   return d->Get(in,n);
00169 }
00170 
00171 int cRSA::Output(unsigned char *out, int n, cBN *r, bool LE) const
00172 {
00173   if(LE) return r->PutLE(out,n);
00174   else   return r->Put(out,n);
00175 }
00176 
00177 int cRSA::RSA(unsigned char *out, const unsigned char *in, int n, const BIGNUM *exp, const BIGNUM *mod, bool LE) const
00178 {
00179   cBNctx ctx;
00180   cBN r, d;
00181   if(Input(&d,in,n,LE)) {
00182     if(BN_mod_exp(r,d,exp,mod,ctx)) return Output(out,n,&r,LE);
00183     PRINTF(L_GEN_ERROR,"rsa: mod-exp failed");
00184     }
00185   return 0;
00186 }
00187 
00188 int cRSA::RSA(BIGNUM *out, const unsigned char *in, int n, const BIGNUM *exp, const BIGNUM *mod, bool LE) const
00189 {
00190   cBNctx ctx;
00191   cBN d;
00192   if(Input(&d,in,n,LE)) {
00193     if(BN_mod_exp(out,d,exp,mod,ctx)) return BN_num_bytes(out);
00194     PRINTF(L_GEN_ERROR,"rsa: mod-exp failed");
00195     }
00196   return 0;
00197 }
00198 
00199 int cRSA::RSA(unsigned char *out, int n, BIGNUM *in, const BIGNUM *exp, const BIGNUM *mod, bool LE) const
00200 {
00201   cBNctx ctx;
00202   cBN r;
00203   if(BN_mod_exp(r,in,exp,mod,ctx)) return Output(out,n,&r,LE);
00204   PRINTF(L_GEN_ERROR,"rsa: mod-exp failed");
00205   return 0;
00206 }
00207 
00208 // -- cDes ---------------------------------------------------------------------
00209 
00210 const unsigned char cDes::_PC1[] = {
00211    57,49,41,33,25,17, 9, 1, 
00212    58,50,42,34,26,18,10, 2,
00213    59,51,43,35,27,19,11, 3,
00214    60,52,44,36,63,55,47,39,
00215    31,23,15, 7,62,54,46,38,
00216    30,22,14, 6,61,53,45,37,
00217    29,21,13, 5,28,20,12, 4
00218   };
00219 
00220 const unsigned char cDes::_PC2[] = {
00221   14,17,11,24, 1, 5,   3,28,15, 6,21,10,
00222   23,19,12, 4,26, 8,  16, 7,27,20,13, 2,
00223   41,52,31,37,47,55,  30,40,51,45,33,48,
00224   44,49,39,56,34,53,  46,42,50,36,29,32
00225   };
00226 
00227 const unsigned char cDes::_E[] = {
00228   32, 1, 2, 3, 4, 5,   4, 5, 6, 7, 8, 9,
00229    8, 9,10,11,12,13,  12,13,14,15,16,17,
00230   16,17,18,19,20,21,  20,21,22,23,24,25,
00231   24,25,26,27,28,29,  28,29,30,31,32, 1
00232   };
00233 
00234 const unsigned char cDes::_P[] = {
00235   16, 7,20,21,  29,12,28,17,
00236    1,15,23,26,   5,18,31,10,
00237    2, 8,24,14,  32,27, 3, 9,
00238   19,13,30, 6,  22,11, 4,25
00239   };
00240 
00241 const unsigned char cDes::IP[] = {
00242   58,50,42,34,26,18,10,2,  60,52,44,36,28,20,12,4,
00243   62,54,46,38,30,22,14,6,  64,56,48,40,32,24,16,8,
00244   57,49,41,33,25,17, 9,1,  59,51,43,35,27,19,11,3,
00245   61,53,45,37,29,21,13,5,  63,55,47,39,31,23,15,7
00246   };
00247 
00248 const unsigned char cDes::FP[] = {
00249   40,8,48,16,56,24,64,32,  39,7,47,15,55,23,63,31,
00250   38,6,46,14,54,22,62,30,  37,5,45,13,53,21,61,29,
00251   36,4,44,12,52,20,60,28,  35,3,43,11,51,19,59,27,
00252   34,2,42,10,50,18,58,26,  33,1,41, 9,49,17,57,25
00253   };
00254 
00255 const unsigned char cDes::S[][64] = {
00256   { 0xe,0x0,0x4,0xf,0xd,0x7,0x1,0x4,  0x2,0xe,0xf,0x2,0xb,0xd,0x8,0x1,
00257     0x3,0xa,0xa,0x6,0x6,0xc,0xc,0xb,  0x5,0x9,0x9,0x5,0x0,0x3,0x7,0x8,
00258     0x4,0xf,0x1,0xc,0xe,0x8,0x8,0x2,  0xd,0x4,0x6,0x9,0x2,0x1,0xb,0x7,
00259     0xf,0x5,0xc,0xb,0x9,0x3,0x7,0xe,  0x3,0xa,0xa,0x0,0x5,0x6,0x0,0xd
00260   },
00261   { 0xf,0x3,0x1,0xd,0x8,0x4,0xe,0x7,  0x6,0xf,0xb,0x2,0x3,0x8,0x4,0xe,
00262     0x9,0xc,0x7,0x0,0x2,0x1,0xd,0xa,  0xc,0x6,0x0,0x9,0x5,0xb,0xa,0x5,
00263     0x0,0xd,0xe,0x8,0x7,0xa,0xb,0x1,  0xa,0x3,0x4,0xf,0xd,0x4,0x1,0x2,
00264     0x5,0xb,0x8,0x6,0xc,0x7,0x6,0xc,  0x9,0x0,0x3,0x5,0x2,0xe,0xf,0x9
00265   },
00266   { 0xa,0xd,0x0,0x7,0x9,0x0,0xe,0x9,  0x6,0x3,0x3,0x4,0xf,0x6,0x5,0xa,
00267     0x1,0x2,0xd,0x8,0xc,0x5,0x7,0xe,  0xb,0xc,0x4,0xb,0x2,0xf,0x8,0x1,
00268     0xd,0x1,0x6,0xa,0x4,0xd,0x9,0x0,  0x8,0x6,0xf,0x9,0x3,0x8,0x0,0x7,
00269     0xb,0x4,0x1,0xf,0x2,0xe,0xc,0x3,  0x5,0xb,0xa,0x5,0xe,0x2,0x7,0xc
00270   },
00271   { 0x7,0xd,0xd,0x8,0xe,0xb,0x3,0x5,  0x0,0x6,0x6,0xf,0x9,0x0,0xa,0x3,
00272     0x1,0x4,0x2,0x7,0x8,0x2,0x5,0xc,  0xb,0x1,0xc,0xa,0x4,0xe,0xf,0x9,
00273     0xa,0x3,0x6,0xf,0x9,0x0,0x0,0x6,  0xc,0xa,0xb,0x1,0x7,0xd,0xd,0x8,
00274     0xf,0x9,0x1,0x4,0x3,0x5,0xe,0xb,  0x5,0xc,0x2,0x7,0x8,0x2,0x4,0xe
00275   },
00276   { 0x2,0xe,0xc,0xb,0x4,0x2,0x1,0xc,  0x7,0x4,0xa,0x7,0xb,0xd,0x6,0x1,
00277     0x8,0x5,0x5,0x0,0x3,0xf,0xf,0xa,  0xd,0x3,0x0,0x9,0xe,0x8,0x9,0x6,
00278     0x4,0xb,0x2,0x8,0x1,0xc,0xb,0x7,  0xa,0x1,0xd,0xe,0x7,0x2,0x8,0xd,
00279     0xf,0x6,0x9,0xf,0xc,0x0,0x5,0x9,  0x6,0xa,0x3,0x4,0x0,0x5,0xe,0x3
00280   },
00281   { 0xc,0xa,0x1,0xf,0xa,0x4,0xf,0x2,  0x9,0x7,0x2,0xc,0x6,0x9,0x8,0x5,
00282     0x0,0x6,0xd,0x1,0x3,0xd,0x4,0xe,  0xe,0x0,0x7,0xb,0x5,0x3,0xb,0x8,
00283     0x9,0x4,0xe,0x3,0xf,0x2,0x5,0xc,  0x2,0x9,0x8,0x5,0xc,0xf,0x3,0xa,
00284     0x7,0xb,0x0,0xe,0x4,0x1,0xa,0x7,  0x1,0x6,0xd,0x0,0xb,0x8,0x6,0xd
00285   },
00286   { 0x4,0xd,0xb,0x0,0x2,0xb,0xe,0x7,  0xf,0x4,0x0,0x9,0x8,0x1,0xd,0xa,
00287     0x3,0xe,0xc,0x3,0x9,0x5,0x7,0xc,  0x5,0x2,0xa,0xf,0x6,0x8,0x1,0x6,
00288     0x1,0x6,0x4,0xb,0xb,0xd,0xd,0x8,  0xc,0x1,0x3,0x4,0x7,0xa,0xe,0x7,
00289     0xa,0x9,0xf,0x5,0x6,0x0,0x8,0xf,  0x0,0xe,0x5,0x2,0x9,0x3,0x2,0xc
00290   },
00291   { 0xd,0x1,0x2,0xf,0x8,0xd,0x4,0x8,  0x6,0xa,0xf,0x3,0xb,0x7,0x1,0x4,
00292     0xa,0xc,0x9,0x5,0x3,0x6,0xe,0xb,  0x5,0x0,0x0,0xe,0xc,0x9,0x7,0x2,
00293     0x7,0x2,0xb,0x1,0x4,0xe,0x1,0x7,  0x9,0x4,0xc,0xa,0xe,0x8,0x2,0xd,
00294     0x0,0xf,0x6,0xc,0xa,0x9,0xd,0x0,  0xf,0x3,0x3,0x5,0x5,0x6,0x8,0xb
00295   } };
00296 
00297 const unsigned char cDes::LS[] = { 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1 };
00298 
00299 /* actualy slower ... :-(
00300 #if defined __GNUC__ && __GNUC__ >= 2
00301 #define shiftin(V,R,n) ({unsigned int VV; \
00302                          __asm__ ("btl %3,%2\n\tadcl %0,%0" : "=g" (VV) : "0" (V), "g" (R), "r" (n) : "cc"); \
00303                          VV; })
00304 #else
00305 */
00306 #define shiftin(V,R,n) ((V<<1)+(((R)>>(n))&1))
00307 #define rol28(V,n) ((V<<(n) ^ V>>(28-(n)))&0xfffffffL)
00308 #define ror28(V,n) ((V>>(n) ^ V<<(28-(n)))&0xfffffffL)
00309 
00310 #if defined __GNUC__ && __GNUC__ >= 2
00311 #if defined __i486__ || defined __pentium__ || defined __pentiumpro__ || defined __amd64__
00312 #define hash(T) ({unsigned int TT; \
00313                  __asm__("bswapl %k0\n\trorw $8,%w0\n\tbswapl %k0" : "=g" (TT) : "0" (T) : "cc"); \
00314                  TT; })
00315 #elif defined __i386__
00316 #define hash(T) ({unsigned int TT; \
00317                  __asm__("rorl $16,%k0\n\trorw $8,%w0\n\troll $16,%k0" : "=g" (TT) : "0" (T) : "cc"); \
00318                  TT; })
00319 #endif
00320 #endif
00321 #ifndef hash // fallback default
00322 #define hash(T) ((T&0x0000ffffL) | ((T>>8)&0x00ff0000L) | ((T<<8)&0xff000000L))
00323 #endif
00324 
00325 #define DESROUND(C,D,T) { \
00326    unsigned int s=0; \
00327    for(int j=7, k=0; j>=0; j--) { \
00328      unsigned int v=0, K=0; \
00329      for(int t=5; t>=0; t--, k++) { \
00330        v=shiftin(v,T,E[k]); \
00331        if(PC2[k]<29) K=shiftin(K,C,28-PC2[k]); \
00332        else          K=shiftin(K,D,56-PC2[k]); \
00333        } \
00334      s=(s<<4) + S[7-j][v^K]; \
00335      } \
00336    T=0; \
00337    for(int j=31; j>=0; j--) T=shiftin(T,s,P[j]); \
00338    }
00339 
00340 #define DESHASH(T) { if(mode&DES_HASH) T=hash(T); }
00341 
00342 cDes::cDes(const unsigned char *pc1, const unsigned char *pc2)
00343 {
00344   PC1=pc1 ? pc1 : _PC1;
00345   PC2=pc2 ? pc2 : _PC2;
00346   for(int i=0; i<48; i++) E[i]=32-_E[i];
00347   for(int i=0; i<32; i++) P[i]=32-_P[31-i];
00348 }
00349 
00350 void cDes::Permute(unsigned char *data, const unsigned char *P, int n) const
00351 {
00352   unsigned char pin[8];
00353   for(int i=0, k=0; k<n; i++) {
00354     int p=0;
00355     for(int j=7; j>=0; j--,k++) {
00356       const int t=P[k]-1;
00357       p=shiftin(p,data[t>>3],7-(t&7));
00358       }
00359     pin[i]=p;
00360     }
00361   memcpy(data,pin,8);
00362 }
00363 
00364 void cDes::Des(unsigned char *data, const unsigned char *key, int mode) const
00365 {
00366   unsigned char mkey[8];
00367   if(mode&DES_PC1) {
00368     memcpy(mkey,key,sizeof(mkey));
00369     Permute(mkey,PC1,56);
00370     key=mkey;
00371     }
00372   if(mode&DES_IP) Permute(data,IP,64);
00373   unsigned int C=UINT32_BE(key  ) >> 4;
00374   unsigned int D=UINT32_BE(key+3) & 0xfffffffL;
00375   unsigned int L=UINT32_BE(data  );
00376   unsigned int R=UINT32_BE(data+4);
00377   if(!(mode&DES_RIGHT)) {
00378     for(int i=15; i>=0; i--) {
00379       C=rol28(C,LS[15-i]); D=rol28(D,LS[15-i]);
00380       unsigned int T=R;
00381       if(mode&DES_MOD) T=Mod(T,key[7]); // apply costum mod e.g. Viaccess
00382       DESROUND(C,D,T);
00383       DESHASH(T);
00384       T^=L; L=R; R=T;
00385       }
00386     }
00387   else {
00388     for(int i=15; i>=0; i--) {
00389       unsigned int T=R;
00390       if(mode&DES_MOD) T=Mod(T,key[7]); // apply costum mod e.g. Viaccess
00391       DESROUND(C,D,T);
00392       DESHASH(T);
00393       T^=L; L=R; R=T;
00394       C=ror28(C,LS[i]); D=ror28(D,LS[i]);
00395       }
00396     }
00397   BYTE4_BE(data  ,R);
00398   BYTE4_BE(data+4,L);
00399   if(mode&DES_FP) Permute(data,FP,64);
00400 }
00401 
00402 // -- cAES ---------------------------------------------------------------------
00403 
00404 #ifndef OPENSSL_HAS_AES
00405 #warning ** openssl lacks AES support. Using deprecated static support code. Update your openssl package.
00406 #include "support/aes_core.c"
00407 #endif
00408 
00409 cAES::cAES(void)
00410 {
00411   active=false;
00412 }
00413 
00414 void cAES::SetKey(const unsigned char *key)
00415 {
00416   AES_set_decrypt_key(key,128,&dkey);
00417   AES_set_encrypt_key(key,128,&ekey);
00418   active=true;
00419 }
00420 
00421 int cAES::Encrypt(const unsigned char *data, int len, unsigned char *crypt) const
00422 {
00423   if(active) {
00424     len=(len+15)&(~15); // pad up to a multiple of 16
00425     for(int i=0; i<len; i+=16) AES_encrypt(data+i,crypt+i,(const AES_KEY *)&ekey);
00426     return len;
00427     }
00428   return -1;
00429 }
00430 
00431 bool cAES::Decrypt(unsigned char *data, int len) const
00432 {
00433   if(active) {
00434     for(int i=0; i<len; i+=16) AES_decrypt(data+i,data+i,(const AES_KEY *)&dkey);
00435     return true;
00436     }
00437   return false;
00438 }
00439 
00440 bool cAES::Decrypt(const unsigned char *data, int len, unsigned char *decrypt) const
00441 {
00442   if(active) {
00443     for(int i=0; i<len; i+=16) AES_decrypt(data+i,decrypt+i,(const AES_KEY *)&dkey);
00444     return true;
00445     }
00446   return false;
00447 }
00448 
00449 // -- cRC6 ---------------------------------------------------------------------
00450 
00451 /*
00452  * This code implements the RC6-32/20 block cipher.
00453  *
00454  * The algorithm is due to Ron Rivest and RSA Labs. This code is based on code
00455  * which was written by Martin Hinner <mhi@penguin.cz> in 1999, no copyright is
00456  * claimed.
00457  */
00458 
00459 #define RC6_WORDSIZE    32
00460 #define RC6_P32         0xB7E15163L
00461 #define RC6_Q32         0x9E3779B9L
00462 
00463 unsigned int cRC6::rol(unsigned int v, unsigned int cnt)
00464 {
00465   cnt&=(RC6_WORDSIZE-1);
00466   return (v<<cnt) | (v>>(RC6_WORDSIZE-cnt));
00467 }
00468 
00469 unsigned int cRC6::ror(unsigned int v, unsigned int cnt)
00470 {
00471   cnt&=(RC6_WORDSIZE-1);
00472   return (v>>cnt) | (v<<(RC6_WORDSIZE-cnt));
00473 }
00474 
00475 void cRC6::SetKey(const unsigned char *Key, int len)
00476 {
00477   key[0]=RC6_P32;
00478   for(int v=1; v<RC6_MAX; v++) key[v]=key[v-1]+RC6_Q32;
00479   len/=4;
00480   unsigned int a=0, b=0, *l=AUTOARRAY(unsigned int,len);
00481   memcpy(l,Key,len*4);
00482   for(int i=0,j=0,v=3*(len>RC6_MAX ? len : RC6_MAX) ; v>0; v--) {
00483     a=key[i]=rol(key[i]+a+b,3);
00484     b=  l[j]=rol(  l[j]+a+b,a+b);
00485     i++; i%=RC6_MAX;
00486     j++; j%=len;
00487     }
00488 }
00489 
00490 void cRC6::Decrypt(unsigned char *data)
00491 {
00492   Decrypt(data,data);
00493 }
00494 
00495 void cRC6::Decrypt(const unsigned char *in, unsigned char *out)
00496 {
00497   unsigned int *l=(unsigned int *)in;
00498   unsigned int a, b, c, d;
00499   a=l[0]-key[RC6_MAX-2];
00500   b=l[1];
00501   c=l[2]-key[RC6_MAX-1];
00502   d=l[3];
00503   for(int i=RC6_ROUNDS; i>0; i--) {
00504     unsigned int t=a;
00505     unsigned int u=b;
00506     a=d; d=c; b=t; c=u;
00507     u=rol((d*(2*d+1)),5);
00508     t=rol((b*(2*b+1)),5);
00509     c=ror(c-key[2*i+1],t)^u;
00510     a=ror(a-key[2*i  ],u)^t;
00511     }
00512   l=(unsigned int *)out;
00513   l[0]=a;
00514   l[1]=b-key[0];
00515   l[2]=c;
00516   l[3]=d-key[1];
00517 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines