From 8c4fcf5f9b4d0efab80442ce54114d16295a44f0 Mon Sep 17 00:00:00 2001
From: leslie <unknown>
Date: Tue, 15 Jan 2008 22:28:22 +0100
Subject: [PATCH] nagra: fix MECM cache for seedsize>5

---
 systems/nagra/nagra2-0101.c | 20 ++++++++++++--------
 systems/nagra/nagra2-0501.c |  4 ++--
 systems/nagra/nagra2.c      |  3 ++-
 systems/nagra/nagra2.h      |  3 ++-
 4 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/systems/nagra/nagra2-0101.c b/systems/nagra/nagra2-0101.c
index e0c085b..0a999d2 100644
--- a/systems/nagra/nagra2-0101.c
+++ b/systems/nagra/nagra2-0101.c
@@ -542,7 +542,8 @@ protected:
   int mecmAddr[2];
   int mecmKeyId;
   //
-  virtual bool Algo(int algo, unsigned char *hd, const unsigned char *ed, unsigned char *hw);
+  virtual bool Algo(int algo, const unsigned char *hd, unsigned char *hw);
+  virtual void DynamicHD(unsigned char *hd, const unsigned char *ed);
   virtual bool RomInit(void);
   virtual void Stepper(void);
   virtual void TimerHandler(unsigned int num);
@@ -564,7 +565,16 @@ cN2Prov0101::cN2Prov0101(int Id, int Flags)
   desSize=16; hwMapper=0;
 }
 
-bool cN2Prov0101::Algo(int algo, unsigned char *hd, const unsigned char *ed, unsigned char *hw)
+void cN2Prov0101::DynamicHD(unsigned char *hd, const unsigned char *ed)
+{
+  hd[5]=ed[5];
+  hd[6]=(ed[7]&0xEF) | ((ed[6]&0x40)>>2);
+  hd[7]=ed[8];
+  hd[8]=(ed[9]&0x7F) | ((ed[6]&0x20)<<2);
+  hd[9]=ed[6]&0x80;
+}
+
+bool cN2Prov0101::Algo(int algo, const unsigned char *hd, unsigned char *hw)
 {
   if(algo!=0x40 && algo!=0x60) {
     PRINTF(L_SYS_ECM,"%04X: unknown MECM algo %02x",id,algo);
@@ -603,12 +613,6 @@ bool cN2Prov0101::Algo(int algo, unsigned char *hd, const unsigned char *ed, uns
      return false;
     }
 
-  // dynamic expand
-  hd[5]=ed[5];
-  hd[6]=(ed[7]&0xEF) | ((ed[6]&0x40)>>2);
-  hd[7]=ed[8];
-  hd[8]=(ed[9]&0x7F) | ((ed[6]&0x20)<<2);
-  hd[9]=ed[6]&0x80;
   memcpy(hw,hd,seedSize);
   ExpandInput(hw);
 
diff --git a/systems/nagra/nagra2-0501.c b/systems/nagra/nagra2-0501.c
index 16a84a0..e5992c6 100644
--- a/systems/nagra/nagra2-0501.c
+++ b/systems/nagra/nagra2-0501.c
@@ -71,7 +71,7 @@ private:
   bool RomCallbacks(void);
   void AddRomCallbacks(void);
 protected:
-  virtual bool Algo(int algo, unsigned char *hd, const unsigned char *ed, unsigned char *hw);
+  virtual bool Algo(int algo, const unsigned char *hd, unsigned char *hw);
   virtual bool NeedsCwSwap(void) { return true; }
   virtual bool RomInit(void);
   virtual void TimerHandler(unsigned int num);
@@ -89,7 +89,7 @@ cN2Prov0501::cN2Prov0501(int Id, int Flags)
   hwMapper=0;
 }
 
-bool cN2Prov0501::Algo(int algo, unsigned char *hd, const unsigned char *ed, unsigned char *hw)
+bool cN2Prov0501::Algo(int algo, const unsigned char *hd, unsigned char *hw)
 {
   if(algo==0x60) {
     hw[0]=hd[0];
diff --git a/systems/nagra/nagra2.c b/systems/nagra/nagra2.c
index 84c2212..0589bb9 100644
--- a/systems/nagra/nagra2.c
+++ b/systems/nagra/nagra2.c
@@ -587,13 +587,14 @@ bool cN2Prov::MECM(unsigned char in15, int algo, const unsigned char *ed, unsign
   hd[2]=cw[15];
   hd[3]=cw[6];
   hd[4]=cw[7];
+  DynamicHD(hd,ed);
 
   if(keyValid && !memcmp(seed,hd,seedSize)) {	// key cached
     memcpy(buf,cwkey,8);
     }
   else {				// key not cached
     memset(hw,0,sizeof(hw));
-    if(!Algo(algo,hd,ed,hw)) return false;
+    if(!Algo(algo,hd,hw)) return false;
     memcpy(&hw[128],hw,64);
     RotateBytes(&hw[64],128);
     SHA1(&hw[64],128,buf);
diff --git a/systems/nagra/nagra2.h b/systems/nagra/nagra2.h
index be5ce30..db94f3f 100644
--- a/systems/nagra/nagra2.h
+++ b/systems/nagra/nagra2.h
@@ -201,7 +201,8 @@ protected:
   int id, flags, seedSize;
   cIDEA idea;
   //
-  virtual bool Algo(int algo, unsigned char *hd, const unsigned char *ed, unsigned char *hw) { return false; }
+  virtual bool Algo(int algo, const unsigned char *hd, unsigned char *hw) { return false; }
+  virtual void DynamicHD(unsigned char *hd, const unsigned char *ed) {}
   virtual bool NeedsCwSwap(void) { return false; }
   void ExpandInput(unsigned char *hw);
 public:
-- 
2.39.5