From 216c372dae457bb3ffa3498dbf210173792d32a2 Mon Sep 17 00:00:00 2001 From: mfong Date: Wed, 19 Mar 2008 01:05:39 +0100 Subject: [PATCH] nagra: various MAP & timing updates --- systems/nagra/nagra2-0101.c | 132 +++++++++++++++++++++++------------- systems/nagra/nagra2.c | 65 ++++++++++++------ systems/nagra/nagra2.h | 5 +- 3 files changed, 132 insertions(+), 70 deletions(-) diff --git a/systems/nagra/nagra2-0101.c b/systems/nagra/nagra2-0101.c index f5bb3c7..d396797 100644 --- a/systems/nagra/nagra2-0101.c +++ b/systems/nagra/nagra2-0101.c @@ -439,17 +439,19 @@ void cMap0101::DoMap(int f, unsigned char *data, int l) case 0x29: { BN_add(B,B,C); - if(l<=0) l=wordsize; // conditional seems pretty useless - bool b=BN_is_bit_set(B,l<<6); - data[0]=b; - if(b) BN_mask_bits(B,l<<6); - cycles=504+(8*l)-((8*l-2)%5)-6; + bool b=BN_is_bit_set(B,wordsize<<6); + if(data) data[0]=b; + if(b) BN_mask_bits(B,wordsize<<6); + cycles=501+(8*wordsize+3)/5*5-6; } break; case 0x32: + l=min(34,l); A.GetLE(data,l<<3); BN_div(C,B,A,D,ctx); - BN_zero(A); + BN_rshift(A,C,17*64); + BN_mask_bits(C,17*64); + BN_zero(J); break; case 0x3b: MonInit(wordsize*60+4*l); @@ -490,45 +492,74 @@ void cMap0101::DoMap(int f, unsigned char *data, int l) #endif { cBN a, b, x, y, scalar; - D.GetLE(data+0x00,16); - x.GetLE(data+0x10,16); - y.GetLE(data+0x20,16); - b.GetLE(data+0x30,16); - a.GetLE(data+0x40,16); - scalar.GetLE(data+0x50,16); + if(l<2 || l>4) l=4; + TMPWS_START(l); + l<<=3; + D.GetLE(data+0*l,l); + x.GetLE(data+1*l,l); + y.GetLE(data+2*l,l); + b.GetLE(data+3*l,l); + a.GetLE(data+4*l,l); + scalar.GetLE(data+5*l,l); + bool doz=false; int scalarbits=BN_num_bits(scalar); - if(scalarbits>=2 && !BN_is_zero(x) && !BN_is_zero(y) && !BN_is_zero(b)) { - CurveInit(a); - ToProjective(0,x,y); - BN_copy(Qx,Px); - BN_copy(Qy,Py); - for(int i=scalarbits-2; i>=0; i--) { - DoubleP(0); - if(BN_is_bit_set(scalar,i)) { - BN_copy(A,Pz); - if(BN_is_zero(Pz)) { - BN_copy(Px,Qx); - BN_copy(Py,Qy); - BN_copy(Pz,Qz); - AddP(1); - } - else { - BN_mask_bits(Px,32); - BN_lshift(b,Qz,32); - BN_add(Px,Px,b); - BN_mask_bits(Px,128); - AddP(0); + if(scalarbits>=2) { + if(BN_is_zero(x) && (BN_is_zero(y) || (BN_is_zero(b) && BN_num_bits(y)==1))) { + BN_zero(Px); + BN_copy(Py,y); + BN_zero(Qz); + } + else { + CurveInit(a); + ToProjective(0,x,y); + BN_copy(Qx,Px); + BN_copy(Qy,Py); + for(int i=scalarbits-2; i>=0; i--) { + DoubleP(0); + if(BN_is_bit_set(scalar,i)) { + BN_copy(A,Pz); + if(BN_is_zero(Pz) || BN_is_zero(D)) { + BN_copy(Px,Qx); + BN_copy(Py,Qy); + BN_copy(Pz,Qz); + AddP(1); + } + else { + doz=true; + if(wordsize==4) { + BN_rshift(Py,Py,32); + BN_lshift(Py,Py,32); + BN_rshift(b,Qz,224); + BN_add(Py,Py,b); + } + BN_mask_bits(Px,32); + BN_lshift(b,Qz,32); + BN_add(Px,Px,b); + BN_mask_bits(Px,128); + AddP(0); + } } } + ToAffine(); } - ToAffine(); } - memset(data,0,0x60); - Px.PutLE(&data[0x00],16); - unsigned char tmp[16]; - Qz.PutLE(tmp,16); - memcpy(&data[0x10],&tmp[0x0C],4); - Py.PutLE(&data[0x20],16); + else { + BN_copy(Px,x); + BN_copy(Py,y); + BN_zero(Qz); + } + memset(data,0,0x40); + Px.PutLE(&data[0x00],l); + if(l<0x20 && doz) { + unsigned char tmp[0x20]; + Qz.PutLE(tmp,l); + memcpy(&data[l],&tmp[l-4],4); + } + Py.PutLE(&data[0x20],l); + TMPWS_END(); + BN_zero(A); + BN_zero(B); + BN_zero(C); break; } default: @@ -719,7 +750,7 @@ bool cN2Prov0101::RomInit(void) bool cN2Prov0101::ProcessMap(int f) { unsigned short addr; - unsigned char tmp[256]; + unsigned char tmp[512]; int l=GetOpSize(Get(0x48)); int dl=l<<3; @@ -774,13 +805,17 @@ bool cN2Prov0101::ProcessMap(int f) AddCycles(MapCycles()); break; case 0x29: - DoMap(f,tmp,-Get(0x48)); + GetMem(HILO(0x44),tmp,dl,0); + DoMap(f,tmp); Set(0x4b,tmp[0]); AddCycles(MapCycles()); break; + case 0x3e: + if(l>wordsize) { l=wordsize; dl=l<<3; } + // fall through case 0x32: case 0x3b: - case 0x3e: + if(l>34) { l=34; dl=34<<3; } GetMem(HILO(0x44),tmp,dl,0); DoMap(f,tmp,l); AddCycles(MapCycles()); @@ -806,14 +841,13 @@ bool cN2Prov0101::ProcessMap(int f) break; case 0x57: addr=HILO(0x46); - GetMem(HILO(addr ),tmp,16,0); - GetMem(HILO(addr+2 ),tmp+0x10,16,0); - GetMem(HILO(addr+4 ),tmp+0x20,16,0); - GetMem(HILO(addr+6 ),tmp+0x30,16,0); - GetMem(HILO(addr+8 ),tmp+0x40,16,0); - GetMem(HILO(addr+10),tmp+0x50,16,0); + l=wordsize; if(l<2 || l>4) l=4; + dl=l<<3; + for(int i=0; i<6; i++) GetMem(HILO(addr+i*2),tmp+i*dl,dl,0); DoMap(f,tmp); SetMem(0x400,tmp,0x40,0); + memset(tmp,0,11*32); + SetMem(0x440,tmp,11*32,0); AddCycles(MapCycles()); break; default: diff --git a/systems/nagra/nagra2.c b/systems/nagra/nagra2.c index 497202a..8edcf3b 100644 --- a/systems/nagra/nagra2.c +++ b/systems/nagra/nagra2.c @@ -270,7 +270,7 @@ void cMapMath::ModSub(BIGNUM *r, BIGNUM *d, BIGNUM *b) BN_mask_bits(r,wordsize<<6); } -void cMapMath::MakeJ0(BIGNUM *j, BIGNUM *d) +void cMapMath::MakeJ0(BIGNUM *j, BIGNUM *d, int bits) { #if OPENSSL_VERSION_NUMBER < 0x0090700fL #error BN_mod_inverse is probably buggy in your openssl version @@ -278,7 +278,7 @@ void cMapMath::MakeJ0(BIGNUM *j, BIGNUM *d) BN_zero(x); BN_sub(j,x,d); BN_set_bit(j,0); - BN_set_bit(x,64); + BN_set_bit(x,bits); BN_mod_inverse(j,j,x,ctx); } @@ -383,6 +383,14 @@ void cMapCore::MonExpNeg(void) MonMul(B,B,B); if(BN_is_bit_set(e,i)) MonMul(B,A,B); } + if(BN_is_bit_set(D,0)) { + int i; + for(i=BN_num_bits(D)-2; i>0; i--) if(BN_is_bit_set(D,i)) break; + if(i<=0) { + MonMul(B,B,B); + MonMul(B,A,B); + } + } BN_set_word(A,1); MonMul(B,A,B); } @@ -493,6 +501,7 @@ void cMapCore::CurveInit(BIGNUM *a) BN_copy(A,B); BN_copy(I,D); BN_add_word(I,1); + BN_mask_bits(I,wordsize<<6); BN_rshift(I,I,1); MonMul(s140,I,B); MonMul(s160,B,a); @@ -510,36 +519,52 @@ bool cMapCore::DoMap(int f, unsigned char *data, int l) cycles=0; switch(f) { case SETSIZE: - wordsize=l; cycles=475-6; break; + cycles=(l>17 ? 459 : (l ? 475 : 454))-6; + if(l>=1 && l<=17) wordsize=l; + break; case IMPORT_J: cycles=890-6; - // fall through + last=0; + regs[0]->GetLE(data,8); + break; case IMPORT_A: case IMPORT_B: case IMPORT_C: case IMPORT_D: - if(!cycles) cycles=771+160*l1-6+(l==0?4:0); + if(l>17) { l=17; cycles+=5; } + else if(l<=0) { l=wordsize; cycles+=4; } + cycles+=771+160*l-6; last=f-IMPORT_J; - // fall through + regs[last]->GetLE(data,l<<3); + break; case IMPORT_LAST: - if(!cycles) cycles=656+160*l-6; - regs[last]->GetLE(data,last>0?dl:8); + if(l>16) { l=1; cycles+=5; } + else if(l<=0) l=1; + cycles=656+160*l-6; + regs[last]->GetLE(data,(last==0?1:l)<<3); break; case EXPORT_J: cycles=897-6; - // fall through + last=0; + regs[0]->PutLE(data,8); + break; case EXPORT_A: case EXPORT_B: case EXPORT_C: case EXPORT_D: - if(!cycles) cycles=778+160*l1-6+(l==0?4:0); + if(l>17) { l=17; cycles+=5; } + else if(l<=0) { l=wordsize; cycles+=4; } + cycles=778+160*l-6; last=f-EXPORT_J; - // fall through + regs[last]->PutLE(data,l<<3); + break; case EXPORT_LAST: - if(!cycles) cycles=668+160*l-6; // Even for 'J' cycles is dependent on 'l' - regs[last]->PutLE(data,last>0?dl:8); + if(l>16) { l=1; cycles+=5; } + else if(l<=0) l=1; + cycles=668+160*l-6; + regs[last]->PutLE(data,(last==0?1:l)<<3); break; case SWAP_A: @@ -557,22 +582,22 @@ bool cMapCore::DoMap(int f, unsigned char *data, int l) case CLEAR_B: case CLEAR_C: case CLEAR_D: - cycles=465+(8*l1)-((8*l1-2)%5)-6; + cycles=462+(8*l1+3)/5*5-6; last=f-CLEAR_A+1; BN_zero(*regs[last]); break; case COPY_A_B: - last=2; BN_copy(B,A); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; + last=2; BN_copy(B,A); cycles=462+(8*l1+3)/5*5-6; break; case COPY_B_A: - last=1; BN_copy(A,B); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; + last=1; BN_copy(A,B); cycles=462+(8*l1+3)/5*5-6; break; case COPY_A_C: - last=3; BN_copy(C,A); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; + last=3; BN_copy(C,A); cycles=462+(8*l1+3)/5*5-6; break; case COPY_C_A: - last=1; BN_copy(A,C); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; + last=1; BN_copy(A,C); cycles=462+(8*l1+3)/5*5-6; break; case COPY_C_D: - last=4; BN_copy(D,C); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; + last=4; BN_copy(D,C); cycles=462+(8*l1+3)/5*5-6; break; case COPY_D_C: - last=3; BN_copy(C,D); cycles=465+(8*l1)-((8*l1-2)%5)-6; break; + last=3; BN_copy(C,D); cycles=462+(8*l1+3)/5*5-6; break; case 0x43: // init SHA1 SHA1_Init(&sctx); diff --git a/systems/nagra/nagra2.h b/systems/nagra/nagra2.h index 0c39434..af00a3e 100644 --- a/systems/nagra/nagra2.h +++ b/systems/nagra/nagra2.h @@ -52,6 +52,9 @@ extern char auxPassword[250]; #define DEF_WORDSIZE 4 +#define TMPWS_START(x) { int __oldws=wordsize; wordsize=(x); +#define TMPWS_END() wordsize=__oldws; } + class cMapMath { private: cBN x, y, s; @@ -62,7 +65,7 @@ protected: cBNctx ctx; SHA_CTX sctx; // stateless - void MakeJ0(BIGNUM *j, BIGNUM *d); + void MakeJ0(BIGNUM *j, BIGNUM *d, int bits=64); void ModAdd(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *d); void ModSub(BIGNUM *r, BIGNUM *d, BIGNUM *b); void MonMul(BIGNUM *o, BIGNUM *a, BIGNUM *b, BIGNUM *c, BIGNUM *d, BIGNUM *j, int w); -- 2.39.5