All pastes #590467 Raw Edit

sasc-ng mecm

public cpp v1 · immutable
#590467 ·published 2007-06-26 16:04 UTC
rendered paste body
--- 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<rounds; j++) {     unsigned char cr[8];     Crypt(block+j*8,hash,cr);-    for(int i=0; i<8; i++) hash[i]=cr[i]^block[j*8+i];+    xxor(hash,8,cr,&block[j*8]);     }   return (0==memcmp(hash,sig,8)); }--- sc/PLUGINS/src/sc-src/systems/nagra/nagra2-0501.c	(revision 103)+++ sc/PLUGINS/src/sc-src/systems/nagra/nagra2-0501.c	(working copy)@@ -17,13 +17,82 @@  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html  */ -// -- cN2Prov0501 ----------------------------------------------------------------+// -- cMap0501 ----------------------------------------------------------------- -class cN2Prov0501 : public cN2Prov {+class cMap0501 : public cMapCore {+private: protected:+  void DoMap(int f, unsigned char *data=0, int l=0);+public:+  cMap0501(void);+  };++cMap0501::cMap0501(void)+{+}++void cMap0501::DoMap(int f, unsigned char *data, int l)+{+  dl(printf("0501: calling function %02X",f));+  switch(f) {+    case 0x37:+      l=(l?l:wordsize)<<3;+      H.GetLE(data,l);+      MonMul(B,H,A);+      break;+    case 0x3a:+      MakeJ();+      BN_zero(R);+      BN_set_bit(R,68*wordsize);+      BN_mod(H,R,D,ctx);+      for(int i=0; i<4; i++) MonMul(H,H,H);+      MonMul(B,A,H);+      MonMul(B,A,B);+      break;+    default:+      if(!cMapCore::DoMap(f,data,l))+        dl(printf("0501: unsupported call %02x",f));+      break;+    }+}++// -- cN2Prov0501 --------------------------------------------------------------++class cN2Prov0501 : public cN2Prov, private cMap0501 {+protected:+  virtual bool Algo(int algo, const unsigned char *hd, unsigned char *hw);   virtual bool NeedsCwSwap(void) { return true; } public:   cN2Prov0501(int Id, int Flags):cN2Prov(Id,Flags) {}   }; -static cN2ProvLinkReg<cN2Prov0501,0x0501,N2FLAG_INV> staticPL0501;+static cN2ProvLinkReg<cN2Prov0501,0x0501,N2FLAG_MECM|N2FLAG_INV> 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;+    }++  dl(printf("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: dl(printf("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: dl(printf("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; i<words; i++) {+    BN_rshift(x,i1,i<<6);+    BN_mask_bits(x,64);+    BN_mul(x,x,i2,ctx);+    BN_add(s,s,x);++    BN_copy(x,s);+    BN_mask_bits(x,64);+    BN_mul(x,x,J,ctx);+    if(i==(words-1)) {+      BN_lshift(y,x,64);+      BN_add(y,y,x);+      // Low+      BN_rshift(C,y,2);+      BN_add(C,C,s);+      BN_rshift(C,C,52);+      BN_mask_bits(C,12);+      }++    BN_mask_bits(x,64);+    BN_mul(x,x,D,ctx);+    BN_add(s,s,x);+    if(i==(words-1)) {+      // High+      BN_lshift(y,s,12);+      BN_add(C,C,y);+      BN_mask_bits(C,wordsize<<6);+      }++    BN_rshift(s,s,64);+    if(BN_cmp(s,D)==1) {+      BN_copy(x,s);+      BN_sub(s,x,D);+      }+    }+  BN_copy(o,s);+}++bool cMapCore::DoMap(int f, unsigned char *data, int l)+{+  switch(f) {+    case 0x43: // init SHA1+      SHA1_Init(&sctx);+      break;+    case 0x44: // add 64 bytes to SHA1 buffer+      RotateBytes(data,64);+      SHA1_Update(&sctx,data,64);+      BYTE4_LE(data   ,sctx.h4);+      BYTE4_LE(data+4 ,sctx.h3);+      BYTE4_LE(data+8 ,sctx.h2);+      BYTE4_LE(data+12,sctx.h1);+      BYTE4_LE(data+16,sctx.h0);+      break;+    case 0x45: // add wordsize bytes to SHA1 buffer and finalize SHA result+      if(wordsize) {+        if(wordsize>1) 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