--- sc/PLUGINS/src/sc-src/systems/nagra/nagra1.c (revision 103) +++ sc/PLUGINS/src/sc-src/systems/nagra/nagra1.c (working copy) @@ -27,6 +27,7 @@ #include "system.h" #include "misc.h" #include "opts.h" +#include "helper.h" #include "debug.h" #include "nagra.h" @@ -512,7 +513,7 @@ for(int j=0; j staticPL0501; +static cN2ProvLinkReg staticPL0501; + +bool cN2Prov0501::Algo(int algo, const unsigned char *hd, unsigned char *hw) +{ + if(algo==0x60) { + hw[0]=hd[0]; + hw[1]=hd[1]; + hw[2]=hd[2]&0xF8; + ExpandInput(hw); + hw[63]|=0x80; + hw[95]=hw[127]=hw[95]&0x7F; + SetWordSize(4); + ImportReg(IMPORT_J,hw+0x18); + ImportReg(IMPORT_D,hw+0x20); + ImportReg(IMPORT_A,hw+0x60); + DoMap(0x37,hw+0x40); + ExportReg(EXPORT_C,hw); + DoMap(0x3a); + ExportReg(EXPORT_C,hw+0x20); + DoMap(0x43); + DoMap(0x44,hw); + hw[0]&=7; + ExportReg(EXPORT_B,hw+3); + memset(hw+3+0x20,0,128-(3+0x20)); + return true; + } + + PRINTF(L_SYS_ECM,"0501: unknown MECM algo %02x",algo); + return false; +} --- sc/PLUGINS/src/sc-src/systems/nagra/nagra2.c (revision 103) +++ sc/PLUGINS/src/sc-src/systems/nagra/nagra2.c (working copy) @@ -88,6 +88,155 @@ return true; } +// -- cMapCore ----------------------------------------------------------------- + +#define SETSIZE 0x02 +#define IMPORT_J 0x03 +#define IMPORT_A 0x04 +#define IMPORT_B 0x05 +#define IMPORT_C 0x06 +#define IMPORT_D 0x07 +#define EXPORT_A 0x0A +#define EXPORT_B 0x0B +#define EXPORT_C 0x0C +#define EXPORT_D 0x0D + +class cMapCore { +private: + cBN x, y, s, j; + SHA_CTX sctx; +protected: + cBN A, B, C, D, J; + cBN H, R; + cBNctx ctx; + int wordsize; + // + void ImportReg(unsigned char reg, const unsigned char *data, int l=0); + void ExportReg(unsigned char reg, unsigned char *data, int l=0, bool BE=false); + void SetWordSize(int l) { wordsize=l; } + void MakeJ(void); + void MonMul(BIGNUM *o, BIGNUM *i1, BIGNUM *i2); + bool DoMap(int f, unsigned char *data=0, int l=0); +public: + cMapCore(void); + }; + +cMapCore::cMapCore(void) +{ + wordsize=4; +} + +void cMapCore::ImportReg(unsigned char reg, const unsigned char *in, int l) +{ + l=(l?l:wordsize)<<3; + switch(reg) { + case IMPORT_J: J.GetLE(in,8); break; + case IMPORT_A: A.GetLE(in,l); break; + case IMPORT_B: B.GetLE(in,l); break; + case IMPORT_C: C.GetLE(in,l); break; + case IMPORT_D: D.GetLE(in,l); break; + default: PRINTF(L_GEN_DEBUG,"internal: nagramap import register not supported"); return; + } +} + +void cMapCore::ExportReg(unsigned char reg, unsigned char *out, int l, bool BE) +{ + l=(l?l:wordsize)<<3; + cBN *ptr; + switch(reg) { + case EXPORT_A: ptr=&A; break; + case EXPORT_B: ptr=&B; break; + case EXPORT_C: ptr=&C; break; + case EXPORT_D: ptr=&D; break; + default: PRINTF(L_GEN_DEBUG,"internal: nagramap export register not supported"); return; + } + if(!BE) ptr->PutLE(out,l); + else ptr->Put(out,l); +} + +void cMapCore::MakeJ(void) +{ +#if OPENSSL_VERSION_NUMBER < 0x0090700fL +#error BN_mod_inverse is probably buggy in your openssl version +#endif + BN_zero(x); + BN_sub(J,x,D); + BN_set_bit(J,0); + BN_set_bit(x,64); + BN_mod_inverse(J,J,x,ctx); +} + +void cMapCore::MonMul(BIGNUM *o, BIGNUM *i1, BIGNUM *i2) +{ + int words=(BN_num_bytes(i1)+7)>>3; + BN_zero(s); + for(int i=0; i1) RotateBytes(data,wordsize); + SHA1_Update(&sctx,data,wordsize); + } + memset(data,0,64); + SHA1_Final(data+64,&sctx); + break; + default: + return false; + } + return true; +} + // -- cN2Prov ------------------------------------------------------------------ class cN2Prov { @@ -274,12 +423,12 @@ // expand IDEA-G key unsigned char idata[96]; for(int i=11; i>=0; i--) { - const int off=i*8; - memcpy(&idata[off],&key[13],8); - idata[off]^=i; - idea.Decrypt(&idata[off],8,&ks,0); - for(int j=7; j>=0; j--) idata[off+j] ^= key[13+j]; - idata[off]^=i; + unsigned char *d=&idata[i*8]; + memcpy(d,&key[13],8); + *d^=i; + idea.Decrypt(d,8,&ks,0); + xxor(d,8,d,&key[13]); + *d^=i; } // Calculate P idata[0] |= 0x80; @@ -302,7 +451,7 @@ idea.SetEncKey(buff,&ks); memcpy(buff,buff+8,8); idea.Encrypt(msg+i,8,buff+8,&ks,0); - for(int j=7; j>=0; j--) buff[j+8]^=msg[i+j]; + xxor(&buff[8],8,&buff[8],msg+i); } buff[8]&=0x7F; return (memcmp(sig,buff+8,8)==0); @@ -467,7 +616,7 @@ break; case 0x00: i+=2; break; - case 0x13 ... 0x15: + case 0x13 ... 0x17: i+=4; break; case 0x30 ... 0x36: case 0xB0: @@ -592,11 +741,12 @@ i+=emmdata[i+1]+2+4; break; case 0xA6: - i+=emmdata[i+1]+1; + i+=15; + break; + case 0xAE: + i+=11; break; - case 0x13: - case 0x14: - case 0x15: + case 0x13 ... 0x17: // Date i+=4; break; case 0xB0: // Update with ROM101 CPU code