|
SASC
DVBSoftCAM
|
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 }